| 1 | // License: GPL. For details, see LICENSE file. |
|---|
| 2 | package org.openstreetmap.josm.actions; |
|---|
| 3 | |
|---|
| 4 | import static org.openstreetmap.josm.gui.help.HelpUtil.ht; |
|---|
| 5 | import static org.openstreetmap.josm.tools.I18n.tr; |
|---|
| 6 | |
|---|
| 7 | import java.awt.event.ActionEvent; |
|---|
| 8 | import java.awt.event.KeyEvent; |
|---|
| 9 | import java.util.Collection; |
|---|
| 10 | import java.util.Collections; |
|---|
| 11 | import java.util.List; |
|---|
| 12 | |
|---|
| 13 | import org.openstreetmap.josm.Main; |
|---|
| 14 | import org.openstreetmap.josm.gui.dialogs.LayerListDialog; |
|---|
| 15 | import org.openstreetmap.josm.gui.layer.Layer; |
|---|
| 16 | import org.openstreetmap.josm.gui.layer.OsmDataLayer; |
|---|
| 17 | import org.openstreetmap.josm.gui.util.GuiHelper; |
|---|
| 18 | import org.openstreetmap.josm.tools.ImageProvider; |
|---|
| 19 | import org.openstreetmap.josm.tools.Shortcut; |
|---|
| 20 | |
|---|
| 21 | public class MergeLayerAction extends AbstractMergeAction { |
|---|
| 22 | |
|---|
| 23 | public MergeLayerAction() { |
|---|
| 24 | super(tr("Merge layer"), "dialogs/mergedown", |
|---|
| 25 | tr("Merge the current layer into another layer"), |
|---|
| 26 | Shortcut.registerShortcut("system:merge", tr("Edit: {0}", |
|---|
| 27 | tr("Merge")), KeyEvent.VK_M, Shortcut.CTRL), |
|---|
| 28 | true, "action/mergelayer", true); |
|---|
| 29 | putValue("help", ht("/Action/MergeLayer")); |
|---|
| 30 | } |
|---|
| 31 | |
|---|
| 32 | protected void doMerge(List<Layer> targetLayers, final Collection<Layer> sourceLayers) { |
|---|
| 33 | final Layer targetLayer = askTargetLayer(targetLayers); |
|---|
| 34 | if (targetLayer == null) |
|---|
| 35 | return; |
|---|
| 36 | Main.worker.submit(new Runnable() { |
|---|
| 37 | @Override |
|---|
| 38 | public void run() { |
|---|
| 39 | boolean layerMerged = false; |
|---|
| 40 | for (Layer sourceLayer: sourceLayers) { |
|---|
| 41 | if (sourceLayer != null && sourceLayer != targetLayer) { |
|---|
| 42 | if (sourceLayer instanceof OsmDataLayer && targetLayer instanceof OsmDataLayer |
|---|
| 43 | && ((OsmDataLayer)sourceLayer).isUploadDiscouraged() != ((OsmDataLayer)targetLayer).isUploadDiscouraged()) { |
|---|
| 44 | if (warnMergingUploadDiscouragedLayers(sourceLayer, targetLayer)) { |
|---|
| 45 | break; |
|---|
| 46 | } |
|---|
| 47 | } |
|---|
| 48 | targetLayer.mergeFrom(sourceLayer); |
|---|
| 49 | Main.map.mapView.removeLayer(sourceLayer); |
|---|
| 50 | layerMerged = true; |
|---|
| 51 | } |
|---|
| 52 | } |
|---|
| 53 | if (layerMerged) { |
|---|
| 54 | Main.map.mapView.setActiveLayer(targetLayer); |
|---|
| 55 | } |
|---|
| 56 | } |
|---|
| 57 | }); |
|---|
| 58 | } |
|---|
| 59 | |
|---|
| 60 | public void merge(List<Layer> sourceLayers) { |
|---|
| 61 | doMerge(sourceLayers, sourceLayers); |
|---|
| 62 | } |
|---|
| 63 | |
|---|
| 64 | public void merge(Layer sourceLayer) { |
|---|
| 65 | if (sourceLayer == null) |
|---|
| 66 | return; |
|---|
| 67 | List<Layer> targetLayers = LayerListDialog.getInstance().getModel().getPossibleMergeTargets(sourceLayer); |
|---|
| 68 | if (targetLayers.isEmpty()) { |
|---|
| 69 | warnNoTargetLayersForSourceLayer(sourceLayer); |
|---|
| 70 | return; |
|---|
| 71 | } |
|---|
| 72 | doMerge(targetLayers, Collections.singleton(sourceLayer)); |
|---|
| 73 | } |
|---|
| 74 | |
|---|
| 75 | public void actionPerformed(ActionEvent e) { |
|---|
| 76 | Layer sourceLayer = Main.main.getEditLayer(); |
|---|
| 77 | if (sourceLayer == null) |
|---|
| 78 | return; |
|---|
| 79 | merge(sourceLayer); |
|---|
| 80 | } |
|---|
| 81 | |
|---|
| 82 | @Override |
|---|
| 83 | protected void updateEnabledState() { |
|---|
| 84 | if (getEditLayer() == null) { |
|---|
| 85 | setEnabled(false); |
|---|
| 86 | return; |
|---|
| 87 | } |
|---|
| 88 | setEnabled(!LayerListDialog.getInstance().getModel().getPossibleMergeTargets(getEditLayer()).isEmpty()); |
|---|
| 89 | } |
|---|
| 90 | |
|---|
| 91 | /** |
|---|
| 92 | * returns true if the user wants to cancel, false if they want to continue |
|---|
| 93 | */ |
|---|
| 94 | public static final boolean warnMergingUploadDiscouragedLayers(Layer sourceLayer, Layer targetLayer) { |
|---|
| 95 | return GuiHelper.warnUser(tr("Merging layers with different upload policies"), |
|---|
| 96 | "<html>" + |
|---|
| 97 | tr("You are about to merge data between layers ''{0}'' and ''{1}''.<br /><br />"+ |
|---|
| 98 | "These layers have different upload policies and should not been merged as it.<br />"+ |
|---|
| 99 | "Merging them will result to enforce the stricter policy (upload discouraged) to ''{1}''.<br /><br />"+ |
|---|
| 100 | "<b>This is not the recommended way of merging such data</b>.<br />"+ |
|---|
| 101 | "You should instead check and merge each object, one by one, by using ''<i>Merge selection</i>''.<br /><br />"+ |
|---|
| 102 | "Are you sure you want to continue?", sourceLayer.getName(), targetLayer.getName(), targetLayer.getName())+ |
|---|
| 103 | "</html>", |
|---|
| 104 | ImageProvider.get("dialogs", "mergedown"), tr("Ignore this hint and merge anyway")); |
|---|
| 105 | } |
|---|
| 106 | } |
|---|