001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.dialogs.layer;
003
004import static org.openstreetmap.josm.tools.I18n.tr;
005
006import java.awt.event.ActionEvent;
007import java.awt.event.KeyEvent;
008import java.util.List;
009
010import javax.swing.AbstractAction;
011
012import org.openstreetmap.josm.Main;
013import org.openstreetmap.josm.gui.MapView;
014import org.openstreetmap.josm.gui.dialogs.LayerListDialog;
015import org.openstreetmap.josm.gui.dialogs.LayerListDialog.LayerListModel;
016import org.openstreetmap.josm.gui.help.HelpUtil;
017import org.openstreetmap.josm.gui.layer.Layer;
018import org.openstreetmap.josm.gui.util.GuiHelper;
019import org.openstreetmap.josm.tools.CheckParameterUtil;
020import org.openstreetmap.josm.tools.ImageProvider;
021import org.openstreetmap.josm.tools.MultikeyShortcutAction;
022import org.openstreetmap.josm.tools.Shortcut;
023
024/**
025 * The action to activate the currently selected layer
026 */
027public final class ActivateLayerAction extends AbstractAction
028implements IEnabledStateUpdating, MapView.LayerChangeListener, MultikeyShortcutAction {
029    private transient Layer layer;
030    private transient Shortcut multikeyShortcut;
031    private final LayerListModel model;
032
033    /**
034     * Constructs a new {@code ActivateLayerAction}.
035     * @param layer the layer
036     * @param model layer list model
037     */
038    public ActivateLayerAction(Layer layer, LayerListModel model) {
039        this(model);
040        CheckParameterUtil.ensureParameterNotNull(layer, "layer");
041        this.layer = layer;
042        putValue(NAME, tr("Activate"));
043        updateEnabledState();
044    }
045
046    /**
047     * Constructs a new {@code ActivateLayerAction}.
048     * @param model layer list model
049     */
050    public ActivateLayerAction(LayerListModel model) {
051        this.model = model;
052        putValue(NAME, tr("Activate"));
053        putValue(SMALL_ICON, ImageProvider.get("dialogs", "activate"));
054        putValue(SHORT_DESCRIPTION, tr("Activate the selected layer"));
055        multikeyShortcut = Shortcut.registerShortcut("core_multikey:activateLayer", tr("Multikey: {0}",
056                tr("Activate layer")), KeyEvent.VK_A, Shortcut.SHIFT);
057        multikeyShortcut.setAccelerator(this);
058        putValue("help", HelpUtil.ht("/Dialog/LayerList#ActivateLayer"));
059    }
060
061    @Override
062    public Shortcut getMultikeyShortcut() {
063        return multikeyShortcut;
064    }
065
066    @Override
067    public void actionPerformed(ActionEvent e) {
068        Layer toActivate;
069        if (layer != null) {
070            toActivate = layer;
071        } else {
072            toActivate = model.getSelectedLayers().get(0);
073        }
074        execute(toActivate);
075    }
076
077    private void execute(Layer layer) {
078        // model is going to be updated via LayerChangeListener and PropertyChangeEvents
079        Main.map.mapView.setActiveLayer(layer);
080        layer.setVisible(true);
081    }
082
083    protected boolean isActiveLayer(Layer layer) {
084        if (!Main.isDisplayingMapView())
085            return false;
086        return Main.map.mapView.getActiveLayer() == layer;
087    }
088
089    @Override
090    public void updateEnabledState() {
091        GuiHelper.runInEDTAndWait(new Runnable() {
092            @Override
093            public void run() {
094                if (layer == null) {
095                    if (model.getSelectedLayers().size() != 1) {
096                        setEnabled(false);
097                        return;
098                    }
099                    setEnabled(!isActiveLayer(model.getSelectedLayers().get(0)));
100                } else {
101                    setEnabled(!isActiveLayer(layer));
102                }
103            }
104        });
105    }
106
107    @Override
108    public void activeLayerChange(Layer oldLayer, Layer newLayer) {
109        updateEnabledState();
110    }
111
112    @Override
113    public void layerAdded(Layer newLayer) {
114        updateEnabledState();
115    }
116
117    @Override
118    public void layerRemoved(Layer oldLayer) {
119        updateEnabledState();
120    }
121
122    @Override
123    public void executeMultikeyAction(int index, boolean repeat) {
124        Layer l = LayerListDialog.getLayerForIndex(index);
125        if (l != null) {
126            execute(l);
127        }
128    }
129
130    @Override
131    public List<MultikeyInfo> getMultikeyCombinations() {
132        return LayerListDialog.getLayerInfoByClass(Layer.class);
133    }
134
135    @Override
136    public MultikeyInfo getLastMultikeyAction() {
137        return null; // Repeating action doesn't make much sense for activating
138    }
139}