Skip to content

Commit 6cc9da9

Browse files
committed
Add option to toggle layer read-only status to popup menu
1 parent fc0a053 commit 6cc9da9

File tree

4 files changed

+130
-0
lines changed

4 files changed

+130
-0
lines changed
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// License: GPL. For details, see LICENSE file.
2+
package org.openstreetmap.josm.actions;
3+
4+
import static org.openstreetmap.josm.tools.I18n.tr;
5+
6+
import java.awt.Component;
7+
import java.awt.event.ActionEvent;
8+
import java.util.List;
9+
10+
import javax.swing.AbstractAction;
11+
import javax.swing.JCheckBoxMenuItem;
12+
13+
import org.openstreetmap.josm.data.osm.Lockable;
14+
import org.openstreetmap.josm.gui.dialogs.LayerListDialog;
15+
import org.openstreetmap.josm.gui.layer.Layer;
16+
import org.openstreetmap.josm.gui.layer.Layer.LayerAction;
17+
import org.openstreetmap.josm.tools.CheckParameterUtil;
18+
import org.openstreetmap.josm.tools.ImageProvider;
19+
20+
/**
21+
* An action enabling/disabling the {@linkplain Lockable#lock() read-only flag}
22+
* of the layer specified in the constructor.
23+
* @param <L> Type of layer the action should be instantiated for
24+
*
25+
* @since xxx
26+
*/
27+
public class ToggleEditLockLayerAction<L extends Layer & Lockable> extends AbstractAction implements LayerAction {
28+
29+
private final L layer;
30+
31+
/**
32+
* Construct a new {@code ToggleEditLockLayerAction}
33+
* @param layer the layer for which to toggle the {@linkplain Lockable#lock() read-only flag}
34+
*
35+
* @since xxx
36+
*/
37+
public ToggleEditLockLayerAction(L layer) {
38+
super(tr("Prevent modification"));
39+
CheckParameterUtil.ensureParameterNotNull(layer, "layer");
40+
putValue(SHORT_DESCRIPTION, tr("Prevent/allow changes being made in this layer"));
41+
new ImageProvider("lock").getResource().attachImageIcon(this, true);
42+
this.layer = layer;
43+
}
44+
45+
@Override
46+
public void actionPerformed(ActionEvent e) {
47+
if (layer.isLocked()) {
48+
layer.unlock();
49+
} else {
50+
layer.lock();
51+
}
52+
53+
layer.invalidate();
54+
LayerListDialog.getInstance().repaint();
55+
}
56+
57+
@Override
58+
public Component createMenuComponent() {
59+
JCheckBoxMenuItem item = new JCheckBoxMenuItem(this);
60+
item.setSelected(layer.isLocked());
61+
return item;
62+
}
63+
64+
@Override
65+
public boolean supportLayers(List<Layer> layers) {
66+
return layers.size() == 1 && layers.get(0) instanceof Lockable;
67+
}
68+
}

src/org/openstreetmap/josm/actions/ToggleUploadDiscouragedLayerAction.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ public class ToggleUploadDiscouragedLayerAction extends AbstractAction implement
3131
*/
3232
public ToggleUploadDiscouragedLayerAction(OsmDataLayer layer) {
3333
super(tr("Discourage upload"));
34+
putValue(SHORT_DESCRIPTION, tr("Allow/disallow upload of changes made in this layer"));
3435
new ImageProvider("no_upload").getResource().attachImageIcon(this, true);
3536
this.layer = layer;
3637
setEnabled(layer.isUploadable());

src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
import org.openstreetmap.josm.actions.AutoScaleAction;
5353
import org.openstreetmap.josm.actions.ExpertToggleAction;
5454
import org.openstreetmap.josm.actions.RenameLayerAction;
55+
import org.openstreetmap.josm.actions.ToggleEditLockLayerAction;
5556
import org.openstreetmap.josm.actions.ToggleUploadDiscouragedLayerAction;
5657
import org.openstreetmap.josm.data.APIDataSet;
5758
import org.openstreetmap.josm.data.Bounds;
@@ -743,6 +744,7 @@ public Action[] getMenuEntries() {
743744
new RenameLayerAction(getAssociatedFile(), this)));
744745
if (ExpertToggleAction.isExpert()) {
745746
actions.add(new ToggleUploadDiscouragedLayerAction(this));
747+
actions.add(new ToggleEditLockLayerAction<>(this));
746748
}
747749
actions.addAll(Arrays.asList(
748750
new ConsistencyTestAction(),
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// License: GPL. For details, see LICENSE file.
2+
package org.openstreetmap.josm.actions;
3+
4+
import static org.junit.jupiter.api.Assertions.assertEquals;
5+
import static org.junit.jupiter.api.Assertions.assertNotEquals;
6+
import static org.junit.jupiter.api.Assertions.assertThrows;
7+
8+
import org.junit.jupiter.api.Test;
9+
import org.junit.jupiter.api.extension.RegisterExtension;
10+
import org.junit.jupiter.params.ParameterizedTest;
11+
import org.junit.jupiter.params.provider.ValueSource;
12+
import org.openstreetmap.josm.data.osm.DataSet;
13+
import org.openstreetmap.josm.gui.MainApplication;
14+
import org.openstreetmap.josm.gui.layer.OsmDataLayer;
15+
import org.openstreetmap.josm.testutils.JOSMTestRules;
16+
17+
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
18+
19+
/**
20+
* Unit tests for class {@link ToggleEditLockLayerAction}.
21+
*/
22+
final class ToggleEditLockLayerActionTest {
23+
24+
/**
25+
* Setup test.
26+
*/
27+
@RegisterExtension
28+
@SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
29+
public static JOSMTestRules test = new JOSMTestRules().main().projection();
30+
31+
/**
32+
* Test null parameter
33+
*/
34+
@Test
35+
void testNullLayer() {
36+
assertThrows(IllegalArgumentException.class, () -> new ToggleEditLockLayerAction<OsmDataLayer>(null));
37+
}
38+
39+
/**
40+
* Test edit lock toggle functionality
41+
* @param locked Initial layer lock status
42+
*/
43+
@ParameterizedTest
44+
@ValueSource(booleans = {true, false})
45+
void testLayerLockToggle(boolean locked) {
46+
OsmDataLayer testLayer = new OsmDataLayer(new DataSet(), "testLayerLock", null);
47+
MainApplication.getLayerManager().addLayer(testLayer);
48+
if (locked) {
49+
testLayer.lock();
50+
}
51+
// Sanity check
52+
assertEquals(locked, testLayer.isLocked());
53+
ToggleEditLockLayerAction<OsmDataLayer> action = new ToggleEditLockLayerAction<>(testLayer);
54+
action.actionPerformed(null);
55+
assertNotEquals(locked, testLayer.isLocked());
56+
action.actionPerformed(null);
57+
assertEquals(locked, testLayer.isLocked());
58+
}
59+
}

0 commit comments

Comments
 (0)