Index: trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 3842)
+++ trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 3843)
@@ -300,4 +300,5 @@
      *--------*/
     public StyleCache mappaintStyle = null;
+    public int mappaintCacheIdx;
 
     /* This should not be called from outside. Fixing the UI to add relevant
Index: trunk/src/org/openstreetmap/josm/gui/MapFrame.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/MapFrame.java	(revision 3842)
+++ trunk/src/org/openstreetmap/josm/gui/MapFrame.java	(revision 3843)
@@ -51,4 +51,5 @@
 import org.openstreetmap.josm.gui.dialogs.HistoryDialog;
 import org.openstreetmap.josm.gui.dialogs.LayerListDialog;
+import org.openstreetmap.josm.gui.dialogs.MapPaintDialog;
 import org.openstreetmap.josm.gui.dialogs.RelationListDialog;
 import org.openstreetmap.josm.gui.dialogs.SelectionListDialog;
@@ -185,4 +186,7 @@
         addToggleDialog(filterDialog = new FilterDialog());
         addToggleDialog(new ChangesetDialog(this));
+        if (Main.pref.getBoolean("mappaintdialog.show", false)) {
+            addToggleDialog(new MapPaintDialog());
+        }
 
         // status line below the map
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/MapPaintDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/MapPaintDialog.java	(revision 3843)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/MapPaintDialog.java	(revision 3843)
@@ -0,0 +1,241 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.dialogs;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.event.ActionEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import javax.swing.AbstractAction;
+import javax.swing.DefaultListSelectionModel;
+import javax.swing.JPanel;
+import javax.swing.JPopupMenu;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.ListSelectionModel;
+import javax.swing.UIManager;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import javax.swing.table.AbstractTableModel;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.gui.SideButton;
+import org.openstreetmap.josm.gui.mappaint.ElemStyles;
+import org.openstreetmap.josm.gui.mappaint.MapPaintStyles;
+import org.openstreetmap.josm.gui.mappaint.StyleSource;
+import org.openstreetmap.josm.gui.widgets.PopupMenuLauncher;
+import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Shortcut;
+
+public class MapPaintDialog extends ToggleDialog {
+
+    protected JTable tblStyles;
+    protected StylesModel model;
+    protected DefaultListSelectionModel selectionModel;
+
+    protected OnOffAction onoffAction;
+    protected ReloadAction reloadAction;
+
+    public MapPaintDialog() {
+        super(tr("Map Paint Styles"), "mapstyle", tr("configure the map painting style"),
+                Shortcut.registerShortcut("subwindow:authors", tr("Toggle: {0}", tr("Authors")), KeyEvent.VK_M, Shortcut.GROUP_LAYER, Shortcut.SHIFT_DEFAULT), 250);
+        build();
+    }
+
+    protected void build() {
+        JPanel pnl = new JPanel();
+        pnl.setLayout(new BorderLayout());
+
+        model = new StylesModel();
+        model.setStyles(MapPaintStyles.getStyles().getStyleSources());
+        
+        tblStyles = new JTable(model);
+        tblStyles.setSelectionModel(selectionModel= new DefaultListSelectionModel());
+        tblStyles.addMouseListener(new PopupMenuHandler());
+        tblStyles.putClientProperty("terminateEditOnFocusLost", true);
+        tblStyles.setBackground(UIManager.getColor("Panel.background"));
+        tblStyles.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
+        tblStyles.setTableHeader(null);
+        tblStyles.getColumnModel().getColumn(0).setMaxWidth(1);
+        tblStyles.getColumnModel().getColumn(0).setResizable(false);
+        tblStyles.setShowGrid(false);
+        tblStyles.setIntercellSpacing(new Dimension(0, 0));
+
+        pnl.add(new JScrollPane(tblStyles), BorderLayout.CENTER);
+
+        pnl.add(buildButtonRow(), BorderLayout.SOUTH);
+
+        add(pnl, BorderLayout.CENTER);
+    }
+
+    protected JPanel buildButtonRow() {
+        JPanel p = getButtonPanel(1);
+        reloadAction = new ReloadAction();
+        onoffAction = new OnOffAction();
+        selectionModel.addListSelectionListener(onoffAction);
+        selectionModel.addListSelectionListener(reloadAction);
+        p.add(new SideButton(onoffAction));
+        return p;
+    }
+    
+    protected class StylesModel extends AbstractTableModel {
+        List<StyleSource> data;
+
+        public StylesModel() {
+            this.data = new ArrayList<StyleSource>();
+        }
+
+        @Override
+        public int getColumnCount() {
+            return 2;
+        }
+
+        @Override
+        public int getRowCount() {
+            return data.size();
+        }
+        
+        @Override
+        public Object getValueAt(int row, int column) {
+            if (column == 0)
+                return data.get(row).active;
+            else
+                return data.get(row).getDisplayString();
+        }
+
+        @Override
+        public boolean isCellEditable(int row, int column) {
+            return column == 0;
+        }
+
+        Class<?>[] columnClasses = {Boolean.class, StyleSource.class};
+
+        @Override
+        public Class<?> getColumnClass(int column) {
+            return columnClasses[column];
+        }
+
+        @Override
+        public void setValueAt(Object aValue, int row, int column) {
+            if (row < 0 || row >= getRowCount() || aValue == null)
+                return;
+            if (column == 0) {
+                toggleOnOff(row);
+            }
+        }
+
+        public void setStyles(Collection<? extends StyleSource> styles) {
+            data.clear();
+            if (styles !=null) {
+                data.addAll(styles);
+            }
+            fireTableDataChanged();
+        }
+
+        public void toggleOnOff(int... rows) {
+            for (Integer p : rows) {
+                StyleSource s = model.data.get(p);
+                s.active = !s.active;
+            }
+            if (rows.length == 1) {
+                model.fireTableCellUpdated(rows[0], 0);
+            } else {
+                model.fireTableDataChanged();
+            }
+            ElemStyles.cacheIdx++;
+            Main.map.mapView.preferenceChanged(null);
+            Main.map.mapView.repaint();
+        }
+    }
+
+    protected class OnOffAction extends AbstractAction implements ListSelectionListener {
+        public OnOffAction() {
+            putValue(SHORT_DESCRIPTION, tr("Turn selected styles on or off"));
+            putValue(SMALL_ICON, ImageProvider.get("apply"));
+            updateEnabledState();
+        }
+
+        protected void updateEnabledState() {
+            setEnabled(tblStyles.getSelectedRowCount() > 0);
+        }
+
+        @Override
+        public void valueChanged(ListSelectionEvent e) {
+            updateEnabledState();
+        }
+
+        @Override
+        public void actionPerformed(ActionEvent e) {
+            int[] pos = tblStyles.getSelectedRows();
+            model.toggleOnOff(pos);
+        }
+    }
+
+    protected class ReloadAction extends AbstractAction implements ListSelectionListener {
+        public ReloadAction() {
+            putValue(NAME, tr("Reload from file"));
+            putValue(SHORT_DESCRIPTION, tr("reload selected styles from file"));
+            putValue(SMALL_ICON, ImageProvider.get("dialogs", "refresh"));
+            updateEnabledState();
+        }
+
+        protected void updateEnabledState() {
+            int[] pos = tblStyles.getSelectedRows();
+            boolean e = pos.length > 0;
+            for (int i : pos) {
+                if (!model.data.get(i).isLocal()) {
+                    e = false;
+                    break;
+                }
+            }
+            setEnabled(e);
+        }
+
+        @Override
+        public void valueChanged(ListSelectionEvent e) {
+            updateEnabledState();
+        }
+
+        @Override
+        public void actionPerformed(ActionEvent e) {
+            int[] pos = tblStyles.getSelectedRows();
+            for (int p : pos) {
+                StyleSource s = model.data.get(p);
+                s.loadStyleSource();
+            }
+            ElemStyles.cacheIdx++;
+            Main.map.mapView.preferenceChanged(null);
+            Main.map.mapView.repaint();
+        }
+    }
+
+    class PopupMenuHandler extends PopupMenuLauncher {
+        @Override
+        public void launch(MouseEvent evt) {
+            Point p = evt.getPoint();
+            int index = tblStyles.rowAtPoint(p);
+            if (index < 0) return;
+            if (!tblStyles.getCellRect(index, 1, false).contains(evt.getPoint()))
+                return;
+            if (!tblStyles.isRowSelected(index)) {
+                tblStyles.setRowSelectionInterval(index, index);
+            }
+            MapPaintPopup menu = new MapPaintPopup();
+            menu.show(MapPaintDialog.this, p.x, p.y);
+        }
+    }
+
+    public class MapPaintPopup extends JPopupMenu {
+        public MapPaintPopup() {
+            add(reloadAction);
+        }
+    }
+}
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyles.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyles.java	(revision 3842)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyles.java	(revision 3843)
@@ -19,5 +19,4 @@
 import org.openstreetmap.josm.gui.NavigatableComponent;
 import org.openstreetmap.josm.gui.mappaint.StyleCache.StyleList;
-import org.openstreetmap.josm.gui.mappaint.xml.XmlStyleSource;
 import org.openstreetmap.josm.tools.FilteredCollection;
 import org.openstreetmap.josm.tools.Pair;
@@ -26,23 +25,25 @@
 
 public class ElemStyles {
-    private List<XmlStyleSource> styleSources;
+    private List<StyleSource> styleSources;
     private boolean drawMultipolygon;
+
+    public static int cacheIdx;
 
     public ElemStyles()
     {
-        styleSources = new ArrayList<XmlStyleSource>();
-    }
-
-    public void add(XmlStyleSource style) {
+        styleSources = new ArrayList<StyleSource>();
+    }
+
+    public void add(StyleSource style) {
         styleSources.add(style);
     }
 
-    public Collection<XmlStyleSource> getStyleSources() {
-        return new FilteredCollection<XmlStyleSource>(styleSources, new Predicate<XmlStyleSource>() {
+    public Collection<StyleSource> getStyleSources() {
+        return new FilteredCollection<StyleSource>(styleSources, new Predicate<StyleSource>() {
 
             String name = Main.pref.get("mappaint.style", "standard");
 
             @Override
-            public boolean evaluate(XmlStyleSource s) {
+            public boolean evaluate(StyleSource s) {
                 return Utils.equal(s.getPrefName(), name);
             }
@@ -54,5 +55,5 @@
         Set<String> names = new HashSet<String>();
         names.add("standard");
-        for (XmlStyleSource s : styleSources) {
+        for (StyleSource s : styleSources) {
             if (s.name != null) {
                 names.add(s.name);
@@ -67,5 +68,5 @@
 
     public Pair<StyleList, Range> getStyleCacheWithRange(OsmPrimitive osm, double scale, NavigatableComponent nc) {
-        if (osm.mappaintStyle == null) {
+        if (osm.mappaintStyle == null || osm.mappaintCacheIdx != cacheIdx) {
             osm.mappaintStyle = StyleCache.EMPTY_STYLECACHE;
         } else {
@@ -83,4 +84,5 @@
         }
         osm.mappaintStyle = osm.mappaintStyle.put(p.a, p.b);
+        osm.mappaintCacheIdx = cacheIdx;
         return p;
     }
@@ -90,5 +92,5 @@
         {
             return generateStyles(osm, scale, null, false);
-        } 
+        }
         else if (osm instanceof Way)
         {
@@ -178,5 +180,5 @@
             }
             return p;
-        } 
+        }
         else if (osm instanceof Relation)
         {
@@ -216,6 +218,8 @@
         MultiCascade mc = new MultiCascade();
 
-        for (XmlStyleSource s : styleSources) {
-            s.apply(mc, osm, scale, multipolyOuterWay, pretendWayIsClosed);
+        for (StyleSource s : styleSources) {
+            if (s.active) {
+                s.apply(mc, osm, scale, multipolyOuterWay, pretendWayIsClosed);
+            }
         }
 
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/MapPaintStyles.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/MapPaintStyles.java	(revision 3842)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/MapPaintStyles.java	(revision 3843)
@@ -2,12 +2,8 @@
 package org.openstreetmap.josm.gui.mappaint;
 
-import org.openstreetmap.josm.gui.mappaint.xml.XmlStyleSource;
-import org.openstreetmap.josm.gui.mappaint.xml.XmlStyleSourceHandler;
 import static org.openstreetmap.josm.tools.I18n.tr;
 
-import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.InputStreamReader;
 import java.util.Collection;
 import java.util.Collections;
@@ -18,12 +14,9 @@
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.gui.mappaint.xml.XmlStyleSource;
 import org.openstreetmap.josm.gui.preferences.SourceEntry;
 import org.openstreetmap.josm.gui.preferences.MapPaintPreference.MapPaintPrefMigration;
 import org.openstreetmap.josm.io.MirroredInputStream;
 import org.openstreetmap.josm.tools.ImageProvider;
-import org.openstreetmap.josm.tools.XmlObjectParser;
-import org.openstreetmap.josm.tools.Utils;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXParseException;
 
 public class MapPaintStyles {
@@ -90,31 +83,13 @@
 
         for (SourceEntry entry : sourceEntries) {
-            XmlStyleSource style = new XmlStyleSource(entry);
+            StyleSource style = new XmlStyleSource(entry);
             try {
-                XmlObjectParser parser = new XmlObjectParser(new XmlStyleSourceHandler(style));
                 MirroredInputStream in = new MirroredInputStream(entry.url);
                 InputStream zip = in.getZipEntry("xml","style");
-                InputStreamReader ins;
-                if(zip != null)
-                {
+                if (zip != null) {
                     style.zipIcons = in.getFile();
-                    ins = new InputStreamReader(zip);
-                } else {
-                    ins = new InputStreamReader(in);
-                }
-                parser.startWithValidation(ins, "http://josm.openstreetmap.de/mappaint-style-1.0",
-                "resource://data/mappaint-style.xsd");
-                while(parser.hasNext()) {
-                }
+                } 
             } catch(IOException e) {
                 System.err.println(tr("Warning: failed to load Mappaint styles from ''{0}''. Exception was: {1}", entry.url, e.toString()));
-                e.printStackTrace();
-                style.hasError = true;
-            } catch(SAXParseException e) {
-                System.err.println(tr("Warning: failed to parse Mappaint styles from ''{0}''. Error was: [{1}:{2}] {3}", entry.url, e.getLineNumber(), e.getColumnNumber(), e.getMessage()));
-                e.printStackTrace();
-                style.hasError = true;
-            } catch(SAXException e) {
-                System.err.println(tr("Warning: failed to parse Mappaint styles from ''{0}''. Error was: {1}", entry.url, e.getMessage()));
                 e.printStackTrace();
                 style.hasError = true;
@@ -122,4 +97,7 @@
             styles.add(style);
         }
+        for (StyleSource s : styles.getStyleSources()) {
+            s.loadStyleSource();
+        }
     }
 }
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/StyleSource.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/StyleSource.java	(revision 3843)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/StyleSource.java	(revision 3843)
@@ -0,0 +1,24 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.mappaint;
+
+import java.io.File;
+
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.gui.preferences.SourceEntry;
+
+abstract public class StyleSource extends SourceEntry {
+    public boolean hasError = false;
+    public File zipIcons;
+
+    public StyleSource(String url, String name, String shortdescription) {
+        super(url, name, shortdescription, true);
+    }
+
+    public StyleSource(SourceEntry entry) {
+        super(entry.url, entry.name, entry.shortdescription, entry.active);
+    }
+
+    abstract public void apply(MultiCascade mc, OsmPrimitive osm, double scale, OsmPrimitive multipolyOuterWay, boolean pretendWayIsClosed);
+
+    abstract public void loadStyleSource();
+}
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/xml/XmlStyleSource.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/xml/XmlStyleSource.java	(revision 3842)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/xml/XmlStyleSource.java	(revision 3843)
@@ -2,9 +2,12 @@
 package org.openstreetmap.josm.gui.mappaint.xml;
 
-import java.io.File;
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.IOException;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
@@ -19,8 +22,13 @@
 import org.openstreetmap.josm.gui.mappaint.MultiCascade;
 import org.openstreetmap.josm.gui.mappaint.Range;
+import org.openstreetmap.josm.gui.mappaint.StyleSource;
 import org.openstreetmap.josm.gui.preferences.SourceEntry;
+import org.openstreetmap.josm.io.MirroredInputStream;
 import org.openstreetmap.josm.tools.Utils;
-
-public class XmlStyleSource extends SourceEntry {
+import org.openstreetmap.josm.tools.XmlObjectParser;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+public class XmlStyleSource extends StyleSource {
 
     public final HashMap<String, IconPrototype> icons = new HashMap<String, IconPrototype>();
@@ -33,13 +41,44 @@
     public final LinkedList<AreaPrototype> areasList = new LinkedList<AreaPrototype>();
 
-    public boolean hasError = false;
-    public File zipIcons;
-
     public XmlStyleSource(String url, String name, String shortdescription) {
-        super(url, name, shortdescription, true);
+        super(url, name, shortdescription);
     }
 
     public XmlStyleSource(SourceEntry entry) {
-        super(entry.url, entry.name, entry.shortdescription, entry.active);
+        super(entry);
+    }
+
+    @Override
+    public void loadStyleSource() {
+        try {
+            MirroredInputStream in = new MirroredInputStream(url);
+            InputStream zip = in.getZipEntry("xml", "style");
+            InputStreamReader reader = null;
+            if (zip != null) {
+                reader = new InputStreamReader(zip);
+            } else {
+                reader = new InputStreamReader(in);
+            }
+
+            XmlObjectParser parser = new XmlObjectParser(new XmlStyleSourceHandler(this));
+            parser.startWithValidation(reader,
+                    "http://josm.openstreetmap.de/mappaint-style-1.0",
+                    "resource://data/mappaint-style.xsd");
+            while(parser.hasNext()) {
+            }
+            
+        } catch(IOException e) {
+            System.err.println(tr("Warning: failed to load Mappaint styles from ''{0}''. Exception was: {1}", url, e.toString()));
+            e.printStackTrace();
+            hasError = true;
+        } catch(SAXParseException e) {
+            System.err.println(tr("Warning: failed to parse Mappaint styles from ''{0}''. Error was: [{1}:{2}] {3}", url, e.getLineNumber(), e.getColumnNumber(), e.getMessage()));
+            e.printStackTrace();
+            hasError = true;
+        } catch(SAXException e) {
+            System.err.println(tr("Warning: failed to parse Mappaint styles from ''{0}''. Error was: {1}", url, e.getMessage()));
+            e.printStackTrace();
+            hasError = true;
+        }
     }
 
@@ -220,4 +259,5 @@
      }
 
+    @Override
     public void apply(MultiCascade mc, OsmPrimitive osm, double scale, OsmPrimitive multipolyOuterWay, boolean pretendWayIsClosed) {
         Cascade def = mc.getCascade("default");
Index: trunk/src/org/openstreetmap/josm/gui/preferences/SourceEntry.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/SourceEntry.java	(revision 3842)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/SourceEntry.java	(revision 3843)
@@ -104,3 +104,9 @@
         return name == null ? "standard" : name;
     }
+
+    public boolean isLocal() {
+        if (url.startsWith("http://") || url.startsWith("resource://"))
+            return false;
+        return true;
+    }
 }
