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