source: josm/trunk/src/org/openstreetmap/josm/actions/ReverseWayAction.java@ 12518

Last change on this file since 12518 was 12356, checked in by michael2402, 7 years ago

CombineWayAction: Allow merging ways that are not in the current edit data set.

  • Property svn:eol-style set to native
File size: 5.7 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.actions;
3
4import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
5import static org.openstreetmap.josm.tools.I18n.tr;
6
7import java.awt.event.ActionEvent;
8import java.awt.event.KeyEvent;
9import java.util.ArrayList;
10import java.util.Collection;
11import java.util.Collections;
12import java.util.LinkedList;
13import java.util.List;
14
15import javax.swing.JOptionPane;
16
17import org.openstreetmap.josm.Main;
18import org.openstreetmap.josm.command.ChangeCommand;
19import org.openstreetmap.josm.command.Command;
20import org.openstreetmap.josm.command.SequenceCommand;
21import org.openstreetmap.josm.corrector.ReverseWayNoTagCorrector;
22import org.openstreetmap.josm.corrector.ReverseWayTagCorrector;
23import org.openstreetmap.josm.data.osm.DataSet;
24import org.openstreetmap.josm.data.osm.Node;
25import org.openstreetmap.josm.data.osm.OsmPrimitive;
26import org.openstreetmap.josm.data.osm.Way;
27import org.openstreetmap.josm.gui.Notification;
28import org.openstreetmap.josm.tools.Shortcut;
29import org.openstreetmap.josm.tools.UserCancelException;
30
31/**
32 * Reverses the ways that are currently selected by the user
33 */
34public final class ReverseWayAction extends JosmAction {
35
36 /**
37 * The resulting way after reversing it and the commands to get there.
38 */
39 public static class ReverseWayResult {
40 private final Way newWay;
41 private final Collection<Command> tagCorrectionCommands;
42 private final Command reverseCommand;
43
44 /**
45 * Create a new {@link ReverseWayResult}
46 * @param newWay The new way primitive
47 * @param tagCorrectionCommands The commands to correct the tags
48 * @param reverseCommand The command to reverse the way
49 */
50 public ReverseWayResult(Way newWay, Collection<Command> tagCorrectionCommands, Command reverseCommand) {
51 this.newWay = newWay;
52 this.tagCorrectionCommands = tagCorrectionCommands;
53 this.reverseCommand = reverseCommand;
54 }
55
56 /**
57 * Gets the new way object
58 * @return The new, reversed way
59 */
60 public Way getNewWay() {
61 return newWay;
62 }
63
64 /**
65 * Gets the commands that will be required to do a full way reversal including changing the tags
66 * @return The comamnds
67 */
68 public Collection<Command> getCommands() {
69 List<Command> c = new ArrayList<>();
70 c.addAll(tagCorrectionCommands);
71 c.add(reverseCommand);
72 return c;
73 }
74
75 /**
76 * Gets a single sequence command for reversing this way including changing the tags
77 * @return the command
78 */
79 public Command getAsSequenceCommand() {
80 return new SequenceCommand(tr("Reverse way"), getCommands());
81 }
82
83 /**
84 * Gets the basic reverse command that only changes the order of the nodes.
85 * @return The reorder nodes command
86 */
87 public Command getReverseCommand() {
88 return reverseCommand;
89 }
90
91 /**
92 * Gets the command to change the tags of the way
93 * @return The command to reverse the tags
94 */
95 public Collection<Command> getTagCorrectionCommands() {
96 return tagCorrectionCommands;
97 }
98 }
99
100 /**
101 * Creates a new {@link ReverseWayAction} and binds the shortcut
102 */
103 public ReverseWayAction() {
104 super(tr("Reverse Ways"), "wayflip", tr("Reverse the direction of all selected ways."),
105 Shortcut.registerShortcut("tools:reverse", tr("Tool: {0}", tr("Reverse Ways")), KeyEvent.VK_R, Shortcut.DIRECT), true);
106 putValue("help", ht("/Action/ReverseWays"));
107 }
108
109 @Override
110 public void actionPerformed(ActionEvent e) {
111 DataSet ds = getLayerManager().getEditDataSet();
112 if (!isEnabled() || ds == null)
113 return;
114
115 final Collection<Way> sel = ds.getSelectedWays();
116 if (sel.isEmpty()) {
117 new Notification(
118 tr("Please select at least one way."))
119 .setIcon(JOptionPane.INFORMATION_MESSAGE)
120 .setDuration(Notification.TIME_SHORT)
121 .show();
122 return;
123 }
124
125 Collection<Command> c = new LinkedList<>();
126 for (Way w : sel) {
127 ReverseWayResult revResult;
128 try {
129 revResult = reverseWay(w);
130 } catch (UserCancelException ex) {
131 Main.trace(ex);
132 return;
133 }
134 c.addAll(revResult.getCommands());
135 }
136 Main.main.undoRedo.add(new SequenceCommand(tr("Reverse ways"), c));
137 }
138
139 /**
140 * @param w the way
141 * @return the reverse command and the tag correction commands
142 * @throws UserCancelException if user cancels a reverse warning dialog
143 */
144 public static ReverseWayResult reverseWay(Way w) throws UserCancelException {
145 ReverseWayNoTagCorrector.checkAndConfirmReverseWay(w);
146 Way wnew = new Way(w);
147 List<Node> nodesCopy = wnew.getNodes();
148 Collections.reverse(nodesCopy);
149 wnew.setNodes(nodesCopy);
150
151 Collection<Command> corrCmds = Collections.<Command>emptyList();
152 if (Main.pref.getBoolean("tag-correction.reverse-way", true)) {
153 corrCmds = (new ReverseWayTagCorrector()).execute(w, wnew);
154 }
155 return new ReverseWayResult(wnew, corrCmds, new ChangeCommand(w.getDataSet(), w, wnew));
156 }
157
158 @Override
159 protected void updateEnabledState() {
160 updateEnabledStateOnCurrentSelection();
161 }
162
163 @Override
164 protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
165 setEnabled(selection.stream().anyMatch(Way.class::isInstance));
166 }
167}
Note: See TracBrowser for help on using the repository browser.