Changeset 1890 in josm for trunk


Ignore:
Timestamp:
2009-08-02T23:15:26+02:00 (15 years ago)
Author:
Gubaer
Message:

update: rewrite of layer dialog
new: allows multiple selection of layers in the dialog
new: move up, move down, toggle visibility, and delete on multiple layers
new: merge from an arbitrary layer into another layer, not only from the first into the second
new: new action for merging of the currently selected primitives on an arbitrary layer
new: make "active" layer explicit (special icon); activating a layer automatically moves it in the first position
refactoring: public fields 'name' and 'visible' on Layer are @deprecated. Use the setter/getters instead, Layer now emits PropertyChangeEvents if name or visibility are changed.

Location:
trunk
Files:
8 added
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/actions/RenameLayerAction.java

    r1861 r1890  
    4343    public void actionPerformed(ActionEvent e) {
    4444        Box panel = Box.createVerticalBox();
    45         final JTextField name = new JTextField(layer.name);
     45        final JTextField name = new JTextField(layer.getName());
    4646        panel.add(name);
    4747        JCheckBox filerename = new JCheckBox(tr("Also rename the file"));
     
    105105            }
    106106        }
    107         layer.name = nameText;
     107        layer.setName(nameText);
    108108        Main.parent.repaint();
    109109    }
  • trunk/src/org/openstreetmap/josm/actions/SaveActionBase.java

    r1879 r1890  
    7272        save(file, layer);
    7373
    74         layer.name = file.getName();
     74        layer.setName(file.getName());
    7575        layer.setAssociatedFile(file);
    7676        Main.parent.repaint();
  • trunk/src/org/openstreetmap/josm/gui/MainMenu.java

    r1811 r1890  
    4040import org.openstreetmap.josm.actions.JoinNodeWayAction;
    4141import org.openstreetmap.josm.actions.JosmAction;
     42import org.openstreetmap.josm.actions.MergeLayerAction;
    4243import org.openstreetmap.josm.actions.MergeNodesAction;
     44import org.openstreetmap.josm.actions.MergeSelectionAction;
    4345import org.openstreetmap.josm.actions.MirrorAction;
    4446import org.openstreetmap.josm.actions.NewAction;
     
    110112    public final JosmAction duplicate = new DuplicateAction();
    111113    public final JosmAction delete = new DeleteAction();
     114    public final JosmAction merge = new MergeLayerAction();
     115    public final JosmAction mergeSelected = new MergeSelectionAction();
    112116    public final JosmAction selectAll = new SelectAllAction();
    113117    public final JosmAction unselectAll = new UnselectAllAction();
     
    213217        add(editMenu, duplicate);
    214218        add(editMenu, delete);
     219        editMenu.addSeparator();
     220        add(editMenu,merge);
     221        add(editMenu,mergeSelected);
    215222        editMenu.addSeparator();
    216223        add(editMenu, selectAll);
  • trunk/src/org/openstreetmap/josm/gui/MapFrame.java

    r1677 r1890  
    100100
    101101        toolBarToggle.setFloatable(false);
    102         addToggleDialog(new LayerListDialog(this));
     102        LayerListDialog.createInstance(this);
     103        addToggleDialog(LayerListDialog.getInstance());
    103104        addToggleDialog(new PropertiesDialog(this));
    104105        addToggleDialog(new HistoryDialog());
     
    133134     */
    134135    public void destroy() {
    135         for (ToggleDialog t : allDialogs)
     136        for (ToggleDialog t : allDialogs) {
    136137            t.close();
     138        }
    137139        for (int i = 0; i < toolBarActions.getComponentCount(); ++i)
    138             if (toolBarActions.getComponent(i) instanceof Destroyable)
     140            if (toolBarActions.getComponent(i) instanceof Destroyable) {
    139141                ((Destroyable)toolBarActions).destroy();
     142            }
    140143        for (int i = 0; i < toolBarToggle.getComponentCount(); ++i)
    141             if (toolBarToggle.getComponent(i) instanceof Destroyable)
     144            if (toolBarToggle.getComponent(i) instanceof Destroyable) {
    142145                ((Destroyable)toolBarToggle).destroy();
     146            }
    143147
    144148        // remove menu entries
     
    195199        boolean old = isVisible();
    196200        super.setVisible(aFlag);
    197         if (old != aFlag)
     201        if (old != aFlag) {
    198202            firePropertyChange("visible", old, aFlag);
     203        }
    199204    }
    200205
     
    209214        if (mapMode == this.mapMode)
    210215            return;
    211         if (this.mapMode != null)
     216        if (this.mapMode != null) {
    212217            this.mapMode.exitMode();
     218        }
    213219        this.mapMode = mapMode;
    214220        mapMode.enterMode();
     
    230236        if(Main.pref.getBoolean("sidetoolbar.visible", true))
    231237        {
    232             if(Main.pref.getBoolean("sidetoolbar.scrollable", true))
     238            if(Main.pref.getBoolean("sidetoolbar.scrollable", true)) {
    233239                panel.add(new ScrollViewport(jb, ScrollViewport.VERTICAL_DIRECTION),
    234                 BorderLayout.WEST);
    235             else
     240                        BorderLayout.WEST);
     241            } else {
    236242                panel.add(jb, BorderLayout.WEST);
    237         }
    238         if (statusLine != null && Main.pref.getBoolean("statusline.visible", true))
     243            }
     244        }
     245        if (statusLine != null && Main.pref.getBoolean("statusline.visible", true)) {
    239246            panel.add(statusLine, BorderLayout.SOUTH);
     247        }
    240248    }
    241249}
  • trunk/src/org/openstreetmap/josm/gui/MapView.java

    r1854 r1890  
    1515import java.awt.geom.GeneralPath;
    1616import java.awt.image.BufferedImage;
     17import java.beans.PropertyChangeEvent;
     18import java.beans.PropertyChangeListener;
    1719import java.util.ArrayList;
    1820import java.util.Collection;
     
    5759 * @author imi
    5860 */
    59 public class MapView extends NavigatableComponent {
     61public class MapView extends NavigatableComponent implements PropertyChangeListener {
    6062
    6163
     
    177179            }
    178180        }
     181        layer.addPropertyChangeListener(this);
    179182        AudioPlayer.reset();
    180183        repaint();
     
    203206     */
    204207    public boolean isActiveLayerVisible() {
    205         return isActiveLayerDrawable() && activeLayer.visible;
     208        return isActiveLayerDrawable() && activeLayer.isVisible();
    206209    }
    207210
     
    212215    public void removeLayer(Layer layer) {
    213216        if (layer == activeLayer) {
     217            for (Layer.LayerChangeListener l : Layer.listeners) {
     218                l.activeLayerChange(layer, null);
     219            }
    214220            activeLayer = null;
    215221        }
     
    219225            }
    220226        }
     227        layer.removePropertyChangeListener(this);
    221228        layer.destroy();
    222229        AudioPlayer.reset();
     
    283290        for (int i = layers.size()-1; i >= 0; --i) {
    284291            Layer l = layers.get(i);
    285             if (l.visible/* && l != getActiveLayer()*/) {
     292            if (l.isVisible()/* && l != getActiveLayer()*/) {
    286293                l.paint(tempG, this);
    287294            }
     
    472479        return temporaryLayers.remove(mvp);
    473480    }
     481
     482    public void propertyChange(PropertyChangeEvent evt) {
     483        if (evt.getPropertyName().equals(Layer.VISIBLE_PROP)) {
     484            repaint();
     485        }
     486    }
    474487}
  • trunk/src/org/openstreetmap/josm/gui/dialogs/LayerListDialog.java

    r1880 r1890  
    99import java.awt.Point;
    1010import java.awt.event.ActionEvent;
    11 import java.awt.event.ActionListener;
    1211import java.awt.event.KeyEvent;
    1312import java.awt.event.MouseAdapter;
    1413import java.awt.event.MouseEvent;
     14import java.beans.PropertyChangeEvent;
     15import java.beans.PropertyChangeListener;
     16import java.util.ArrayList;
    1517import java.util.Collection;
     18import java.util.Collections;
     19import java.util.List;
     20import java.util.concurrent.CopyOnWriteArrayList;
    1621
    1722import javax.swing.AbstractAction;
    18 import javax.swing.Action;
    1923import javax.swing.DefaultListCellRenderer;
    2024import javax.swing.DefaultListModel;
     25import javax.swing.DefaultListSelectionModel;
    2126import javax.swing.Icon;
    2227import javax.swing.JLabel;
     
    2530import javax.swing.JPanel;
    2631import javax.swing.JScrollPane;
     32import javax.swing.ListModel;
    2733import javax.swing.ListSelectionModel;
    2834import javax.swing.UIManager;
     35import javax.swing.event.ListDataEvent;
     36import javax.swing.event.ListDataListener;
    2937import javax.swing.event.ListSelectionEvent;
    3038import javax.swing.event.ListSelectionListener;
    3139
    3240import org.openstreetmap.josm.Main;
     41import org.openstreetmap.josm.actions.MergeLayerAction;
    3342import org.openstreetmap.josm.gui.ConditionalOptionPaneUtil;
    3443import org.openstreetmap.josm.gui.ExtendedDialog;
     
    4049import org.openstreetmap.josm.gui.layer.Layer.LayerChangeListener;
    4150import org.openstreetmap.josm.tools.ImageProvider;
     51import org.openstreetmap.josm.tools.Shortcut;
    4252import org.openstreetmap.josm.tools.ImageProvider.OverlayPosition;
    43 import org.openstreetmap.josm.tools.Shortcut;
    4453
    4554/**
    46  * A component that manages the list of all layers and react to selection changes
    47  * by setting the active layer in the mapview.
    48  *
    49  * @author imi
     55 * This is a toggle dialog which displays the list of layers. Actions allow to
     56 * change the ordering the layer, to hide/show layers, to activate layers
     57 * and to delete layers.
     58 *
    5059 */
    51 public class LayerListDialog extends ToggleDialog implements LayerChangeListener {
    52 
    53     /**
    54      * The last layerlist created. Used to update the list in the Show/Hide and Delete actions.
    55      * TODO: Replace with Listener-Pattern.
    56      */
    57     static JList instance;
    58     private JScrollPane listScrollPane;
    59 
    60     public final static class DeleteLayerAction extends AbstractAction {
    61 
    62         private final Layer layer;
    63 
     60public class LayerListDialog extends ToggleDialog {
     61
     62    /** the unique instance of the dialog */
     63    static private LayerListDialog instance;
     64
     65    /**
     66     * Creates the instance of the dialog. It's connected to the map frame <code>mapFrame</code>
     67     *
     68     * @param mapFrame the map frame
     69     */
     70    static public void createInstance(MapFrame mapFrame) {
     71        instance = new LayerListDialog(mapFrame);
     72    }
     73
     74    /**
     75     * Replies the instance of the dialog
     76     *
     77     * @return the instance of the dialog
     78     * @throws IllegalStateException thrown, if the dialog is not created yet
     79     * @see #createInstance(MapFrame)
     80     */
     81    static public LayerListDialog getInstance() throws IllegalStateException {
     82        if (instance == null)
     83            throw new IllegalStateException(tr("Dialog not created yet. Invoke createInstance() first"));
     84        return instance;
     85    }
     86
     87    /** the model for the layer list */
     88    private LayerListModel model;
     89
     90    /** the selection model */
     91    private DefaultListSelectionModel selectionModel;
     92
     93    /** the list of layers */
     94    private LayerList layerList;
     95
     96    protected JPanel createButtonPanel() {
     97        JPanel buttonPanel = new JPanel(new GridLayout(1, 5));
     98
     99        // -- move up action
     100        MoveUpAction moveUpAction = new MoveUpAction();
     101        adaptTo(moveUpAction, model);
     102        adaptTo(moveUpAction,selectionModel);
     103        buttonPanel.add(new SideButton(moveUpAction));
     104
     105        // -- move down action
     106        MoveDownAction moveDownAction = new MoveDownAction();
     107        adaptTo(moveDownAction, model);
     108        adaptTo(moveDownAction,selectionModel);
     109        buttonPanel.add(new SideButton(moveDownAction));
     110
     111        // -- activate action
     112        ActivateLayerAction activateLayerAction = new ActivateLayerAction();
     113        adaptTo(activateLayerAction, selectionModel);
     114        buttonPanel.add(new SideButton(activateLayerAction, "activate"));
     115
     116        // -- show hide action
     117        ShowHideLayerAction showHideLayerAction = new ShowHideLayerAction();
     118        adaptTo(showHideLayerAction, selectionModel);
     119        buttonPanel.add(new SideButton(showHideLayerAction, "showhide"));
     120
     121        // -- merge layer action
     122        MergeAction mergeLayerAction = new MergeAction();
     123        adaptTo(mergeLayerAction, model);
     124        adaptTo(mergeLayerAction,selectionModel);
     125        buttonPanel.add(new SideButton(mergeLayerAction));
     126
     127        //-- delete layer action
     128        DeleteLayerAction deleteLayerAction = new DeleteLayerAction();
     129        adaptTo(deleteLayerAction, selectionModel);
     130        buttonPanel.add(new SideButton(deleteLayerAction, "delete"));
     131
     132        return buttonPanel;
     133    }
     134
     135    /**
     136     * Create an layerlist and attach it to the given mapView.
     137     */
     138    protected LayerListDialog(MapFrame mapFrame) {
     139        super(tr("Layers"), "layerlist", tr("Open a list of all loaded layers."),
     140                Shortcut.registerShortcut("subwindow:layers", tr("Toggle: {0}", tr("Layers")), KeyEvent.VK_L, Shortcut.GROUP_LAYER), 100);
     141
     142        // create the models
     143        //
     144        selectionModel = new DefaultListSelectionModel();
     145        selectionModel.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
     146        model = new LayerListModel(selectionModel);
     147        Layer.listeners.add(model);
     148
     149        // create the list control
     150        //
     151        layerList = new LayerList(model);
     152        layerList.setSelectionModel(selectionModel);
     153        layerList.addMouseListener(new LayerListMouseAdapter());
     154        layerList.setBackground(UIManager.getColor("Button.background"));
     155        layerList.setCellRenderer(new LayerListCellRenderer());
     156        add(new JScrollPane(layerList), BorderLayout.CENTER);
     157
     158        // init the model
     159        //
     160        final MapView mapView = mapFrame.mapView;
     161        model.populate(mapView.getAllLayers());
     162        model.setSelectedLayer(mapView.getActiveLayer());
     163        model.addLayerListModelListener(
     164                new LayerListModelListener() {
     165                    public void makeVisible(int index, Layer layer) {
     166                        layerList.ensureIndexIsVisible(index);
     167                    }
     168                }
     169        );
     170
     171        add(createButtonPanel(), BorderLayout.SOUTH);
     172    }
     173
     174    public LayerListModel getModel() {
     175        return model;
     176    }
     177
     178    private interface IEnabledStateUpdating {
     179        void updateEnabledState();
     180    }
     181
     182    protected void adaptTo(final IEnabledStateUpdating listener, ListSelectionModel listSelectionModel) {
     183        listSelectionModel.addListSelectionListener(
     184                new ListSelectionListener() {
     185                    public void valueChanged(ListSelectionEvent e) {
     186                        listener.updateEnabledState();
     187                    }
     188                }
     189        );
     190    }
     191
     192    protected void adaptTo(final IEnabledStateUpdating listener, ListModel listModel) {
     193        listModel.addListDataListener(
     194                new ListDataListener() {
     195                    public void contentsChanged(ListDataEvent e) {
     196                        listener.updateEnabledState();
     197                    }
     198
     199                    public void intervalAdded(ListDataEvent e) {
     200                        listener.updateEnabledState();
     201                    }
     202
     203                    public void intervalRemoved(ListDataEvent e) {
     204                        listener.updateEnabledState();
     205                    }
     206                }
     207        );
     208    }
     209
     210    /**
     211     * The action to delete the currently selected layer
     212     */
     213    public final  class DeleteLayerAction extends AbstractAction implements IEnabledStateUpdating {
     214
     215        private  Layer layer;
     216
     217        /**
     218         * Creates a {@see DeleteLayerAction} for a specific layer.
     219         *
     220         * @param layer the layer. Must not be null.
     221         * @exception IllegalArgumentException thrown, if layer is null
     222         */
    64223        public DeleteLayerAction(Layer layer) {
    65             super(tr("Delete"), ImageProvider.get("dialogs", "delete"));
     224            this();
     225            if (layer == null)
     226                throw new IllegalArgumentException(tr("parameter ''{0}'' must not be null", "layer"));
     227            this.layer = layer;
     228            putValue(NAME, tr("Delete"));
     229            updateEnabledState();
     230        }
     231
     232        /**
     233         * Creates a {@see DeleteLayerAction} which will delete the currently
     234         * selected layers in the layer dialog.
     235         *
     236         */
     237        public DeleteLayerAction() {
     238            putValue(SMALL_ICON,ImageProvider.get("dialogs", "delete"));
    66239            putValue(SHORT_DESCRIPTION, tr("Delete the selected layer."));
    67240            putValue("help", "Action/LayerDelete");
     241            updateEnabledState();
     242        }
     243
     244        protected boolean confirmSkipSaving(OsmDataLayer layer) {
     245            int result = new ExtendedDialog(Main.parent,
     246                    tr("Unsaved Changes"),
     247                    tr("There are unsaved changes in the layer''{0}''. Delete the layer anwyay?",layer.getName()),
     248                    new String[] {tr("Delete Layer"), tr("Cancel")},
     249                    new String[] {"dialogs/delete.png", "cancel.png"}).getValue();
     250
     251            return result != 1;
     252        }
     253
     254        protected boolean confirmDeleteLayer(Layer layer) {
     255            return ConditionalOptionPaneUtil.showConfirmationDialog(
     256                    "delete_layer",
     257                    Main.parent,
     258                    tr("Do you really want to delete the whole layer ''{0}''?", layer.getName()),
     259                    tr("Confirmation"),
     260                    JOptionPane.YES_NO_OPTION,
     261                    JOptionPane.QUESTION_MESSAGE,
     262                    JOptionPane.YES_OPTION);
     263        }
     264
     265        public void deleteLayer(Layer layer) {
     266            if (layer == null)
     267                return;
     268            if (layer instanceof OsmDataLayer) {
     269                OsmDataLayer dataLayer = (OsmDataLayer)layer;
     270                if (dataLayer.isModified() && ! confirmSkipSaving(dataLayer))
     271                    return;
     272                else if (!confirmDeleteLayer(dataLayer))
     273                    return;
     274
     275            } else {
     276                if (!confirmDeleteLayer(layer))
     277                    return;
     278            }
     279            // model and view are going to be updated via LayerChangeListener
     280            //
     281            Main.main.removeLayer(layer);
     282        }
     283
     284        public void actionPerformed(ActionEvent e) {
     285            if (this.layer == null) {
     286                List<Layer> selectedLayers = getModel().getSelectedLayers();
     287                for (Layer layer: selectedLayers) {
     288                    deleteLayer(layer);
     289                }
     290            } else {
     291                deleteLayer(this.layer);
     292            }
     293        }
     294
     295        public void updateEnabledState() {
     296            if (layer == null) {
     297                setEnabled(! getModel().getSelectedLayers().isEmpty());
     298            } else {
     299                setEnabled(true);
     300            }
     301        }
     302    }
     303
     304    public final class ShowHideLayerAction extends AbstractAction implements IEnabledStateUpdating {
     305        private  Layer layer;
     306
     307        /**
     308         * Creates a {@see ShowHideLayerAction} which toggle the visibility of
     309         * a specific layer.
     310         *
     311         * @param layer  the layer. Must not be null.
     312         * @exception IllegalArgumentException thrown, if layer is null
     313         */
     314        public ShowHideLayerAction(Layer layer) throws IllegalArgumentException {
     315            this();
     316            if (layer == null)
     317                throw new IllegalArgumentException(tr("parameter ''{0}'' must not be null", "layer"));
    68318            this.layer = layer;
    69         }
    70 
    71         public void actionPerformed(ActionEvent e) {
    72             int sel = instance.getSelectedIndex();
    73             Layer l = layer != null ? layer : (Layer)instance.getSelectedValue();
    74             if(l == null)
    75                 return;
    76             if (l instanceof OsmDataLayer)
    77             {
    78                 if (((OsmDataLayer)l).isModified())
    79                 {
    80                     int result = new ExtendedDialog(Main.parent, tr("Unsaved Changes"),
    81                             tr("There are unsaved changes. Delete the layer anwyay?"),
    82                             new String[] {tr("Delete Layer"), tr("Cancel")},
    83                             new String[] {"dialogs/delete.png", "cancel.png"}).getValue();
    84 
    85                     if(result != 1) return;
    86                 }
    87                 else if (!ConditionalOptionPaneUtil.showConfirmationDialog(
    88                         "delete_layer",
    89                         Main.parent,
    90                         tr("Do you really want to delete the whole layer?"),
    91                         tr("Confirmation"),
    92                         JOptionPane.YES_NO_OPTION,
    93                         JOptionPane.QUESTION_MESSAGE,
    94                         JOptionPane.YES_OPTION))
    95                     return;
    96             }
    97             Main.main.removeLayer(l);
    98             if (sel >= instance.getModel().getSize()) {
    99                 sel = instance.getModel().getSize()-1;
    100             }
    101             if (instance.getSelectedValue() == null) {
    102                 instance.setSelectedIndex(sel);
    103             }
    104             if (Main.map != null) {
    105                 Main.map.mapView.setActiveLayer((Layer)instance.getSelectedValue());
    106             }
    107         }
    108     }
    109 
    110     public final static class ShowHideLayerAction extends AbstractAction {
    111         private final Layer layer;
    112 
    113         public ShowHideLayerAction(Layer layer) {
    114             super(tr("Show/Hide"), ImageProvider.get("dialogs", "showhide"));
     319            putValue(NAME, tr("Show/Hide"));
     320            updateEnabledState();
     321        }
     322
     323        /**
     324         * Creates a {@see ShowHideLayerAction} which will toggle the visibility of
     325         * the currently selected layers
     326         *
     327         */
     328        public ShowHideLayerAction() {
     329            putValue(SMALL_ICON, ImageProvider.get("dialogs", "showhide"));
    115330            putValue(SHORT_DESCRIPTION, tr("Toggle visible state of the selected layer."));
    116331            putValue("help", "Action/LayerShowHide");
     332            updateEnabledState();
     333        }
     334
     335        public void actionPerformed(ActionEvent e) {
     336            if (layer != null) {
     337                layer.toggleVisible();
     338            } else {
     339                for(Layer layer: model.getSelectedLayers()) {
     340                    layer.toggleVisible();
     341                }
     342            }
     343        }
     344
     345        public void updateEnabledState() {
     346            if (layer == null) {
     347                setEnabled(! getModel().getSelectedLayers().isEmpty());
     348            } else {
     349                setEnabled(true);
     350            }
     351        }
     352    }
     353
     354    /**
     355     * The action to activate the currently selected layer
     356     */
     357
     358    public final class ActivateLayerAction extends AbstractAction implements IEnabledStateUpdating{
     359        private  Layer layer;
     360
     361        public ActivateLayerAction(Layer layer) throws IllegalArgumentException {
     362            this();
     363            if (layer == null)
     364                throw new IllegalArgumentException(tr("parameter ''{0}'' must not be null", "layer"));
    117365            this.layer = layer;
     366            putValue(NAME, tr("Activate"));
     367            updateEnabledState();
     368        }
     369
     370        public ActivateLayerAction() {
     371            putValue(SMALL_ICON, ImageProvider.get("dialogs", "activate"));
     372            putValue(SHORT_DESCRIPTION, tr("Activate the selected layer"));
     373            putValue("help", "Action/ActivateLayer");
     374            updateEnabledState();
    118375        }
    119376
    120377        public void actionPerformed(ActionEvent e) {
    121             Layer l = layer == null ? (Layer)instance.getSelectedValue() : layer;
    122             if(l == null)
     378            Layer toActivate;
     379            if (layer != null) {
     380                toActivate = layer;
     381            } else {
     382                toActivate = model.getSelectedLayers().get(0);
     383            }
     384            getModel().activateLayer(toActivate);
     385        }
     386
     387        protected boolean isActiveLayer(Layer layer) {
     388            if (Main.map == null) return false;
     389            if (Main.map.mapView == null) return false;
     390            return Main.map.mapView.getActiveLayer() == layer;
     391        }
     392
     393        public void updateEnabledState() {
     394            if (layer == null) {
     395                if (getModel().getSelectedLayers().size() != 1) {
     396                    setEnabled(false);
     397                    return;
     398                }
     399                Layer selectedLayer = getModel().getSelectedLayers().get(0);
     400                setEnabled(!isActiveLayer(selectedLayer));
     401            } else {
     402                setEnabled(!isActiveLayer(layer));
     403            }
     404        }
     405    }
     406
     407    /**
     408     * The action to merge the currently selected layer into another layer.
     409     */
     410    public final class MergeAction extends AbstractAction implements IEnabledStateUpdating {
     411        private  Layer layer;
     412
     413        public MergeAction(Layer layer) throws IllegalArgumentException {
     414            this();
     415            if (layer == null)
     416                throw new IllegalArgumentException(tr("parameter ''{0}'' must not be null", "layer"));
     417            this.layer = layer;
     418            putValue(NAME, tr("Merge"));
     419            updateEnabledState();
     420        }
     421
     422        public MergeAction() {
     423            putValue(SMALL_ICON, ImageProvider.get("dialogs", "mergedown"));
     424            putValue(SHORT_DESCRIPTION, tr("Merge this layer into another layer"));
     425            putValue("help", "Action/MergeLayer");
     426            updateEnabledState();
     427        }
     428
     429        public void actionPerformed(ActionEvent e) {
     430            if (layer != null) {
     431                new MergeLayerAction().merge(layer);
     432            } else {
     433                Layer selectedLayer = getModel().getSelectedLayers().get(0);
     434                new MergeLayerAction().merge(selectedLayer);
     435            }
     436        }
     437
     438        protected boolean isActiveLayer(Layer layer) {
     439            if (Main.map == null) return false;
     440            if (Main.map.mapView == null) return false;
     441            return Main.map.mapView.getActiveLayer() == layer;
     442        }
     443
     444        public void updateEnabledState() {
     445            if (layer == null) {
     446                if (getModel().getSelectedLayers().size() != 1) {
     447                    setEnabled(false);
     448                    return;
     449                }
     450                Layer selectedLayer = getModel().getSelectedLayers().get(0);
     451                List<Layer> targets = getModel().getPossibleMergeTargets(selectedLayer);
     452                setEnabled(!targets.isEmpty());
     453            } else {
     454                List<Layer> targets = getModel().getPossibleMergeTargets(layer);
     455                setEnabled(!targets.isEmpty());
     456            }
     457        }
     458    }
     459
     460    /**
     461     * the list cell renderer used to render layer list entries
     462     *
     463     */
     464    class LayerListCellRenderer extends DefaultListCellRenderer {
     465
     466        protected boolean isActiveLayer(Layer layer) {
     467            if (Main.map == null) return false;
     468            if (Main.map.mapView == null) return false;
     469            return Main.map.mapView.getActiveLayer() == layer;
     470        }
     471
     472        @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
     473            Layer layer = (Layer)value;
     474            JLabel label = (JLabel)super.getListCellRendererComponent(list,
     475                    layer.getName(), index, isSelected, cellHasFocus);
     476            Icon icon = layer.getIcon();
     477            if (isActiveLayer(layer)) {
     478                icon = ImageProvider.overlay(icon, "overlay/active", OverlayPosition.SOUTHWEST);
     479            }
     480            if (!layer.isVisible()) {
     481                icon = ImageProvider.overlay(icon, "overlay/invisiblenew", OverlayPosition.SOUTHEAST);
     482            }
     483            label.setIcon(icon);
     484            label.setToolTipText(layer.getToolTipText());
     485            return label;
     486        }
     487    }
     488
     489    class LayerListMouseAdapter extends MouseAdapter {
     490
     491        private void openPopup(MouseEvent e) {
     492            Point p = e.getPoint();
     493            int index = layerList.locationToIndex(p);
     494            if (index < 0) return;
     495            if (!layerList.getCellBounds(index, index).contains(e.getPoint()))
    123496                return;
    124             l.visible = !l.visible;
    125             Main.map.mapView.repaint();
    126             instance.repaint();
    127         }
    128     }
    129 
    130     public final static class ShowHideMarkerText extends AbstractAction {
    131         private final Layer layer;
    132 
    133         public ShowHideMarkerText(Layer layer) {
    134             super(tr("Show/Hide Text/Icons"), ImageProvider.get("dialogs", "showhide"));
    135             putValue(SHORT_DESCRIPTION, tr("Toggle visible state of the marker text and icons."));
    136             putValue("help", "Action/ShowHideTextIcons");
    137             this.layer = layer;
     497            Layer layer = model.getLayer(index);
     498            LayerListPopup menu = new LayerListPopup(layerList, layer);
     499            menu.show(LayerListDialog.this, p.x, p.y-3);
     500        }
     501        @Override public void mousePressed(MouseEvent e) {
     502            if (e.isPopupTrigger()) {
     503                openPopup(e);
     504            }
     505        }
     506        @Override public void mouseReleased(MouseEvent e) {
     507            if (e.isPopupTrigger()) {
     508                openPopup(e);
     509            }
     510        }
     511        @Override public void mouseClicked(MouseEvent e) {
     512            if (e.getClickCount() == 2) {
     513                int index = layerList.locationToIndex(e.getPoint());
     514                if (!layerList.getCellBounds(index, index).contains(e.getPoint()))
     515                    return;
     516                Layer layer = model.getLayer(index);
     517                String current = Main.pref.get("marker.show "+layer.getName(),"show");
     518                Main.pref.put("marker.show "+layer.getName(), current.equalsIgnoreCase("show") ? "hide" : "show");
     519                layer.toggleVisible();
     520            }
     521        }
     522    }
     523
     524    /**
     525     * The action to move up the currently selected entries in the list.
     526     */
     527    class MoveUpAction extends AbstractAction implements  IEnabledStateUpdating{
     528        public MoveUpAction() {
     529            putValue(SMALL_ICON, ImageProvider.get("dialogs", "up"));
     530            putValue(SHORT_DESCRIPTION, tr("Move the selected layer one row up."));
     531            updateEnabledState();
     532        }
     533
     534        public void updateEnabledState() {
     535            setEnabled(model.canMoveUp());
    138536        }
    139537
    140538        public void actionPerformed(ActionEvent e) {
    141             Layer l = layer == null ? (Layer)instance.getSelectedValue() : layer;
    142             String current = Main.pref.get("marker.show "+l.name,"show");
    143             Main.pref.put("marker.show "+l.name, current.equalsIgnoreCase("show") ? "hide" : "show");
    144             Main.map.mapView.repaint();
    145             instance.repaint();
    146         }
    147     }
    148 
    149     /**
    150      * The data model for the list component.
    151      */
    152     DefaultListModel model = new DefaultListModel();
    153     /**
    154      * The merge action. This is only called, if the current selection and its
    155      * item below are editable datasets and the merge button is clicked.
    156      */
    157     private final SideButton mergeButton;
    158     /**
    159      * Button for moving layer up.
    160      */
    161     private final SideButton upButton;
    162     /**
    163      * Button for moving layer down.
    164      */
    165     private final SideButton downButton;
    166     /**
    167      * Button for delete layer.
    168      */
    169     private Action deleteAction = new DeleteLayerAction(null);
    170 
    171     /**
    172      * Create an layerlist and attach it to the given mapView.
    173      */
    174     public LayerListDialog(MapFrame mapFrame) {
    175         super(tr("Layers"), "layerlist", tr("Open a list of all loaded layers."),
    176                 Shortcut.registerShortcut("subwindow:layers", tr("Toggle: {0}", tr("Layers")), KeyEvent.VK_L, Shortcut.GROUP_LAYER), 100);
    177         instance = new JList(model) {
    178             @Override
    179             protected void processMouseEvent(MouseEvent e) {
    180                 // if the layer list is embedded in a detached dialog, the last row is
    181                 // is selected if a user clicks in the empty space *below* the last row.
    182                 // This mouse event filter prevents this.
    183                 //
    184                 int idx = locationToIndex(e.getPoint());
    185                 if (getCellBounds(idx, idx).contains(e.getPoint())) {
    186                     super.processMouseEvent(e);
    187                 }
    188             }
    189         };
    190         listScrollPane = new JScrollPane(instance);
    191         add(listScrollPane, BorderLayout.CENTER);
    192         instance.setBackground(UIManager.getColor("Button.background"));
    193         instance.setCellRenderer(new DefaultListCellRenderer(){
    194             @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
    195                 Layer layer = (Layer)value;
    196                 JLabel label = (JLabel)super.getListCellRendererComponent(list,
    197                         layer.name, index, isSelected, cellHasFocus);
    198                 Icon icon = layer.getIcon();
    199                 if (!layer.visible) {
    200                     icon = ImageProvider.overlay(icon, "overlay/invisible", OverlayPosition.SOUTHEAST);
    201                 }
    202                 label.setIcon(icon);
    203                 label.setToolTipText(layer.getToolTipText());
    204                 return label;
    205             }
    206         });
    207 
    208         final MapView mapView = mapFrame.mapView;
    209 
    210         Collection<Layer> data = mapView.getAllLayers();
    211         for (Layer l : data) {
    212             model.addElement(l);
    213         }
    214 
    215         instance.setSelectedValue(mapView.getActiveLayer(), true);
    216         instance.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    217         instance.addListSelectionListener(new ListSelectionListener(){
    218             public void valueChanged(ListSelectionEvent e) {
    219                 if (instance.getModel().getSize() == 0)
    220                     return;
    221                 if (instance.getSelectedIndex() == -1) {
    222                     instance.setSelectedIndex(e.getFirstIndex());
    223                 }
    224                 mapView.setActiveLayer((Layer)instance.getSelectedValue());
    225             }
    226         });
    227         Layer.listeners.add(this);
    228 
    229         instance.addMouseListener(new MouseAdapter(){
    230             private void openPopup(MouseEvent e) {
    231                 Point p = e.getPoint();
    232                 int index = instance.locationToIndex(p);
    233                 Layer layer = (Layer)instance.getModel().getElementAt(index);
    234                 LayerListPopup menu = new LayerListPopup(instance, layer);
    235                 menu.show(listScrollPane, p.x, p.y-3);
    236             }
    237             @Override public void mousePressed(MouseEvent e) {
    238                 if (e.isPopupTrigger()) {
    239                     openPopup(e);
    240                 }
    241             }
    242             @Override public void mouseReleased(MouseEvent e) {
    243                 if (e.isPopupTrigger()) {
    244                     openPopup(e);
    245                 }
    246             }
    247             @Override public void mouseClicked(MouseEvent e) {
    248                 if (e.getClickCount() == 2) {
    249                     int index = instance.locationToIndex(e.getPoint());
    250                     Layer layer = (Layer)instance.getModel().getElementAt(index);
    251                     String current = Main.pref.get("marker.show "+layer.name,"show");
    252                     Main.pref.put("marker.show "+layer.name, current.equalsIgnoreCase("show") ? "hide" : "show");
    253                     layer.visible = !layer.visible;
    254                     Main.map.mapView.repaint();
    255                     instance.repaint();
    256                 }
    257             }
    258         });
    259 
    260 
    261         // Buttons
    262         JPanel buttonPanel = new JPanel(new GridLayout(1, 5));
    263 
    264         ActionListener upDown = new ActionListener(){
    265             public void actionPerformed(ActionEvent e) {
    266                 Layer l = (Layer)instance.getSelectedValue();
    267                 int sel = instance.getSelectedIndex();
    268                 int selDest = e.getActionCommand().equals("up") ? sel-1 : sel+1;
    269                 mapView.moveLayer(l, selDest);
    270                 model.set(sel, model.get(selDest));
    271                 model.set(selDest, l);
    272                 instance.setSelectedIndex(selDest);
    273                 updateButtonEnabled();
    274                 mapView.repaint();
    275             }
    276         };
    277 
    278         upButton = new SideButton("up", "LayerList", tr("Move the selected layer one row up."), upDown);
    279         buttonPanel.add(upButton);
    280 
    281         downButton = new SideButton("down", "LayerList", tr("Move the selected layer one row down."), upDown);
    282         buttonPanel.add(downButton);
    283 
    284         buttonPanel.add(new SideButton(new ShowHideLayerAction(null), "showhide"));
    285         buttonPanel.add(new SideButton(deleteAction, "delete"));
    286 
    287         mergeButton = new SideButton("mergedown", "LayerList", tr("Merge the layer directly below into the selected layer."),
    288                 new ActionListener(){
    289             public void actionPerformed(ActionEvent e) {
    290                 Layer lTo = (Layer)instance.getSelectedValue();
    291                 Layer lFrom = (Layer)model.get(instance.getSelectedIndex()+1);
    292                 lTo.mergeFrom(lFrom);
    293                 mapView.removeLayer(lFrom);
    294                 updateButtonEnabled();
    295                 mapView.repaint();
    296             }
    297         });
    298         buttonPanel.add(mergeButton);
    299 
    300         add(buttonPanel, BorderLayout.SOUTH);
    301 
    302         updateButtonEnabled();
    303     }
    304 
    305     /**
    306      * Updates the state of the Buttons.
    307      */
    308     void updateButtonEnabled() {
    309         int sel = instance.getSelectedIndex();
    310         Layer l = (Layer)instance.getSelectedValue();
    311         boolean enable = model.getSize() > 1;
    312         enable = enable && sel < model.getSize()-1;
    313         enable = enable && ((Layer)model.get(sel+1)).isMergable(l);
    314         mergeButton.setEnabled(enable);
    315         upButton.setEnabled(sel > 0);
    316         downButton.setEnabled(sel >= 0 && sel < model.getSize()-1);
    317         deleteAction.setEnabled(!model.isEmpty());
    318 
    319         if(model.getSize() != 0) {
    320             setTitle(tr("Layers: {0}", model.getSize()), true);
    321         } else {
    322             setTitle(tr("Layers"), false);
    323         }
    324     }
    325 
    326     /**
    327      * Add the new layer to the list.
    328      */
    329     public void layerAdded(Layer newLayer) {
    330         int pos = Main.map.mapView.getLayerPos(newLayer);
    331         model.add(pos, newLayer);
    332         updateButtonEnabled();
    333     }
    334 
    335     public void layerRemoved(Layer oldLayer) {
    336         model.removeElement(oldLayer);
    337         if (model.isEmpty()) {
    338             Layer.listeners.remove(this);
    339             return;
    340         }
    341         if (instance.getSelectedIndex() == -1) {
    342             instance.setSelectedIndex(0);
    343         }
    344         updateButtonEnabled();
    345     }
    346 
    347     /**
    348      * If the newLayer is not the actual selection, select it.
    349      */
    350     public void activeLayerChange(Layer oldLayer, Layer newLayer) {
    351         if (newLayer != instance.getSelectedValue()) {
    352             instance.setSelectedValue(newLayer, true);
    353         }
    354         updateButtonEnabled();
     539            model.moveUp();
     540        }
     541    }
     542
     543    /**
     544     * The action to move down the currently selected entries in the list.
     545     */
     546    class MoveDownAction extends AbstractAction implements IEnabledStateUpdating {
     547        public MoveDownAction() {
     548            putValue(SMALL_ICON, ImageProvider.get("dialogs", "down"));
     549            putValue(SHORT_DESCRIPTION, tr("Move the selected layer one row down."));
     550            updateEnabledState();
     551        }
     552
     553        public void updateEnabledState() {
     554            setEnabled(model.canMoveDown());
     555        }
     556
     557        public void actionPerformed(ActionEvent e) {
     558            model.moveDown();
     559        }
     560    }
     561
     562    /**
     563     * Observer interface to be implemented by views using {@see LayerListModel}
     564     *
     565     */
     566    public interface LayerListModelListener {
     567        public void makeVisible(int index, Layer layer);
     568    }
     569
     570    /**
     571     * The layer list model. The model manages a list of layers and provides methods for
     572     * moving layers up and down, for toggling their visibiliy, for activating a layer.
     573     *
     574     * The model is a {@see ListModel} and it provides a {@see ListSelectionModel}. It expectes
     575     * to be configured with a {@see DefaultListSelectionModel}. The selection model is used
     576     * to update the selection state of views depending on messages sent to the model.
     577     *
     578     * The model manages a list of {@see LayerListModelListener} which are mainly notified if
     579     * the model requires views to make a specific list entry visible.
     580     */
     581    public class LayerListModel extends DefaultListModel implements LayerChangeListener, PropertyChangeListener{
     582
     583        private ArrayList<Layer> layers;
     584        private DefaultListSelectionModel selectionModel;
     585        private CopyOnWriteArrayList<LayerListModelListener> listeners;
     586
     587        private LayerListModel(DefaultListSelectionModel selectionModel) {
     588            layers = new ArrayList<Layer>();
     589            this.selectionModel = selectionModel;
     590            listeners = new CopyOnWriteArrayList<LayerListModelListener>();
     591        }
     592
     593        public void addLayerListModelListener(LayerListModelListener listener) {
     594            synchronized(listeners) {
     595                if (listener != null && !listeners.contains(listener)) {
     596                    listeners.add(listener);
     597                }
     598            }
     599        }
     600
     601        public void removeLayerListModelListener(LayerListModelListener listener) {
     602            synchronized(listeners) {
     603                if (listener != null && listeners.contains(listener)) {
     604                    listeners.remove(listener);
     605                }
     606            }
     607        }
     608
     609        protected void fireMakeVisible(int index, Layer layer) {
     610            for (LayerListModelListener listener : listeners) {
     611                listener.makeVisible(index, layer);
     612            }
     613        }
     614
     615        public void populate(Collection<Layer> layers) {
     616            if (layers == null)
     617                return;
     618            this.layers.clear();
     619            this.layers.addAll(layers);
     620            for (Layer layer: this.layers) {
     621                layer.addPropertyChangeListener(this);
     622            }
     623            fireContentsChanged(this, 0, getSize());
     624        }
     625
     626        public void setSelectedLayer(Layer layer) {
     627            int idx = layers.indexOf(layer);
     628            if (idx >= 0) {
     629                selectionModel.setSelectionInterval(idx, idx);
     630            }
     631            fireContentsChanged(this, 0, getSize());
     632            ensureSelectedIsVisible();
     633        }
     634
     635        public List<Layer> getSelectedLayers() {
     636            ArrayList<Layer> selected = new ArrayList<Layer>();
     637            for (int i=0; i<layers.size(); i++) {
     638                if (selectionModel.isSelectedIndex(i)) {
     639                    selected.add(layers.get(i));
     640                }
     641            }
     642            return selected;
     643        }
     644
     645        public List<Integer> getSelectedRows() {
     646            ArrayList<Integer> selected = new ArrayList<Integer>();
     647            for (int i=0; i<layers.size();i++) {
     648                if (selectionModel.isSelectedIndex(i)) {
     649                    selected.add(i);
     650                }
     651            }
     652            return selected;
     653        }
     654
     655        public void removeLayer(Layer layer) {
     656            if (layer == null)
     657                return;
     658            List<Integer> selectedRows = getSelectedRows();
     659            int deletedRow = layers.indexOf(layer);
     660            if (deletedRow < 0)
     661                // layer not found in the list of layers
     662                return;
     663            layers.remove(layer);
     664            fireContentsChanged(this, 0,getSize());
     665            for (int row: selectedRows) {
     666                if (row < deletedRow) {
     667                    selectionModel.addSelectionInterval(row, row);
     668                } else if (row == deletedRow){
     669                    // do nothing
     670                } else {
     671                    selectionModel.addSelectionInterval(row-1, row-1);
     672                }
     673            }
     674            ensureSelectedIsVisible();
     675        }
     676
     677        public void addLayer(Layer layer) {
     678            if (layer == null) return;
     679            if (layers.contains(layer)) return;
     680            layers.add(layer);
     681            layer.addPropertyChangeListener(this);
     682            fireContentsChanged(this, 0, getSize());
     683        }
     684
     685        public Layer getFirstLayer() {
     686            if (getSize() == 0) return null;
     687            return layers.get(0);
     688        }
     689
     690        public Layer getLayer(int index) {
     691            if (index < 0 || index >= getSize())
     692                return null;
     693            return layers.get(index);
     694        }
     695
     696        public boolean canMoveUp() {
     697            List<Integer> sel = getSelectedRows();
     698            return !sel.isEmpty() && sel.get(0) > 0;
     699        }
     700
     701        public void moveUp() {
     702            if (!canMoveUp()) return;
     703            List<Integer> sel = getSelectedRows();
     704            for (int row: sel) {
     705                Layer l1 = layers.get(row);
     706                Layer l2 = layers.get(row-1);
     707                layers.set(row, l2);
     708                layers.set(row-1,l1);
     709                Main.map.mapView.moveLayer(l1, row-1);
     710            }
     711            fireContentsChanged(this, 0, getSize());
     712            selectionModel.clearSelection();
     713            for(int row: sel) {
     714                selectionModel.addSelectionInterval(row-1, row-1);
     715            }
     716            ensureSelectedIsVisible();
     717        }
     718
     719        public boolean canMoveDown() {
     720            List<Integer> sel = getSelectedRows();
     721            return !sel.isEmpty() && sel.get(sel.size()-1) < layers.size()-1;
     722        }
     723
     724        public void moveDown() {
     725            if (!canMoveDown()) return;
     726            List<Integer> sel = getSelectedRows();
     727            Collections.reverse(sel);
     728            for (int row: sel) {
     729                Layer l1 = layers.get(row);
     730                Layer l2 = layers.get(row+1);
     731                layers.set(row, l2);
     732                layers.set(row+1,l1);
     733                Main.map.mapView.moveLayer(l1, row+1);
     734            }
     735            fireContentsChanged(this, 0, getSize());
     736            selectionModel.clearSelection();
     737            for(int row: sel) {
     738                selectionModel.addSelectionInterval(row+1, row+1);
     739            }
     740            ensureSelectedIsVisible();
     741        }
     742
     743        protected void ensureSelectedIsVisible() {
     744            int index = selectionModel.getMinSelectionIndex();
     745            if (index <0 )return;
     746            if (index >= layers.size()) return;
     747            Layer layer = layers.get(index);
     748            fireMakeVisible(index, layer);
     749        }
     750
     751        public List<Layer> getPossibleMergeTargets(Layer layer) {
     752            ArrayList<Layer> targets = new ArrayList<Layer>();
     753            if (layer == null)
     754                return targets;
     755            for(Layer target: layers) {
     756                if (layer == target) {
     757                    continue;
     758                }
     759                if (target.isMergable(layer)) {
     760                    targets.add(target);
     761                }
     762            }
     763            return targets;
     764        }
     765
     766        public void activateLayer(Layer layer) {
     767            layers.remove(layer);
     768            layers.add(0,layer);
     769            Main.map.mapView.setActiveLayer(layer);
     770            layer.setVisible(true);
     771            selectionModel.setSelectionInterval(0,0);
     772            ensureSelectedIsVisible();
     773        }
     774
     775        /* ------------------------------------------------------------------------------ */
     776        /* Interface ListModel                                                            */
     777        /* ------------------------------------------------------------------------------ */
     778        @Override
     779        public Object getElementAt(int index) {
     780            return layers.get(index);
     781        }
     782
     783        @Override
     784        public int getSize() {
     785            return layers.size();
     786        }
     787
     788        /* ------------------------------------------------------------------------------ */
     789        /* Interface LayerChangeListener                                                  */
     790        /* ------------------------------------------------------------------------------ */
     791        public void activeLayerChange(Layer oldLayer, Layer newLayer) {
     792            if (oldLayer != null) {
     793                int idx = layers.indexOf(oldLayer);
     794                if (idx >= 0) {
     795                    fireContentsChanged(this, idx,idx);
     796                }
     797            }
     798
     799            if (newLayer != null) {
     800                int idx = layers.indexOf(newLayer);
     801                if (idx >= 0) {
     802                    fireContentsChanged(this, idx,idx);
     803                }
     804            }
     805        }
     806
     807        public void layerAdded(Layer newLayer) {
     808            addLayer(newLayer);
     809        }
     810
     811        public void layerRemoved(Layer oldLayer) {
     812            removeLayer(oldLayer);
     813        }
     814
     815        /* ------------------------------------------------------------------------------ */
     816        /* Interface PropertyChangeListener                                               */
     817        /* ------------------------------------------------------------------------------ */
     818        public void propertyChange(PropertyChangeEvent evt) {
     819            if (evt.getSource() instanceof Layer) {
     820                Layer layer = (Layer)evt.getSource();
     821                int idx = layers.indexOf(layer);
     822                if (idx < 0) return;
     823                fireContentsChanged(this, idx, idx);
     824            }
     825        }
     826    }
     827
     828    class LayerList extends JList {
     829        public LayerList(ListModel dataModel) {
     830            super(dataModel);
     831        }
     832
     833        @Override
     834        protected void processMouseEvent(MouseEvent e) {
     835            // if the layer list is embedded in a detached dialog, the last row is
     836            // is selected if a user clicks in the empty space *below* the last row.
     837            // This mouse event filter prevents this.
     838            //
     839            int idx = locationToIndex(e.getPoint());
     840            if (getCellBounds(idx, idx).contains(e.getPoint())) {
     841                super.processMouseEvent(e);
     842            }
     843        }
     844    }
     845
     846    public ShowHideLayerAction createShowHideLayerAction(Layer layer) {
     847        return new ShowHideLayerAction(layer);
     848    }
     849
     850    public DeleteLayerAction createDeleteLayerAction(Layer layer) {
     851        return new DeleteLayerAction(layer);
     852    }
     853
     854    public ActivateLayerAction createActivateLayerAction(Layer layer) {
     855        return new ActivateLayerAction(layer);
     856    }
     857
     858    public MergeAction createMergeLayerAction(Layer layer) {
     859        return new MergeAction(layer);
    355860    }
    356861}
  • trunk/src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java

    r1889 r1890  
    660660            );
    661661            switch(ret) {
    662             case ConditionalOptionPaneUtil.DIALOG_DISABLED_OPTION: return;
    663             case JOptionPane.CLOSED_OPTION: return;
    664             case JOptionPane.NO_OPTION: return;
    665             case JOptionPane.YES_OPTION:
    666                 memberTableModel.removeMembersReferringTo(toCheck);
    667                 break;
     662                case ConditionalOptionPaneUtil.DIALOG_DISABLED_OPTION: return;
     663                case JOptionPane.CLOSED_OPTION: return;
     664                case JOptionPane.NO_OPTION: return;
     665                case JOptionPane.YES_OPTION:
     666                    memberTableModel.removeMembersReferringTo(toCheck);
     667                    break;
    668668            }
    669669        }
     
    698698            );
    699699            switch(ret) {
    700             case ConditionalOptionPaneUtil.DIALOG_DISABLED_OPTION : return true;
    701             case JOptionPane.YES_OPTION: return true;
    702             case JOptionPane.NO_OPTION: return false;
    703             case JOptionPane.CLOSED_OPTION: return false;
    704             case JOptionPane.CANCEL_OPTION: throw new AddAbortException();
     700                case ConditionalOptionPaneUtil.DIALOG_DISABLED_OPTION : return true;
     701                case JOptionPane.YES_OPTION: return true;
     702                case JOptionPane.NO_OPTION: return false;
     703                case JOptionPane.CLOSED_OPTION: return false;
     704                case JOptionPane.CANCEL_OPTION: throw new AddAbortException();
    705705            }
    706706            // should not happen
     
    10731073            );
    10741074            switch(ret) {
    1075             case JOptionPane.CANCEL_OPTION: return false;
    1076             case JOptionPane.YES_OPTION: return true;
    1077             case JOptionPane.NO_OPTION: return false;
     1075                case JOptionPane.CANCEL_OPTION: return false;
     1076                case JOptionPane.YES_OPTION: return true;
     1077                case JOptionPane.NO_OPTION: return false;
    10781078            }
    10791079            return false;
     
    13141314            );
    13151315            switch(ret) {
    1316             case JOptionPane.YES_OPTION: return true;
    1317             case ConditionalOptionPaneUtil.DIALOG_DISABLED_OPTION: return true;
    1318             default:
    1319                 return false;
     1316                case JOptionPane.YES_OPTION: return true;
     1317                case ConditionalOptionPaneUtil.DIALOG_DISABLED_OPTION: return true;
     1318                default:
     1319                    return false;
    13201320            }
    13211321        }
  • trunk/src/org/openstreetmap/josm/gui/layer/GeoImageLayer.java

    r1865 r1890  
    266266            MapFrame frame = Main.map;
    267267            if (frame != null) {
    268               frame.mapView.repaint();
     268                frame.mapView.repaint();
    269269            }
    270270        }
     
    276276        private final GpxLayer gpxLayer;
    277277        public Loader(Collection<File> files, GpxLayer gpxLayer) {
    278             super(tr("Images for {0}", gpxLayer.name));
     278            super(tr("Images for {0}", gpxLayer.getName()));
    279279            this.files = files;
    280280            this.gpxLayer = gpxLayer;
     
    412412                    return;
    413413                mousePressed  = true;
    414                 if (visible) {
     414                if (isVisible()) {
    415415                    Main.map.mapView.repaint();
    416416                }
     
    420420                    return;
    421421                mousePressed = false;
    422                 if (!visible)
     422                if (!isVisible())
    423423                    return;
    424424                for (int i = data.size(); i > 0; --i) {
     
    699699        });
    700700        return new Component[]{
    701                 new JMenuItem(new LayerListDialog.ShowHideLayerAction(this)),
    702                 new JMenuItem(new LayerListDialog.DeleteLayerAction(this)),
     701                new JMenuItem(LayerListDialog.getInstance().createShowHideLayerAction(this)),
     702                new JMenuItem(LayerListDialog.getInstance().createDeleteLayerAction(this)),
    703703                new JSeparator(),
    704704                sync,
  • trunk/src/org/openstreetmap/josm/gui/layer/GpxLayer.java

    r1865 r1890  
    4545import org.openstreetmap.josm.Main;
    4646import org.openstreetmap.josm.actions.RenameLayerAction;
    47 import org.openstreetmap.josm.actions.SaveAction;
    48 import org.openstreetmap.josm.actions.SaveAsAction;
    4947import org.openstreetmap.josm.actions.downloadtasks.DownloadOsmTaskList;
    5048import org.openstreetmap.josm.data.coor.EastNorth;
     
    9189    public GpxLayer(GpxData d, String name) {
    9290        this(d);
    93         this.name = name;
     91        this.setName(name);
    9492    }
    9593
    9694    public GpxLayer(GpxData d, String name, boolean isLocal) {
    9795        this(d);
    98         this.name = name;
     96        this.setName(name);
    9997        this.isLocalFile = isLocal;
    10098    }
     
    129127                    panel.add(b);
    130128                }
    131                 String propName = "draw.rawgps.lines.layer " + name;
     129                String propName = "draw.rawgps.lines.layer " + getName();
    132130                if (Main.pref.hasKey(propName)) {
    133131                    group.setSelected(r[Main.pref.getBoolean(propName) ? 1 : 2].getModel(), true);
     
    157155        color.addActionListener(new ActionListener() {
    158156            public void actionPerformed(ActionEvent e) {
    159                 JColorChooser c = new JColorChooser(getColor(name));
     157                JColorChooser c = new JColorChooser(getColor(getName()));
    160158                Object[] options = new Object[] { tr("OK"), tr("Cancel"), tr("Default") };
    161159                int answer = OptionPaneUtil.showOptionDialog(
     
    169167                switch (answer) {
    170168                    case 0:
    171                         Main.pref.putColor("layer " + name, c.getColor());
     169                        Main.pref.putColor("layer " + getName(), c.getColor());
    172170                        break;
    173171                    case 1:
    174172                        return;
    175173                    case 2:
    176                         Main.pref.putColor("layer " + name, null);
     174                        Main.pref.putColor("layer " + getName(), null);
    177175                        break;
    178176                }
     
    196194                }
    197195
    198                 MarkerLayer ml = new MarkerLayer(namedTrackPoints, tr("Named Trackpoints from {0}", name),
     196                MarkerLayer ml = new MarkerLayer(namedTrackPoints, tr("Named Trackpoints from {0}", getName()),
    199197                        getAssociatedFile(), me);
    200198                if (ml.data.size() > 0) {
     
    256254                        names = "";
    257255                    }
    258                     MarkerLayer ml = new MarkerLayer(new GpxData(), tr("Audio markers from {0}", name) + names,
     256                    MarkerLayer ml = new MarkerLayer(new GpxData(), tr("Audio markers from {0}", getName()) + names,
    259257                            getAssociatedFile(), me);
    260258                    if (sel != null) {
     
    312310
    313311        if (Main.applet)
    314             return new Component[] { new JMenuItem(new LayerListDialog.ShowHideLayerAction(this)),
    315                 new JMenuItem(new LayerListDialog.DeleteLayerAction(this)), new JSeparator(), color, line,
     312            return new Component[] { new JMenuItem(LayerListDialog.getInstance().createShowHideLayerAction(this)),
     313                new JMenuItem(LayerListDialog.getInstance().createDeleteLayerAction(this)), new JSeparator(), color, line,
    316314                new JMenuItem(new ConvertToDataLayerAction()), new JSeparator(),
    317315                new JMenuItem(new RenameLayerAction(getAssociatedFile(), this)), new JSeparator(),
    318316                new JMenuItem(new LayerListPopup.InfoAction(this)) };
    319         return new Component[] { new JMenuItem(new LayerListDialog.ShowHideLayerAction(this)),
    320                 new JMenuItem(new LayerListDialog.DeleteLayerAction(this)), new JSeparator(),
     317        return new Component[] { new JMenuItem(LayerListDialog.getInstance().createShowHideLayerAction(this)),
     318                new JMenuItem(LayerListDialog.getInstance().createDeleteLayerAction(this)), new JSeparator(),
    321319                new JMenuItem(new LayerSaveAction(this)), new JMenuItem(new LayerSaveAsAction(this)), color, line,
    322320                tagimage, importAudio, markersFromNamedTrackpoints, new JMenuItem(new ConvertToDataLayerAction()),
     
    416414         ****************************************************************/
    417415        // Long startTime = System.currentTimeMillis();
    418         Color neutralColor = getColor(name);
     416        Color neutralColor = getColor(getName());
    419417        // also draw lines between points belonging to different segments
    420418        boolean forceLines = Main.pref.getBoolean("draw.rawgps.lines.force");
     
    431429        boolean lines = (Main.pref.getBoolean("draw.rawgps.lines", true) || (Main.pref
    432430                .getBoolean("draw.rawgps.lines.localfiles") && this.isLocalFile));
    433         String linesKey = "draw.rawgps.lines.layer " + name;
     431        String linesKey = "draw.rawgps.lines.layer " + getName();
    434432        // draw lines, per-layer setting
    435433        if (Main.pref.hasKey(linesKey)) {
     
    726724            }
    727725            Main.main
    728             .addLayer(new OsmDataLayer(ds, tr("Converted from: {0}", GpxLayer.this.name), getAssociatedFile()));
     726            .addLayer(new OsmDataLayer(ds, tr("Converted from: {0}", GpxLayer.this.getName()), getAssociatedFile()));
    729727            Main.main.removeLayer(GpxLayer.this);
    730728        }
  • trunk/src/org/openstreetmap/josm/gui/layer/Layer.java

    r1808 r1890  
    88import java.awt.Graphics;
    99import java.awt.event.ActionEvent;
     10import java.beans.PropertyChangeListener;
     11import java.beans.PropertyChangeSupport;
    1012import java.io.File;
    1113import java.util.Collection;
     
    3941 */
    4042abstract public class Layer implements Destroyable, MapViewPaintable {
     43    static public final String VISIBLE_PROP = Layer.class.getName() + ".visible";
     44    static public final String NAME_PROP = Layer.class.getName() + ".name";
     45
     46    /** keeps track of property change listeners */
     47    private PropertyChangeSupport propertyChangeSupport;
    4148
    4249    /**
     
    5865    /**
    5966     * The visibility state of the layer.
    60      */
     67     *
     68     * @deprecated use {@see #setVisible(boolean)} and {@see #isVisible()} instead. This field
     69     * is going to be private (or protected) in a future release.
     70     */
     71    @Deprecated
    6172    public boolean visible = true;
    6273
     
    6879    /**
    6980     * The name of this layer.
    70      */
     81     *
     82     * @deprecated use {@see #getName()} and {@see #setName(String)} instead. This field
     83     * is going to be private  (or protected) in the future.
     84     */
     85    @Deprecated
    7186    public String name;
    7287    /**
     
    7994     */
    8095    public Layer(String name) {
    81         this.name = name;
     96        this.propertyChangeSupport = new PropertyChangeSupport(this);
     97        setName(name);
    8298    }
    8399
     
    140156    public String getName() {
    141157        return name;
     158    }
     159
     160    /**
     161     * Sets the name of the layer
     162     *
     163     *@param name the name. If null, the name is set to the empty string.
     164     *
     165     */
     166    public void setName(String name) {
     167        if (name == null) {
     168            name = "";
     169        }
     170        String oldValue = this.name;
     171        this.name = name;
     172        if (!oldValue.equals(this.name)) {
     173            propertyChangeSupport.firePropertyChange(NAME_PROP, oldValue, this.name);
     174        }
    142175    }
    143176
     
    189222    }
    190223
     224    /**
     225     * Sets the visibility of this layer. Emits property change event for
     226     * property {@see #VISIBLE_PROP}.
     227     *
     228     * @param visible true, if the layer is visible; false, otherwise.
     229     */
     230    public void setVisible(boolean visible) {
     231        boolean oldValue = this.visible;
     232        this.visible  = visible;
     233        if (oldValue != this.visible) {
     234            fireVisibleChanged(oldValue, this.visible);
     235        }
     236    }
     237
     238    /**
     239     * Replies true if this layer is visible. False, otherwise.
     240     * @return  true if this layer is visible. False, otherwise.
     241     */
     242    public boolean isVisible() {
     243        return visible;
     244    }
     245
     246    /**
     247     * Toggles the visibility state of this layer.
     248     */
     249    public void toggleVisible() {
     250        setVisible(!isVisible());
     251    }
     252
     253    /**
     254     * Adds a {@see PropertyChangeListener}
     255     *
     256     * @param listener the listener
     257     */
     258    public void addPropertyChangeListener(PropertyChangeListener listener) {
     259        propertyChangeSupport.addPropertyChangeListener(listener);
     260    }
     261
     262    /**
     263     * Removes a {@see PropertyChangeListener}
     264     *
     265     * @param listener the listener
     266     */
     267    public void removePropertyChangeListener(PropertyChangeListener listener) {
     268        propertyChangeSupport.removePropertyChangeListener(listener);
     269    }
     270
     271    /**
     272     * fires a property change for the property {@see #VISIBLE_PROP}
     273     *
     274     * @param oldValue the old value
     275     * @param newValue the new value
     276     */
     277    protected void fireVisibleChanged(boolean oldValue, boolean newValue) {
     278        propertyChangeSupport.firePropertyChange(VISIBLE_PROP, oldValue, newValue);
     279    }
    191280}
  • trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java

    r1865 r1890  
    407407        }
    408408        final JPanel p = new JPanel(new GridBagLayout());
    409         p.add(new JLabel(tr("{0} consists of:", name)), GBC.eol());
     409        p.add(new JLabel(tr("{0} consists of:", getName())), GBC.eol());
    410410        for (int i = 0; i < counter.normal.length; ++i) {
    411411            String s = counter.normal[i]+" "+trn(counter.names[i],counter.names[i]+"s",counter.normal[i]);
     
    423423        if (Main.applet)
    424424            return new Component[]{
    425                 new JMenuItem(new LayerListDialog.ShowHideLayerAction(this)),
    426                 new JMenuItem(new LayerListDialog.DeleteLayerAction(this)),
     425                new JMenuItem(LayerListDialog.getInstance().createActivateLayerAction(this)),
     426                new JMenuItem(LayerListDialog.getInstance().createShowHideLayerAction(this)),
     427                new JMenuItem(LayerListDialog.getInstance().createDeleteLayerAction(this)),
     428                new JSeparator(),
     429                new JMenuItem(LayerListDialog.getInstance().createMergeLayerAction(this)),
    427430                new JSeparator(),
    428431                new JMenuItem(new RenameLayerAction(getAssociatedFile(), this)),
     
    430433                new JMenuItem(new LayerListPopup.InfoAction(this))};
    431434        return new Component[]{
    432                 new JMenuItem(new LayerListDialog.ShowHideLayerAction(this)),
    433                 new JMenuItem(new LayerListDialog.DeleteLayerAction(this)),
     435                new JMenuItem(LayerListDialog.getInstance().createActivateLayerAction(this)),
     436                new JMenuItem(LayerListDialog.getInstance().createShowHideLayerAction(this)),
     437                new JMenuItem(LayerListDialog.getInstance().createDeleteLayerAction(this)),
    434438                new JSeparator(),
     439                new JMenuItem(LayerListDialog.getInstance().createMergeLayerAction(this)),
    435440                new JMenuItem(new LayerSaveAction(this)),
    436441                new JMenuItem(new LayerSaveAsAction(this)),
     
    515520        }
    516521        public void actionPerformed(ActionEvent e) {
    517             Main.main.addLayer(new GpxLayer(toGpxData(), tr("Converted from: {0}", name)));
     522            Main.main.addLayer(new GpxLayer(toGpxData(), tr("Converted from: {0}", getName())));
    518523            Main.main.removeLayer(OsmDataLayer.this);
    519524        }
  • trunk/src/org/openstreetmap/josm/gui/layer/RawGpsLayer.java

    r1865 r1890  
    1313import java.awt.event.ActionEvent;
    1414import java.awt.event.ActionListener;
    15 import java.io.BufferedReader;
    1615import java.io.File;
    17 import java.io.InputStreamReader;
    18 import java.net.URL;
    19 import java.net.URLConnection;
    20 import java.net.UnknownHostException;
    2116import java.util.Collection;
    2217
     
    2520import javax.swing.ButtonGroup;
    2621import javax.swing.Icon;
    27 import javax.swing.JCheckBox;
    2822import javax.swing.JColorChooser;
    2923import javax.swing.JLabel;
     
    3327import javax.swing.JRadioButton;
    3428import javax.swing.JSeparator;
    35 import javax.swing.JTextField;
    36 import javax.swing.text.html.Option;
    3729
    3830import org.openstreetmap.josm.Main;
    39 import org.openstreetmap.josm.actions.GpxExportAction;
    4031import org.openstreetmap.josm.actions.RenameLayerAction;
    4132import org.openstreetmap.josm.data.Preferences.PreferenceChangedListener;
     
    5142import org.openstreetmap.josm.gui.dialogs.LayerListDialog;
    5243import org.openstreetmap.josm.gui.dialogs.LayerListPopup;
    53 import org.openstreetmap.josm.io.MultiPartFormOutputStream;
    5444import org.openstreetmap.josm.tools.GBC;
    5545import org.openstreetmap.josm.tools.ImageProvider;
     
    9181                ds.ways.add(w);
    9282            }
    93             Main.main.addLayer(new OsmDataLayer(ds, tr("Converted from: {0}", RawGpsLayer.this.name), null));
     83            Main.main.addLayer(new OsmDataLayer(ds, tr("Converted from: {0}", RawGpsLayer.this.getName()), null));
    9484            Main.main.removeLayer(RawGpsLayer.this);
    9585        }
     
    129119
    130120    @Override public void paint(Graphics g, MapView mv) {
    131         g.setColor(Main.pref.getColor(marktr("gps point"), "layer "+name, Color.gray));
     121        g.setColor(Main.pref.getColor(marktr("gps point"), "layer "+getName(), Color.gray));
    132122        Point old = null;
    133123
    134124        boolean force = Main.pref.getBoolean("draw.rawgps.lines.force");
    135125        boolean lines = Main.pref.getBoolean("draw.rawgps.lines", true);
    136         String linesKey = "draw.rawgps.lines.layer "+name;
     126        String linesKey = "draw.rawgps.lines.layer "+getName();
    137127        if (Main.pref.hasKey(linesKey)) {
    138128            lines = Main.pref.getBoolean(linesKey);
     
    197187        }
    198188        b.append("</html>");
    199         return "<html>"+trn("{0} consists of {1} track", "{0} consists of {1} tracks", data.size(), name, data.size())+" ("+trn("{0} point", "{0} points", points, points)+")<br>"+b.toString();
     189        return "<html>"+trn("{0} consists of {1} track", "{0} consists of {1} tracks", data.size(), getName(), data.size())+" ("+trn("{0} point", "{0} points", points, points)+")<br>"+b.toString();
    200190    }
    201191
     
    214204                    panel.add(b);
    215205                }
    216                 String propName = "draw.rawgps.lines.layer "+name;
     206                String propName = "draw.rawgps.lines.layer "+getName();
    217207                if (Main.pref.hasKey(propName)) {
    218208                    group.setSelected(r[Main.pref.getBoolean(propName) ? 1:2].getModel(), true);
     
    241231        color.addActionListener(new ActionListener(){
    242232            public void actionPerformed(ActionEvent e) {
    243                 JColorChooser c = new JColorChooser(Main.pref.getColor(marktr("gps point"), "layer "+name, Color.gray));
     233                JColorChooser c = new JColorChooser(Main.pref.getColor(marktr("gps point"), "layer "+getName(), Color.gray));
    244234                Object[] options = new Object[]{tr("OK"), tr("Cancel"), tr("Default")};
    245235                int answer = OptionPaneUtil.showOptionDialog(
     
    251241                switch (answer) {
    252242                    case 0:
    253                         Main.pref.putColor("layer "+name, c.getColor());
     243                        Main.pref.putColor("layer "+getName(), c.getColor());
    254244                        break;
    255245                    case 1:
    256246                        return;
    257247                    case 2:
    258                         Main.pref.putColor("layer "+name, null);
     248                        Main.pref.putColor("layer "+getName(), null);
    259249                        break;
    260250                }
     
    265255        if (Main.applet)
    266256            return new Component[]{
    267                 new JMenuItem(new LayerListDialog.ShowHideLayerAction(this)),
    268                 new JMenuItem(new LayerListDialog.DeleteLayerAction(this)),
     257                new JMenuItem(LayerListDialog.getInstance().createShowHideLayerAction(this)),
     258                new JMenuItem(LayerListDialog.getInstance().createDeleteLayerAction(this)),
    269259                new JSeparator(),
    270260                color,
     
    276266                new JMenuItem(new LayerListPopup.InfoAction(this))};
    277267        return new Component[]{
    278                 new JMenuItem(new LayerListDialog.ShowHideLayerAction(this)),
    279                 new JMenuItem(new LayerListDialog.DeleteLayerAction(this)),
     268                new JMenuItem(LayerListDialog.getInstance().createShowHideLayerAction(this)),
     269                new JMenuItem(LayerListDialog.getInstance().createDeleteLayerAction(this)),
    280270                new JSeparator(),
    281271                new JMenuItem(new LayerGpxExportAction(this)),
  • trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/MarkerLayer.java

    r1865 r1890  
    1919import java.util.Collection;
    2020
     21import javax.swing.AbstractAction;
    2122import javax.swing.Icon;
    2223import javax.swing.JColorChooser;
     
    6263    public GpxLayer fromLayer = null;
    6364
    64     /*
    65     private Icon audioTracerIcon = null;
    66     private EastNorth playheadPosition = null;
    67     private static Timer timer = null;
    68     private static double audioAnimationInterval = 0.0; // seconds
    69     private static double playheadTime = -1.0;
    70      */
    7165    public MarkerLayer(GpxData indata, String name, File associatedFile, GpxLayer fromLayer) {
    7266
     
    122116                            return;
    123117                        mousePressed  = true;
    124                         if (visible) {
     118                        if (isVisible()) {
    125119                            Main.map.mapView.repaint();
    126120                        }
     
    130124                            return;
    131125                        mousePressed = false;
    132                         if (!visible)
     126                        if (!isVisible())
    133127                            return;
    134128                        if (ev.getPoint() != null) {
     
    161155        boolean mousePressedTmp = mousePressed;
    162156        Point mousePos = mv.getMousePosition();
    163         String mkrTextShow = Main.pref.get("marker.show "+name, "show");
    164 
    165         g.setColor(getColor(name));
     157        String mkrTextShow = Main.pref.get("marker.show "+getName(), "show");
     158
     159        g.setColor(getColor(getName()));
    166160
    167161        for (Marker mkr : data) {
     
    195189
    196190    @Override public Object getInfoComponent() {
    197         return "<html>"+trn("{0} consists of {1} marker", "{0} consists of {1} markers", data.size(), name, data.size()) + "</html>";
     191        return "<html>"+trn("{0} consists of {1} marker", "{0} consists of {1} markers", data.size(), getName(), data.size()) + "</html>";
    198192    }
    199193
     
    203197        color.addActionListener(new ActionListener(){
    204198            public void actionPerformed(ActionEvent e) {
    205                 JColorChooser c = new JColorChooser(getColor(name));
     199                JColorChooser c = new JColorChooser(getColor(getName()));
    206200                Object[] options = new Object[]{tr("OK"), tr("Cancel"), tr("Default")};
    207201                int answer = OptionPaneUtil.showOptionDialog(
     
    215209                );
    216210                switch (answer) {
    217                 case 0:
    218                     Main.pref.putColor("layer "+name, c.getColor());
    219                     break;
    220                 case 1:
    221                     return;
    222                 case 2:
    223                     Main.pref.putColor("layer "+name, null);
    224                     break;
     211                    case 0:
     212                        Main.pref.putColor("layer "+getName(), c.getColor());
     213                        break;
     214                    case 1:
     215                        return;
     216                    case 2:
     217                        Main.pref.putColor("layer "+getName(), null);
     218                        break;
    225219                }
    226220                Main.map.repaint();
     
    282276
    283277        Collection<Component> components = new ArrayList<Component>();
    284         components.add(new JMenuItem(new LayerListDialog.ShowHideLayerAction(this)));
    285         components.add(new JMenuItem(new LayerListDialog.ShowHideMarkerText(this)));
    286         components.add(new JMenuItem(new LayerListDialog.DeleteLayerAction(this)));
     278        components.add(new JMenuItem(LayerListDialog.getInstance().createShowHideLayerAction(this)));
     279        components.add(new JMenuItem(new ShowHideMarkerText(this)));
     280        components.add(new JMenuItem(LayerListDialog.getInstance().createDeleteLayerAction(this)));
    287281        components.add(new JSeparator());
    288282        components.add(color);
     
    450444    }
    451445
     446
     447    public final  class ShowHideMarkerText extends AbstractAction {
     448        private final Layer layer;
     449
     450        public ShowHideMarkerText(Layer layer) {
     451            super(tr("Show/Hide Text/Icons"), ImageProvider.get("dialogs", "showhide"));
     452            putValue(SHORT_DESCRIPTION, tr("Toggle visible state of the marker text and icons."));
     453            putValue("help", "Action/ShowHideTextIcons");
     454            this.layer = layer;
     455        }
     456
     457        public void actionPerformed(ActionEvent e) {
     458            String current = Main.pref.get("marker.show "+layer.getName(),"show");
     459            Main.pref.put("marker.show "+layer.getName(), current.equalsIgnoreCase("show") ? "hide" : "show");
     460            Main.map.mapView.repaint();
     461        }
     462    }
    452463}
Note: See TracChangeset for help on using the changeset viewer.