Index: /applications/editors/josm/plugins/roadsigns/data/defaultroadsignpreset.xml
===================================================================
--- /applications/editors/josm/plugins/roadsigns/data/defaultroadsignpreset.xml	(revision 21994)
+++ /applications/editors/josm/plugins/roadsigns/data/defaultroadsignpreset.xml	(revision 21995)
@@ -3,5 +3,21 @@
 Preset file for road signs plugin.
 
-Plugin is in early state of development (05-2010) and it is likely, the preset format will be changing.
+The plugin is in early state of development (05-2010) and the format is likely to change.
+
+How to customize
+================
+
+Add the following to your JOSM preference file
+(or enter it in the advanced preferences tab in JOSM):
+
+plugin.roadsign.sources=/path/to/myroadsignpreset.xml
+plugin.roadsign.icon.sources=/path/to/image/folder
+
+(The second one is only needed if you like to display your own icons.)
+
+
+Preset format
+=============
+
 Some values can contain parameters like $foo, that will be replaced by the value of the parameter named foo.
 
@@ -9,27 +25,35 @@
     ref             Short official designation of the sign that can be used for the traffic_sign tag. (accepts parameters)
     id              Unique identifier. (If missing, equals ref. Either id or ref must be present.)
-    icon            Icon path. (If missing, id or ref is used as icon path. In this case ':' and '.' characters are converted to underscore '_'.)
+    icon            Icon image name. (If missing, id or ref is used as image name. In this case ':' and '.' characters are converted to underscore '_'.)
     name            Name of the sign. (required)
-    long_name       Official name of the sign. (optional)
+    long_name       Long (e.g. official) name of the sign.
     help            Some notes to guide the user.
     wiki            Page in the osm wiki
-    deprecated      Set to "yes" if authorities have decided to no longer install signs of this kind. 
+    deprecated      Set to "yes" if authorities have decided to no longer install signs of this kind.
                     (But old signs may still be there and need to be recorded.)
-    
+
 tag:
+    Some tags can be named (ident=*) and modified by other subsequent tags. If this finally results in an
+    empty value (""), then the tag is skipped altogether. Note that the default value of a named tag is
+    only used if there are no appending tags. E.g. access=no becomes access=delivery and not access=no;delivery.
+
     static tags:
         key             The key text. (accepts parameters)
         value           The value text. (accepts parameters)
-    
-    identified tags:
+
+    named tags:
         key             The key text.
         value           The default value text. If the final evaluation of the value results in an empty string, the tag is dropped.
         ident           Name a tag so it can later be changed by other tags.
-    
+
     modifying tags:
-        tag_ref         Name of the tag to be changed.
-        append_value    Append a string to the value of the tag. The default value of the identified tag is dropped (unless there is no
-                        modifying tag appending a value).
-            
+        appending:
+            tag_ref         Name of the tag to be changed.
+            append_value    Append a string to the value of the tag. The default value of the identified tag is dropped (unless there is no
+                            modifying tag appending a value).
+        condition:
+            tag_ref         Name of the tag to be changed.
+            condition       The condition to add. (K=V becomes K:cond=V.)
+
 parameter:
     ident           identifier to get the value of this parameter (required)
@@ -39,5 +63,5 @@
     field_width     for text fields: the width of the field (number of characters)
     default         default value (required)
-    
+
 supplementary: (list of recommended additional signs)
     id         the id of the supplementary sign
@@ -46,22 +70,20 @@
 <roadsignpreset country="DE">
     <sign ref="DE:110" name="Incline" de.name="Steigung"
-            help="Applies for the road section with steep incline. (Split the way at the ends of the steep section.) \
+            help="Applies for the road section with steep incline. (Split the way at the ends of the steep section.) 
 Positive values indicate movement upward in the direction of the (osm) way and negative values indicate movement downwards in the direction of the way."
-            de.help="&lt;p&gt;Gilt für das Streckenstück mit hoher Steigung. (Weg am Anfang und Ende des steilen Abschnittes auftrennen.) \
-Positive Werte stehen für einen Anstieg in Richtung des ways und negative Werte für einen Abfall in Richtung des ways.&lt;/p&gt;\" 
-            wiki="Key:incline" 
+            de.help="Gilt für das Streckenstück mit hoher Steigung. (Weg am Anfang und Ende des steilen Abschnittes auftrennen.) 
+Positive Werte stehen für einen Anstieg in Richtung des ways und negative Werte für einen Abfall in Richtung des ways."
+            wiki="Key:incline"
             de.wiki="DE:Key:incline">
         <tag key="incline" value="$val%"/>
         <parameter input="textfield" name="max. incline" de.name="Maximale Steigung" type="int" ident="val" default="12" suffix="%" field_width="3"/>
     </sign>
-    
+
     <sign ref="DE:215" name="Roundabout" de.name="Kreisverkehr"
         wiki="Tag:junction=roundabout"
-        de.wiki="DE:Tag:junction=roundabout"
-        help=""
-        de.help="">
+        de.wiki="DE:Tag:junction=roundabout">
         <tag key="junction" value="roundabout"/>
     </sign>
-    
+
     <sign id="oneway" icon="DE_220;DE_267" name="One-way road" de.name="Einbahnstraße">  <!--ref="DE:220;DE:267"-->
         <tag key="oneway" value="yes"/>
@@ -69,5 +91,5 @@
 <!--        FIXME: lane->-->
     </sign>
-    
+
     <sign ref="DE:237" name="Bicycle path" de.name="Radweg">
         <tag key="highway" value="path"/>
@@ -87,5 +109,5 @@
         <supplementary id="DE:1026-38"/> <!-- Land- und forstwirtschaftlicher Verkehr frei -->
     </sign>
-    
+
     <sign ref="DE:239" name="Pedestrian path" de.name="Gehweg">
         <tag key="highway" value="path"/>
@@ -139,5 +161,5 @@
         <!-- Kraftfahrzeuge frei -->
     </sign>
-    
+
     <sign ref="DE:250" name="All vehicles prohibited" de.name="Verbot für Fahrzeuge aller Art">
         <tag key="vehicle" value="no" ident="mode"/>
@@ -154,7 +176,7 @@
         <supplementary id="DE:1026-38"/> <!-- Land- und forstwirtschaftlicher Verkehr frei -->
     </sign>
-    
+
     <sign ref="DE:251" name="Motorcars prohibited" de.name="Verbot für Kraftwagen"
-            long_name="Motorcars and other multi-track motorized vehicles prohibited" 
+            long_name="Motorcars and other multi-track motorized vehicles prohibited"
             de.long_name="Verbot für Kraftwagen und sonstige mehrspurige Kraftfahrzeuge"
             wiki="Key:motorcar"
@@ -196,5 +218,5 @@
         <supplementary id="DE:1026-35"/> <!-- Lieferverkehr frei -->
     </sign>
-    
+
     <sign ref="DE:256" deprecated="yes" name="Mopeds prohibited" de.name="Verbot für Mofas">
         <tag key="mofa" value="no" ident="mode"/>
@@ -206,10 +228,10 @@
         <tag key="horse" value="no" ident="mode"/>
     </sign>
-    
+
     <sign ref="DE:259" name="Pedestrians prohibited" de.name="Verbot für Fußgänger">
         <tag key="foot" value="no" ident="mode"/>
         <supplementary id="DE:1020-30"/> <!-- Anlieger frei -->
     </sign>
-    
+
     <sign ref="DE:260" name="Motor vehicles prohibited" de.name="Verbot für Kraftfahrzeuge"
         long_name="Motorcycles, also with sidecar, mopeds, mofas as well as motorcars and other multi-track motorized vehicles prohibited"
@@ -226,23 +248,25 @@
     </sign>
 
-    <sign ref="DE:261" name="Hazardous cargo prohibited" de.name="Verbot für kennzeichnungspflichtige Kraftfahrzeuge mit gefährlichen Gütern" wiki="Key:hazmat" de.wiki="DE:Key:hazmat">
-        <tag key="hazmat" value="no" ident="mode"/>        
-    </sign>
-    
+    <sign ref="DE:261" name="Hazardous cargo prohibited" de.name="Verbot für kennzeichnungspflichtige Kraftfahrzeuge mit gefährlichen Gütern"
+            wiki="Key:hazmat" 
+            de.wiki="DE:Key:hazmat">
+        <tag key="hazmat" value="no" ident="mode"/>
+    </sign>
+
     <sign ref="DE:262[$val]" icon="DE_262" name="Weight limit" de.name="Tatsächliches Gewicht" wiki="Key:maxweight">
         <tag key="maxweight" value="$val"/>
         <parameter ident="val" input="textfield" default="5.5" suffix="t" field_width="3"/>
     </sign>
-    
+
     <sign ref="DE:263[$val]" icon="DE_263" name="Axle weight limit" de.name="Tatsächliche Achslast" wiki="Key:maxaxleload">
         <tag key="maxaxleload" value="$val"/>
         <parameter ident="val" input="textfield" default="8" suffix="t" field_width="3"/>
     </sign>
-    
+
     <sign ref="DE:264[$val]" icon="DE_264" name="Width limit" de.name="Tatsächliche Breite">
         <tag key="maxwidth" value="$val"/>
         <parameter ident="val" input="textfield" default="2" suffix="m" field_width="3"/>
     </sign>
-    
+
     <sign ref="DE:265[$val]" icon="DE_265" name="Height limit" de.name="Tatsächliche Höhe">
         <tag key="maxheight" value="$val"/>
@@ -250,12 +274,12 @@
     </sign>
 
-    <sign ref="DE:266[$val]" icon="DE_266" name="Length limit" de.name="Tatsächliche Länge" 
+    <sign ref="DE:266[$val]" icon="DE_266" name="Length limit" de.name="Tatsächliche Länge"
             wiki="Key:maxlength">
         <tag key="maxlength" value="$val"/>
         <parameter ident="val" input="textfield" default="10" suffix="m" field_width="3"/>
     </sign>
-    
-    <sign ref="DE:269" name="Water polluting cargo prohibited" de.name="Verbot für Fahrzeuge mit wassergefährdender Ladung" 
-            wiki="Key:hazmat" 
+
+    <sign ref="DE:269" name="Water polluting cargo prohibited" de.name="Verbot für Fahrzeuge mit wassergefährdender Ladung"
+            wiki="Key:hazmat"
             de.wiki="DE:Key:hazmat">
         <tag key="hazmat:water" value="no" ident="mode"/>
@@ -268,5 +292,5 @@
         <supplementary id="DE:1048-12"/> <!-- nur LKW -->
     </sign>
-    
+
     <sign ref="DE:274.1[$val]" icon="DE_274_1" name="Speed limit zone" de.name="Zone mit zulässiger Höchstgeschwindigkeit">
         <tag key="maxspeed" value="$val"/>
@@ -274,5 +298,5 @@
         <parameter ident="val" type="int" input="combo" editable="yes" text="speed-limit" de.text="Höchstgeschwindigkeit" suffix="km/h" values="20,30" default="30" field_width="2"/>
     </sign>
-    
+
     <sign ref="DE:275[$val]" icon="DE_275" name="Minimum speed limit" de.name="Vorgeschriebene Mindestgeschwindigkeit" wiki="Key:minspeed">
         <tag key="minspeed" value="$val"/>
@@ -283,9 +307,9 @@
         <tag key="highway" value="living_street"/>
     </sign>
-    
+
     <sign ref="DE:327" name="Tunnel" de.name="Tunnel">
         <tag key="tunnel" value="yes"/>
     </sign>
-    
+
     <sign ref="DE:1020-12" supplementary="yes" name="Bicyle and residents allowed" de.name="Radfahrer und Anlieger frei"> <!-- FIXME: bad translation into English -->
         <tag key="bicycle" value="yes"/>
@@ -331,9 +355,9 @@
         <tag tag_ref="mode" append_value="delivery"/>
     </sign>
-    
+
     <sign ref="DE:1026-36" supplementary="yes" name="Agricultural vehicles allowed" de.name="Landwirtschaftlicher Verkehr frei">
         <tag tag_ref="mode" append_value="agricultural"/>
     </sign>
-    
+
     <sign ref="DE:1026-37" supplementary="yes" name="Forestry vehicles allowed" de.name="Forstwirtschaftlicher Verkehr frei">
         <tag tag_ref="mode" append_value="forestry"/>
@@ -344,8 +368,8 @@
         <tag tag_ref="mode" append_value="forestry"/>
     </sign>
-    
+
     <sign ref="DE:1048-12" supplementary="yes" name="Heavy goods vehicles only" de.name="nur LKW"
             long_name="Vehicles with a permitted gross weight over 3.5 t including their trailers prohibited, except passenger cars and busses, only"
-            de.long_name="nur Kraftfahrzeuge mit einem zulässigen Gesamtgewicht über 3,5 t, einschl. ihrer Anhänger, und Zugmaschinen, ausgenommen Personenkraftwagen und Kraftomnibusse">
+            de.long_name="Nur Kraftfahrzeuge mit einem zulässigen Gesamtgewicht über 3,5 t, einschl. ihrer Anhänger, und Zugmaschinen, ausgenommen Personenkraftwagen und Kraftomnibusse">
         <tag tag_ref="restriction" condition="hgv"/>
     </sign>
Index: /applications/editors/josm/plugins/roadsigns/src/org/openstreetmap/josm/plugins/roadsigns/RoadSignInputDialog.java
===================================================================
--- /applications/editors/josm/plugins/roadsigns/src/org/openstreetmap/josm/plugins/roadsigns/RoadSignInputDialog.java	(revision 21994)
+++ /applications/editors/josm/plugins/roadsigns/src/org/openstreetmap/josm/plugins/roadsigns/RoadSignInputDialog.java	(revision 21995)
@@ -33,8 +33,11 @@
 import javax.swing.Scrollable;
 import javax.swing.SwingConstants;
+import javax.swing.SwingUtilities;
 import javax.swing.border.Border;
 import javax.swing.border.EtchedBorder;
 import javax.swing.event.DocumentEvent;
 import javax.swing.event.DocumentListener;
+import javax.swing.event.HyperlinkEvent;
+import javax.swing.event.HyperlinkListener;
 import javax.swing.table.AbstractTableModel;
 
@@ -49,4 +52,5 @@
 import org.openstreetmap.josm.plugins.roadsigns.Sign.SignParameter;
 import org.openstreetmap.josm.plugins.roadsigns.Sign.Tag;
+import org.openstreetmap.josm.tools.OpenBrowser;
 import org.openstreetmap.josm.tools.Pair;
 
@@ -74,4 +78,5 @@
     private JPanel pnlPossibleSupplements;
     private JEditorPane info;
+    private JScrollPane scrollInfo;
 
     public RoadSignInputDialog(List<Sign> signs) {
@@ -126,5 +131,4 @@
         pnlSignSelection.setLayout(fLayout);
 
-        
         pnlPossibleSigns = new FixedWidthPanel();
         pnlPossibleSupplements = new FixedWidthPanel();
@@ -146,8 +150,19 @@
         info.setEditable(false);
         info.setContentType("text/html");
-        info.setText("");
+        info.setText(" ");
         info.setBackground(this.getBackground());
-        JScrollPane scroll3 = new JScrollPane(info, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
-        multiSplitPane.add(scroll3, "bottom");
+        info.addHyperlinkListener(new HyperlinkListener() {
+            public void hyperlinkUpdate(HyperlinkEvent e) {
+                if (e == null || e.getURL() == null)
+                    return;
+                System.err.println(e.getURL());
+                if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
+                    OpenBrowser.displayUrl(e.getURL().toString());
+                }
+            }
+        });
+
+        scrollInfo = new JScrollPane(info, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+        multiSplitPane.add(scrollInfo, "bottom");
 
         return multiSplitPane;
@@ -162,4 +177,11 @@
         for (Sign s : signs) {
             JLabel lbl = new JLabel(s.getIcon());
+            String tt = "<html>"+s.name;
+            String ref = s.getDefaultRef();
+            if (ref != null) {
+                tt += "  <i><small>("+ref+")</small></i>";
+            }
+            tt += "</html>";
+            lbl.setToolTipText(tt);
             s.label = lbl;
             lbl.addMouseListener(new SignClickListener(s));
@@ -621,27 +643,43 @@
         @Override
         public void mouseClicked(MouseEvent e) {
+            info.setText(longText());
+            /* scroll up again */
+            SwingUtilities.invokeLater(new Runnable(){
+                public void run() {
+                    scrollInfo.getVerticalScrollBar().setValue(0);
+                }
+            });
             sel.add(sign);
         }
 
-        @Override
-        public void mouseEntered(MouseEvent e) {
+        private String longText() {
             StringBuilder txt = new StringBuilder();
-            txt.append("<p><b><large>");
-            txt.append(sign.name);
-            txt.append("</large></b>");
+            txt.append(sign.long_name == null ? sign.name : sign.long_name);
             String ref = sign.getDefaultRef();
             if (ref != null) {
                 txt.append("  <i><small>("+ref+")</small></i>");
             }
-            txt.append("</p>");
-//            if (sign.long_name != null) {
-//                txt.append("<i><smaller>("+sign.long_name+")</smaller></i>");
-//            }
-            info.setText(txt.toString());
-        }
-
-        @Override
-        public void mouseExited(MouseEvent e) {
-            info.setText("");
+
+            if (sign.help != null) {
+                txt.append("<p>");
+                txt.append(sign.help);
+                txt.append("</p>");
+            }
+
+            if (sign.wiki != null || sign.loc_wiki != null) {
+                String wikiPrefix = "http://wiki.openstreetmap.org/wiki/";
+                txt.append("<p>");
+                if (sign.loc_wiki != null) {
+                    String link = wikiPrefix+sign.loc_wiki;
+                    txt.append("<a href=\""+link+"\">"+link+"</a>");
+                    txt.append("<br>");
+                }
+                if (sign.wiki != null && ! sign.wiki.equals(sign.loc_wiki)) {
+                    String link = wikiPrefix+sign.wiki;
+                    txt.append("<a href=\""+link+"\">"+link+"</a>");
+                }
+                txt.append("</p>");
+            }
+            return txt.toString();
         }
     }
@@ -660,47 +698,47 @@
         @Override
         public void setBounds(int x, int y, int width, int height) {
-			super.setBounds(x, y, getParent().getWidth(), height);
-		}
+            super.setBounds(x, y, getParent().getWidth(), height);
+        }
 
         @Override
-		public Dimension getPreferredSize() {
-			return new Dimension(getWidth(), getPreferredHeight());
-		}
-
-		public Dimension getPreferredScrollableViewportSize() {
-			return super.getPreferredSize();
-		}
-
-		public int getScrollableUnitIncrement( Rectangle visibleRect, int orientation, int direction ) {
+        public Dimension getPreferredSize() {
+            return new Dimension(getWidth(), getPreferredHeight());
+        }
+
+        public Dimension getPreferredScrollableViewportSize() {
+            return super.getPreferredSize();
+        }
+
+        public int getScrollableUnitIncrement( Rectangle visibleRect, int orientation, int direction ) {
             final int FRAC = 20;
-			int inc = (orientation == SwingConstants.VERTICAL ? getParent().getHeight() : getParent().getWidth()) / FRAC;
-			return Math.max(inc, 1);
-		}
-
-		public int getScrollableBlockIncrement( Rectangle visibleRect, int orientation, int direction ) {
-			return orientation == SwingConstants.VERTICAL ? getParent().getHeight() : getParent().getWidth();
-		}
-
-		public boolean getScrollableTracksViewportWidth() {
-			return true;
-		}
-
-		public boolean getScrollableTracksViewportHeight() {
-			return false;
-		}
-
-		private int getPreferredHeight() {
-			int prefH = 0;
+            int inc = (orientation == SwingConstants.VERTICAL ? getParent().getHeight() : getParent().getWidth()) / FRAC;
+            return Math.max(inc, 1);
+        }
+
+        public int getScrollableBlockIncrement( Rectangle visibleRect, int orientation, int direction ) {
+            return orientation == SwingConstants.VERTICAL ? getParent().getHeight() : getParent().getWidth();
+        }
+
+        public boolean getScrollableTracksViewportWidth() {
+            return true;
+        }
+
+        public boolean getScrollableTracksViewportHeight() {
+            return false;
+        }
+
+        private int getPreferredHeight() {
+            int prefH = 0;
             int num = getComponentCount();
-			for (int i = 0; i < num; ++i) {
-				Rectangle rect = getComponent(i).getBounds();
-				int h = rect.y + rect.height;
-				if (h > prefH) {
-					prefH = h;
-                }
-			}
-			prefH += ((FlowLayout) getLayout()).getVgap();
-			return prefH;
-		}
+            for (int i = 0; i < num; ++i) {
+                Rectangle rect = getComponent(i).getBounds();
+                int h = rect.y + rect.height;
+                if (h > prefH) {
+                    prefH = h;
+                }
+            }
+            prefH += ((FlowLayout) getLayout()).getVgap();
+            return prefH;
+        }
     }
 }
Index: /applications/editors/josm/plugins/roadsigns/src/org/openstreetmap/josm/plugins/roadsigns/RoadSignsPlugin.java
===================================================================
--- /applications/editors/josm/plugins/roadsigns/src/org/openstreetmap/josm/plugins/roadsigns/RoadSignsPlugin.java	(revision 21994)
+++ /applications/editors/josm/plugins/roadsigns/src/org/openstreetmap/josm/plugins/roadsigns/RoadSignsPlugin.java	(revision 21995)
@@ -31,7 +31,7 @@
 
 public class RoadSignsPlugin extends Plugin {
-
     private static boolean presetsLoaded = false;
     public static List<Sign> signs;
+    static List<String> iconDirs;
 
     public RoadSignsPlugin(PluginInformation info) {
@@ -68,6 +68,13 @@
         presetsLoaded=true;
         List<String> files = new ArrayList<String>(
-                                   Main.pref.getCollection("plugin.roadsign.sources",
-                                        Collections.<String>singletonList("resource://data/defaultroadsignpreset.xml")));
+                Main.pref.getCollection("plugin.roadsign.sources",
+                    Collections.<String>singletonList("resource://data/defaultroadsignpreset.xml")));
+        iconDirs = new ArrayList<String>(
+                Main.pref.getCollection("plugin.roadsign.icon.sources", Collections.<String>emptySet()));
+
+        if (Main.pref.getBoolean("plugin.roadsign.use_default_icon_source", true)) {
+            iconDirs.add("resource://images/");
+        }
+
         for (String source : files) {
             try {
Index: /applications/editors/josm/plugins/roadsigns/src/org/openstreetmap/josm/plugins/roadsigns/RoadSignsReader.java
===================================================================
--- /applications/editors/josm/plugins/roadsigns/src/org/openstreetmap/josm/plugins/roadsigns/RoadSignsReader.java	(revision 21994)
+++ /applications/editors/josm/plugins/roadsigns/src/org/openstreetmap/josm/plugins/roadsigns/RoadSignsReader.java	(revision 21995)
@@ -107,4 +107,9 @@
                     curSign.isSupplementing = true;
                 }
+
+                curSign.wiki = atts.getValue("wiki");
+                curSign.loc_wiki = getLocalized(atts, "wiki");
+
+                curSign.help = getLocalized(atts, "help");
 
             } else if (curSign != null && qname.equals("tag")) {
Index: /applications/editors/josm/plugins/roadsigns/src/org/openstreetmap/josm/plugins/roadsigns/Sign.java
===================================================================
--- /applications/editors/josm/plugins/roadsigns/src/org/openstreetmap/josm/plugins/roadsigns/Sign.java	(revision 21994)
+++ /applications/editors/josm/plugins/roadsigns/src/org/openstreetmap/josm/plugins/roadsigns/Sign.java	(revision 21995)
@@ -30,4 +30,7 @@
     public List<SignParameter> params = new ArrayList<SignParameter>();
     public boolean isSupplementing;
+    public String loc_wiki;
+    public String wiki;
+    public String help;
 
     public JLabel label; // FIXME: don't put gui stuff here
@@ -78,5 +81,5 @@
     public ImageIcon getIcon() {
         if (icon == null) {
-            icon = ImageProvider.get(iconURL);
+            icon = ImageProvider.getIfAvailable(RoadSignsPlugin.iconDirs, "plugin.sign."+id, null, iconURL, null);
         }
         return icon;
