001 // License: GPL. For details, see LICENSE file. 002 package org.openstreetmap.josm.actions; 003 004 import static org.openstreetmap.josm.gui.help.HelpUtil.ht; 005 import static org.openstreetmap.josm.tools.I18n.tr; 006 007 import java.awt.event.ActionEvent; 008 import java.awt.event.KeyEvent; 009 import java.util.Collection; 010 import java.util.List; 011 012 import org.openstreetmap.josm.data.osm.DataSet; 013 import org.openstreetmap.josm.data.osm.OsmPrimitive; 014 import org.openstreetmap.josm.data.osm.visitor.MergeSourceBuildingVisitor; 015 import org.openstreetmap.josm.gui.dialogs.LayerListDialog; 016 import org.openstreetmap.josm.gui.layer.Layer; 017 import org.openstreetmap.josm.gui.layer.OsmDataLayer; 018 import org.openstreetmap.josm.gui.util.GuiHelper; 019 import org.openstreetmap.josm.tools.ImageProvider; 020 import org.openstreetmap.josm.tools.Shortcut; 021 022 public class MergeSelectionAction extends AbstractMergeAction { 023 public MergeSelectionAction() { 024 super(tr("Merge selection"), "dialogs/mergedown", tr("Merge the currently selected objects into another layer"), 025 Shortcut.registerShortcut("system:mergeselection", tr("Edit: {0}", tr("Merge selection")), 026 KeyEvent.VK_M, Shortcut.CTRL_SHIFT), 027 true /* register */ 028 ); 029 putValue("help", ht("/Action/MergeSelection")); 030 } 031 032 public void mergeSelected(DataSet source) { 033 List<Layer> targetLayers = LayerListDialog.getInstance().getModel().getPossibleMergeTargets(getEditLayer()); 034 if (targetLayers.isEmpty()) { 035 warnNoTargetLayersForSourceLayer(getEditLayer()); 036 return; 037 } 038 Layer targetLayer = askTargetLayer(targetLayers); 039 if (targetLayer == null) 040 return; 041 if (getEditLayer().isUploadDiscouraged() && targetLayer instanceof OsmDataLayer && !((OsmDataLayer)targetLayer).isUploadDiscouraged() 042 && getEditLayer().data.getAllSelected().size() > 1) { 043 if (warnMergingUploadDiscouragedObjects(targetLayer)) { 044 return; 045 } 046 } 047 MergeSourceBuildingVisitor builder = new MergeSourceBuildingVisitor(getEditLayer().data); 048 ((OsmDataLayer)targetLayer).mergeFrom(builder.build()); 049 } 050 051 public void actionPerformed(ActionEvent e) { 052 if (getEditLayer() == null || getEditLayer().data.getAllSelected().isEmpty()) 053 return; 054 mergeSelected(getEditLayer().data); 055 } 056 057 @Override 058 protected void updateEnabledState() { 059 if (getCurrentDataSet() == null) { 060 setEnabled(false); 061 } else { 062 updateEnabledState(getCurrentDataSet().getAllSelected()); 063 } 064 } 065 066 @Override 067 protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) { 068 setEnabled(selection != null && !selection.isEmpty()); 069 } 070 071 /** 072 * returns true if the user wants to cancel, false if they want to continue 073 */ 074 public static final boolean warnMergingUploadDiscouragedObjects(Layer targetLayer) { 075 return GuiHelper.warnUser(tr("Merging too many objects with different upload policies"), 076 "<html>" + 077 tr("You are about to merge more than 1 object between layers ''{0}'' and ''{1}''.<br /><br />"+ 078 "<b>This is not the recommended way of merging such data</b>.<br />"+ 079 "You should instead check and merge each object, <b>one by one</b>.<br /><br />"+ 080 "Are you sure you want to continue?", getEditLayer().getName(), targetLayer.getName(), targetLayer.getName())+ 081 "</html>", 082 ImageProvider.get("dialogs", "mergedown"), tr("Ignore this hint and merge anyway")); 083 } 084 }