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

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

see #15182 - deprecate all Main logging methods and introduce suitable replacements in Logging for most of them

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