PageRenderTime 28ms CodeModel.GetById 18ms app.highlight 4ms RepoModel.GetById 1ms app.codeStats 0ms

/src/org/ishafoundation/archives/transcript/components/studio/concept/ConceptManagerDialog.mxml

http://transcriptstudio4isha.googlecode.com/
Macromedia eXtensible Markup Language | 309 lines | 290 code | 19 blank | 0 comment | 0 complexity | 91044890032a7379ad56440267331c14 MD5 | raw file
  1<?xml version="1.0" encoding="utf-8"?>
  2<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml" alpha="2.0" layout="vertical" x="30" y="30" width="700" height="450" title="Concept Manager" horizontalAlign="center" creationComplete="init()" paddingLeft="0" paddingRight="0" paddingTop="0" roundedBottomCorners="false">
  3<mx:Script>
  4	<![CDATA[
  5		import mx.events.CloseEvent;
  6		import org.ishafoundation.archives.transcript.components.generic.MessagePopUp;
  7		import org.ishafoundation.archives.transcript.util.Constants;
  8		import mx.utils.StringUtil;
  9		import org.ishafoundation.archives.transcript.components.generic.TextInputDialog;
 10		import mx.events.MenuEvent;
 11		import mx.collections.ArrayCollection;
 12		import mx.managers.DragManager;
 13		import mx.binding.utils.BindingUtils;
 14		import mx.controls.Alert;
 15		import mx.events.DragEvent;
 16		import name.carter.mark.flex.util.Utils;
 17		import mx.managers.PopUpManager;
 18		import org.ishafoundation.archives.transcript.model.ReferenceManager;
 19		
 20		[Bindable]
 21    	private var referenceMgr:ReferenceManager;
 22    	[Bindable]
 23    	public var selectedConceptId:String;
 24    	
 25		public static function createInstance(referenceMgr:ReferenceManager):ConceptManagerDialog {
 26			var result:ConceptManagerDialog = new ConceptManagerDialog();
 27			result.referenceMgr = referenceMgr; 
 28			return result;
 29		}
 30		
 31		private function init():void {
 32			referenceMgr.getAllConcepts(function(conceptIds:Array):void {
 33				conceptList.dataProvider = conceptIds;
 34			}, function(msg:String):void {
 35				Alert.show(msg, "Failed to get all concepts");
 36			});
 37		}
 38
 39    	private function selectionChange(newConceptId:String):void {
 40    		if (DragManager.isDragging) {
 41    			return;
 42    		}
 43    		if (this.selectedConceptId != newConceptId) {
 44	    		trace("Selection changed to: " + newConceptId);
 45    			this.selectedConceptId = newConceptId;
 46    		}
 47    		conceptList.selectedItem = newConceptId;
 48    	}
 49
 50    	/**
 51    	 * Convenience method
 52    	 */
 53    	private static function sort(arr:Array):Array {
 54    		var result:Array = arr;
 55    		arr.sort();
 56    		return result;
 57    	}
 58    	
 59		private function closeMe():void {
 60        	PopUpManager.removePopUp(this);
 61		}
 62
 63		private function dragDropToSubTypeList(evt:DragEvent):void {
 64			if (!evt.dragSource.hasFormat("items")) {
 65				return;
 66			}
 67			evt.preventDefault();
 68			evt.currentTarget.hideDropFeedback(evt);
 69			var itemsArray:Array = evt.dragSource.dataForFormat("items") as Array;
 70			var draggedConceptId:String = itemsArray[0].toString();
 71			trace("Concept dropped: " + draggedConceptId);
 72			if (this.selectedConceptId == draggedConceptId) {
 73				Alert.show("Cannot assign concept as subtype of itself: " + draggedConceptId);
 74			}
 75			else {
 76				referenceMgr.addSubtype(this.selectedConceptId, draggedConceptId, function(added:Boolean):void {
 77					if (added) {
 78						refresh();
 79					}
 80					else {
 81						Alert.show("Already subtype: " + draggedConceptId);
 82					}
 83				}, function(msg:String):void {
 84					Alert.show(msg, "Failed to add subtype: " + draggedConceptId);
 85				});
 86			}
 87		}
 88		
 89		private function dragDropToSynonymList(evt:DragEvent):void {
 90			if (!evt.dragSource.hasFormat("items")) {
 91				return;
 92			}
 93			evt.preventDefault();
 94			evt.currentTarget.hideDropFeedback(evt);
 95			var itemsArray:Array = evt.dragSource.dataForFormat("items") as Array;
 96			var draggedConceptId:String = itemsArray[0].toString();
 97			trace("Concept dropped: " + draggedConceptId);
 98			if (this.selectedConceptId == draggedConceptId) {
 99				Alert.show("Cannot assign concept as synonym of itself: " + draggedConceptId);
100			}
101			else {
102				referenceMgr.addSynonyms([this.selectedConceptId, draggedConceptId], function(added:Boolean):void {
103					if (added) {
104						refresh();
105					}
106					else {
107						Alert.show("Already synonym: " + draggedConceptId);
108					}
109				}, function(msg:String):void {
110					Alert.show(msg, "Failed to add synonym: " + draggedConceptId);
111				});
112			}
113		}
114		
115		private function dragComplete(evt:DragEvent):void {
116			conceptList.selectedItem = this.selectedConceptId;			
117		}
118		
119		private function generateCollectedConcepts(conceptId:String):String {
120			if (conceptId == null) {
121				return "";
122			}
123			else {
124				return sort(referenceMgr.getCollectedConceptIds(conceptId).toArray()).toString().replace(/,/g, ", ")
125			}
126		}
127		
128		private function subTypeRemoveHandler():void {
129			var subtypeId:String = subTypeList.selectedItem as String;
130			referenceMgr.removeSubtype(this.selectedConceptId, subtypeId, function(removed:Boolean):void {
131				if (removed) {
132					refresh();
133				}
134				else {
135					Alert.show("Subtype not found: " + subtypeId);
136				}
137			}, function(msg:String):void {
138				Alert.show(msg, "Failed to remove subtype: " + subtypeId);
139			});
140		}
141		
142		private function synonymsLeaveHandler():void {
143			referenceMgr.removeSynonym(this.selectedConceptId, function(removed:Boolean):void {
144				if (removed) {
145					refresh();
146				}
147				else {
148					Alert.show("Synonym not found: " + this.selectedConceptId);
149				}
150			}, function(msg:String):void {
151				Alert.show(msg, "Failed to remove synonym: " + this.selectedConceptId);
152			});
153		}
154		
155		private function refresh():void {
156			subTypeList.executeBindings();
157			synonymList.executeBindings();
158			collectedConceptTextArea.executeBindings();
159		}
160		
161		private function addConcept():void {
162			var newConceptDialog:TextInputDialog = TextInputDialog.display(this, "Enter new concept", null, Constants.CONCEPT_ID_RESTRICTION);
163			newConceptDialog.okButton.addEventListener(MouseEvent.CLICK, function(evt:MouseEvent):void {
164				var conceptId:String = Utils.normalizeSpace(newConceptDialog.textInput.text);
165				if (conceptId != "") {
166					var messagePopUp:MessagePopUp = createMessagePopup("Adding concept: " + conceptId);
167					referenceMgr.addConcept(conceptId, function(returnVal:int):void {
168						init();
169						selectionChange(conceptId);
170						if (returnVal == 0) {
171							messagePopUp.enableOkButton("Concept already exists!");
172						}
173						else {
174							messagePopUp.enableOkButton("Added");
175						}
176					},
177					function(msg:String):void {
178						messagePopUp.enableOkButton("Failed", msg);
179					});
180				}
181			});			
182		}
183		
184		private function renameConcept():void {
185			var oldConceptId:String = conceptList.selectedItem.toString();
186			var thisObj:ConceptManagerDialog = this;
187			referenceMgr.countConceptInstances(oldConceptId, function(count:int):void {
188				if (count == 0) {
189					renameConceptWithoutConfirmation(oldConceptId);
190				}
191				else {
192					Alert.show("Are you sure you want to rename " + count + " instance(s)?", "Renaming concept: " + oldConceptId, Alert.OK | Alert.CANCEL, thisObj, function(evt:CloseEvent):void {
193						if (evt.detail == Alert.OK) {
194							renameConceptWithoutConfirmation(oldConceptId);
195						}
196					});
197				}
198			}, function(msg:String):void {
199				Alert.show(msg, "Error");				
200			});
201		}
202		
203		private function renameConceptWithoutConfirmation(oldConceptId:String):void {
204			var renameConceptDialog:TextInputDialog = TextInputDialog.display(this, "Rename concept", oldConceptId, Constants.CONCEPT_ID_RESTRICTION);
205			renameConceptDialog.okButton.addEventListener(MouseEvent.CLICK, function(evt:MouseEvent):void {
206				var newConceptId:String = Utils.normalizeSpace(renameConceptDialog.textInput.text);
207				if (newConceptId != "") {
208					if (oldConceptId == newConceptId) {
209						Alert.show("Concept name unchanged: " + oldConceptId);
210						return;
211					}
212					var messagePopUp:MessagePopUp = createMessagePopup("Renaming concept: " + oldConceptId + " to: " + newConceptId);
213					referenceMgr.renameConcept(oldConceptId, newConceptId, function(returnVal:int):void {
214						init();
215						if (returnVal == 0) {
216							selectionChange(null);
217							messagePopUp.enableOkButton("Could not find concept!");
218						}
219						else {
220							selectionChange(newConceptId);
221							messagePopUp.enableOkButton("Renamed");
222						}
223					},
224					function(msg:String):void {
225						messagePopUp.enableOkButton("Failed", msg);
226					});
227				}
228			});
229		}
230		
231		private function removeConcept():void {
232			var conceptId:String = conceptList.selectedItem.toString();
233			referenceMgr.countConceptInstances(conceptId, function(count:int):void {
234				if (count == 0) {
235					var messagePopUp:MessagePopUp = createMessagePopup("Removing concept: " + conceptId);
236					referenceMgr.removeConcept(conceptId, function(returnVal:int):void {
237						init();
238						selectionChange(null);
239						messagePopUp.enableOkButton(returnVal == 0 ? "Could not find concept!" : "Removed");
240					},
241					function(msg:String):void {
242						messagePopUp.enableOkButton("Failed", msg);
243					});
244				}
245				else {
246					Alert.show("Cannot remove concept because it appears at least once (" + count + " instance(s)) in all transcripts");
247				}
248			}, function(msg:String):void {
249				Alert.show(msg, "Error");
250			});
251		}
252		
253		private function onMenuClick(evt:MenuEvent):void {
254			var actionName:String = evt.item.@id;
255			if ( actionName == "add" ) {
256				addConcept();
257			}
258			else if ( actionName == "rename" ) {
259				renameConcept();
260			}
261			else if ( actionName == "remove" ) {
262				removeConcept();
263			}
264		}
265		
266		private function createMessagePopup(title:String):MessagePopUp {
267			var result:MessagePopUp = MessagePopUp.display(this, title, "Please wait...", 250);
268			result.okButton.enabled = false;
269			return result;
270		}
271	]]>
272	</mx:Script>
273	<mx:MenuBar id="myMenuBar" width="100%" labelField="@label" itemClick="onMenuClick(event)">
274		<mx:XMLList id="menuData">
275			<menuitem label="Concept">
276				<menuitem id="add" label="Add..."/>
277				<menuitem id="rename" label="Rename..." enabled="{conceptList.selectedItem != null}"/>
278				<menuitem id="remove" label="Remove" enabled="{conceptList.selectedItem != null}"/>
279			</menuitem>
280		</mx:XMLList>
281	</mx:MenuBar>
282	<mx:HDividedBox width="100%" height="100%" horizontalGap="{Utils.DIVIDER_SIZE}">
283		<mx:VBox width="33%" height="100%" minWidth="100">
284			<mx:Label text="All Concepts"/>
285			<mx:List id="conceptList" width="100%" height="100%" change="selectionChange(conceptList.selectedItem as String)" dragEnabled="true" dragDrop="dragDropToSubTypeList(event)" dragComplete="dragComplete(event)"/>
286		</mx:VBox>
287		<mx:VDividedBox width="67%" height="100%" minWidth="250" verticalGap="{Utils.DIVIDER_SIZE}">
288			<mx:HDividedBox width="100%" height="60%" minHeight="100" horizontalGap="{Utils.DIVIDER_SIZE}" paddingBottom="10">
289				<mx:VBox width="100%" height="100%" minWidth="130" horizontalAlign="center">
290					<mx:Label text="Immediate subtypes" width="100%"/>
291					<mx:List id="subTypeList" height="100%" width="100%" enabled="{this.selectedConceptId != null}" dropEnabled="true" dragDrop="dragDropToSubTypeList(event)" dataProvider="{this.selectedConceptId == null ? null : sort(this.referenceMgr.getConceptSubTypes(this.selectedConceptId).toArray())}"/>
292					<mx:Button label="Remove" click="subTypeRemoveHandler()" enabled="{subTypeList.selectedItem != null}"/>
293				</mx:VBox>
294				<mx:VBox width="100%" height="100%" minWidth="100" horizontalAlign="center">
295					<mx:Label text="Synonym group" width="100%"/>
296					<mx:List id="synonymList" height="100%" width="100%" enabled="{this.selectedConceptId != null}" selectable="false" dropEnabled="true" dragDrop="dragDropToSynonymList(event)" dataProvider="{this.selectedConceptId == null ? null : sort(referenceMgr.getConceptSynonymsIncludingSelf(this.selectedConceptId).toArray())}"/>
297					<mx:Button label="Leave Group" enabled="{(synonymList.dataProvider as ArrayCollection).length > 1}" click="synonymsLeaveHandler()"/>
298				</mx:VBox>
299			</mx:HDividedBox>
300			<mx:VBox width="100%" height="40%" minHeight="100" paddingTop="10">
301				<mx:Label text="Collected synonyms and subtypes"/>
302				<mx:TextArea id="collectedConceptTextArea" width="100%" height="100%" editable="false" selectable="false" wordWrap="true" enabled="{this.selectedConceptId != null}" text="{generateCollectedConcepts(this.selectedConceptId)}"/>
303			</mx:VBox>
304		</mx:VDividedBox>
305	</mx:HDividedBox>
306	<mx:HBox>
307		<mx:Button id="okButton" label="OK" click="{closeMe();referenceMgr.refreshAutoCompleteConcepts()}"/>
308	</mx:HBox>	
309</mx:TitleWindow>