Changeset 4431 in josm


Ignore:
Timestamp:
2011-09-17T10:59:32+02:00 (13 years 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.