Ticket #13430: patch-paste-from-osm.patch
| File patch-paste-from-osm.patch, 16.5 KB (added by , 9 years ago) |
|---|
-
src/org/openstreetmap/josm/gui/GettingStarted.java
diff --git a/src/org/openstreetmap/josm/gui/GettingStarted.java b/src/org/openstreetmap/josm/gui/GettingStarted.java index 3c05eea..f04b348 100644
a b import javax.swing.event.HyperlinkListener; 23 23 24 24 import org.openstreetmap.josm.Main; 25 25 import org.openstreetmap.josm.data.Version; 26 import org.openstreetmap.josm.gui.datatransfer. FileTransferHandler;26 import org.openstreetmap.josm.gui.datatransfer.OpenTransferHandler; 27 27 import org.openstreetmap.josm.gui.preferences.server.ProxyPreference; 28 28 import org.openstreetmap.josm.gui.preferences.server.ProxyPreferenceListener; 29 29 import org.openstreetmap.josm.gui.widgets.JosmEditorPane; … … public final class GettingStarted extends JPanel implements ProxyPreferenceListe 132 132 133 133 getMOTD(); 134 134 135 setTransferHandler(new FileTransferHandler());135 setTransferHandler(new OpenTransferHandler()); 136 136 } 137 137 138 138 private void getMOTD() { -
new file src/org/openstreetmap/josm/gui/datatransfer/AbstractStackTransferHandler.java
diff --git a/src/org/openstreetmap/josm/gui/datatransfer/AbstractStackTransferHandler.java b/src/org/openstreetmap/josm/gui/datatransfer/AbstractStackTransferHandler.java new file mode 100644 index 0000000..de50169
- + 1 // License: GPL. For details, see LICENSE file. 2 package org.openstreetmap.josm.gui.datatransfer; 3 4 import java.awt.datatransfer.UnsupportedFlavorException; 5 import java.io.IOException; 6 import java.util.Collection; 7 8 import javax.swing.JComponent; 9 import javax.swing.TransferHandler; 10 11 import org.openstreetmap.josm.Main; 12 import org.openstreetmap.josm.data.coor.EastNorth; 13 import org.openstreetmap.josm.gui.datatransfer.importers.AbstractOsmDataPaster; 14 import org.openstreetmap.josm.gui.layer.OsmDataLayer; 15 import org.openstreetmap.josm.tools.bugreport.BugReport; 16 17 /** 18 * A transfer handler class that allows you to manage a prioritized stack of transfer handlers. 19 * @author Michael Zangl 20 * @since xxx 21 */ 22 public abstract class AbstractStackTransferHandler extends TransferHandler { 23 24 protected abstract Collection<AbstractOsmDataPaster> getSupportedPasters(); 25 26 @Override 27 public int getSourceActions(JComponent c) { 28 return COPY; 29 } 30 31 @Override 32 public boolean canImport(TransferSupport support) { 33 // import everything for now, only support copy. 34 for (AbstractOsmDataPaster df : getSupportedPasters()) { 35 if (df.supports(support)) { 36 return true; 37 } 38 } 39 return false; 40 } 41 42 @Override 43 public boolean importData(TransferSupport support) { 44 return importData(support, Main.getLayerManager().getEditLayer(), null); 45 } 46 47 protected boolean importData(TransferSupport support, OsmDataLayer layer, EastNorth center) { 48 for (AbstractOsmDataPaster df : getSupportedPasters()) { 49 if (df.supports(support)) { 50 try { 51 if (df.importData(support, layer, center)) { 52 return true; 53 } 54 } catch (UnsupportedFlavorException | IOException e) { 55 Main.warn(e); 56 } catch (RuntimeException e) { 57 BugReport.intercept(e).put("paster", df).put("flavors", () -> support.getDataFlavors()).warn(); 58 } 59 } 60 } 61 return super.importData(support); 62 } 63 64 } -
deleted file src/org/openstreetmap/josm/gui/datatransfer/FileTransferHandler.java
diff --git a/src/org/openstreetmap/josm/gui/datatransfer/FileTransferHandler.java b/src/org/openstreetmap/josm/gui/datatransfer/FileTransferHandler.java deleted file mode 100644 index 2274dfe..0000000
+ - 1 // License: GPL. For details, see LICENSE file.2 package org.openstreetmap.josm.gui.datatransfer;3 4 import java.awt.datatransfer.UnsupportedFlavorException;5 import java.io.IOException;6 7 import javax.swing.JComponent;8 import javax.swing.TransferHandler;9 10 import org.openstreetmap.josm.Main;11 import org.openstreetmap.josm.gui.datatransfer.importers.FilePaster;12 13 /**14 * This transfer handler allows to drop files to open them.15 *16 * @author Michael Zangl17 * @since 1062018 */19 public class FileTransferHandler extends TransferHandler {20 21 private static final FilePaster filePaster = new FilePaster();22 23 @Override24 public int getSourceActions(JComponent c) {25 return COPY;26 }27 28 @Override29 public boolean canImport(TransferSupport support) {30 return filePaster.supports(support);31 }32 33 @Override34 public boolean importData(TransferSupport support) {35 try {36 if (filePaster.supports(support)) {37 return filePaster.importData(support, null, null);38 }39 } catch (UnsupportedFlavorException | IOException e) {40 Main.warn(e, "Error while importing file.");41 }42 return super.importData(support);43 }44 } -
new file src/org/openstreetmap/josm/gui/datatransfer/OpenTransferHandler.java
diff --git a/src/org/openstreetmap/josm/gui/datatransfer/OpenTransferHandler.java b/src/org/openstreetmap/josm/gui/datatransfer/OpenTransferHandler.java new file mode 100644 index 0000000..cf9a05c
- + 1 // License: GPL. For details, see LICENSE file. 2 package org.openstreetmap.josm.gui.datatransfer; 3 4 import java.util.Arrays; 5 import java.util.Collection; 6 7 import org.openstreetmap.josm.gui.datatransfer.importers.AbstractOsmDataPaster; 8 import org.openstreetmap.josm.gui.datatransfer.importers.FilePaster; 9 import org.openstreetmap.josm.gui.datatransfer.importers.OsmLinkPaster; 10 11 /** 12 * This transfer handler allows to e.g. drop files to open them. 13 * 14 * @author Michael Zangl 15 * @since 10620 16 * @since xxx rename 17 */ 18 public class OpenTransferHandler extends AbstractStackTransferHandler { 19 20 private static final Collection<AbstractOsmDataPaster> SUPPORTED = Arrays.asList(new FilePaster(), new OsmLinkPaster()); 21 22 @Override 23 protected Collection<AbstractOsmDataPaster> getSupportedPasters() { 24 return SUPPORTED; 25 } 26 } -
src/org/openstreetmap/josm/gui/datatransfer/OsmTransferHandler.java
diff --git a/src/org/openstreetmap/josm/gui/datatransfer/OsmTransferHandler.java b/src/org/openstreetmap/josm/gui/datatransfer/OsmTransferHandler.java index fdc8b89..a8f7dc8 100644
a b import java.io.IOException; 8 8 import java.util.Arrays; 9 9 import java.util.Collection; 10 10 11 import javax.swing.TransferHandler;12 13 11 import org.openstreetmap.josm.Main; 14 12 import org.openstreetmap.josm.data.coor.EastNorth; 15 13 import org.openstreetmap.josm.data.osm.OsmPrimitive; 16 14 import org.openstreetmap.josm.gui.datatransfer.importers.AbstractOsmDataPaster; 17 15 import org.openstreetmap.josm.gui.datatransfer.importers.FilePaster; 16 import org.openstreetmap.josm.gui.datatransfer.importers.OsmLinkPaster; 18 17 import org.openstreetmap.josm.gui.datatransfer.importers.PrimitiveDataPaster; 19 18 import org.openstreetmap.josm.gui.datatransfer.importers.PrimitiveTagTransferPaster; 20 19 import org.openstreetmap.josm.gui.datatransfer.importers.TagTransferPaster; … … import org.openstreetmap.josm.gui.layer.OsmDataLayer; 26 25 * @author Michael Zangl 27 26 * @since 10604 28 27 */ 29 public class OsmTransferHandler extends TransferHandler {28 public class OsmTransferHandler extends AbstractStackTransferHandler { 30 29 31 30 private static final Collection<AbstractOsmDataPaster> SUPPORTED = Arrays.asList( 32 31 new FilePaster(), new PrimitiveDataPaster(), 33 32 new PrimitiveTagTransferPaster(), 34 new TagTransferPaster(), new TextTagPaster());33 new TagTransferPaster(), new OsmLinkPaster(), new TextTagPaster()); 35 34 36 35 @Override 37 public boolean canImport(TransferSupport support) { 38 // import everything for now, only support copy. 39 for (AbstractOsmDataPaster df : SUPPORTED) { 40 if (df.supports(support)) { 41 return true; 42 } 43 } 44 return false; 45 } 46 47 @Override 48 public boolean importData(TransferSupport support) { 49 return importData(support, Main.getLayerManager().getEditLayer(), null); 50 } 51 52 private boolean importData(TransferSupport support, OsmDataLayer layer, EastNorth center) { 53 for (AbstractOsmDataPaster df : SUPPORTED) { 54 if (df.supports(support)) { 55 try { 56 if (df.importData(support, layer, center)) { 57 return true; 58 } 59 } catch (UnsupportedFlavorException | IOException e) { 60 Main.warn(e); 61 } 62 } 63 } 64 return super.importData(support); 36 protected Collection<AbstractOsmDataPaster> getSupportedPasters() { 37 return SUPPORTED; 65 38 } 66 39 67 40 private boolean importTags(TransferSupport support, Collection<? extends OsmPrimitive> primitives) { -
src/org/openstreetmap/josm/gui/datatransfer/importers/AbstractOsmDataPaster.java
diff --git a/src/org/openstreetmap/josm/gui/datatransfer/importers/AbstractOsmDataPaster.java b/src/org/openstreetmap/josm/gui/datatransfer/importers/AbstractOsmDataPaster.java index f9aa4c3..619b9f9 100644
a b public abstract class AbstractOsmDataPaster { 56 56 /** 57 57 * Attempts to import the given transfer data. 58 58 * @param support The transfer support to import from. 59 * @param layer The layer to paste at. 59 * @param layer The layer to paste at. May be null. 60 60 * @param pasteAt The position to paste at. 61 61 * @return <code>true</code> if the import was successful. 62 62 * @throws UnsupportedFlavorException if the requested data flavor is not supported -
new file src/org/openstreetmap/josm/gui/datatransfer/importers/OsmLinkPaster.java
diff --git a/src/org/openstreetmap/josm/gui/datatransfer/importers/OsmLinkPaster.java b/src/org/openstreetmap/josm/gui/datatransfer/importers/OsmLinkPaster.java new file mode 100644 index 0000000..1f990c1
- + 1 // License: GPL. For details, see LICENSE file. 2 package org.openstreetmap.josm.gui.datatransfer.importers; 3 4 import java.awt.Component; 5 import java.awt.datatransfer.DataFlavor; 6 import java.awt.datatransfer.UnsupportedFlavorException; 7 import java.io.IOException; 8 import java.util.Collections; 9 import java.util.List; 10 import java.util.regex.Matcher; 11 import java.util.regex.Pattern; 12 13 import javax.swing.TransferHandler.TransferSupport; 14 15 import org.openstreetmap.josm.Main; 16 import org.openstreetmap.josm.data.coor.EastNorth; 17 import org.openstreetmap.josm.data.coor.LatLon; 18 import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 19 import org.openstreetmap.josm.data.osm.PrimitiveId; 20 import org.openstreetmap.josm.data.osm.SimplePrimitiveId; 21 import org.openstreetmap.josm.data.preferences.BooleanProperty; 22 import org.openstreetmap.josm.gui.MapView; 23 import org.openstreetmap.josm.gui.io.DownloadPrimitivesWithReferrersTask; 24 import org.openstreetmap.josm.gui.layer.OsmDataLayer; 25 26 /** 27 * Handles the paste / drop of an OSM address. 28 * <p> 29 * e.g. http://www.openstreetmap.org/node/123 downloads node 123 30 * 31 * @author Michael Zangl 32 * @since xxx 33 */ 34 public class OsmLinkPaster extends AbstractOsmDataPaster { 35 36 private static final BooleanProperty PASTE_REFERRERS = new BooleanProperty("paste.url.download-referrers", true); 37 private static final String OSM_SERVER = "^https?\\://(\\w+\\.)?(osm|openstreetmap)\\.org/"; 38 39 /** 40 * Create a new Osm address paster 41 */ 42 public OsmLinkPaster() { 43 super(DataFlavor.stringFlavor); 44 } 45 46 @Override 47 public boolean importData(TransferSupport support, OsmDataLayer layer, EastNorth pasteAt) 48 throws UnsupportedFlavorException, IOException { 49 if (!supports(support)) { 50 throw new UnsupportedFlavorException(df); 51 } 52 53 String transferData = (String) support.getTransferable().getTransferData(df); 54 List<PrimitiveId> ids = parseIds(transferData); 55 56 if (!ids.isEmpty()) { 57 Main.worker.submit(new DownloadPrimitivesWithReferrersTask(layer == null, 58 ids, PASTE_REFERRERS.get(), PASTE_REFERRERS.get(), null, null)); 59 return true; 60 } 61 62 LatLon ll = parseLatLon(transferData); 63 if (ll != null) { 64 Component comp = support.getComponent(); 65 if (comp instanceof MapView) { 66 ((MapView) comp).zoomTo(ll); 67 } 68 } 69 70 return false; 71 } 72 73 protected static LatLon parseLatLon(String transferData) { 74 Matcher matcher = Pattern 75 .compile(OSM_SERVER + "#map=(?<zoom>\\d+)/(?<lat>-?\\d+\\.\\d+)/(?<lon>-?\\d+\\.\\d+)$") 76 .matcher(transferData); 77 78 if (!matcher.matches()) { 79 return null; 80 } else { 81 return new LatLon(Double.parseDouble(matcher.group("lat")), Double.parseDouble(matcher.group("lon"))); 82 } 83 } 84 85 static List<PrimitiveId> parseIds(String transferData) { 86 Matcher matcher = Pattern 87 .compile(OSM_SERVER + "(?<type>node|way|relation)/(?<id>\\d+)(\\/.*)?$") 88 .matcher(transferData); 89 90 if (!matcher.matches()) { 91 return Collections.emptyList(); 92 } 93 94 OsmPrimitiveType type; 95 switch (matcher.group("type")) { 96 case "way": 97 type = OsmPrimitiveType.WAY; 98 break; 99 100 case "node": 101 type = OsmPrimitiveType.NODE; 102 break; 103 104 case "relation": 105 type = OsmPrimitiveType.RELATION; 106 break; 107 108 default: 109 throw new AssertionError(); 110 } 111 112 return Collections.singletonList(new SimplePrimitiveId(Long.parseLong(matcher.group("id")), type)); 113 } 114 115 } -
new file test/unit/org/openstreetmap/josm/gui/datatransfer/importers/OsmLinkPasterTest.java
diff --git a/test/unit/org/openstreetmap/josm/gui/datatransfer/importers/OsmLinkPasterTest.java b/test/unit/org/openstreetmap/josm/gui/datatransfer/importers/OsmLinkPasterTest.java new file mode 100644 index 0000000..a227b93
- + 1 // License: GPL. For details, see LICENSE file. 2 package org.openstreetmap.josm.gui.datatransfer.importers; 3 4 import static org.junit.Assert.assertArrayEquals; 5 6 import org.junit.Rule; 7 import org.junit.Test; 8 import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 9 import org.openstreetmap.josm.data.osm.SimplePrimitiveId; 10 import org.openstreetmap.josm.testutils.JOSMTestRules; 11 12 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; 13 14 /** 15 * Test {@link OsmLinkPaster} 16 * @author Michael Zangl 17 * @since xxx 18 */ 19 public class OsmLinkPasterTest { 20 /** 21 * No dependencies 22 */ 23 @Rule 24 @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD") 25 public JOSMTestRules test = new JOSMTestRules(); 26 27 /** 28 * Test of {@link OsmLinkPaster#parseIds(String)} 29 */ 30 @Test 31 public void testParseIds() { 32 assertArrayEquals(new Object[] { new SimplePrimitiveId(1234, OsmPrimitiveType.NODE) }, 33 OsmLinkPaster.parseIds("http://www.openstreetmap.org/node/1234").toArray()); 34 assertArrayEquals(new Object[] { new SimplePrimitiveId(1234, OsmPrimitiveType.WAY) }, 35 OsmLinkPaster.parseIds("http://www.openstreetmap.org/way/1234").toArray()); 36 assertArrayEquals(new Object[] { new SimplePrimitiveId(1234, OsmPrimitiveType.RELATION) }, 37 OsmLinkPaster.parseIds("http://www.openstreetmap.org/relation/1234").toArray()); 38 39 assertArrayEquals(new Object[] { new SimplePrimitiveId(1234, OsmPrimitiveType.NODE) }, 40 OsmLinkPaster.parseIds("http://www.osm.org/node/1234").toArray()); 41 assertArrayEquals(new Object[] { new SimplePrimitiveId(1234, OsmPrimitiveType.WAY) }, 42 OsmLinkPaster.parseIds("http://osm.org/way/1234").toArray()); 43 assertArrayEquals(new Object[] { new SimplePrimitiveId(1234, OsmPrimitiveType.RELATION) }, 44 OsmLinkPaster.parseIds("https://www.openstreetmap.org/relation/1234").toArray()); 45 46 47 assertArrayEquals(new Object[0], OsmLinkPaster.parseIds("http://www.openstreetmap.org/xx/1234").toArray()); 48 assertArrayEquals(new Object[0], OsmLinkPaster.parseIds("http://www.openstreetmap.org/way/1234x").toArray()); 49 assertArrayEquals(new Object[0], OsmLinkPaster.parseIds("").toArray()); 50 } 51 52 }
