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.Component;
007import java.awt.event.ActionEvent;
008import java.awt.event.KeyEvent;
009import java.lang.ref.WeakReference;
010import java.util.List;
011
012import javax.swing.AbstractAction;
013import javax.swing.JMenuItem;
014
015import org.openstreetmap.josm.gui.dialogs.LayerListDialog;
016import org.openstreetmap.josm.gui.dialogs.LayerListDialog.LayerListModel;
017import org.openstreetmap.josm.gui.help.HelpUtil;
018import org.openstreetmap.josm.gui.layer.Layer;
019import org.openstreetmap.josm.gui.layer.Layer.LayerAction;
020import org.openstreetmap.josm.tools.ImageProvider;
021import org.openstreetmap.josm.tools.MultikeyShortcutAction;
022import org.openstreetmap.josm.tools.Shortcut;
023
024/**
025 * Action which will toggle the visibility of the currently selected layers.
026 */
027public final class ShowHideLayerAction extends AbstractAction implements IEnabledStateUpdating, LayerAction, MultikeyShortcutAction {
028
029    private transient WeakReference<Layer> lastLayer;
030    private final transient Shortcut multikeyShortcut;
031    private final LayerListModel model;
032
033    /**
034     * Creates a {@link ShowHideLayerAction} which will toggle the visibility of the currently selected layers
035     * @param model layer list model
036     */
037    public ShowHideLayerAction(LayerListModel model) {
038        this.model = model;
039        putValue(NAME, tr("Show/hide"));
040        putValue(SMALL_ICON, ImageProvider.get("dialogs", "showhide"));
041        putValue(SHORT_DESCRIPTION, tr("Toggle visible state of the selected layer."));
042        putValue("help", HelpUtil.ht("/Dialog/LayerList#ShowHideLayer"));
043        multikeyShortcut = Shortcut.registerShortcut("core_multikey:showHideLayer", tr("Multikey: {0}",
044                tr("Show/hide layer")), KeyEvent.VK_S, Shortcut.SHIFT);
045        multikeyShortcut.setAccelerator(this);
046        updateEnabledState();
047    }
048
049    @Override
050    public Shortcut getMultikeyShortcut() {
051        return multikeyShortcut;
052    }
053
054    @Override
055    public void actionPerformed(ActionEvent e) {
056        for (Layer l : model.getSelectedLayers()) {
057            l.toggleVisible();
058        }
059    }
060
061    @Override
062    public void executeMultikeyAction(int index, boolean repeat) {
063        Layer l = LayerListDialog.getLayerForIndex(index);
064        if (l != null) {
065            l.toggleVisible();
066            lastLayer = new WeakReference<>(l);
067        } else if (repeat && lastLayer != null) {
068            l = lastLayer.get();
069            if (LayerListDialog.isLayerValid(l)) {
070                l.toggleVisible();
071            }
072        }
073    }
074
075    @Override
076    public void updateEnabledState() {
077        setEnabled(!model.getSelectedLayers().isEmpty());
078    }
079
080    @Override
081    public Component createMenuComponent() {
082        return new JMenuItem(this);
083    }
084
085    @Override
086    public boolean supportLayers(List<Layer> layers) {
087        return true;
088    }
089
090    @Override
091    public boolean equals(Object obj) {
092        return obj instanceof ShowHideLayerAction;
093    }
094
095    @Override
096    public int hashCode() {
097        return getClass().hashCode();
098    }
099
100    @Override
101    public List<MultikeyInfo> getMultikeyCombinations() {
102        return LayerListDialog.getLayerInfoByClass(Layer.class);
103    }
104
105    @Override
106    public MultikeyInfo getLastMultikeyAction() {
107        if (lastLayer != null)
108            return LayerListDialog.getLayerInfo(lastLayer.get());
109        return null;
110    }
111}