Prevent single-node ways from being created by undo.
[potlatch2.git] / net / systemeD / halcyon / connection / actions / AddNodeToWayAction.as
1 package net.systemeD.halcyon.connection.actions {
2
3     import net.systemeD.halcyon.connection.*;
4     
5     public class AddNodeToWayAction extends UndoableEntityAction {
6         private var node:Node;
7         private var nodeList:Array;
8         private var index:int;
9         private var firstNode:Node;
10         
11         public function AddNodeToWayAction(way:Way, node:Node, nodeList:Array, index:int) {
12             super(way, "Add node "+node.id+" to");
13             this.node = node;
14             this.nodeList = nodeList;
15             this.index = index;
16         }
17             
18         public override function doAction():uint {
19             var way:Way = entity as Way;
20
21                         // undelete way if it was deleted before (only happens on redo)
22                         if (way.deleted) {
23                                 way.setDeletedState(false);
24                                 if (!firstNode.hasParentWays) firstNode.connection.unregisterPOI(firstNode);
25                                 firstNode.addParent(way);
26                                 way.connection.dispatchEvent(new EntityEvent(Connection.NEW_WAY, way));
27                         }
28
29                         // add node
30             if ( index == -1 ) index = nodeList.length;
31             node.addParent(way);
32             nodeList.splice(index, 0, node);
33             markDirty();
34                         way.expandBbox(node);
35             way.dispatchEvent(new WayNodeEvent(Connection.WAY_NODE_ADDED, node, way, index));
36             
37             return SUCCESS;
38         }
39             
40         public override function undoAction():uint {
41             var way:Way = entity as Way;
42
43                         // ** FIXME: if the user undoes adding the 2nd node, then we delete the way and create a POI from the
44                         //           one remaining node (see below). _However_, when we delete the way, we also need to remove 
45                         //           it from any relations... and to do that, this needs to be a CompositeUndoableAction.
46                         //           Which it isn't (because we want all the markDirty/markClean stuff). So, for now, we'll
47                         //           simply refuse to undo adding the 2nd node if the way is in any relations. (This should
48                         //           be a vanishingly small case anyway, because usually the AddMemberToRelationAction will
49                         //           have been undone already.)
50                         if (way.length==2 && way.parentRelations.length) return FAIL;
51
52                         // remove node
53             var removed:Array=nodeList.splice(index, 1);
54                         if (nodeList.indexOf(removed[0])==-1) { removed[0].removeParent(way); }
55                         markClean();
56             way.dispatchEvent(new WayNodeEvent(Connection.WAY_NODE_REMOVED, removed[0], way, index));
57             
58                         // delete way if it's now 1-length, and convert the one remaining node to a POI
59                         if (way.length==1) {
60                                 way.setDeletedState(true);
61                                 way.dispatchEvent(new EntityEvent(Connection.WAY_DELETED, way));
62                                 firstNode=way.getNode(0);
63                                 firstNode.removeParent(way);
64                                 if (!firstNode.hasParentWays) firstNode.connection.registerPOI(firstNode);
65                                 MainUndoStack.getGlobalStack().removeLastIfAction(BeginWayAction);
66                         }
67                         return SUCCESS;
68         }
69     }
70 }