source: josm/trunk/src/org/openstreetmap/josm/data/osm/FilterMatcher.java@ 3401

Last change on this file since 3401 was 3401, checked in by jttt, 14 years ago

Fix #5255 filter: wrong info about the amount of filtered objects.

  • Property svn:mime-type set to text/plain
File size: 4.4 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.data.osm;
3
4import java.util.ArrayList;
5import java.util.Collection;
6import java.util.List;
7
8import org.openstreetmap.josm.actions.search.SearchCompiler;
9import org.openstreetmap.josm.actions.search.SearchAction.SearchMode;
10import org.openstreetmap.josm.actions.search.SearchCompiler.Match;
11import org.openstreetmap.josm.actions.search.SearchCompiler.Not;
12import org.openstreetmap.josm.actions.search.SearchCompiler.ParseError;
13
14public class FilterMatcher {
15
16 private static class FilterInfo {
17 final Match match;
18 final boolean isDelete;
19 final boolean isInverted;
20
21 FilterInfo(Filter filter) throws ParseError {
22 if (filter.mode == SearchMode.remove || filter.mode == SearchMode.in_selection) {
23 isDelete = true;
24 } else {
25 isDelete = false;
26 }
27
28 Match compiled = SearchCompiler.compile(filter.text, filter.caseSensitive, filter.regexSearch);
29 this.match = filter.inverted?new Not(compiled):compiled;
30 this.isInverted = filter.inverted;
31 }
32 }
33
34 private final List<FilterInfo> hiddenFilters = new ArrayList<FilterInfo>();
35 private final List<FilterInfo> disabledFilters = new ArrayList<FilterInfo>();
36
37 public void update(Collection<Filter> filters) throws ParseError {
38 hiddenFilters.clear();
39 disabledFilters.clear();
40
41 for (Filter filter: filters) {
42
43 if (!filter.enable) {
44 continue;
45 }
46
47 FilterInfo fi = new FilterInfo(filter);
48 if (fi.isDelete) {
49 if (filter.hiding) {
50 // Remove only hide flag
51 hiddenFilters.add(fi);
52 } else {
53 // Remove both flags
54 disabledFilters.add(fi);
55 hiddenFilters.add(fi);
56 }
57 } else {
58 if (filter.mode == SearchMode.replace) {
59 if (filter.hiding) {
60 hiddenFilters.clear();
61 disabledFilters.clear();
62 }
63 }
64
65 disabledFilters.add(fi);
66 if (filter.hiding) {
67 hiddenFilters.add(fi);
68 }
69 }
70 }
71 }
72
73 private boolean getState(OsmPrimitive primitive, boolean hidden) {
74 return hidden?primitive.isDisabledAndHidden():primitive.isDisabled();
75 }
76
77 private boolean allParentWaysFiltered(OsmPrimitive primitive, boolean hidden) {
78 List<OsmPrimitive> refs = primitive.getReferrers();
79 boolean foundWay = false;
80
81 for (OsmPrimitive p: refs) {
82 if (p instanceof Way) {
83 foundWay = true;
84 if (!getState(p, hidden))
85 return false;
86 }
87 }
88
89 return foundWay;
90 }
91
92 private boolean oneParentWayNotFiltered(OsmPrimitive primitive, boolean hidden) {
93 List<OsmPrimitive> refs = primitive.getReferrers();
94 for (OsmPrimitive p: refs) {
95 if (p instanceof Way && !getState(p, hidden))
96 return true;
97 }
98
99 return false;
100 }
101
102 private boolean test(List<FilterInfo> filters, OsmPrimitive primitive, boolean hidden) {
103
104 if (primitive.isIncomplete())
105 return false;
106
107 boolean selected = false;
108 boolean onlyInvertedFilters = true;
109
110 for (FilterInfo fi: filters) {
111 if (fi.isDelete && selected && fi.match.match(primitive)) {
112 selected = false;
113 } else if (!fi.isDelete && (!selected || (onlyInvertedFilters && !fi.isInverted)) && fi.match.match(primitive)) {
114 selected = true;
115 onlyInvertedFilters = onlyInvertedFilters && fi.isInverted;
116 }
117 }
118
119 if (primitive instanceof Node) {
120 if (!selected)
121 return !primitive.isTagged() && allParentWaysFiltered(primitive, hidden);
122 if (onlyInvertedFilters)
123 return selected && !oneParentWayNotFiltered(primitive, hidden);
124 return true;
125 } else
126 return selected;
127
128 }
129
130 public boolean isHidden(OsmPrimitive primitive) {
131 return test(hiddenFilters, primitive, true);
132 }
133
134 public boolean isDisabled(OsmPrimitive primitive) {
135 return test(disabledFilters, primitive, false);
136 }
137
138}
Note: See TracBrowser for help on using the repository browser.