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

Last change on this file since 12691 was 12641, checked in by Don-vip, 7 years ago

see #15182 - deprecate Main.main.undoRedo. Replacement: gui.MainApplication.undoRedo

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