Index: trunk/src/org/openstreetmap/josm/actions/JosmAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/JosmAction.java	(revision 10352)
+++ trunk/src/org/openstreetmap/josm/actions/JosmAction.java	(revision 10353)
@@ -16,5 +16,9 @@
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.gui.layer.LayerManager.LayerAddEvent;
 import org.openstreetmap.josm.gui.layer.LayerManager.LayerChangeListener;
+import org.openstreetmap.josm.gui.layer.LayerManager.LayerOrderChangeEvent;
+import org.openstreetmap.josm.gui.layer.LayerManager.LayerRemoveEvent;
+import org.openstreetmap.josm.gui.layer.MainLayerManager;
 import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeEvent;
 import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeListener;
@@ -28,5 +32,8 @@
  * Base class helper for all Actions in JOSM. Just to make the life easier.
  *
- * A JosmAction is a {@link LayerChangeListener} and a {@link SelectionChangedListener}. Upon
+ * This action allows you to set up an icon, a tooltip text, a globally registered shortcut, register it in the main toolbar and set up
+ * layer/selection listeners that call {@link #updateEnabledState()} whenever the global context is changed.
+ *
+ * A JosmAction can register a {@link LayerChangeListener} and a {@link SelectionChangedListener}. Upon
  * a layer change event or a selection change event it invokes {@link #updateEnabledState()}.
  * Subclasses can override {@link #updateEnabledState()} in order to update the {@link #isEnabled()}-state
@@ -44,19 +51,6 @@
     protected transient Shortcut sc;
     private transient LayerChangeAdapter layerChangeAdapter;
+    private transient ActiveLayerChangeAdapter activeLayerChangeAdapter;
     private transient SelectionChangeAdapter selectionChangeAdapter;
-
-    /**
-     * Returns the shortcut for this action.
-     * @return the shortcut for this action, or "No shortcut" if none is defined
-     */
-    public Shortcut getShortcut() {
-        if (sc == null) {
-            sc = Shortcut.registerShortcut("core:none", tr("No Shortcut"), KeyEvent.CHAR_UNDEFINED, Shortcut.NONE);
-            // as this shortcut is shared by all action that don't want to have a shortcut,
-            // we shouldn't allow the user to change it...
-            // this is handled by special name "core:none"
-        }
-        return sc;
-    }
 
     /**
@@ -178,4 +172,45 @@
     }
 
+
+    /**
+     * Installs the listeners to this action.
+     * <p>
+     * This should either never be called or only called in the constructor of this action.
+     * <p>
+     * All registered adapters should be removed in {@link #destroy()}
+     */
+    protected void installAdapters() {
+        // make this action listen to layer change and selection change events
+        if (listenToLayerChange()) {
+            layerChangeAdapter = new LayerChangeAdapter();
+            activeLayerChangeAdapter = new ActiveLayerChangeAdapter();
+            getLayerManager().addLayerChangeListener(layerChangeAdapter);
+            getLayerManager().addActiveLayerChangeListener(activeLayerChangeAdapter);
+        }
+        if (listenToSelectionChange()) {
+            selectionChangeAdapter = new SelectionChangeAdapter();
+            DataSet.addSelectionListener(selectionChangeAdapter);
+        }
+        initEnabledState();
+    }
+
+    /**
+     * Overwrite this if {@link #updateEnabledState()} should be called when the active / availabe layers change. Default is true.
+     * @return <code>true</code> if a {@link LayerChangeListener} and a {@link ActiveLayerChangeListener} should be registered.
+     * @since 10352
+     */
+    protected boolean listenToLayerChange() {
+        return true;
+    }
+
+    /**
+     * Overwrite this if {@link #updateEnabledState()} should be called when the selection changed. Default is true.
+     * @return <code>true</code> if a {@link SelectionChangedListener} should be registered.
+     * @since 10352
+     */
+    protected boolean listenToSelectionChange() {
+        return true;
+    }
+
     @Override
     public void destroy() {
@@ -184,7 +219,10 @@
         }
         if (layerChangeAdapter != null) {
-            Main.getLayerManager().removeActiveLayerChangeListener(layerChangeAdapter);
-        }
-        DataSet.removeSelectionListener(selectionChangeAdapter);
+            getLayerManager().removeLayerChangeListener(layerChangeAdapter);
+            getLayerManager().removeActiveLayerChangeListener(activeLayerChangeAdapter);
+        }
+        if (selectionChangeAdapter != null) {
+            DataSet.removeSelectionListener(selectionChangeAdapter);
+        }
     }
 
@@ -198,4 +236,18 @@
 
     /**
+     * Returns the shortcut for this action.
+     * @return the shortcut for this action, or "No shortcut" if none is defined
+     */
+    public Shortcut getShortcut() {
+        if (sc == null) {
+            sc = Shortcut.registerShortcut("core:none", tr("No Shortcut"), KeyEvent.CHAR_UNDEFINED, Shortcut.NONE);
+            // as this shortcut is shared by all action that don't want to have a shortcut,
+            // we shouldn't allow the user to change it...
+            // this is handled by special name "core:none"
+        }
+        return sc;
+    }
+
+    /**
      * Sets the tooltip text of this action.
      * @param tooltip The text to display in tooltip. Can be {@code null}
@@ -208,10 +260,24 @@
 
     /**
+     * Gets the layer manager used for this action. Defaults to the main layer manager but you can overwrite this.
+     * <p>
+     * The layer manager must be available when {@link #installAdapters()} is called and must not change.
+     *
+     * @return The layer manager.
+     * @since 10352
+     */
+    public MainLayerManager getLayerManager() {
+        return Main.getLayerManager();
+    }
+
+    /**
      * Replies the current edit layer
      *
      * @return the current edit layer. null, if no edit layer exists
-     */
+     * @deprecated Use {@link #getLayerManager()}.getEditLayer() instead. To be removed in end of 2016.
+     */
+    @Deprecated
     public static OsmDataLayer getEditLayer() {
-        return Main.main != null ? Main.main.getEditLayer() : null;
+        return Main.getLayerManager().getEditLayer();
     }
 
@@ -220,16 +286,9 @@
      *
      * @return the current dataset. null, if no current dataset exists
-     */
+     * @deprecated Use {@link #getLayerManager()}.getEditDataSet() instead. To be removed in end of 2016.
+     */
+    @Deprecated
     public static DataSet getCurrentDataSet() {
-        return Main.main != null ? Main.main.getCurrentDataSet() : null;
-    }
-
-    protected void installAdapters() {
-        // make this action listen to layer change and selection change events
-        layerChangeAdapter = new LayerChangeAdapter();
-        selectionChangeAdapter = new SelectionChangeAdapter();
-        Main.getLayerManager().addActiveLayerChangeListener(layerChangeAdapter);
-        DataSet.addSelectionListener(selectionChangeAdapter);
-        initEnabledState();
+        return Main.getLayerManager().getEditDataSet();
     }
 
@@ -273,4 +332,5 @@
      * @see #updateEnabledState(Collection)
      * @see #initEnabledState()
+     * @see #listenToLayerChange()
      */
     protected void updateEnabledState() {
@@ -286,4 +346,5 @@
      * @see #updateEnabledState()
      * @see #initEnabledState()
+     * @see #listenToSelectionChange()
      */
     protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
@@ -293,5 +354,30 @@
      * Adapter for layer change events. Runs updateEnabledState() whenever the active layer changed.
      */
-    protected class LayerChangeAdapter implements ActiveLayerChangeListener {
+    protected class LayerChangeAdapter implements LayerChangeListener {
+        @Override
+        public void layerAdded(LayerAddEvent e) {
+            updateEnabledState();
+        }
+
+        @Override
+        public void layerRemoving(LayerRemoveEvent e) {
+            updateEnabledState();
+        }
+
+        @Override
+        public void layerOrderChanged(LayerOrderChangeEvent e) {
+            updateEnabledState();
+        }
+
+        @Override
+        public String toString() {
+            return "LayerChangeAdapter [" + JosmAction.this.toString() + ']';
+        }
+    }
+
+    /**
+     * Adapter for layer change events. Runs updateEnabledState() whenever the active layer changed.
+     */
+    protected class ActiveLayerChangeAdapter implements ActiveLayerChangeListener {
         @Override
         public void activeOrEditLayerChanged(ActiveLayerChangeEvent e) {
@@ -301,5 +387,5 @@
         @Override
         public String toString() {
-            return "LayerChangeAdapter [" + JosmAction.this.toString() + ']';
+            return "ActiveLayerChangeAdapter [" + JosmAction.this.toString() + ']';
         }
     }
