Changeset 8494 in josm for trunk/src/org
- Timestamp:
- 2015-06-19T19:18:10+02:00 (10 years ago)
- Location:
- trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Condition.java
r8338 r8494 2 2 package org.openstreetmap.josm.gui.mappaint.mapcss; 3 3 4 import java.lang.reflect.InvocationTargetException; 5 import java.lang.reflect.Method; 4 6 import java.text.MessageFormat; 5 7 import java.util.Arrays; … … 69 71 70 72 public static PseudoClassCondition createPseudoClassCondition(String id, boolean not, Context context) { 71 return newPseudoClassCondition(id, not, context);73 return PseudoClassCondition.createPseudoClassCondition(id, not, context); 72 74 } 73 75 … … 376 378 } 377 379 380 /** 381 * Like <a href="http://www.w3.org/TR/css3-selectors/#pseudo-classes">CSS pseudo classes</a>, MapCSS pseudo classes 382 * are written in lower case with dashes between words. 383 */ 384 static class PseudoClasses { 385 386 /** 387 * {@code closed} tests whether the way is closed or the relation is a closed multipolygon 388 */ 389 static boolean closed(Environment e) { 390 if (e.osm instanceof Way && ((Way) e.osm).isClosed()) 391 return true; 392 if (e.osm instanceof Relation && ((Relation) e.osm).isMultipolygon()) 393 return true; 394 return false; 395 } 396 397 /** 398 * {@code :modified} tests whether the object has been modified. 399 * @see OsmPrimitive#isModified() () 400 */ 401 static boolean modified(Environment e) { 402 return e.osm.isModified() || e.osm.isNewOrUndeleted(); 403 } 404 405 /** 406 * {@code ;new} tests whether the object is new. 407 * @see OsmPrimitive#isNew() 408 */ 409 static boolean _new(Environment e) { 410 return e.osm.isNew(); 411 } 412 413 /** 414 * {@code :connection} tests whether the object is a connection node. 415 * @see Node#isConnectionNode() 416 */ 417 static boolean connection(Environment e) { 418 return e.osm instanceof Node && ((Node) e.osm).isConnectionNode(); 419 } 420 421 /** 422 * {@code :tagged} tests whether the object is tagged. 423 * @see OsmPrimitive#isTagged() 424 */ 425 static boolean tagged(Environment e) { 426 return e.osm.isTagged(); 427 } 428 429 /** 430 * {@code :same-tags} tests whether the object has the same tags as its child/parent. 431 * @see OsmPrimitive#hasSameInterestingTags(OsmPrimitive) 432 */ 433 static boolean sameTags(Environment e) { 434 return e.osm.hasSameInterestingTags(Utils.firstNonNull(e.child, e.parent)); 435 } 436 437 /** 438 * {@code :area-style} tests whether the object has an area style. This is useful for validators. 439 * @see ElemStyles#hasAreaElemStyle(OsmPrimitive, boolean) 440 */ 441 static boolean areaStyle(Environment e) { 442 // only for validator 443 return ElemStyles.hasAreaElemStyle(e.osm, false); 444 } 445 446 /** 447 * {@code unconnected}: tests whether the object is a unconnected node. 448 */ 449 static boolean unconnected(Environment e) { 450 return e.osm instanceof Node && OsmPrimitive.getFilteredList(e.osm.getReferrers(), Way.class).isEmpty(); 451 } 452 453 /** 454 * {@code righthandtraffic} checks if there is right-hand traffic at the current location. 455 * @see ExpressionFactory.Functions#is_right_hand_traffic(Environment) 456 */ 457 static boolean righthandtraffic(Environment e) { 458 return ExpressionFactory.Functions.is_right_hand_traffic(e); 459 } 460 461 /** 462 * {@code unclosed-multipolygon} tests whether the object is an unclosed multipolygon. 463 */ 464 static boolean unclosed_multipolygon(Environment e) { 465 return e.osm instanceof Relation && ((Relation) e.osm).isMultipolygon() && 466 !e.osm.isIncomplete() && !((Relation) e.osm).hasIncompleteMembers() && 467 !MultipolygonCache.getInstance().get(Main.map.mapView, (Relation) e.osm).getOpenEnds().isEmpty(); 468 } 469 } 470 378 471 public static class PseudoClassCondition extends Condition { 379 472 380 public final String id;473 public final Method method; 381 474 public final boolean not; 382 475 383 p ublicPseudoClassCondition(String id, boolean not, Context context) {384 this. id = id;476 private PseudoClassCondition(Method method, boolean not) { 477 this.method = method; 385 478 this.not = not; 479 } 480 481 public static PseudoClassCondition createPseudoClassCondition(String id, boolean not, Context context) { 386 482 CheckParameterUtil.ensureThat(!"sameTags".equals(id) || Context.LINK.equals(context), "sameTags only supported in LINK context"); 483 if ("open_end".equals(id)) { 484 return new OpenEndPseudoClassCondition(not); 485 } 486 final Method method = getMethod(id); 487 if (method != null) { 488 return new PseudoClassCondition(method, not); 489 } 490 throw new IllegalArgumentException("Invalid pseudo class specified: " + id); 491 492 } 493 494 protected static Method getMethod(String id) { 495 id = id.replaceAll("-|_", ""); 496 for (Method method : PseudoClasses.class.getDeclaredMethods()) { 497 // for backwards compatibility, consider :sameTags == :same-tags == :same_tags (#11150) 498 final String methodName = method.getName().replaceAll("-|_", ""); 499 if (methodName.equalsIgnoreCase(id)) { 500 return method; 501 } 502 } 503 return null; 387 504 } 388 505 389 506 @Override 390 507 public boolean applies(Environment e) { 391 return not ^ appliesImpl(e); 392 } 393 394 public boolean appliesImpl(Environment e) { 395 switch(id) { 396 case "closed": 397 if (e.osm instanceof Way && ((Way) e.osm).isClosed()) 398 return true; 399 if (e.osm instanceof Relation && ((Relation) e.osm).isMultipolygon()) 400 return true; 401 break; 402 case "modified": 403 return e.osm.isModified() || e.osm.isNewOrUndeleted(); 404 case "new": 405 return e.osm.isNew(); 406 case "connection": 407 return e.osm instanceof Node && ((Node) e.osm).isConnectionNode(); 408 case "tagged": 409 return e.osm.isTagged(); 410 case "sameTags": 411 return e.osm.hasSameInterestingTags(Utils.firstNonNull(e.child, e.parent)); 412 case "areaStyle": 413 // only for validator 414 return ElemStyles.hasAreaElemStyle(e.osm, false); 415 case "unconnected": 416 return e.osm instanceof Node && OsmPrimitive.getFilteredList(e.osm.getReferrers(), Way.class).isEmpty(); 417 case "righthandtraffic": 418 return ExpressionFactory.Functions.is_right_hand_traffic(e); 419 case "unclosed_multipolygon": 420 return e.osm instanceof Relation && ((Relation) e.osm).isMultipolygon() && 421 !e.osm.isIncomplete() && !((Relation) e.osm).hasIncompleteMembers() && 422 !MultipolygonCache.getInstance().get(Main.map.mapView, (Relation) e.osm).getOpenEnds().isEmpty(); 423 case "open_end": 424 // handling at org.openstreetmap.josm.gui.mappaint.mapcss.Selector.ChildOrParentSelector.MultipolygonOpenEndFinder 425 return true; 426 } 427 return false; 508 try { 509 return not ^ (Boolean) method.invoke(null, e); 510 } catch (IllegalAccessException | InvocationTargetException ex) { 511 throw new RuntimeException(ex); 512 } 428 513 } 429 514 430 515 @Override 431 516 public String toString() { 432 return ":" + (not ? "!" : "") + id; 517 return (not ? "!" : "") + ":" + method.getName(); 518 } 519 } 520 521 public static class OpenEndPseudoClassCondition extends PseudoClassCondition { 522 public OpenEndPseudoClassCondition(boolean not) { 523 super(null, not); 524 } 525 526 @Override 527 public boolean applies(Environment e) { 528 return true; 433 529 } 434 530 } -
trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java
r8415 r8494 369 369 } else if (ChildOrParentSelectorType.CHILD.equals(type) 370 370 && link.conds != null && !link.conds.isEmpty() 371 && link.conds.get(0) instanceof Condition.PseudoClassCondition 372 && "open_end".equals(((Condition.PseudoClassCondition) link.conds.get(0)).id)) { 371 && link.conds.get(0) instanceof Condition.OpenEndPseudoClassCondition) { 373 372 if (e.osm instanceof Node) { 374 373 e.osm.visitReferrers(new MultipolygonOpenEndFinder(e));
Note:
See TracChangeset
for help on using the changeset viewer.