Commit 7d500cf67b108657e24df3bfaa5a0c3c26de9fe2

Authored by Nathanaël Jourdane
1 parent 36904910

fix indentation

Showing 2 changed files with 1745 additions and 1829 deletions   Show diff stats
js/app/models/InteractiveNode.js
1   -/**
  1 +/**
2 2 * Project : AMDA-NG4
3 3 * Name : InteractiveNode.js
4 4 * @class amdaModel.InteractiveNode
... ... @@ -9,530 +9,515 @@
9 9 */
10 10  
11 11 Ext.define('amdaModel.InteractiveNode', {
12   - extend: 'amdaModel.AmdaNode',
13   -
14   - requires: [
15   - 'amdaPlotObj.PlotRequestObject'
16   - ],
17   -
18   - fields: [
19   - {name: 'contextNode', type: 'amdaModel.AmdaNode', persist: false},
20   - {name: 'objectDataModel', type: 'string', persist: false},
21   - {name: 'object', type: 'object', persist: false},
22   - {name: 'moduleId', type: 'string', persist: false},
23   - {name: 'filtered', type: 'boolean', defaultValue: false, persist: false},
24   - {name: 'disable', type: 'boolean', defaultValue: false, persist: false}
25   - ],
26   -
27   - statics: {
28   - preloadNodes : function(node,onready)
29   - {
30   - var me = this;
31   -
32   - var nodesToLoad = new Array();
33   - nodesToLoad.push(node);
34   - this.preloadTreeNode(node, nodesToLoad, function (node)
35   - {
36   - var isFinish = true;
37   - nodesToLoad.forEach(function (element, index, array)
38   - {
39   - if (!element.isLoaded())
40   - isFinish = false;
41   - });
42   - if (isFinish && onready)
43   - onready.call();
44   - });
45   - },
46   -
47   - preloadTreeNode : function(node, nodesToLoad, onloaded)
48   - {
49   - var me = this;
50   -
51   - if (node.isLoaded())
52   - {
53   - node.eachChild(function(n)
54   - {
55   - if (!n.isLoaded() && !n.isLeaf())
56   - {
57   - nodesToLoad.push(n);
58   - me.preloadTreeNode(n,nodesToLoad,onloaded);
59   - }
60   - });
61   -
62   - if (onloaded)
63   - onloaded.call(me,node);
64   - return;
65   - }
66   -
67   - node.store.load({
68   - node : node,
69   - callback : function(records, operation, successful)
70   - {
71   - records.forEach(function (record)
72   - {
73   - if (!record.isLoaded() && !record.isLeaf())
74   - {
75   - nodesToLoad.push(record);
76   - me.preloadTreeNode(record,nodesToLoad,onloaded);
77   - }
78   - });
79   - if (onloaded)
80   - onloaded.call(me,node);
81   - }
82   - });
83   - }
84   - },
85   -
86   - onReady : null,
87   -
88   - constructor : function(config)
89   - {
90   - this.callParent(arguments);
91   - this.set('nodeType',this.self.nodeType);
92   - this.set('ownerTreeId',amdaUI.ExplorerUI.RESRC_TAB.TREE_ID);
93   - if (this.get('id')) { // TODO why sometimes (delete in remote interoper tree) this.get('id') = undefined ?
94   - // if id of this node have root category suffix
95   - if (Ext.util.Format.substr(this.get('id'), -(amdaUI.ExplorerUI.CAT_SUFFIX.length), this.get('id').length) === amdaUI.ExplorerUI.CAT_SUFFIX)
96   - {
97   - // set the expanded property to true
98   - this.set('expanded',true);
99   - }
100   - }
101   - },
102   -
103   -/**
104   -* this method is overriden into ExecutableNode to return true
105   -*/
106   - isExecutable: function()
107   - {
108   - return false;
109   - },
  12 + extend: 'amdaModel.AmdaNode',
110 13  
111   -/**
112   -* open Module with THIS NODE
113   -*/
114   - editInModule : function (contextNode, onReady)
115   - {
116   - // set the contextNode of this node
117   - this.set('contextNode',contextNode);
118   - // parameter module
119   - var me = this;
120   - myDesktopApp.getLoadedModule(this.get('moduleId'),true, function (module) {
121   - // If the node to edit is not already linked to this module
122   - if (module.getLinkedNode() != me)
123   - {
124   - // set relative node into parameter Module
125   - module.setLinkedNode(me);
126   - if (contextNode==null)
127   - {
128   - // set the root node as contextNode
129   - contextNode = me.getRootNode();
130   - }
131   - module.setContextNode(contextNode);
132   -
133   - } else if (module.getLinkedNode() != null){
134   - //TODO the node to edit is already edited
135   - // myDesktopApp.warningMsg('This object is being edited');
136   - //Sol1: msg alert: "warning this node is already edited! If you want to get the original, please press the 'reset' button"->'OK'
137   - //Sol2: msg with user choice: "warning this node is already edited! Would you confirm this action and lost your modification?"->'Confirm','Cancel'
138   - }
139   - // Opening parameter window
140   - module.createWindow(onReady);
141   - });
142   - },
  14 + requires: [
  15 + 'amdaPlotObj.PlotRequestObject'
  16 + ],
143 17  
144   -/**
145   -* Method to rename the workspace node
146   -*/
147   - rename: function(value,callBackFn)
148   - {
149   - var dataToSend = {id : this.get('id'), old_name: this.modified.text, name: value, parent : this.parentNode.get('id'), leaf: this.isLeaf(), nodeType: this.get('nodeType')};
150   - AmdaAction.renameObject(dataToSend, callBackFn);
151   - },
152   -
153   -/**
154   -* Method to rename the workspace node when D&D
155   -*/
156   - renameDD: function(parentId, callBackFn)
157   - {
158   - var dataToSend = {id : this.get('id'), old_name: this.get('name'), name: this.get('name'), parent : parentId, leaf: this.isLeaf(), nodeType: this.get('nodeType')};
159   - AmdaAction.renameObject(dataToSend, callBackFn);
160   - },
161   -
162   -/**
163   -* validation method on name (used in module forms)
164   -* @param name the name to validate
165   -* @returns
166   -*/
167   - isValidName : function(name, callBackFn)
168   - {
169   - var dataToSend = {name: name, nodeType: this.get('nodeType'), leaf: this.isLeaf()};
170   - AmdaAction.validNameObject(dataToSend, callBackFn);
171   - },
  18 + fields: [
  19 + {name: 'contextNode', type: 'amdaModel.AmdaNode', persist: false},
  20 + {name: 'objectDataModel', type: 'string', persist: false},
  21 + {name: 'object', type: 'object', persist: false},
  22 + {name: 'moduleId', type: 'string', persist: false},
  23 + {name: 'filtered', type: 'boolean', defaultValue: false, persist: false},
  24 + {name: 'disable', type: 'boolean', defaultValue: false, persist: false}
  25 + ],
172 26  
173   -/**
174   -* Method to persist modifications of an AmdaObject by Server side and update the workspace
175   -* node linked to a Module
176   -*/
177   - update : function(opt)
178   - {
179   - AmdaAction.modifyObject(this.get('object').getJsonValues(true), function(res,e){
180   -
181   - if(e.status) {
182   - if (res.id) {
183   - if (!this.get('contextNode')) {
184   - // set the root node of 'Derived Parameters' tree as contextNode
185   - this.set('contextNode',this.getRootNode());
186   - }
187   - this.get('contextNode').expand(false,false);
188   - this.myGetOwnerTree().getSelectionModel().select(this);
189   -
190   - if (opt)
191   - {
192   - var scope = opt.scope ? opt.scope : this;
193   - if (opt.callback)
194   - opt.callback.call(scope,'update');
195   - }
196   -
197   - Ext.Msg.alert('Complete', 'Object '+this.get('object').get('name')+' has been modified');
198   - // fix the modifications for object
199   - this.get('object').commit();
200   -
201   - if (res.info) {
202   - this.set('info',res.info);
203   - }
204   -
205   - if (this.get('nodeType') == 'myDataParam') {
206   - if (res.isSpectra) {
207   - this.set('iconCls', 'icon-spectra');
208   - }
209   - else {
210   - if (res.size > 1) this.set('iconCls', 'icon-unknowntype');
211   - }
212   - }
213   -
214   - // update my data on possibble mask change
215   - if (res.updateMyData) {
216   - this.updateMyData();
217   - this.updateMask(res.mask);
218   - }
219   - // reload object into the view of corresponding Module
220   - var me = this;
221   - myDesktopApp.getLoadedModule(this.get('moduleId'), true, function (module) {
222   - module.getUiContent().setObject(me.get('object'));
223   - });
224   - }
225   - else {
226   - //TODO proper error message handling
227   - // error code from server; but e.status==true
228   - // revert all modifications since last load or commit
229   - this.get('object').reject();
230   - myDesktopApp.errorMsg(res.error);
231   - }
232   - }
233   - else {
234   - // revert all modifications since last load or commit
235   - this.get('object').reject();
236   - myDesktopApp.errorMsg(e.message);
237   - }
238   - },this);
239   - },
  27 + statics: {
  28 + preloadNodes: function (node, onready) {
  29 + var me = this;
240 30  
241   -/**
242   -* Method to create a new AmdaObject by server side and create the workspace node linked to a Module
243   -* under its contextNode or the root node corresponding to this nodeType category
244   -*/
245   - create : function(opt)
246   - {
247   - if (!this.get('contextNode') || (this.get('contextNode').data.id == 'sharedtimeTable-treeRootNode') || (this.get('contextNode').data.id == 'sharedcatalog-treeRootNode')) {
248   - // set the root node of 'Derived Parameters' tree as contextNode
249   - this.set('contextNode',this.getRootNode());
250   - }
251   - // call the Ext.Direct method to create parameter
252   - AmdaAction.createObject(this.get('object').getJsonValues(false), this.get('contextNode').get('id'), function(res,e){
253   - //success
254   - if(e.status)
255   - {
256   - // if correct response received
257   - if (res.id) { //if (res.id || res.error == 'NAME_EXISTS') {
258   - // 'save as' case ; delete old node if it exists
259   - if (this.toRename)
260   - {
261   - this.toRename = false;
262   - var myRoot = this.getRootNode();
263   - // search the same named node to override
264   - var updateNode = myRoot.findChild('text',this.get('object').get('name'),true);
265   - // destroy the overrided node
266   - updateNode.parentNode.removeChild(updateNode);//TODO ??if destroy==true => too many recursions....
267   - updateNode.destroy();
268   - }
269   - // set text of this node
270   - this.set('text',this.get('object').get('name'));
271   - //set id of this node
272   - this.set('id',res.id);
273   - this.internalId = res.id;
274   - // set id of node's object
275   - this.get('object').set('id',res.id);
276   -
277   - if (res.created){
278   - // set the created date
279   - this.get('object').set('created',res.created);
280   - }
281   -
282   - if (res.info){
283   - // set the tooltip
284   - this.set('info',res.info);
285   - //set globalStart & global Stop to be used for time selection
286   - if (this.get('nodeType') == 'myDataParam')
287   - {
288   - var startStop = res.info.split("<br/>");
289   - var globalStart = startStop[1].substr(0,19);
290   - var globalStop = startStop[1].substr(20);
291   -
292   - this.set('globalStart', globalStart);
293   - this.set('globalStop', globalStop);
294   -
295   - if (res.mask)
296   - this.set('linkedMask', res.mask);
297   - if (res.size)
298   - this.set('size', res.size);
299   -
300   - if (res.isSpectra) {
301   - this.set('iconCls', 'icon-spectra');
302   - }
303   - else {
304   - if (res.size > 1)
305   - this.set('iconCls', 'icon-unknowntype');
306   - }
307   - }
308   - }
309   - //TODO do we need this commission ???
310   - // fix the modifications for object
311   - this.get('object').commit();
312   - // if ownerTree panel is not active
313   - if (this.myGetOwnerTree().ownerCt.getActiveTab()!==this.myGetOwnerTree())
314   - {
315   - // set ownerTree panel as the active tab - to enable selection of this node his ownerTree must have a view
316   - this.myGetOwnerTree().ownerCt.setActiveTab(this.myGetOwnerTree());
317   - }
318   -
319   - Ext.Msg.alert('Complete', 'New object '+this.get('object').get('name')+' has been created');
320   - // expand the contextNode
321   - this.get('contextNode').expand(false, function()
322   - {
323   - if (!this.get('contextNode').findChild('text',this.get('text'))) {
324   - // create node in tree as child of contextNode
325   - this.get('contextNode').appendChild(this);
326   - }
327   - // select the new node
328   - this.myGetOwnerTree().getSelectionModel().select(this);
329   - if (opt)
330   - {
331   - var scope = opt.scope ? opt.scope : this;
332   - if (opt.callback)
333   - opt.callback.call(scope,'create');
334   - }
335   - }, this);
336   -
337   - // myDataParamNode - update MyData subtree
338   - //TODO put this in mydataparamnode
339   - if (res.updateMyData) {
340   - this.updateMyData();
341   - this.updateMask(res.mask);
342   - }
343   -
344   - }
345   - // error code from server; but e.status==true
346   - else {
347   - myDesktopApp.errorMsg(res.error);
348   - // revert all modifications since last load or commit
349   - this.get('object').reject();
350   - }
351   - }
352   - // failure: e.status == false
353   - else {
354   - // revert all modifications since last load or commit
355   - this.get('object').reject();
356   - //TODO: this.destroy();
357   - myDesktopApp.errorMsg(e.message);
358   - }
359   - },this);
360   - },
  31 + var nodesToLoad = [];
  32 + nodesToLoad.push(node);
  33 + this.preloadTreeNode(node, nodesToLoad, function (node) {
  34 + var isFinish = true;
  35 + nodesToLoad.forEach(function (element, index, array) {
  36 + if (!element.isLoaded())
  37 + isFinish = false;
  38 + });
  39 + if (isFinish && onready)
  40 + onready.call();
  41 + });
  42 + },
361 43  
362   -/**
363   -* Generic part of Context Menu
364   -*
365   -*/
366   - allMenuItems : function() {
367   - var src = this.self.objectName;
368   - var menuItems =
369   - [ {
370   - fnId : 'root-createLeaf',
371   - text : 'Create '+ src
372   - }, {
373   - fnId : 'root-createDir',
374   - text : 'Create Folder'
375   - }, {
376   - fnId : 'dire-createLeaf',
377   - text : 'Create ' + src
378   - }, {
379   - fnId : 'dire-createDir',
380   - text : 'Create Folder'
381   - }, {
382   - fnId : 'dire-renameNode',
383   - text : 'Rename Folder'
384   - }, {
385   - fnId : 'dire-deleteNode',
386   - text : 'Delete Folder'
387   - }, {
388   - fnId : 'leaf-editLeaf',
389   - text : 'Edit ' + src
390   - }, {
391   - fnId : 'leaf-renameNode',
392   - text : 'Rename ' + src
393   - }, {
394   - fnId : 'leaf-deleteNode',
395   - text : 'Delete '+ src
396   - } ];
397   - return menuItems;
398   - },
399   -
400   - allMenuMultiItems : function() {
401   - var menuMulti = [
402   - {
403   - fnId : 'mult-deleteMulti',
404   - text : 'Delete selected ' + this.self.objectName + 's'
405   - }
406   - ];
407   - return menuMulti;
408   - },
409   -
410   - getAllContextMenuItems: function(){
411   - return this.allMenuItems();
412   - },
413   -
414   - getMultiContextMenuItems: function(){
415   - return this.allMenuMultiItems();
416   - },
417   -
418   -/**
419   -* default implementation
420   -* no menu display if there's no override of this function
421   -*/
422   - getMultiContextMenuItems: function(){
423   - return null;
424   - },
425   -
426   -/**
427   -* Context Menu Actions
428   -*
429   -*/
430   - onMenuItemClick : function(menu,item,event) {
431   - // fnId parsing :
432   - var fnId = Ext.util.Format.substr(item.fnId, 5, item.fnId.length);
433   -
434   - switch (fnId) {
435   - case 'deleteNode':
436   - this.deleteNode();
437   - break;
438   - case 'createDir':
439   - this.createDir();
440   - break;
441   - case 'createLeaf':
442   - this.createLeaf(this);
443   - break;
444   - case 'renameNode':
445   - this.renameNode();
446   - break;
447   - case 'editLeaf':
448   - this.editLeaf();
449   - break;
450   - case 'deleteMulti':
451   - this.deleteMulti();
452   - break;
453   - case 'plotParam':
454   - this.createPlot(this);
455   - break;
456   - case 'downParam':
457   - this.createDownload(this);
458   - break;
459   - default:
460   - break;
461   - } // switch end
462   - },
463   -
464   - getTimeFromNode: function(node) {
465   - var startString = new String(node.get('globalStart'));
466   - var stopString = new String(node.get('globalStop'));
467   -
468   - var startDate = new Date(startString.replace(/\-/g,'\/').replace(/[T|Z]/g,' '));
469   - var stopDate = new Date(stopString.replace(/\-/g,'\/').replace(/[T|Z]/g,' '));
470   -
471   - if (stopDate - startDate > 86400000 ) {
472   - var startTime = Ext.Date.add(stopDate, Ext.Date.DAY, -1);
473   - // var timeObj = {start: Ext.Date.format(startTime, 'Y/m/d H:i:s'), stop: Ext.Date.format(stopDate, 'Y/m/d H:i:s')};
474   - var timeObj = {start: Ext.Date.format(startTime, 'Y/m/d'), stop: Ext.Date.format(stopDate, 'Y/m/d')};
475   - }
476   - else {
477   - var timeObj = {start: node.get('globalStart'), stop: node.get('globalStop')};
478   - }
479   - return timeObj;
480   - },
481   -
482   - createPlot: function(node)
483   - {
484   - if (node.get('disable')) return;
485   - myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.plot.id, true, function (module) {
486   - if (!myDesktopApp.desktop.getWindow(myDesktopApp.dynamicModules.plot.id)) {
487   - var request = Ext.create(amdaPlotObj.PlotRequestObject.$className);
488   - var newNode = Ext.create(amdaModel.PlotNode.$className, { object : request });
489   - // edit newNode into Plot Module with node as contextNode
490   - newNode.editInModule();
491   - if((node.get('globalStart') != null) && (node.get('globalStop') != null) && node.get('globalStart') != 'depending on mission' && node.get('isParameter')) {
492   - module.getUiContent().setTimeFromData(node.getTimeFromNode(node));
493   - }
494   - }
495   - module.getUiContent().addParameter(node);
496   - });
497   - },
498   -
499   - createDownload: function(node)
500   - {
501   - if (node.get('disable')) return;
502   -
503   - if (node.get('notyet')) {
504   - myDesktopApp.warningMsg('Sorry! access to this parameter is restricted.');
505   - return;
506   - }
507   -
508   - myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.download.id, true, function (module) {
509   - if (!myDesktopApp.desktop.getWindow(myDesktopApp.dynamicModules.download.id)) {
510   - var request = Ext.create(amdaModel.Download.$className);
511   - amdaModel.DownloadNode.set('object',request);
512   - // singleton!
513   - amdaModel.DownloadNode.editInModule();
514   - if ((node.get('globalStart') != null) && (node.get('globalStop') != null) && node.get('globalStart') != 'depending on mission' && node.get('isParameter')) {
515   - module.getUiContent().setTimeFromData(node.getTimeFromNode(node));
516   - }
517   - }
518   - var paramName;
519   - var components = null;
520   - switch (node.$className) {
521   - case 'amdaModel.AliasNode' :
522   - paramName = "#"+node.get('text');
523   - break;
524   - case 'amdaModel.DerivedParamNode' :
525   - paramName = "ws_"+node.get('text');
526   - break;
527   - case 'amdaModel.MyDataParamNode' :
528   - paramName = 'wsd_'+node.get('text');
529   - break;
530   - default :
531   - if (node.get('alias')!= "" )
532   - paramName = "#"+node.get('alias');
533   - else
534   - paramName = node.get('id');
535   - }
  44 + preloadTreeNode: function (node, nodesToLoad, onloaded) {
  45 + var me = this;
  46 +
  47 + if (node.isLoaded()) {
  48 + node.eachChild(function (n) {
  49 + if (!n.isLoaded() && !n.isLeaf()) {
  50 + nodesToLoad.push(n);
  51 + me.preloadTreeNode(n, nodesToLoad, onloaded);
  52 + }
  53 + });
  54 +
  55 + if (onloaded)
  56 + onloaded.call(me, node);
  57 + return;
  58 + }
  59 +
  60 + node.store.load({
  61 + node: node,
  62 + callback: function (records, operation, successful) {
  63 + records.forEach(function (record) {
  64 + if (!record.isLoaded() && !record.isLeaf()) {
  65 + nodesToLoad.push(record);
  66 + me.preloadTreeNode(record, nodesToLoad, onloaded);
  67 + }
  68 + });
  69 + if (onloaded)
  70 + onloaded.call(me, node);
  71 + }
  72 + });
  73 + }
  74 + },
  75 +
  76 + onReady: null,
  77 +
  78 + constructor: function (config) {
  79 + this.callParent(arguments);
  80 + this.set('nodeType', this.self.nodeType);
  81 + this.set('ownerTreeId', amdaUI.ExplorerUI.RESRC_TAB.TREE_ID);
  82 + if (this.get('id')) { // TODO why sometimes (delete in remote interoper tree) this.get('id') = undefined ?
  83 + // if id of this node have root category suffix
  84 + if (Ext.util.Format.substr(this.get('id'), -(amdaUI.ExplorerUI.CAT_SUFFIX.length), this.get('id').length) === amdaUI.ExplorerUI.CAT_SUFFIX) {
  85 + // set the expanded property to true
  86 + this.set('expanded', true);
  87 + }
  88 + }
  89 + },
  90 +
  91 + /**
  92 + * this method is overriden into ExecutableNode to return true
  93 + */
  94 + isExecutable: function () {
  95 + return false;
  96 + },
  97 +
  98 + /**
  99 + * open Module with THIS NODE
  100 + */
  101 + editInModule: function (contextNode, onReady) {
  102 + // set the contextNode of this node
  103 + this.set('contextNode', contextNode);
  104 + // parameter module
  105 + var me = this;
  106 + myDesktopApp.getLoadedModule(this.get('moduleId'), true, function (module) {
  107 + // If the node to edit is not already linked to this module
  108 + if (module.getLinkedNode() != me) {
  109 + // set relative node into parameter Module
  110 + module.setLinkedNode(me);
  111 + if (contextNode == null) {
  112 + // set the root node as contextNode
  113 + contextNode = me.getRootNode();
  114 + }
  115 + module.setContextNode(contextNode);
  116 +
  117 + } else if (module.getLinkedNode() != null) {
  118 + //TODO the node to edit is already edited
  119 + // myDesktopApp.warningMsg('This object is being edited');
  120 + //Sol1: msg alert: "warning this node is already edited! If you want to get the original, please press the 'reset' button"->'OK'
  121 + //Sol2: msg with user choice: "warning this node is already edited! Would you confirm this action and lost your modification?"->'Confirm','Cancel'
  122 + }
  123 + // Opening parameter window
  124 + module.createWindow(onReady);
  125 + });
  126 + },
  127 +
  128 + /**
  129 + * Method to rename the workspace node
  130 + */
  131 + rename: function (value, callBackFn) {
  132 + var dataToSend = {
  133 + id: this.get('id'),
  134 + old_name: this.modified.text,
  135 + name: value,
  136 + parent: this.parentNode.get('id'),
  137 + leaf: this.isLeaf(),
  138 + nodeType: this.get('nodeType')
  139 + };
  140 + AmdaAction.renameObject(dataToSend, callBackFn);
  141 + },
  142 +
  143 + /**
  144 + * Method to rename the workspace node when D&D
  145 + */
  146 + renameDD: function (parentId, callBackFn) {
  147 + var dataToSend = {
  148 + id: this.get('id'),
  149 + old_name: this.get('name'),
  150 + name: this.get('name'),
  151 + parent: parentId,
  152 + leaf: this.isLeaf(),
  153 + nodeType: this.get('nodeType')
  154 + };
  155 + AmdaAction.renameObject(dataToSend, callBackFn);
  156 + },
  157 +
  158 + /**
  159 + * validation method on name (used in module forms)
  160 + * @param name the name to validate
  161 + * @returns
  162 + */
  163 + isValidName: function (name, callBackFn) {
  164 + var dataToSend = {name: name, nodeType: this.get('nodeType'), leaf: this.isLeaf()};
  165 + AmdaAction.validNameObject(dataToSend, callBackFn);
  166 + },
  167 +
  168 + /**
  169 + * Method to persist modifications of an AmdaObject by Server side and update the workspace
  170 + * node linked to a Module
  171 + */
  172 + update: function (opt) {
  173 + AmdaAction.modifyObject(this.get('object').getJsonValues(true), function (res, e) {
  174 +
  175 + if (e.status) {
  176 + if (res.id) {
  177 + if (!this.get('contextNode')) {
  178 + // set the root node of 'Derived Parameters' tree as contextNode
  179 + this.set('contextNode', this.getRootNode());
  180 + }
  181 + this.get('contextNode').expand(false, false);
  182 + this.myGetOwnerTree().getSelectionModel().select(this);
  183 +
  184 + if (opt) {
  185 + var scope = opt.scope ? opt.scope : this;
  186 + if (opt.callback)
  187 + opt.callback.call(scope, 'update');
  188 + }
  189 +
  190 + Ext.Msg.alert('Complete', 'Object ' + this.get('object').get('name') + ' has been modified');
  191 + // fix the modifications for object
  192 + this.get('object').commit();
  193 +
  194 + if (res.info) {
  195 + this.set('info', res.info);
  196 + }
  197 +
  198 + if (this.get('nodeType') == 'myDataParam') {
  199 + if (res.isSpectra) {
  200 + this.set('iconCls', 'icon-spectra');
  201 + }
  202 + else {
  203 + if (res.size > 1) this.set('iconCls', 'icon-unknowntype');
  204 + }
  205 + }
  206 +
  207 + // update my data on possibble mask change
  208 + if (res.updateMyData) {
  209 + this.updateMyData();
  210 + this.updateMask(res.mask);
  211 + }
  212 + // reload object into the view of corresponding Module
  213 + var me = this;
  214 + myDesktopApp.getLoadedModule(this.get('moduleId'), true, function (module) {
  215 + module.getUiContent().setObject(me.get('object'));
  216 + });
  217 + }
  218 + else {
  219 + //TODO proper error message handling
  220 + // error code from server; but e.status==true
  221 + // revert all modifications since last load or commit
  222 + this.get('object').reject();
  223 + myDesktopApp.errorMsg(res.error);
  224 + }
  225 + }
  226 + else {
  227 + // revert all modifications since last load or commit
  228 + this.get('object').reject();
  229 + myDesktopApp.errorMsg(e.message);
  230 + }
  231 + }, this);
  232 + },
  233 +
  234 + /**
  235 + * Method to create a new AmdaObject by server side and create the workspace node linked to a Module
  236 + * under its contextNode or the root node corresponding to this nodeType category
  237 + */
  238 + create: function (opt) {
  239 + if (!this.get('contextNode') || (this.get('contextNode').data.id == 'sharedtimeTable-treeRootNode') || (this.get('contextNode').data.id == 'sharedcatalog-treeRootNode')) {
  240 + // set the root node of 'Derived Parameters' tree as contextNode
  241 + this.set('contextNode', this.getRootNode());
  242 + }
  243 + // call the Ext.Direct method to create parameter
  244 + AmdaAction.createObject(this.get('object').getJsonValues(false), this.get('contextNode').get('id'), function (res, e) {
  245 + //success
  246 + if (e.status) {
  247 + // if correct response received
  248 + if (res.id) { //if (res.id || res.error == 'NAME_EXISTS') {
  249 + // 'save as' case ; delete old node if it exists
  250 + if (this.toRename) {
  251 + this.toRename = false;
  252 + var myRoot = this.getRootNode();
  253 + // search the same named node to override
  254 + var updateNode = myRoot.findChild('text', this.get('object').get('name'), true);
  255 + // destroy the overrided node
  256 + updateNode.parentNode.removeChild(updateNode);//TODO ??if destroy==true => too many recursions....
  257 + updateNode.destroy();
  258 + }
  259 + // set text of this node
  260 + this.set('text', this.get('object').get('name'));
  261 + //set id of this node
  262 + this.set('id', res.id);
  263 + this.internalId = res.id;
  264 + // set id of node's object
  265 + this.get('object').set('id', res.id);
  266 +
  267 + if (res.created) {
  268 + // set the created date
  269 + this.get('object').set('created', res.created);
  270 + }
  271 +
  272 + if (res.info) {
  273 + // set the tooltip
  274 + this.set('info', res.info);
  275 + //set globalStart & global Stop to be used for time selection
  276 + if (this.get('nodeType') == 'myDataParam') {
  277 + var startStop = res.info.split("<br/>");
  278 + var globalStart = startStop[1].substr(0, 19);
  279 + var globalStop = startStop[1].substr(20);
  280 +
  281 + this.set('globalStart', globalStart);
  282 + this.set('globalStop', globalStop);
  283 +
  284 + if (res.mask)
  285 + this.set('linkedMask', res.mask);
  286 + if (res.size)
  287 + this.set('size', res.size);
  288 +
  289 + if (res.isSpectra) {
  290 + this.set('iconCls', 'icon-spectra');
  291 + }
  292 + else {
  293 + if (res.size > 1)
  294 + this.set('iconCls', 'icon-unknowntype');
  295 + }
  296 + }
  297 + }
  298 + //TODO do we need this commission ???
  299 + // fix the modifications for object
  300 + this.get('object').commit();
  301 + // if ownerTree panel is not active
  302 + if (this.myGetOwnerTree().ownerCt.getActiveTab() !== this.myGetOwnerTree()) {
  303 + // set ownerTree panel as the active tab - to enable selection of this node his ownerTree must have a view
  304 + this.myGetOwnerTree().ownerCt.setActiveTab(this.myGetOwnerTree());
  305 + }
  306 +
  307 + Ext.Msg.alert('Complete', 'New object ' + this.get('object').get('name') + ' has been created');
  308 + // expand the contextNode
  309 + this.get('contextNode').expand(false, function () {
  310 + if (!this.get('contextNode').findChild('text', this.get('text'))) {
  311 + // create node in tree as child of contextNode
  312 + this.get('contextNode').appendChild(this);
  313 + }
  314 + // select the new node
  315 + this.myGetOwnerTree().getSelectionModel().select(this);
  316 + if (opt) {
  317 + var scope = opt.scope ? opt.scope : this;
  318 + if (opt.callback)
  319 + opt.callback.call(scope, 'create');
  320 + }
  321 + }, this);
  322 +
  323 + // myDataParamNode - update MyData subtree
  324 + //TODO put this in mydataparamnode
  325 + if (res.updateMyData) {
  326 + this.updateMyData();
  327 + this.updateMask(res.mask);
  328 + }
  329 +
  330 + }
  331 + // error code from server; but e.status==true
  332 + else {
  333 + myDesktopApp.errorMsg(res.error);
  334 + // revert all modifications since last load or commit
  335 + this.get('object').reject();
  336 + }
  337 + }
  338 + // failure: e.status == false
  339 + else {
  340 + // revert all modifications since last load or commit
  341 + this.get('object').reject();
  342 + //TODO: this.destroy();
  343 + myDesktopApp.errorMsg(e.message);
  344 + }
  345 + }, this);
  346 + },
  347 +
  348 + /**
  349 + * Generic part of Context Menu
  350 + *
  351 + */
  352 + allMenuItems: function () {
  353 + var src = this.self.objectName;
  354 + var menuItems = [
  355 + {
  356 + fnId: 'root-createLeaf',
  357 + text: 'Create ' + src
  358 + }, {
  359 + fnId: 'root-createDir',
  360 + text: 'Create Folder'
  361 + }, {
  362 + fnId: 'dire-createLeaf',
  363 + text: 'Create ' + src
  364 + }, {
  365 + fnId: 'dire-createDir',
  366 + text: 'Create Folder'
  367 + }, {
  368 + fnId: 'dire-renameNode',
  369 + text: 'Rename Folder'
  370 + }, {
  371 + fnId: 'dire-deleteNode',
  372 + text: 'Delete Folder'
  373 + }, {
  374 + fnId: 'leaf-editLeaf',
  375 + text: 'Edit ' + src
  376 + }, {
  377 + fnId: 'leaf-renameNode',
  378 + text: 'Rename ' + src
  379 + }, {
  380 + fnId: 'leaf-deleteNode',
  381 + text: 'Delete ' + src
  382 + }
  383 + ];
  384 + return menuItems;
  385 + },
  386 +
  387 + allMenuMultiItems: function () {
  388 + var menuMulti = [
  389 + {
  390 + fnId: 'mult-deleteMulti',
  391 + text: 'Delete selected ' + this.self.objectName + 's'
  392 + }
  393 + ];
  394 + return menuMulti;
  395 + },
  396 +
  397 + getAllContextMenuItems: function () {
  398 + return this.allMenuItems();
  399 + },
  400 +
  401 + getMultiContextMenuItems: function () {
  402 + return this.allMenuMultiItems();
  403 + },
  404 +
  405 + /**
  406 + * default implementation
  407 + * no menu display if there's no override of this function
  408 + */
  409 + getMultiContextMenuItems: function () {
  410 + return null;
  411 + },
  412 +
  413 + /**
  414 + * Context Menu Actions
  415 + *
  416 + */
  417 + onMenuItemClick: function (menu, item, event) {
  418 + // fnId parsing :
  419 + var fnId = Ext.util.Format.substr(item.fnId, 5, item.fnId.length);
  420 +
  421 + switch (fnId) {
  422 + case 'deleteNode':
  423 + this.deleteNode();
  424 + break;
  425 + case 'createDir':
  426 + this.createDir();
  427 + break;
  428 + case 'createLeaf':
  429 + this.createLeaf(this);
  430 + break;
  431 + case 'renameNode':
  432 + this.renameNode();
  433 + break;
  434 + case 'editLeaf':
  435 + this.editLeaf();
  436 + break;
  437 + case 'deleteMulti':
  438 + this.deleteMulti();
  439 + break;
  440 + case 'plotParam':
  441 + this.createPlot(this);
  442 + break;
  443 + case 'downParam':
  444 + this.createDownload(this);
  445 + break;
  446 + default:
  447 + break;
  448 + } // switch end
  449 + },
  450 +
  451 + getTimeFromNode: function (node) {
  452 + var startString = String(node.get('globalStart'));
  453 + var stopString = String(node.get('globalStop'));
  454 +
  455 + var startDate = new Date(startString.replace(/\-/g, '\/').replace(/[T|Z]/g, ' '));
  456 + var stopDate = new Date(stopString.replace(/\-/g, '\/').replace(/[T|Z]/g, ' '));
  457 +
  458 + if (stopDate - startDate > 86400000) {
  459 + var startTime = Ext.Date.add(stopDate, Ext.Date.DAY, -1);
  460 + // var timeObj = {start: Ext.Date.format(startTime, 'Y/m/d H:i:s'), stop: Ext.Date.format(stopDate, 'Y/m/d H:i:s')};
  461 + var timeObj = {start: Ext.Date.format(startTime, 'Y/m/d'), stop: Ext.Date.format(stopDate, 'Y/m/d')};
  462 + }
  463 + else {
  464 + var timeObj = {start: node.get('globalStart'), stop: node.get('globalStop')};
  465 + }
  466 + return timeObj;
  467 + },
  468 +
  469 + createPlot: function (node) {
  470 + if (node.get('disable')) return;
  471 + myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.plot.id, true, function (module) {
  472 + if (!myDesktopApp.desktop.getWindow(myDesktopApp.dynamicModules.plot.id)) {
  473 + var request = Ext.create(amdaPlotObj.PlotRequestObject.$className);
  474 + var newNode = Ext.create(amdaModel.PlotNode.$className, {object: request});
  475 + // edit newNode into Plot Module with node as contextNode
  476 + newNode.editInModule();
  477 + if ((node.get('globalStart') != null) && (node.get('globalStop') != null) && node.get('globalStart') != 'depending on mission' && node.get('isParameter')) {
  478 + module.getUiContent().setTimeFromData(node.getTimeFromNode(node));
  479 + }
  480 + }
  481 + module.getUiContent().addParameter(node);
  482 + });
  483 + },
  484 +
  485 + createDownload: function (node) {
  486 + if (node.get('disable')) return;
  487 +
  488 + if (node.get('notyet')) {
  489 + myDesktopApp.warningMsg('Sorry! access to this parameter is restricted.');
  490 + return;
  491 + }
  492 +
  493 + myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.download.id, true, function (module) {
  494 + if (!myDesktopApp.desktop.getWindow(myDesktopApp.dynamicModules.download.id)) {
  495 + var request = Ext.create(amdaModel.Download.$className);
  496 + amdaModel.DownloadNode.set('object', request);
  497 + // singleton!
  498 + amdaModel.DownloadNode.editInModule();
  499 + if ((node.get('globalStart') != null) && (node.get('globalStop') != null) && node.get('globalStart') != 'depending on mission' && node.get('isParameter')) {
  500 + module.getUiContent().setTimeFromData(node.getTimeFromNode(node));
  501 + }
  502 + }
  503 + var paramName;
  504 + var components = null;
  505 + switch (node.$className) {
  506 + case 'amdaModel.AliasNode' :
  507 + paramName = "#" + node.get('text');
  508 + break;
  509 + case 'amdaModel.DerivedParamNode' :
  510 + paramName = "ws_" + node.get('text');
  511 + break;
  512 + case 'amdaModel.MyDataParamNode' :
  513 + paramName = 'wsd_' + node.get('text');
  514 + break;
  515 + default :
  516 + if (node.get('alias') != "")
  517 + paramName = "#" + node.get('alias');
  518 + else
  519 + paramName = node.get('id');
  520 + }
536 521 // var component_info = node.get('component_info');
537 522 // if (component_info && component_info.parentId) {
538 523 // //It's a component
... ... @@ -543,263 +528,248 @@ Ext.define(&#39;amdaModel.InteractiveNode&#39;, {
543 528 // if (component_info.index2)
544 529 // components['index2'] = component_info.index2;
545 530 // }
546   - module.addParam(paramName,true,node.get('needsArgs'),components);
547   - });
548   - },
549   -
550   - deleteNode: function() {
551   - // if the target is a directory
552   - if (!this.isLeaf()) {
553   - // determine if this directory is empty before launching the delete confirmation method
554   - this.isNotEmptyDir(this.confirmDirectoryDeletion);
555   - // else (the target is a leaf)
556   - } else {
557   - // no confirmation prompt for leaves
558   - this.confirmDirectoryDeletion(false);
559   - }
560   - },
561   -
562   -/**
563   -* this method return if node has Childs even if it was not already loaded
564   -*/
565   - isNotEmptyDir : function(callbackFn) {
566   - var hasChilds;
567   - // if node not already loaded
568   - if (!this.isLoaded()){
569   - // call directFunction to load this node
570   - AmdaAction.getTree({node:this.get('id'),nodeType:this.get('nodeType')},function(res,e){
571   - callbackFn.call(this,res.length>0?true:false);
572   - },this);
573   - }
574   - else {
575   - callbackFn.call(this,this.hasChildNodes());
576   - }
577   - },
578   -
579   -/**
580   -* this method is used to display a confirmation message
581   -*/
582   - confirmDirectoryDeletion : function(isNotEmptyDir)
583   - {
584   - // if this is a non-empty directory
585   - if (isNotEmptyDir) {
586   - // Prompt to the user if he also wants to delete its content
587   - Ext.Msg.confirm('non-empty directory', 'The target is a non-empty directory!<br>Do you want to continue and also delete its content?', function(btn, text){
588   - if (btn == 'yes'){
589   - // do delete
590   - this.realDelete();
591   - }
592   - },this);
593   - }
594   - else {
595   - this.realDelete();
596   - }
597   - },
598   -
599   -/*
600   -* Call the extDirect method to delete parameter
601   -* Callback method needed to execute node deletion in tree if id in result or to show error msg
602   -*/
603   - realDelete : function()
604   - {
605   - AmdaAction.deleteObject({id: this.get('id'), leaf: this.isLeaf(), nodeType: this.get('nodeType')}, function(res,e){
606   - //TODO proper errors handling
607   - // node deletion in tree
608   - if (res) { // if success
609   - if (res.id) {
610   - //Ext.Msg.show({title:'Warning', msg: 'Requests with parameter '+node.data.text+' are deleted', icon: Ext.MessageBox.ERROR, buttons: Ext.Msg.OK});
611   - if (this.parentNode) {
612   - if (this.isLeaf()){
613   - var moduleId = this.get('moduleId');
614   - // if really interactive node
615   - if (moduleId) {
616   - var me = this;
617   - myDesktopApp.getLoadedModule(moduleId, true, function (module) {
618   - var editedNode = module.getLinkedNode();
619   - // file node is not linked directly to the module
620   - var isThisFile = false;
621   -
622   - if (editedNode && editedNode.$className == 'amdaModel.MyDataParamNode')
623   - if (editedNode.get('fileObject').get('fileName') == me.get('text'))
624   - isThisFile = true;
625   -
626   - if (me.$className == 'amdaModel.DerivedParamNode')
627   - {
628   - var obj = {
629   - paramId : 'ws_'+me.get('text')
630   - };
631   - AmdaAction.compilParamDelete(obj);
632   - }
633   -
634   - if (editedNode === me || isThisFile){
635   - var newNode = Ext.ModelManager.create({leaf : true}, me.$className);
636   - // several tabs could be connected to one node
637   - if (moduleId === myDesktopApp.dynamicModules.plot.id) {
638   - var linkedNodes = module.linkedNodes;
639   -
640   - if (linkedNodes) {
641   - linkedNodes.each(function(key, value){
642   - if (value === me) {
643   - linkedNodes.replace(key,newNode);
644   - var tabPanel = module.getUiContent().tabPanel.items.getByKey(key);
645   - tabPanel.setObject(Ext.create(amdaModel.Plot.$className, {}));
646   - }
647   - }, me);
648   - }
649   - }
650   - newNode.editInModule();
651   - }
652   - });
653   - }
654   - }
655   - //update mask info in myData
656   - if (res.maskDesc && !res.maskDeleted) {
657   - this.parentNode.set('info', res.maskDesc);
658   - this.updateMyDataParam(res.mask, res.maskDesc);
659   - }
660   - this.remove();
661   - }
662   - //TODO Several special node-dependent actions - to move to node functions..
663   - // nodes of another nodeType to be deleted as they depend on deleted node
664   - if (res.params) {
665   - this.deleteDependence(res.params);
666   - //TODO reset
667   - }
668   - // mask was deleted or updated - to update mydata tree
669   - if (res.maskDeleted) {
670   - this.updateMyData();
671   - }
672   - }
673   - else {
674   - myDesktopApp.warningMsg(res.error);
675   - }
676   - }
677   - else {
678   - myDesktopApp.errorMsg(e.message);
679   - }
680   - }, this);
681   - },
682   -
683   -/*
684   -* Delete musti selection
685   -*/
686   - deleteMulti: function()
687   - {
688   - var selection = this.myGetOwnerTree().getSelectionModel().selected.items;
689   - alert(selection.length +' to delete!');
690   - Ext.Array.each(selection,function(item,index,allItems){
691   - item.deleteNode();
692   - })
693   - },
694   -
695   -/*
696   -* Create Folder
697   -*/
698   - createDir: function() {
699   - var me = this;
700   - amdaModel.InteractiveNode.preloadNodes(this.getRootNode(),
701   - function()
702   - {
703   - var newNode = Ext.create(me.$className,
704   - {
705   - leaf : false, nodeType : me.get('nodeType'),
706   - text : amdaModel.AmdaNode.NEW_DIR_NAME,
707   - children : []
708   - });
709   -
710   - // insert the new node as a child of node
711   - me.insertChild(0, newNode);
712   - // start text edition on this new directory node
713   - me.expand(false);
714   - newNode.expand(false);
715   -
716   - // select the new node
717   - me.myGetOwnerTree().getSelectionModel().select(newNode);
718   - // call the renameNode method for this new node
719   - newNode.renameNode();
720   - });
721   - },
722   -
723   -/*
724   -*
725   -*/
726   - createLeaf: function(contextNode) {
727   - // create new node with the same type than the contextNode
728   - var newNode = Ext.create(contextNode.$className, {leaf : true});
729   -
730   - // load the rootNode and recursively all its child nodes
731   - amdaModel.InteractiveNode.preloadNodes(contextNode.getRootNode(),
732   - function()
733   - {
734   - // edit newNode into Parameter Module with node as contextNode
735   - newNode.editInModule(contextNode);
736   - });
737   - },
738   -
739   - renameNode: function()
740   - {
741   - if (this.myGetOwnerTree())
742   - {
743   - // load the rootNode and recursively all its child nodes if not already loaded
744   - var me = this;
745   - amdaModel.InteractiveNode.preloadNodes(this.getRootNode(),
746   - function()
747   - {
748   - // fire the edition event on tree
749   - me.myGetOwnerTree().fireEvent('edition',me.myGetOwnerTree().view, me.myGetOwnerTree().getSelectionModel().selected.items[0]);
750   - });
751   - }
752   - else
753   - {
754   - myDesktopApp.errorMsg('tree is undefined');
755   - }
756   - },
757   -
758   -/*
759   -* load the rootNode and recursively all its child nodes
760   -* to know all names of DerivedParameters
761   -*/
762   - editLeaf: function(onReady)
763   - {
764   - var me = this;
765   - amdaModel.InteractiveNode.preloadNodes(this.getRootNode(),
766   - function()
767   - {
768   - if (me.get('object'))
769   - {
770   - // launch edition of parameter into parameter module
771   - me.editInModule(null, onReady);
772   - }
773   - else
774   - {
775   - // call the ext method to get the details of parameter
776   - // the edition of real parameter is done into callback method getObjectCallback
777   - if (onReady)
778   - me.onReady = onReady;
779   -
780   - AmdaAction.getObject(me.get('id'), me.get('nodeType'), me.getObjectCallback, me);
781   - }
782   - });
783   - },
784   -
785   -/*
786   -*
787   -*/
788   - getObjectCallback : function(result,remoteEvent)
789   - {
790   - var t = remoteEvent.getTransaction();
791   -
792   - if (result) {
793   - var paramObj = Ext.create(this.get('objectDataModel'), result);
794   - // set parameter into node
795   - this.set('object',paramObj);
796   - // Edition of parameter into parameter Module
797   - this.editInModule(null, this.onReady);
798   - }
799   - else {
800   - // EXCEPTION : parameter not found !?
801   - myDesktopApp.errorMsg(t.action + "." + t.method + " : No parameter '"
802   - + this.get('name') + "' found!");
803   - }
804   - }
  531 + module.addParam(paramName, true, node.get('needsArgs'), components);
  532 + });
  533 + },
  534 +
  535 + deleteNode: function () {
  536 + // if the target is a directory
  537 + if (!this.isLeaf()) {
  538 + // determine if this directory is empty before launching the delete confirmation method
  539 + this.isNotEmptyDir(this.confirmDirectoryDeletion);
  540 + // else (the target is a leaf)
  541 + } else {
  542 + // no confirmation prompt for leaves
  543 + this.confirmDirectoryDeletion(false);
  544 + }
  545 + },
  546 +
  547 + /**
  548 + * this method return if node has Childs even if it was not already loaded
  549 + */
  550 + isNotEmptyDir: function (callbackFn) {
  551 + var hasChilds;
  552 + // if node not already loaded
  553 + if (!this.isLoaded()) {
  554 + // call directFunction to load this node
  555 + AmdaAction.getTree({node: this.get('id'), nodeType: this.get('nodeType')}, function (res, e) {
  556 + callbackFn.call(this, res.length > 0 ? true : false);
  557 + }, this);
  558 + }
  559 + else {
  560 + callbackFn.call(this, this.hasChildNodes());
  561 + }
  562 + },
  563 +
  564 + /**
  565 + * this method is used to display a confirmation message
  566 + */
  567 + confirmDirectoryDeletion: function (isNotEmptyDir) {
  568 + // if this is a non-empty directory
  569 + if (isNotEmptyDir) {
  570 + // Prompt to the user if he also wants to delete its content
  571 + Ext.Msg.confirm('non-empty directory', 'The target is a non-empty directory!<br>Do you want to continue and also delete its content?', function (btn, text) {
  572 + if (btn == 'yes') {
  573 + // do delete
  574 + this.realDelete();
  575 + }
  576 + }, this);
  577 + }
  578 + else {
  579 + this.realDelete();
  580 + }
  581 + },
  582 +
  583 + /*
  584 + * Call the extDirect method to delete parameter
  585 + * Callback method needed to execute node deletion in tree if id in result or to show error msg
  586 + */
  587 + realDelete: function () {
  588 + AmdaAction.deleteObject({
  589 + id: this.get('id'),
  590 + leaf: this.isLeaf(),
  591 + nodeType: this.get('nodeType')
  592 + }, function (res, e) {
  593 + //TODO proper errors handling
  594 + // node deletion in tree
  595 + if (res) { // if success
  596 + if (res.id) {
  597 + //Ext.Msg.show({title:'Warning', msg: 'Requests with parameter '+node.data.text+' are deleted', icon: Ext.MessageBox.ERROR, buttons: Ext.Msg.OK});
  598 + if (this.parentNode) {
  599 + if (this.isLeaf()) {
  600 + var moduleId = this.get('moduleId');
  601 + // if really interactive node
  602 + if (moduleId) {
  603 + var me = this;
  604 + myDesktopApp.getLoadedModule(moduleId, true, function (module) {
  605 + var editedNode = module.getLinkedNode();
  606 + // file node is not linked directly to the module
  607 + var isThisFile = false;
  608 +
  609 + if (editedNode && editedNode.$className == 'amdaModel.MyDataParamNode')
  610 + if (editedNode.get('fileObject').get('fileName') == me.get('text'))
  611 + isThisFile = true;
  612 +
  613 + if (me.$className == 'amdaModel.DerivedParamNode') {
  614 + var obj = {
  615 + paramId: 'ws_' + me.get('text')
  616 + };
  617 + AmdaAction.compilParamDelete(obj);
  618 + }
  619 +
  620 + if (editedNode === me || isThisFile) {
  621 + var newNode = Ext.ModelManager.create({leaf: true}, me.$className);
  622 + // several tabs could be connected to one node
  623 + if (moduleId === myDesktopApp.dynamicModules.plot.id) {
  624 + var linkedNodes = module.linkedNodes;
  625 +
  626 + if (linkedNodes) {
  627 + linkedNodes.each(function (key, value) {
  628 + if (value === me) {
  629 + linkedNodes.replace(key, newNode);
  630 + var tabPanel = module.getUiContent().tabPanel.items.getByKey(key);
  631 + tabPanel.setObject(Ext.create(amdaModel.Plot.$className, {}));
  632 + }
  633 + }, me);
  634 + }
  635 + }
  636 + newNode.editInModule();
  637 + }
  638 + });
  639 + }
  640 + }
  641 + //update mask info in myData
  642 + if (res.maskDesc && !res.maskDeleted) {
  643 + this.parentNode.set('info', res.maskDesc);
  644 + this.updateMyDataParam(res.mask, res.maskDesc);
  645 + }
  646 + this.remove();
  647 + }
  648 + //TODO Several special node-dependent actions - to move to node functions..
  649 + // nodes of another nodeType to be deleted as they depend on deleted node
  650 + if (res.params) {
  651 + this.deleteDependence(res.params);
  652 + //TODO reset
  653 + }
  654 + // mask was deleted or updated - to update mydata tree
  655 + if (res.maskDeleted) {
  656 + this.updateMyData();
  657 + }
  658 + }
  659 + else {
  660 + myDesktopApp.warningMsg(res.error);
  661 + }
  662 + }
  663 + else {
  664 + myDesktopApp.errorMsg(e.message);
  665 + }
  666 + }, this);
  667 + },
  668 +
  669 + /*
  670 + * Delete musti selection
  671 + */
  672 + deleteMulti: function () {
  673 + var selection = this.myGetOwnerTree().getSelectionModel().selected.items;
  674 + alert(selection.length + ' to delete!');
  675 + Ext.Array.each(selection, function (item, index, allItems) {
  676 + item.deleteNode();
  677 + })
  678 + },
  679 +
  680 + /*
  681 + * Create Folder
  682 + */
  683 + createDir: function () {
  684 + var me = this;
  685 + amdaModel.InteractiveNode.preloadNodes(this.getRootNode(), function () {
  686 + var newNode = Ext.create(me.$className,
  687 + {
  688 + leaf: false, nodeType: me.get('nodeType'),
  689 + text: amdaModel.AmdaNode.NEW_DIR_NAME,
  690 + children: []
  691 + });
  692 +
  693 + // insert the new node as a child of node
  694 + me.insertChild(0, newNode);
  695 + // start text edition on this new directory node
  696 + me.expand(false);
  697 + newNode.expand(false);
  698 +
  699 + // select the new node
  700 + me.myGetOwnerTree().getSelectionModel().select(newNode);
  701 + // call the renameNode method for this new node
  702 + newNode.renameNode();
  703 + });
  704 + },
  705 +
  706 + /*
  707 + *
  708 + */
  709 + createLeaf: function (contextNode) {
  710 + // create new node with the same type than the contextNode
  711 + var newNode = Ext.create(contextNode.$className, {leaf: true});
  712 +
  713 + // load the rootNode and recursively all its child nodes
  714 + amdaModel.InteractiveNode.preloadNodes(contextNode.getRootNode(), function () {
  715 + // edit newNode into Parameter Module with node as contextNode
  716 + newNode.editInModule(contextNode);
  717 + });
  718 + },
  719 +
  720 + renameNode: function () {
  721 + if (this.myGetOwnerTree()) {
  722 + // load the rootNode and recursively all its child nodes if not already loaded
  723 + var me = this;
  724 + amdaModel.InteractiveNode.preloadNodes(this.getRootNode(), function () {
  725 + // fire the edition event on tree
  726 + me.myGetOwnerTree().fireEvent('edition', me.myGetOwnerTree().view, me.myGetOwnerTree().getSelectionModel().selected.items[0]);
  727 + });
  728 + }
  729 + else {
  730 + myDesktopApp.errorMsg('tree is undefined');
  731 + }
  732 + },
  733 +
  734 + /*
  735 + * load the rootNode and recursively all its child nodes
  736 + * to know all names of DerivedParameters
  737 + */
  738 + editLeaf: function (onReady) {
  739 + var me = this;
  740 + amdaModel.InteractiveNode.preloadNodes(this.getRootNode(), function () {
  741 + if (me.get('object')) {
  742 + // launch edition of parameter into parameter module
  743 + me.editInModule(null, onReady);
  744 + }
  745 + else {
  746 + // call the ext method to get the details of parameter
  747 + // the edition of real parameter is done into callback method getObjectCallback
  748 + if (onReady)
  749 + me.onReady = onReady;
  750 +
  751 + AmdaAction.getObject(me.get('id'), me.get('nodeType'), me.getObjectCallback, me);
  752 + }
  753 + });
  754 + },
  755 +
  756 + /*
  757 + *
  758 + */
  759 + getObjectCallback: function (result, remoteEvent) {
  760 + var t = remoteEvent.getTransaction();
  761 +
  762 + if (result) {
  763 + var paramObj = Ext.create(this.get('objectDataModel'), result);
  764 + // set parameter into node
  765 + this.set('object', paramObj);
  766 + // Edition of parameter into parameter Module
  767 + this.editInModule(null, this.onReady);
  768 + }
  769 + else {
  770 + // EXCEPTION : parameter not found !?
  771 + myDesktopApp.errorMsg(t.action + "." + t.method + " : No parameter '"
  772 + + this.get('name') + "' found!");
  773 + }
  774 + }
805 775 });
... ...
js/app/views/ExplorerUI.js
1 1 /**
2 2 * Project  : AMDA-NG4
3 3 * Name : ExplorerUI.js
4   - * @class amdaUI.ExplorerUI
  4 + * @class amdaUI.ExplorerUI
5 5 * @extends Ext.tab.Panel
6 6 * @class amdaUI.TreeToolColumn
7 7 * @extends Ext.tree.Column
... ... @@ -12,1067 +12,1013 @@
12 12 */
13 13  
14 14 Ext.define('amdaUI.TreeToolColumn', {
15   - extend: 'Ext.tree.Column',
16   - alias: 'widget.treetoolcolumn',
17   -
18   - /**
19   - * Add more tools here. These will be on the prototype for all TreeToolColumns
20   - */
21   - tools: {
22   - 'info': 'js/resources/images/16x16/info_mini.png'
23   - },
24   -
25   - initComponent: function()
26   - {
27   - var me = this;
28   - me.addEvents('toolclick');
29   - me.callParent();
30   - me.on('toolclick', me.toolHandler, me);
31   - },
32   -
33   - renderer: function(value, metaData, record, rowIdx, colIdx, store, view)
34   - {
35   - var toolCol = view.getHeaderAtIndex(colIdx);
36   -
37   - if (!toolCol.toolIsVisible(record)) return value;
38   -
39   - var toolId = 'tool-' + rowIdx + '-' + colIdx,
40   - toolImg = toolCol.tools[toolCol.tool],
41   - imgHtml = Ext.DomHelper.markup({
42   - id : toolId,
43   - tag : 'img',
44   - tooltype: toolCol.tool,
45   - src : toolImg,
46   - style : 'cursor:hand;'
47   - });
48   -
49   - return value + ' ' + imgHtml;
50   - },
51   -
52   - processEvent: function(type, view, cell, recordIndex, cellIndex, e)
53   - {
54   - if(type === "click" && e.target.tagName === "IMG")
55   - {
56   - var tooltype = e.target.getAttribute("tooltype");
57   - if(tooltype)
58   - return this.fireEvent("toolclick", view, cell, recordIndex, cellIndex, e);
59   - }
60   - return this.fireEvent.apply(this, arguments);
61   - },
62   -
63   - /**
64   - * Override this when you add columns to the tree... see example below
65   - */
  15 + extend: 'Ext.tree.Column',
  16 + alias: 'widget.treetoolcolumn',
  17 +
  18 + /**
  19 + * Add more tools here. These will be on the prototype for all TreeToolColumns
  20 + */
  21 + tools: {
  22 + 'info': 'js/resources/images/16x16/info_mini.png'
  23 + },
  24 +
  25 + initComponent: function () {
  26 + var me = this;
  27 + me.addEvents('toolclick');
  28 + me.callParent();
  29 + me.on('toolclick', me.toolHandler, me);
  30 + },
  31 +
  32 + renderer: function (value, metaData, record, rowIdx, colIdx, store, view) {
  33 + var toolCol = view.getHeaderAtIndex(colIdx);
  34 +
  35 + if (!toolCol.toolIsVisible(record)) return value;
  36 +
  37 + var toolId = 'tool-' + rowIdx + '-' + colIdx,
  38 + toolImg = toolCol.tools[toolCol.tool],
  39 + imgHtml = Ext.DomHelper.markup({
  40 + id: toolId,
  41 + tag: 'img',
  42 + tooltype: toolCol.tool,
  43 + src: toolImg,
  44 + style: 'cursor:hand;'
  45 + });
  46 +
  47 + return value + ' ' + imgHtml;
  48 + },
  49 +
  50 + processEvent: function (type, view, cell, recordIndex, cellIndex, e) {
  51 + if (type === "click" && e.target.tagName === "IMG") {
  52 + var tooltype = e.target.getAttribute("tooltype");
  53 + if (tooltype)
  54 + return this.fireEvent("toolclick", view, cell, recordIndex, cellIndex, e);
  55 + }
  56 + return this.fireEvent.apply(this, arguments);
  57 + },
  58 +
  59 + /**
  60 + * Override this when you add columns to the tree... see example below
  61 + */
66 62 // toolHandler: function() {
67 63 // alert("override this");
68 64 // },
69 65  
70   - toolIsVisible : function(record) {
71   - return false;
72   - }
  66 + toolIsVisible: function (record) {
  67 + return false;
  68 + }
73 69 });
74 70  
75 71  
76 72 // ExplorerUI
77 73 Ext.define('amdaUI.ExplorerUI', {
78   - extend: 'Ext.tab.Panel',
79   - alias : 'widget.panelExplorer',
80   -
81   - statics:
82   - {
83   - RESRC_TAB : {
84   - TREE_ID:'resourcesTree',
85   - TREE_TYPE:'resources'
86   - },
87   - OPE_TAB : {
88   - TREE_ID:'operationsTree',
89   - TREE_TYPE:'operations'
90   - },
91   - JOB_TAB : {
92   - TREE_ID:'jobsTree',
93   - TREE_TYPE:'jobs'
94   - },
95   -
96   - CAT_SUFFIX: '-treeBase',
97   - ROOT_SUFFIX: '-treeRootNode',
98   - SUB_ROOT_SUFFIX : 'RootNode',
99   -
100   - ITEM_KIND_BASE : 'base',
101   - ITEM_KIND_ROOT : 'root',
102   - ITEM_KIND_LEAF : 'leaf',
103   - ITEM_KIND_DIRE : 'dire',
104   - ITEM_KIND_PARA : 'para',
105   - ITEM_KIND_MISS : 'miss'
106   - },
107   -
108   - initComponent : function (config)
109   - {
110   - var explorerModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.explorer.id);
111   -
112   - var myConf = {
113   - split : true,
114   - width : '100%',
115   - height : '100%',
116   - autoScroll : true,
117   - border : true,
118   - header : false,
119   - defaults : {
120   - // applied to each contained panel
121   - containerScroll : true
122   - },
123   - stateful: true,
124   - //stateId: 'tp1',
125   - stateEvents: ['tabchange'],
126   - getState: function() {
127   - return {
128   - activeTab: this.items.findIndex('id',this.getActiveTab().id)
129   - };
130   - },
131   - applyState: function(s) {
132   - this.setActiveTab(s.activeTab);
133   - },
134   - items: [
135   - this.initTree(amdaUI.ExplorerUI.RESRC_TAB.TREE_TYPE),
136   - this.initTree(amdaUI.ExplorerUI.OPE_TAB.TREE_TYPE),
137   - this.initTree(amdaUI.ExplorerUI.JOB_TAB.TREE_TYPE)
138   - ],
139   - tbar : [
140   - {
141   - xtype : 'combo',
142   - fieldLabel: 'Filter',
143   - labelWidth: 25,
144   - width: 140,
145   - store: explorerModule.filtersStore,
146   - queryMode: 'local',
147   - displayField: 'name',
148   - valueField: 'id',
149   - listeners : {
150   - scope : this,
151   - select: function(combo, records) {
152   - AmdaAction.setCrtFilterId({id : records[0].get('id')},
153   - function (result, e)
154   - {
155   - var t = e.getTransaction();
156   - if (e.status)
157   - {
158   - if (result)
159   - {
160   - var explorerModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.explorer.id);
161   - if (explorerModule)
162   - explorerModule.setCrtFilter();
163   - }
164   - else
165   - Ext.Msg.show( {
166   - title : 'Filter',
167   - msg : 'Cannot apply filter',
168   - modal : true,
169   - icon : Ext.Msg.ERROR,
170   - buttons : Ext.Msg.OK
171   - });
172   - }
173   - else
174   - {
175   - // FAILURE
176   - Ext.Msg.show({title:'Error System', msg: e.message, icon: Ext.MessageBox.ERROR, buttons: Ext.Msg.OK});
177   - }
178   - },this);
179   - }
180   - }
181   - },
182   - {
183   - text: '',
184   - iconCls : 'icon-parameters',
185   - tooltip: { text: 'Edit Filter', align: 'bl-tl' },
186   - handler: function(t){
187   - myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.filters.id, true, function (module) {
188   - module.createWindow();
189   - });
190   - }
191   - },
192   - {
193   - text: '',
194   - iconCls : 'icon-remover',
195   - tooltip: { text: 'Reset Filter', align: 'bl-tl' },
196   - handler: function(t){
197   - var explorerModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.explorer.id);
198   - explorerModule.resetFilter();
199   - }
200   - }, '-',
201   - {
202   - xtype: 'displayfield',
203   - fieldLabel: 'SortBy',
204   - width: 40
205   - },
206   - {
207   - text: 'Name',
208   - scope : this,
209   - tooltip: { text: 'Sort out AMDA DataBase Data by Mission Name', align: 'bl-tl' },
210   - pressed: true,
211   - enableToggle : true,
212   - toggleGroup: 'sorting',
213   - handler: function(){
214   - var tree = Ext.getCmp(amdaUI.ExplorerUI.RESRC_TAB.TREE_ID);
215   - tree.getStore().sort([
216   - { sorterFn: function(o1, o2){
217   - if (o1.get('nodeType') !== 'localParam')
218   - return;
219   -
220   - return o1.get('text').toUpperCase() < o2.get('text').toUpperCase() ? -1 : 1;
221   - }
222   - }]);
223   - this.updateFilter();
224   - }
225   - },
226   - {
227   - text: 'Target',
228   - scope : this,
229   - tooltip: {text: 'Sort out AMDA DataBase Data by Mission Main Target', align: 'bl-tl'},
230   - enableToggle : true,
231   - toggleGroup: 'sorting',
232   - handler: function(){
233   - var tree = Ext.getCmp(amdaUI.ExplorerUI.RESRC_TAB.TREE_ID);
234   - tree.getStore().sort([{ property : 'rank' }]);
235   - this.updateFilter();
236   - }
237   - }]
238   - };
239   - Ext.apply (this , Ext.apply (arguments, myConf));
240   - this.callParent(arguments);
241   - },
242   -
243   - initTree : function(treeType)
244   - {
245   - switch (treeType)
246   - {
247   - case amdaUI.ExplorerUI.RESRC_TAB.TREE_TYPE:
248   - treeId = amdaUI.ExplorerUI.RESRC_TAB.TREE_ID;
249   - break;
250   - case amdaUI.ExplorerUI.OPE_TAB.TREE_TYPE:
251   - treeId = amdaUI.ExplorerUI.OPE_TAB.TREE_ID;
252   - break;
253   - case amdaUI.ExplorerUI.JOB_TAB.TREE_TYPE:
254   - treeId = amdaUI.ExplorerUI.JOB_TAB.TREE_ID;
255   - break;
256   - default:
257   - treeId = amdaUI.ExplorerUI.RESRC_TAB.TREE_ID;
258   - break;
259   - }
260   -
261   - var store = Ext.create('Ext.data.TreeStore', {
262   - root: {
263   - expanded: true,
264   - nodeType : treeType
265   - },
266   - model: 'amdaModel.AmdaNode',
267   - sorters:[{ direction: 'ASC' ,
268   - sorterFn: function(o1, o2){
269   - if (o1.get('nodeType') !== 'localParam')
270   - return;
271   -
272   - return o1.get('text').toUpperCase() < o2.get('text').toUpperCase() ? -1 : 1;
273   - }
274   - }],
275   - listeners: {
276   - beforeload: function(store, operation){
277   - store.proxy.extraParams = {
278   - nodeType: operation.node.get('nodeType')
279   - };
280   - }
281   - }
282   - });
283   -
284   - var menu = new Ext.menu.Menu();
285   -
286   - var tree = Ext.create('Ext.tree.Panel', {
287   - id : treeId,
288   - title: treeType,
289   - store: store,
290   - rootVisible: false,
291   - animate: false,
292   - hideHeaders : true,
293   - selModel: Ext.create('Ext.selection.TreeModel', {
294   - // ignoreRightMouseSelection: true,
295   - mode: 'MULTI'
296   - }),
297   - viewConfig:
298   - {
299   - plugins:
300   - {
301   - ptype: 'treeviewdragdrop',
302   - enableDrag:true,
303   - enableDrop:true,
304   - //TODO - BRE - Wait a fix for drag&drop issue
305   - ddGroup:'explorerTree',
306   - pluginId : 'ddplugin',
307   -
308   - isValidDropPoint : function (node, position, dragZone, e, data)
309   - {
310   - if (!node || !data.item) {
311   - return false;
312   - }
313   - var view = this.view,
314   - targetNode = view.getRecord(node),
315   - draggedRecords = data.records,
316   - dataLength = draggedRecords.length,
317   - ln = draggedRecords.length,
318   - i, record;
319   -
320   - // No drop position, or dragged records: invalid drop point
321   - if (!(targetNode && position && dataLength)) {
322   - return false;
323   - }
324   - // If the targetNode is within the folder we are dragging
325   - for (i = 0; i < ln; i++) {
326   - record = draggedRecords[i];
327   - if (record.isNode && record.contains(targetNode)) {
328   - return false;
329   - }
330   - }
331   - // Respect the allowDrop field on Tree nodes
332   - if (position === 'append' && targetNode.get('allowDrop') === false) {
333   - return false;
334   - }
335   - else if (position != 'append' && targetNode.parentNode.get('allowDrop') === false) {
336   - return false;
337   - }
338   - // If the target record is in the dragged dataset, then invalid drop
339   - if (Ext.Array.contains(draggedRecords, targetNode)) {
340   - return false;
341   - }
342   - //
343   - if (dataLength > 1)
344   - return false;
345   -
346   - var draggedRecord = draggedRecords[0];
347   - //
348   - switch (targetNode.data.nodeType)
349   - {
350   - case 'localParam' :
351   - case 'remoteParam' :
352   - case 'remoteSimuParam' :
353   - case 'myData' :
354   - return false;
355   - default :
356   - if (draggedRecord.data.id == targetNode.data.nodeType+'-treeRootNode')
357   - return false;
358   - if ((position == 'before') && (targetNode.data.id == targetNode.data.nodeType+'-treeRootNode'))
359   - return false;
360   - return (draggedRecord.data.nodeType == targetNode.data.nodeType);
361   - }
362   - return false;
363   - },
364   - onViewRender : function(view)
365   - {
366   - var me = this;
367   -
368   - view.on('itemupdate', function(record,index,node,opts)
369   - {
370   - var forceHide = false;
371   - var crtRec = record.parentNode;
372   - while (crtRec && !forceHide)
373   - {
374   - if (crtRec.get('filtered'))
375   - forceHide = crtRec.get('filtered');
376   - crtRec = crtRec.parentNode;
377   - }
378   - tree.setNodesVisibility(record,forceHide);
379   - tree.applyDisableToNode(record);
380   - });
381   -
382   - view.on('itemadd', function(records,index,node,opts)
383   - {
384   - Ext.each(records,function (rec)
385   - {
386   - tree.applyFilterToNode(rec);
387   - tree.applyDisableToNode(rec);
388   - });
389   - });
390   -
391   - view.on('afteritemexpand', function(record,index,node,opts)
392   - {
393   - var forceHide = false;
394   - var crtRec = record.parentNode;
395   - while (crtRec && !forceHide)
396   - {
397   - if (crtRec.get('filtered'))
398   - forceHide = crtRec.get('filtered');
399   - crtRec = crtRec.parentNode;
400   -
401   - }
402   - tree.setNodesVisibility(record,forceHide);
403   - tree.applyDisableToNode(record);
404   - });
405   -
406   - if (me.enableDrag)
407   - {
408   - me.dragZone = Ext.create('Ext.tree.ViewDragZone', {
409   - view: view,
410   - ddGroup: me.dragGroup || me.ddGroup,
411   - dragText: me.dragText,
412   - repairHighlightColor: me.nodeHighlightColor,
413   - repairHighlight: me.nodeHighlightOnRepair
414   - });
415   - }
416   -
417   - if (me.enableDrop)
418   - {
419   - me.dropZone = Ext.create('Ext.tree.ViewDropZone', {
420   - view: view,
421   - ddGroup: me.dropGroup || me.ddGroup,
422   - allowContainerDrops: me.allowContainerDrops,
423   - appendOnly: me.appendOnly,
424   - allowParentInserts: me.allowParentInserts,
425   - expandDelay: me.expandDelay,
426   - dropHighlightColor: me.nodeHighlightColor,
427   - dropHighlight: me.nodeHighlightOnDrop,
428   - isValidDropPoint : me.isValidDropPoint
429   - });
430   - }
431   - }
432   - },
433   - listeners :
434   - {
435   - beforedrop : function(node, data, overModel, dropPosition)
436   - {
437   - var parentId;
438   - switch(dropPosition)
439   - {
440   - case 'append' :
441   - if (overModel.isLeaf())
442   - parentId = overModel.parentNode.get('id');
443   - else
444   - parentId = overModel.get('id');
445   -
446   - if(!overModel.isExpanded() && overModel.isExpandable()) {
447   - myDesktopApp.warningMsg('Please open the folder before node adding');
448   - return false;
449   - }
450   - break;
451   - case 'before' :
452   - case 'after' :
453   - parentId = overModel.parentNode.get('id');
454   - break;
455   - }
456   -
457   - Ext.each(data.records, function(rec)
458   - {
459   - rec.renameDD(parentId,function(result)
460   - {
461   - if (result)
462   - {
463   - if (!result.id)
464   - {
465   - Ext.Msg.show({
466   - title : 'Drop is impossible',
467   - msg : result.error,
468   - buttons : Ext.Msg.OK,
469   - icon : Ext.MessageBox.WARNING
470   - });
471   -
472   - return false;
473   - }
474   - }
475   - else
476   - {
477   - Ext.Msg.show({
478   - title : 'Drop is impossible',
479   - msg : 'Cannot connect to the server',
480   - buttons : Ext.Msg.OK,
481   - icon : Ext.MessageBox.WARNING
482   - });
483   -
484   - return false;
485   - }
486   -
487   - return true;
488   - });
489   - });
490   - }
491   - }
492   - },
493   - listeners:
494   - {
495   - itemmouseenter: function(view, record, item){
496   - if(record.get('isParameter')){
497   - var el = Ext.get(item),
498   - td = el.down('td > div');
499   - td.setStyle('cursor', 'crosshair');
500   - }
501   - else
502   - {
503   - var el = Ext.get(item),
504   - td = el.down('td > div');
505   - td.setStyle('cursor', 'pointer');
506   - }
507   - },
508   -
509   - itemcontextmenu: function(view, rec, item, index, e){
510   - // Add record to selection model
511   - view.ownerCt.getSelectionModel().select(rec);
512   -
513   - // block other events
514   - e.stopEvent();
515   -
516   - // clear menu items
517   - menu.removeAll();
518   - var menuItems;
519   -
520   - // if it's a single selection
521   - if (view.ownerCt.getSelectionModel().selected.length === 1) {
522   - // get items menu corresponding to right clicked record
523   - menuItems = rec.getContextMenuItems(this);
524   -
525   - } else if (view.ownerCt.getSelectionModel().selected.length > 1) {
526   - // get items menu corresponding to right clicked record
527   - menuItems = rec.getContextMenuMultiItems(this);
528   - }
529   - // if there's at least one item menu
530   - if (menuItems && menuItems.length){
531   - // add the items
532   - menu.add(menuItems);
533   - // add listener on right clicked record
534   - var onRecordClick = function (menu, item, e, eOpts)
535   - {
536   - if (this.myGetOwnerTree().getSelectionModel().isSelected(this)) {
537   - //Dispatch click event to the record
538   - this.onMenuItemClick(menu,item,e);
539   - }
540   - //Remove old click listener
541   - menu.removeListener('click',onRecordClick,this);
542   - };
543   -
544   - menu.addListener('click',onRecordClick,rec);
545   - // then show menu
546   - menu.showAt(e.getXY());
547   - }
548   - },
549   -
550   - itemdblclick: function(view, record, item, index, event){
551   - event.stopEvent();
552   - // first check if it is for SAVE-START-STOP plugin...
553   - if (Ext.PluginManager.getCount() > 0 &&
554   - record.get('nodeType') == amdaModel.TimeTableNode.nodeType && record.isLeaf()) {
555   - var zmgr = myDesktopApp.desktop.getDesktopZIndexManager();
556   - var winActive = zmgr.getActive();
557   - var winId = winActive.getId();
558   - if (winId == 'explorer-win') {
559   - zmgr.eachTopDown(function(win) {
560   - var id = win.getId();
561   - if (id !== 'explorer-win') {
562   - winId = id;
563   - return false;
564   - }
565   - });
566   - }
567   - }
568   -
569   - if (record.get('nodeType') == 'remoteParam' && !record.isLeaf()
570   - && !record.get('isParameter')) {
571   - myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.interop.id, true, function (module) {
572   - module.createWindow(record.getBaseId());
573   - });
574   - }
575   -
576   - if (record.isLeaf() || record.data.isParameter)
577   - switch (record.get('nodeType'))
578   - {
579   - case 'myData' :
580   - case 'myDataParam' :
581   - case 'derivedParam' :
582   - case 'timeTable' :
583   - case 'sharedtimeTable' :
584   - case 'sharedcatalog' :
585   - case 'catalog' :
586   - case 'request' :
587   - case 'condition' :
588   - record.editLeaf();
589   - break;
590   - case 'localParam' :
591   - case 'remoteParam':
592   - case 'remoteSimuParam':
593   - record.createAlias(record);
594   - break;
595   - case 'bkgWorks' :
596   - if (!record.get('object')) {
597   - AmdaAction.getObject(record.get('id'), record.get('nodeType'), record.getObjectCallback, record);
598   - }
599   - else {
600   - if (record.get('status') == 'done') {
601   - var isInteractive = false;
602   - var isNewTab = true;
603   - record.editNode(isNewTab, isInteractive);
604   - }
605   - else {
606   - myDesktopApp.infoMsg('Job Status: ' + record.get('status'));
607   - }
608   - }
609   - break;
610   - }
611   - },
612   -
613   - beforeselect: function(view,node,index,options){
614   - // if there's at least one node already selected
615   - if(view.selected.length
616   - //AND (the node which is beeing selected has a different nodeType than the first selected node OR the first selected node isn't a leaf
617   - && ( node.get('nodeType')!== view.selected.items[0].get('nodeType') || !view.selected.items[0].isLeaf())
618   - // OR the node which is beeing selected has no nodeType OR it isn't a leaf OR
619   - || !node.get('nodeType') || !node.isLeaf()
620   - ){
621   - // clear old selection
622   - view.deselectAll();
623   - }
624   - },
625   -
626   - afterrender: function(comp){
627   - var view = comp.getView();
628   - view.tip = Ext.create('Ext.tip.ToolTip', {
629   - // The overall target element.
630   - target: view.el,
631   - // Each grid row causes its own seperate show and hide.
632   - delegate: view.itemSelector,
633   - dismissDelay : 0,
634   - // showDelay: 100,
635   - // anchor: 'left',
636   - // Moving within the row should not hide the tip.
637   - trackMouse: true,
638   - autoRender: true,
639   - listeners: {
640   - // Change content dynamically depending on which element triggered the show.
641   - beforeshow: function updateTipBody(tip) {
642   - if (view.getRecord(tip.triggerElement)) {
643   - var info = view.getRecord(tip.triggerElement).get('info');
644   - if (!info || info == '') {
645   - tip.addCls('hide');
646   - }
647   - else {
648   - tip.removeCls('hide');
649   - tip.update(info);
650   - }
651   - }
652   - }
653   - }
654   - });
655   - },
656   - // if remote base is empty - open interoperability module
657   - itemexpand: function(node) {
658   - if ( node.get('nodeType') == amdaModel.RemoteParamNode.nodeType
659   - && node.getDepth() == 3 && !node.hasChildNodes()) {
660   - node.addData();
661   - }
662   - },
663   - scope: this
664   - },
665   -
666   - hideHeaders: true,
667   - // must define a column with a field to enable editor
668   - columns: [{
669   - xtype : 'treetoolcolumn',
670   - text : 'Name',
671   - flex : 1,
672   - dataIndex: 'text',
673   - tool: 'info', // this references the "tools" object on the prototype
674   - toolHandler: function(view, cell, recordIndex, cellIndex, e) {
675   - var tooltype = e.target.getAttribute("tooltype");
676   - var record = view.store.getAt(recordIndex);
677   - switch (tooltype)
678   - {
679   - case 'info' :
680   - myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.info.id, true, function (module) {
681   - module.createWindow(record.get('help'), record.get('text'));
682   - });
683   - break;
684   - }
685   - },
686   - toolIsVisible : function(record) {
687   -
688   - switch (record.get('nodeType'))
689   - {
690   - case 'localParam' :
691   - case 'remoteParam' :
692   - case 'remoteSimuParam' :
693   -
694   - return record.get('help') != '';
695   - }
696   - return false;
697   - },
698   - field: {
699   - validFlag: true,
700   - listeners: {
701   - change : function( field, newValue, oldValue, eOpts )
702   - {
703   - var explModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.explorer.id);
704   - var explUI = explModule.getUiContent();
705   - var activeTreePanel = explUI.getActiveTab();
706   -
707   - var editedNode = activeTreePanel.getSelectionModel().selected.items[0];
708   - if (editedNode) {
709   - editedNode.isValidName(newValue, function (res) {
710   - var validFlag = true;
711   - if(newValue === amdaModel.AmdaNode.NEW_DIR_NAME) {
712   - validFlag = 'Field is not modified'
713   - } else if (!res) {
714   - validFlag = 'Error during object validation';
715   - } else if (!res.valid) {
716   - if (res.error) {
717   - validFlag = res.error;
718   - } else {
719   - validFlag = 'Invalid object name';
720   - }
721   - }
722   - if (validFlag === true) {
723   - field.lastValid = newValue;
724   - } else {
725   - field.markInvalid(validFlag);
726   - }
727   - field.validFlag = validFlag;
728   - });
729   - }
730   - }
731   - },
732   - scope: this
733   - }
734   - }],
735   - //add our custom editor plugin
736   - plugins: [ new MyTreeEditor({
737   - pluginId: 'treeEditor',
738   - listeners: {
739   - 'edit': function (editor, e) {
740   - if(e.column.field.validFlag !== true) {
741   - if(e.column.field.lastValid) {
742   - e.record.data[e.field] = e.column.field.lastValid;
743   - } else {
744   - e.record.remove(true);
  74 + extend: 'Ext.tab.Panel',
  75 + alias: 'widget.panelExplorer',
  76 +
  77 + statics: {
  78 + RESRC_TAB: {
  79 + TREE_ID: 'resourcesTree',
  80 + TREE_TYPE: 'resources'
  81 + },
  82 + OPE_TAB: {
  83 + TREE_ID: 'operationsTree',
  84 + TREE_TYPE: 'operations'
  85 + },
  86 + JOB_TAB: {
  87 + TREE_ID: 'jobsTree',
  88 + TREE_TYPE: 'jobs'
  89 + },
  90 +
  91 + CAT_SUFFIX: '-treeBase',
  92 + ROOT_SUFFIX: '-treeRootNode',
  93 + SUB_ROOT_SUFFIX: 'RootNode',
  94 +
  95 + ITEM_KIND_BASE: 'base',
  96 + ITEM_KIND_ROOT: 'root',
  97 + ITEM_KIND_LEAF: 'leaf',
  98 + ITEM_KIND_DIRE: 'dire',
  99 + ITEM_KIND_PARA: 'para',
  100 + ITEM_KIND_MISS: 'miss'
  101 + },
  102 +
  103 + initComponent: function (config) {
  104 + var explorerModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.explorer.id);
  105 +
  106 + var myConf = {
  107 + split: true,
  108 + width: '100%',
  109 + height: '100%',
  110 + autoScroll: true,
  111 + border: true,
  112 + header: false,
  113 + defaults: {
  114 + // applied to each contained panel
  115 + containerScroll: true
  116 + },
  117 + stateful: true,
  118 + //stateId: 'tp1',
  119 + stateEvents: ['tabchange'],
  120 + getState: function () {
  121 + return {
  122 + activeTab: this.items.findIndex('id', this.getActiveTab().id)
  123 + };
  124 + },
  125 + applyState: function (s) {
  126 + this.setActiveTab(s.activeTab);
  127 + },
  128 + items: [
  129 + this.initTree(amdaUI.ExplorerUI.RESRC_TAB.TREE_TYPE),
  130 + this.initTree(amdaUI.ExplorerUI.OPE_TAB.TREE_TYPE),
  131 + this.initTree(amdaUI.ExplorerUI.JOB_TAB.TREE_TYPE)
  132 + ],
  133 + tbar: [
  134 + {
  135 + xtype: 'combo',
  136 + fieldLabel: 'Filter',
  137 + labelWidth: 25,
  138 + width: 140,
  139 + store: explorerModule.filtersStore,
  140 + queryMode: 'local',
  141 + displayField: 'name',
  142 + valueField: 'id',
  143 + listeners: {
  144 + scope: this,
  145 + select: function (combo, records) {
  146 + AmdaAction.setCrtFilterId({id: records[0].get('id')}, function (result, e) {
  147 + var t = e.getTransaction();
  148 + if (e.status) {
  149 + if (result) {
  150 + var explorerModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.explorer.id);
  151 + if (explorerModule)
  152 + explorerModule.setCrtFilter();
745 153 }
746   - }
747   - },
748   - 'beforeedit': function (editor, e) {
749   - e.column.field.fireEvent('change', e.column.field, e.value, '');
  154 + else
  155 + Ext.Msg.show({
  156 + title: 'Filter',
  157 + msg: 'Cannot apply filter',
  158 + modal: true,
  159 + icon: Ext.Msg.ERROR,
  160 + buttons: Ext.Msg.OK
  161 + });
  162 + }
  163 + else {
  164 + // FAILURE
  165 + Ext.Msg.show({
  166 + title: 'Error System',
  167 + msg: e.message,
  168 + icon: Ext.MessageBox.ERROR,
  169 + buttons: Ext.Msg.OK
  170 + });
  171 + }
  172 + }, this);
  173 + }
  174 + }
  175 + },
  176 + {
  177 + text: '',
  178 + iconCls: 'icon-parameters',
  179 + tooltip: {text: 'Edit Filter', align: 'bl-tl'},
  180 + handler: function (t) {
  181 + myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.filters.id, true, function (module) {
  182 + module.createWindow();
  183 + });
  184 + }
  185 + },
  186 + {
  187 + text: '',
  188 + iconCls: 'icon-remover',
  189 + tooltip: {text: 'Reset Filter', align: 'bl-tl'},
  190 + handler: function (t) {
  191 + var explorerModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.explorer.id);
  192 + explorerModule.resetFilter();
  193 + }
  194 + }, '-',
  195 + {
  196 + xtype: 'displayfield',
  197 + fieldLabel: 'SortBy',
  198 + width: 40
  199 + },
  200 + {
  201 + text: 'Name',
  202 + scope: this,
  203 + tooltip: {text: 'Sort out AMDA DataBase Data by Mission Name', align: 'bl-tl'},
  204 + pressed: true,
  205 + enableToggle: true,
  206 + toggleGroup: 'sorting',
  207 + handler: function () {
  208 + var tree = Ext.getCmp(amdaUI.ExplorerUI.RESRC_TAB.TREE_ID);
  209 + tree.getStore().sort([
  210 + {
  211 + sorterFn: function (o1, o2) {
  212 + if (o1.get('nodeType') !== 'localParam')
  213 + return;
  214 +
  215 + return o1.get('text').toUpperCase() < o2.get('text').toUpperCase() ? -1 : 1;
  216 + }
750 217 }
751   - },
752   - scope: this
753   - })],
754   -
755   - setNodesVisibility : function(node,forceHide)
756   - {
757   - var isFiltered = node.get('filtered');
758   -
759   - for (var i = 0; i < node.childNodes.length; i++)
760   - this.setNodesVisibility(node.childNodes[i],forceHide || isFiltered);
761   -
762   - this.setNodeVisibility(node,!(forceHide || isFiltered));
763   - },
764   -
765   - setNodeVisibility : function(node,isVisible)
766   - {
767   - var record = store.getNodeById(node.internalId);
768   - var viewNode = Ext.fly(tree.getView().getNode(record));
769   - if (viewNode)
770   - {
771   - viewNode.setVisibilityMode(Ext.Element.DISPLAY);
772   - if (isVisible)
773   - {
774   - viewNode.show();
775   - this.applyDisableToNode(record);
776   - }
777   - else
778   - viewNode.hide();
779   - }
780   - },
781   -
782   - applyFilterToNode : function(node)
783   - {
784   - if (!node)
785   - return;
786   -
787   - var filter = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.explorer.id).filter;
788   -
789   - switch (node.get('nodeType'))
790   - {
791   - case 'localParam' :
792   - if (!filter || !filter['param'])
793   - {
794   - //no filter applied
795   - node.set('filtered',false);
796   - return;
797   - }
798   - var pos = node.get('depth') - 3; //depth from local param root node
799   - if (pos < 0 || pos > 2)
800   - {
801   - node.set('filtered',false);
802   - return;
803   - }
804   - var isFiltered = true;
805   - for (var i = 0; i < filter['param'].length; i++)
806   - {
807   - s = filter['param'][i].split(';');
808   - if (node.get('id') == s[pos])
809   - {
810   - isFiltered = false;
811   - break;
812   - }
813   - }
814   - node.set('filtered',isFiltered);
815   - break;
816   -
817   - case 'remoteSimuParam' :
818   - if (!filter || !filter['simu'] )
819   - {
820   - //no filter applied
821   - node.set('filtered',false);
822   - return;
823   - }
824   - var pos = node.get('depth') - 3; //depth from remote param root node
825   -
826   - if (pos < 0 || pos > 5)
827   - {
828   - node.set('filtered',false);
829   - return;
830   - }
831   - var isFiltered = true;
832   -
833   - for (var i = 0; i < filter['simu'].length; i++)
834   - {
835   - s = filter['simu'][i].split(';');
836   -
837   - if (node.get('id') == s[pos])
838   - {
839   - isFiltered = false;
840   - break;
841   - }
842   - }
843   - node.set('filtered',isFiltered);
844   - break;
845   - /*case 'alias' :
846   - if (!this.localParamFilter.result || this.localParamFilter.id == "" ||
847   - !node.isLeaf())
848   - {
849   - //no filter applied
850   - node.set('filtered',false);
851   - return;
852   - }
853   - var crtParam = node.get('id');
854   - crtParam = crtParam.replace('alias_','');
855   - crtParam = crtParam.replace(/_/g,':');
856   - var isFiltered = true;
857   - for (var i = 0; i < this.localParamFilter.result.length; i++)
858   - {
859   - s = this.localParamFilter.result[i].split(';');
860   - console.log(s[2]);
861   - if (crtParam == s[2])
862   - {
863   - isFiltered = false;
864   - break;
865   - }
866   - }
867   - node.set('filtered',isFiltered);
868   - break;*/
869   - default :
870   - return;
871   - }
872   - },
873   -
874   - applyFilterToNodes : function(node)
875   - {
876   - node.eachChild(function (child){
877   - tree.applyFilterToNodes(child);
878   - });
879   - tree.applyFilterToNode(node);
880   - },
881   -
882   - applyDisableToNode : function(node)
883   - {
884   - var crtNode = node;
885   - var disable = false;
886   -
887   - do
888   - {
889   - if (crtNode.get('disable'))
890   - {
891   - disable = true;
892   - break;
893   - }
894   - crtNode = crtNode.parentNode;
895   - } while (crtNode);
896   -
897   -
898   - var viewNode = Ext.fly(tree.getView().getNode(node));
899   - if (disable)
900   - {
901   - node.set('disable',true);
902   - viewNode.setStyle('opacity',0.5);
903   - }
904   - }
905   - });
906   -
907   - tree.addEvents('edition');
908   -
909   - return tree;
910   - },
911   -
912   - updateFilter : function()
913   - {
914   - var filter = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.explorer.id).filter;
915   -
916   - var keys = [];
917   - for (var f in filter) {
918   - if (hasOwnProperty.call(filter, f))
919   - keys.push(f);
920   - }
921   -
922   - var tree = this.query('#'+amdaUI.ExplorerUI.RESRC_TAB.TREE_ID)[0];
923   - tree.getView().refresh();
924   -
925   - for (var i = 0; i < keys.length; i++)
926   - {
927   - if (keys[i] == "_empty_")
928   - continue;
929   -
930   - switch (keys[i])
931   - {
932   - case 'param' :
933   - //apply filter to local datasets
934   - var localNode = tree.getRootNode().findChild('id','myLocalData-treeRootNode',true);
935   - tree.applyFilterToNodes(localNode);
936   - tree.setNodesVisibility(localNode,false);
937   - tree.applyDisableToNode(localNode);
938   -
939   - //apply filter to aliases
940   - var aliasNode = tree.getRootNode().findChild('id','alias-treeRootNode',true);
941   - tree.applyFilterToNodes(aliasNode);
942   - tree.setNodesVisibility(aliasNode,false);
943   - tree.applyDisableToNode(aliasNode);
944   - break;
945   -
946   - case 'simu' :
947   - //apply filter to simulation datasets (in remote data)
948   - var remoteNode = tree.getRootNode().findChild('id','myRemoteSimuData-treeRootNode',true);
949   - tree.applyFilterToNodes(remoteNode);
950   - tree.setNodesVisibility(remoteNode,false);
951   - tree.applyDisableToNode(remoteNode);
952   - break;
953   - }
954   - }
955   -
956   - this.dockedItems.getAt(1).items.items[0].select(filter['name']);
957   - }
  218 + ]);
  219 + this.updateFilter();
  220 + }
  221 + },
  222 + {
  223 + text: 'Target',
  224 + scope: this,
  225 + tooltip: {text: 'Sort out AMDA DataBase Data by Mission Main Target', align: 'bl-tl'},
  226 + enableToggle: true,
  227 + toggleGroup: 'sorting',
  228 + handler: function () {
  229 + var tree = Ext.getCmp(amdaUI.ExplorerUI.RESRC_TAB.TREE_ID);
  230 + tree.getStore().sort([{property: 'rank'}]);
  231 + this.updateFilter();
  232 + }
  233 + }
  234 + ]
  235 + };
  236 + Ext.apply(this, Ext.apply(arguments, myConf));
  237 + this.callParent(arguments);
  238 + },
  239 +
  240 + initTree: function (treeType) {
  241 + switch (treeType) {
  242 + case amdaUI.ExplorerUI.RESRC_TAB.TREE_TYPE:
  243 + treeId = amdaUI.ExplorerUI.RESRC_TAB.TREE_ID;
  244 + break;
  245 + case amdaUI.ExplorerUI.OPE_TAB.TREE_TYPE:
  246 + treeId = amdaUI.ExplorerUI.OPE_TAB.TREE_ID;
  247 + break;
  248 + case amdaUI.ExplorerUI.JOB_TAB.TREE_TYPE:
  249 + treeId = amdaUI.ExplorerUI.JOB_TAB.TREE_ID;
  250 + break;
  251 + default:
  252 + treeId = amdaUI.ExplorerUI.RESRC_TAB.TREE_ID;
  253 + break;
  254 + }
  255 +
  256 + var store = Ext.create('Ext.data.TreeStore', {
  257 + root: {
  258 + expanded: true,
  259 + nodeType: treeType
  260 + },
  261 + model: 'amdaModel.AmdaNode',
  262 + sorters: [
  263 + {
  264 + direction: 'ASC',
  265 + sorterFn: function (o1, o2) {
  266 + if (o1.get('nodeType') !== 'localParam')
  267 + return;
  268 +
  269 + return o1.get('text').toUpperCase() < o2.get('text').toUpperCase() ? -1 : 1;
  270 + }
  271 + }
  272 + ],
  273 + listeners: {
  274 + beforeload: function (store, operation) {
  275 + store.proxy.extraParams = {
  276 + nodeType: operation.node.get('nodeType')
  277 + };
  278 + }
  279 + }
  280 + });
  281 +
  282 + var menu = new Ext.menu.Menu();
  283 +
  284 + var tree = Ext.create('Ext.tree.Panel', {
  285 + id: treeId,
  286 + title: treeType,
  287 + store: store,
  288 + rootVisible: false,
  289 + animate: false,
  290 + hideHeaders: true,
  291 + selModel: Ext.create('Ext.selection.TreeModel', {
  292 + // ignoreRightMouseSelection: true,
  293 + mode: 'MULTI'
  294 + }),
  295 + viewConfig: {
  296 + plugins: {
  297 + ptype: 'treeviewdragdrop',
  298 + enableDrag: true,
  299 + enableDrop: true,
  300 + //TODO - BRE - Wait a fix for drag&drop issue
  301 + ddGroup: 'explorerTree',
  302 + pluginId: 'ddplugin',
  303 +
  304 + isValidDropPoint: function (node, position, dragZone, e, data) {
  305 + if (!node || !data.item) {
  306 + return false;
  307 + }
  308 + var view = this.view,
  309 + targetNode = view.getRecord(node),
  310 + draggedRecords = data.records,
  311 + dataLength = draggedRecords.length,
  312 + ln = draggedRecords.length,
  313 + i, record;
  314 +
  315 + // No drop position, or dragged records: invalid drop point
  316 + if (!(targetNode && position && dataLength)) {
  317 + return false;
  318 + }
  319 + // If the targetNode is within the folder we are dragging
  320 + for (i = 0; i < ln; i++) {
  321 + record = draggedRecords[i];
  322 + if (record.isNode && record.contains(targetNode)) {
  323 + return false;
  324 + }
  325 + }
  326 + // Respect the allowDrop field on Tree nodes
  327 + if (position === 'append' && targetNode.get('allowDrop') === false) {
  328 + return false;
  329 + }
  330 + else if (position != 'append' && targetNode.parentNode.get('allowDrop') === false) {
  331 + return false;
  332 + }
  333 + // If the target record is in the dragged dataset, then invalid drop
  334 + if (Ext.Array.contains(draggedRecords, targetNode)) {
  335 + return false;
  336 + }
  337 + //
  338 + if (dataLength > 1)
  339 + return false;
  340 +
  341 + var draggedRecord = draggedRecords[0];
  342 + //
  343 + switch (targetNode.data.nodeType) {
  344 + case 'localParam' :
  345 + case 'remoteParam' :
  346 + case 'remoteSimuParam' :
  347 + case 'myData' :
  348 + return false;
  349 + default :
  350 + if (draggedRecord.data.id == targetNode.data.nodeType + '-treeRootNode')
  351 + return false;
  352 + if ((position == 'before') && (targetNode.data.id == targetNode.data.nodeType + '-treeRootNode'))
  353 + return false;
  354 + return (draggedRecord.data.nodeType == targetNode.data.nodeType);
  355 + }
  356 + return false;
  357 + },
  358 + onViewRender: function (view) {
  359 + var me = this;
  360 +
  361 + view.on('itemupdate', function (record, index, node, opts) {
  362 + var forceHide = false;
  363 + var crtRec = record.parentNode;
  364 + while (crtRec && !forceHide) {
  365 + if (crtRec.get('filtered'))
  366 + forceHide = crtRec.get('filtered');
  367 + crtRec = crtRec.parentNode;
  368 + }
  369 + tree.setNodesVisibility(record, forceHide);
  370 + tree.applyDisableToNode(record);
  371 + });
  372 +
  373 + view.on('itemadd', function (records, index, node, opts) {
  374 + Ext.each(records, function (rec) {
  375 + tree.applyFilterToNode(rec);
  376 + tree.applyDisableToNode(rec);
  377 + });
  378 + });
  379 +
  380 + view.on('afteritemexpand', function (record, index, node, opts) {
  381 + var forceHide = false;
  382 + var crtRec = record.parentNode;
  383 + while (crtRec && !forceHide) {
  384 + if (crtRec.get('filtered'))
  385 + forceHide = crtRec.get('filtered');
  386 + crtRec = crtRec.parentNode;
  387 +
  388 + }
  389 + tree.setNodesVisibility(record, forceHide);
  390 + tree.applyDisableToNode(record);
  391 + });
  392 +
  393 + if (me.enableDrag) {
  394 + me.dragZone = Ext.create('Ext.tree.ViewDragZone', {
  395 + view: view,
  396 + ddGroup: me.dragGroup || me.ddGroup,
  397 + dragText: me.dragText,
  398 + repairHighlightColor: me.nodeHighlightColor,
  399 + repairHighlight: me.nodeHighlightOnRepair
  400 + });
  401 + }
  402 +
  403 + if (me.enableDrop) {
  404 + me.dropZone = Ext.create('Ext.tree.ViewDropZone', {
  405 + view: view,
  406 + ddGroup: me.dropGroup || me.ddGroup,
  407 + allowContainerDrops: me.allowContainerDrops,
  408 + appendOnly: me.appendOnly,
  409 + allowParentInserts: me.allowParentInserts,
  410 + expandDelay: me.expandDelay,
  411 + dropHighlightColor: me.nodeHighlightColor,
  412 + dropHighlight: me.nodeHighlightOnDrop,
  413 + isValidDropPoint: me.isValidDropPoint
  414 + });
  415 + }
  416 + }
  417 + },
  418 + listeners: {
  419 + beforedrop: function (node, data, overModel, dropPosition) {
  420 + var parentId;
  421 + switch (dropPosition) {
  422 + case 'append' :
  423 + if (overModel.isLeaf())
  424 + parentId = overModel.parentNode.get('id');
  425 + else
  426 + parentId = overModel.get('id');
  427 +
  428 + if (!overModel.isExpanded() && overModel.isExpandable()) {
  429 + myDesktopApp.warningMsg('Please open the folder before node adding');
  430 + return false;
  431 + }
  432 + break;
  433 + case 'before' :
  434 + case 'after' :
  435 + parentId = overModel.parentNode.get('id');
  436 + break;
  437 + }
  438 +
  439 + Ext.each(data.records, function (rec) {
  440 + rec.renameDD(parentId, function (result) {
  441 + if (result) {
  442 + if (!result.id) {
  443 + Ext.Msg.show({
  444 + title: 'Drop is impossible',
  445 + msg: result.error,
  446 + buttons: Ext.Msg.OK,
  447 + icon: Ext.MessageBox.WARNING
  448 + });
  449 +
  450 + return false;
  451 + }
  452 + }
  453 + else {
  454 + Ext.Msg.show({
  455 + title: 'Drop is impossible',
  456 + msg: 'Cannot connect to the server',
  457 + buttons: Ext.Msg.OK,
  458 + icon: Ext.MessageBox.WARNING
  459 + });
  460 +
  461 + return false;
  462 + }
  463 +
  464 + return true;
  465 + });
  466 + });
  467 + }
  468 + }
  469 + },
  470 + listeners: {
  471 + itemmouseenter: function (view, record, item) {
  472 + if (record.get('isParameter')) {
  473 + var el = Ext.get(item),
  474 + td = el.down('td > div');
  475 + td.setStyle('cursor', 'crosshair');
  476 + }
  477 + else {
  478 + var el = Ext.get(item),
  479 + td = el.down('td > div');
  480 + td.setStyle('cursor', 'pointer');
  481 + }
  482 + },
  483 +
  484 + itemcontextmenu: function (view, rec, item, index, e) {
  485 + // Add record to selection model
  486 + view.ownerCt.getSelectionModel().select(rec);
  487 +
  488 + // block other events
  489 + e.stopEvent();
  490 +
  491 + // clear menu items
  492 + menu.removeAll();
  493 + var menuItems;
  494 +
  495 + // if it's a single selection
  496 + if (view.ownerCt.getSelectionModel().selected.length === 1) {
  497 + // get items menu corresponding to right clicked record
  498 + menuItems = rec.getContextMenuItems(this);
  499 +
  500 + } else if (view.ownerCt.getSelectionModel().selected.length > 1) {
  501 + // get items menu corresponding to right clicked record
  502 + menuItems = rec.getContextMenuMultiItems(this);
  503 + }
  504 + // if there's at least one item menu
  505 + if (menuItems && menuItems.length) {
  506 + // add the items
  507 + menu.add(menuItems);
  508 + // add listener on right clicked record
  509 + var onRecordClick = function (menu, item, e, eOpts) {
  510 + if (this.myGetOwnerTree().getSelectionModel().isSelected(this)) {
  511 + //Dispatch click event to the record
  512 + this.onMenuItemClick(menu, item, e);
  513 + }
  514 + //Remove old click listener
  515 + menu.removeListener('click', onRecordClick, this);
  516 + };
  517 +
  518 + menu.addListener('click', onRecordClick, rec);
  519 + // then show menu
  520 + menu.showAt(e.getXY());
  521 + }
  522 + },
  523 +
  524 + itemdblclick: function (view, record, item, index, event) {
  525 + event.stopEvent();
  526 + // first check if it is for SAVE-START-STOP plugin...
  527 + if (Ext.PluginManager.getCount() > 0 &&
  528 + record.get('nodeType') == amdaModel.TimeTableNode.nodeType && record.isLeaf()) {
  529 + var zmgr = myDesktopApp.desktop.getDesktopZIndexManager();
  530 + var winActive = zmgr.getActive();
  531 + var winId = winActive.getId();
  532 + if (winId == 'explorer-win') {
  533 + zmgr.eachTopDown(function (win) {
  534 + var id = win.getId();
  535 + if (id !== 'explorer-win') {
  536 + winId = id;
  537 + return false;
  538 + }
  539 + });
  540 + }
  541 + }
  542 +
  543 + if (record.get('nodeType') == 'remoteParam' && !record.isLeaf()
  544 + && !record.get('isParameter')) {
  545 + myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.interop.id, true, function (module) {
  546 + module.createWindow(record.getBaseId());
  547 + });
  548 + }
  549 +
  550 + if (record.isLeaf() || record.data.isParameter)
  551 + switch (record.get('nodeType')) {
  552 + case 'myData' :
  553 + case 'myDataParam' :
  554 + case 'derivedParam' :
  555 + case 'timeTable' :
  556 + case 'sharedtimeTable' :
  557 + case 'sharedcatalog' :
  558 + case 'catalog' :
  559 + case 'request' :
  560 + case 'condition' :
  561 + record.editLeaf();
  562 + break;
  563 + case 'localParam' :
  564 + case 'remoteParam':
  565 + case 'remoteSimuParam':
  566 + record.createAlias(record);
  567 + break;
  568 + case 'bkgWorks' :
  569 + if (!record.get('object')) {
  570 + AmdaAction.getObject(record.get('id'), record.get('nodeType'), record.getObjectCallback, record);
  571 + }
  572 + else {
  573 + if (record.get('status') == 'done') {
  574 + var isInteractive = false;
  575 + var isNewTab = true;
  576 + record.editNode(isNewTab, isInteractive);
  577 + }
  578 + else {
  579 + myDesktopApp.infoMsg('Job Status: ' + record.get('status'));
  580 + }
  581 + }
  582 + break;
  583 + }
  584 + },
  585 +
  586 + beforeselect: function (view, node, index, options) {
  587 + // if there's at least one node already selected
  588 + if (view.selected.length
  589 + //AND (the node which is beeing selected has a different nodeType than the first selected node OR the first selected node isn't a leaf
  590 + && (node.get('nodeType') !== view.selected.items[0].get('nodeType') || !view.selected.items[0].isLeaf())
  591 + // OR the node which is beeing selected has no nodeType OR it isn't a leaf OR
  592 + || !node.get('nodeType') || !node.isLeaf()
  593 + ) {
  594 + // clear old selection
  595 + view.deselectAll();
  596 + }
  597 + },
  598 +
  599 + afterrender: function (comp) {
  600 + var view = comp.getView();
  601 + view.tip = Ext.create('Ext.tip.ToolTip', {
  602 + // The overall target element.
  603 + target: view.el,
  604 + // Each grid row causes its own seperate show and hide.
  605 + delegate: view.itemSelector,
  606 + dismissDelay: 0,
  607 + // showDelay: 100,
  608 + // anchor: 'left',
  609 + // Moving within the row should not hide the tip.
  610 + trackMouse: true,
  611 + autoRender: true,
  612 + listeners: {
  613 + // Change content dynamically depending on which element triggered the show.
  614 + beforeshow: function updateTipBody(tip) {
  615 + if (view.getRecord(tip.triggerElement)) {
  616 + var info = view.getRecord(tip.triggerElement).get('info');
  617 + if (!info || info == '') {
  618 + tip.addCls('hide');
  619 + }
  620 + else {
  621 + tip.removeCls('hide');
  622 + tip.update(info);
  623 + }
  624 + }
  625 + }
  626 + }
  627 + });
  628 + },
  629 + // if remote base is empty - open interoperability module
  630 + itemexpand: function (node) {
  631 + if (node.get('nodeType') == amdaModel.RemoteParamNode.nodeType
  632 + && node.getDepth() == 3 && !node.hasChildNodes()) {
  633 + node.addData();
  634 + }
  635 + },
  636 + scope: this
  637 + },
  638 +
  639 + hideHeaders: true,
  640 + // must define a column with a field to enable editor
  641 + columns: [
  642 + {
  643 + xtype: 'treetoolcolumn',
  644 + text: 'Name',
  645 + flex: 1,
  646 + dataIndex: 'text',
  647 + tool: 'info', // this references the "tools" object on the prototype
  648 + toolHandler: function (view, cell, recordIndex, cellIndex, e) {
  649 + var tooltype = e.target.getAttribute("tooltype");
  650 + var record = view.store.getAt(recordIndex);
  651 + switch (tooltype) {
  652 + case 'info' :
  653 + myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.info.id, true, function (module) {
  654 + module.createWindow(record.get('help'), record.get('text'));
  655 + });
  656 + break;
  657 + }
  658 + },
  659 + toolIsVisible: function (record) {
  660 +
  661 + switch (record.get('nodeType')) {
  662 + case 'localParam' :
  663 + case 'remoteParam' :
  664 + case 'remoteSimuParam' :
  665 +
  666 + return record.get('help') != '';
  667 + }
  668 + return false;
  669 + },
  670 + field: {
  671 + validFlag: true,
  672 + listeners: {
  673 + change: function (field, newValue, oldValue, eOpts) {
  674 + var explModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.explorer.id);
  675 + var explUI = explModule.getUiContent();
  676 + var activeTreePanel = explUI.getActiveTab();
  677 +
  678 + var editedNode = activeTreePanel.getSelectionModel().selected.items[0];
  679 + if (editedNode) {
  680 + editedNode.isValidName(newValue, function (res) {
  681 + var validFlag = true;
  682 + if (newValue === amdaModel.AmdaNode.NEW_DIR_NAME) {
  683 + validFlag = 'Field is not modified'
  684 + } else if (!res) {
  685 + validFlag = 'Error during object validation';
  686 + } else if (!res.valid) {
  687 + if (res.error) {
  688 + validFlag = res.error;
  689 + } else {
  690 + validFlag = 'Invalid object name';
  691 + }
  692 + }
  693 + if (validFlag === true) {
  694 + field.lastValid = newValue;
  695 + } else {
  696 + field.markInvalid(validFlag);
  697 + }
  698 + field.validFlag = validFlag;
  699 + });
  700 + }
  701 + }
  702 + },
  703 + scope: this
  704 + }
  705 + }
  706 + ],
  707 + //add our custom editor plugin
  708 + plugins: [new MyTreeEditor({
  709 + pluginId: 'treeEditor',
  710 + listeners: {
  711 + 'edit': function (editor, e) {
  712 + if (e.column.field.validFlag !== true) {
  713 + if (e.column.field.lastValid) {
  714 + e.record.data[e.field] = e.column.field.lastValid;
  715 + } else {
  716 + e.record.remove(true);
  717 + }
  718 + }
  719 + },
  720 + 'beforeedit': function (editor, e) {
  721 + e.column.field.fireEvent('change', e.column.field, e.value, '');
  722 + }
  723 + },
  724 + scope: this
  725 + })],
  726 +
  727 + setNodesVisibility: function (node, forceHide) {
  728 + var isFiltered = node.get('filtered');
  729 +
  730 + for (var i = 0; i < node.childNodes.length; i++)
  731 + this.setNodesVisibility(node.childNodes[i], forceHide || isFiltered);
  732 +
  733 + this.setNodeVisibility(node, !(forceHide || isFiltered));
  734 + },
  735 +
  736 + setNodeVisibility: function (node, isVisible) {
  737 + var record = store.getNodeById(node.internalId);
  738 + var viewNode = Ext.fly(tree.getView().getNode(record));
  739 + if (viewNode) {
  740 + viewNode.setVisibilityMode(Ext.Element.DISPLAY);
  741 + if (isVisible) {
  742 + viewNode.show();
  743 + this.applyDisableToNode(record);
  744 + }
  745 + else
  746 + viewNode.hide();
  747 + }
  748 + },
  749 +
  750 + applyFilterToNode: function (node) {
  751 + if (!node)
  752 + return;
  753 +
  754 + var filter = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.explorer.id).filter;
  755 +
  756 + switch (node.get('nodeType')) {
  757 + case 'localParam' :
  758 + if (!filter || !filter['param']) {
  759 + //no filter applied
  760 + node.set('filtered', false);
  761 + return;
  762 + }
  763 + var pos = node.get('depth') - 3; //depth from local param root node
  764 + if (pos < 0 || pos > 2) {
  765 + node.set('filtered', false);
  766 + return;
  767 + }
  768 + var isFiltered = true;
  769 + for (var i = 0; i < filter['param'].length; i++) {
  770 + s = filter['param'][i].split(';');
  771 + if (node.get('id') == s[pos]) {
  772 + isFiltered = false;
  773 + break;
  774 + }
  775 + }
  776 + node.set('filtered', isFiltered);
  777 + break;
  778 +
  779 + case 'remoteSimuParam' :
  780 + if (!filter || !filter['simu']) {
  781 + //no filter applied
  782 + node.set('filtered', false);
  783 + return;
  784 + }
  785 + var pos = node.get('depth') - 3; //depth from remote param root node
  786 +
  787 + if (pos < 0 || pos > 5) {
  788 + node.set('filtered', false);
  789 + return;
  790 + }
  791 + var isFiltered = true;
  792 +
  793 + for (var i = 0; i < filter['simu'].length; i++) {
  794 + s = filter['simu'][i].split(';');
  795 +
  796 + if (node.get('id') == s[pos]) {
  797 + isFiltered = false;
  798 + break;
  799 + }
  800 + }
  801 + node.set('filtered', isFiltered);
  802 + break;
  803 + /*case 'alias' :
  804 + if (!this.localParamFilter.result || this.localParamFilter.id == "" ||
  805 + !node.isLeaf()) {
  806 + //no filter applied
  807 + node.set('filtered',false);
  808 + return;
  809 + }
  810 + var crtParam = node.get('id');
  811 + crtParam = crtParam.replace('alias_','');
  812 + crtParam = crtParam.replace(/_/g,':');
  813 + var isFiltered = true;
  814 + for (var i = 0; i < this.localParamFilter.result.length; i++) {
  815 + s = this.localParamFilter.result[i].split(';');
  816 + console.log(s[2]);
  817 + if (crtParam == s[2]) {
  818 + isFiltered = false;
  819 + break;
  820 + }
  821 + }
  822 + node.set('filtered',isFiltered);
  823 + break;*/
  824 + default :
  825 + return;
  826 + }
  827 + },
  828 +
  829 + applyFilterToNodes: function (node) {
  830 + node.eachChild(function (child) {
  831 + tree.applyFilterToNodes(child);
  832 + });
  833 + tree.applyFilterToNode(node);
  834 + },
  835 +
  836 + applyDisableToNode: function (node) {
  837 + var crtNode = node;
  838 + var disable = false;
  839 +
  840 + do {
  841 + if (crtNode.get('disable')) {
  842 + disable = true;
  843 + break;
  844 + }
  845 + crtNode = crtNode.parentNode;
  846 + } while (crtNode);
  847 +
  848 +
  849 + var viewNode = Ext.fly(tree.getView().getNode(node));
  850 + if (disable) {
  851 + node.set('disable', true);
  852 + viewNode.setStyle('opacity', 0.5);
  853 + }
  854 + }
  855 + });
  856 +
  857 + tree.addEvents('edition');
  858 +
  859 + return tree;
  860 + },
  861 +
  862 + updateFilter: function () {
  863 + var filter = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.explorer.id).filter;
  864 +
  865 + var keys = [];
  866 + for (var f in filter) {
  867 + if (hasOwnProperty.call(filter, f))
  868 + keys.push(f);
  869 + }
  870 +
  871 + var tree = this.query('#' + amdaUI.ExplorerUI.RESRC_TAB.TREE_ID)[0];
  872 + tree.getView().refresh();
  873 +
  874 + for (var i = 0; i < keys.length; i++) {
  875 + if (keys[i] == "_empty_")
  876 + continue;
  877 +
  878 + switch (keys[i]) {
  879 + case 'param' :
  880 + //apply filter to local datasets
  881 + var localNode = tree.getRootNode().findChild('id', 'myLocalData-treeRootNode', true);
  882 + tree.applyFilterToNodes(localNode);
  883 + tree.setNodesVisibility(localNode, false);
  884 + tree.applyDisableToNode(localNode);
  885 +
  886 + //apply filter to aliases
  887 + var aliasNode = tree.getRootNode().findChild('id', 'alias-treeRootNode', true);
  888 + tree.applyFilterToNodes(aliasNode);
  889 + tree.setNodesVisibility(aliasNode, false);
  890 + tree.applyDisableToNode(aliasNode);
  891 + break;
  892 +
  893 + case 'simu' :
  894 + //apply filter to simulation datasets (in remote data)
  895 + var remoteNode = tree.getRootNode().findChild('id', 'myRemoteSimuData-treeRootNode', true);
  896 + tree.applyFilterToNodes(remoteNode);
  897 + tree.setNodesVisibility(remoteNode, false);
  898 + tree.applyDisableToNode(remoteNode);
  899 + break;
  900 + }
  901 + }
  902 +
  903 + this.dockedItems.getAt(1).items.items[0].select(filter['name']);
  904 + }
958 905 });
959 906  
960 907 // MyTreeEditor
961   -Ext.define( 'MyTreeEditor', {
962   - extend: 'Ext.grid.plugin.CellEditing',
963   - alias: 'editing.treeeditor',
964   -
965   - // initialization method of plugin
966   - init: function(cmp) {
967   - var me = this;
968   - me.hostCmp = cmp;
969   - // on parent event
970   - me.hostCmp.on({
971   - // on edition event
972   - edition : {
973   - delay: 50,
974   - fn : function(view, record, item, index, e){
975   - // view.getHeaderAtIndex(0).field.validFlag = 'Not modified';
976   - // call the start edition method
977   - me.startEdit(record, view.getHeaderAtIndex(0));
978   - },
979   - scope: me
980   - }
981   - });
982   - me.callParent(arguments);
983   - },
984   -
985   - /**
986   - * Cancel any active editing.
987   - */
988   - cancelEdit: function() {
989   - var me = this,
990   - activeEd = me.getActiveEditor(),
991   - viewEl = me.grid.getView().getEl(me.getActiveColumn());
992   -
993   - me.setActiveEditor(null);
994   - me.setActiveColumn(null);
995   - me.setActiveRecord(null);
996   - if (activeEd) {
997   - activeEd.cancelEdit();
998   - viewEl.focus();
999   - this.fireEvent('canceledit', activeEd, me.context);
1000   - }
1001   - },
1002   -
1003   - /**
1004   - * overwrite the initEditTriggers to disable edition on click/dblclick
1005   - * and to add custom
1006   - */
1007   - initEditTriggers: function()
1008   - {
1009   - var me = this,
1010   - view = me.view;
1011   -
1012   - me.on({
1013   - edit: function(editor,event){
1014   - // if there is a modification
1015   - if (event.originalValue !== event.value) {
1016   - // delegate rename action on model
1017   - event.record.rename(event.value,function(result){
1018   - // if a result has been returned : success
1019   - if(result) {
1020   - // delegate commit action to delete modification flag
1021   - event.record.commit();
1022   - var rec = event.record.data;
1023   - // in case of directory
1024   - if (!rec.leaf){
1025   - // set folder's ID returned by server
1026   - rec.id = result.id;
1027   - }
1028   - } else { // in case of transaction error
1029   - // reset originalValue
1030   - event.record.value = event.originalValue;
1031   - event.record.set('text', event.originalValue);
1032   - event.record.commit();
1033   - }
1034   - });
1035   - }
1036   - }
1037   - });
1038   -
1039   - // enable Enter key and Esc Key
1040   - view.on('render', function() {
1041   - me.keyNav = Ext.create('Ext.util.KeyNav', view.el, {
1042   - enter: me.onEnterKey,
1043   - esc: me.onEscKey,
1044   - scope: me
1045   - });
1046   - }, me, { single: true });
1047   - },
1048   - //overwrite the getEditing context because we do not need the rowId
1049   - getEditingContext: function(record, columnHeader) {
1050   - var me = this,
1051   - grid = me.grid,
1052   - store = grid.store,
1053   - colIdx,
1054   - view = grid.getView(),
1055   - value;
1056   -
1057   - // getting colIdx and real columnHeader
1058   - if (Ext.isNumber(columnHeader)) {
1059   - colIdx = columnHeader;
1060   - columnHeader = grid.headerCt.getHeaderAtIndex(colIdx);
1061   - } else {
1062   - colIdx = columnHeader.getIndex();
1063   - }
1064   - // getting current value
1065   - value = record.get(columnHeader.dataIndex);
1066   -
1067   - // return editing context
1068   - return {
1069   - grid: grid,
1070   - record: record,
1071   - field: columnHeader.dataIndex,
1072   - value: value,
1073   - column: columnHeader,
1074   - colIdx: colIdx,
1075   - view: columnHeader.getOwnerHeaderCt().view
1076   - };
1077   - }
  908 +Ext.define('MyTreeEditor', {
  909 + extend: 'Ext.grid.plugin.CellEditing',
  910 + alias: 'editing.treeeditor',
  911 +
  912 + // initialization method of plugin
  913 + init: function (cmp) {
  914 + var me = this;
  915 + me.hostCmp = cmp;
  916 + // on parent event
  917 + me.hostCmp.on({
  918 + // on edition event
  919 + edition: {
  920 + delay: 50,
  921 + fn: function (view, record, item, index, e) {
  922 + // view.getHeaderAtIndex(0).field.validFlag = 'Not modified';
  923 + // call the start edition method
  924 + me.startEdit(record, view.getHeaderAtIndex(0));
  925 + },
  926 + scope: me
  927 + }
  928 + });
  929 + me.callParent(arguments);
  930 + },
  931 +
  932 + /**
  933 + * Cancel any active editing.
  934 + */
  935 + cancelEdit: function () {
  936 + var me = this,
  937 + activeEd = me.getActiveEditor(),
  938 + viewEl = me.grid.getView().getEl(me.getActiveColumn());
  939 +
  940 + me.setActiveEditor(null);
  941 + me.setActiveColumn(null);
  942 + me.setActiveRecord(null);
  943 + if (activeEd) {
  944 + activeEd.cancelEdit();
  945 + viewEl.focus();
  946 + this.fireEvent('canceledit', activeEd, me.context);
  947 + }
  948 + },
  949 +
  950 + /**
  951 + * overwrite the initEditTriggers to disable edition on click/dblclick
  952 + * and to add custom
  953 + */
  954 + initEditTriggers: function () {
  955 + var me = this,
  956 + view = me.view;
  957 +
  958 + me.on({
  959 + edit: function (editor, event) {
  960 + // if there is a modification
  961 + if (event.originalValue !== event.value) {
  962 + // delegate rename action on model
  963 + event.record.rename(event.value, function (result) {
  964 + // if a result has been returned : success
  965 + if (result) {
  966 + // delegate commit action to delete modification flag
  967 + event.record.commit();
  968 + var rec = event.record.data;
  969 + // in case of directory
  970 + if (!rec.leaf) {
  971 + // set folder's ID returned by server
  972 + rec.id = result.id;
  973 + }
  974 + } else { // in case of transaction error
  975 + // reset originalValue
  976 + event.record.value = event.originalValue;
  977 + event.record.set('text', event.originalValue);
  978 + event.record.commit();
  979 + }
  980 + });
  981 + }
  982 + }
  983 + });
  984 +
  985 + // enable Enter key and Esc Key
  986 + view.on('render', function () {
  987 + me.keyNav = Ext.create('Ext.util.KeyNav', view.el, {
  988 + enter: me.onEnterKey,
  989 + esc: me.onEscKey,
  990 + scope: me
  991 + });
  992 + }, me, {single: true});
  993 + },
  994 + //overwrite the getEditing context because we do not need the rowId
  995 + getEditingContext: function (record, columnHeader) {
  996 + var me = this,
  997 + grid = me.grid,
  998 + store = grid.store,
  999 + colIdx,
  1000 + view = grid.getView(),
  1001 + value;
  1002 +
  1003 + // getting colIdx and real columnHeader
  1004 + if (Ext.isNumber(columnHeader)) {
  1005 + colIdx = columnHeader;
  1006 + columnHeader = grid.headerCt.getHeaderAtIndex(colIdx);
  1007 + } else {
  1008 + colIdx = columnHeader.getIndex();
  1009 + }
  1010 + // getting current value
  1011 + value = record.get(columnHeader.dataIndex);
  1012 +
  1013 + // return editing context
  1014 + return {
  1015 + grid: grid,
  1016 + record: record,
  1017 + field: columnHeader.dataIndex,
  1018 + value: value,
  1019 + column: columnHeader,
  1020 + colIdx: colIdx,
  1021 + view: columnHeader.getOwnerHeaderCt().view
  1022 + };
  1023 + }
1078 1024 });
... ...