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.util.List; 009 010import javax.swing.AbstractAction; 011import javax.swing.JMenuItem; 012 013import org.openstreetmap.josm.Main; 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.Layer.LayerAction; 018import org.openstreetmap.josm.tools.CheckParameterUtil; 019import org.openstreetmap.josm.tools.ImageProvider; 020 021/** 022 * The action to merge the currently selected layer into another layer. 023 */ 024public final class MergeAction extends AbstractAction implements IEnabledStateUpdating, LayerAction, Layer.MultiLayerAction { 025 private transient Layer layer; 026 private transient List<Layer> layers; 027 private final LayerListModel model; 028 029 /** 030 * Constructs a new {@code MergeAction}. 031 * @param layer the layer 032 * @param model layer list model 033 * @throws IllegalArgumentException if {@code layer} is null 034 */ 035 public MergeAction(Layer layer, LayerListModel model) { 036 this(layer, null, model); 037 CheckParameterUtil.ensureParameterNotNull(layer, "layer"); 038 } 039 040 /** 041 * Constructs a new {@code MergeAction}. 042 * @param layers the layer list 043 * @param model layer list model 044 * @throws IllegalArgumentException if {@code layers} is null 045 */ 046 public MergeAction(List<Layer> layers, LayerListModel model) { 047 this(null, layers, model); 048 CheckParameterUtil.ensureParameterNotNull(layers, "layers"); 049 } 050 051 /** 052 * Constructs a new {@code MergeAction}. 053 * @param layer the layer (null if layer list if specified) 054 * @param layers the layer list (null if a single layer is specified) 055 * @param model layer list model 056 */ 057 private MergeAction(Layer layer, List<Layer> layers, LayerListModel model) { 058 this.layer = layer; 059 this.layers = layers; 060 this.model = model; 061 putValue(NAME, tr("Merge")); 062 putValue(SMALL_ICON, ImageProvider.get("dialogs", "mergedown")); 063 putValue(SHORT_DESCRIPTION, tr("Merge this layer into another layer")); 064 putValue("help", HelpUtil.ht("/Dialog/LayerList#MergeLayer")); 065 updateEnabledState(); 066 } 067 068 @Override 069 public void actionPerformed(ActionEvent e) { 070 if (layer != null) { 071 Main.main.menu.merge.merge(layer); 072 } else if (layers != null) { 073 Main.main.menu.merge.merge(layers); 074 } else { 075 if (model.getSelectedLayers().size() == 1) { 076 Layer selectedLayer = model.getSelectedLayers().get(0); 077 Main.main.menu.merge.merge(selectedLayer); 078 } else { 079 Main.main.menu.merge.merge(model.getSelectedLayers()); 080 } 081 } 082 } 083 084 @Override 085 public void updateEnabledState() { 086 if (layer == null && layers == null) { 087 if (model.getSelectedLayers().isEmpty()) { 088 setEnabled(false); 089 } else if (model.getSelectedLayers().size() > 1) { 090 setEnabled(supportLayers(model.getSelectedLayers())); 091 } else { 092 Layer selectedLayer = model.getSelectedLayers().get(0); 093 List<Layer> targets = model.getPossibleMergeTargets(selectedLayer); 094 setEnabled(!targets.isEmpty()); 095 } 096 } else if (layer != null) { 097 List<Layer> targets = model.getPossibleMergeTargets(layer); 098 setEnabled(!targets.isEmpty()); 099 } else { 100 setEnabled(supportLayers(layers)); 101 } 102 } 103 104 @Override 105 public boolean supportLayers(List<Layer> layers) { 106 if (layers.isEmpty()) { 107 return false; 108 } else { 109 final Layer firstLayer = layers.get(0); 110 final List<Layer> remainingLayers = layers.subList(1, layers.size()); 111 return model.getPossibleMergeTargets(firstLayer).containsAll(remainingLayers); 112 } 113 } 114 115 @Override 116 public Component createMenuComponent() { 117 return new JMenuItem(this); 118 } 119 120 @Override 121 public MergeAction getMultiLayerAction(List<Layer> layers) { 122 return new MergeAction(layers, model); 123 } 124}