No Selection]]> Nothing selected"; } else if (entity.hasTags()) { iconText.htmlText = "Not recognised
Try looking at the tags under the advanced properties"; } else { iconText.htmlText = "No tags set
Please use the menu below to define what this "+entity.getType()+" is"; } currentCategorySelector.setSelectedFeature(null); } // Set it as the popup, and make sure it's visible popupChange.popUp=currentCategorySelector; currentCategorySelector.visible=true; } private function isMultipleEditable(entities:Array):Boolean { for each(var entity:Entity in entities) { if(!(entity is Node || entity is Way)) return false; } return true; } private function limitType(entity:Entity):String { if (entity is Node ) return "point"; else if (entity is Way ) return Way(entity).isArea() ? "area" : "line"; else if (entity is Relation) return "relation"; return null; } private var tabComponents:Object = {}; private function initialiseEditors():void { // reset tab to 0 to work around TabNavigator bug (#3444) if (editorStack is TabNavigator) { try { var tabBar:TabBar=TabBar(TabNavigator(editorStack).getTabAt(0).parent); tabBar.selectedIndex=0; } catch(errObject:Error) {} } editorStack.removeAllChildren(); if ( selectedEntity == null || feature == null ) return; var editorBox:VBox = createEditorBox(); editorBox.label = "Basic"; editorStack.addChild(editorBox); var tabs:Object = {}; tabComponents = {}; for each (var factory:EditorFactory in feature.editors) { if ( factory.presence.isEditorPresent(factory, selectedEntity, null) ) { var editor:DisplayObject = factory.createEditorInstance(selectedEntity); if ( editor != null ) editorBox.addChild(editor); } var category:String = factory.category; if (category!='') { var tab:VBox = tabs[category]; if ( tab == null) { tab = createEditorBox(); tab.label = category; editorStack.addChild(tab); tabs[category] = tab; tabComponents[tab] = []; } var catEditor:DisplayObject = factory.createEditorInstance(selectedEntity); if ( catEditor != null ) tabComponents[tab].push(catEditor); // tab.addChild(catEditor); } } } private function createEditorBox():VBox { var box:VBox = new VBox(); box.percentWidth = 100; box.percentHeight = 100; box.styleName = "dndEditorContainer"; return box; } private function ensureEditorsPopulated(tab:VBox):void { var components:Array = tabComponents[tab]; if ( components == null || tab == null || tab.numChildren >= components.length ) return; for each (var component:DisplayObject in components ) { tab.addChild(component); } } private function initEditorStackUIs():void { editorStackTabNavigator = new SuperTabNavigator(); editorStackTabNavigator.allowTabSqueezing=false; editorStackTabNavigator.minTabWidth=10; editorStackTabNavigator.closePolicy="close_never"; editorStackTabNavigator.scrollSpeed=20; editorStackTabNavigator.creationPolicy="auto"; editorStackTabNavigator.percentWidth=100; editorStackTabNavigator.percentHeight=100; editorStackTabNavigator.styleName="dndStackTab"; editorStackTabNavigator.popUpButtonPolicy="off" editorStackAccordion = new Accordion(); editorStackAccordion.percentWidth=100; editorStackAccordion.percentHeight=100; editorStackAccordion.creationPolicy="auto"; editorStackAccordion.styleName="dndStackAccordion"; setEditorStackUI(true); } private function setEditorStackUI(isTabbed:Boolean):void { var children:Array=[]; var i:uint; if (editorStack) { // blank existing component editorStack.removeEventListener("change",editorStackUIChange); editorStack.removeEventListener("updateComplete",editorStackUIUpdate); editorStack.removeAllChildren(); editorContainer.removeChildAt(1); } // replace with new component editorStack = (isTabbed ? editorStackTabNavigator : editorStackAccordion) as Container; editorContainer.addChild(editorStack); // re-add children and listeners initialiseEditors(); editorStack.addEventListener("change",editorStackUIChange); editorStack.addEventListener("updateComplete",editorStackUIUpdate); } private function editorStackUIChange(event:Event):void { ensureEditorsPopulated(IndexChangedEvent(event).relatedObject as VBox); } private function editorStackUIUpdate(event:Event):void { if (editorStack is SuperTabNavigator) { var e:SuperTabNavigator = editorStack as SuperTabNavigator; if (e.selectedIndex<0) { return; } for (var i:uint=0; i"+entity.id+""; } removeRelationListeners(); if ( entity == null ) { relationsGrid.dataProvider = null; } else { resetRelationsGrid(entity); entity.addEventListener(Connection.ADDED_TO_RELATION, addedToRelation); entity.addEventListener(Connection.REMOVED_FROM_RELATION, removedFromRelation); } } private function setupMultiAdvanced(entity:Entity):void { multiAdvancedTagGrid.init(entity); resetRelationsGrid(entity); entity.addEventListener(Connection.ADDED_TO_RELATION, addedToRelation, false, 0, true); entity.addEventListener(Connection.REMOVED_FROM_RELATION, removedFromRelation, false, 0, true); } public function addNewTag():void { if (stack.selectedChild!=advancedContainer) { return; } advancedTagGrid.addNewTag(); } private function addedToRelation(event:RelationMemberEvent):void { resetRelationsGrid(selectedEntity); } private function removedFromRelation(event:RelationMemberEvent):void { resetRelationsGrid(selectedEntity); } private function removeRelationListeners():void { for each( var rel:Relation in listeningToRelations ) { rel.removeEventListener(Connection.TAG_CHANGED, relationTagChanged); rel.removeEventListener(Connection.RELATION_MEMBER_ADDED, entityRelationMemberChanged); rel.removeEventListener(Connection.RELATION_MEMBER_REMOVED, entityRelationMemberChanged); } listeningToRelations = []; if (relationsGrid) relationsGrid.removeEventListener(DataGridEvent.ITEM_EDIT_END, relationRoleChanged); if (multiRelationsGrid) multiRelationsGrid.removeEventListener(DataGridEvent.ITEM_EDIT_END, relationRoleChanged); } private function resetRelationsGrid(entity:Entity):void { removeRelationListeners(); var instance:DataGrid=relationsGrid; if (entity is EntityCollection) instance=multiRelationsGrid; var memberships:Array = entity.getRelationMemberships(); for each (var m:Object in memberships) { m.relation.addEventListener(Connection.TAG_CHANGED, relationTagChanged); m.relation.addEventListener(Connection.RELATION_MEMBER_ADDED, entityRelationMemberChanged); m.relation.addEventListener(Connection.RELATION_MEMBER_REMOVED, entityRelationMemberChanged); listeningToRelations.push(m.relation); } instance.dataProvider = memberships; instance.addEventListener(DataGridEvent.ITEM_EDIT_END, relationRoleChanged, false, -100); } private function relationRoleChanged(event:DataGridEvent):void { if (event.dataField != 'role') { return; } // shouldn't really happen var relations:Array=event.currentTarget.dataProvider.toArray(); var props:Object=relations[event.rowIndex]; var relation:Relation=props['relation']; var newRole:String=event.itemRenderer.data['role']; if (selectedEntity is EntityCollection) { for each (var entity:Entity in EntityCollection(selectedEntity).entities) { var indexes:Array=relation.findEntityMemberIndexes(entity); for each (var index:int in indexes) { relation.setMember(index, new RelationMember(entity,newRole), MainUndoStack.getGlobalStack().addAction); } } } else { relation.setMember(props['index'], new RelationMember(selectedEntity,newRole), MainUndoStack.getGlobalStack().addAction); } } private function relationTagChanged(event:TagEvent):void { resetRelationsGrid(selectedEntity); } private function entityRelationMemberChanged(event:RelationMemberEvent):void { resetRelationsGrid(selectedEntity); } private function checkMembers():void { if (selectedEntity is Relation) { setupMembers(selectedEntity as Relation); } } private function setupMembers(rel:Relation):void { var members:Array = []; for (var i:int=0 ; i=0; i--) { rel.removeMemberByIndex(i, action.push); } // add members in new order for each(var memberObject:Object in membersGrid.dataProvider) { var e:Entity; var id:Number = memberObject.id; switch (memberObject.type) { case 'node': e = connection.getNode(id); break; case 'way': e = connection.getWay(id); break; case 'relation': e = connection.getRelation(id); break; } rel.appendMember(new RelationMember(e, memberObject.role), action.push); } MainUndoStack.getGlobalStack().addAction(action); } private function editRelation(id:Number):void { var panel:RelationEditorPanel = RelationEditorPanel( PopUpManager.createPopUp(Application(Application.application), RelationEditorPanel, true)); panel.setRelation(connection.getRelation(id)); PopUpManager.centerPopUp(panel); } /** Create relation actions menu */ public function createRelationMenu(button:PopUpButton):void { var menu:Menu = new Menu(); var dp:Object = [ {label: "Select all members"}, {label: "Deselect all members"}, {label: "Add selection to this relation", enabled: false}, {label: "Delete relation"} ]; menu.dataProvider = dp; menu.addEventListener("itemClick", selectRelationMenu); button.popUp = menu; } /** Enable 'add selection to...' entry only if some of the selection isn't in the relation. Called each time the menu is clicked. */ public function updateRelationMenu(event:Event):void { rowData=event.target.parent.data; // this makes it accessible from selectRelationMenu var menu:Menu = Menu(event.target.popUp); var enable:Boolean = false; if (selectedEntity != null && selectedEntity is EntityCollection) { // Enable only if some entities aren't a member of the relation enable=!rowData.universal; } if (enable==menu.dataProvider[2].enabled) return; menu.dataProvider[2].enabled=enable; menu.invalidateList(); } /** Do the action selected in the relation actions menu */ public function selectRelationMenu(event:MenuEvent):void { var rel:Relation=rowData.relation; var entities:Array; var controller:EditController=Application.application.theController; switch (event.index) { case 0: // Select all members entities=selectedEntity.entities.concat(rel.memberEntities); entities=entities.filter(function(e:*, i:int, arr:Array):Boolean { return arr.indexOf(e) == i } ); // remove duplicates // ** FIXME: This is a really horrible way of changing the controller state controller.setState(controller.findStateForSelection(entities)); break; case 1: // Deselect all members entities=selectedEntity.entities; entities=entities.filter(function(e:*, i:int, arr:Array):Boolean { return !e.hasParent(rel) } ); controller.setState(controller.findStateForSelection(entities)); break; case 2: // Add selection to this relation var undo:CompositeUndoableAction=new CompositeUndoableAction("Remove selection from relations"); for each (var entity:Entity in selectedEntity.entities) { if (!entity.hasParent(rel)) { rel.appendMember(new RelationMember(entity,''), undo.push); } } MainUndoStack.getGlobalStack().addAction(undo); break; case 3: // Delete relation Alert.show("Do you really want to delete the relation?","Are you sure?",Alert.YES | Alert.CANCEL,null, function(event:CloseEvent):void { if (event.detail==Alert.CANCEL) return; rel.remove(MainUndoStack.getGlobalStack().addAction); } ); break; } } private function tagChanged(event:TagEvent):void { refreshFeatureIcon(); } public function loadFeatures():void { mapFeatures = MapFeatures.getInstance(); stack.removeChild(membersVBox); // remove by default, will be added if relation } /** Open up a new browser page, showing the help page as defined in Map Features XML file .*/ public function openDescription():void { if ( feature != null && feature.hasHelpURL() ) navigateToURL(new URLRequest(feature.helpURL), "potlatch_help"); } /** Open up a new browser page showing OSM's view of the current entity. */ public function openEntityPage():void { if (selectedEntity != null && selectedEntity.id >= 0) { // This is slightly hard-coded, but not drastically. The ../s could be changed for string manipulation of the apiBase var urlBase:String = connection.apiBase + '../../browse/' navigateToURL(new URLRequest(urlBase+selectedEntity.getType()+'/'+selectedEntity.id), "potlatch_browse"); } } public function addToRelation():void { new RelationSelectPanel().init(selectedEntity,new Object()); } private function removeFromRelation(id:Number, index:int=-1):void { var rel:Relation=connection.getRelation(id); if (index>-1) { rel.removeMemberByIndex(index, MainUndoStack.getGlobalStack().addAction); } else if (selectedEntity is EntityCollection) { var undo:CompositeUndoableAction=new CompositeUndoableAction("Remove selection from relations"); for each (var e:Entity in EntityCollection(selectedEntity).entities) rel.removeMember(e,undo.push); MainUndoStack.getGlobalStack().addAction(undo); } } public function changeFeatureType(event:Event):void { if ( selectedEntity == null ) return; UIComponent.suspendBackgroundProcessing(); var newFeature:Feature = currentCategorySelector.selectedType; var undoStack:Function = MainUndoStack.getGlobalStack().addAction; var action:CompositeUndoableAction = new CompositeUndoableAction( "Set "+selectedEntity.getType()+" "+selectedEntity.id+" to "+newFeature.name); selectedEntity.suspend(); // remove tags from the current feature if ( feature != null ) { for each( var oldtag:Object in feature.tags ) { selectedEntity.setTag(oldtag["k"], null, action.push); } } // set tags for new feature if ( newFeature != null ) { for each( var newtag:Object in newFeature.tags ) { selectedEntity.setTag(newtag["k"], newtag["v"], action.push); } } selectedEntity.resume(); undoStack(action); popupChange.close(); initialiseEditors(); UIComponent.resumeBackgroundProcessing(); } private function resizePOIGrid(event:Event):void { var rows:Number=event.target.dataProvider.length/event.target.columnCount; if (rows!=Math.floor(rows)) { rows=Math.floor(rows+1); } event.target.height=rows*(event.target.rowHeight+1); } ]]>