public void actionPerformed(ActionEvent e) { Collection<OsmPrimitive> selection = getCurrentDataSet().getSelected(); Set<Node> selectedNodes = OsmPrimitive.getFilteredSet(selection, Node.class); getCurrentDataSet().clearSelection(selectedNodes); Command cmd = null; if (Main.main.undoRedo.commands == null) return; int num = Main.main.undoRedo.commands.size(); if (num == 0) return; int k = 0, idx; if (selection != null && !selection.isEmpty() && selection.hashCode() == lastHash) { // we are selecting next command in history if nothing is selected idx = Main.main.undoRedo.commands.indexOf(lastCmd); // System.out.println("My previous selection found "+idx); } else { idx = num; // System.out.println("last history item taken"); } Set<Node> nodes = new HashSet<Node>(10); do { // select next history element if (idx > 0) idx--; else idx = num - 1; cmd = Main.main.undoRedo.commands.get(idx); Collection<? extends OsmPrimitive> pp = cmd.getParticipatingPrimitives(); nodes.clear(); for (OsmPrimitive p : pp) { // find all affected ways if (p instanceof Node && !p.isDeleted()) nodes.add((Node) p); } if (!nodes.isEmpty()) { getCurrentDataSet().setSelected(nodes); lastCmd = cmd; // remember last used command and last selection lastHash = getCurrentDataSet().getSelected().hashCode(); return; } k++; // System.out.println("no nodes found, previous..."); } while (k < num); // try to find previous command if this affects nothing lastCmd = null; lastHash = 0; }
/** * handles everything related to highlighting primitives and way segments for the given pointer * position (via MouseEvent) and modifiers. * * @param e current mouse event * @param modifiers mouse modifiers, not necessarly taken from the given mouse event */ private void addHighlighting(MouseEvent e, int modifiers) { if (!drawTargetHighlight) return; Set<OsmPrimitive> newHighlights = new HashSet<>(); DeleteParameters parameters = getDeleteParameters(e, modifiers); if (parameters.mode == DeleteMode.segment) { // deleting segments is the only action not working on OsmPrimitives // so we have to handle them separately. repaintIfRequired(newHighlights, parameters.nearestSegment); } else { // don't call buildDeleteCommands for DeleteMode.segment because it doesn't support // silent operation and SplitWayAction will show dialogs. A lot. Command delCmd = buildDeleteCommands(e, modifiers, true); if (delCmd != null) { // all other cases delete OsmPrimitives directly, so we can safely do the following for (OsmPrimitive osm : delCmd.getParticipatingPrimitives()) { newHighlights.add(osm); } } repaintIfRequired(newHighlights, null); } }
public static boolean checkAndConfirmOutlyingDelete( Collection<? extends OsmPrimitive> primitives, Collection<? extends OsmPrimitive> ignore) { return Command.checkAndConfirmOutlyingOperation( "delete", tr("Delete confirmation"), tr( "You are about to delete nodes outside of the area you have downloaded." + "<br>" + "This can cause problems because other objects (that you do not see) might use them." + "<br>" + "Do you really want to delete?"), tr( "You are about to delete incomplete objects." + "<br>" + "This will cause problems because you don''t see the real object." + "<br>" + "Do you really want to delete?"), primitives, ignore); }
/** * Gets called whenever the shortcut is pressed or the menu entry is selected Checks whether the * selected objects are suitable to join and joins them if so */ @Override public void actionPerformed(ActionEvent e) { LinkedList<Way> ways = new LinkedList<Way>(Main.main.getCurrentDataSet().getSelectedWays()); if (ways.isEmpty()) { new Notification(tr("Please select at least one closed way that should be joined.")) .setIcon(JOptionPane.INFORMATION_MESSAGE) .show(); return; } List<Node> allNodes = new ArrayList<Node>(); for (Way way : ways) { if (!way.isClosed()) { new Notification( tr("One of the selected ways is not closed and therefore cannot be joined.")) .setIcon(JOptionPane.INFORMATION_MESSAGE) .show(); return; } allNodes.addAll(way.getNodes()); } // TODO: Only display this warning when nodes outside dataSourceArea are deleted boolean ok = Command.checkAndConfirmOutlyingOperation( "joinarea", tr("Join area confirmation"), trn( "The selected way has nodes outside of the downloaded data region.", "The selected ways have nodes outside of the downloaded data region.", ways.size()) + "<br/>" + tr("This can lead to nodes being deleted accidentally.") + "<br/>" + tr("Are you really sure to continue?") + tr("Please abort if you are not sure"), tr("The selected area is incomplete. Continue?"), allNodes, null); if (!ok) return; // analyze multipolygon relations and collect all areas List<Multipolygon> areas = collectMultipolygons(ways); if (areas == null) // too complex multipolygon relations found return; if (!testJoin(areas)) { new Notification(tr("No intersection found. Nothing was changed.")) .setIcon(JOptionPane.INFORMATION_MESSAGE) .show(); return; } if (!resolveTagConflicts(areas)) return; // user canceled, do nothing. try { JoinAreasResult result = joinAreas(areas); if (result.hasChanges) { List<Way> allWays = new ArrayList<Way>(); for (Multipolygon pol : result.polygons) { allWays.add(pol.outerWay); allWays.addAll(pol.innerWays); } DataSet ds = Main.main.getCurrentDataSet(); ds.setSelected(allWays); Main.map.mapView.repaint(); } else { new Notification(tr("No intersection found. Nothing was changed.")) .setIcon(JOptionPane.INFORMATION_MESSAGE) .show(); } } catch (UserCancelException exception) { // revert changes // FIXME: this is dirty hack makeCommitsOneAction(tr("Reverting changes")); Main.main.undoRedo.undo(); Main.main.undoRedo.redoCommands.clear(); } }