return a;
}
- public function hasMemberInRole(entity:Entity,role:String):Boolean {
+ /** Is there an entity member in this specific role. (role=null for any role) */
+ public function hasMemberInRole(entity:Entity,role:String=null):Boolean {
for (var index:uint = 0; index < members.length; index++) {
- if (members[index].role==role && members[index].entity == entity) { return true; }
+ if (members[index].entity == entity &&
+ (members[index].role==role || role == null)) { return true; }
}
return false;
}
private var keys:Object={};
public var spaceHeld:Boolean=false;
- public var clipboards:Object={};
+ public var clipboards:Object={}; // one array of tags to repeat, per object type
+ public var relationClipboards:Object={}; // one array of relations to repeat, per object type
public var cursorsEnabled:Boolean=true;
private var maximised:Boolean=false;
private var maximiseFunction:String;
import net.systemeD.potlatch2.EditController;
import net.systemeD.potlatch2.save.SaveManager;
import net.systemeD.potlatch2.utils.SnapshotConnection;
+ import net.systemeD.halcyon.AttentionEvent;
import flash.ui.Keyboard;
import mx.controls.Alert;
import mx.events.CloseEvent;
object.setTag(k, controller.clipboards[object.getType()][k], undo.push)
}
MainUndoStack.getGlobalStack().addAction(undo);
- controller.updateSelectionUI();
+ controller.updateSelectionUI();
object.resume();
-
-
}
+
+ /** Create a "repeat relations" action on the current entity, if possible. */
+ protected function repeatRelations(object:Entity):void {
+ if (!controller.relationClipboards[object.getType()]) { return; }
+ object.suspend();
+
+ var undo:CompositeUndoableAction = new CompositeUndoableAction("Repeat relations");
+ var relationsadded: int;
+ for each (var rr:Object in controller.relationClipboards[object.getType()]) {
+ if (!rr.relation.hasMemberInRole(object, null)) {
+ rr.relation.appendMember(new RelationMember(object, rr.role), undo.push);
+ relationsadded ++;
+
+ }
+ }
+ MainUndoStack.getGlobalStack().addAction(undo);
+ controller.updateSelectionUI();
+ object.resume();
+ if (relationsadded > 0) {
+ var msg:String=relationsadded.toString() + " relation(s) added to " + object.getType() + ".";
+ controller.dispatchEvent(new AttentionEvent(AttentionEvent.ALERT, null, msg));
+ }
+ }
+
+ /** Copy list of relations from current object, for future repeatRelation() call. */
+ protected function copyRelations(object: Entity):void {
+ // Leave existing relations alone if it doesn't have any
+ if (object.parentRelations.length == 0)
+ return;
+ controller.relationClipboards[object.getType()]=[];
+ for each (var rm:Object in object.getRelationMemberships() ) {
+ var rr:Object={
+ relation: rm.relation,
+ role: rm.role
+ };
+ controller.relationClipboards[object.getType()].push(rr);
+ }
+ }
/** Remove all tags from current selection. */
protected function removeTags():void {
case Keyboard.BACKSPACE:
case 189: /* minus */ return backspaceNode(MainUndoStack.getGlobalStack().addAction);
case 79: /* O */ return replaceNode();
- case 82: /* R */ repeatTags(firstSelected); return this;
+ case 82: /* R */ { if (! event.shiftKey) repeatTags(firstSelected);
+ else repeatRelations(firstSelected);
+ return this; }
case 70: /* F */ followWay(); return this;
}
var cs:ControllerState = sharedKeyboardEvents(event);
switch (event.keyCode) {
case Keyboard.BACKSPACE: return deletePOI();
case Keyboard.DELETE: return deletePOI();
- case 82: repeatTags(firstSelected); return this; // 'R'
+ case 82: /* R */ { if (! event.shiftKey) repeatTags(firstSelected);
+ else repeatRelations(firstSelected);
+ return this; }
}
var cs:ControllerState = sharedKeyboardEvents(event);
return cs ? cs : this;
if(firstSelected.hasTags()) {
controller.clipboards['node']=firstSelected.getTagsCopy();
}
+ copyRelations(firstSelected);
layer.setPurgable(selection,true);
clearSelection(newState);
}
/** Behaviour includes: parallel way, repeat tags, reverse direction, simplify, cycle way selection, delete */
override public function processKeyboardEvent(event:KeyboardEvent):ControllerState {
switch (event.keyCode) {
- case 82: /* R */ repeatTags(firstSelected); return this;
+ case 82: /* R */ { if (! event.shiftKey) repeatTags(firstSelected);
+ else repeatRelations(firstSelected);
+ return this; }
case 191: /* / */ return cycleWays();
case Keyboard.BACKSPACE:
case Keyboard.DELETE: if (event.shiftKey) { return deleteWay(); } break;
}
layer.setPurgable(selection,false);
}
- /** Officially leave the state, remembering the current way's tags for future repeats. */
+ /** Officially leave the state, remembering the current way's tags and relations for future repeats. */
// TODO: tweak this so that repeat tags aren't remembered if you only select a way in order to branch off it. (a la PL1)
override public function exitState(newState:ControllerState):void {
if (firstSelected.hasTags()) {
controller.clipboards['way']=firstSelected.getTagsCopy();
}
+ copyRelations(firstSelected);
layer.setPurgable(selection,true);
firstSelected.removeEventListener(Connection.WAY_REORDERED, updateSelectionUI);
clearSelection(newState);
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 82: /* R */ { if (! event.shiftKey) repeatTags(firstSelected);
+ else repeatRelations(firstSelected);
+ return this; }
case 87: return new SelectedWay(parentWay); // 'W'
case 191: return cycleWays(); // '/'
case 74: if (event.shiftKey) { return unjoin() }; return join();// 'J'
if (firstSelected.hasTags()) {
controller.clipboards['node']=firstSelected.getTagsCopy();
}
+ copyRelations(firstSelected);
layer.setPurgable(selection,true);
clearSelection(newState);
}
["P", "Create parallel way"],
["Q", "Make area right-angled"],
["R", "Repeat tags"],
+ ["Shift-R", "Repeat relations"],
];
var text3:Array = [["S", "Save"],
["T", "Toggle between simple and advanced tags"],