Merge pull request #28 from gravitystorm/docs
[potlatch2.git] / net / systemeD / potlatch2 / panels / BackgroundMergePanel.mxml
1 <?xml version="1.0" encoding="utf-8"?>
2 <!---
3     The Background Merge Panel allows the tags from two features - one from
4     a read-only vector background layer, one from an editable layer - to be
5     compared. Tags are highlighted depending whether they match, and tags from
6     the background layer can be easily merged.
7 -->
8
9 <mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" height="100%">
10   <mx:Text id="backgroundMergePanelText" text="Review and Merge tags from the Background layer" width="100%" styleName="helpInfo" />
11   <mx:DataGrid editable="false" id="backgroundPanelDG" width="100%" height="50%">
12     <mx:columns>
13       <mx:DataGridColumn editable="false" dataField="k" headerText="Key" />
14       <mx:DataGridColumn editable="false" dataField="e" headerText="OSM value" />
15       <mx:DataGridColumn editable="false" headerText="Merge" width="50" textAlign="center">
16         <mx:itemRenderer>
17           <mx:Component>
18             <mx:HBox horizontalAlign="center" verticalAlign="middle">
19               <mx:Button label="&lt;&lt;" visible="{parentDocument.buttonVisible(data.b, data.e)}" click="parentDocument.mergeForKey(data.k);" />
20             </mx:HBox>
21           </mx:Component>
22         </mx:itemRenderer>
23       </mx:DataGridColumn>
24       <mx:DataGridColumn editable="false" itemRenderer="net.systemeD.potlatch2.panels.BackgroundMergeFieldComponent" dataField="b" headerText="Background value" />
25     </mx:columns>
26   </mx:DataGrid>
27   <mx:ViewStack id="statusStack" resizeToContent="true" width="100%">
28     <mx:VBox id="empty" />
29     <mx:VBox id="not_complete">
30       <mx:Text text="All the data copied to the main layer? Click 'complete'!" />
31       <mx:Button label="Complete" click="markComplete()"/>
32     </mx:VBox>
33     <mx:VBox id="complete">
34       <mx:Text text="This feature has been marked as complete. If this is wrong, press the button below." />
35       <mx:Button label="Not complete" click="markNotComplete()"/>
36     </mx:VBox>
37   </mx:ViewStack>
38   <mx:Script><![CDATA[
39
40       import net.systemeD.halcyon.connection.*;
41       import net.systemeD.halcyon.MapPaint;
42       import net.systemeD.potlatch2.utils.SnapshotConnection;
43
44       import mx.collections.*;
45
46       private var editableEntity:Entity;
47       private var backgroundEntity:Entity;
48       private var tagDataProvider:ArrayCollection;
49
50       /**
51       * @param entities The two entities that are being compared. One should be from a background layer, but the
52       *                 order is not important.
53       */
54       public function init(entities:Array):void {
55           if ( tagDataProvider == null ) {
56               tagDataProvider = new ArrayCollection();
57               backgroundPanelDG.dataProvider = tagDataProvider;
58           }
59
60           if (parentDocument.controller.map.getLayerForEntity(entities[0]).isBackground) {
61               backgroundEntity = entities[0];
62               editableEntity = entities[1];
63           } else {
64               backgroundEntity = entities[1];
65               editableEntity = entities[0];
66           }
67           backgroundEntity.addEventListener(Connection.STATUS_CHANGED, statusEvent, false, 0, true);
68           setStatusStack();
69           editableEntity.addEventListener(Connection.TAG_CHANGED, tagChanged, false, 0, true);
70           updateTagDataProvider();
71       }
72
73       private function updateTagDataProvider():void {
74           var tag:Tag;
75           var keys:Array = [];
76
77           tagDataProvider.removeAll();
78
79           for each (tag in backgroundEntity.getTagArray() ) {
80               keys.push(tag.key);
81           }
82
83           for each (tag in editableEntity.getTagArray() ) {
84               keys.push(tag.key);
85           }
86
87           keys=keys.filter(function(k:*, i:int, arr:Array):Boolean { return arr.indexOf(k) == i } ); // remove duplicates
88           keys.sort();
89
90           for each (var key:String in keys) {
91               tagDataProvider.addItem({k:key, e:editableEntity.getTag(key), b:backgroundEntity.getTag(key)});
92           }
93           backgroundPanelDG.invalidateList();
94       }
95
96       private function tagChanged(e:Event):void {
97           updateTagDataProvider();
98       }
99
100       /**
101       * Should the button for merging tags be shown?
102       *
103       * @param b The tag value for the background entity
104       * @param e The tag value for the editable entity
105       */
106       public function buttonVisible(b:String, e:String):Boolean {
107           if (b != null && b != e) {
108               return true;
109           }
110           return false;
111       }
112
113       /**
114       * Merge the data for the given key. Results in the value being copied to the editable entity, using the
115       * global undo stack.
116       *
117       * @param key The tag key to be merged.
118       */
119       public function mergeForKey(key:String):void {
120           editableEntity.setTag(key, backgroundEntity.getTag(key), MainUndoStack.getGlobalStack().addAction);
121       }
122
123       /**
124       * Figure out an appropriate background color for the row. Don't call this for things you don't want coloured in. Like for empty tags.
125       *
126       * @param i The row index in the tagDataProvider
127       * @return The colour to be used as the background of the field
128       */
129       public function getColorFor(i:int):int {
130           if (tagDataProvider[i].e == tagDataProvider[i].b) {
131               return 0xDDFFDD; // matching, green
132            } else if (tagDataProvider[i].e == null) {
133               return 0xDDDDFF; // new value, blue
134            } else if (tagDataProvider[i].b) {
135               return 0xFFDDDD; // conflicting, red
136            }
137            return NaN; // which is interpretted as black
138       }
139
140       private function statusEvent(e:Event):void {
141             setStatusStack();
142       }
143
144       private function setStatusStack():void {
145           switch (backgroundEntity.status) {
146               case 'incomplete':
147                   statusStack.selectedChild = not_complete;
148                   break;
149               case 'complete':
150                   statusStack.selectedChild = complete;
151                   break;
152               default:
153                   statusStack.selectedChild = empty;
154           }
155       }
156
157       private function markComplete():void {
158           if (backgroundEntity.connection is SnapshotConnection) {
159               SnapshotConnection(backgroundEntity.connection).markComplete(backgroundEntity);
160           }
161       }
162
163       private function markNotComplete():void {
164           if (backgroundEntity.connection is SnapshotConnection) {
165               SnapshotConnection(backgroundEntity.connection).markNotComplete(backgroundEntity);
166           }
167       }
168   ]]>
169   </mx:Script>
170 </mx:VBox>