diff --git a/js/app/models/InteractiveNode.js b/js/app/models/InteractiveNode.js index 06f20bb..2e486e9 100644 --- a/js/app/models/InteractiveNode.js +++ b/js/app/models/InteractiveNode.js @@ -204,6 +204,10 @@ Ext.define('amdaModel.InteractiveNode', { this.set('info',res.info); } + if (res.last_update) { + this.get('object').set('last_update', res.last_update); + } + // myDataParam and Parameter special update this.specialUpdate(res, false); @@ -280,9 +284,29 @@ Ext.define('amdaModel.InteractiveNode', { // set the tooltip this.set('info',res.info); } + + var reloadObject = false; + if (res.last_update) { + this.get('object').set('last_update', res.last_update); + reloadObject = true; + } + //set globalStart & global Stop to be used for time selection this.specialUpdate(res, true); + // reload object into the view of corresponding Module + var me = this; + if (reloadObject) { + myDesktopApp.getLoadedModule(this.get('moduleId'), true, function (module) { + if (!opt || !opt.plot) { + module.getUiContent().setObject(me.get('object')); + } + else { + module.getUiContent().reloadPlot(me); + } + }); + } + //TODO do we need this commission ??? // fix the modifications for object this.get('object').commit(); diff --git a/js/app/models/Parameter.js b/js/app/models/Parameter.js index e7f9256..06af5e9 100644 --- a/js/app/models/Parameter.js +++ b/js/app/models/Parameter.js @@ -19,13 +19,16 @@ Ext.define('amdaModel.Parameter', { extend: 'amdaModel.AmdaObject', fields : [ - {name: 'timestep', type: 'string'}, + {name: 'timestep', type: 'string'}, // only used if 'sampling_mode' is 'timestep' {name: 'units', type: 'string'}, {name: 'buildchain', type: 'string'}, {name: 'description', type: 'string'}, {name: 'ytitle', type: 'string'}, - {name: 'dim_1', type: 'number'}, - {name: 'dim_2', type: 'number'} + {name: 'dim_1', type: 'number'}, + {name: 'dim_2', type: 'number'}, + {name: 'last_update', type: 'int', defaultValue: 0}, + {name: 'sampling_mode', type: 'string', defaultValue: 'timestep'}, // 'timestep' or 'refparam' + {name: 'reference_param', type: 'string'} // only used if 'sampling_mode' is 'refparam' ], /** @@ -54,7 +57,9 @@ Ext.define('amdaModel.Parameter', { myValues.dim_1 = this.get('dim_1'); myValues.dim_2 = this.get('dim_2'); myValues.nodeType = amdaModel.DerivedParamNode.nodeType; + myValues.sampling_mode = this.get('sampling_mode'); + myValues.reference_param = this.get('reference_param'); return myValues; } -}); \ No newline at end of file +}); diff --git a/js/app/views/ParameterUI.js b/js/app/views/ParameterUI.js index 1a0e53e..50dd5d7 100755 --- a/js/app/views/ParameterUI.js +++ b/js/app/views/ParameterUI.js @@ -83,7 +83,7 @@ Ext.define('amdaUI.ParameterUI', setObject : function (object) { this.object = object; - // load object into form + // load object into form this.formPanel.getForm().loadRecord(this.object); }, @@ -140,7 +140,9 @@ Ext.define('amdaUI.ParameterUI', var obj = { paramId : 'ws_'+this.object.get('name'), buildchain:this.object.get('buildchain'), - timestep:this.object.get('timestep') + timestep:this.object.get('timestep'), + reference_param: this.object.get('reference_param'), + sampling_mode: this.object.get('sampling_mode') }; loadMask.show(); AmdaAction.generateParamInfo(obj, function (result, e) { @@ -169,12 +171,11 @@ Ext.define('amdaUI.ParameterUI', }); }, - /** * save method called by Save button */ saveProcess : function(toRename) - { + { if(this.object.dirty) { // Parameter Module @@ -268,6 +269,7 @@ Ext.define('amdaUI.ParameterUI', { this.fieldName = new Ext.form.field.Text({ labelAlign: 'top', itemId: 'formParamName', + labelPad: 0, fieldLabel: 'Parameter Name', name : 'name', allowBlank : false, //blankText : 'Name is required', @@ -293,11 +295,12 @@ Ext.define('amdaUI.ParameterUI', this.constructionField = new extensions.SelectableTextArea({ labelAlign: 'top', + labelPad: 0, itemId: 'formParamConstructParameter', fieldLabel:'<img amda_clicktip="constructParameter" src="js/resources/images/16x16/info_mini.png"/> Construct Parameter', allowBlank : false, blankText : 'Construct Parameter is required', name : 'buildchain', - flex: 0.9, + flex: 0.6, validateOnChange: false, validateOnBlur: false, validator : this.isBalanced, @@ -401,6 +404,90 @@ Ext.define('amdaUI.ParameterUI', // } // } }); + + var samplingmode_store = new Ext.data.ArrayStore({ + fields: ['id', 'name'], + data: [ + ['timestep', 'Time Step'], + ['refparam', 'Ref. Parameter'] + ] + }); + + this.timeStepField = new Ext.form.NumberField({ + fieldLabel: '<img amda_clicktip="resamplingStep" src="js/resources/images/16x16/info_mini.png"/> Time Step (sec)', + labelAlign: 'top', + labelPad: 0, + blankText : 'Time Step is required', + name : 'timestep', + minValue : 0.001, + decimalPrecision : 10, + hideTrigger: true, + width: 150, + validateOnBlur: false + }); + + this.refParamField = new Ext.form.TextField({ + fieldLabel: '<img amda_clicktip="resamplingRefParam" src="js/resources/images/16x16/info_mini.png"/> Reference Param.', + labelAlign: 'top', + labelPad: 0, + name : 'reference_param', + width: 150, + hidden: true, + listeners: { + afterrender: function(field, eOpts ){ + var paramTarget = new Ext.dd.DropTarget(field.el.dom, + { + ddGroup: 'explorerTree', + notifyEnter: function(ddSource, e, data) { + }, + notifyDrop: function(ddSource, e, data) { + var selectedRecord = ddSource.dragData.records[0]; + switch (selectedRecord.$className) { + case 'amdaModel.LocalParamNode' : + case 'amdaModel.RemoteParamNode' : + case 'amdaModel.RemoteSimuParamNode' : + if (!selectedRecord.get('isParameter') || selectedRecord.get('disable')) + return false; + if (selectedRecord.get('alias') != "" ) + field.setValue("#"+selectedRecord.get('alias')); + else + field.setValue(selectedRecord.get('id')); + return true; + case 'amdaModel.AliasNode' : + if (!selectedRecord.isLeaf()) + return false; + field.setValue("#"+selectedRecord.get('text')); + return true; + case 'amdaModel.DerivedParamNode' : + if (!selectedRecord.isLeaf()) + return false; + field.setValue("ws_"+selectedRecord.get('text')); + return true; + case 'amdaModel.MyDataParamNode' : + if (!selectedRecord.isLeaf()) + return false; + field.setValue("wsd_"+selectedRecord.get('text')); + return true; + default: + return false; + } + return true; + } + } + ); + }, + scope: this + } + }); + + this.samplingDefContainer = new Ext.container.Container({ + border: false, + items: [ + this.timeStepField, + this.refParamField + ], + width: 150 + }); this.formPanel = new Ext.form.Panel({ id: 'vbox-paramForm', @@ -411,7 +498,7 @@ Ext.define('amdaUI.ParameterUI', trackResetOnLoad: true, //reset to the last loaded record layout: { type: 'vbox', - defaultMargins: {top: 10, left:10, bottom:5, right:5}, + defaultMargins: {top: 5, left:5, bottom:10, right:10}, align: 'stretch' }, defaults: { @@ -428,7 +515,8 @@ Ext.define('amdaUI.ParameterUI', }, defaultType: 'textfield', defaults: { - labelAlign: 'top' + labelAlign: 'top', + labelPad: 0 }, items: [ this.fieldName, @@ -436,17 +524,40 @@ Ext.define('amdaUI.ParameterUI', xtype:'component', width: 20 }, { - xtype : 'numberfield', - itemId: 'formParamTimeStep', fieldLabel: '<img amda_clicktip="resamplingStep" src="js/resources/images/16x16/info_mini.png"/> Time Step (sec)', labelAlign: 'top', - allowBlank : false, blankText : 'Time Step is required', - name : 'timestep', - minValue : 0.001, - decimalPrecision : 10, - hideTrigger: true, + fieldLabel: 'Last modification', + xtype: 'displayfield', + name : 'last_update', width: 150, - //validateOnChange: false, - validateOnBlur: false + renderer: function(value, field) { + var tpl = new Ext.XTemplate('<p style="font-style:italic;color:gray;margin:0;">{date}</>'); + var mod_date = 'Not saved'; + if (value > 0) + mod_date = Ext.Date.format(new Date(value*1000), "Y-m-d\\TH:i:s"); + return tpl.apply({date: mod_date}); + }, }, + { + xtype: 'combo', + fieldLabel: 'Sampling mode', + name: 'sampling_mode', + queryMode: 'local', + editable: false, + valueField: 'id', + displayField: 'name', + store: samplingmode_store, + value: samplingmode_store.first(), + listeners: { + change: function(field, value) { + this.timeStepField.setVisible(value != 'refparam'); + this.refParamField.setVisible(value == 'refparam'); + }, + scope: this + } + }, + { + xtype:'component', width: 20 + }, + this.samplingDefContainer, { itemId: 'formParamUnit', fieldLabel: 'Units', diff --git a/php/classes/DerivedParamMgr.php b/php/classes/DerivedParamMgr.php index 1a9a16e..6ebbba3 100644 --- a/php/classes/DerivedParamMgr.php +++ b/php/classes/DerivedParamMgr.php @@ -138,12 +138,13 @@ class DerivedParamMgr extends AmdaObjectMgr { if (file_exists(USERWSDIR.'Alias.xml')) { $p->buildchain = $this->resetAlias($p->buildchain); - } + } + $p->last_update = time(); // switch between myData and Derived $this->createObjectDescription($p); $this->addToContent($p, $folder); - return array('id' => $this->id, 'info' => $p->buildchain, 'dim_1' => $p->dim_1, 'dim_2' => $p->dim_2); + return array('id' => $this->id, 'info' => $p->buildchain, 'dim_1' => $p->dim_1, 'dim_2' => $p->dim_2, 'last_update' => $p->last_update); } // myData parameter else @@ -317,12 +318,13 @@ class DerivedParamMgr extends AmdaObjectMgr public function getObject($id) { if (!file_exists(USERWSDIR.$id.'.xml')) return array('error' => NO_OBJECT_FILE); - + $this->objectDom -> load(USERWSDIR.$id.'.xml'); if (!($objToGet = $this->objectDom->getElementById($id))) return array('error' => NO_SUCH_ID); $attributesToReturn['id'] = $objToGet->getAttribute('xml:id'); $attributes = $objToGet -> childNodes; + $last_update = 0; foreach($attributes as $attribute) { if ($attribute->tagName === "buildchain") $attributesToReturn[$attribute->tagName] = $this->setAlias($attribute->nodeValue); @@ -343,7 +345,11 @@ class DerivedParamMgr extends AmdaObjectMgr } else $attributesToReturn[$attribute->tagName] = $attribute->nodeValue; } - + + if (empty($attributesToReturn['last_update'])) { + $attributesToReturn['last_update'] = filemtime(USERWSDIR.$id.'.xml'); + } + return $attributesToReturn; } -- libgit2 0.21.2