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.gui.dialogs.LayerListDialog;
013import org.openstreetmap.josm.gui.dialogs.LayerListDialog.LayerListModel;
014import org.openstreetmap.josm.gui.help.HelpUtil;
015import org.openstreetmap.josm.gui.layer.Layer;
016import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeEvent;
017import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeListener;
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, ActiveLayerChangeListener, 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        new ImageProvider("dialogs", "activate").getResource().attachImageIcon(this, true);
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        model.getLayerManager().setActiveLayer(layer);
080        layer.setVisible(true);
081    }
082
083    boolean isActiveLayer(Layer layer) {
084        return model.getLayerManager().getActiveLayer() == layer;
085    }
086
087    @Override
088    public void updateEnabledState() {
089        GuiHelper.runInEDTAndWait(new Runnable() {
090            @Override
091            public void run() {
092                if (layer == null) {
093                    if (model.getSelectedLayers().size() != 1) {
094                        setEnabled(false);
095                        return;
096                    }
097                    setEnabled(!isActiveLayer(model.getSelectedLayers().get(0)));
098                } else {
099                    setEnabled(!isActiveLayer(layer));
100                }
101            }
102        });
103    }
104
105    @Override
106    public void activeOrEditLayerChanged(ActiveLayerChangeEvent e) {
107        updateEnabledState();
108    }
109
110    @Override
111    public void executeMultikeyAction(int index, boolean repeat) {
112        Layer l = LayerListDialog.getLayerForIndex(index);
113        if (l != null) {
114            execute(l);
115        }
116    }
117
118    @Override
119    public List<MultikeyInfo> getMultikeyCombinations() {
120        return LayerListDialog.getLayerInfoByClass(Layer.class);
121    }
122
123    @Override
124    public MultikeyInfo getLastMultikeyAction() {
125        return null; // Repeating action doesn't make much sense for activating
126    }
127
128}