Changeset 4431 in josm


Ignore:
Timestamp:
17.09.2011 10:59:32 (8 months ago)
Author:
jttt
Message:

Custom primitive name formatters via tagging presets

Location:
trunk
Files:
1 added
17 edited

Legend:

Unmodified
Added
Removed
  • trunk/data/tagging-preset.xsd

    r4218 r4431  
    44        elementFormDefault="qualified"> 
    55 
    6         <!-- Localized attributes (for example de.description are not supported  
    7                 by xsd, so every element needs <anyAttribute/> To cover at least some common  
     6        <!-- Localized attributes (for example de.description are not supported 
     7                by xsd, so every element needs <anyAttribute/> To cover at least some common 
    88                errors, elements have specified prohibited attributes --> 
    99 
     
    6262                <attribute name="icon" type="string" /> 
    6363                <attribute name="type" type="string" /> 
     64                <attribute name="name_template" type="string"/> 
     65                <attribute name="name_template_filter" type="string"/> 
    6466 
    6567                <attribute name="text" use="prohibited" /> 
  • trunk/src/org/openstreetmap/josm/data/gpx/WayPoint.java

    r4282 r4431  
    7474    /** 
    7575     * <p>Replies the projected east/north coordinates.</p> 
    76      *  
     76     * 
    7777     * <p>Uses the {@link Main#getProjection() global projection} to project the lan/lon-coordinates. 
    7878     * Internally caches the projected coordinates.</p> 
     
    8080     * <p><strong>Caveat:</strong> doesn't listen to projection changes. Clients must 
    8181     * {@link #reproject() trigger a reprojection} or {@link #invalidateEastNorthCache() invalidate the internal cache}.</p> 
    82      *  
     82     * 
    8383     * @return the east north coordinates or {@code null} 
    8484     * @see #invalidateEastNorthCache() 
    85      *  
     85     * 
    8686     */ 
    8787    public final EastNorth getEastNorth() { 
     
    123123 
    124124    @Override 
    125     public Object getTemplateValue(String name) { 
    126         return attr.get(name); 
     125    public Object getTemplateValue(String name, boolean special) { 
     126        if (!special) 
     127            return attr.get(name); 
     128        else 
     129            return null; 
    127130    } 
    128131 
  • trunk/src/org/openstreetmap/josm/data/osm/AbstractPrimitive.java

    r4150 r4431  
    1717 
    1818public abstract class AbstractPrimitive implements IPrimitive { 
    19      
     19 
    2020    private static final AtomicLong idCounter = new AtomicLong(0); 
    2121 
     
    305305        } 
    306306    } 
    307      
     307 
    308308    /** 
    309309     * Marks this primitive as being modified. 
     
    373373        return (flags & FLAG_VISIBLE) != 0; 
    374374    } 
    375      
     375 
    376376    /** 
    377377     * Sets whether this primitive is visible, i.e. whether it is known on the server 
     
    414414        return (flags & FLAG_INCOMPLETE) != 0; 
    415415    } 
    416      
     416 
    417417    protected String getFlagsAsString() { 
    418418        StringBuilder builder = new StringBuilder(); 
     
    528528        } 
    529529    } 
    530      
     530 
    531531    /** 
    532532     * Remove the given key from the list 
     
    589589    } 
    590590 
     591    public final String getIgnoreCase(String key) { 
     592        String[] keys = this.keys; 
     593        if (key == null) 
     594            return null; 
     595        if (keys == null) 
     596            return null; 
     597        for (int i=0; i<keys.length;i+=2) { 
     598            if (keys[i].equalsIgnoreCase(key)) return keys[i+1]; 
     599        } 
     600        return null; 
     601    } 
     602 
    591603    @Override 
    592604    public final Collection<String> keySet() { 
     
    642654     */ 
    643655    abstract protected void keysChangedImpl(Map<String, String> originalKeys); 
    644      
     656 
    645657    /** 
    646658     * Replies the name of this primitive. The default implementation replies the value 
     
    680692        return getName(); 
    681693    } 
    682      
    683     /** 
    684      * Replies the display name of a primitive formatted by <code>formatter</code> 
    685      * 
    686      * @return the display name 
    687      */ 
    688     @Override 
    689     public abstract String getDisplayName(NameFormatter formatter); 
    690694 
    691695} 
  • trunk/src/org/openstreetmap/josm/data/osm/IPrimitive.java

    r4100 r4431  
    3030    int getChangesetId(); 
    3131    void setChangesetId(int changesetId); 
    32      
     32 
    3333    void visit(PrimitiveVisitor visitor); 
    3434    String getName(); 
    3535    String getLocalName(); 
    36     String getDisplayName(NameFormatter formatter); 
    3736 
    3837} 
  • trunk/src/org/openstreetmap/josm/data/osm/NameFormatter.java

    r4100 r4431  
    55 
    66public interface NameFormatter { 
    7     String format(INode node); 
    8     String format(IWay way); 
    9     String format(IRelation relation); 
     7    String format(Node node); 
     8    String format(Way way); 
     9    String format(Relation relation); 
    1010    String format(Changeset changeset); 
    1111 
  • trunk/src/org/openstreetmap/josm/data/osm/NodeData.java

    r4126 r4431  
    2525        return lat != Double.NaN && lon != Double.NaN; 
    2626    } 
    27      
     27 
    2828    @Override 
    2929    public LatLon getCoor() { 
     
    7777    } 
    7878 
    79     @Override 
    80     public String getDisplayName(NameFormatter formatter) { 
    81         return formatter.format(this); 
    82     } 
    8379} 
  • trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java

    r4103 r4431  
    2525import org.openstreetmap.josm.tools.CheckParameterUtil; 
    2626import org.openstreetmap.josm.tools.Predicate; 
     27import org.openstreetmap.josm.tools.template_engine.TemplateEngineDataProvider; 
    2728 
    2829/** 
     
    3637 * @author imi 
    3738 */ 
    38 abstract public class OsmPrimitive extends AbstractPrimitive implements Comparable<OsmPrimitive> { 
     39abstract public class OsmPrimitive extends AbstractPrimitive implements Comparable<OsmPrimitive>, TemplateEngineDataProvider { 
     40    private static final String SPECIAL_VALUE_ID = "id"; 
     41    private static final String SPECIAL_VALUE_LOCAL_NAME = "localname"; 
     42 
    3943 
    4044    /** 
     
    412416        super.updateFlags(flag, value); 
    413417    } 
    414      
     418 
    415419    @Override 
    416420    protected final void updateFlags(int flag, boolean value) { 
     
    621625 
    622626        String directionDefault = "oneway? | incline=* | aerialway=* | "+ 
    623         "waterway=stream | waterway=river | waterway=canal | waterway=drain | waterway=rapids | "+ 
    624         "\"piste:type\"=downhill | \"piste:type\"=sled | man_made=\"piste:halfpipe\" | "+ 
    625         "junction=roundabout"; 
     627                "waterway=stream | waterway=river | waterway=canal | waterway=drain | waterway=rapids | "+ 
     628                "\"piste:type\"=downhill | \"piste:type\"=sled | man_made=\"piste:halfpipe\" | "+ 
     629                "junction=roundabout"; 
    626630 
    627631        try { 
     
    700704     * Keys handling 
    701705     ------------*/ 
    702      
     706 
    703707    @Override 
    704708    public final void setKeys(Map<String, String> keys) { 
     
    710714        } 
    711715    } 
    712      
     716 
    713717    @Override 
    714718    public final void put(String key, String value) { 
     
    719723            writeUnlock(locked); 
    720724        } 
    721     }   
    722      
     725    } 
     726 
    723727    @Override 
    724728    public final void remove(String key) { 
     
    739743            writeUnlock(locked); 
    740744        } 
    741     }   
    742      
     745    } 
     746 
    743747    @Override 
    744748    protected final void keysChangedImpl(Map<String, String> originalKeys) { 
     
    857861    /** 
    858862     * <p>Visits {@code visitor} for all referrers.</p> 
    859      *  
     863     * 
    860864     * @param visitor the visitor. Ignored, if null. 
    861865     */ 
     
    889893        if (referrers == null) return false; 
    890894        checkDataset(); 
    891         if (referrers instanceof OsmPrimitive) { 
    892           return n<=1 && referrers instanceof Way && ((OsmPrimitive)referrers).dataSet == dataSet; 
    893         } else { 
    894           int counter=0; 
    895           for (OsmPrimitive o : (OsmPrimitive[])referrers) { 
    896             if (dataSet == o.dataSet && o instanceof Way) { 
    897               if (++counter >= n)  
    898                 return true; 
    899             } 
    900           } 
    901           return false; 
     895        if (referrers instanceof OsmPrimitive) 
     896            return n<=1 && referrers instanceof Way && ((OsmPrimitive)referrers).dataSet == dataSet; 
     897        else { 
     898            int counter=0; 
     899            for (OsmPrimitive o : (OsmPrimitive[])referrers) { 
     900                if (dataSet == o.dataSet && o instanceof Way) { 
     901                    if (++counter >= n) 
     902                        return true; 
     903                } 
     904            } 
     905            return false; 
    902906        } 
    903907    } 
     
    10021006 
    10031007        return 
    1004         isDeleted() == other.isDeleted() 
    1005         && isModified() == other.isModified() 
    1006         && timestamp == other.timestamp 
    1007         && version == other.version 
    1008         && isVisible() == other.isVisible() 
    1009         && (user == null ? other.user==null : user==other.user) 
    1010         && changesetId == other.changesetId; 
     1008                isDeleted() == other.isDeleted() 
     1009                && isModified() == other.isModified() 
     1010                && timestamp == other.timestamp 
     1011                && version == other.version 
     1012                && isVisible() == other.isVisible() 
     1013                && (user == null ? other.user==null : user==other.user) 
     1014                && changesetId == other.changesetId; 
    10111015    } 
    10121016 
     
    11011105    } 
    11021106 
     1107    /** 
     1108     * Replies the display name of a primitive formatted by <code>formatter</code> 
     1109     * 
     1110     * @return the display name 
     1111     */ 
     1112    public abstract String getDisplayName(NameFormatter formatter); 
     1113 
     1114    @Override 
     1115    public Collection<String> getTemplateKeys() { 
     1116        Collection<String> keySet = keySet(); 
     1117        List<String> result = new ArrayList<String>(keySet.size() + 2); 
     1118        result.add(SPECIAL_VALUE_ID); 
     1119        result.add(SPECIAL_VALUE_LOCAL_NAME); 
     1120        result.addAll(keySet); 
     1121        return result; 
     1122    } 
     1123 
     1124    @Override 
     1125    public Object getTemplateValue(String name, boolean special) { 
     1126        if (special) { 
     1127            String lc = name.toLowerCase(); 
     1128            if (SPECIAL_VALUE_ID.equals(lc)) 
     1129                return getId(); 
     1130            else if (SPECIAL_VALUE_LOCAL_NAME.equals(lc)) 
     1131                return getLocalName(); 
     1132            else 
     1133                return null; 
     1134 
     1135        } else 
     1136            return getIgnoreCase(name); 
     1137    } 
     1138 
     1139    @Override 
     1140    public boolean evaluateCondition(Match condition) { 
     1141        return condition.match(this); 
     1142    } 
     1143 
    11031144} 
  • trunk/src/org/openstreetmap/josm/data/osm/RelationData.java

    r4100 r4431  
    6262        return OsmPrimitiveType.RELATION; 
    6363    } 
    64      
    65     @Override  
     64 
     65    @Override 
    6666    public void visit(PrimitiveVisitor visitor) { 
    6767        visitor.visit(this); 
    6868    } 
    6969 
    70     @Override 
    71     public String getDisplayName(NameFormatter formatter) { 
    72         return formatter.format(this); 
    73     } 
    74  
    7570} 
  • trunk/src/org/openstreetmap/josm/data/osm/Way.java

    r4321 r4431  
    162162        visitor.visit(this); 
    163163    } 
    164      
     164 
    165165    @Override public void visit(PrimitiveVisitor visitor) { 
    166166        visitor.visit(this); 
     
    453453 
    454454 
    455     @Override 
    456455    public String getDisplayName(NameFormatter formatter) { 
    457456        return formatter.format(this); 
  • trunk/src/org/openstreetmap/josm/data/osm/WayData.java

    r4100 r4431  
    44import java.util.ArrayList; 
    55import java.util.List; 
     6 
    67import org.openstreetmap.josm.data.osm.visitor.PrimitiveVisitor; 
    78 
     
    5758        return OsmPrimitiveType.WAY; 
    5859    } 
    59      
    60     @Override  
     60 
     61    @Override 
    6162    public void visit(PrimitiveVisitor visitor) { 
    6263        visitor.visit(this); 
    6364    } 
    6465 
    65     @Override 
    66     public String getDisplayName(NameFormatter formatter) { 
    67         return formatter.format(this); 
    68     } 
    69  
    7066} 
  • trunk/src/org/openstreetmap/josm/gui/DefaultNameFormatter.java

    r4324 r4431  
    1919import org.openstreetmap.josm.data.coor.CoordinateFormat; 
    2020import org.openstreetmap.josm.data.osm.Changeset; 
    21 import org.openstreetmap.josm.data.osm.INode; 
    2221import org.openstreetmap.josm.data.osm.IPrimitive; 
    2322import org.openstreetmap.josm.data.osm.IRelation; 
    24 import org.openstreetmap.josm.data.osm.IWay; 
    2523import org.openstreetmap.josm.data.osm.NameFormatter; 
    2624import org.openstreetmap.josm.data.osm.Node; 
    27 import org.openstreetmap.josm.data.osm.OsmPrimitive; 
    2825import org.openstreetmap.josm.data.osm.OsmUtils; 
    2926import org.openstreetmap.josm.data.osm.Relation; 
    30 import org.openstreetmap.josm.data.osm.RelationMember; 
    3127import org.openstreetmap.josm.data.osm.Way; 
    3228import org.openstreetmap.josm.data.osm.history.HistoryNameFormatter; 
     
    3531import org.openstreetmap.josm.data.osm.history.HistoryRelation; 
    3632import org.openstreetmap.josm.data.osm.history.HistoryWay; 
     33import org.openstreetmap.josm.gui.tagging.TaggingPreset; 
     34import org.openstreetmap.josm.tools.TaggingPresetNameTemplateList; 
    3735 
    3836/** 
     
    5755        return instance; 
    5856    } 
    59      
     57 
    6058    /** 
    6159     * Registers a format hook. Adds the hook at the first position of the format hooks. 
     
    103101            namingTagsForRelations = new ArrayList<String>( 
    104102                    Main.pref.getCollection("relation.nameOrder", Arrays.asList(DEFAULT_NAMING_TAGS_FOR_RELATIONS)) 
    105             ); 
     103                    ); 
    106104        } 
    107105        return namingTagsForRelations; 
     
    116114     * @return the decorated name 
    117115     */ 
    118     protected String decorateNameWithId(String name, IPrimitive primitive) { 
    119         if (Main.pref.getBoolean("osm-primitives.showid")) 
    120             if (Main.pref.getBoolean("osm-primitives.showid.new-primitives")) 
    121                 return name + tr(" [id: {0}]", primitive.getUniqueId()); 
    122             else 
    123                 return name + tr(" [id: {0}]", primitive.getId()); 
    124         else 
    125             return name; 
     116    protected void decorateNameWithId(StringBuilder name, IPrimitive primitive) { 
     117        if (Main.pref.getBoolean("osm-primitives.showid")) { 
     118            if (Main.pref.getBoolean("osm-primitives.showid.new-primitives")) { 
     119                name.append(tr(" [id: {0}]", primitive.getUniqueId())); 
     120            } else { 
     121                name.append(tr(" [id: {0}]", primitive.getId())); 
     122            } 
     123        } 
    126124    } 
    127125 
     
    132130     * @return the name 
    133131     */ 
    134     public String format(INode node) { 
    135         String name = ""; 
     132    public String format(Node node) { 
     133        StringBuilder name = new StringBuilder(); 
    136134        if (node.isIncomplete()) { 
    137             name = tr("incomplete"); 
    138         } else { 
    139             if (Main.pref.getBoolean("osm-primitives.localize-name", true)) { 
    140                 name = node.getLocalName(); 
     135            name.append(tr("incomplete")); 
     136        } else { 
     137            TaggingPreset preset = TaggingPresetNameTemplateList.getInstance().findPresetTemplate(node); 
     138            if (preset == null) { 
     139                String n; 
     140                if (Main.pref.getBoolean("osm-primitives.localize-name", true)) { 
     141                    n = node.getLocalName(); 
     142                } else { 
     143                    n = node.getName(); 
     144                } 
     145                if(n == null) 
     146                { 
     147                    String s; 
     148                    if((s = node.get("addr:housename")) != null) { 
     149                        /* I18n: name of house as parameter */ 
     150                        n = tr("House {0}", s); 
     151                    } 
     152                    if(n == null && (s = node.get("addr:housenumber")) != null) { 
     153                        String t = node.get("addr:street"); 
     154                        if(t != null) { 
     155                            /* I18n: house number, street as parameter, number should remain 
     156                        before street for better visibility */ 
     157                            n =  tr("House number {0} at {1}", s, t); 
     158                        } 
     159                        else { 
     160                            /* I18n: house number as parameter */ 
     161                            n = tr("House number {0}", s); 
     162                        } 
     163                    } 
     164                } 
     165 
     166                if (n == null) { 
     167                    n = node.isNew() ? tr("node") : ""+ node.getId(); 
     168                } 
     169                name.append(n); 
    141170            } else { 
    142                 name = node.getName(); 
    143             } 
    144             if(name == null) 
    145             { 
    146                 String s; 
    147                 if((s = node.get("addr:housename")) != null) { 
    148                     /* I18n: name of house as parameter */ 
    149                     name = tr("House {0}", s); 
    150                 } 
    151                 if(name == null && (s = node.get("addr:housenumber")) != null) { 
    152                     String t = node.get("addr:street"); 
    153                     if(t != null) { 
    154                         /* I18n: house number, street as parameter, number should remain 
    155                         before street for better visibility */ 
    156                         name =  tr("House number {0} at {1}", s, t); 
    157                     } 
    158                     else { 
    159                         /* I18n: house number as parameter */ 
    160                         name = tr("House number {0}", s); 
    161                     } 
    162                 } 
    163             } 
    164  
    165             if (name == null) { 
    166                 name = node.isNew() ? tr("node") : ""+ node.getId(); 
    167             } 
    168             name += " \u200E(" + node.getCoor().latToString(CoordinateFormat.getDefaultFormat()) + ", " + node.getCoor().lonToString(CoordinateFormat.getDefaultFormat()) + ")"; 
    169         } 
    170         name = decorateNameWithId(name, node); 
    171  
     171                preset.nameTemplate.appendText(name, node); 
     172            } 
     173            name.append(" \u200E(").append(node.getCoor().latToString(CoordinateFormat.getDefaultFormat())).append(", ").append(node.getCoor().lonToString(CoordinateFormat.getDefaultFormat())).append(")"); 
     174        } 
     175        decorateNameWithId(name, node); 
     176 
     177 
     178        String result = name.toString(); 
    172179        for (NameFormatterHook hook: formatHooks) { 
    173             String hookResult = hook.checkFormat(node, name); 
    174             if (hookResult != null) { 
     180            String hookResult = hook.checkFormat(node, result); 
     181            if (hookResult != null) 
    175182                return hookResult; 
    176             } 
    177         } 
    178  
    179         return name; 
     183        } 
     184 
     185        return result; 
    180186    } 
    181187 
     
    198204     * @return the name 
    199205     */ 
    200     public String format(IWay way) { 
    201         String name = ""; 
     206    public String format(Way way) { 
     207        StringBuilder name = new StringBuilder(); 
    202208        if (way.isIncomplete()) { 
    203             name = tr("incomplete"); 
    204         } else { 
    205             if (Main.pref.getBoolean("osm-primitives.localize-name", true)) { 
    206                 name = way.getLocalName(); 
     209            name.append(tr("incomplete")); 
     210        } else { 
     211            TaggingPreset preset = TaggingPresetNameTemplateList.getInstance().findPresetTemplate(way); 
     212            if (preset == null) { 
     213                String n; 
     214                if (Main.pref.getBoolean("osm-primitives.localize-name", true)) { 
     215                    n = way.getLocalName(); 
     216                } else { 
     217                    n = way.getName(); 
     218                } 
     219                if (n == null) { 
     220                    n = way.get("ref"); 
     221                } 
     222                if (n == null) { 
     223                    n = 
     224                            (way.get("highway") != null) ? tr("highway") : 
     225                                (way.get("railway") != null) ? tr("railway") : 
     226                                    (way.get("waterway") != null) ? tr("waterway") : 
     227                                        (way.get("landuse") != null) ? tr("landuse") : null; 
     228                } 
     229                if(n == null) 
     230                { 
     231                    String s; 
     232                    if((s = way.get("addr:housename")) != null) { 
     233                        /* I18n: name of house as parameter */ 
     234                        n = tr("House {0}", s); 
     235                    } 
     236                    if(n == null && (s = way.get("addr:housenumber")) != null) { 
     237                        String t = way.get("addr:street"); 
     238                        if(t != null) { 
     239                            /* I18n: house number, street as parameter, number should remain 
     240                        before street for better visibility */ 
     241                            n =  tr("House number {0} at {1}", s, t); 
     242                        } 
     243                        else { 
     244                            /* I18n: house number as parameter */ 
     245                            n = tr("House number {0}", s); 
     246                        } 
     247                    } 
     248                } 
     249                if(n == null || n.length() == 0) { 
     250                    n = String.valueOf(way.getId()); 
     251                } 
     252 
     253                name.append(n); 
    207254            } else { 
    208                 name = way.getName(); 
    209             } 
    210             if (name == null) { 
    211                 name = way.get("ref"); 
    212             } 
    213             if (name == null) { 
    214                 name = 
    215                     (way.get("highway") != null) ? tr("highway") : 
    216                         (way.get("railway") != null) ? tr("railway") : 
    217                             (way.get("waterway") != null) ? tr("waterway") : 
    218                                 (way.get("landuse") != null) ? tr("landuse") : null; 
    219             } 
    220             if(name == null) 
    221             { 
    222                 String s; 
    223                 if((s = way.get("addr:housename")) != null) { 
    224                     /* I18n: name of house as parameter */ 
    225                     name = tr("House {0}", s); 
    226                 } 
    227                 if(name == null && (s = way.get("addr:housenumber")) != null) { 
    228                     String t = way.get("addr:street"); 
    229                     if(t != null) { 
    230                         /* I18n: house number, street as parameter, number should remain 
    231                         before street for better visibility */ 
    232                         name =  tr("House number {0} at {1}", s, t); 
    233                     } 
    234                     else { 
    235                         /* I18n: house number as parameter */ 
    236                         name = tr("House number {0}", s); 
    237                     } 
    238                 } 
     255                preset.nameTemplate.appendText(name, way); 
    239256            } 
    240257 
     
    242259            if (nodesNo > 1 && way.isClosed()) { 
    243260                nodesNo--; 
    244             } 
    245             if(name == null || name.length() == 0) { 
    246                 name = String.valueOf(way.getId()); 
    247261            } 
    248262            /* note: length == 0 should no longer happen, but leave the bracket code 
     
    250264            /* I18n: count of nodes as parameter */ 
    251265            String nodes = trn("{0} node", "{0} nodes", nodesNo, nodesNo); 
    252             name += (name.length() > 0) ? " ("+nodes+")" : nodes; 
    253         } 
    254         name = decorateNameWithId(name, way); 
    255          
     266            name.append(" (").append(nodes).append(")"); 
     267        } 
     268        decorateNameWithId(name, way); 
     269 
     270        String result = name.toString(); 
    256271        for (NameFormatterHook hook: formatHooks) { 
    257             String hookResult = hook.checkFormat(way, name); 
    258             if (hookResult != null) { 
     272            String hookResult = hook.checkFormat(way, result); 
     273            if (hookResult != null) 
    259274                return hookResult; 
    260             } 
    261         } 
    262  
    263         return name; 
     275        } 
     276 
     277        return result; 
    264278    } 
    265279 
     
    282296     * @return the name 
    283297     */ 
    284     public String format(IRelation relation) { 
    285         String name; 
     298    public String format(Relation relation) { 
     299        StringBuilder name = new StringBuilder(); 
    286300        if (relation.isIncomplete()) { 
    287             name = tr("incomplete"); 
    288         } else { 
    289             name = getRelationTypeName(relation); 
     301            name.append(tr("incomplete")); 
     302        } else { 
     303            TaggingPreset preset = TaggingPresetNameTemplateList.getInstance().findPresetTemplate(relation); 
     304 
     305            formatRelationNameAndType(relation, name, preset); 
     306 
     307            int mbno = relation.getMembersCount(); 
     308            name.append(trn("{0} member", "{0} members", mbno, mbno)); 
     309 
     310            if (relation.hasIncompleteMembers()) { 
     311                name.append(", ").append(tr("incomplete")); 
     312            } 
     313 
     314            name.append(")"); 
     315        } 
     316        decorateNameWithId(name, relation); 
     317 
     318        String result = name.toString(); 
     319        for (NameFormatterHook hook: formatHooks) { 
     320            String hookResult = hook.checkFormat(relation, result); 
     321            if (hookResult != null) 
     322                return hookResult; 
     323        } 
     324 
     325        return result; 
     326    } 
     327 
     328    private void formatRelationNameAndType(Relation relation, StringBuilder result, TaggingPreset preset) { 
     329        if (preset == null) { 
     330            result.append(getRelationTypeName(relation)); 
    290331            String relationName = getRelationName(relation); 
    291332            if (relationName == null) { 
     
    294335                relationName = "\"" + relationName + "\""; 
    295336            } 
    296             name += " (" + relationName + ", "; 
    297  
    298             int mbno = relation.getMembersCount(); 
    299             name += trn("{0} member", "{0} members", mbno, mbno); 
    300  
    301             if (relation instanceof Relation) { 
    302                 if (((Relation) relation).hasIncompleteMembers()) { 
    303                     name += ", "+tr("incomplete"); 
    304                 } 
    305             } 
    306  
    307             name += ")"; 
    308         } 
    309         name = decorateNameWithId(name, relation); 
    310  
    311         for (NameFormatterHook hook: formatHooks) { 
    312             String hookResult = hook.checkFormat(relation, name); 
    313             if (hookResult != null) { 
    314                 return hookResult; 
    315             } 
    316         } 
    317  
    318         return name; 
     337            result.append(" (").append(relationName).append(", "); 
     338        } else { 
     339            preset.nameTemplate.appendText(result, relation); 
     340            result.append("("); 
     341        } 
    319342    } 
    320343 
     
    322345        @Override 
    323346        public int compare(Relation r1, Relation r2) { 
    324             String type1 = getRelationTypeName(r1); 
    325             String type2 = getRelationTypeName(r2); 
    326  
    327             int comp = type1.compareTo(type2); 
    328             if (comp != 0) 
    329                 return comp; 
    330  
    331             String name1 = getRelationName(r1); 
    332             String name2 = getRelationName(r2); 
    333  
    334             if (name1 == null && name2 == null) 
    335                 return (r1.getUniqueId() > r2.getUniqueId())?1:-1; 
    336             else if (name1 == null) 
    337                 return -1; 
    338             else if (name2 == null) 
    339                 return 1; 
    340             else if (!name1.isEmpty() && !name2.isEmpty() && Character.isDigit(name1.charAt(0)) && Character.isDigit(name2.charAt(0))) { 
    341                 //Compare numerically 
    342                 String ln1 = getLeadingNumber(name1); 
    343                 String ln2 = getLeadingNumber(name2); 
    344  
    345                 comp = Long.valueOf(ln1).compareTo(Long.valueOf(ln2)); 
    346                 if (comp != 0) 
    347                     return comp; 
    348  
    349                 // put 1 before 0001 
    350                 comp = ln1.compareTo(ln2); 
    351                 if (comp != 0) 
    352                     return comp; 
    353  
    354                 comp = name1.substring(ln1.length()).compareTo(name2.substring(ln2.length())); 
     347            //TODO This doesn't work correctly with formatHooks 
     348 
     349            TaggingPreset preset1 = TaggingPresetNameTemplateList.getInstance().findPresetTemplate(r1); 
     350            TaggingPreset preset2 = TaggingPresetNameTemplateList.getInstance().findPresetTemplate(r2); 
     351 
     352            if (preset1 != null || preset2 != null) { 
     353                StringBuilder name1 = new StringBuilder(); 
     354                formatRelationNameAndType(r1, name1, preset1); 
     355                StringBuilder name2 = new StringBuilder(); 
     356                formatRelationNameAndType(r2, name2, preset2); 
     357 
     358                int comp = name1.toString().compareTo(name2.toString()); 
    355359                if (comp != 0) 
    356360                    return comp; 
    357361            } else { 
    358                 comp = name1.compareToIgnoreCase(name2); 
     362 
     363                String type1 = getRelationTypeName(r1); 
     364                String type2 = getRelationTypeName(r2); 
     365 
     366                int comp = type1.compareTo(type2); 
    359367                if (comp != 0) 
    360368                    return comp; 
    361             } 
     369 
     370                String name1 = getRelationName(r1); 
     371                String name2 = getRelationName(r2); 
     372 
     373                if (name1 == null && name2 == null) 
     374                    return (r1.getUniqueId() > r2.getUniqueId())?1:-1; 
     375                else if (name1 == null) 
     376                    return -1; 
     377                else if (name2 == null) 
     378                    return 1; 
     379                else if (!name1.isEmpty() && !name2.isEmpty() && Character.isDigit(name1.charAt(0)) && Character.isDigit(name2.charAt(0))) { 
     380                    //Compare numerically 
     381                    String ln1 = getLeadingNumber(name1); 
     382                    String ln2 = getLeadingNumber(name2); 
     383 
     384                    comp = Long.valueOf(ln1).compareTo(Long.valueOf(ln2)); 
     385                    if (comp != 0) 
     386                        return comp; 
     387 
     388                    // put 1 before 0001 
     389                    comp = ln1.compareTo(ln2); 
     390                    if (comp != 0) 
     391                        return comp; 
     392 
     393                    comp = name1.substring(ln1.length()).compareTo(name2.substring(ln2.length())); 
     394                    if (comp != 0) 
     395                        return comp; 
     396                } else { 
     397                    comp = name1.compareToIgnoreCase(name2); 
     398                    if (comp != 0) 
     399                        return comp; 
     400                } 
     401            } 
     402 
    362403 
    363404            if (r1.getMembersCount() != r2.getMembersCount()) 
    364405                return (r1.getMembersCount() > r2.getMembersCount())?1:-1; 
    365406 
    366             comp = Boolean.valueOf(r1.hasIncompleteMembers()).compareTo(Boolean.valueOf(r2.hasIncompleteMembers())); 
     407            int comp = Boolean.valueOf(r1.hasIncompleteMembers()).compareTo(Boolean.valueOf(r2.hasIncompleteMembers())); 
    367408            if (comp != 0) 
    368409                return comp; 
     
    408449            name += "["+admin_level+"]"; 
    409450        } 
    410          
     451 
    411452        for (NameFormatterHook hook: formatHooks) { 
    412453            String hookResult = hook.checkRelationTypeName(relation, name); 
    413             if (hookResult != null) { 
     454            if (hookResult != null) 
    414455                return hookResult; 
    415             } 
    416456        } 
    417457 
     
    562602                            (way.get("waterway") != null) ? tr("waterway") : 
    563603                                (way.get("landuse") != null) ? tr("landuse") : "" 
    564             ); 
     604                    ); 
    565605        } 
    566606 
  • trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/Marker.java

    r4283 r4431  
    378378 
    379379    @Override 
    380     public List<String> getTemplateKeys() { 
    381         List<String> result; 
     380    public Collection<String> getTemplateKeys() { 
     381        Collection<String> result; 
    382382        if (dataProvider != null) { 
    383383            result = dataProvider.getTemplateKeys(); 
     
    401401 
    402402    @Override 
    403     public Object getTemplateValue(String name) { 
     403    public Object getTemplateValue(String name, boolean special) { 
    404404        if (MARKER_FORMATTED_OFFSET.equals(name)) 
    405405            return formatOffset(); 
     
    407407            return offset; 
    408408        else if (dataProvider != null) 
    409             return dataProvider.getTemplateValue(name); 
     409            return dataProvider.getTemplateValue(name, special); 
    410410        else 
    411411            return null; 
  • trunk/src/org/openstreetmap/josm/gui/preferences/GPXSettingsPanel.java

    r4287 r4431  
    3333    private static final int WAYPOINT_LABEL_CUSTOM = 6; 
    3434    private static final String[] LABEL_PATTERN_TEMPLATE = new String[] {Marker.LABEL_PATTERN_AUTO, Marker.LABEL_PATTERN_NAME, 
    35         Marker.LABEL_PATTERN_DESC, "{*}", "?{ '{name}' | '{desc}' | '{formattedWaypointOffset}' }", ""}; 
     35        Marker.LABEL_PATTERN_DESC, "{special:everything}", "?{ '{name}' | '{desc}' | '{formattedWaypointOffset}' }", ""}; 
    3636    private static final String[] LABEL_PATTERN_DESC = new String[] {tr("Auto"), /* gpx data field name */ trc("gpx_field", "Name"), 
    3737        /* gpx data field name */ trc("gpx_field", "Desc(ription)"), tr("Everything"), tr("Name or offset"), tr("None"), tr("Custom")}; 
  • trunk/src/org/openstreetmap/josm/gui/tagging/TaggingPreset.java

    r4340 r4431  
    4747 
    4848import org.openstreetmap.josm.Main; 
     49import org.openstreetmap.josm.actions.search.SearchCompiler; 
     50import org.openstreetmap.josm.actions.search.SearchCompiler.Match; 
    4951import org.openstreetmap.josm.command.ChangePropertyCommand; 
    5052import org.openstreetmap.josm.command.Command; 
     
    7678import org.openstreetmap.josm.tools.UrlLabel; 
    7779import org.openstreetmap.josm.tools.XmlObjectParser; 
     80import org.openstreetmap.josm.tools.template_engine.ParseError; 
     81import org.openstreetmap.josm.tools.template_engine.TemplateEntry; 
     82import org.openstreetmap.josm.tools.template_engine.TemplateParser; 
    7883import org.xml.sax.SAXException; 
    7984 
     
    121126        protected void initAutoCompletionField(AutoCompletingTextField field, String key) { 
    122127            OsmDataLayer layer = Main.main.getEditLayer(); 
    123             if (layer == null) { 
     128            if (layer == null) 
    124129                return; 
    125             } 
    126130            AutoCompletionList list = new AutoCompletionList(); 
    127131            Main.main.getEditLayer().data.getAutoCompletionManager().populateWithTagValues(list, key); 
     
    303307            String v = (value instanceof JComboBox) 
    304308                    ? ((JComboBox) value).getEditor().getItem().toString() 
    305                     : ((JTextField) value).getText(); 
    306             v = v.trim(); 
    307  
    308             if (!"false".equals(use_last_as_default)) { 
    309                 lastValue.put(key, v); 
    310             } 
    311             if (v.equals(originalValue) || (originalValue == null && v.length() == 0)) { 
    312                 return; 
    313             } 
    314  
    315             if (delete_if_empty && v.length() == 0) { 
    316                 v = null; 
    317             } 
    318             changedTags.add(new Tag(key, v)); 
     309                            : ((JTextField) value).getText(); 
     310                    v = v.trim(); 
     311 
     312                    if (!"false".equals(use_last_as_default)) { 
     313                        lastValue.put(key, v); 
     314                    } 
     315                    if (v.equals(originalValue) || (originalValue == null && v.length() == 0)) 
     316                        return; 
     317 
     318                    if (delete_if_empty && v.length() == 0) { 
     319                        v = null; 
     320                    } 
     321                    changedTags.add(new Tag(key, v)); 
    319322        } 
    320323 
     
    491494                e.display_value = (locale_display_values == null) 
    492495                        ? (values_context == null ? tr(fixPresetString(display_array[i])) 
    493                         : trc(values_context, fixPresetString(display_array[i]))) : display_array[i]; 
    494                 if (short_descriptions_array != null) { 
    495                     e.short_description = locale_short_descriptions == null ? tr(fixPresetString(short_descriptions_array[i])) 
    496                             : fixPresetString(short_descriptions_array[i]); 
    497                 } 
    498                 lhm.put(value_array[i], e); 
     496                                : trc(values_context, fixPresetString(display_array[i]))) : display_array[i]; 
     497                        if (short_descriptions_array != null) { 
     498                            e.short_description = locale_short_descriptions == null ? tr(fixPresetString(short_descriptions_array[i])) 
     499                                    : fixPresetString(short_descriptions_array[i]); 
     500                        } 
     501                        lhm.put(value_array[i], e); 
    499502            } 
    500503 
     
    544547            // no change if same as before 
    545548            if (originalValue == null) { 
    546                 if (value.length() == 0) { 
     549                if (value.length() == 0) 
    547550                    return; 
    548                 } 
    549             } else if (value.equals(originalValue.toString())) { 
     551            } else if (value.equals(originalValue.toString())) 
    550552                return; 
    551             } 
    552553 
    553554            if (delete_if_empty && value.length() == 0) { 
     
    676677        @Override 
    677678        protected String getDisplayIfNull(String display) { 
    678             if (combo.isEditable()) { 
     679            if (combo.isEditable()) 
    679680                return combo.getEditor().getItem().toString(); 
    680             } else { 
     681            else 
    681682                return display; 
    682             } 
    683683 
    684684        } 
     
    10081008    public EnumSet<PresetType> types; 
    10091009    public List<Item> data = new LinkedList<Item>(); 
     1010    public TemplateEntry nameTemplate; 
     1011    public Match nameTemplateFilter; 
    10101012    private static HashMap<String,String> lastValue = new HashMap<String,String>(); 
    10111013 
     
    10881090        this.types = getType(types); 
    10891091    } 
     1092 
     1093    public void setName_template(String pattern) throws SAXException { 
     1094        try { 
     1095            this.nameTemplate = new TemplateParser(pattern).parse(); 
     1096        } catch (ParseError e) { 
     1097            System.err.println("Error while parsing " + pattern + ": " + e.getMessage()); 
     1098            throw new SAXException(e); 
     1099        } 
     1100    } 
     1101 
     1102    public void setName_template_filter(String filter) throws SAXException { 
     1103        try { 
     1104            this.nameTemplateFilter = SearchCompiler.compile(filter, false, false); 
     1105        } catch (org.openstreetmap.josm.actions.search.SearchCompiler.ParseError e) { 
     1106            System.err.println("Error while parsing" + filter + ": " + e.getMessage()); 
     1107            throw new SAXException(e); 
     1108        } 
     1109    } 
     1110 
    10901111 
    10911112    public static List<TaggingPreset> readAll(Reader in, boolean validate) throws SAXException { 
     
    11991220                        tr("Error"), 
    12001221                        JOptionPane.ERROR_MESSAGE 
    1201                 ); 
     1222                        ); 
    12021223            } catch (SAXException e) { 
    12031224                System.err.println(e.getMessage()); 
     
    12091230                        tr("Error"), 
    12101231                        JOptionPane.ERROR_MESSAGE 
    1211                 ); 
     1232                        ); 
    12121233            } 
    12131234            zipIcons = null; 
  • trunk/src/org/openstreetmap/josm/tools/template_engine/TemplateEngineDataProvider.java

    r4282 r4431  
    22package org.openstreetmap.josm.tools.template_engine; 
    33 
    4 import java.util.List; 
     4import java.util.Collection; 
    55 
    66import org.openstreetmap.josm.actions.search.SearchCompiler.Match; 
    77 
    88public interface TemplateEngineDataProvider { 
    9     List<String> getTemplateKeys(); 
    10     Object getTemplateValue(String name); 
     9    Collection<String> getTemplateKeys(); 
     10    Object getTemplateValue(String name, boolean special); 
    1111    boolean evaluateCondition(Match condition); 
    1212} 
  • trunk/src/org/openstreetmap/josm/tools/template_engine/Variable.java

    r4282 r4431  
    22package org.openstreetmap.josm.tools.template_engine; 
    33 
    4 import java.util.List; 
     4import java.util.Collection; 
    55 
    66 
    77public class Variable implements TemplateEntry { 
    88 
     9    private static final String SPECIAL_VARIABLE_PREFIX = "special:"; 
     10    private static final String SPECIAL_VALUE_EVERYTHING = "everything"; 
     11 
     12 
    913    private final String variableName; 
     14    private final boolean special; 
    1015 
    1116    public Variable(String variableName) { 
    12         this.variableName = variableName; 
     17        if (variableName.toLowerCase().startsWith(SPECIAL_VARIABLE_PREFIX)) { 
     18            this.variableName = variableName.substring(SPECIAL_VARIABLE_PREFIX.length()); 
     19            // special:special:key means that real key named special:key is needed, not special variable 
     20            this.special = !this.variableName.toLowerCase().startsWith(SPECIAL_VARIABLE_PREFIX); 
     21        } else { 
     22            this.variableName = variableName; 
     23            this.special = false; 
     24        } 
    1325    } 
    1426 
    1527    @Override 
    1628    public void appendText(StringBuilder result, TemplateEngineDataProvider dataProvider) { 
    17         if ("*".equals(variableName)) { 
    18             List<String> keys = dataProvider.getTemplateKeys(); 
     29        if (special && SPECIAL_VALUE_EVERYTHING.equals(variableName)) { 
     30            Collection<String> keys = dataProvider.getTemplateKeys(); 
    1931            boolean first = true; 
    2032            for (String key: keys) { 
     
    2436                    first = false; 
    2537                } 
    26                 result.append(key).append("=").append(dataProvider.getTemplateValue(key)); 
     38                result.append(key).append("=").append(dataProvider.getTemplateValue(key, false)); 
    2739            } 
    2840        } else { 
    29             Object value = dataProvider.getTemplateValue(variableName); 
     41            Object value = dataProvider.getTemplateValue(variableName, special); 
    3042            if (value != null) { 
    3143                result.append(value); 
     
    3648    @Override 
    3749    public boolean isValid(TemplateEngineDataProvider dataProvider) { 
    38         if ("*".equals(variableName)) 
     50        if (special && SPECIAL_VALUE_EVERYTHING.equals(variableName)) 
    3951            return true; 
    4052        else 
    41             return dataProvider.getTemplateValue(variableName) != null; 
     53            return dataProvider.getTemplateValue(variableName, special) != null; 
    4254    } 
    4355 
     
    4759    } 
    4860 
     61    public boolean isSpecial() { 
     62        return special; 
     63    } 
     64 
    4965} 
  • trunk/test/unit/org/openstreetmap/josm/tools/template_engine/TemplateEngineTest.java

    r4282 r4431  
    77 
    88import org.junit.Assert; 
     9import org.junit.BeforeClass; 
    910import org.junit.Test; 
     11import org.openstreetmap.josm.Main; 
    1012import org.openstreetmap.josm.actions.search.SearchCompiler; 
    1113import org.openstreetmap.josm.actions.search.SearchCompiler.Match; 
     14import org.openstreetmap.josm.data.Preferences; 
     15import org.openstreetmap.josm.data.osm.Relation; 
    1216import org.unitils.reflectionassert.ReflectionAssert; 
    1317 
    1418public class TemplateEngineTest { 
     19 
     20    @BeforeClass 
     21    public static void before() { 
     22        Main.pref = new Preferences(); 
     23    } 
    1524 
    1625    @Test 
     
    6271    TemplateEngineDataProvider dataProvider = new TemplateEngineDataProvider() { 
    6372        @Override 
    64         public Object getTemplateValue(String name) { 
    65             if ("name".equals(name)) 
    66                 return "waypointName"; 
    67             else if ("number".equals(name)) 
    68                 return 10; 
    69             else 
    70                 return null; 
     73        public Object getTemplateValue(String name, boolean special) { 
     74            if (special) { 
     75                if ("localName".equals(name)) 
     76                    return "localName"; 
     77                else 
     78                    return null; 
     79            } else { 
     80                if ("name".equals(name)) 
     81                    return "waypointName"; 
     82                else if ("number".equals(name)) 
     83                    return 10; 
     84                else if ("special:key".equals(name)) 
     85                    return "specialKey"; 
     86                else 
     87                    return null; 
     88            } 
    7189        } 
    7290        @Override 
     
    90108 
    91109    @Test 
     110    public void testFillingSearchExpression() throws Exception { 
     111        TemplateParser parser = new TemplateParser("?{ admin_level = 2 'NUTS 1' | admin_level = 4 'NUTS 2' |  '{admin_level}'}"); 
     112        TemplateEntry templateEntry = parser.parse(); 
     113 
     114        StringBuilder sb = new StringBuilder(); 
     115        Relation r = new Relation(); 
     116        r.put("admin_level", "2"); 
     117        templateEntry.appendText(sb, r); 
     118        Assert.assertEquals("NUTS 1", sb.toString()); 
     119 
     120        sb.setLength(0); 
     121        r.put("admin_level", "5"); 
     122        templateEntry.appendText(sb, r); 
     123        Assert.assertEquals("5", sb.toString()); 
     124    } 
     125 
     126    @Test 
    92127    public void testPrintAll() throws Exception { 
    93         TemplateParser parser = new TemplateParser("{*}"); 
     128        TemplateParser parser = new TemplateParser("{special:everything}"); 
    94129        TemplateEntry entry = parser.parse(); 
    95130        StringBuilder sb = new StringBuilder(); 
     
    107142    } 
    108143 
     144    @Test 
     145    public void testSpecialVariable() throws Exception { 
     146        TemplateParser parser = new TemplateParser("{name}u{special:localName}u{special:special:key}"); 
     147        TemplateEntry templateEntry = parser.parse(); 
     148 
     149        StringBuilder sb = new StringBuilder(); 
     150        templateEntry.appendText(sb, dataProvider); 
     151        Assert.assertEquals("waypointNameulocalNameuspecialKey", sb.toString()); 
     152 
     153    } 
     154 
    109155 
    110156} 
Note: See TracChangeset for help on using the changeset viewer.