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.IEnabledStateUpdating;
013import org.openstreetmap.josm.gui.dialogs.LayerListDialog;
014import org.openstreetmap.josm.gui.dialogs.LayerListDialog.LayerListModel;
015import org.openstreetmap.josm.gui.help.HelpUtil;
016import org.openstreetmap.josm.gui.layer.Layer;
017import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeEvent;
018import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeListener;
019import org.openstreetmap.josm.gui.util.GuiHelper;
020import org.openstreetmap.josm.tools.CheckParameterUtil;
021import org.openstreetmap.josm.tools.ImageProvider;
022import org.openstreetmap.josm.tools.MultikeyShortcutAction;
023import org.openstreetmap.josm.tools.Shortcut;
024
025/**
026 * The action to activate the currently selected layer
027 */
028public final class ActivateLayerAction extends AbstractAction
029implements IEnabledStateUpdating, ActiveLayerChangeListener, MultikeyShortcutAction {
030    private transient Layer layer;
031    private transient Shortcut multikeyShortcut;
032    private final LayerListModel model;
033
034    /**
035     * Constructs a new {@code ActivateLayerAction}.
036     * @param layer the layer
037     * @param model layer list model
038     */
039    public ActivateLayerAction(Layer layer, LayerListModel model) {
040        this(model);
041        CheckParameterUtil.ensureParameterNotNull(layer, "layer");
042        this.layer = layer;
043        putValue(NAME, tr("Activate"));
044        updateEnabledState();
045    }
046
047    /**
048     * Constructs a new {@code ActivateLayerAction}.
049     * @param model layer list model
050     */
051    public ActivateLayerAction(LayerListModel model) {
052        this.model = model;
053        putValue(NAME, tr("Activate"));
054        new ImageProvider("dialogs", "activate").getResource().attachImageIcon(this, true);
055        putValue(SHORT_DESCRIPTION, tr("Activate the selected layer"));
056        multikeyShortcut = Shortcut.registerShortcut("core_multikey:activateLayer", tr("Multikey: {0}",
057                tr("Activate layer")), KeyEvent.VK_A, Shortcut.SHIFT);
058        multikeyShortcut.setAccelerator(this);
059        putValue("help", HelpUtil.ht("/Dialog/LayerList#ActivateLayer"));
060    }
061
062    @Override
063    public Shortcut getMultikeyShortcut() {
064        return multikeyShortcut;
065    }
066
067    @Override
068    public void actionPerformed(ActionEvent e) {
069        Layer toActivate;
070        if (layer != null) {
071            toActivate = layer;
072        } else {
073            toActivate = model.getSelectedLayers().get(0);
074        }
075        execute(toActivate);
076    }
077
078    private void execute(Layer layer) {
079        // model is going to be updated via LayerChangeListener and PropertyChangeEvents
080        model.getLayerManager().setActiveLayer(layer);
081        layer.setVisible(true);
082    }
083
084    boolean isActiveLayer(Layer layer) {
085        return model.getLayerManager().getActiveLayer() == layer;
086    }
087
088    @Override
089    public void updateEnabledState() {
090        GuiHelper.runInEDTAndWait(() -> {
091            if (layer == null) {
092                if (model.getSelectedLayers().size() != 1) {
093                    setEnabled(false);
094                    return;
095                }
096                setEnabled(!isActiveLayer(model.getSelectedLayers().get(0)));
097            } else {
098                setEnabled(!isActiveLayer(layer));
099            }
100        });
101    }
102
103    @Override
104    public void activeOrEditLayerChanged(ActiveLayerChangeEvent e) {
105        updateEnabledState();
106    }
107
108    @Override
109    public void executeMultikeyAction(int index, boolean repeat) {
110        Layer l = LayerListDialog.getLayerForIndex(index);
111        if (l != null) {
112            execute(l);
113        }
114    }
115
116    @Override
117    public List<MultikeyInfo> getMultikeyCombinations() {
118        return LayerListDialog.getLayerInfoByClass(Layer.class);
119    }
120
121    @Override
122    public MultikeyInfo getLastMultikeyAction() {
123        return null; // Repeating action doesn't make much sense for activating
124    }
125
126}