Resurrecting earlier work on replace branch
authorRichard Fairhurst <richard@systemeD.net>
Sun, 30 Oct 2011 20:57:20 +0000 (20:57 +0000)
committerRichard Fairhurst <richard@systemeD.net>
Sun, 30 Oct 2011 20:57:20 +0000 (20:57 +0000)
net/systemeD/halcyon/connection/Way.as
net/systemeD/halcyon/connection/actions/AddNodeToWayAction.as
net/systemeD/potlatch2/controller/ControllerState.as
net/systemeD/potlatch2/controller/DrawWay.as
net/systemeD/potlatch2/controller/SelectedWayNode.as

index 0897732..fcbd181 100644 (file)
@@ -90,7 +90,7 @@ package net.systemeD.halcyon.connection {
         public function insertNode(index:uint, node:Node, performAction:Function):void {
                        if (index>0 && getNode(index-1)==node) return;
                        if (index<nodes.length-1 && getNode(index)==node) return;
-                       performAction(new AddNodeToWayAction(this, node, nodes, index));
+                       performAction(new AddNodeToWayAction(this, node, nodes, index, false));
         }
 
         public function appendNode(node:Node, performAction:Function):uint {
index 185bf55..266af85 100644 (file)
@@ -7,12 +7,14 @@ package net.systemeD.halcyon.connection.actions {
         private var nodeList:Array;
         private var index:int;
         private var firstNode:Node;
+        private var autoDelete:Boolean;                /* automatically delete way when undoing addition of node 2? */
         
-        public function AddNodeToWayAction(way:Way, node:Node, nodeList:Array, index:int) {
+        public function AddNodeToWayAction(way:Way, node:Node, nodeList:Array, index:int, autoDelete:Boolean=true) {
             super(way, "Add node "+node.id+" to");
             this.node = node;
             this.nodeList = nodeList;
             this.index = index;
+            this.autoDelete = autoDelete;
         }
             
         public override function doAction():uint {
@@ -47,7 +49,7 @@ package net.systemeD.halcyon.connection.actions {
                        //           simply refuse to undo adding the 2nd node if the way is in any relations. (This should
                        //           be a vanishingly small case anyway, because usually the AddMemberToRelationAction will
                        //           have been undone already.)
-                       if (way.length==2 && way.parentRelations.length) return FAIL;
+                       if (autoDelete && way.length==2 && way.parentRelations.length) return FAIL;
 
                        // remove node
             var removed:Array=nodeList.splice(index, 1);
@@ -56,7 +58,7 @@ package net.systemeD.halcyon.connection.actions {
             way.dispatchEvent(new WayNodeEvent(Connection.WAY_NODE_REMOVED, removed[0], way, index));
             
                        // delete way if it's now 1-length, and convert the one remaining node to a POI
-                       if (way.length==1) {
+                       if (autoDelete && way.length==1) {
                                way.setDeletedState(true);
                                way.dispatchEvent(new EntityEvent(Connection.WAY_DELETED, way));
                                firstNode=way.getNode(0);
index a905d23..7acac44 100644 (file)
@@ -213,13 +213,16 @@ package net.systemeD.potlatch2.controller {
 
                /** Revert all selected items to previously saved state, via a dialog box. */
                protected function revertSelection():void {
-                       if (selectCount==0) return;
-                       Alert.show("Revert selected items to the last saved version, discarding your changes?","Are you sure?",Alert.YES | Alert.CANCEL,null,revertHandler);
+                       var revertable:Boolean=false;
+                       for each (var item:Entity in _selection)
+                               if (item.id>0) revertable=true;
+                       if (revertable)
+                               Alert.show("Revert selected items to the last saved version, discarding your changes?","Are you sure?",Alert.YES | Alert.CANCEL,null,revertHandler);
                }
                protected function revertHandler(event:CloseEvent):void {
                        if (event.detail==Alert.CANCEL) return;
                        for each (var item:Entity in _selection) {
-                               item.connection.loadEntity(item);
+                               if (item.id>0) item.connection.loadEntity(item);
                        }
                }
 
index d1ea59a..d269b0b 100644 (file)
@@ -177,6 +177,7 @@ package net.systemeD.potlatch2.controller {
                                case Keyboard.DELETE:           
                                case Keyboard.BACKSPACE:        
                                case 189: /* minus */       return backspaceNode(MainUndoStack.getGlobalStack().addAction);
+                               case 79: /* O */                        return new SelectedWayNode(firstSelected as Way, editEnd ? Way(firstSelected).length-1 : 0); //, event);
                                case 82: /* R */            repeatTags(firstSelected); return this;
                                case 70: /* F */            followWay(); return this;
                        }
@@ -225,7 +226,7 @@ package net.systemeD.potlatch2.controller {
                        if ( editEnd )
                                Way(firstSelected).appendNode(node, performAction);
                        else
-                               Way(firstSelected).insertNode(0, node, performAction);
+                               Way(firstSelected).prependNode(node, performAction);
                }
                
                protected function backspaceNode(performAction:Function):ControllerState {
index 8680e1e..dd30530 100644 (file)
@@ -69,6 +69,7 @@ package net.systemeD.potlatch2.controller {
                        switch (event.keyCode) {
                                case 189:                                       return removeNode();                                    // '-'
                                case 88:                                        return splitWay();                                              // 'X'
+                               case 79:                                        return replaceNode();                                   // 'O'
                 case 81:  /* Q */           Quadrilateralise.quadrilateralise(parentWay, MainUndoStack.getGlobalStack().addAction); return this;
                                case 82:                                        repeatTags(firstSelected); return this; // 'R'
                                case 87:                                        return new SelectedWay(parentWay);              // 'W'
@@ -132,6 +133,29 @@ package net.systemeD.potlatch2.controller {
                            return new DrawWay(selectedWay, isLast, true);
         }
 
+               /** Replace the selected node with a new one created at the mouse position. 
+                       FIXME: currently two actions - should be undoable as one, but we need to execute the first action before we can run getNode(). */
+               public function replaceNode():ControllerState {
+                       // create a new node
+                       var newPoiAction:CreatePOIAction = new CreatePOIAction(
+                               layer.connection,
+                               {},
+                               controller.map.coord2lat(layer.mouseY),
+                               controller.map.coord2lon(layer.mouseX));
+                       MainUndoStack.getGlobalStack().addAction(newPoiAction);
+
+                       // replace old node
+                       var oldNode:Node=firstSelected as Node;
+                       var newNode:Node=newPoiAction.getNode();
+                       oldNode.replaceWith(newNode, MainUndoStack.getGlobalStack().addAction);
+
+                       // start dragging
+                       // we fake a MouseEvent because DragWayNode expects the x/y co-ords to be passed that way
+                       var d:DragWayNode=new DragWayNode(parentWay, parentWay.indexOfNode(newNode), new MouseEvent(MouseEvent.CLICK, true, false, layer.mouseX, layer.mouseY), true);
+                       d.forceDragStart();
+                       return d;
+               }
+
                /** Splits a way into two separate ways, at the currently selected node. Handles simple loops and P-shapes. Untested for anything funkier. */
                public function splitWay():ControllerState {
                        var n:Node=firstSelected as Node;
@@ -218,6 +242,7 @@ package net.systemeD.potlatch2.controller {
             var msg:String = "Nodes merged"
             if (MergeNodesAction.lastTagsMerged) msg += ": check conflicting tags";
             controller.dispatchEvent(new AttentionEvent(AttentionEvent.ALERT, null, msg));
+                       if (n.isDeleted()) n=Node(firstSelected);
             return new SelectedWayNode(n.parentWays[0], Way(n.parentWays[0]).indexOfNode(n));
         }