Commit 986749f3896d7c68e92b1cdbcf665520589ae6db

Authored by Benjamin Renard
2 parents cbcca5af 5e831fb7

Merge branch 'master' into hapi

desktop.php
... ... @@ -108,7 +108,7 @@
108 108  
109 109 var gatewayTimeout = '<?php if (defined('GATEWAY_TIMEOUT')) echo GATEWAY_TIMEOUT; else echo 300000; ?>'; // in msec
110 110  
111   - var logExecTime = <?php echo (LOG_EXEC_TIME === TRUE ? 'true' : 'false'); ?>;
  111 + var logExecTime = <?php echo (defined('LOG_EXEC_TIME') && (LOG_EXEC_TIME === TRUE) ? 'true' : 'false'); ?>;
112 112  
113 113 //create mask class (LoadMask for elements has been deprecated, use Ext.dom.Element.mask & Ext.dom.Element.unmask)
114 114 var AMDAMask = new Ext.Class({
... ...
generic_data/Functions/constants.xml
1 1 <?xml version="1.0"?>
2   -<constants>
  2 +<constants xml:id="constants">
3 3 <constant info="astronomical unit" name="AU" units="km" kind="space">1.49598e+8</constant>
4 4 <constant info="Boltzmann constant" name="k" units="J/K" kind="physics">1.38054e-23</constant>
5 5 <constant info="kelvin to electron-volt" name="K2eV" units="eV/K" kind="units">8.622e-5</constant>
... ... @@ -8,8 +8,8 @@
8 8 <constant info="electron mass" name="m_e" units="kg" kind="physics">9.1091e-31</constant>
9 9 <constant info="speed of light in vacuum" name="c" units="m/s" kind="physics">2.99792e+08</constant>
10 10 <constant info="elementary charge" name="q_e" units="C" kind="physics">1.6021e-19</constant>
11   - <constant info='electric constant' name="epsilon_0" units="F/m" kind="physics">8.85416e-12</constant>
12   - <constant info='magnetic constant' name="mu_0" units="H/m" kind="physics">1.25664e-06</constant>
  11 + <constant info="electric constant" name="epsilon_0" units="F/m" kind="physics">8.85416e-12</constant>
  12 + <constant info="magnetic constant" name="mu_0" units="H/m" kind="physics">1.25664e-06</constant>
13 13 <constant info="pi" name="pi" kind="physics">3.14159</constant>
14 14 <constant info="rad2deg" name="rad2deg" units="deg/rad" kind="units">57.2958</constant>
15 15 <constant info="deg2rad" name="deg2rad" units="rad/deg" kind="units">0.0174533</constant>
... ...
generic_data/Functions/functions.xml
1 1 <?xml version="1.0"?>
2   -<functions>
  2 +<functions xml:id="functions">
3 3 <function name="mean_(,)" args="1" kind="time">
4 4 <prompt>input averaging time in secs</prompt>
5 5 <info_brief>average</info_brief>
... ... @@ -60,7 +60,6 @@
60 60 <info_brief>variance() function</info_brief>
61 61 <new_kernel>#var_sm</new_kernel>
62 62 </function>
63   -
64 63 <function name="skew_sm_(,)" args="1" kind="sliding">
65 64 <prompt>input window time in secs</prompt>
66 65 <info_brief>skewness() function</info_brief>
... ... @@ -71,56 +70,53 @@
71 70 <info_brief>smooths with a boxcar average</info_brief>
72 71 <new_kernel>#boxcar</new_kernel>
73 72 </function>
74   -
75 73 <!-- <function name="shiftN_(,)" args="1" kind="amda">
76 74 <prompt>input number of points N to delay by</prompt>
77 75 <info_brief>Delays array by N points back (N &lt; 0) and forth (N &gt; 0)</info_brief>
78 76 </function>-->
79   -
80 77 <function name="shiftT_(,)" args="1" kind="amda">
81 78 <prompt>input time interval T in secs to delay by</prompt>
82 79 <info_brief>Shifts parameter by T secs back (T &lt; 0) and forth (T &gt; 0))</info_brief>
83 80 <new_kernel>#timeShift</new_kernel>
84 81 </function>
85   -
86   - <function name="vAlfven(,)" params="2" kind="physics">
87   - <prompt>Alfven velocity Valfven(density[cm^โป3], mag[nT])</prompt>
  82 + <function name="vAlfven(,)" args="2" kind="physics">
  83 + <!-- <prompt>Alfven velocity Valfven(density[cm^โป3], mag[nT])</prompt> -->
88 84 <info_brief>Alfven velocity Valfven(density[cm^โป3], mag[nT])</info_brief>
89 85 <new_kernel>alfvenVelocity</new_kernel>
90 86 </function>
91 87  
92   - <function name="perreault78(,,)" params="3" kind="physics">
  88 + <function name="perreault78(,,)" args="3" kind="physics">
93 89 <info_brief>Perreault and Akasofu 1978 model u = perreault78(E_mag, B_mag, theta_p)</info_brief>
94 90 <new_kernel>perreault78</new_kernel>
95 91 </function>
96 92  
97   - <function name="newell2007(,)" params="3" kind="physics">
  93 + <function name="newell2007(,)" args="3" kind="physics">
98 94 <info_brief>NEWELL et al 2007 solar wind-magnetosphere coupling function d_phi/d_t = newell2007(mu, B_mag, theta) </info_brief>
99 95 <new_kernel>newell2007</new_kernel>
100 96 </function>
101 97  
102   - <!--<function name="fairfield70(,tilt_angle_60)" params="2" kind="physics">-->
103   - <function name="fairfield70(,)" params="2" kind="physics">
104   - <prompt>xyz_sm (Re), dipole tilt angle (deg)</prompt>
  98 + <!--<function name="fairfield70(,tilt_angle_60)" args="2" kind="physics">-->
  99 + <function name="fairfield70(,)" args="2" kind="physics">
  100 + <!-- <prompt>xyz_sm (Re), dipole tilt angle (deg)</prompt> -->
105 101 <info_brief>Distance (Re) from s/c location to Fairfield1970 model neutral sheet position.&lt;br/&gt;
106 102 dZ = fairfield70(xyz_sm, tilt_angle),&lt;br/&gt; xyz_sm is the s/c SM coordinates (Re) and tilt angle is in degrees.&lt;br/&gt; Valid for y_sm &lt; 15 Re.</info_brief>
107 103 <new_kernel>fairfield70</new_kernel>
108 104 </function>
109 105  
110   - <!--<function name="fairfield80(,tilt_angle_60)" params="2" kind="physics">-->
111   - <function name="fairfield80(,)" params="2" kind="physics">
112   - <prompt>xyz_sm (Re), dipole tilt angle (deg)</prompt>
  106 + <!--<function name="fairfield80(,tilt_angle_60)" args="2" kind="physics">-->
  107 + <function name="fairfield80(,)" args="2" kind="physics">
  108 + <!-- <prompt>xyz_sm (Re), dipole tilt angle (deg)</prompt> -->
113 109  
114 110 <info_brief>Distance (Re) from s/c location to Fairfield1980 model neutral sheet position.&lt;br/&gt;
115 111 dZ = fairfield80(xyz_sm, tilt_angle),&lt;br/&gt; xyz_sm is the s/c SM coordinates (Re) and tilt angle is in degrees.&lt;br/&gt;</info_brief>
116 112 <new_kernel>fairfield80</new_kernel>
117 113 </function>
118 114  
119   - <!--<function name="lopez90(omni_kp,,,tilt_angle_60)" params="4" kind="physics">-->
120   - <function name="lopez90(,,,)" params="4" kind="physics">
121   - <prompt>
  115 + <!--<function name="lopez90(omni_kp,,,tilt_angle_60)" args="4" kind="physics">-->
  116 + <function name="lopez90(,,,)" args="4" kind="physics">
  117 + <!-- <prompt>
122 118 Kp, MLT (deg), R (Re), dipole tilt angle ( deg )
123   - </prompt>
  119 + </prompt> -->
124 120 <info_brief>
125 121 Magnetic latitude of the neutral sheet (Lopez1990 model) &lt;br/&gt;
126 122 MLAT = lopez90(Kp, MLT, R, tilt_angle) &lt;br/&gt;
... ... @@ -134,21 +130,26 @@
134 130 <info_brief>frame transformation</info_brief>
135 131 <new_kernel>#framesTransformation</new_kernel>
136 132 </function>-->
137   - <function name="angle(,)" params="2" kind="vectors">
  133 + <function name="angle(,)" args="2" kind="vectors">
138 134 <info_brief>Angle between two vectors</info_brief>
139 135 <new_kernel>angle</new_kernel>
140 136 </function>
141 137  
142   - <function name="cross(,)" params="2" kind="vectors">
  138 + <function name="cross(,)" args="2" kind="vectors">
143 139 <info_brief>Cross product</info_brief>
144 140 <new_kernel>cross</new_kernel>
145 141 </function>
146 142  
147   - <function name="dot(,)" params="2" kind="vectors">
  143 + <function name="dot(,)" args="2" kind="vectors">
148 144 <info_brief>Dot product</info_brief>
149 145 <new_kernel>dot</new_kernel>
150 146 </function>
151 147  
  148 + <function name="vector(,,)" args="3" kind="vectors">
  149 + <info_brief>Build vector from components</info_brief>
  150 + <new_kernel>vector_</new_kernel>
  151 + </function>
  152 +
152 153 <function name="module()" kind="vectors">
153 154 <info_brief>Magnitude</info_brief>
154 155 <new_kernel>magnitude</new_kernel>
... ... @@ -178,7 +179,7 @@
178 179 <info_brief>Arc-tangent</info_brief>
179 180 <new_kernel>atan</new_kernel>
180 181 </function>
181   - <function name="atan2(,)" params="2" kind="math">
  182 + <function name="atan2(,)" args="2" kind="math">
182 183 <info_brief>Arc-tangent</info_brief>
183 184 <new_kernel>atan2</new_kernel>
184 185 </function>
... ...
js/app/models/Function.js
... ... @@ -15,9 +15,8 @@ Ext.define(&#39;amdaModel.Function&#39;, {
15 15 fields : [
16 16 {name: 'name', mapping: '@name', type:'string'},
17 17 {name: 'kind', mapping: '@kind', type: 'string', defaultValue: 'amda'},
18   - {name: 'args', mapping: '@args', type: 'int', defaultValue: 0},
  18 + {name: 'args', mapping: '@args', type: 'int', defaultValue: 1},
19 19 {name: 'argv', mapping: '@argv', type: 'string'},
20   - {name: 'params', mapping: '@params', type:'int', defaultValue: 1},
21 20 {name: 'prompt', type: 'string', defaultValue: ''},
22 21 {name: 'info_brief', type: 'string', defaultValue: ''}
23 22 ],
... ... @@ -37,4 +36,4 @@ Ext.define(&#39;amdaModel.Function&#39;, {
37 36 record: 'function'
38 37 }
39 38 }
40   -});
41 39 \ No newline at end of file
  40 +});
... ...
js/app/views/CalculatorUI.js
... ... @@ -14,470 +14,473 @@
14 14 * @ptype calculator
15 15 */
16 16  
17   -var CalculatorData = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '(', ')', '[', ']', '+', '-', '*', '/', '^', '.', '>', '<', '&', '|'];
18   -// 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','(',')','[',']','+','-','*','/','^', '.','>','>=','=','!=','<=','<', '&', '|'];
19 18  
20 19 Ext.define('amdaUI.CalculatorUI', {
21   - extend: 'Ext.util.Observable',
22   -
23   - requires: [
24   - 'amdaModel.Constant',
25   - 'amdaModel.Function'
26   - ],
27   -
28   - alias: 'plugin.calculator',
29   -
30   - statics: {
31   - constantStore: null,
32   - functionStore: null
33   - },
34   -
35   - win: null,
36   -
37   - constructor: function (config) {
38   - Ext.apply(this, config);
39   - this.callParent(arguments);
40   - },
41   -
42   - init: function (cmp)
43   - {
44   - this.hostCmp = cmp;
45   - this.hostCmp.on({
46   - scope: this,
47   - added: function () {
48   - this.hostCmp.ownerCt.on({
49   - render: this.onRender,
50   - show: this.onShow,
51   - hide: this.onHide,
52   - scope: this});
53   - }
54   - });
55   - },
56   -
57   - onRender: function ()
58   - {
59   - this.win = new Ext.Window({
60   - width: 350,
61   - height: 170,
62   - x: 380, y: 0,
63   - baseCls: 'x-panel',
64   - title: 'Tools For ' + this.context + ' Construction',
65   - layout: 'fit',
66   - closable: false,
67   - collapsible: true,
68   - constrain: true,
69   - floating: true,
70   - ghost: false,
71   - renderTo: this.hostCmp.id,
72   - items: this.getFormConfig(),
73   - listeners: {
74   - boxready: function (w)
75   - {
76   - if (w.y + w.height > myDesktopApp.desktop.el.getHeight())
77   - w.el.setY((myDesktopApp.desktop.el.getHeight() - w.height > 0) ? myDesktopApp.desktop.el.getHeight() - w.height : 0);
78   - }
79   - },
80   - getConstrainVector: function (constrainTo) {
81   - var me = this;
82   - if (me.constrain || me.constrainHeader) {
83   - constrainTo = constrainTo || (me.floatParent && me.floatParent.getTargetEl()) || me.container || me.el.getScopeParent();
84   - return (me.constrainHeader ? me.header.el : me.el).getConstrainVector(constrainTo);
85   - }
86   - }
87   - });
88   -
89   - //load constants store
90   - if (!amdaUI.CalculatorUI.constantStore)
91   - {
92   - amdaUI.CalculatorUI.constantStore = Ext.create('Ext.data.Store', {model: 'amdaModel.Constant'});
93   - amdaUI.CalculatorUI.constantStore.load({
94   - scope: this,
95   - callback: function (records, operation, success)
96   - {
97   - this.createAllConstantBtns();
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   - } else
115   - this.createAllFunctionBtns();
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.params;
190   - var fnText = currentBtn.text.split('(');
191   - var newConstruction = sel.beforeText + fnText[0] + "(";
192   - // if there at least one parameter selected
193   - if (params.length) {
194   - for (var i = 0; i < nbParams; i++) {
195   - if (i > 0) {
196   - newConstruction += ",";
197   - }
198   - newConstruction += params[i];
199   - }
200   - }
201   - // we keep position
202   - var afterParameterPos = newConstruction.length;
203   - newConstruction += afterParamsText;
204   - var caretPos = newConstruction.length;
205   - newConstruction += sel.afterText;
206   - this.hostCmp.constructionField.setValue(newConstruction);
207   -
208   - // If we haven't the right number of selected parameters
209   - if (params.length < nbParams) {
210   - var stringParamRequired = currentBtn.initialConfig.params + " parameter(s)";
211   - Ext.Msg.alert('Caution', 'you\'ll have to add ' + stringParamRequired + ' to apply this function',
212   - function () {
213   - // set Caret Position at placement of required parameter in function
214   - this.hostCmp.constructionField.setCaretPosition(afterParameterPos);
215   - }, this
216   - );
217   - } else {
218   - // set Caret Position after inserted Text
219   - this.hostCmp.constructionField.setCaretPosition(caretPos);
220   - }
221   - },
222   -
223   - /**
224   - * This method construct an array of arguments into selected text
225   - * @param selectedText the selection to parse
226   - * @param parseIndex the index to start parsing
227   - * @return the arguments array
228   - */
229   - parseArgsInFormula: function (selectedText, parseIndex) {
230   -
231   - if (!selectedText || selectedText == "") {
232   - return [];
233   - } else {
234   - var params = [];
235   - var startIndex = parseIndex;
236   - var curIndex = parseIndex;
237   - var openBrace = 0;
238   - var sep = 0;
239   - var closeBrace = 0;
240   -
241   - // while there is a separator
242   - while (sep != -1) {
243   - openBrace = selectedText.indexOf("(", curIndex);
244   - sep = selectedText.indexOf(",", curIndex);
245   - closeBrace = selectedText.indexOf(")", curIndex);
246   -
247   - // if there's an open bracket and no close bracket or inversely
248   - if (openBrace != -1 && closeBrace == -1 || openBrace == -1 && closeBrace != -1) {
249   - // invalid selection
250   - return -1;
251   - }
252   -
253   - // if there's a separator and opening brackets into selection
254   - if (sep != -1 && openBrace != -1) {
255   - // if brace is before separator
256   - if (openBrace < sep) {
257   - curIndex = this.getEndBracket(selectedText, openBrace + 1);
258   - if (curIndex === -1) {
259   - return -1;
260   - }
261   - } else {// else separator is before brace
262   - params.push(selectedText.substring(startIndex, sep));
263   - startIndex = curIndex = sep + 1;
264   - }
265   - // if there's only separators into selection
266   - } else if (sep != -1) {
267   - params.push(selectedText.substring(startIndex, sep));
268   - startIndex = curIndex = sep + 1;
269   - }
270   - }
271   - params.push(selectedText.substring(startIndex, selectedText.length));
272   - return params;
273   - }
274   - },
275   -
276   - getEndBracket: function (string, indOpenBrace) {
277   - // we search for the corresponding end brace (after open bracket)
278   - var currentIndex = indOpenBrace;
279   - var nextCloseBrace = 0;
280   - var nextOpenBrace = 0;
281   - var braceLevel = 1;
282   - while (nextCloseBrace !== -1 && braceLevel !== 0) {
283   - // get index of next opening bracket
284   - nextOpenBrace = string.indexOf("(", currentIndex);
285   - // get index of next closing bracket
286   - nextCloseBrace = string.indexOf(")", currentIndex);
287   - // if both exist
288   - if (nextOpenBrace != -1 && nextCloseBrace != -1) {
289   - // if opening bracket is before closing one
290   - if (nextOpenBrace < nextCloseBrace) {
291   - currentIndex = nextOpenBrace + 1;
292   - braceLevel++;
293   - } else { // if closing bracket is before opening one
294   - currentIndex = nextCloseBrace + 1;
295   - braceLevel--;
296   - }
297   - // if there's only a next opening bracket
298   - } else if (nextOpenBrace != -1 && nextCloseBrace == -1) {
299   - currentIndex = nextOpenBrace + 1;
300   - braceLevel++;
301   - // if there's only a next closing bracket
302   - } else if (nextOpenBrace == -1 && nextCloseBrace != -1) {
303   - currentIndex = nextCloseBrace + 1;
304   - braceLevel--;
305   - }
306   - }
307   - // if no level imbrication left return index after closing bracket of block else -1
308   - return braceLevel == 0 ? currentIndex : -1;
309   - },
310   -
311   - getCalculatorBtn: function ()
312   - {
313   - var btns = [];
314   -
315   - Ext.each(CalculatorData, function (c) {
316   - btns.push({
317   - text: c,
318   - scope: this,
319   - handler: function (b, e) {
320   - // keep selection into construction field
321   - var selection = this.hostCmp.constructionField.getSelection();
322   - // the new value of construction field
323   - var newConstruction = "";
324   - // replacement of selection into construction field by text of clicked button
325   - newConstruction = selection.beforeText + b.text;
326   - var caretPos = newConstruction.length;
327   - newConstruction += selection.afterText;
328   - this.hostCmp.constructionField.setValue(newConstruction);
329   - // set Caret Position after inserted Text
330   - this.hostCmp.constructionField.setCaretPosition(caretPos);
331   - }
332   - })
333   - },
334   - this
335   - );
336   -
337   - return btns;
338   - },
339   -
340   - createAllFunctionBtns: function ()
341   - {
342   - this.createFunctionBtns('MathFunctions', 'Simple Maths');
343   - this.createFunctionBtns('VectorFunctions', 'Vector Functions');
344   - this.createFunctionBtns('TimeFunctions', 'Statistics');
345   - this.createFunctionBtns('FunctionsSliding', 'Statistics/Sliding');
346   - this.createFunctionBtns('PhysicsFunctions', 'Physics');
347   - this.createFunctionBtns('AmdaFunctions', 'Special');
348   - },
349   -
350   - createAllConstantBtns: function ()
351   - {
352   - this.createConstantBtns('Space', 'Planets Constants');
353   - this.createConstantBtns('Physics', 'Physics Constants');
354   - this.createConstantBtns('Units', 'Units Conversion');
355   - },
356   -
357   - createConstantBtns: function (item, tabTitle)
358   - {
359   - var constTab = this.win.query('#calc_tab_const_id');
360   -
361   - if (constTab.length < 1)
362   - return;
363   -
364   - switch (item)
365   - {
366   - case 'Space' :
367   - amdaUI.CalculatorUI.constantStore.filter('kind', 'space');
368   - break;
369   - case 'Physics' :
370   - amdaUI.CalculatorUI.constantStore.filter('kind', 'physics');
371   - break;
372   - case 'Units' :
373   - amdaUI.CalculatorUI.constantStore.filter('kind', 'units');
374   - break;
375   - }
376   -
377   - var crtTab = constTab[0].add(
378   - {
379   - title: tabTitle,
380   - defaults: {xtype: 'button', columnWidth: .20}
381   - });
382   -
383   - amdaUI.CalculatorUI.constantStore.each(function (c) {
384   - crtTab.add(
385   - {
386   - text: c.get('name'),
387   - tooltip: c.get('units') == '' ? c.get('info') + '<br/>' + c.get('value') :
388   - c.get('info') + '<br/>' + c.get('value') + ' ' + c.get('units'),
389   - scope: this,
390   - handler: function (b, e) {
391   - // keep selection into construction field
392   - var selection = this.hostCmp.constructionField.getSelection();
393   - // the new value of construction field
394   - var newConstruction = "";
395   - // replacement of selection into construction field by text of clicked button
396   - newConstruction = selection.beforeText + '@' + b.text;
397   - var caretPos = newConstruction.length;
398   - newConstruction += selection.afterText;
399   - this.hostCmp.constructionField.setValue(newConstruction);
400   - // set Caret Position after inserted Text
401   - this.hostCmp.constructionField.setCaretPosition(caretPos);
402   - }
403   - });
404   - }, this);
405   -
406   - //clear filter
407   - amdaUI.CalculatorUI.constantStore.clearFilter();
408   - },
409   -
410   - createFunctionBtns: function (item, tabTitle)
411   - {
412   - var funcTab = this.win.query('#calc_tab_func_id');
413   -
414   - if (funcTab.length < 1)
415   - return;
416   - var width = .20;
417   -
418   - switch (item)
419   - {
420   - case 'MathFunctions' :
421   - amdaUI.CalculatorUI.functionStore.filter('kind', 'math');
422   - break;
423   - case 'AmdaFunctions' :
424   - amdaUI.CalculatorUI.functionStore.filter('kind', 'amda');
425   - break;
426   - case 'TimeFunctions' :
427   - amdaUI.CalculatorUI.functionStore.filter('kind', 'time');
428   - break;
429   - case 'FunctionsSliding' :
430   - amdaUI.CalculatorUI.functionStore.filter('kind', 'sliding');
431   - break;
432   - case 'VectorFunctions' :
433   - amdaUI.CalculatorUI.functionStore.filter('kind', 'vector');
434   - break;
435   - case 'PhysicsFunctions' :
436   - amdaUI.CalculatorUI.functionStore.filter('kind', 'physics');
437   - width = .25;
438   - break;
439   - }
440   -
441   - var crtTab = funcTab[0].add(
442   - {
443   - title: tabTitle,
444   - defaults: {xtype: 'button', columnWidth: width}
445   - });
446   -
447   - amdaUI.CalculatorUI.functionStore.each(function (f) {
448   - crtTab.add(
449   - {
450   - text: f.get('name'),
451   - args: f.get('args'),
452   - params: f.get('params'),
453   - prompt: f.get('prompt'),
454   - tooltip: f.get('info_brief'),
455   - scope: this,
456   - handler: function (b, e) {
457   - var selection = this.hostCmp.constructionField.getSelection();
458   - var selectedText = selection && selection.text != "" ? Ext.util.Format.trim(selection.text) : null;
459   - if (selectedText && selectedText !== "") {
460   - selectedText.replace("[", "(");
461   - selectedText.replace("{", "(");
462   - selectedText.replace("}", ")");
463   - selectedText.replace("]", ")");
464   - }
465   - // Formula Parsing for arguments
466   - 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 + }
  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);
467 469 // var params = selectedText ? selectedText.split(',') : [];
468   - if (params === -1) {
469   - Ext.Msg.alert("Invalid Selection", "Action aborted");
470   - } else {
471   - // calculation of the required number of parameters
472   - var nbParams = b.initialConfig.params;
473   -
474   - if (params.length > nbParams)
475   - {
476   - // Show a dialog using config options:
477   - Ext.Msg.show({
478   - title: 'Caution',
479   - msg: 'you have selected more than ' + nbParams + ' parameter(s) to apply this function<br>Only the first will be kept, others will be deleted',
480   - buttons: Ext.Msg.OKCANCEL,
  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,
481 484 // animEl: 'elId',
482 485 icon: Ext.MessageBox.WARNING,
483 486 fn: function (bt1) {
... ...
php/WebServices/WebServer.php
... ... @@ -200,7 +200,7 @@ class WebServer
200 200 private function doDownloadRequest($interval, $paramList, $formatInfo, $file_info)
201 201 {
202 202 if (!isset($this->paramLoader))
203   - $this->paramLoader = new IHMUserParamLoaderClass();
  203 + $this->paramLoader = new IHMUserParamManagerClass();
204 204  
205 205 //Build parameter list
206 206 $params = array();
... ...
php/classes/RequestMgr.php
... ... @@ -213,7 +213,7 @@ class RequestMgr extends AmdaObjectMgr
213 213 case 'request' :
214 214  
215 215 //TODO check TT as well (first start and last stop ?)
216   - if ($obj->timesrc != 'Interval') continue;
  216 + if ($obj->timesrc != 'Interval') break;
217 217  
218 218 $argsTab = array();
219 219 foreach ($obj->panels as $panel)
... ...
php/config.php
... ... @@ -39,7 +39,7 @@ if (!defined(&#39;MAGIC_FILE&#39;)) define(&#39;MAGIC_FILE&#39;,&#39;/usr/share/misc/magic&#39;);
39 39 date_default_timezone_set('UTC');
40 40  
41 41 // GUESTS LOGIN section
42   -define("MaxGuests", 10); // Max Guests number
  42 +define("MaxGuests", 15); // Max Guests number
43 43 define("GuestSessionDuration", 300); //300 minutes
44 44 define("MaxGuestTimeInterval", 10); // days
45 45  
... ... @@ -67,7 +67,7 @@ ini_set(&#39;user_agent&#39;, &#39;Mozilla/5.0 (X11; U; Linux i686; en-US; rv:7.0) Gecko/201
67 67 // ini_set('post_max_size',1050000000);
68 68  
69 69 // Delay between two update of remote parameters (in sec.)
70   -define('REMOTE_PARAMS_UPDATE_DELAY', 3600);
  70 +define('REMOTE_PARAMS_UPDATE_DELAY', 86400);
71 71  
72 72 // General Info dirs
73 73 define('DATAPATH', IHM_SRC_DIR.'/generic_data/');
... ...