source: ComponentRegistry/branches/ComponentRegistry-1.12.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/CMDComponentXMLEditor.as @ 1988

Last change on this file since 1988 was 1988, checked in by twagoo, 12 years ago

Created branch for ComponentRegistry-1.12.0
Bumped trunk to 1.13.0

File size: 13.5 KB
Line 
1package clarin.cmdi.componentregistry.editor {
2        import clarin.cmdi.componentregistry.common.CMDSpecRenderer;
3        import clarin.cmdi.componentregistry.common.ItemDescription;
4        import clarin.cmdi.componentregistry.common.LabelConstants;
5        import clarin.cmdi.componentregistry.common.StyleConstants;
6        import clarin.cmdi.componentregistry.common.components.AddComponentLabelButton;
7        import clarin.cmdi.componentregistry.common.components.AddElementLabelButton;
8        import clarin.cmdi.componentregistry.common.components.RemoveLabelButton;
9        import clarin.cmdi.componentregistry.editor.model.CMDComponent;
10        import clarin.cmdi.componentregistry.editor.model.CMDComponentElement;
11        import clarin.cmdi.componentregistry.editor.model.CMDSpec;
12        import clarin.cmdi.componentregistry.services.IsocatService;
13       
14        import flash.display.DisplayObject;
15        import flash.events.Event;
16        import flash.events.MouseEvent;
17        import flash.utils.Dictionary;
18        import flash.utils.getTimer;
19       
20        import mx.collections.ArrayCollection;
21        import mx.containers.Form;
22        import mx.containers.FormItem;
23        import mx.containers.FormItemDirection;
24        import mx.controls.Alert;
25        import mx.controls.Label;
26        import mx.controls.Spacer;
27        import mx.core.Container;
28        import mx.core.UIComponent;
29        import mx.events.ChildExistenceChangedEvent;
30        import mx.events.CloseEvent;
31        import mx.events.DragEvent;
32        import mx.managers.DragManager;
33        import mx.managers.IFocusManagerComponent;
34       
35        [Event(name="editorChange", type="flash.events.Event")]
36        public class CMDComponentXMLEditor extends Form implements IFocusManagerComponent, CMDSpecRenderer {
37               
38                public static const DRAG_NEW_COMPONENT:String = "newComponent";
39                public static const DRAG_NEW_ELEMENT:String = "newElement";
40                public static const DRAG_NEW_ATTRIBUTE:String = "newAttribute";
41                private static const DRAG_ITEMS:String = "items";
42               
43                public static const EDITOR_CHANGE_EVENT:String = "editorChange";
44               
45                private var _spec:CMDSpec;
46                private var _firstComponent:CMDComponent;
47                private var addComponentLabel:Label
48                private var addElementLabel:Label
49               
50                public function CMDComponentXMLEditor() {
51                        super();
52                        focusEnabled = true;
53                        tabEnabled = true;
54                        styleName = StyleConstants.XMLBROWSER;
55                        addEventListener(DragEvent.DRAG_ENTER, dragEnterHandler);
56                        addEventListener(DragEvent.DRAG_OVER, dragOverHandler);
57                        addEventListener(DragEvent.DRAG_DROP, dragDropHandler);
58                        addEventListener(ChildExistenceChangedEvent.CHILD_ADD, dispatchEditorChangeEvent);
59                        addEventListener(ChildExistenceChangedEvent.CHILD_REMOVE, dispatchEditorChangeEvent);
60                }
61               
62                public function validate():Boolean {
63                        var componentDisplayPrioMap:Dictionary = new Dictionary(true);
64                        componentDisplayPrioMap[this] = new ArrayCollection();
65                        var result:Boolean = validateChildren(getChildren(), componentDisplayPrioMap, this);
66                        result = validateDisplayPriorityFields(componentDisplayPrioMap) && result;
67                        return result;
68                }
69               
70                private function validateChildren(children:Array, componentDisplayPrioMap:Dictionary, key:Object):Boolean {
71                        var result:Boolean = true;
72                        for each (var o:Object in children) {
73                                if (o is CMDValidator) {
74                                        var validatorResult : Boolean = CMDValidator(o).validate();
75                                        if(!validatorResult){
76                                                CMDValidator(o).validate();
77                                        }
78                                        result = validatorResult && result;
79                                }
80                                if (o is Container) {
81                                        var newKey:Object = key;
82                                        if (o is ComponentEdit) {
83                                                componentDisplayPrioMap[o] = new ArrayCollection();
84                                                newKey = o;
85                                        }
86                                        result = validateChildren(Container(o).getChildren(), componentDisplayPrioMap, newKey) && result;
87                                        if (o is DisplayPriorityInput) {
88                                                componentDisplayPrioMap[newKey].addItem(o);
89                                        }
90                                }
91                        }
92                        return result;
93                }
94               
95                private function validateDisplayPriorityFields(componentDisplayPrioMap:Dictionary):Boolean {
96                        var result:Boolean = true;
97                        for (var key:Object in componentDisplayPrioMap) {
98                                var displayPrioritySet:Boolean = false;
99                                var displayPriorityFields:ArrayCollection = componentDisplayPrioMap[key];
100                                for each (var input:DisplayPriorityInput in displayPriorityFields) { // get values
101                                        if (input.getValue() > 0) {
102                                                displayPrioritySet = true;
103                                                break;
104                                        }
105                                }
106                                for each (var inputF:DisplayPriorityInput in displayPriorityFields) { // set results
107                                        if (displayPrioritySet) {
108                                                result = inputF.validate(input.getValue()) && result;
109                                        } else {
110                                                result = inputF.validate(null) && result;
111                                        }
112                                }
113                        }
114                        return result;
115                }
116               
117                private function dragEnterHandler(event:DragEvent):void {
118                        DragManager.acceptDragDrop(event.currentTarget as UIComponent);
119                        UIComponent(event.currentTarget).drawFocus(true);
120                }
121               
122               
123                private function dragOverHandler(event:DragEvent):void {
124                        if (event.dragSource.hasFormat(DRAG_ITEMS)) {
125                                DragManager.showFeedback(DragManager.COPY);
126                        } else {
127                                DragManager.showFeedback(DragManager.NONE);
128                        }
129                }
130               
131                private function dragDropHandler(event:DragEvent):void {
132                        if (event.dragSource.hasFormat(DRAG_ITEMS)) {
133                                var items:Array = event.dragSource.dataForFormat(DRAG_ITEMS) as Array;
134                                for each (var item:ItemDescription in items) {
135                                        var comp:CMDComponent = new CMDComponent();
136                                        comp.componentId = item.id;
137                                        _firstComponent.cmdComponents.addItem(comp);
138                                        addComponent(comp);
139                                }
140                        }
141                }
142               
143                public function set cmdSpec(cmdSpec:CMDSpec):void {
144                        _spec = cmdSpec;
145                        createNewEditor();
146                        dispatchEditorChangeEvent();
147                }
148               
149                private function dispatchEditorChangeEvent(event:Event = null):void {
150                        dispatchEvent(new Event(EDITOR_CHANGE_EVENT));
151                }
152               
153                [Bindable]
154                public function get cmdSpec():CMDSpec {
155                        return _spec;
156                }
157               
158                private function createNewEditor():void {
159                        var start:int = getTimer();
160                        addComponentLabel = null
161                        addElementLabel = null
162                        removeAllChildren();
163                        checkFirstDefiningComponent(_spec.cmdComponents);
164                        handleHeader(_spec);
165                        handleElements(_firstComponent.cmdElements);
166                        addElementAddButton();
167                        handleComponents(_firstComponent.cmdComponents);
168                        addComponentAddButton();
169                        trace("Created editor view in " + (getTimer() - start) + " ms.");
170                }
171               
172                private function clearEditorHandler(event:Event):void {
173                        if (_spec && !_spec.isProfile) {
174                                clearEditorComponent();
175                        } else {
176                                clearEditorProfile();
177                        }
178                }
179               
180                public function get specHasChanges():Boolean {
181                        return _spec.hasChanged;
182                }
183               
184                public function clearEditorComponent() : void{         
185                        clearEditorSubmit(doClearEditorComponent);
186                }       
187               
188                public function clearEditorProfile() : void{
189                        clearEditorSubmit(doClearEditorProfile);
190                }
191               
192                private function clearEditorSubmit(clearFunction:Function) : void {
193                        if(_spec.hasChanged) {
194                                Alert.show("This will discard all changes to the component currently being edited", "Discard changes", Alert.OK|Alert.CANCEL, null, clearFunction); 
195                        } else{
196                                callLater(clearFunction);
197                        }
198                }
199               
200                public function doClearEditorComponent(event:CloseEvent=null) : void{
201                        if(event == null || event.detail == Alert.OK){
202                                cmdSpec = CMDSpec.createEmptyComponent();
203                                cmdSpec.changeTracking = true;
204                                dispatchEditorChangeEvent();
205                        }
206                }       
207               
208                public function doClearEditorProfile(event:CloseEvent=null) : void{
209                        if(event == null || event.detail == Alert.OK){
210                                cmdSpec = CMDSpec.createEmptyProfile();
211                                cmdSpec.changeTracking = true;
212                                dispatchEditorChangeEvent();
213                        }
214                }
215               
216                /**
217                 * The xml model allows more component to be defined but we force only one component at the "root" level.
218                 */
219                private function checkFirstDefiningComponent(components:ArrayCollection):void {
220                        if (components.length != 1) {
221                                throw new Error("A profile/component must have 1 component defined at root level.");
222                        } else {
223                                _firstComponent = components.getItemAt(0) as CMDComponent;
224                                if (_firstComponent.componentId != "" && _firstComponent.componentId != null) {
225                                        _firstComponent = new CMDComponent();
226                                        _firstComponent.name = _spec.headerName;
227                                        _firstComponent.cmdComponents = _spec.cmdComponents;
228                                        _spec.cmdComponents = new ArrayCollection();
229                                        _spec.cmdComponents.addItem(_firstComponent);
230                                }
231                        }
232                }
233               
234                private function handleHeader(spec:CMDSpec):void {
235                        var head:FormItem = new FormItem();
236                        head.direction = FormItemDirection.HORIZONTAL;
237                        var buttons:FormItem = new SelectTypeRadioButtons(spec);
238                        head.addChild(buttons);
239                        var startOverLabel:Label = createStartOverButton();
240                        startOverLabel.setStyle("paddingTop", "2");
241                        startOverLabel.height = buttons.height;
242                        var space:Spacer = new Spacer();
243                        space.width = 55;
244                        head.addChild(space);
245                        head.addChild(startOverLabel);
246                        addChild(head);
247                       
248                        var nameInput:NameInputLine = new NameInputLine(_firstComponent.name, function(val:String):void {
249                                _firstComponent.name = val;
250                                _spec.headerName = val;
251                        }, InputValidators.getNameValidator());
252                        addChild(nameInput);
253                       
254                        var groupNameInput:FormItemInputLine = new FormItemInputLine(LabelConstants.GROUP_NAME, spec.groupName, function(val:String):void {
255                                spec.groupName = val;
256                        }); // editable, not required
257                        addChild(groupNameInput);
258                       
259                        var descriptionInput:FormItemInputText = new FormItemInputText(LabelConstants.DESCRIPTION, spec.headerDescription, function(val:String):void {
260                                spec.headerDescription = val;
261                        }, InputValidators.getIsRequiredValidator()); //editable, required
262                        addChild(descriptionInput);
263                       
264                        var domainInput:ComboBoxInputLine = new ComboBoxInputLine(LabelConstants.DOMAIN_NAME, _spec.domainName, LabelConstants.DOMAIN_NAME_DATA, LabelConstants.DOMAIN_NAME_PROMPT, function(val:Object):void {
265                                if (val) {
266                                        _spec.domainName = val.data;
267                                }
268                        }); // editable, not required
269                        addChild(domainInput);
270                       
271                        //                      var idInput:FormItemInputLine = new FormItemInputLine(XMLBrowser:"Id", spec.headerId, function(val:String):void {
272                        //                                      spec.headerId = val;
273                        //                              }, false);
274                        //                      idInput.toolTip = "Id will be generated";
275                        //                      addChild(idInput);
276                        var link:ConceptLinkInput = new ConceptLinkInput(LabelConstants.CONCEPTLINK, _firstComponent.conceptLink, function(val:String):void {
277                                _firstComponent.conceptLink = val;
278                        }, IsocatService.TYPE_CONTAINER);
279                        addChild(link);
280                       
281                        addChild(new AttributeListEdit(_firstComponent, this))
282                }
283               
284                private function addComponentAddButton():void {
285                        addComponentLabel = new AddComponentLabelButton();
286                        addComponentLabel.addEventListener(MouseEvent.CLICK, function(event:MouseEvent):void {
287                                var comp:CMDComponent = CMDComponent.createEmptyComponent();
288                                _firstComponent.cmdComponents.addItem(comp);
289                                addComponent(comp);
290                               
291                        });
292                        addComponentLabel.addEventListener(MouseEvent.MOUSE_OVER, function(event:MouseEvent):void {
293                                drawFocus(true);
294                        });
295                        addComponentLabel.addEventListener(MouseEvent.MOUSE_OUT, function(event:MouseEvent):void {
296                                drawFocus(false);
297                        });
298                        addChild(addComponentLabel);
299                }
300               
301                private function addElementAddButton():void {
302                        addElementLabel = new AddElementLabelButton();
303                        addElementLabel.addEventListener(MouseEvent.CLICK, function(event:MouseEvent):void {
304                                var element:CMDComponentElement = CMDComponentElement.createEmptyElement();
305                                _firstComponent.cmdElements.addItem(element);
306                                addElement(element);
307                               
308                        });
309                        addElementLabel.addEventListener(MouseEvent.MOUSE_OVER, function(event:MouseEvent):void {
310                                drawFocus(true);
311                        });
312                        addElementLabel.addEventListener(MouseEvent.MOUSE_OUT, function(event:MouseEvent):void {
313                                drawFocus(false);
314                        });
315                        addChild(addElementLabel);
316                }
317               
318                /* private function createOptionalGroupNameInput(spec:CMDSpec):FormItem {
319                var result:FormItemInputLine = new FormItemInputLine(LabelConstants.GROUP_NAME, spec.groupName, function(val:String):void {
320                spec.groupName = val;
321                }, true, InputValidators.getIsRequiredValidator());
322                BindingUtils.bindSetter(function(val:Boolean):void {
323                result.visible = !val;
324                }, spec, "isProfile");
325                return result;
326                }  */
327               
328                private function handleComponents(components:ArrayCollection):void {
329                        for each (var component:CMDComponent in components) {
330                                addComponent(component);
331                        }
332                }
333               
334                public function addComponent(component:CMDComponent):void {
335                        var comp:Container = new ComponentEdit(component, this, _firstComponent);
336                        comp.addEventListener(ComponentEdit.REMOVE_COMPONENT_EVENT, removeComponent);
337                        if (!addComponentLabel) {
338                                addChild(comp);
339                        } else {
340                                addChildAt(comp, getChildIndex(addComponentLabel)); //Add components at the place of the button so button moves down
341                        }
342                }
343               
344                private function removeComponent(event:Event):void {
345                        var comp:CMDComponent = ComponentEdit(event.currentTarget).component;
346                        _firstComponent.removeComponent(comp);
347                        removeChild(event.currentTarget as DisplayObject);
348                }
349               
350               
351                private function handleElements(elements:ArrayCollection):void {
352                        for each (var element:CMDComponentElement in elements) {
353                                addElement(element);
354                        }
355                }
356               
357                public function addElement(element:CMDComponentElement):void {
358                        var elem:Container = new ElementEdit(element, this, _firstComponent);
359                        elem.setStyle("paddingLeft", "50");
360                        elem.addEventListener(ElementEdit.REMOVE_ELEMENT_EVENT, removeElement);
361                        if (!addElementLabel) {
362                                addChild(elem);
363                        } else {
364                                addChildAt(elem, getChildIndex(addElementLabel));
365                        }
366                }
367               
368                private function removeElement(event:Event):void {
369                        var elem:CMDComponentElement = ElementEdit(event.currentTarget).element;
370                        _firstComponent.removeElement(elem);
371                        removeChild(event.currentTarget as DisplayObject);
372                }
373               
374                private function createStartOverButton():Label {
375                        var startOverButton:Label = new RemoveLabelButton();
376                        startOverButton.addEventListener(MouseEvent.CLICK, clearEditorHandler);
377                        startOverButton.toolTip = "Clears all input and removes added components";
378                        startOverButton.text = "start over";
379                        return startOverButton;
380                }
381        }
382}
Note: See TracBrowser for help on using the repository browser.