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