// License: GPL. For details, see LICENSE file. package org.openstreetmap.josm.gui.dialogs.layer; import static org.openstreetmap.josm.tools.I18n.tr; import java.awt.Component; import java.awt.event.ActionEvent; import java.util.List; import javax.swing.AbstractAction; import javax.swing.JMenuItem; import org.openstreetmap.josm.Main; import org.openstreetmap.josm.gui.dialogs.IEnabledStateUpdating; import org.openstreetmap.josm.gui.dialogs.LayerListDialog.LayerListModel; import org.openstreetmap.josm.gui.help.HelpUtil; import org.openstreetmap.josm.gui.layer.Layer; import org.openstreetmap.josm.gui.layer.Layer.LayerAction; import org.openstreetmap.josm.tools.CheckParameterUtil; import org.openstreetmap.josm.tools.ImageProvider; /** * The action to merge the currently selected layer into another layer. */ public final class MergeAction extends AbstractAction implements IEnabledStateUpdating, LayerAction, Layer.MultiLayerAction { private transient Layer layer; private transient List<Layer> layers; private final LayerListModel model; /** * Constructs a new {@code MergeAction}. * @param layer the layer * @param model layer list model * @throws IllegalArgumentException if {@code layer} is null */ public MergeAction(Layer layer, LayerListModel model) { this(layer, null, model); CheckParameterUtil.ensureParameterNotNull(layer, "layer"); } /** * Constructs a new {@code MergeAction}. * @param layers the layer list * @param model layer list model * @throws IllegalArgumentException if {@code layers} is null */ public MergeAction(List<Layer> layers, LayerListModel model) { this(null, layers, model); CheckParameterUtil.ensureParameterNotNull(layers, "layers"); } /** * Constructs a new {@code MergeAction}. * @param layer the layer (null if layer list if specified) * @param layers the layer list (null if a single layer is specified) * @param model layer list model */ private MergeAction(Layer layer, List<Layer> layers, LayerListModel model) { this.layer = layer; this.layers = layers; this.model = model; putValue(NAME, tr("Merge")); new ImageProvider("dialogs", "mergedown").getResource().attachImageIcon(this, true); putValue(SHORT_DESCRIPTION, tr("Merge this layer into another layer")); putValue("help", HelpUtil.ht("/Dialog/LayerList#MergeLayer")); updateEnabledState(); } @Override public void actionPerformed(ActionEvent e) { if (layer != null) { Main.main.menu.merge.merge(layer); } else if (layers != null) { Main.main.menu.merge.merge(layers); } else { if (model.getSelectedLayers().size() == 1) { Layer selectedLayer = model.getSelectedLayers().get(0); Main.main.menu.merge.merge(selectedLayer); } else { Main.main.menu.merge.merge(model.getSelectedLayers()); } } } @Override public void updateEnabledState() { if (layer == null && layers == null) { if (model.getSelectedLayers().isEmpty()) { setEnabled(false); } else if (model.getSelectedLayers().size() > 1) { setEnabled(supportLayers(model.getSelectedLayers())); } else { Layer selectedLayer = model.getSelectedLayers().get(0); List<Layer> targets = model.getPossibleMergeTargets(selectedLayer); setEnabled(!targets.isEmpty()); } } else if (layer != null) { List<Layer> targets = model.getPossibleMergeTargets(layer); setEnabled(!targets.isEmpty()); } else { setEnabled(supportLayers(layers)); } } @Override public boolean supportLayers(List<Layer> layers) { if (layers.isEmpty()) { return false; } else { final Layer firstLayer = layers.get(0); final List<Layer> remainingLayers = layers.subList(1, layers.size()); return model.getPossibleMergeTargets(firstLayer).containsAll(remainingLayers); } } @Override public Component createMenuComponent() { return new JMenuItem(this); } @Override public MergeAction getMultiLayerAction(List<Layer> layers) { return new MergeAction(layers, model); } }