// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.plugins.utilsplugin2.selection;
import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
import static org.openstreetmap.josm.tools.I18n.tr;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import javax.swing.JOptionPane;
import org.openstreetmap.josm.Main;
import org.openstreetmap.josm.actions.JosmAction;
import org.openstreetmap.josm.actions.SelectByInternalPointAction;
import org.openstreetmap.josm.data.osm.DataSet;
import org.openstreetmap.josm.data.osm.Node;
import org.openstreetmap.josm.data.osm.OsmPrimitive;
import org.openstreetmap.josm.data.osm.Way;
import org.openstreetmap.josm.gui.Notification;
import org.openstreetmap.josm.tools.Shortcut;
/**
* Extends current selection by selecting nodes on all touched ways
*/
public class SelectBoundaryAction extends JosmAction {
private Way lastUsedStartingWay; //used for repeated calls
private boolean lastUsedLeft;
public SelectBoundaryAction() {
super(tr("Area boundary [testing]"), "selboundary", tr("Select relation or all ways that forms area boundary"),
Shortcut.registerShortcut("tools:selboundary", tr("Tool: {0}", "Area boundary [testing]"),
KeyEvent.VK_SLASH, Shortcut.SHIFT), true);
putValue("help", ht("/Action/SelectAreaBoundary"));
}
@Override
public void actionPerformed(ActionEvent e) {
DataSet ds = getLayerManager().getEditDataSet();
if (ds != null) {
Collection<Way> selectedWays = ds.getSelectedWays();
Collection<Node> selectedNodes = ds.getSelectedNodes();
Set<Way> newWays = new HashSet<>();
Way w = null;
if (selectedWays.isEmpty()) {
if (selectedNodes.size() == 1) {
for (OsmPrimitive p : selectedNodes.iterator().next().getReferrers()) {
if (p instanceof Way && p.isSelectable()) {
w = (Way) p;
break;
}
}
} else {
Point p = Main.map.mapView.getMousePosition();
SelectByInternalPointAction.performSelection(Main.map.mapView.getEastNorth(p.x, p.y), false, false);
return;
}
} else if (selectedWays.size() == 1) {
w = selectedWays.iterator().next();
} else if (selectedWays.contains(lastUsedStartingWay)) {
w = lastUsedStartingWay; //repeated call for selected way
lastUsedLeft = !lastUsedLeft;
}
if (w == null) return; //no starting way found
if (!w.isSelectable()) return;
if (w.isClosed()) return;
if (w.getNodesCount() < 2) return;
newWays.add(w);
lastUsedStartingWay = w;
// try going left at each turn
if (!NodeWayUtils.addAreaBoundary(w, newWays, lastUsedLeft)) {
NodeWayUtils.addAreaBoundary(w, newWays, !lastUsedLeft); // try going right at each turn
}
if (!newWays.isEmpty()) {
ds.setSelected(newWays);
} else {
new Notification(tr("Nothing found. Please select way that is a part of some polygon formed by connected ways"))
.setIcon(JOptionPane.WARNING_MESSAGE).show();
}
}
}
@Override
protected void updateEnabledState() {
setEnabled(getLayerManager().getEditDataSet() != null);
}
@Override
protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
setEnabled(selection != null && !selection.isEmpty());
}
}