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