- Timestamp:
- 2011-03-30T22:25:20+02:00 (14 years ago)
- Location:
- trunk/src/org/openstreetmap/josm/gui/mappaint
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/gui/mappaint/Environment.java
r3893 r4011 2 2 package org.openstreetmap.josm.gui.mappaint; 3 3 4 import java.util.Collection; 5 import java.util.List; 6 4 7 import org.openstreetmap.josm.data.osm.OsmPrimitive; 8 import org.openstreetmap.josm.gui.mappaint.mapcss.Instruction; 5 9 6 10 public class Environment { 7 11 8 12 public OsmPrimitive osm; 9 13 public MultiCascade mc; 10 14 public String layer; 11 15 public StyleSource source; 16 17 /** 18 * <p>When matching a child selector, the matching referrers will be stored. 19 * They can be accessed in {@link Instruction#execute(Environment)} to access 20 * tags from parent objects.</p> 21 */ 22 private List<OsmPrimitive> matchingReferrers = null; 12 23 13 24 public Environment(OsmPrimitive osm, MultiCascade mc, String layer, StyleSource source) { … … 18 29 } 19 30 31 public Collection<OsmPrimitive> getMatchingReferrers() { 32 return matchingReferrers; 33 } 34 35 public void setMatchingReferrers(List<OsmPrimitive> refs) { 36 matchingReferrers = refs; 37 } 38 39 public void clearMatchingReferrers() { 40 matchingReferrers = null; 41 } 20 42 } -
trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Expression.java
r4008 r4011 17 17 import org.openstreetmap.josm.actions.search.SearchCompiler.ParseError; 18 18 import org.openstreetmap.josm.data.osm.OsmPrimitive; 19 import org.openstreetmap.josm.data.osm.Relation;20 19 import org.openstreetmap.josm.gui.mappaint.Cascade; 21 20 import org.openstreetmap.josm.gui.mappaint.Environment; … … 174 173 } 175 174 176 // FIXME: respect parent selector chain177 175 public String parent_tag(String key) { 178 for (Relation parent: OsmPrimitive.getFilteredList(env.osm.getReferrers(), Relation.class)) { 179 String value = parent.get(key); 180 if (value != null) return value; 181 } 182 return null; 176 if (env.getMatchingReferrers() == null) { 177 // we don't have a matched parent, so just search all referrers 178 for (OsmPrimitive parent : env.osm.getReferrers()) { 179 String value = parent.get(key); 180 if (value != null) 181 return value; 182 } 183 return null; 184 } 185 if (env.getMatchingReferrers().isEmpty()) 186 return null; 187 // use always the first matching referrer to have consistency 188 // in an expression and declaration block 189 return env.getMatchingReferrers().iterator().next().get(key); 183 190 } 184 191 -
trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSStyleSource.java
r3987 r4011 140 140 for (MapCSSRule r : rules) { 141 141 for (Selector s : r.selectors) { 142 if (s.applies(env)) { 142 env.clearMatchingReferrers(); 143 if (s.matches(env)) { // as side effect env.matchingReferrers will be set (if s is a child selector) 143 144 if (s.getRange().contains(scale)) { 144 145 mc.range = Range.cut(mc.range, s.getRange()); -
trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java
r3902 r4011 2 2 package org.openstreetmap.josm.gui.mappaint.mapcss; 3 3 4 import java.util.ArrayList; 4 5 import java.util.List; 5 6 … … 15 16 16 17 public interface Selector { 17 18 public boolean applies(Environment e); 18 19 /** 20 * Apply the selector to the primitive and check if it matches. 21 * 22 * @param env the Environment. env.mc and env.layer are read-only when matching a selector. 23 * env.source is not needed. This method will set the matchingReferrers field of env as 24 * a side effect! Make sure to clear it before invoking this method. 25 * @return true, if the selector applies 26 */ 27 public boolean matches(Environment env); 19 28 20 29 public String getSubpart(); 30 21 31 public Range getRange(); 22 32 23 public static class DescendentSelector implements Selector { 33 /** 34 * <p>Represents a child selector or a parent selector.</p> 35 * 36 * <p>In addition to the standard CSS notation for child selectors, JOSM also supports 37 * an "inverse" notation:</p> 38 * <pre> 39 * selector_a > selector_b { ... } // the standard notation (child selector) 40 * relation[type=route] > way { ... } // example (all ways of a route) 41 * 42 * selector_a < selector_b { ... } // the inverse notation (parent selector) 43 * node[traffic_calming] < way { ... } // example (way that has a traffic calming node) 44 * </pre> 45 * 46 */ 47 public static class ChildOrParentSelector implements Selector { 24 48 Selector a, b; 25 boolean child; 49 /** true, if this represents a parent selector (otherwise it is a child selector) 50 */ 51 private final boolean parentSelector; 26 52 27 public DescendentSelector(Selector a, Selector b, boolean child) { 53 /** 54 * 55 * @param a the first selector 56 * @param b the second selector 57 * @param parentSelector if true, this is a parent selector; otherwise a child selector 58 */ 59 public ChildOrParentSelector(Selector a, Selector b, boolean parentSelector) { 28 60 this.a = a; 29 61 this.b = b; 30 this. child = child;62 this.parentSelector = parentSelector; 31 63 } 32 64 33 65 @Override 34 public boolean applies(Environment e) {35 if (!b. applies(e))66 public boolean matches(Environment e) { 67 if (!b.matches(e)) 36 68 return false; 37 69 38 70 Environment e2 = new Environment(null, e.mc, e.layer, e.source); 39 if (child) { 40 for (OsmPrimitive osm : e.osm.getReferrers()) { 41 e2.osm = osm; 42 if (a.applies(e2)) 43 return true; 71 List<OsmPrimitive> matchingRefs = new ArrayList<OsmPrimitive>(); 72 if (!parentSelector) { 73 for (OsmPrimitive ref : e.osm.getReferrers()) { 74 e2.osm = ref; 75 if (a.matches(e2)) { 76 matchingRefs.add(ref); 77 } 78 } 79 if (!matchingRefs.isEmpty()) { 80 e.setMatchingReferrers(matchingRefs); 81 return true; 44 82 } 45 83 } else { … … 47 85 for (OsmPrimitive chld : ((Relation) e.osm).getMemberPrimitives()) { 48 86 e2.osm = chld; 49 if (a. applies(e2))87 if (a.matches(e2)) 50 88 return true; 51 89 } … … 53 91 for (Node n : ((Way) e.osm).getNodes()) { 54 92 e2.osm = n; 55 if (a. applies(e2))93 if (a.matches(e2)) 56 94 return true; 57 95 } … … 104 142 105 143 @Override 106 public boolean applies(Environment e) {144 public boolean matches(Environment e) { 107 145 if (!baseApplies(e.osm)) 108 146 return false; -
trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/parser/MapCSSParser.java
r3971 r4011 15 15 import org.openstreetmap.josm.gui.mappaint.mapcss.Expression.FunctionExpression; 16 16 import org.openstreetmap.josm.gui.mappaint.mapcss.Expression.LiteralExpression; 17 import org.openstreetmap.josm.gui.mappaint.mapcss.Selector. DescendentSelector;17 import org.openstreetmap.josm.gui.mappaint.mapcss.Selector.ChildOrParentSelector; 18 18 import org.openstreetmap.josm.gui.mappaint.mapcss.Selector.GeneralSelector; 19 19 import org.openstreetmap.josm.tools.Pair; … … 275 275 276 276 final public Selector child_selector() throws ParseException { 277 boolean child= false;277 boolean parentSelector = false; 278 278 Selector sel1, sel2 = null; 279 279 sel1 = selector(); … … 285 285 case GREATER: 286 286 jj_consume_token(GREATER); 287 child = true;287 parentSelector = false; 288 288 break; 289 289 case LESS: 290 290 jj_consume_token(LESS); 291 child = false;291 parentSelector = true; 292 292 break; 293 293 default: … … 304 304 ; 305 305 } 306 {if (true) return sel2 != null ? new DescendentSelector(sel1, sel2, child) : sel1;}306 {if (true) return sel2 != null ? new ChildOrParentSelector(sel1, sel2, parentSelector) : sel1;} 307 307 throw new Error("Missing return statement in function"); 308 308 } -
trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/parser/MapCSSParser.jj
r3971 r4011 20 20 import org.openstreetmap.josm.gui.mappaint.mapcss.Expression.FunctionExpression; 21 21 import org.openstreetmap.josm.gui.mappaint.mapcss.Expression.LiteralExpression; 22 import org.openstreetmap.josm.gui.mappaint.mapcss.Selector. DescendentSelector;22 import org.openstreetmap.josm.gui.mappaint.mapcss.Selector.ChildOrParentSelector; 23 23 import org.openstreetmap.josm.gui.mappaint.mapcss.Selector.GeneralSelector; 24 24 import org.openstreetmap.josm.tools.Pair; … … 251 251 Selector child_selector() : 252 252 { 253 boolean child= false;253 boolean parentSelector = false; 254 254 Selector sel1, sel2 = null; 255 255 } … … 257 257 sel1=selector() w() 258 258 ( 259 ( <GREATER> { child = true; } | <LESS> { child = false; } ) w()259 ( <GREATER> { parentSelector = false; } | <LESS> { parentSelector = true; } ) w() 260 260 sel2=selector() w() 261 261 )? 262 { return sel2 != null ? new DescendentSelector(sel1, sel2, child) : sel1; }262 { return sel2 != null ? new ChildOrParentSelector(sel1, sel2, parentSelector) : sel1; } 263 263 } 264 264 -
trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/parser/MapCSSParserTokenManager.java
r3967 r4011 13 13 import org.openstreetmap.josm.gui.mappaint.mapcss.Expression.FunctionExpression; 14 14 import org.openstreetmap.josm.gui.mappaint.mapcss.Expression.LiteralExpression; 15 import org.openstreetmap.josm.gui.mappaint.mapcss.Selector. DescendentSelector;15 import org.openstreetmap.josm.gui.mappaint.mapcss.Selector.ChildOrParentSelector; 16 16 import org.openstreetmap.josm.gui.mappaint.mapcss.Selector.GeneralSelector; 17 17 import org.openstreetmap.josm.tools.Pair;
Note:
See TracChangeset
for help on using the changeset viewer.