| 1 | // License: GPL. Copyright 2007 by Immanuel Scholz and others |
|---|
| 2 | package org.openstreetmap.josm.actions; |
|---|
| 3 | |
|---|
| 4 | import static org.openstreetmap.josm.gui.help.HelpUtil.ht; |
|---|
| 5 | import static org.openstreetmap.josm.tools.I18n.tr; |
|---|
| 6 | |
|---|
| 7 | import java.awt.event.ActionEvent; |
|---|
| 8 | import java.awt.event.KeyEvent; |
|---|
| 9 | import java.util.ArrayList; |
|---|
| 10 | import java.util.Collection; |
|---|
| 11 | import java.util.Collections; |
|---|
| 12 | import java.util.LinkedList; |
|---|
| 13 | import java.util.List; |
|---|
| 14 | |
|---|
| 15 | import javax.swing.JOptionPane; |
|---|
| 16 | |
|---|
| 17 | import org.openstreetmap.josm.Main; |
|---|
| 18 | import org.openstreetmap.josm.command.ChangeCommand; |
|---|
| 19 | import org.openstreetmap.josm.command.Command; |
|---|
| 20 | import org.openstreetmap.josm.command.SequenceCommand; |
|---|
| 21 | import org.openstreetmap.josm.corrector.ReverseWayTagCorrector; |
|---|
| 22 | import org.openstreetmap.josm.corrector.UserCancelException; |
|---|
| 23 | import org.openstreetmap.josm.data.osm.Node; |
|---|
| 24 | import org.openstreetmap.josm.data.osm.OsmPrimitive; |
|---|
| 25 | import org.openstreetmap.josm.data.osm.Way; |
|---|
| 26 | import org.openstreetmap.josm.tools.Shortcut; |
|---|
| 27 | import org.openstreetmap.josm.tools.Utils; |
|---|
| 28 | |
|---|
| 29 | public final class ReverseWayAction extends JosmAction { |
|---|
| 30 | |
|---|
| 31 | public static class ReverseWayResult { |
|---|
| 32 | private Way newWay; |
|---|
| 33 | private Collection<Command> tagCorrectionCommands; |
|---|
| 34 | private Command reverseCommand; |
|---|
| 35 | |
|---|
| 36 | public ReverseWayResult(Way newWay, Collection<Command> tagCorrectionCommands, Command reverseCommand) { |
|---|
| 37 | this.newWay = newWay; |
|---|
| 38 | this.tagCorrectionCommands = tagCorrectionCommands; |
|---|
| 39 | this.reverseCommand = reverseCommand; |
|---|
| 40 | } |
|---|
| 41 | |
|---|
| 42 | public Way getNewWay() { |
|---|
| 43 | return newWay; |
|---|
| 44 | } |
|---|
| 45 | |
|---|
| 46 | public Collection<Command> getCommands() { |
|---|
| 47 | List<Command> c = new ArrayList<Command>(); |
|---|
| 48 | c.addAll(tagCorrectionCommands); |
|---|
| 49 | c.add(reverseCommand); |
|---|
| 50 | return c; |
|---|
| 51 | } |
|---|
| 52 | |
|---|
| 53 | public Command getAsSequenceCommand() { |
|---|
| 54 | return new SequenceCommand(tr("Reverse way"), getCommands()); |
|---|
| 55 | } |
|---|
| 56 | |
|---|
| 57 | public Command getReverseCommand() { |
|---|
| 58 | return reverseCommand; |
|---|
| 59 | } |
|---|
| 60 | |
|---|
| 61 | public Collection<Command> getTagCorrectionCommands() { |
|---|
| 62 | return tagCorrectionCommands; |
|---|
| 63 | } |
|---|
| 64 | } |
|---|
| 65 | |
|---|
| 66 | public ReverseWayAction() { |
|---|
| 67 | super(tr("Reverse Ways"), "wayflip", tr("Reverse the direction of all selected ways."), |
|---|
| 68 | Shortcut.registerShortcut("tools:reverse", tr("Tool: {0}", tr("Reverse Ways")), KeyEvent.VK_R, Shortcut.GROUP_EDIT), true); |
|---|
| 69 | putValue("help", ht("/Action/ReverseWays")); |
|---|
| 70 | } |
|---|
| 71 | |
|---|
| 72 | public void actionPerformed(ActionEvent e) { |
|---|
| 73 | if (! isEnabled()) |
|---|
| 74 | return; |
|---|
| 75 | if (getCurrentDataSet() == null) |
|---|
| 76 | return; |
|---|
| 77 | |
|---|
| 78 | final Collection<Way> sel = getCurrentDataSet().getSelectedWays(); |
|---|
| 79 | if (sel.isEmpty()) { |
|---|
| 80 | JOptionPane.showMessageDialog( |
|---|
| 81 | Main.parent, |
|---|
| 82 | tr("Please select at least one way."), |
|---|
| 83 | tr("Information"), |
|---|
| 84 | JOptionPane.INFORMATION_MESSAGE |
|---|
| 85 | ); |
|---|
| 86 | return; |
|---|
| 87 | } |
|---|
| 88 | |
|---|
| 89 | boolean propertiesUpdated = false; |
|---|
| 90 | Collection<Command> c = new LinkedList<Command>(); |
|---|
| 91 | for (Way w : sel) { |
|---|
| 92 | ReverseWayResult revResult; |
|---|
| 93 | try { |
|---|
| 94 | revResult = reverseWay(w); |
|---|
| 95 | } catch (UserCancelException ex) { |
|---|
| 96 | return; |
|---|
| 97 | } |
|---|
| 98 | c.addAll(revResult.getCommands()); |
|---|
| 99 | propertiesUpdated |= !revResult.getTagCorrectionCommands().isEmpty(); |
|---|
| 100 | } |
|---|
| 101 | Main.main.undoRedo.add(new SequenceCommand(tr("Reverse ways"), c)); |
|---|
| 102 | if (propertiesUpdated) { |
|---|
| 103 | getCurrentDataSet().fireSelectionChanged(); |
|---|
| 104 | } |
|---|
| 105 | Main.map.repaint(); |
|---|
| 106 | } |
|---|
| 107 | |
|---|
| 108 | /** |
|---|
| 109 | * @param w the way |
|---|
| 110 | * @return the reverse command and the tag correction commands |
|---|
| 111 | */ |
|---|
| 112 | public static ReverseWayResult reverseWay(Way w) throws UserCancelException { |
|---|
| 113 | Way wnew = new Way(w); |
|---|
| 114 | List<Node> nodesCopy = wnew.getNodes(); |
|---|
| 115 | Collections.reverse(nodesCopy); |
|---|
| 116 | wnew.setNodes(nodesCopy); |
|---|
| 117 | |
|---|
| 118 | Collection<Command> corrCmds = Collections.<Command>emptyList(); |
|---|
| 119 | if (Main.pref.getBoolean("tag-correction.reverse-way", true)) { |
|---|
| 120 | corrCmds = (new ReverseWayTagCorrector()).execute(w, wnew); |
|---|
| 121 | } |
|---|
| 122 | return new ReverseWayResult(wnew, corrCmds, new ChangeCommand(w, wnew)); |
|---|
| 123 | } |
|---|
| 124 | |
|---|
| 125 | protected int getNumWaysInSelection() { |
|---|
| 126 | if (getCurrentDataSet() == null) return 0; |
|---|
| 127 | int ret = 0; |
|---|
| 128 | for (OsmPrimitive primitive : getCurrentDataSet().getSelected()) { |
|---|
| 129 | if (primitive instanceof Way) { |
|---|
| 130 | ret++; |
|---|
| 131 | } |
|---|
| 132 | } |
|---|
| 133 | return ret; |
|---|
| 134 | } |
|---|
| 135 | |
|---|
| 136 | @Override |
|---|
| 137 | protected void updateEnabledState() { |
|---|
| 138 | if (getCurrentDataSet() == null) { |
|---|
| 139 | setEnabled(false); |
|---|
| 140 | } else { |
|---|
| 141 | updateEnabledState(getCurrentDataSet().getSelected()); |
|---|
| 142 | } |
|---|
| 143 | } |
|---|
| 144 | |
|---|
| 145 | @Override |
|---|
| 146 | protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) { |
|---|
| 147 | setEnabled(Utils.exists(selection, OsmPrimitive.wayPredicate)); |
|---|
| 148 | } |
|---|
| 149 | } |
|---|