Changeset 1169 in josm for trunk/src/org/openstreetmap/josm/command
- Timestamp:
- 2008-12-23T15:07:05+01:00 (16 years ago)
- Location:
- trunk/src/org/openstreetmap/josm/command
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/command/AddCommand.java
r655 r1169 22 22 * A command that adds an osm primitive to a dataset. Keys cannot be added this 23 23 * way. 24 * 24 * 25 25 * See {@link ChangeCommand ChangeCommand} for comments on relation back references. 26 * 26 * 27 27 * @author imi 28 28 */ 29 29 public class AddCommand extends Command { 30 30 31 /** 32 * The primitive to add to the dataset. 33 */ 34 private final OsmPrimitive osm; 35 36 private DataSet ds; 31 /** 32 * The primitive to add to the dataset. 33 */ 34 private final OsmPrimitive osm; 37 35 38 /** 39 * Create the command and specify the element to add. 40 */ 41 public AddCommand(OsmPrimitive osm) { 42 this.osm = osm; 43 this.ds = Main.main.editLayer().data; 44 } 36 private DataSet ds; 45 37 46 @Override public boolean executeCommand() { 47 osm.visit(new AddVisitor(ds)); 48 return true; 49 } 50 51 @Override public void undoCommand() { 52 osm.visit(new DeleteVisitor(ds)); 53 } 54 55 @Override public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) { 56 added.add(osm); 57 } 58 59 // faster implementation 60 @Override public boolean invalidBecauselayerRemoved(Layer oldLayer) { 61 return oldLayer instanceof OsmDataLayer && ((OsmDataLayer)oldLayer).data == ds; 38 /** 39 * Create the command and specify the element to add. 40 */ 41 public AddCommand(OsmPrimitive osm) { 42 this.osm = osm; 43 this.ds = Main.main.editLayer().data; 62 44 } 63 45 64 @Override public MutableTreeNode description() { 65 NameVisitor v = new NameVisitor(); 66 osm.visit(v); 67 return new DefaultMutableTreeNode(new JLabel(tr("Add")+" "+tr(v.className)+" "+v.name, v.icon, JLabel.HORIZONTAL)); 46 @Override public boolean executeCommand() { 47 osm.visit(new AddVisitor(ds)); 48 return true; 49 } 50 51 @Override public void undoCommand() { 52 osm.visit(new DeleteVisitor(ds)); 53 } 54 55 @Override public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) { 56 added.add(osm); 57 } 58 59 // faster implementation 60 @Override public boolean invalidBecauselayerRemoved(Layer oldLayer) { 61 return oldLayer instanceof OsmDataLayer && ((OsmDataLayer)oldLayer).data == ds; 62 } 63 64 @Override public MutableTreeNode description() { 65 NameVisitor v = new NameVisitor(); 66 osm.visit(v); 67 return new DefaultMutableTreeNode(new JLabel(tr("Add")+" "+tr(v.className)+" "+v.name, v.icon, JLabel.HORIZONTAL)); 68 68 } 69 69 } -
trunk/src/org/openstreetmap/josm/command/ChangeCommand.java
r630 r1169 14 14 15 15 /** 16 * Command that basically replaces one OSM primitive by another of the 16 * Command that basically replaces one OSM primitive by another of the 17 17 * same type. 18 * 18 * 19 19 * @author Imi 20 20 */ 21 21 public class ChangeCommand extends Command { 22 22 23 24 23 private final OsmPrimitive osm; 24 private final OsmPrimitive newOsm; 25 25 26 27 28 26 public ChangeCommand(OsmPrimitive osm, OsmPrimitive newOsm) { 27 this.osm = osm; 28 this.newOsm = newOsm; 29 29 } 30 30 31 32 33 34 35 31 @Override public boolean executeCommand() { 32 super.executeCommand(); 33 osm.cloneFrom(newOsm); 34 osm.modified = true; 35 return true; 36 36 } 37 37 38 39 38 @Override public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) { 39 modified.add(osm); 40 40 } 41 41 42 43 44 45 42 @Override public MutableTreeNode description() { 43 NameVisitor v = new NameVisitor(); 44 osm.visit(v); 45 return new DefaultMutableTreeNode(new JLabel(tr("Change")+" "+tr(v.className)+" "+v.name, v.icon, JLabel.HORIZONTAL)); 46 46 } 47 47 } -
trunk/src/org/openstreetmap/josm/command/ChangePropertyCommand.java
r1101 r1169 20 20 * Command that manipulate the key/value structure of several objects. Manages deletion, 21 21 * adding and modify of values and keys. 22 * 22 * 23 23 * @author imi 24 24 */ 25 25 public class ChangePropertyCommand extends Command { 26 /** 27 * All primitives that are affected with this command. 28 */ 29 private final List<OsmPrimitive> objects; 30 /** 31 * The key that is subject to change. 32 */ 33 private final String key; 34 /** 35 * The key value. If it is <code>null</code>, delete all key references with the given 36 * key. Otherwise, change the properties of all objects to the given value or create keys of 37 * those objects that do not have the key yet. 38 */ 39 private final String value; 40 41 public ChangePropertyCommand(Collection<? extends OsmPrimitive> objects, String key, String value) { 42 this.objects = new LinkedList<OsmPrimitive>(); 43 this.key = key; 44 this.value = value; 45 if (value == null) { 46 for (OsmPrimitive osm : objects) { 47 if(osm.get(key) != null) 48 this.objects.add(osm); 49 } 50 } else { 51 for (OsmPrimitive osm : objects) { 52 String val = osm.get(key); 53 if (val == null || !value.equals(val)) { 54 this.objects.add(osm); 55 } 56 } 57 } 58 } 26 /** 27 * All primitives that are affected with this command. 28 */ 29 private final List<OsmPrimitive> objects; 30 /** 31 * The key that is subject to change. 32 */ 33 private final String key; 34 /** 35 * The key value. If it is <code>null</code>, delete all key references with the given 36 * key. Otherwise, change the properties of all objects to the given value or create keys of 37 * those objects that do not have the key yet. 38 */ 39 private final String value; 59 40 60 public ChangePropertyCommand(OsmPrimitive object, String key, String value) { 61 this.objects = new LinkedList<OsmPrimitive>(); 62 this.key = key; 63 this.value = value; 64 String val = object.get(key); 65 if ((value == null && val != null) 66 || (value != null && (val == null || !value.equals(val)))) 67 this.objects.add(object); 68 } 69 70 @Override public boolean executeCommand() { 71 super.executeCommand(); // save old 72 if (value == null) { 73 for (OsmPrimitive osm : objects) { 74 osm.modified = true; 75 osm.remove(key); 76 } 77 } else { 78 for (OsmPrimitive osm : objects) { 79 osm.modified = true; 80 osm.put(key, value); 81 } 82 } 83 return true; 84 } 41 public ChangePropertyCommand(Collection<? extends OsmPrimitive> objects, String key, String value) { 42 this.objects = new LinkedList<OsmPrimitive>(); 43 this.key = key; 44 this.value = value; 45 if (value == null) { 46 for (OsmPrimitive osm : objects) { 47 if(osm.get(key) != null) 48 this.objects.add(osm); 49 } 50 } else { 51 for (OsmPrimitive osm : objects) { 52 String val = osm.get(key); 53 if (val == null || !value.equals(val)) { 54 this.objects.add(osm); 55 } 56 } 57 } 58 } 85 59 86 @Override public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) { 87 modified.addAll(objects); 88 } 60 public ChangePropertyCommand(OsmPrimitive object, String key, String value) { 61 this.objects = new LinkedList<OsmPrimitive>(); 62 this.key = key; 63 this.value = value; 64 String val = object.get(key); 65 if ((value == null && val != null) 66 || (value != null && (val == null || !value.equals(val)))) 67 this.objects.add(object); 68 } 89 69 90 @Override public MutableTreeNode description() { 91 String text = value == null ? tr( "Remove \"{0}\" for", key) : tr("Set {0}={1} for",key,value); 92 if (objects.size() == 1) { 93 NameVisitor v = new NameVisitor(); 94 objects.iterator().next().visit(v); 95 text += " "+tr(v.className)+" "+v.name; 96 } else 97 text += " "+objects.size()+" "+trn("object","objects",objects.size()); 98 DefaultMutableTreeNode root = new DefaultMutableTreeNode(new JLabel(text, ImageProvider.get("data", "key"), JLabel.HORIZONTAL)); 99 if (objects.size() == 1) 100 return root; 101 NameVisitor v = new NameVisitor(); 102 for (OsmPrimitive osm : objects) { 103 osm.visit(v); 104 root.add(new DefaultMutableTreeNode(v.toLabel())); 105 } 106 return root; 70 @Override public boolean executeCommand() { 71 super.executeCommand(); // save old 72 if (value == null) { 73 for (OsmPrimitive osm : objects) { 74 osm.modified = true; 75 osm.remove(key); 76 } 77 } else { 78 for (OsmPrimitive osm : objects) { 79 osm.modified = true; 80 osm.put(key, value); 81 } 82 } 83 return true; 84 } 85 86 @Override public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) { 87 modified.addAll(objects); 88 } 89 90 @Override public MutableTreeNode description() { 91 String text = value == null ? tr( "Remove \"{0}\" for", key) : tr("Set {0}={1} for",key,value); 92 if (objects.size() == 1) { 93 NameVisitor v = new NameVisitor(); 94 objects.iterator().next().visit(v); 95 text += " "+tr(v.className)+" "+v.name; 96 } else 97 text += " "+objects.size()+" "+trn("object","objects",objects.size()); 98 DefaultMutableTreeNode root = new DefaultMutableTreeNode(new JLabel(text, ImageProvider.get("data", "key"), JLabel.HORIZONTAL)); 99 if (objects.size() == 1) 100 return root; 101 NameVisitor v = new NameVisitor(); 102 for (OsmPrimitive osm : objects) { 103 osm.visit(v); 104 root.add(new DefaultMutableTreeNode(v.toLabel())); 105 } 106 return root; 107 107 } 108 108 } -
trunk/src/org/openstreetmap/josm/command/Command.java
r655 r1169 25 25 * one atomic action on a specific dataset, such as move or delete. 26 26 * 27 * Remember that the command must be executable and undoable, even if the 27 * Remember that the command must be executable and undoable, even if the 28 28 * Main.ds has changed, so the command must save the dataset it operates on 29 29 * if necessary. … … 47 47 } 48 48 49 private CloneVisitor orig; 49 private CloneVisitor orig; 50 50 51 51 protected DataSet ds; … … 70 70 71 71 /** 72 * Undoes the command. 72 * Undoes the command. 73 73 * It can be assumed that all objects are in the same state they were before. 74 74 * It can also be assumed that executeCommand was called exactly once before. 75 * 75 * 76 76 * This implementation undoes all objects stored by a former call to executeCommand. 77 77 */ … … 122 122 * Fill in the changed data this command operates on. 123 123 * Add to the lists, don't clear them. 124 * 124 * 125 125 * @param modified The modified primitives 126 126 * @param deleted The deleted primitives -
trunk/src/org/openstreetmap/josm/command/ConflictResolveCommand.java
r630 r1169 25 25 public class ConflictResolveCommand extends Command { 26 26 27 28 29 30 27 private final Collection<ConflictItem> conflicts; 28 private final Map<OsmPrimitive, OsmPrimitive> resolved; 29 private Map<OsmPrimitive, OsmPrimitive> origAllConflicts; 30 private final ConflictDialog conflictDialog; 31 31 32 33 34 35 36 32 public ConflictResolveCommand(List<ConflictItem> conflicts, Map<OsmPrimitive, OsmPrimitive> resolved) { 33 this.conflicts = conflicts; 34 this.resolved = resolved; 35 conflictDialog = Main.map.conflictDialog; 36 } 37 37 38 39 38 @Override public boolean executeCommand() { 39 super.executeCommand(); 40 40 41 origAllConflicts = new HashMap<OsmPrimitive, OsmPrimitive>(conflictDialog.conflicts); 42 43 Set<OsmPrimitive> completed = new HashSet<OsmPrimitive>(resolved.keySet()); 44 for (ConflictItem ci : conflicts) { 45 for (Entry<OsmPrimitive, OsmPrimitive> e : resolved.entrySet()) { 46 if (ci.resolution == ConflictResolver.Resolution.THEIR) 47 ci.apply(e.getKey(), e.getValue()); 48 else if (ci.resolution == ConflictResolver.Resolution.MY) 49 ci.apply(e.getValue(), e.getKey()); 50 else if (ci.hasConflict(e.getKey(), e.getValue())) 51 completed.remove(e.getKey()); 52 } 53 } 54 if (!completed.isEmpty()) { 55 for (OsmPrimitive k : completed) 56 conflictDialog.conflicts.remove(k); 57 conflictDialog.rebuildList(); 58 } 59 return true; 60 } 41 origAllConflicts = new HashMap<OsmPrimitive, OsmPrimitive>(conflictDialog.conflicts); 61 42 62 @Override public void undoCommand() { 63 super.undoCommand(); 64 Main.map.conflictDialog.conflicts.clear(); 65 Main.map.conflictDialog.conflicts.putAll(origAllConflicts); 66 Main.map.conflictDialog.rebuildList(); 67 } 43 Set<OsmPrimitive> completed = new HashSet<OsmPrimitive>(resolved.keySet()); 44 for (ConflictItem ci : conflicts) { 45 for (Entry<OsmPrimitive, OsmPrimitive> e : resolved.entrySet()) { 46 if (ci.resolution == ConflictResolver.Resolution.THEIR) 47 ci.apply(e.getKey(), e.getValue()); 48 else if (ci.resolution == ConflictResolver.Resolution.MY) 49 ci.apply(e.getValue(), e.getKey()); 50 else if (ci.hasConflict(e.getKey(), e.getValue())) 51 completed.remove(e.getKey()); 52 } 53 } 54 if (!completed.isEmpty()) { 55 for (OsmPrimitive k : completed) 56 conflictDialog.conflicts.remove(k); 57 conflictDialog.rebuildList(); 58 } 59 return true; 60 } 68 61 69 @Override public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) { 70 modified.addAll(resolved.keySet()); 71 } 62 @Override public void undoCommand() { 63 super.undoCommand(); 64 Main.map.conflictDialog.conflicts.clear(); 65 Main.map.conflictDialog.conflicts.putAll(origAllConflicts); 66 Main.map.conflictDialog.rebuildList(); 67 } 72 68 73 @Override public MutableTreeNode description() { 74 int i = 0; 75 for (ConflictItem c : conflicts) 76 if (c.resolution != null) 77 i++; 78 return new DefaultMutableTreeNode(new JLabel(tr("Resolve {0} conflicts in {1} objects",i,resolved.size()), ImageProvider.get("data", "object"), JLabel.HORIZONTAL)); 69 @Override public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) { 70 modified.addAll(resolved.keySet()); 71 } 72 73 @Override public MutableTreeNode description() { 74 int i = 0; 75 for (ConflictItem c : conflicts) 76 if (c.resolution != null) 77 i++; 78 return new DefaultMutableTreeNode(new JLabel(tr("Resolve {0} conflicts in {1} objects",i,resolved.size()), ImageProvider.get("data", "object"), JLabel.HORIZONTAL)); 79 79 } 80 80 } -
trunk/src/org/openstreetmap/josm/command/DeleteCommand.java
r1047 r1169 105 105 /** 106 106 * Delete the primitives and everything they reference. 107 * 107 * 108 108 * If a node is deleted, the node and all ways and relations the node is part of are deleted as 109 109 * well. 110 * 110 * 111 111 * If a way is deleted, all relations the way is member of are also deleted. 112 * 112 * 113 113 * If a way is deleted, only the way and no nodes are deleted. 114 * 114 * 115 115 * @param selection The list of all object to be deleted. 116 116 * @return command A command to perform the deletions, or null of there is nothing to delete. … … 130 130 /** 131 131 * Try to delete all given primitives. 132 * 132 * 133 133 * If a node is used by a way, it's removed from that way. If a node or a way is used by a 134 134 * relation, inform the user and do not delete. 135 * 135 * 136 136 * If this would cause ways with less than 2 nodes to be created, delete these ways instead. If 137 137 * they are part of a relation, inform the user and do not delete. 138 * 138 * 139 139 * @param selection The objects to delete. 140 140 * @param alsoDeleteNodesInWay <code>true</code> if nodes should be deleted as well … … 341 341 // leave message in one tr() as there is a grammatical connection. 342 342 tr("You are about to delete nodes outside of the area you have downloaded." + 343 "<br>" + 343 "<br>" + 344 344 "This can cause problems because other objects (that you don't see) might use them." + 345 "<br>" + 345 "<br>" + 346 346 "Do you really want to delete?") + "</html>")); 347 347 return DontShowAgainInfo.show("delete_outside_nodes", msg, false, JOptionPane.YES_NO_OPTION, JOptionPane.YES_OPTION); -
trunk/src/org/openstreetmap/josm/command/MoveCommand.java
r655 r1169 26 26 * MoveCommand moves a set of OsmPrimitives along the map. It can be moved again 27 27 * to collect several MoveCommands into one command. 28 * 28 * 29 29 * @author imi 30 30 */ 31 31 public class MoveCommand extends Command { 32 33 34 35 36 37 38 39 40 41 42 43 32 /** 33 * The objects that should be moved. 34 */ 35 public Collection<Node> objects = new LinkedList<Node>(); 36 /** 37 * x difference movement. Coordinates are in northern/eastern 38 */ 39 private double x; 40 /** 41 * y difference movement. Coordinates are in northern/eastern 42 */ 43 private double y; 44 44 45 /** 46 * Small helper for holding the interesting part of the old data state of the 47 * objects. 48 */ 49 public static class OldState { 50 LatLon latlon; 51 EastNorth eastNorth; 52 boolean modified; 53 } 54 55 /** 56 * List of all old states of the objects. 57 */ 58 private List<OldState> oldState = new LinkedList<OldState>(); 45 /** 46 * Small helper for holding the interesting part of the old data state of the 47 * objects. 48 */ 49 public static class OldState { 50 LatLon latlon; 51 EastNorth eastNorth; 52 boolean modified; 53 } 59 54 60 61 public MoveCommand(OsmPrimitive osm, double x, double y) { 62 this(Collections.singleton(osm), x, y); 63 } 64 /** 65 * Create a MoveCommand and assign the initial object set and movement vector. 66 */ 67 public MoveCommand(Collection<OsmPrimitive> objects, double x, double y) { 68 this.x = x; 69 this.y = y; 70 this.objects = AllNodesVisitor.getAllNodes(objects); 71 for (Node n : this.objects) { 72 OldState os = new OldState(); 73 os.eastNorth = n.eastNorth; 74 os.latlon = n.coor; 75 os.modified = n.modified; 76 oldState.add(os); 77 } 78 } 55 /** 56 * List of all old states of the objects. 57 */ 58 private List<OldState> oldState = new LinkedList<OldState>(); 79 59 80 /**81 * Move the same set of objects again by the specified vector. The vectors82 * are added together and so the resulting will be moved to the previous83 * vector plus this one.84 *85 * The move is immediately executed and any undo will undo both vectors to86 * the original position the objects had before first moving.87 */88 public void moveAgain(double x, double y) {89 for (Node n : objects) {90 n.eastNorth = new EastNorth(n.eastNorth.east()+x, n.eastNorth.north()+y);91 n.coor = Main.proj.eastNorth2latlon(n.eastNorth);92 }93 this.x += x;94 this.y += y;95 }96 97 @Override public boolean executeCommand() {98 for (Node n : objects) {99 n.eastNorth = new EastNorth(n.eastNorth.east()+x, n.eastNorth.north()+y);100 n.coor = Main.proj.eastNorth2latlon(n.eastNorth);101 n.modified = true;102 }103 return true;104 }105 60 106 @Override public void undoCommand() { 107 Iterator<OldState> it = oldState.iterator(); 108 for (Node n : objects) { 109 OldState os = it.next(); 110 n.eastNorth = os.eastNorth; 111 n.coor = os.latlon; 112 n.modified = os.modified; 113 } 114 } 61 public MoveCommand(OsmPrimitive osm, double x, double y) { 62 this(Collections.singleton(osm), x, y); 63 } 64 /** 65 * Create a MoveCommand and assign the initial object set and movement vector. 66 */ 67 public MoveCommand(Collection<OsmPrimitive> objects, double x, double y) { 68 this.x = x; 69 this.y = y; 70 this.objects = AllNodesVisitor.getAllNodes(objects); 71 for (Node n : this.objects) { 72 OldState os = new OldState(); 73 os.eastNorth = n.eastNorth; 74 os.latlon = n.coor; 75 os.modified = n.modified; 76 oldState.add(os); 77 } 78 } 115 79 116 @Override public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) { 117 for (OsmPrimitive osm : objects) 118 modified.add(osm); 119 } 80 /** 81 * Move the same set of objects again by the specified vector. The vectors 82 * are added together and so the resulting will be moved to the previous 83 * vector plus this one. 84 * 85 * The move is immediately executed and any undo will undo both vectors to 86 * the original position the objects had before first moving. 87 */ 88 public void moveAgain(double x, double y) { 89 for (Node n : objects) { 90 n.eastNorth = new EastNorth(n.eastNorth.east()+x, n.eastNorth.north()+y); 91 n.coor = Main.proj.eastNorth2latlon(n.eastNorth); 92 } 93 this.x += x; 94 this.y += y; 95 } 120 96 121 @Override public MutableTreeNode description() { 122 return new DefaultMutableTreeNode(new JLabel(tr("Move")+" "+objects.size()+" "+trn("node","nodes",objects.size()), ImageProvider.get("data", "node"), JLabel.HORIZONTAL)); 97 @Override public boolean executeCommand() { 98 for (Node n : objects) { 99 n.eastNorth = new EastNorth(n.eastNorth.east()+x, n.eastNorth.north()+y); 100 n.coor = Main.proj.eastNorth2latlon(n.eastNorth); 101 n.modified = true; 102 } 103 return true; 104 } 105 106 @Override public void undoCommand() { 107 Iterator<OldState> it = oldState.iterator(); 108 for (Node n : objects) { 109 OldState os = it.next(); 110 n.eastNorth = os.eastNorth; 111 n.coor = os.latlon; 112 n.modified = os.modified; 113 } 114 } 115 116 @Override public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) { 117 for (OsmPrimitive osm : objects) 118 modified.add(osm); 119 } 120 121 @Override public MutableTreeNode description() { 122 return new DefaultMutableTreeNode(new JLabel(tr("Move")+" "+objects.size()+" "+trn("node","nodes",objects.size()), ImageProvider.get("data", "node"), JLabel.HORIZONTAL)); 123 123 } 124 124 } -
trunk/src/org/openstreetmap/josm/command/RotateCommand.java
r748 r1169 23 23 /** 24 24 * RotateCommand rotates a number of objects around their centre. 25 * 25 * 26 26 * @author Frederik Ramm <frederik@remote.org> 27 27 */ 28 28 public class RotateCommand extends Command { 29 30 /**31 * The objects to rotate.32 */33 public Collection<Node> objects = new LinkedList<Node>();34 35 /**36 * pivot point37 */38 private Node pivot;39 40 /**41 * angle of rotation starting click to pivot42 */43 private double startAngle;44 45 /**46 * computed rotation angle between starting click and current mouse pos47 */48 private double rotationAngle;49 50 /**51 * List of all old states of the objects.52 */53 private Map<Node, MoveCommand.OldState> oldState = new HashMap<Node, MoveCommand.OldState>();54 55 /**56 * Creates a RotateCommand.57 * Assign the initial object set, compute pivot point and rotation angle.58 * Computation of pivot point is done by the same rules that are used in59 * the "align nodes in circle" action.60 */61 public RotateCommand(Collection<OsmPrimitive> objects, EastNorth start, EastNorth end) {62 29 63 this.objects = AllNodesVisitor.getAllNodes(objects); 64 pivot = new Node(new LatLon(0,0)); 65 pivot.eastNorth = new EastNorth(0,0); 30 /** 31 * The objects to rotate. 32 */ 33 public Collection<Node> objects = new LinkedList<Node>(); 66 34 67 for (Node n : this.objects) { 68 MoveCommand.OldState os = new MoveCommand.OldState(); 69 os.eastNorth = n.eastNorth; 70 os.latlon = n.coor; 71 os.modified = n.modified; 72 oldState.put(n, os); 73 pivot.eastNorth = new EastNorth(pivot.eastNorth.east()+os.eastNorth.east(), pivot.eastNorth.north()+os.eastNorth.north()); 74 } 75 pivot.eastNorth = new EastNorth(pivot.eastNorth.east()/this.objects.size(), pivot.eastNorth.north()/this.objects.size()); 76 pivot.coor = Main.proj.eastNorth2latlon(pivot.eastNorth); 35 /** 36 * pivot point 37 */ 38 private Node pivot; 77 39 78 rotationAngle = Math.PI/2; 79 rotateAgain(start, end); 80 } 40 /** 41 * angle of rotation starting click to pivot 42 */ 43 private double startAngle; 81 44 82 /** 83 * Rotate the same set of objects again, by the angle between given 84 * start and end nodes. Internally this is added to the existing 85 * rotation so a later undo will undo the whole rotation. 86 */ 87 public void rotateAgain(EastNorth start, EastNorth end) { 88 // compute angle 89 startAngle = Math.atan2(start.east()-pivot.eastNorth.east(), start.north()-pivot.eastNorth.north()); 90 double endAngle = Math.atan2(end.east()-pivot.eastNorth.east(), end.north()-pivot.eastNorth.north()); 91 rotationAngle += startAngle - endAngle; 92 rotateNodes(false); 93 } 45 /** 46 * computed rotation angle between starting click and current mouse pos 47 */ 48 private double rotationAngle; 94 49 95 /** 96 * Helper for actually rotationg the nodes. 97 * @param setModified - true if rotated nodes should be flagged "modified" 98 */ 99 private void rotateNodes(boolean setModified) { 100 for (Node n : objects) { 101 double cosPhi = Math.cos(rotationAngle); 102 double sinPhi = Math.sin(rotationAngle); 103 EastNorth oldEastNorth = oldState.get(n).eastNorth; 104 double x = oldEastNorth.east() - pivot.eastNorth.east(); 105 double y = oldEastNorth.north() - pivot.eastNorth.north(); 106 double nx = sinPhi * x + cosPhi * y + pivot.eastNorth.east(); 107 double ny = -cosPhi * x + sinPhi * y + pivot.eastNorth.north(); 108 n.eastNorth = new EastNorth(nx, ny); 109 n.coor = Main.proj.eastNorth2latlon(n.eastNorth); 110 if (setModified) 111 n.modified = true; 112 } 113 } 114 115 @Override public boolean executeCommand() { 116 rotateNodes(true); 117 return true; 118 } 50 /** 51 * List of all old states of the objects. 52 */ 53 private Map<Node, MoveCommand.OldState> oldState = new HashMap<Node, MoveCommand.OldState>(); 119 54 120 @Override public void undoCommand() { 121 for (Node n : objects) { 122 MoveCommand.OldState os = oldState.get(n); 123 n.eastNorth = os.eastNorth; 124 n.coor = os.latlon; 125 n.modified = os.modified; 126 } 127 } 55 /** 56 * Creates a RotateCommand. 57 * Assign the initial object set, compute pivot point and rotation angle. 58 * Computation of pivot point is done by the same rules that are used in 59 * the "align nodes in circle" action. 60 */ 61 public RotateCommand(Collection<OsmPrimitive> objects, EastNorth start, EastNorth end) { 128 62 129 @Override public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) { 130 for (OsmPrimitive osm : objects) 131 modified.add(osm); 132 } 63 this.objects = AllNodesVisitor.getAllNodes(objects); 64 pivot = new Node(new LatLon(0,0)); 65 pivot.eastNorth = new EastNorth(0,0); 133 66 134 @Override public MutableTreeNode description() { 135 return new DefaultMutableTreeNode(new JLabel(tr("Rotate")+" "+objects.size()+" "+trn("node","nodes",objects.size()), ImageProvider.get("data", "node"), JLabel.HORIZONTAL)); 67 for (Node n : this.objects) { 68 MoveCommand.OldState os = new MoveCommand.OldState(); 69 os.eastNorth = n.eastNorth; 70 os.latlon = n.coor; 71 os.modified = n.modified; 72 oldState.put(n, os); 73 pivot.eastNorth = new EastNorth(pivot.eastNorth.east()+os.eastNorth.east(), pivot.eastNorth.north()+os.eastNorth.north()); 74 } 75 pivot.eastNorth = new EastNorth(pivot.eastNorth.east()/this.objects.size(), pivot.eastNorth.north()/this.objects.size()); 76 pivot.coor = Main.proj.eastNorth2latlon(pivot.eastNorth); 77 78 rotationAngle = Math.PI/2; 79 rotateAgain(start, end); 80 } 81 82 /** 83 * Rotate the same set of objects again, by the angle between given 84 * start and end nodes. Internally this is added to the existing 85 * rotation so a later undo will undo the whole rotation. 86 */ 87 public void rotateAgain(EastNorth start, EastNorth end) { 88 // compute angle 89 startAngle = Math.atan2(start.east()-pivot.eastNorth.east(), start.north()-pivot.eastNorth.north()); 90 double endAngle = Math.atan2(end.east()-pivot.eastNorth.east(), end.north()-pivot.eastNorth.north()); 91 rotationAngle += startAngle - endAngle; 92 rotateNodes(false); 93 } 94 95 /** 96 * Helper for actually rotationg the nodes. 97 * @param setModified - true if rotated nodes should be flagged "modified" 98 */ 99 private void rotateNodes(boolean setModified) { 100 for (Node n : objects) { 101 double cosPhi = Math.cos(rotationAngle); 102 double sinPhi = Math.sin(rotationAngle); 103 EastNorth oldEastNorth = oldState.get(n).eastNorth; 104 double x = oldEastNorth.east() - pivot.eastNorth.east(); 105 double y = oldEastNorth.north() - pivot.eastNorth.north(); 106 double nx = sinPhi * x + cosPhi * y + pivot.eastNorth.east(); 107 double ny = -cosPhi * x + sinPhi * y + pivot.eastNorth.north(); 108 n.eastNorth = new EastNorth(nx, ny); 109 n.coor = Main.proj.eastNorth2latlon(n.eastNorth); 110 if (setModified) 111 n.modified = true; 112 } 113 } 114 115 @Override public boolean executeCommand() { 116 rotateNodes(true); 117 return true; 118 } 119 120 @Override public void undoCommand() { 121 for (Node n : objects) { 122 MoveCommand.OldState os = oldState.get(n); 123 n.eastNorth = os.eastNorth; 124 n.coor = os.latlon; 125 n.modified = os.modified; 126 } 127 } 128 129 @Override public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) { 130 for (OsmPrimitive osm : objects) 131 modified.add(osm); 132 } 133 134 @Override public MutableTreeNode description() { 135 return new DefaultMutableTreeNode(new JLabel(tr("Rotate")+" "+objects.size()+" "+trn("node","nodes",objects.size()), ImageProvider.get("data", "node"), JLabel.HORIZONTAL)); 136 136 } 137 137 } -
trunk/src/org/openstreetmap/josm/command/SequenceCommand.java
r853 r1169 20 20 public class SequenceCommand extends Command { 21 21 22 23 24 25 26 27 28 22 /** 23 * The command sequenz to be executed. 24 */ 25 private Command[] sequence; 26 private boolean sequence_complete; 27 private final String name; 28 public boolean continueOnError = false; 29 29 30 31 32 33 34 35 36 37 38 30 /** 31 * Create the command by specifying the list of commands to execute. 32 * @param sequenz The sequence that should be executed. 33 */ 34 public SequenceCommand(String name, Collection<Command> sequenz) { 35 this.name = name; 36 this.sequence = new Command[sequenz.size()]; 37 this.sequence = sequenz.toArray(this.sequence); 38 } 39 39 40 /** 41 * Convenient constructor, if the commands are known at compile time. 42 */ 43 public SequenceCommand(String name, Command... sequenz) { 44 this(name, Arrays.asList(sequenz)); 45 } 46 47 public int executed_commands = 0; 48 @Override public boolean executeCommand() { 49 for (int i=0; i < sequence.length; i++) { 50 Command c = sequence[i]; 51 boolean result = c.executeCommand(); 52 if (!result) 53 Main.debug("SequenceCommand, executing command[" + i + "] " + c + " result: " + result); 54 if (!result && !continueOnError) { 55 this.undoCommands(i-1); 56 return false; 57 } 58 } 59 sequence_complete = true; 60 return true; 61 } 40 /** 41 * Convenient constructor, if the commands are known at compile time. 42 */ 43 public SequenceCommand(String name, Command... sequenz) { 44 this(name, Arrays.asList(sequenz)); 45 } 62 46 63 public Command getLastCommand() { 64 if(sequence.length == 0) 65 return null; 66 return sequence[sequence.length-1]; 67 } 68 private void undoCommands(int start) { 69 // We probably aborted this halfway though the 70 // execution sequence because of a sub-command 71 // error. We already undid the sub-commands. 72 if (!sequence_complete) 73 return; 74 for (int i = start; i >= 0; --i) 75 sequence[i].undoCommand(); 76 } 47 public int executed_commands = 0; 48 @Override public boolean executeCommand() { 49 for (int i=0; i < sequence.length; i++) { 50 Command c = sequence[i]; 51 boolean result = c.executeCommand(); 52 if (!result) 53 Main.debug("SequenceCommand, executing command[" + i + "] " + c + " result: " + result); 54 if (!result && !continueOnError) { 55 this.undoCommands(i-1); 56 return false; 57 } 58 } 59 sequence_complete = true; 60 return true; 61 } 77 62 78 @Override public void undoCommand() { 79 this.undoCommands(sequence.length-1); 80 } 63 public Command getLastCommand() { 64 if(sequence.length == 0) 65 return null; 66 return sequence[sequence.length-1]; 67 } 68 private void undoCommands(int start) { 69 // We probably aborted this halfway though the 70 // execution sequence because of a sub-command 71 // error. We already undid the sub-commands. 72 if (!sequence_complete) 73 return; 74 for (int i = start; i >= 0; --i) 75 sequence[i].undoCommand(); 76 } 81 77 82 @Override public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) { 83 for (Command c : sequence) 84 c.fillModifiedData(modified, deleted, added); 85 } 78 @Override public void undoCommand() { 79 this.undoCommands(sequence.length-1); 80 } 86 81 87 @Override public MutableTreeNode description() { 88 DefaultMutableTreeNode root = new DefaultMutableTreeNode(tr("Sequence")+": "+name); 89 for (Command c : sequence) 90 root.add(c.description()); 91 return root; 82 @Override public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) { 83 for (Command c : sequence) 84 c.fillModifiedData(modified, deleted, added); 85 } 86 87 @Override public MutableTreeNode description() { 88 DefaultMutableTreeNode root = new DefaultMutableTreeNode(tr("Sequence")+": "+name); 89 for (Command c : sequence) 90 root.add(c.description()); 91 return root; 92 92 } 93 93 }
Note:
See TracChangeset
for help on using the changeset viewer.