Merge branch 'master' of github.com:systemed/potlatch2
[potlatch2.git] / net / systemeD / potlatch2 / TagGrid.mxml
1 <?xml version="1.0" encoding="utf-8"?>
2
3 <!--
4         Advanced tag grid
5 -->
6
7 <mx:DataGrid editable="true" doubleClickEnabled="true" doubleClick="addNewTag(event)" sortableColumns="false"
8         variableRowHeight="true"
9     xmlns:fx="http://ns.adobe.com/mxml/2009"
10         xmlns:controls="net.systemeD.controls.*"
11         xmlns:mx="library://ns.adobe.com/flex/mx">
12         <mx:columns>
13
14                 <!-- Key -->
15
16                 <mx:DataGridColumn editable="true" dataField="key" headerText="Key">
17                         <mx:itemEditor>
18                                 <fx:Component>
19                                         <controls:AutoComplete
20                                                 dataProvider="{MapFeatures.getInstance().getAutoCompleteKeys(outerDocument.getEntityType())}"
21                                                 labelField="name"
22                                                 rowCount="10"
23                                                 restrict="&#x0020;-&#x10FFFF;"
24                                                 maxChars="255" 
25                                                 typedText="{outerDocument.selectedItem.key}">
26                                         <fx:Script><![CDATA[ import net.systemeD.potlatch2.mapfeatures.*; ]]></fx:Script>
27                                         </controls:AutoComplete>
28                                 </fx:Component>
29                         </mx:itemEditor>
30                 </mx:DataGridColumn>
31
32                 <!-- Value -->
33
34                 <mx:DataGridColumn wordWrap="true" editable="true" dataField="value" headerText="Value" itemRenderer="net.systemeD.controls.DataGridWarningField" >
35                         <mx:itemEditor>
36                                 <fx:Component>
37                                         <controls:AutoComplete
38                                                 dataProvider="{MapFeatures.getInstance().getAutoCompleteValues(outerDocument.getEntityType(),outerDocument.selectedItem.key)}"
39                                                 labelField="name"
40                                                 rowCount="10"
41                                                 restrict="&#x0020;-&#x10FFFF;"
42                                                 maxChars="255" 
43                                                 typedText="{outerDocument.selectedItem.value}">
44                                         <fx:Script><![CDATA[ import net.systemeD.potlatch2.mapfeatures.*; ]]></fx:Script>
45                                         </controls:AutoComplete>
46                                 </fx:Component>
47                         </mx:itemEditor>
48                 </mx:DataGridColumn>
49
50                 <!-- Delete button -->
51
52                 <mx:DataGridColumn width="20" editable="false">
53                         <mx:itemRenderer>
54                                 <fx:Component>
55                     <mx:HBox horizontalAlign="center" verticalAlign="top">
56                       <mx:Image source="@Embed('../../../embedded/delete_small.svg')"
57                           click='event.stopPropagation();outerDocument.removeTag();'
58                           buttonMode="true" useHandCursor="true" width="12" height="12">
59                       </mx:Image>
60                                         </mx:HBox>
61                                 </fx:Component>
62                         </mx:itemRenderer>
63                 </mx:DataGridColumn>
64         </mx:columns>
65
66         <fx:Script><![CDATA[
67
68                 import net.systemeD.halcyon.connection.*;
69                 import mx.collections.*;
70                 import mx.utils.StringUtil;
71
72                 private var selectedEntity:Entity;
73                 private var tagDataProvider:ArrayCollection;
74
75                 /** Assign a new selected Entity, and update editing controls appropriately. */
76                 public function init(entity:Entity):void {
77                         if (selectedEntity==entity) return;
78                         if (selectedEntity) selectedEntity.removeEventListener(Connection.TAG_CHANGED, tagChanged);
79
80                         selectedEntity=entity;
81                         if (!selectedEntity) return;
82                         selectedEntity.addEventListener(Connection.TAG_CHANGED, tagChanged, false, 0, true);
83
84                         if ( tagDataProvider == null ) {
85                                 tagDataProvider = new ArrayCollection();
86                                 dataProvider = tagDataProvider;
87                         } else {
88                                 tagDataProvider.removeAll();
89                         }
90
91                         var tags:Array = selectedEntity.getTagArray();
92                         tags.sortOn("key");
93                         for each(var tag:Tag in tags) { tagDataProvider.addItem(tag); }
94                 }
95
96                 /** Update dataProvider in response to a tag being edited or removed */
97                 private function tagChanged(event:TagEvent):void {
98                         if (event.key==event.oldKey && event.oldValue==event.newValue) return;
99                         var set:Boolean=false;
100                         for (var i:uint=0; i<tagDataProvider.length; i++) {
101                                 if (tagDataProvider[i].key==event.oldKey || tagDataProvider[i].key==event.key) {
102                                         if (event.newValue && event.key) {
103                                                 if (!set) {
104                                                         // this entry in the dataProvider has changed
105                                                         tagDataProvider[i].key = StringUtil.trim(event.key);
106                                                         tagDataProvider[i].value = StringUtil.trim(event.newValue);
107                                                         set=true;
108                                                 } else {
109                                                         // trap duplicate tags
110                                                         tagDataProvider.removeItemAt(i);
111                                                 }
112                                         } else {
113                                                 // this entry in the dataProvider has been deleted
114                                                 tagDataProvider.removeItemAt(i);
115                                         }
116                                 }
117                         }
118                         if (!set && event.newValue) tagDataProvider.addItem(new Tag(event.entity,event.key,event.newValue));
119
120                         // tell Flex to redraw the grid because we've changed a tag
121                         invalidateList();
122                 }
123
124                 /** Create editing controls for a new key/value pair, with default values. */
125                 public function addNewTag(event:Event=null):void {
126                         if (event && event.target is TextField) return;
127                         var newKey:String = "(new tag)";
128                         var newTag:Tag = new Tag(selectedEntity, newKey, "(new value)");
129                         tagDataProvider.addItem(newTag);
130                         editedItemPosition = {rowIndex: tagDataProvider.getItemIndex(newTag), columnIndex: 0};
131                 }
132
133                 /** Remove the selected tag from the selected entity. */
134                 public function removeTag():void {
135                         var k:String = selectedItem.key;
136                         if (selectedEntity.getTag(k)) {
137                                 // genuinely a tag on the Entity, so remove it
138                                 selectedEntity.setTag(k, null, MainUndoStack.getGlobalStack().addAction);
139                         } else {
140                                 // a "(new key)=(new value)" pair, which is in the dataProvider but not the Entity
141                                 for (var i:uint=0; i<tagDataProvider.length; i++) {
142                                         if (tagDataProvider[i].key==k) {
143                                                 tagDataProvider.removeItemAt(i);
144                                                 return;
145                                         }
146                                 }
147                         }
148                 }
149
150                 /** Return the type ("node", "way", "relation") of the selected entity. */
151                 public function getEntityType():String {
152                         return selectedEntity.getType();
153                 }
154
155         ]]></fx:Script>
156 </mx:DataGrid>