Commit 922e84e16911753ecd3aca0a7060cb942c249abd

Authored by Hacene SI HADJ MOHAND
1 parent 1577b1e7

ok coté ihm

generic_data/Functions/functions.xml
... ... @@ -80,7 +80,8 @@
80 80 <new_kernel>#timeShift</new_kernel>
81 81 </function>
82 82 <function name="vAlfven(,)" args="2" kind="physics">
83   - <!-- <prompt>Alfven velocity Valfven(density[cm^⁻3], mag[nT])</prompt> -->
  83 + <!--prompt>input density[cm^⁻3])</prompt-->
  84 + <!--default_args>arg1</default_args-->
84 85 <info_brief>Alfven velocity Valfven(density[cm^⁻3], mag[nT])</info_brief>
85 86 <new_kernel>alfvenVelocity</new_kernel>
86 87 </function>
... ...
js/app/models/Function.js
... ... @@ -18,6 +18,7 @@ Ext.define(&#39;amdaModel.Function&#39;, {
18 18 {name: 'args', mapping: '@args', type: 'int', defaultValue: 1},
19 19 {name: 'argv', mapping: '@argv', type: 'string'},
20 20 {name: 'prompt', type: 'string', defaultValue: ''},
  21 + {name: 'default_args', type: 'string', defaultValue: ''},
21 22 {name: 'info_brief', type: 'string', defaultValue: ''}
22 23 ],
23 24  
... ...
js/app/views/CalculatorUI.js
... ... @@ -14,487 +14,516 @@
14 14 * @ptype calculator
15 15 */
16 16  
17   -var CalculatorData = ['1','2','3','4','5','6','7','8','9','0','(',')','[',']','+','-','*','/','^', '.','>','>=','=','!=','<=','<', '&', '|'];
  17 +var CalculatorData = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '(', ')', '[', ']', '+', '-', '*', '/', '^', '.', '>', '>=', '=', '!=', '<=', '<', '&', '|'];
18 18  
19 19 Ext.define('amdaUI.CalculatorUI', {
20   - extend: 'Ext.util.Observable',
21   -
22   - requires : [
23   - 'amdaModel.Constant',
24   - 'amdaModel.Function'
25   - ],
26   -
27   - alias: 'plugin.calculator',
28   -
29   - statics : {
30   - constantStore : null,
31   - functionStore : null
32   - },
33   -
34   - win: null,
35   -
36   - constructor: function(config) {
37   - Ext.apply(this, config);
38   - this.callParent(arguments);
39   - },
40   -
41   - init: function(cmp)
42   - {
43   - this.hostCmp = cmp;
44   - this.hostCmp.on({
45   - scope: this,
46   - added: function(){
47   - this.hostCmp.ownerCt.on({
48   - render: this.onRender,
49   - show: this.onShow,
50   - hide : this.onHide,
51   - scope: this });
52   - }
53   - });
54   - },
55   -
56   - onRender: function()
57   - {
58   - this.win = new Ext.Window({
59   - width: 350,
60   - height: 170,
61   - x: 380, y: 0,
62   - baseCls:'x-panel',
63   - title: 'Tools For ' + this.context + ' Construction',
64   - layout: 'fit',
65   - closable: false,
66   - collapsible: true,
67   - constrain: true,
68   - floating: true,
69   - ghost: false,
70   - renderTo: this.hostCmp.id,
71   - items: this.getFormConfig(),
72   - listeners : {
73   - boxready: function (w)
74   - {
75   - if (w.y + w.height > myDesktopApp.desktop.el.getHeight())
76   - w.el.setY((myDesktopApp.desktop.el.getHeight()-w.height > 0) ? myDesktopApp.desktop.el.getHeight()-w.height : 0);
77   - }
78   - },
79   - getConstrainVector: function(constrainTo){
80   - var me = this;
81   - if (me.constrain || me.constrainHeader) {
82   - constrainTo = constrainTo || (me.floatParent && me.floatParent.getTargetEl()) || me.container || me.el.getScopeParent();
83   - return (me.constrainHeader ? me.header.el : me.el).getConstrainVector(constrainTo);
84   - }
85   - }
86   - });
87   -
88   - //load constants store
89   - if (!amdaUI.CalculatorUI.constantStore)
90   - {
91   - amdaUI.CalculatorUI.constantStore = Ext.create('Ext.data.Store',{model: 'amdaModel.Constant'});
92   - amdaUI.CalculatorUI.constantStore.load({
93   - scope : this,
94   - callback: function(records, operation, success)
95   - {
96   - this.createAllConstantBtns();
97   - }
98   - });
99   - }
100   - else
101   - this.createAllConstantBtns();
102   -
103   - //load functions store
104   - if (!amdaUI.CalculatorUI.functionStore)
105   - {
106   - amdaUI.CalculatorUI.functionStore = Ext.create('Ext.data.Store',{model: 'amdaModel.Function'});
107   - amdaUI.CalculatorUI.functionStore.load({
108   - scope : this,
109   - callback: function(records, operation, success)
110   - {
111   - this.createAllFunctionBtns();
112   - }
113   - });
114   - }
115   - else
116   - this.createAllFunctionBtns();
117   - },
118   -
119   - onShow: function() {
120   - this.win.show();
121   - var parentWin = this.hostCmp.findParentByType('window');
122   -
123   - if (parentWin.getId() === myDesktopApp.dynamicModules.param.id) {
124   - this.win.setPosition(335,10);
125   - }
126   - else {
127   -
128   - var posX = parentWin.getWidth() - this.win.getWidth() - 30;
129   - var posY = parentWin.getHeight() - this.win.getHeight() - 110 - 30/*20*/;
130   - this.win.setPosition(posX,posY);//(420,290);
131   - }
132   - },
133   -
134   - onHide : function()
135   - {
136   - this.win.hide();
137   - },
138   -
139   - getFormConfig: function(){
140   - return {
141   - xtype: 'tabpanel',
142   - border: false, frame: true, plain: true,
143   - enableTabScroll: true,
144   - defaults: { frame: true, border: false, plain: true, autoScroll:true},
145   - activeTab: 0,
146   - items: [ {
147   - title: 'Calculator',layout: 'column',
148   - defaults: { xtype: 'button', columnWidth: .11},
149   - items: this.getItems('Calculator')
150   - } , {
151   - title: 'Constants', xtype:'tabpanel', //iconCls: 'tabs',
152   - enableTabScroll: true, tabPosition: 'bottom',
153   - defaults: { frame: true, border: false, plain: true, layout: 'column', autoScroll:true},
154   - activeTab: 0,
155   - id : 'calc_tab_const_id'
156   - }, {
157   - title: 'Functions', xtype:'tabpanel', //iconCls: 'tabs',
158   - enableTabScroll: true, tabPosition: 'bottom',
159   - defaults: { frame: true, border: false, plain: true, layout: 'column', autoScroll:true},
160   - activeTab: 0,
161   - id : 'calc_tab_func_id'
162   - }]
163   - };
164   - },
165   -
166   - /**
167   - * Prompt any argument to user before processing Formula
168   - * @param sel selected text
169   - * @param currentBtn calculator button pressed
170   - * @param params array of parameters
171   - */
172   - preProcessFormula: function(sel,currentBtn, params) {
173   -
174   - if (currentBtn.initialConfig.args!=0 && currentBtn.initialConfig.prompt!=""){
175   - // Prompt for user precision and process the result using a callback
176   - Ext.Msg.prompt('Argument',currentBtn.initialConfig.prompt, function(bt2, text){
177   - if (bt2 === 'ok'){
178   - var afterParamsText = "," + text + ")";
179   - //TODO: more than one args and prompt
180   - this.processFormula(sel,currentBtn, params, afterParamsText);
181   -
182   - }
183   - },this);
184   - } else {
185   - this.processFormula(sel,currentBtn, params, ")");
186   - }// endif prompt
187   - },
188   -
189   - processFormula : function(sel,currentBtn, params, afterParamsText){
190   - // calculation of the required number of parameters
191   - var nbParams = currentBtn.initialConfig.args;
192   - var fnText = currentBtn.text.split('(');
193   - var newConstruction = sel.beforeText + fnText[0]+"(";
194   - // if there at least one parameter selected
195   - if (params.length){
196   - for (var i=0;i<nbParams;i++) {
197   - if(i>0) {
198   - newConstruction += ",";
199   - }
200   - newConstruction += params[i];
201   - }
202   - }
203   - // we keep position
204   - var afterParameterPos = newConstruction.length;
205   - newConstruction += afterParamsText;
206   - var caretPos = newConstruction.length;
207   - newConstruction += sel.afterText;
208   - this.hostCmp.constructionField.setValue(newConstruction);
209   -
210   - // If we haven't the right number of selected parameters
211   - if (params.length < nbParams){
212   - var stringParamRequired = currentBtn.initialConfig.args+" parameter(s)";
213   - Ext.Msg.alert('Caution', 'you\'ll have to add '+ stringParamRequired +' to apply this function',
214   - function(){
215   - // set Caret Position at placement of required parameter in function
216   - this.hostCmp.constructionField.setCaretPosition(afterParameterPos);
217   - },this
218   - );
219   - } else {
220   - // set Caret Position after inserted Text
221   - this.hostCmp.constructionField.setCaretPosition(caretPos);
222   - }
223   - },
224   -
225   - /**
226   - * This method construct an array of arguments into selected text
227   - * @param selectedText the selection to parse
228   - * @param parseIndex the index to start parsing
229   - * @return the arguments array
230   - */
231   - parseArgsInFormula : function (selectedText, parseIndex) {
232   -
233   - if (!selectedText || selectedText==""){
234   - return [];
235   - } else {
236   - var params = [];
237   - var startIndex = parseIndex;
238   - var curIndex = parseIndex;
239   - var openBrace = 0;
240   - var sep = 0;
241   - var closeBrace = 0;
242   -
243   - // while there is a separator
244   - while(sep!=-1){
245   - openBrace = selectedText.indexOf("(",curIndex);
246   - sep = selectedText.indexOf(",",curIndex);
247   - closeBrace = selectedText.indexOf(")",curIndex);
248   -
249   - // if there's an open bracket and no close bracket or inversely
250   - if (openBrace!=-1 && closeBrace==-1 || openBrace==-1 && closeBrace!=-1) {
251   - // invalid selection
252   - return -1;
253   - }
254   -
255   - // if there's a separator and opening brackets into selection
256   - if (sep!=-1 && openBrace!=-1){
257   - // if brace is before separator
258   - if (openBrace<sep) {
259   - curIndex = this.getEndBracket(selectedText,openBrace+1);
260   - if (curIndex===-1){
261   - return -1;
262   - }
263   - } else {// else separator is before brace
264   - params.push(selectedText.substring(startIndex,sep));
265   - startIndex = curIndex = sep+1;
266   - }
267   - // if there's only separators into selection
268   - } else if (sep!=-1) {
269   - params.push(selectedText.substring(startIndex,sep));
270   - startIndex = curIndex = sep+1;
271   - }
272   - }
273   - params.push(selectedText.substring(startIndex,selectedText.length));
274   - return params;
275   - }
276   - },
277   -
278   - getEndBracket : function(string,indOpenBrace){
279   - // we search for the corresponding end brace (after open bracket)
280   - var currentIndex = indOpenBrace;
281   - var nextCloseBrace = 0;
282   - var nextOpenBrace = 0;
283   - var braceLevel = 1;
284   - while (nextCloseBrace!==-1 && braceLevel!==0){
285   - // get index of next opening bracket
286   - nextOpenBrace = string.indexOf("(",currentIndex);
287   - // get index of next closing bracket
288   - nextCloseBrace = string.indexOf(")",currentIndex);
289   - // if both exist
290   - if (nextOpenBrace!=-1 && nextCloseBrace!=-1) {
291   - // if opening bracket is before closing one
292   - if (nextOpenBrace<nextCloseBrace) {
293   - currentIndex = nextOpenBrace+1;
294   - braceLevel++;
295   - } else { // if closing bracket is before opening one
296   - currentIndex = nextCloseBrace+1;
297   - braceLevel--;
298   - }
299   - // if there's only a next opening bracket
300   - } else if (nextOpenBrace!=-1 && nextCloseBrace==-1) {
301   - currentIndex = nextOpenBrace+1;
302   - braceLevel++;
303   - // if there's only a next closing bracket
304   - } else if (nextOpenBrace==-1 && nextCloseBrace!=-1) {
305   - currentIndex = nextCloseBrace+1;
306   - braceLevel--;
307   - }
308   - }
309   - // if no level imbrication left return index after closing bracket of block else -1
310   - return braceLevel==0 ? currentIndex : -1;
311   - },
312   -
313   - getCalculatorBtn : function()
314   - {
315   - var btns = [];
316   -
317   - Ext.each(CalculatorData, function (c){
318   - btns.push({
319   - text: c,
320   - scope: this,
321   - handler: function(b,e){
322   - // keep selection into construction field
323   - var selection = this.hostCmp.constructionField.getSelection();
324   - // the new value of construction field
325   - var newConstruction = "";
326   - // replacement of selection into construction field by text of clicked button
327   - newConstruction = selection.beforeText + b.text;
328   - var caretPos = newConstruction.length;
329   - newConstruction += selection.afterText;
330   - this.hostCmp.constructionField.setValue(newConstruction);
331   - // set Caret Position after inserted Text
332   - this.hostCmp.constructionField.setCaretPosition(caretPos);
333   - }
334   - })
335   - },
336   - this
337   - );
338   -
339   - return btns;
340   - },
341   -
342   - createAllFunctionBtns : function()
343   - {
344   - this.createFunctionBtns('MathFunctions','Simple Maths');
345   - this.createFunctionBtns('VectorFunctions','Vector Functions');
346   - this.createFunctionBtns('TimeFunctions','Statistics');
347   - this.createFunctionBtns('FunctionsSliding','Statistics/Sliding');
348   - this.createFunctionBtns('PhysicsFunctions', 'Physics');
349   - this.createFunctionBtns('AmdaFunctions','Special');
350   - },
351   -
352   - createAllConstantBtns : function()
353   - {
354   - this.createConstantBtns('Space','Planets Constants');
355   - this.createConstantBtns('Physics','Physics Constants');
356   - this.createConstantBtns('Units','Units Conversion');
357   - },
358   -
359   - createConstantBtns : function(item, tabTitle)
360   - {
361   - var constTab = this.win.query('#calc_tab_const_id');
362   -
363   - if (constTab.length < 1)
364   - return;
365   -
366   - switch (item)
367   - {
368   - case 'Space' :
369   - amdaUI.CalculatorUI.constantStore.filter('kind','space');
370   - break;
371   - case 'Physics' :
372   - amdaUI.CalculatorUI.constantStore.filter('kind','physics');
373   - break;
374   - case 'Units' :
375   - amdaUI.CalculatorUI.constantStore.filter('kind','units');
376   - break;
377   - }
378   -
379   - var crtTab = constTab[0].add(
380   - {
381   - title : tabTitle,
382   - defaults: { xtype: 'button', columnWidth: .20}
383   - });
384   -
385   - amdaUI.CalculatorUI.constantStore.each( function(c){
386   - crtTab.add(
387   - {
388   - text: c.get('name'),
389   - tooltip: c.get('units') == '' ? c.get('info')+'<br/>'+c.get('value') :
390   - c.get('info')+'<br/>'+c.get('value')+' '+c.get('units'),
391   - scope: this,
392   - handler: function(b,e){
393   - // keep selection into construction field
394   - var selection = this.hostCmp.constructionField.getSelection();
395   - // the new value of construction field
396   - var newConstruction = "";
397   - // replacement of selection into construction field by text of clicked button
398   - newConstruction = selection.beforeText + '@'+b.text;
399   - var caretPos = newConstruction.length;
400   - newConstruction += selection.afterText;
401   - this.hostCmp.constructionField.setValue(newConstruction);
402   - // set Caret Position after inserted Text
403   - this.hostCmp.constructionField.setCaretPosition(caretPos);
404   - }
405   - });
406   - },this);
407   -
408   - //clear filter
409   - amdaUI.CalculatorUI.constantStore.clearFilter();
410   - },
411   -
412   - createFunctionBtns : function(item, tabTitle)
413   - {
414   - var funcTab = this.win.query('#calc_tab_func_id');
415   -
416   - if (funcTab.length < 1)
417   - return;
418   -
419   - var width = .20;
420   -
421   - switch (item)
422   - {
423   - case 'MathFunctions' :
424   - amdaUI.CalculatorUI.functionStore.filter('kind','math');
425   - break;
426   - case 'AmdaFunctions' :
427   - amdaUI.CalculatorUI.functionStore.filter('kind','amda');
428   - break;
429   - case 'TimeFunctions' :
430   - amdaUI.CalculatorUI.functionStore.filter('kind','time');
431   - break;
432   - case 'FunctionsSliding' :
433   - amdaUI.CalculatorUI.functionStore.filter('kind','sliding');
434   - break;
435   - case 'VectorFunctions' :
436   - amdaUI.CalculatorUI.functionStore.filter('kind','vector');
437   - break;
438   - case 'PhysicsFunctions' :
439   - amdaUI.CalculatorUI.functionStore.filter('kind', 'physics');
440   - width = .25;
441   - break;
442   - }
443   -
444   - var crtTab = funcTab[0].add(
445   - {
446   - title : tabTitle,
447   - defaults: { xtype: 'button', columnWidth: width}
448   - });
449   -
450   - amdaUI.CalculatorUI.functionStore.each( function(f){
451   - crtTab.add(
452   - {
453   - text: f.get('name'),
454   - args: f.get('args'),
455   - prompt: f.get('prompt'),
456   - tooltip: f.get('info_brief'),
457   - scope: this,
458   - handler: function(b,e){
459   - var selection = this.hostCmp.constructionField.getSelection();
460   - var selectedText = selection&&selection.text!="" ? Ext.util.Format.trim(selection.text) : null;
461   - if (selectedText && selectedText!==""){
462   - selectedText.replace("[","(");
463   - selectedText.replace("{","(");
464   - selectedText.replace("}",")");
465   - selectedText.replace("]",")");
466   - }
467   - // Formula Parsing for arguments
468   - var params = this.parseArgsInFormula(selectedText,0);
  20 + extend: 'Ext.util.Observable',
  21 +
  22 + requires: [
  23 + 'amdaModel.Constant',
  24 + 'amdaModel.Function'
  25 + ],
  26 +
  27 + alias: 'plugin.calculator',
  28 +
  29 + statics: {
  30 + constantStore: null,
  31 + functionStore: null
  32 + },
  33 +
  34 + win: null,
  35 +
  36 + constructor: function (config) {
  37 + Ext.apply(this, config);
  38 + this.callParent(arguments);
  39 + },
  40 +
  41 + init: function (cmp)
  42 + {
  43 + this.hostCmp = cmp;
  44 + this.hostCmp.on({
  45 + scope: this,
  46 + added: function () {
  47 + this.hostCmp.ownerCt.on({
  48 + render: this.onRender,
  49 + show: this.onShow,
  50 + hide: this.onHide,
  51 + scope: this});
  52 + }
  53 + });
  54 + },
  55 +
  56 + onRender: function ()
  57 + {
  58 + this.win = new Ext.Window({
  59 + width: 350,
  60 + height: 170,
  61 + x: 380, y: 0,
  62 + baseCls: 'x-panel',
  63 + title: 'Tools For ' + this.context + ' Construction',
  64 + layout: 'fit',
  65 + closable: false,
  66 + collapsible: true,
  67 + constrain: true,
  68 + floating: true,
  69 + ghost: false,
  70 + renderTo: this.hostCmp.id,
  71 + items: this.getFormConfig(),
  72 + listeners: {
  73 + boxready: function (w)
  74 + {
  75 + if (w.y + w.height > myDesktopApp.desktop.el.getHeight())
  76 + w.el.setY((myDesktopApp.desktop.el.getHeight() - w.height > 0) ? myDesktopApp.desktop.el.getHeight() - w.height : 0);
  77 + }
  78 + },
  79 + getConstrainVector: function (constrainTo) {
  80 + var me = this;
  81 + if (me.constrain || me.constrainHeader) {
  82 + constrainTo = constrainTo || (me.floatParent && me.floatParent.getTargetEl()) || me.container || me.el.getScopeParent();
  83 + return (me.constrainHeader ? me.header.el : me.el).getConstrainVector(constrainTo);
  84 + }
  85 + }
  86 + });
  87 +
  88 + //load constants store
  89 + if (!amdaUI.CalculatorUI.constantStore)
  90 + {
  91 + amdaUI.CalculatorUI.constantStore = Ext.create('Ext.data.Store', {model: 'amdaModel.Constant'});
  92 + amdaUI.CalculatorUI.constantStore.load({
  93 + scope: this,
  94 + callback: function (records, operation, success)
  95 + {
  96 + this.createAllConstantBtns();
  97 + }
  98 + });
  99 + } else
  100 + this.createAllConstantBtns();
  101 +
  102 + //load functions store
  103 + if (!amdaUI.CalculatorUI.functionStore)
  104 + {
  105 + amdaUI.CalculatorUI.functionStore = Ext.create('Ext.data.Store', {model: 'amdaModel.Function'});
  106 + amdaUI.CalculatorUI.functionStore.load({
  107 + scope: this,
  108 + callback: function (records, operation, success)
  109 + {
  110 + this.createAllFunctionBtns();
  111 + }
  112 + });
  113 + } else
  114 + this.createAllFunctionBtns();
  115 +
  116 + },
  117 +
  118 + onShow: function () {
  119 + this.win.show();
  120 + var parentWin = this.hostCmp.findParentByType('window');
  121 +
  122 + if (parentWin.getId() === myDesktopApp.dynamicModules.param.id) {
  123 + this.win.setPosition(335, 10);
  124 + } else {
  125 +
  126 + var posX = parentWin.getWidth() - this.win.getWidth() - 30;
  127 + var posY = parentWin.getHeight() - this.win.getHeight() - 110 - 30/*20*/;
  128 + this.win.setPosition(posX, posY);//(420,290);
  129 + }
  130 + },
  131 +
  132 + onHide: function ()
  133 + {
  134 + this.win.hide();
  135 + },
  136 +
  137 + getFormConfig: function () {
  138 + return {
  139 + xtype: 'tabpanel',
  140 + border: false, frame: true, plain: true,
  141 + enableTabScroll: true,
  142 + defaults: {frame: true, border: false, plain: true, autoScroll: true},
  143 + activeTab: 0,
  144 + items: [{
  145 + title: 'Calculator', layout: 'column',
  146 + defaults: {xtype: 'button', columnWidth: .11},
  147 + items: this.getItems('Calculator')
  148 + }, {
  149 + title: 'Constants', xtype: 'tabpanel', //iconCls: 'tabs',
  150 + enableTabScroll: true, tabPosition: 'bottom',
  151 + defaults: {frame: true, border: false, plain: true, layout: 'column', autoScroll: true},
  152 + activeTab: 0,
  153 + id: 'calc_tab_const_id'
  154 + }, {
  155 + title: 'Functions', xtype: 'tabpanel', //iconCls: 'tabs',
  156 + enableTabScroll: true, tabPosition: 'bottom',
  157 + defaults: {frame: true, border: false, plain: true, layout: 'column', autoScroll: true},
  158 + activeTab: 0,
  159 + id: 'calc_tab_func_id'
  160 + }]
  161 + };
  162 + },
  163 +
  164 + /**
  165 + * Prompt any argument to user before processing Formula
  166 + * @param sel selected text
  167 + * @param currentBtn calculator button pressed
  168 + * @param params array of parameters
  169 + */
  170 + preProcessFormula: function (sel, currentBtn, params) {
  171 +
  172 + if (currentBtn.initialConfig.args != 0 && currentBtn.initialConfig.prompt != "") {
  173 + // Prompt for user precision and process the result using a callback
  174 + Ext.Msg.prompt('Argument', currentBtn.initialConfig.prompt, function (bt2, text) {
  175 + if (bt2 === 'ok') {
  176 + var afterParamsText = text + ")";
  177 + //TODO: more than one args and prompt
  178 + this.processFormula(sel, currentBtn, params, afterParamsText);
  179 +
  180 + }
  181 + }, this);
  182 + } else {
  183 + this.processFormula(sel, currentBtn, params, ")");
  184 + }// endif prompt
  185 + },
  186 +
  187 + processFormula: function (sel, currentBtn, params, afterParamsText) {
  188 + // calculation of the required number of parameters
  189 + var nbParams = currentBtn.initialConfig.args;
  190 + var remainingParams = nbParams - params.length;
  191 + var fnText = currentBtn.text.split('(');
  192 + var newConstruction = sel.beforeText + fnText[0] + "(";
  193 + // if there at least one parameter selected
  194 + if (params.length) {
  195 + for (var i = 0; i < params.length; i++) {
  196 + if (i > 0) {
  197 + newConstruction += ",";
  198 + }
  199 + newConstruction += params[i];
  200 + }
  201 + }
  202 + // we keep position
  203 + var afterParameterPos = newConstruction.length;
  204 + for (var i = 0; i < remainingParams-1; i++) {
  205 + newConstruction += ',';
  206 + }
  207 + if(afterParamsText != ")")
  208 + newConstruction += ','
  209 + newConstruction += afterParamsText;
  210 + var caretPos = newConstruction.length;
  211 + newConstruction += sel.afterText;
  212 + this.hostCmp.constructionField.setValue(newConstruction);
  213 +
  214 + // If we haven't the right number of selected parameters
  215 + if (remainingParams > 0) {
  216 + var stringParamRequired = (remainingParams) + " parameter(s)";
  217 + Ext.Msg.alert('Caution', 'you\'ll have to add ' + stringParamRequired + ' to apply this function',
  218 + function () {
  219 + // set Caret Position at placement of required parameter in function
  220 + this.hostCmp.constructionField.setCaretPosition(afterParameterPos);
  221 + }, this
  222 + );
  223 + } else if (remainingParams < 0) {
  224 + var stringParamRequired = (-remainingParams) + " parameter(s)";
  225 +
  226 + Ext.Msg.show({
  227 + title: 'Caution',
  228 + msg: 'you\'ll have to remove ' + stringParamRequired + ' to apply this function',
  229 + buttons: Ext.Msg.OK,
  230 + // animEl: 'elId',
  231 + icon: Ext.MessageBox.WARNING,
  232 + fn:function () {
  233 + // set Caret Position at placement of required parameter in function
  234 + this.hostCmp.constructionField.setCaretPosition(afterParameterPos);
  235 + },
  236 + scope: this
  237 + });
  238 + } else {
  239 + // set Caret Position after inserted Text
  240 + this.hostCmp.constructionField.setCaretPosition(caretPos);
  241 + }
  242 + },
  243 +
  244 + /**
  245 + * This method construct an array of arguments into selected text
  246 + * @param selectedText the selection to parse
  247 + * @param parseIndex the index to start parsing
  248 + * @return the arguments array
  249 + */
  250 + parseArgsInFormula: function (selectedText, parseIndex) {
  251 +
  252 + if (!selectedText || selectedText == "") {
  253 + return [];
  254 + } else {
  255 + var params = [];
  256 + var startIndex = parseIndex;
  257 + var curIndex = parseIndex;
  258 + var openBrace = 0;
  259 + var sep = 0;
  260 + var closeBrace = 0;
  261 +
  262 + // while there is a separator
  263 + while (sep != -1) {
  264 + openBrace = selectedText.indexOf("(", curIndex);
  265 + sep = selectedText.indexOf(",", curIndex);
  266 + closeBrace = selectedText.indexOf(")", curIndex);
  267 +
  268 + // if there's an open bracket and no close bracket or inversely
  269 + if (openBrace != -1 && closeBrace == -1 || openBrace == -1 && closeBrace != -1) {
  270 + // invalid selection
  271 + return -1;
  272 + }
  273 +
  274 + // if there's a separator and opening brackets into selection
  275 + if (sep != -1 && openBrace != -1) {
  276 + // if brace is before separator
  277 + if (openBrace < sep) {
  278 + curIndex = this.getEndBracket(selectedText, openBrace + 1);
  279 + if (curIndex === -1) {
  280 + return -1;
  281 + }
  282 + } else {// else separator is before brace
  283 + params.push(selectedText.substring(startIndex, sep));
  284 + startIndex = curIndex = sep + 1;
  285 + }
  286 + // if there's only separators into selection
  287 + } else if (sep != -1) {
  288 + params.push(selectedText.substring(startIndex, sep));
  289 + startIndex = curIndex = sep + 1;
  290 + }
  291 + }
  292 + params.push(selectedText.substring(startIndex, selectedText.length));
  293 + return params;
  294 + }
  295 + },
  296 +
  297 + getEndBracket: function (string, indOpenBrace) {
  298 + // we search for the corresponding end brace (after open bracket)
  299 + var currentIndex = indOpenBrace;
  300 + var nextCloseBrace = 0;
  301 + var nextOpenBrace = 0;
  302 + var braceLevel = 1;
  303 + while (nextCloseBrace !== -1 && braceLevel !== 0) {
  304 + // get index of next opening bracket
  305 + nextOpenBrace = string.indexOf("(", currentIndex);
  306 + // get index of next closing bracket
  307 + nextCloseBrace = string.indexOf(")", currentIndex);
  308 + // if both exist
  309 + if (nextOpenBrace != -1 && nextCloseBrace != -1) {
  310 + // if opening bracket is before closing one
  311 + if (nextOpenBrace < nextCloseBrace) {
  312 + currentIndex = nextOpenBrace + 1;
  313 + braceLevel++;
  314 + } else { // if closing bracket is before opening one
  315 + currentIndex = nextCloseBrace + 1;
  316 + braceLevel--;
  317 + }
  318 + // if there's only a next opening bracket
  319 + } else if (nextOpenBrace != -1 && nextCloseBrace == -1) {
  320 + currentIndex = nextOpenBrace + 1;
  321 + braceLevel++;
  322 + // if there's only a next closing bracket
  323 + } else if (nextOpenBrace == -1 && nextCloseBrace != -1) {
  324 + currentIndex = nextCloseBrace + 1;
  325 + braceLevel--;
  326 + }
  327 + }
  328 + // if no level imbrication left return index after closing bracket of block else -1
  329 + return braceLevel == 0 ? currentIndex : -1;
  330 + },
  331 +
  332 + getCalculatorBtn: function ()
  333 + {
  334 + var btns = [];
  335 +
  336 + Ext.each(CalculatorData, function (c) {
  337 + btns.push({
  338 + text: c,
  339 + scope: this,
  340 + handler: function (b, e) {
  341 + // keep selection into construction field
  342 + var selection = this.hostCmp.constructionField.getSelection();
  343 + // the new value of construction field
  344 + var newConstruction = "";
  345 + // replacement of selection into construction field by text of clicked button
  346 + newConstruction = selection.beforeText + b.text;
  347 + var caretPos = newConstruction.length;
  348 + newConstruction += selection.afterText;
  349 + this.hostCmp.constructionField.setValue(newConstruction);
  350 + // set Caret Position after inserted Text
  351 + this.hostCmp.constructionField.setCaretPosition(caretPos);
  352 + }
  353 + })
  354 + },
  355 + this
  356 + );
  357 +
  358 + return btns;
  359 + },
  360 +
  361 + createAllFunctionBtns: function ()
  362 + {
  363 + this.createFunctionBtns('MathFunctions', 'Simple Maths');
  364 + this.createFunctionBtns('VectorFunctions', 'Vector Functions');
  365 + this.createFunctionBtns('TimeFunctions', 'Statistics');
  366 + this.createFunctionBtns('FunctionsSliding', 'Statistics/Sliding');
  367 + this.createFunctionBtns('PhysicsFunctions', 'Physics');
  368 + this.createFunctionBtns('AmdaFunctions', 'Special');
  369 + },
  370 +
  371 + createAllConstantBtns: function ()
  372 + {
  373 + this.createConstantBtns('Space', 'Planets Constants');
  374 + this.createConstantBtns('Physics', 'Physics Constants');
  375 + this.createConstantBtns('Units', 'Units Conversion');
  376 + },
  377 +
  378 + createConstantBtns: function (item, tabTitle)
  379 + {
  380 + var constTab = this.win.query('#calc_tab_const_id');
  381 +
  382 + if (constTab.length < 1)
  383 + return;
  384 +
  385 + switch (item)
  386 + {
  387 + case 'Space' :
  388 + amdaUI.CalculatorUI.constantStore.filter('kind', 'space');
  389 + break;
  390 + case 'Physics' :
  391 + amdaUI.CalculatorUI.constantStore.filter('kind', 'physics');
  392 + break;
  393 + case 'Units' :
  394 + amdaUI.CalculatorUI.constantStore.filter('kind', 'units');
  395 + break;
  396 + }
  397 +
  398 + var crtTab = constTab[0].add(
  399 + {
  400 + title: tabTitle,
  401 + defaults: {xtype: 'button', columnWidth: .20}
  402 + });
  403 +
  404 + amdaUI.CalculatorUI.constantStore.each(function (c) {
  405 + crtTab.add(
  406 + {
  407 + text: c.get('name'),
  408 + tooltip: c.get('units') == '' ? c.get('info') + '<br/>' + c.get('value') :
  409 + c.get('info') + '<br/>' + c.get('value') + ' ' + c.get('units'),
  410 + scope: this,
  411 + handler: function (b, e) {
  412 + // keep selection into construction field
  413 + var selection = this.hostCmp.constructionField.getSelection();
  414 + // the new value of construction field
  415 + var newConstruction = "";
  416 + // replacement of selection into construction field by text of clicked button
  417 + newConstruction = selection.beforeText + '@' + b.text;
  418 + var caretPos = newConstruction.length;
  419 + newConstruction += selection.afterText;
  420 + this.hostCmp.constructionField.setValue(newConstruction);
  421 + // set Caret Position after inserted Text
  422 + this.hostCmp.constructionField.setCaretPosition(caretPos);
  423 + }
  424 + });
  425 + }, this);
  426 +
  427 + //clear filter
  428 + amdaUI.CalculatorUI.constantStore.clearFilter();
  429 + },
  430 +
  431 + createFunctionBtns: function (item, tabTitle)
  432 + {
  433 + var funcTab = this.win.query('#calc_tab_func_id');
  434 +
  435 + if (funcTab.length < 1)
  436 + return;
  437 +
  438 + var width = .20;
  439 +
  440 + switch (item)
  441 + {
  442 + case 'MathFunctions' :
  443 + amdaUI.CalculatorUI.functionStore.filter('kind', 'math');
  444 + break;
  445 + case 'AmdaFunctions' :
  446 + amdaUI.CalculatorUI.functionStore.filter('kind', 'amda');
  447 + break;
  448 + case 'TimeFunctions' :
  449 + amdaUI.CalculatorUI.functionStore.filter('kind', 'time');
  450 + break;
  451 + case 'FunctionsSliding' :
  452 + amdaUI.CalculatorUI.functionStore.filter('kind', 'sliding');
  453 + break;
  454 + case 'VectorFunctions' :
  455 + amdaUI.CalculatorUI.functionStore.filter('kind', 'vector');
  456 + break;
  457 + case 'PhysicsFunctions' :
  458 + amdaUI.CalculatorUI.functionStore.filter('kind', 'physics');
  459 + width = .25;
  460 + break;
  461 + }
  462 +
  463 + var crtTab = funcTab[0].add(
  464 + {
  465 + title: tabTitle,
  466 + defaults: {xtype: 'button', columnWidth: width}
  467 + });
  468 +
  469 + amdaUI.CalculatorUI.functionStore.each(function (f) {
  470 + crtTab.add(
  471 + {
  472 + text: f.get('name'),
  473 + args: f.get('args'),
  474 + defaultArgs: f.get('default_args'),
  475 + prompt: f.get('prompt'),
  476 + tooltip: f.get('info_brief'),
  477 + scope: this,
  478 + handler: function (b, e) {
  479 + var selection = this.hostCmp.constructionField.getSelection();
  480 + var selectedText = selection && selection.text != "" ? Ext.util.Format.trim(selection.text) : null;
  481 + if (selectedText && selectedText !== "") {
  482 + selectedText.replace("[", "(");
  483 + selectedText.replace("{", "(");
  484 + selectedText.replace("}", ")");
  485 + selectedText.replace("]", ")");
  486 + }
  487 + var params = [];
  488 + var raw_args = b.initialConfig.defaultArgs;
  489 + if (raw_args && raw_args != "") {
  490 + params = b.initialConfig.defaultArgs.split(',');
  491 + }
  492 + // Formula Parsing for arguments
  493 + //var params = this.parseArgsInFormula(selectedText, 0);
469 494 // var params = selectedText ? selectedText.split(',') : [];
470   - if (params === -1) {
471   - Ext.Msg.alert("Invalid Selection", "Action aborted");
472   - }
473   - else {
474   - // calculation of the required number of parameters
475   - var nbParams = b.initialConfig.args;
476   -
477   - if (params.length>nbParams)
478   - {
479   - // Show a dialog using config options:
480   - Ext.Msg.show({
481   - title:'Caution',
482   - msg: 'you have selected more than '+nbParams+' parameter(s) to apply this function<br>Only the first will be kept, others will be deleted',
483   - buttons: Ext.Msg.OKCANCEL,
484   -// animEl: 'elId',
485   - icon: Ext.MessageBox.WARNING,
486   - fn: function (bt1) {
487   - if (bt1 === 'ok') {
488   - this.preProcessFormula(selection, b, params);
489   - }
490   - },
491   - scope: this
492   - });
493   - } else
494   - {
495   - this.preProcessFormula(selection, b, params);
496   - }
  495 +
  496 + if (params === -1) {
  497 + Ext.Msg.alert("Invalid Selection", "Action aborted");
  498 + } else {
  499 + // calculation of the required number of parameters
  500 + var nbParams = b.initialConfig.args;
  501 + this.preProcessFormula(selection, b, params);
  502 +
  503 + /**
  504 +
  505 + if (params.length > nbParams)
  506 + {
  507 + // Show a dialog using config options:
  508 + Ext.Msg.show({
  509 + title: 'Caution',
  510 + msg: 'you have selected more than ' + nbParams + ' parameter(s) to apply this function<br>Only the first will be kept, others will be deleted',
  511 + buttons: Ext.Msg.OKCANCEL,
  512 + // animEl: 'elId',
  513 + icon: Ext.MessageBox.WARNING,
  514 + fn: function (bt1) {
  515 + if (bt1 === 'ok') {
  516 + this.preProcessFormula(selection, b, params);
  517 + }
  518 + },
  519 + scope: this
  520 + });
  521 + } else
  522 + {
  523 + this.preProcessFormula(selection, b, params);
  524 + }*/
497 525 }
  526 +
498 527 }
499 528 });
500 529 },
... ...