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

Last change on this file since 11452 was 11452, checked in by Don-vip, 7 years ago

sonar - fb-contrib:SEO_SUBOPTIMAL_EXPRESSION_ORDER - Performance - Method orders expressions in a conditional in a sub optimal way

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