source: josm/trunk/src/org/openstreetmap/josm/gui/dialogs/FilterTableModel.java@ 10611

Last change on this file since 10611 was 10446, checked in by Don-vip, 8 years ago

see #13001 - replace calls to Main.main.getCurrentDataSet() by Main.getLayerManager().getEditDataSet()

  • Property svn:eol-style set to native
File size: 12.7 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.dialogs;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5import static org.openstreetmap.josm.tools.I18n.trc;
6import static org.openstreetmap.josm.tools.I18n.trn;
7
8import java.awt.Color;
9import java.awt.Font;
10import java.awt.Graphics;
11import java.awt.Graphics2D;
12import java.util.ArrayList;
13import java.util.Collection;
14import java.util.HashSet;
15import java.util.LinkedList;
16import java.util.List;
17
18import javax.swing.BorderFactory;
19import javax.swing.JLabel;
20import javax.swing.JOptionPane;
21import javax.swing.table.AbstractTableModel;
22
23import org.openstreetmap.josm.Main;
24import org.openstreetmap.josm.actions.search.SearchCompiler.ParseError;
25import org.openstreetmap.josm.data.osm.DataSet;
26import org.openstreetmap.josm.data.osm.Filter;
27import org.openstreetmap.josm.data.osm.Filter.FilterPreferenceEntry;
28import org.openstreetmap.josm.data.osm.FilterMatcher;
29import org.openstreetmap.josm.data.osm.FilterWorker;
30import org.openstreetmap.josm.data.osm.Node;
31import org.openstreetmap.josm.data.osm.OsmPrimitive;
32import org.openstreetmap.josm.tools.Utils;
33
34/**
35 *
36 * @author Petr_Dlouhý
37 */
38public class FilterTableModel extends AbstractTableModel {
39
40 public static final int COL_ENABLED = 0;
41 public static final int COL_HIDING = 1;
42 public static final int COL_TEXT = 2;
43 public static final int COL_INVERTED = 3;
44
45 // number of primitives that are disabled but not hidden
46 public int disabledCount;
47 // number of primitives that are disabled and hidden
48 public int disabledAndHiddenCount;
49
50 /**
51 * Constructs a new {@code FilterTableModel}.
52 */
53 public FilterTableModel() {
54 loadPrefs();
55 }
56
57 private final transient List<Filter> filters = new LinkedList<>();
58 private final transient FilterMatcher filterMatcher = new FilterMatcher();
59
60 private void updateFilters() {
61 filterMatcher.reset();
62 for (Filter filter : filters) {
63 try {
64 filterMatcher.add(filter);
65 } catch (ParseError e) {
66 JOptionPane.showMessageDialog(
67 Main.parent,
68 tr("<html>Error in filter <code>{0}</code>:<br>{1}", Utils.shortenString(filter.text, 80), e.getMessage()),
69 tr("Error in filter"),
70 JOptionPane.ERROR_MESSAGE);
71 filter.enable = false;
72 savePrefs();
73 }
74 }
75 executeFilters();
76 }
77
78 public void executeFilters() {
79 DataSet ds = Main.getLayerManager().getEditDataSet();
80 boolean changed = false;
81 if (ds == null) {
82 disabledAndHiddenCount = 0;
83 disabledCount = 0;
84 changed = true;
85 } else {
86 final Collection<OsmPrimitive> deselect = new HashSet<>();
87
88 ds.beginUpdate();
89 try {
90
91 final Collection<OsmPrimitive> all = ds.allNonDeletedCompletePrimitives();
92
93 changed = FilterWorker.executeFilters(all, filterMatcher);
94
95 disabledCount = 0;
96 disabledAndHiddenCount = 0;
97 // collect disabled and selected the primitives
98 for (OsmPrimitive osm : all) {
99 if (osm.isDisabled()) {
100 disabledCount++;
101 if (osm.isSelected()) {
102 deselect.add(osm);
103 }
104 if (osm.isDisabledAndHidden()) {
105 disabledAndHiddenCount++;
106 }
107 }
108 }
109 disabledCount -= disabledAndHiddenCount;
110 } finally {
111 ds.endUpdate();
112 }
113
114 if (!deselect.isEmpty()) {
115 ds.clearSelection(deselect);
116 }
117 }
118
119 if (Main.isDisplayingMapView() && changed) {
120 Main.map.mapView.repaint();
121 Main.map.filterDialog.updateDialogHeader();
122 }
123 }
124
125 public void executeFilters(Collection<? extends OsmPrimitive> primitives) {
126 DataSet ds = Main.getLayerManager().getEditDataSet();
127 if (ds == null)
128 return;
129
130 boolean changed = false;
131 List<OsmPrimitive> deselect = new ArrayList<>();
132
133 ds.beginUpdate();
134 try {
135 for (int i = 0; i < 2; i++) {
136 for (OsmPrimitive primitive: primitives) {
137
138 if (i == 0 && primitive instanceof Node) {
139 continue;
140 }
141
142 if (i == 1 && !(primitive instanceof Node)) {
143 continue;
144 }
145
146 if (primitive.isDisabled()) {
147 disabledCount--;
148 }
149 if (primitive.isDisabledAndHidden()) {
150 disabledAndHiddenCount--;
151 }
152 changed = changed | FilterWorker.executeFilters(primitive, filterMatcher);
153 if (primitive.isDisabled()) {
154 disabledCount++;
155 }
156 if (primitive.isDisabledAndHidden()) {
157 disabledAndHiddenCount++;
158 }
159
160 if (primitive.isSelected() && primitive.isDisabled()) {
161 deselect.add(primitive);
162 }
163
164 }
165 }
166 } finally {
167 ds.endUpdate();
168 }
169
170 if (changed) {
171 Main.map.mapView.repaint();
172 Main.map.filterDialog.updateDialogHeader();
173 ds.clearSelection(deselect);
174 }
175
176 }
177
178 public void clearFilterFlags() {
179 DataSet ds = Main.getLayerManager().getEditDataSet();
180 if (ds != null) {
181 FilterWorker.clearFilterFlags(ds.allPrimitives());
182 }
183 disabledCount = 0;
184 disabledAndHiddenCount = 0;
185 }
186
187 private void loadPrefs() {
188 List<FilterPreferenceEntry> entries = Main.pref.getListOfStructs("filters.entries", null, FilterPreferenceEntry.class);
189 if (entries != null) {
190 for (FilterPreferenceEntry e : entries) {
191 filters.add(new Filter(e));
192 }
193 updateFilters();
194 }
195 }
196
197 private void savePrefs() {
198 Collection<FilterPreferenceEntry> entries = new ArrayList<>();
199 for (Filter flt : filters) {
200 entries.add(flt.getPreferenceEntry());
201 }
202 Main.pref.putListOfStructs("filters.entries", entries, FilterPreferenceEntry.class);
203 }
204
205 public void addFilter(Filter f) {
206 filters.add(f);
207 savePrefs();
208 updateFilters();
209 fireTableRowsInserted(filters.size() - 1, filters.size() - 1);
210 }
211
212 public void moveDownFilter(int i) {
213 if (i >= filters.size() - 1)
214 return;
215 filters.add(i + 1, filters.remove(i));
216 savePrefs();
217 updateFilters();
218 fireTableRowsUpdated(i, i + 1);
219 }
220
221 public void moveUpFilter(int i) {
222 if (i == 0)
223 return;
224 filters.add(i - 1, filters.remove(i));
225 savePrefs();
226 updateFilters();
227 fireTableRowsUpdated(i - 1, i);
228 }
229
230 public void removeFilter(int i) {
231 filters.remove(i);
232 savePrefs();
233 updateFilters();
234 fireTableRowsDeleted(i, i);
235 }
236
237 public void setFilter(int i, Filter f) {
238 filters.set(i, f);
239 savePrefs();
240 updateFilters();
241 fireTableRowsUpdated(i, i);
242 }
243
244 public Filter getFilter(int i) {
245 return filters.get(i);
246 }
247
248 @Override
249 public int getRowCount() {
250 return filters.size();
251 }
252
253 @Override
254 public int getColumnCount() {
255 return 5;
256 }
257
258 @Override
259 public String getColumnName(int column) {
260 String[] names = {/* translators notes must be in front */
261 /* column header: enable filter */trc("filter", "E"),
262 /* column header: hide filter */trc("filter", "H"),
263 /* column header: filter text */trc("filter", "Text"),
264 /* column header: inverted filter */trc("filter", "I"),
265 /* column header: filter mode */trc("filter", "M")};
266 return names[column];
267 }
268
269 @Override
270 public Class<?> getColumnClass(int column) {
271 Class<?>[] classes = {Boolean.class, Boolean.class, String.class, Boolean.class, String.class};
272 return classes[column];
273 }
274
275 public boolean isCellEnabled(int row, int column) {
276 if (!filters.get(row).enable && column != 0)
277 return false;
278 return true;
279 }
280
281 @Override
282 public boolean isCellEditable(int row, int column) {
283 if (!filters.get(row).enable && column != 0)
284 return false;
285 if (column < 4)
286 return true;
287 return false;
288 }
289
290 @Override
291 public void setValueAt(Object aValue, int row, int column) {
292 if (row >= filters.size()) {
293 return;
294 }
295 Filter f = filters.get(row);
296 switch (column) {
297 case COL_ENABLED:
298 f.enable = (Boolean) aValue;
299 savePrefs();
300 updateFilters();
301 fireTableRowsUpdated(row, row);
302 break;
303 case COL_HIDING:
304 f.hiding = (Boolean) aValue;
305 savePrefs();
306 updateFilters();
307 break;
308 case COL_TEXT:
309 f.text = (String) aValue;
310 savePrefs();
311 break;
312 case COL_INVERTED:
313 f.inverted = (Boolean) aValue;
314 savePrefs();
315 updateFilters();
316 break;
317 default: // Do nothing
318 }
319 if (column != 0) {
320 fireTableCellUpdated(row, column);
321 }
322 }
323
324 @Override
325 public Object getValueAt(int row, int column) {
326 if (row >= filters.size()) {
327 return null;
328 }
329 Filter f = filters.get(row);
330 switch (column) {
331 case COL_ENABLED:
332 return f.enable;
333 case COL_HIDING:
334 return f.hiding;
335 case COL_TEXT:
336 return f.text;
337 case COL_INVERTED:
338 return f.inverted;
339 case 4:
340 switch (f.mode) { /* translators notes must be in front */
341 case replace: /* filter mode: replace */
342 return trc("filter", "R");
343 case add: /* filter mode: add */
344 return trc("filter", "A");
345 case remove: /* filter mode: remove */
346 return trc("filter", "D");
347 case in_selection: /* filter mode: in selection */
348 return trc("filter", "F");
349 default:
350 Main.warn("Unknown filter mode: " + f.mode);
351 }
352 break;
353 default: // Do nothing
354 }
355 return null;
356 }
357
358 /**
359 * On screen display label
360 */
361 private static class OSDLabel extends JLabel {
362 OSDLabel(String text) {
363 super(text);
364 setOpaque(true);
365 setForeground(Color.black);
366 setBackground(new Color(0, 0, 0, 0));
367 setFont(getFont().deriveFont(Font.PLAIN));
368 setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10));
369 }
370
371 @Override
372 public void paintComponent(Graphics g) {
373 g.setColor(new Color(255, 255, 255, 140));
374 g.fillRoundRect(getX(), getY(), getWidth(), getHeight(), 10, 10);
375 super.paintComponent(g);
376 }
377 }
378
379 private final OSDLabel lblOSD = new OSDLabel("");
380
381 public void drawOSDText(Graphics2D g) {
382 String message = "<html>" + tr("<h2>Filter active</h2>");
383
384 if (disabledCount == 0 && disabledAndHiddenCount == 0)
385 return;
386
387 if (disabledAndHiddenCount != 0) {
388 /* for correct i18n of plural forms - see #9110 */
389 message += trn("<p><b>{0}</b> object hidden", "<p><b>{0}</b> objects hidden", disabledAndHiddenCount, disabledAndHiddenCount);
390 }
391
392 if (disabledAndHiddenCount != 0 && disabledCount != 0) {
393 message += "<br>";
394 }
395
396 if (disabledCount != 0) {
397 /* for correct i18n of plural forms - see #9110 */
398 message += trn("<b>{0}</b> object disabled", "<b>{0}</b> objects disabled", disabledCount, disabledCount);
399 }
400
401 message += tr("</p><p>Close the filter dialog to see all objects.<p></html>");
402
403 lblOSD.setText(message);
404 lblOSD.setSize(lblOSD.getPreferredSize());
405
406 int dx = Main.map.mapView.getWidth() - lblOSD.getPreferredSize().width - 15;
407 int dy = 15;
408 g.translate(dx, dy);
409 lblOSD.paintComponent(g);
410 g.translate(-dx, -dy);
411 }
412
413 /**
414 * Returns the list of filters.
415 * @return the list of filters
416 */
417 public List<Filter> getFilters() {
418 return filters;
419 }
420}
Note: See TracBrowser for help on using the repository browser.