Ticket #5097: 5097v1.patch
| File 5097v1.patch, 14.0 KB (added by , 12 years ago) |
|---|
-
new file src/org/openstreetmap/josm/actions/RepeatAction.java
diff --git a/src/org/openstreetmap/josm/actions/RepeatAction.java b/src/org/openstreetmap/josm/actions/RepeatAction.java new file mode 100644 index 0000000..e4ddd74
- + 1 package org.openstreetmap.josm.actions; 2 3 import org.openstreetmap.josm.Main; 4 import org.openstreetmap.josm.command.RepeatableCommand; 5 import org.openstreetmap.josm.data.SelectionChangedListener; 6 import org.openstreetmap.josm.data.osm.DataSet; 7 import org.openstreetmap.josm.data.osm.OsmPrimitive; 8 import org.openstreetmap.josm.gui.layer.OsmDataLayer; 9 import org.openstreetmap.josm.tools.Shortcut; 10 11 import java.awt.event.ActionEvent; 12 import java.awt.event.KeyEvent; 13 import java.util.Collection; 14 15 import static org.openstreetmap.josm.tools.I18n.tr; 16 17 public class RepeatAction extends JosmAction implements OsmDataLayer.CommandQueueListener, SelectionChangedListener { 18 19 public RepeatAction() { 20 super(tr("Repeat"), null, tr("Repeat the last action."), 21 Shortcut.registerShortcut("system:repeat", tr("Edit: {0}", tr("Repeat")), KeyEvent.VK_PERIOD, Shortcut.ALT_CTRL), true); 22 setEnabled(false); 23 DataSet.addSelectionListener(this); 24 } 25 26 @Override 27 public void actionPerformed(ActionEvent e) { 28 if (Main.map != null) { 29 Main.map.repaint(); 30 Main.main.undoRedo.add(getRepeatableCommand().repeatableFor(Main.main.getCurrentDataSet().getSelected())); 31 } 32 } 33 34 @Override 35 protected void updateEnabledState() { 36 setEnabled(getRepeatableCommand() != null 37 && Main.main.getCurrentDataSet() != null 38 && !Main.main.getCurrentDataSet().getSelected().isEmpty() 39 && getRepeatableCommand().isRepeatableFor(Main.main.getCurrentDataSet().getSelected())); 40 if (getRepeatableCommand() == null) { 41 putValue(NAME, tr("Repeat")); 42 setTooltip(tr("Repeat the last action.")); 43 } else { 44 putValue(NAME, tr("Repeat ...")); 45 setTooltip(tr("Repeat {0}", getRepeatableCommand().getDescriptionText())); 46 } 47 } 48 49 @Override 50 public void commandChanged(int queueSize, int redoSize) { 51 updateEnabledState(); 52 } 53 54 @Override 55 public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) { 56 updateEnabledState(); 57 } 58 59 protected RepeatableCommand getRepeatableCommand() { 60 if (Main.main != null 61 && !Main.main.undoRedo.commands.isEmpty() 62 && Main.main.undoRedo.commands.getLast() instanceof RepeatableCommand) { 63 return (RepeatableCommand) Main.main.undoRedo.commands.getLast(); 64 } else { 65 return null; 66 } 67 } 68 } 69 -
src/org/openstreetmap/josm/command/ChangePropertyCommand.java
diff --git a/src/org/openstreetmap/josm/command/ChangePropertyCommand.java b/src/org/openstreetmap/josm/command/ChangePropertyCommand.java index 8a3ac10..a106d8f 100644
a b import org.openstreetmap.josm.tools.ImageProvider; 28 28 * 29 29 * @author imi 30 30 */ 31 public class ChangePropertyCommand extends Command {31 public class ChangePropertyCommand extends RepeatableCommand { 32 32 /** 33 33 * All primitives that are affected with this command. 34 34 */ … … public class ChangePropertyCommand extends Command { 213 213 } 214 214 return children; 215 215 } 216 217 @Override 218 public boolean isRepeatableFor(Collection<OsmPrimitive> primitives) { 219 return true; 220 } 221 222 @Override 223 public RepeatableCommand repeatableFor(Collection<OsmPrimitive> primitives) { 224 return new ChangePropertyCommand(primitives, tags); 225 } 216 226 } -
new file src/org/openstreetmap/josm/command/RepeatableCommand.java
diff --git a/src/org/openstreetmap/josm/command/RepeatableCommand.java b/src/org/openstreetmap/josm/command/RepeatableCommand.java new file mode 100644 index 0000000..a6f1029
- + 1 package org.openstreetmap.josm.command; 2 3 import org.openstreetmap.josm.data.osm.OsmPrimitive; 4 import org.openstreetmap.josm.gui.layer.OsmDataLayer; 5 import org.openstreetmap.josm.tools.Predicate; 6 import org.openstreetmap.josm.tools.Utils; 7 8 import java.util.Collection; 9 10 public abstract class RepeatableCommand extends Command { 11 public RepeatableCommand() { 12 } 13 14 public RepeatableCommand(OsmDataLayer layer) throws IllegalArgumentException { 15 super(layer); 16 } 17 18 public abstract boolean isRepeatableFor(final Collection<OsmPrimitive> primitives); 19 20 public abstract RepeatableCommand repeatableFor(final Collection<OsmPrimitive> primitives); 21 22 public static Predicate<Command> getIsRepeatableForPredicate(final Collection<OsmPrimitive> primitives) { 23 return new Predicate<Command>() { 24 @Override 25 public boolean evaluate(Command c) { 26 return c instanceof RepeatableCommand && ((RepeatableCommand) c).isRepeatableFor(primitives); 27 } 28 }; 29 } 30 31 public static Utils.Function<RepeatableCommand, RepeatableCommand> getRepeatForFunction(final Collection<OsmPrimitive> primitives) { 32 return new Utils.Function<RepeatableCommand, RepeatableCommand>() { 33 @Override 34 public RepeatableCommand apply(RepeatableCommand x) { 35 return x.repeatableFor(primitives); 36 } 37 }; 38 } 39 } -
src/org/openstreetmap/josm/command/SequenceCommand.java
diff --git a/src/org/openstreetmap/josm/command/SequenceCommand.java b/src/org/openstreetmap/josm/command/SequenceCommand.java index f172f22..2ae6b2a 100644
a b import static org.openstreetmap.josm.tools.I18n.tr; 6 6 import java.util.Arrays; 7 7 import java.util.Collection; 8 8 import java.util.HashSet; 9 import java.util.List; 9 10 10 11 import javax.swing.Icon; 11 12 12 13 import org.openstreetmap.josm.data.osm.OsmPrimitive; 13 14 import org.openstreetmap.josm.tools.ImageProvider; 15 import org.openstreetmap.josm.tools.Predicate; 16 import org.openstreetmap.josm.tools.Utils; 14 17 15 18 /** 16 19 * A command consisting of a sequence of other commands. Executes the other commands … … import org.openstreetmap.josm.tools.ImageProvider; 18 21 * @author imi 19 22 * @since 31 20 23 */ 21 public class SequenceCommand extends Command {24 public class SequenceCommand extends RepeatableCommand { 22 25 23 26 /** The command sequence to be executed. */ 24 27 private Command[] sequence; … … public class SequenceCommand extends Command { 32 35 * @param name The description text 33 36 * @param sequenz The sequence that should be executed. 34 37 */ 35 public SequenceCommand(String name, Collection< Command> sequenz) {38 public SequenceCommand(String name, Collection<? extends Command> sequenz) { 36 39 super(); 37 40 this.name = name; 38 41 this.sequence = sequenz.toArray(new Command[sequenz.size()]); … … public class SequenceCommand extends Command { 121 124 protected final void setSequenceComplete(boolean sequenceComplete) { 122 125 this.sequenceComplete = sequenceComplete; 123 126 } 127 128 @Override 129 public boolean isRepeatableFor(final Collection<OsmPrimitive> primitives) { 130 return Utils.forAll(Arrays.asList(sequence), getIsRepeatableForPredicate(primitives)); 131 } 132 133 @SuppressWarnings("unchecked") 134 @Override 135 public RepeatableCommand repeatableFor(final Collection<OsmPrimitive> primitives) { 136 final List commands = Arrays.asList(sequence); 137 return new SequenceCommand(name, Utils.transform(commands, getRepeatForFunction(primitives))); 138 } 124 139 } -
src/org/openstreetmap/josm/gui/MainMenu.java
diff --git a/src/org/openstreetmap/josm/gui/MainMenu.java b/src/org/openstreetmap/josm/gui/MainMenu.java index a4d6653..886dcff 100644
a b import javax.swing.event.MenuEvent; 22 22 import javax.swing.event.MenuListener; 23 23 24 24 import org.openstreetmap.josm.Main; 25 import org.openstreetmap.josm.actions.AboutAction; 26 import org.openstreetmap.josm.actions.AddNodeAction; 27 import org.openstreetmap.josm.actions.AlignInCircleAction; 28 import org.openstreetmap.josm.actions.AlignInLineAction; 29 import org.openstreetmap.josm.actions.AutoScaleAction; 30 import org.openstreetmap.josm.actions.ChangesetManagerToggleAction; 31 import org.openstreetmap.josm.actions.CloseChangesetAction; 32 import org.openstreetmap.josm.actions.CombineWayAction; 33 import org.openstreetmap.josm.actions.CopyAction; 34 import org.openstreetmap.josm.actions.CopyCoordinatesAction; 35 import org.openstreetmap.josm.actions.CreateCircleAction; 36 import org.openstreetmap.josm.actions.CreateMultipolygonAction; 37 import org.openstreetmap.josm.actions.DeleteAction; 38 import org.openstreetmap.josm.actions.DialogsToggleAction; 39 import org.openstreetmap.josm.actions.DistributeAction; 40 import org.openstreetmap.josm.actions.DownloadAction; 41 import org.openstreetmap.josm.actions.DownloadPrimitiveAction; 42 import org.openstreetmap.josm.actions.DownloadReferrersAction; 43 import org.openstreetmap.josm.actions.DuplicateAction; 44 import org.openstreetmap.josm.actions.ExitAction; 45 import org.openstreetmap.josm.actions.ExpertToggleAction; 46 import org.openstreetmap.josm.actions.FollowLineAction; 47 import org.openstreetmap.josm.actions.FullscreenToggleAction; 48 import org.openstreetmap.josm.actions.GpxExportAction; 49 import org.openstreetmap.josm.actions.HelpAction; 50 import org.openstreetmap.josm.actions.HistoryInfoAction; 51 import org.openstreetmap.josm.actions.HistoryInfoWebAction; 52 import org.openstreetmap.josm.actions.InfoAction; 53 import org.openstreetmap.josm.actions.InfoWebAction; 54 import org.openstreetmap.josm.actions.JoinAreasAction; 55 import org.openstreetmap.josm.actions.JoinNodeWayAction; 56 import org.openstreetmap.josm.actions.JosmAction; 57 import org.openstreetmap.josm.actions.JumpToAction; 58 import org.openstreetmap.josm.actions.MergeLayerAction; 59 import org.openstreetmap.josm.actions.MergeNodesAction; 60 import org.openstreetmap.josm.actions.MergeSelectionAction; 61 import org.openstreetmap.josm.actions.MirrorAction; 62 import org.openstreetmap.josm.actions.MoveAction; 63 import org.openstreetmap.josm.actions.MoveNodeAction; 64 import org.openstreetmap.josm.actions.NewAction; 65 import org.openstreetmap.josm.actions.OpenFileAction; 66 import org.openstreetmap.josm.actions.OpenLocationAction; 67 import org.openstreetmap.josm.actions.OrthogonalizeAction; 25 import org.openstreetmap.josm.actions.*; 68 26 import org.openstreetmap.josm.actions.OrthogonalizeAction.Undo; 69 import org.openstreetmap.josm.actions.PasteAction;70 import org.openstreetmap.josm.actions.PasteTagsAction;71 import org.openstreetmap.josm.actions.PreferenceToggleAction;72 import org.openstreetmap.josm.actions.PreferencesAction;73 import org.openstreetmap.josm.actions.PurgeAction;74 import org.openstreetmap.josm.actions.RedoAction;75 import org.openstreetmap.josm.actions.RestartAction;76 import org.openstreetmap.josm.actions.ReverseWayAction;77 import org.openstreetmap.josm.actions.SaveAction;78 import org.openstreetmap.josm.actions.SaveAsAction;79 import org.openstreetmap.josm.actions.SelectAllAction;80 import org.openstreetmap.josm.actions.SessionLoadAction;81 import org.openstreetmap.josm.actions.SessionSaveAsAction;82 import org.openstreetmap.josm.actions.ShowStatusReportAction;83 import org.openstreetmap.josm.actions.SimplifyWayAction;84 import org.openstreetmap.josm.actions.SplitWayAction;85 import org.openstreetmap.josm.actions.ToggleGPXLinesAction;86 import org.openstreetmap.josm.actions.UnGlueAction;87 import org.openstreetmap.josm.actions.UnJoinNodeWayAction;88 import org.openstreetmap.josm.actions.UndoAction;89 import org.openstreetmap.josm.actions.UnselectAllAction;90 import org.openstreetmap.josm.actions.UpdateDataAction;91 import org.openstreetmap.josm.actions.UpdateModifiedAction;92 import org.openstreetmap.josm.actions.UpdateSelectionAction;93 import org.openstreetmap.josm.actions.UploadAction;94 import org.openstreetmap.josm.actions.UploadSelectionAction;95 import org.openstreetmap.josm.actions.ViewportFollowToggleAction;96 import org.openstreetmap.josm.actions.WireframeToggleAction;97 import org.openstreetmap.josm.actions.ZoomInAction;98 import org.openstreetmap.josm.actions.ZoomOutAction;99 27 import org.openstreetmap.josm.actions.audio.AudioBackAction; 100 28 import org.openstreetmap.josm.actions.audio.AudioFasterAction; 101 29 import org.openstreetmap.josm.actions.audio.AudioFwdAction; … … public class MainMenu extends JMenuBar { 172 100 public final UndoAction undo = new UndoAction(); 173 101 /** Edit -> Redo */ 174 102 public final RedoAction redo = new RedoAction(); 103 /** Edit -> Repeat */ 104 public final RepeatAction repeat = new RepeatAction(); 175 105 /** Edit -> Copy */ 176 106 public final CopyAction copy = new CopyAction(); 177 107 /** Edit -> Copy Coordinates */ … … public class MainMenu extends JMenuBar { 621 551 Main.main.undoRedo.addCommandQueueListener(undo); 622 552 add(editMenu, redo); 623 553 Main.main.undoRedo.addCommandQueueListener(redo); 554 add(editMenu, repeat); 555 Main.main.undoRedo.addCommandQueueListener(repeat); 624 556 editMenu.addSeparator(); 625 557 add(editMenu, copy); 626 558 add(editMenu, copyCoordinates, true); -
src/org/openstreetmap/josm/tools/Utils.java
diff --git a/src/org/openstreetmap/josm/tools/Utils.java b/src/org/openstreetmap/josm/tools/Utils.java index 48149d6..92ff0cc 100644
a b public final class Utils { 100 100 return null; 101 101 } 102 102 103 public static <T> Predicate<T> not(final Predicate<T> predicate) { 104 return new Predicate<T>() { 105 @Override 106 public boolean evaluate(T object) { 107 return !predicate.evaluate(object); 108 } 109 }; 110 } 111 112 public static <T> boolean forAll(Iterable<? extends T> collection, Predicate<? super T> predicate) { 113 return !exists(collection, not(predicate)); 114 } 115 103 116 /** 104 117 * Filter a collection by (sub)class. 105 118 * This is an efficient read-only implementation.
