Skip to content

Commit

Permalink
Prohibit copy-paste from MapWithAI layer to OSM layer
Browse files Browse the repository at this point in the history
Signed-off-by: Taylor Smock <[email protected]>
  • Loading branch information
tsmock committed May 26, 2021
1 parent 946593f commit bf34797
Show file tree
Hide file tree
Showing 6 changed files with 173 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import org.openstreetmap.josm.plugins.mapwithai.data.validation.tests.StubEndsTest;
import org.openstreetmap.josm.plugins.mapwithai.frontend.MapWithAIDownloadReader;
import org.openstreetmap.josm.plugins.mapwithai.gui.preferences.MapWithAIPreferences;
import org.openstreetmap.josm.plugins.mapwithai.tools.MapWithAICopyProhibit;
import org.openstreetmap.josm.spi.preferences.Config;
import org.openstreetmap.josm.tools.Destroyable;
import org.openstreetmap.josm.tools.Logging;
Expand Down Expand Up @@ -110,6 +111,8 @@ public MapWithAIPlugin(PluginInformation info) {
mapWithAIDownloadReader = new MapWithAIDownloadReader();
DownloadDialog.addDownloadSource(mapWithAIDownloadReader);
MainApplication.worker.execute(() -> UpdateProd.doProd(info.mainversion));

destroyables.add(new MapWithAICopyProhibit());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.plugins.mapwithai.tools;

import org.openstreetmap.josm.data.osm.DataSet;
import org.openstreetmap.josm.gui.MainApplication;
import org.openstreetmap.josm.gui.Notification;
import org.openstreetmap.josm.gui.datatransfer.ClipboardUtils;
import org.openstreetmap.josm.gui.datatransfer.data.PrimitiveTransferData;
import org.openstreetmap.josm.gui.layer.MainLayerManager;
import org.openstreetmap.josm.gui.util.GuiHelper;
import org.openstreetmap.josm.plugins.mapwithai.backend.MapWithAILayer;
import org.openstreetmap.josm.tools.Destroyable;
import org.openstreetmap.josm.tools.Logging;

import javax.swing.JOptionPane;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;
import java.util.stream.Stream;

import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
import static org.openstreetmap.josm.tools.I18n.tr;

/**
* Keep users from copying from the MapWithAI layer to the OSM layer
*/
public class MapWithAICopyProhibit implements MainLayerManager.ActiveLayerChangeListener, Destroyable {
/**
* Create a new listener to keep copy-paste from happening between the MapWithAI
* layer and the OSM layer
*/
public MapWithAICopyProhibit() {
MainApplication.getLayerManager().addActiveLayerChangeListener(this);
}

@Override
public void activeOrEditLayerChanged(MainLayerManager.ActiveLayerChangeEvent e) {
if (e.getPreviousActiveLayer() instanceof MapWithAILayer && ClipboardUtils.getClipboardContent() != null
&& Stream.of(ClipboardUtils.getClipboardContent().getTransferDataFlavors())
.anyMatch(PrimitiveTransferData.DATA_FLAVOR::equals)) {
PrimitiveTransferData data;
try {
Object tData = ClipboardUtils.getClipboardContent().getTransferData(PrimitiveTransferData.DATA_FLAVOR);
if (tData instanceof PrimitiveTransferData) {
data = (PrimitiveTransferData) tData;
} else {
return;
}
} catch (UnsupportedFlavorException | IOException exception) {
Logging.error(exception);
return;
}
DataSet dataSet = ((MapWithAILayer) e.getPreviousActiveLayer()).getDataSet();
if (data.getAll().stream().anyMatch(pdata -> dataSet.getPrimitiveById(pdata) != null)) {
ClipboardUtils.clear();
Notification notification = new Notification(tr(
"Please use the `MapWithAI: Add Selected Data` command instead of copying and pasting from the MapWithAI Layer."))
.setDuration(Notification.TIME_DEFAULT).setIcon(JOptionPane.INFORMATION_MESSAGE)
.setHelpTopic(ht("Plugin/MapWithAI#BasicUsage"));
GuiHelper.runInEDT(notification::show);
}
}
}

@Override
public void destroy() {
MainApplication.getLayerManager().removeActiveLayerChangeListener(this);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public class MapWithAILayerTest {
@Rule
@SuppressFBWarnings("URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
public JOSMTestRules test = new MapWithAITestRules().sources().wiremock().preferences().main().projection()
.fakeAPI().territories();
.fakeAPI().territories();

MapWithAILayer layer;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public class MapWithAIMoveActionTest {
@Rule
@SuppressFBWarnings("URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
public JOSMTestRules test = new MapWithAITestRules().wiremock().preferences().main().projection().territories()
.assertionsInEDT();
.assertionsInEDT();

@BeforeClass
public static void beforeAll() {
Expand Down Expand Up @@ -116,7 +116,7 @@ public void testConflationDupeKeyRemoval() {

UndoRedoHandler.getInstance().undo();
Awaitility.await().atMost(Durations.ONE_SECOND)
.until(() -> !((Way) ds.getPrimitiveById(way2)).lastNode().hasKey(DuplicateCommand.KEY));
.until(() -> !((Way) ds.getPrimitiveById(way2)).lastNode().hasKey(DuplicateCommand.KEY));
assertFalse(way2.lastNode().hasKey(DuplicateCommand.KEY), "The dupe key should no longer exist");
assertTrue(way1.lastNode().hasKey(DuplicateCommand.KEY), "The dupe key should no longer exist");
}
Expand Down Expand Up @@ -168,7 +168,7 @@ public void testMaxAddNotification() {
}
for (int i = 0; i < 11; i++) {
GuiHelper
.runInEDTAndWaitWithException(() -> ds.setSelected(ds.allNonDeletedPrimitives().iterator().next()));
.runInEDTAndWaitWithException(() -> ds.setSelected(ds.allNonDeletedPrimitives().iterator().next()));
moveAction.actionPerformed(null);
}
assertTrue(notification.shown);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public class MapWithAIUploadHookTest {
@Rule
@SuppressFBWarnings("URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
public JOSMTestRules test = new MapWithAITestRules().sources().wiremock().main().projection().preferences()
.territories();
.territories();

/**
* Test method for {@link MapWithAIUploadHook#modifyChangesetTags(Map)}.
Expand Down Expand Up @@ -108,8 +108,8 @@ public void testModifyChangesetTags() throws PluginException {

BBox tBBox = new BBox(1, 0, 0, 1);
MainApplication.getLayerManager()
.addLayer(new GpxLayer(DetectTaskingManagerUtils.createTaskingManagerGpxData(tBBox),
DetectTaskingManagerUtils.MAPWITHAI_CROP_AREA));
.addLayer(new GpxLayer(DetectTaskingManagerUtils.createTaskingManagerGpxData(tBBox),
DetectTaskingManagerUtils.MAPWITHAI_CROP_AREA));

tags.clear();
hook.modifyChangesetTags(tags);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.plugins.mapwithai.tools;

import mockit.Mock;
import mockit.MockUp;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.openstreetmap.josm.TestUtils;
import org.openstreetmap.josm.actions.CopyAction;
import org.openstreetmap.josm.actions.PasteAction;
import org.openstreetmap.josm.data.coor.LatLon;
import org.openstreetmap.josm.data.osm.DataSet;
import org.openstreetmap.josm.data.osm.Node;
import org.openstreetmap.josm.gui.MainApplication;
import org.openstreetmap.josm.gui.layer.MainLayerManager;
import org.openstreetmap.josm.gui.layer.OsmDataLayer;
import org.openstreetmap.josm.plugins.mapwithai.backend.MapWithAILayer;
import org.openstreetmap.josm.testutils.JOSMTestRules;
import org.openstreetmap.josm.testutils.mockers.WindowMocker;

import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

/**
* Test class for {@link MapWithAICopyProhibit}
*
* @author Taylor Smock
*/
class MapWithAICopyProhibitTest {
private static class BlacklistUtilsMock extends MockUp<BlacklistUtils> {
@Mock
public static boolean isBlacklisted() {
return false;
}
}

// preferences for nodes, main for actions, projection for mapview
@RegisterExtension
JOSMTestRules josmTestRules = new JOSMTestRules().preferences().main().projection();

@Test
void testDestroyable() {
MapWithAICopyProhibit mapWithAICopyProhibit = new MapWithAICopyProhibit();
assertDoesNotThrow(
() -> MainApplication.getLayerManager().removeActiveLayerChangeListener(mapWithAICopyProhibit));
MainLayerManager layerManager = MainApplication.getLayerManager();
IllegalArgumentException illegalArgumentException = assertThrows(IllegalArgumentException.class,
() -> layerManager.removeActiveLayerChangeListener(mapWithAICopyProhibit));
assertEquals("Attempted to remove listener that was not in list: " + mapWithAICopyProhibit,
illegalArgumentException.getMessage());
layerManager.addActiveLayerChangeListener(mapWithAICopyProhibit);
mapWithAICopyProhibit.destroy();
illegalArgumentException = assertThrows(IllegalArgumentException.class,
() -> layerManager.removeActiveLayerChangeListener(mapWithAICopyProhibit));
assertEquals("Attempted to remove listener that was not in list: " + mapWithAICopyProhibit,
illegalArgumentException.getMessage());
}

@Test
void testCopyProhibit() {
TestUtils.assumeWorkingJMockit();
new WindowMocker();
new BlacklistUtilsMock();

MapWithAICopyProhibit mapWithAICopyProhibit = new MapWithAICopyProhibit();
MainLayerManager layerManager = MainApplication.getLayerManager();
OsmDataLayer osmDataLayer = new OsmDataLayer(new DataSet(), "TEST", null);
MapWithAILayer mapWithAILayer = new MapWithAILayer(new DataSet(), "TEST", null);
layerManager.addLayer(osmDataLayer);
layerManager.addLayer(mapWithAILayer);
DataSet mapWithAIDataSet = mapWithAILayer.getDataSet();
Node testNode = new Node(LatLon.ZERO);
mapWithAIDataSet.addPrimitive(testNode);
mapWithAIDataSet.setSelected(testNode);
layerManager.setActiveLayer(mapWithAILayer);

CopyAction copyAction = new CopyAction();
copyAction.actionPerformed(null);
PasteAction pasteAction = new PasteAction();

assertEquals(1, mapWithAIDataSet.allPrimitives().size());
pasteAction.actionPerformed(null);
assertEquals(2, mapWithAIDataSet.allPrimitives().size());
pasteAction.actionPerformed(null);
assertEquals(3, mapWithAIDataSet.allPrimitives().size());

layerManager.setActiveLayer(osmDataLayer);
assertEquals(0, osmDataLayer.getDataSet().allPrimitives().size());
for (int i = 0; i < 10; i++) {
pasteAction.actionPerformed(null);
assertEquals(0, osmDataLayer.getDataSet().allPrimitives().size());
}
}
}

0 comments on commit bf34797

Please sign in to comment.