source: source/class/pf/Application.js @ 64:c8235428508e

Last change on this file since 64:c8235428508e was 64:c8235428508e, checked in by fnevgeny, 17 years ago

Added help menu entry -> plasma@wikipedia.

File size: 79.5 KB
Line 
1/* ************************************************************************
2
3   Copyright:
4
5   License:
6
7   Authors:
8
9************************************************************************ */
10
11/* ************************************************************************
12
13#resource(pf.image:image)
14#embed(pf.image/*)
15
16************************************************************************ */
17
18
19var plasma_entities = new Array(
20    {
21        name      : "Plasma frequency",
22        dimension : "frequency",
23        nspecies  : 1,
24        section   : "fundamental",
25        formula   : "%s1.getPlasmaFrequency()"
26    },
27    {
28        name      : "Gyrofrequency",
29        dimension : "frequency",
30        nspecies  : 1,
31        section   : "fundamental",
32        formula   : "%s1.getGyroFrequency(this.B)"
33    },
34
35    {
36        name      : "Debye length",
37        dimension : "length",
38        nspecies  : 1,
39        section   : "fundamental",
40        formula   : "%s1.getDebyeLength()"
41    },
42    {
43        name      : "Full Debye length",
44        dimension : "length",
45        nspecies  : 1,
46        section   : "fundamental",
47        formula   : "this.getFullDebyeLength(%s1)"
48    },
49    {
50        name      : "deBroglie length",
51        dimension : "length",
52        nspecies  : 1,
53        section   : "fundamental",
54        formula   : "%s1.getDeBroglieLength()"
55    },
56    {
57        name      : "Mean interparticle distance",
58        dimension : "length",
59        nspecies  : 1,
60        section   : "fundamental",
61        formula   : "%s1.getMeanDistance()"
62    },
63    {
64        name      : "Distance of minimal approach",
65        dimension : "length",
66        nspecies  : 1,
67        section   : "fundamental",
68        formula   : "%s1.getMinApproachDistance()"
69    },
70    {
71        name      : "Gyroradius",
72        dimension : "length",
73        nspecies  : 1,
74        section   : "fundamental",
75        formula   : "%s1.getGyroRadius(this.B)"
76    },
77    {
78        name      : "Inertial length",
79        dimension : "length",
80        nspecies  : 1,
81        section   : "fundamental",
82        formula   : "%s1.getInertialLength()"
83    },
84
85    {
86        name      : "Thermal velocity",
87        dimension : "velocity",
88        nspecies  : 1,
89        section   : "fundamental",
90        formula   : "%s1.getThermalVelocity()"
91    },
92    {
93        name      : "Alfven velocity",
94        dimension : "velocity",
95        nspecies  : 1,
96        section   : "fundamental",
97        formula   : "%s1.getAlfvenVelocity(this.B)"
98    },
99
100    {
101        name      : "Coupling parameter",
102        dimension : "none",
103        nspecies  : 1,
104        section   : "fundamental",
105        formula   : "%s1.getCoupling()"
106    },
107    {
108        name      : "Typical Debye screening",
109        dimension : "none",
110        nspecies  : 1,
111        section   : "spectroscopy",
112        formula   : "var r = %s1.getMeanDistance()/%s1.getDebyeLength(); \
113                     (1 + r)*Math.exp(-r)"
114    },
115
116    {
117        name      : "Transition energy",
118        dimension : "energy",
119        nspecies  : 0,
120        section   : "spectroscopy",
121        formula   : "this.getWavenumber()"
122    },
123    {
124        name      : "Natural linewidth",
125        dimension : "energy",
126        nspecies  : 0,
127        section   : "spectroscopy",
128        formula   : "this.getNaturalWidth()"
129    },
130    {
131        name      : "Doppler FWHM",
132        dimension : "energy",
133        nspecies  : 0,
134        section   : "spectroscopy",
135        formula   : "2*this.getDopplerHwhm()"
136    },
137    {
138        name      : "Zeeman splitting",
139        dimension : "energy",
140        nspecies  : 0,
141        section   : "spectroscopy",
142        formula   : "2*this.getZeemanSplitting()"
143    },
144    {
145        name      : "Total Stark FWHM",
146        dimension : "energy",
147        nspecies  : 0,
148        section   : "spectroscopy",
149        formula   : "2*this.getStarkHwhm()"
150    },
151    {
152        name      : "QS Stark FWHM",
153        dimension : "energy",
154        nspecies  : 1,
155        section   : "spectroscopy",
156        formula   : "2*this.getQsHwhm(%s1)"
157    },
158    {
159        name      : "Stark FWHM",
160        dimension : "energy",
161        nspecies  : 1,
162        section   : "spectroscopy",
163        formula   : "2*this.getQsHwhm(%s1)*this.getStarkQuasistaticity(%s1)"
164    },
165
166    {
167        name      : "Dynamic Stark range",
168        dimension : "energy",
169        nspecies  : 1,
170        section   : "spectroscopy",
171        formula   : "this.getMicrofieldFrequency(%s1)/3e10/(2*Math.PI)"
172    },
173
174    {
175        name      : "Minimal energy distance",
176        dimension : "energy",
177        nspecies  : 0,
178        section   : "spectroscopy",
179        formula   : "this.getMinEnergyDistance()"
180    },
181
182    {
183        name      : "Static/dynamic Stark ratio",
184        dimension : "none",
185        nspecies  : 1,
186        section   : "spectroscopy",
187        formula   : "this.getStarkRatio(%s1)"
188    },
189    {
190        name      : "Stark quasistaticity",
191        dimension : "none",
192        nspecies  : 1,
193        section   : "spectroscopy",
194        formula   : "this.getStarkQuasistaticity(%s1)"
195    },
196
197    {
198        name      : "Transition wavelength",
199        dimension : "length",
200        nspecies  : 0,
201        section   : "spectroscopy",
202        formula   : "1/this.getWavenumber()"
203    },
204
205    {
206        name      : "Transition frequency",
207        dimension : "frequency",
208        nspecies  : 0,
209        section   : "spectroscopy",
210        formula   : "3e10*this.getWavenumber()"
211    },
212
213    {
214        name      : "Holtsmark field",
215        dimension : "efield",
216        nspecies  : 1,
217        section   : "spectroscopy",
218        formula   : "%s1.getHoltsmarkField()"
219    },
220
221    {
222        name      : "Microfield frequency",
223        dimension : "frequency",
224        nspecies  : 1,
225        section   : "spectroscopy",
226        formula   : "this.getMicrofieldFrequency(%s1)"
227    },
228   
229    {
230        name      : "Cyclotron losses",
231        dimension : "power_density",
232        nspecies  : 1,
233        section   : "radiation",
234        formula   : "%s1.getCyclotronLosses(this.B)"
235    },
236   
237    {
238        name      : "Free-free losses",
239        dimension : "power_density",
240        nspecies  : 0,
241        section   : "radiation",
242        formula   : "this.getBremsstrahlungLosses()"
243    },
244   
245    {
246        name      : "Free-free spectral density",
247        dimension : "spectral_power_density",
248        nspecies  : 0,
249        section   : "radiation",
250        formula   : "this.getBremsstrahlungSpectralDensity()"
251    },
252   
253    {
254        name      : "Free-bound losses",
255        dimension : "power_density",
256        nspecies  : 0,
257        section   : "radiation",
258        formula   : "this.getFreeBoundLosses()"
259    },
260   
261    {
262        name      : "Free-bound spectral density",
263        dimension : "spectral_power_density",
264        nspecies  : 0,
265        section   : "radiation",
266        formula   : "this.getFreeBoundSpectralDensity()"
267    },
268   
269    {
270        name      : "Bound-bound losses",
271        dimension : "power_density",
272        nspecies  : 0,
273        section   : "radiation",
274        formula   : "this.getBoundBoundLosses()"
275    },
276   
277    {
278        name      : "Ideal gas pressure",
279        dimension : "pressure",
280        nspecies  : 1,
281        section   : "fundamental",
282        formula   : "%s1.getPressure()"
283    },
284   
285    {
286        name      : "Total pressure",
287        dimension : "pressure",
288        nspecies  : 0,
289        section   : "fundamental",
290        formula   : "this.getPressure()"
291    },
292   
293    {
294        name      : "Magnetic field pressure",
295        dimension : "pressure",
296        nspecies  : 0,
297        section   : "fundamental",
298        formula   : "this.getMagneticFieldPressure()"
299    },
300   
301    {
302        name      : "Beta",
303        dimension : "none",
304        nspecies  : 0,
305        section   : "fundamental",
306        formula   : "this.getBeta()"
307    },
308   
309    {
310        name      : "Thomson cross-section",
311        dimension : "area",
312        nspecies  : 1,
313        section   : "collisions",
314        formula   : "%s1.getThomsonXsTotal()"
315    }
316);
317
318
319function LymanA(n)
320{
321    if (n <= 1) {
322        return 0;
323    } else {
324        return 8e9*256/9*n*Math.pow((n - 1)/(n + 1), 2*n)/((n*n - 1)*(n*n - 1));
325    }
326}
327
328
329function NumPrint(v, prec)
330{
331    var s;
332   
333    if (prec == null) {
334        prec = 3;
335    }
336   
337    if (v == 0.0) {
338        s = "0";
339    } else
340    if (!isFinite(v)) {
341        s = v;
342    } else
343    if (Math.abs(v) < 1.e6 && Math.abs(v) >= 0.1) {
344        s = sprintf("%." + prec.toString() + "f", v);
345    } else {
346        s = sprintf("%." + prec.toString() + "e", v);
347    }
348   
349    return s;
350}
351
352function changeN_e(ev)
353{
354    var e = ev.getTarget();
355    var N_e = e.getNumValue();
356   
357    if (isFinite(N_e) && this.e.setN(N_e)) {
358        this.updatePlasmaParameters();
359        this.updateGUI();
360    }
361}
362
363function changeT_e(ev)
364{
365    var e = ev.getTarget();
366    var T_e = e.getNumValue();
367   
368    if (isFinite(T_e)) {
369        this.e.setT(T_e);
370        this.i.setT(T_e);
371        this.r.setT(T_e);
372        this.updateGUI();
373    }
374}
375
376function changeZ_i(ev)
377{
378    var e = ev.getTarget();
379    var Z_i = parseInt(e.getValue());
380   
381    if (isFinite(Z_i)) {
382        this.i.setQ(Z_i);
383        this.updatePlasmaParameters();
384        this.updateGUI();
385    }
386}
387
388function changeT_i(ev)
389{
390    var e = ev.getTarget();
391    var T_i = e.getNumValue();
392   
393    if (isFinite(T_i)) {
394        this.i.setT(T_i);
395        this.r.setT(T_i);
396        this.updateGUI();
397    }
398}
399
400function changeZ_r(ev)
401{
402    var e = ev.getTarget();
403    var Z_r = parseInt(e.getValue());
404   
405    if (isFinite(Z_r)) {
406        this.r.setQ(Z_r);
407        this.updatePlasmaParameters();
408        this.updateGUI();
409    }
410}
411
412function changeP_r(ev)
413{
414    var e = ev.getTarget();
415    var P_r = parseInt(e.getValue())/100.0;
416   
417    if (isFinite(P_r)) {
418        this.P_r = P_r;
419        this.updatePlasmaParameters();
420        this.updateGUI();
421    }
422}
423
424function changeT_r(ev)
425{
426    var e = ev.getTarget();
427    var T_r = e.getNumValue();
428   
429    if (isFinite(T_r)) {
430        this.r.setT(T_r);
431        this.updateGUI();
432    }
433}
434
435function changeM_i(ev)
436{
437    var e = ev.getTarget();
438    var M_i = parseInt(e.getValue());
439   
440    if (isFinite(M_i)) {
441        this.i.setM(M_i);
442        this.updateGUI();
443    }
444}
445
446function changeM_r(ev)
447{
448    var e = ev.getTarget();
449    var M_r = parseInt(e.getValue());
450   
451    if (isFinite(M_r)) {
452        this.r.setM(M_r);
453        this.updateGUI();
454    }
455}
456
457function changeN_u(ev)
458{
459    var e = ev.getTarget();
460    var n_u = parseInt(e.getValue());
461   
462    this.n_u = n_u;
463    this.updateGUI();
464}
465
466function changeN_l(ev)
467{
468    var e = ev.getTarget();
469    var n_l = parseInt(e.getValue());
470   
471    this.n_l = n_l;
472    this.updateGUI();
473}
474
475function changeB(ev)
476{
477    var e = ev.getTarget();
478    var v = e.getNumValue();
479   
480    if (isFinite(v)) {
481        this.B = v;
482        this.updateGUI();
483    }
484}
485
486function viewMenuCB(ev)
487{
488    var explorer_is_seen;
489   
490    if (this.entity_tree.isSeeable()) {
491        explorer_is_seen = true;
492    } else {
493        explorer_is_seen = false;
494    }
495   
496    this.showSectionsButton.setEnabled(explorer_is_seen);
497    this.showSpeciesButton.setEnabled(explorer_is_seen);
498    this.redrawButton.setEnabled(this.canvas.isSeeable());
499}
500
501function editMenuCB(ev)
502{
503    var explorer_is_seen;
504   
505    if (this.entity_tree.isSeeable()) {
506        explorer_is_seen = true;
507    } else {
508        explorer_is_seen = false;
509    }
510
511    var tree = this.entity_tree;
512    var leaf = tree.getSelectedElement();
513
514    if (leaf && leaf.classname == "qx.ui.tree.TreeFile" && explorer_is_seen) {
515        if (this.isFavorite(leaf)) {
516            this.editMenuButtonAddToFav.setEnabled(false);
517            this.editMenuButtonRemFromFav.setEnabled(true);
518        } else {
519            this.editMenuButtonAddToFav.setEnabled(true);
520            this.editMenuButtonRemFromFav.setEnabled(false);
521        }
522    } else {
523        this.editMenuButtonAddToFav.setEnabled(false);
524        this.editMenuButtonRemFromFav.setEnabled(false);
525    }
526}
527
528function treeMenuCB(ev)
529{
530    if (ev.getButton() == "right") {
531        var menu = this.treeMenu;
532
533        if (menu.isSeeable()) {
534            menu.hide();
535        } else {
536            var leaf = ev.getTarget();
537            var el = leaf.getElement();
538           
539            if (leaf.classname == "qx.ui.tree.TreeFile") {
540                if (this.isFavorite(leaf)) {
541                    this.treeMenuButtonAddToFav.setEnabled(false);
542                    this.treeMenuButtonRemFromFav.setEnabled(true);
543                } else {
544                    this.treeMenuButtonAddToFav.setEnabled(true);
545                    this.treeMenuButtonRemFromFav.setEnabled(false);
546                }
547            } else {
548                this.treeMenuButtonAddToFav.setEnabled(false);
549                this.treeMenuButtonRemFromFav.setEnabled(false);
550            }
551           
552            // position the menu
553            menu.setLeft(ev.getClientX());
554            menu.setTop(ev.getClientY());
555
556            menu.show();
557        };
558
559        ev.setPropagationStopped(true);
560    }
561}
562
563function showFundamentalCB(ev)
564{
565    this.showFundamental = !this.showFundamental;
566    this.rePopulateTree();
567}
568
569function showSpectroscopyCB(ev)
570{
571    this.showSpectroscopy = !this.showSpectroscopy;
572    this.rePopulateTree();
573}
574
575function showElectronsCB(ev)
576{
577    this.showElectrons = !this.showElectrons;
578    this.rePopulateTree();
579}
580
581function showIonsCB(ev)
582{
583    this.showIons = !this.showIons;
584    this.rePopulateTree();
585}
586
587function showRadiatorsCB(ev)
588{
589    this.showRadiators = !this.showRadiators;
590    this.rePopulateTree();
591}
592
593function addToFavCB(ev)
594{
595    var tree = this.entity_tree;
596    var leaf = tree.getSelectedElement();
597
598    if (!leaf) {
599        return;
600    }
601
602    leaf.setTextColor("red");
603
604    // Add to the list of favorites
605    var fav = new Array;
606    fav.entity  = leaf.getUserData("entity");
607    fav.species = leaf.getUserData("species");
608    fav.color   = this.nextColor();
609    this.favorites.push(fav);
610   
611    // Switch the dimension selector ...
612    this.gui_compare_dim.selectByValue(fav.entity.dimension);
613    // ... and update the list of favorites
614    this.updateFavoritesListView();
615    this.updateLegendListView();
616}
617
618function removeFromFavCB(ev)
619{
620    var tree = this.entity_tree;
621    var leaf = tree.getSelectedElement();
622
623    if (!leaf) {
624        return;
625    }
626    leaf.setTextColor("black");
627
628    var entity  = leaf.getUserData("entity");
629    var species = leaf.getUserData("species");
630
631    // Remove from the list of favorites
632    for (var k = 0; k < this.favorites.length; k++) {
633        var fav = this.favorites[k];
634        if (fav.entity  == entity && fav.species == species) {
635            this.favorites.splice(k, 1);
636            break;
637        }
638    }
639
640    // Switch the dimension selector ...
641    this.gui_compare_dim.selectByValue(entity.dimension);
642    // ... and update the list of favorites
643    this.updateFavoritesListView();
644    this.updateLegendListView();
645}
646
647function clickEntityCB(ev)
648{
649    var e = ev.getTarget();
650    var entity = e.getUserData("entity");
651   
652    this.gui_entity_units.update(entity.dimension,
653        this.prefs.units[entity.dimension]);
654   
655    this.updateEntityValue();
656}
657
658function changeUnitsCB(ev)
659{
660    this.updateEntityValue();
661}
662
663/**
664 * The application
665 */
666qx.Class.define("pf.Application",
667{
668    extend : qx.application.Gui,
669
670    /*
671    *****************************************************************************
672       MEMBERS
673    *****************************************************************************
674    */
675
676    members :
677    {
678        R0 : 0.5, // 0.3/0.7/1 ?
679       
680        showFundamental  : true,
681        showSpectroscopy : true,
682
683        showElectrons  : true,
684        showIons       : true,
685        showRadiators  : true,
686
687        checkPlasmaParameters : function()
688        {
689            if ((this.P_r < 0.0 || this.P_r > 1.0) ||
690                this.Z_i < 1 ||
691                this.P_r == 1.0 && this.Z_r == 0) {
692                return false;
693            } else {
694                return true;
695            }
696        },
697
698        updatePlasmaParameters : function()
699        {
700            // Safety measures
701            if (this.checkPlasmaParameters() != true) {
702                return false;
703            }
704           
705            var N_e = this.e.getN();
706            var N_i, N_r;
707           
708            if (this.P_r < 1.0) {
709                N_i = N_e*(1.0 - this.P_r)/
710                    (this.i.getQ()*(1.0 - this.P_r) + this.r.getQ()*this.P_r);
711               
712                N_r = N_i*this.P_r/(1.0 - this.P_r);
713            } else {
714                N_i = 0.0;
715                N_r = N_e/this.r.getQ();
716            }
717           
718            this.i.setN(N_i);
719            this.r.setN(N_r);
720           
721            return true;
722        },
723       
724        updateGUI : function()
725        {
726            this.gui_N_i.setNumValue(this.i.getN());
727            this.gui_N_r.setNumValue(this.r.getN());
728            this.gui_T_i.setNumValue(this.i.getT());
729            this.gui_T_r.setNumValue(this.r.getT());
730            this.gui_Zcore.setValue(this.r.getQ() + 1);
731           
732            // Update the currently selecte entity
733            this.updateEntityValue();
734           
735            // Update the list of favorites
736            this.updateFavoritesListView();
737            this.updateLegendListView();
738        },
739       
740        getWavenumber : function()
741        {
742            var n_u = this.n_u;
743            var n_l = this.n_l;
744            var Z_core = this.r.getQ() + 1;
745           
746            return pf.base.Bohr.transitionEnergy(Z_core, n_u, n_l);
747        },
748       
749        getMinEnergyDistance : function()
750        {
751            var n;
752            if (this.n_u < this.n_l) {
753                n = this.n_l;
754            } else {
755                n = this.n_u;
756            }
757           
758            var Z_core = this.r.getQ() + 1;
759           
760            return pf.base.Bohr.transitionEnergy(Z_core, n + 1, n);
761        },
762       
763        getNaturalWidth : function()
764        {
765            var n_u = this.n_u;
766            var n_l = this.n_l;
767            var Z_core = this.r.getQ() + 1;
768           
769            return Math.pow(Z_core, 4)*
770                (LymanA(n_u) + LymanA(n_l))/3e10/(2*Math.PI);
771        },
772       
773        getDopplerHwhm : function()
774        {
775            var v   = this.r.getThermalVelocity();
776            var nu  = this.getWavenumber();
777           
778            return Math.sqrt(2*Math.log(2))*nu*v/3e10;
779        },
780       
781        getMicrofieldFrequency : function(s)
782        {
783            var r = s.getMeanDistance();
784            var v_r = this.r.getThermalVelocity();
785            var v_s = s.getThermalVelocity();
786            var v = Math.sqrt(v_r*v_r + v_s*v_s);
787           
788            return v/r;
789        },
790       
791        getFullDebyeLength : function(s)
792        {
793            var tmp = 0;
794            var m = s.getM();
795           
796            var sa = new Array(this.e, this.i, this.r);
797            for (var i = 0; i < 3; i++) {
798                var os = sa[i];
799                if (os.getM() <= m) {
800                    var ld = os.getDebyeLength();
801                    if (ld) {
802                        tmp += 1/(ld*ld);
803                    }
804                }
805               
806            }
807           
808            return 1/Math.sqrt(tmp);
809        },
810       
811        getPpiFactor : function(s)
812        {
813            var dl = this.getFullDebyeLength(s);
814            var r1 = s.getMeanDistance();
815            var r;
816            if (isFinite(dl) && isFinite(r1)) {
817                r = r1/dl;
818            } else {
819                r = 0;
820            }
821           
822            return (1 + r)*Math.exp(-r);
823            // return 1 - 0.6*r
824        },
825       
826        getRpiFactor : function(s)
827        {
828            var r1 = s.getMeanDistance();
829            var q_r = this.r.getQ();
830            var q_s = s.getQ();
831            if (q_r == 0 || q_s == 0) {
832                return 1;
833            }
834             
835            var r_m = s.getMinApproachDistance()*q_r/q_s;
836            return Math.exp(-r_m/r1);
837        },
838       
839        getQsHwhm : function(s)
840        {
841            var n_u = this.n_u;
842            var n_l = this.n_l;
843            var Z_core = this.r.getQ() + 1;
844            var ef = s.getHoltsmarkField();
845            var ppi = this.getPpiFactor(s);
846            var rpi = this.getRpiFactor(s);
847           
848            // 1.4385 is S_1 HWHM
849            return 1.4385*4.271417e-5*3/2*(n_u*n_u - n_l*n_l)/Z_core*ef*ppi*rpi;
850        },
851       
852        getStarkRatio : function(s)
853        {
854            var R;
855            var w_qs = this.getQsHwhm(s);
856            if (w_qs == 0) {
857                R = 0;
858            } else {
859                R = 2*w_qs/(this.getMicrofieldFrequency(s)/3e10/(2*Math.PI));
860            }
861           
862            return R;
863        },
864       
865        getStarkQuasistaticity : function(s)
866        {
867            var R = this.getStarkRatio(s);
868            return R/(R + this.R0);
869        },
870       
871        getStarkHwhm : function()
872        {
873            var w = 0;
874           
875            var sa = new Array(this.e, this.i, this.r);
876            for (var i = 0; i < 3; i++) {
877                var s = sa[i];
878                var qs = this.getQsHwhm(s);
879                var f  = this.getStarkQuasistaticity(s);
880
881                w += Math.pow(f*qs, 3/2);
882            }
883           
884            return Math.pow(w, 2/3);
885        },
886       
887        getZeemanSplitting : function()
888        {
889            return 0.466860*this.B;
890        },
891
892        getTotalFwhm : function()
893        {
894            var s_hwhm = this.getStarkHwhm();
895            var z_hwhm = this.getZeemanSplitting();
896            var d_hwhm = this.getDopplerHwhm();
897            return 2*Math.sqrt(s_hwhm*s_hwhm + z_hwhm*z_hwhm + d_hwhm*d_hwhm);
898        },
899       
900        getBremsstrahlungLosses : function()
901        {
902            var z_i = this.i.getQ();
903            var z_r = this.r.getQ();
904            return 1.69e-32*this.e.getN()*Math.sqrt(this.e.getT())*
905                (this.i.getN()*z_i*z_i + this.r.getN()*z_r*z_r);
906        },
907       
908        getBremsstrahlungSpectralDensity : function()
909        {
910            var photon_eV = this.getWavenumber()/8065.5;
911            return this.getBremsstrahlungLosses()/(8065.5*this.e.getT())*
912                Math.exp(-photon_eV/this.e.getT());
913        },
914       
915        getFreeBoundLosses : function()
916        {
917            var z_i = this.i.getQ();
918            var z_r = this.r.getQ();
919            return -1.69e-32/8065.5*this.e.getN()/Math.sqrt(this.e.getT())*
920                (this.i.getN()*z_i*z_i*pf.base.Bohr.bindingEnergy(z_i, 1) +
921                 this.r.getN()*z_r*z_r*pf.base.Bohr.bindingEnergy(z_r, 1));
922        },
923       
924        getFreeBoundSpectralDensity : function()
925        {
926            var photon_eV = this.getWavenumber()/8065.5;
927            return this.getFreeBoundLosses()/(8065.5*this.e.getT())*
928                Math.exp(-photon_eV/this.e.getT());
929        },
930       
931        getBoundBoundLosses : function()
932        {
933            var Z_core = this.r.getQ() + 1;
934            var photon_eV =
935                pf.base.Bohr.transitionEnergy(Z_core, 2, 1)/8065.5;
936           
937            // FIXME!!
938            var level_pop = Math.exp(-photon_eV/this.e.getT());
939           
940            return level_pop*Math.pow(Z_core, 4)*LymanA(2)*
941                1.6022e-19*photon_eV*this.r.getN();
942        },
943       
944        getPressure : function()
945        {
946            return this.e.getPressure() +
947                   this.i.getPressure() +
948                   this.r.getPressure();
949        },
950       
951        getMagneticFieldPressure : function()
952        {
953            return 3.98e6*this.B*this.B;
954        },
955       
956        getBeta : function()
957        {
958            return this.getPressure()/this.getMagneticFieldPressure();
959        },
960       
961
962        getEntityFullName : function (entity, species)
963        {
964            var name = entity.name;
965            if (entity.nspecies == 1) {
966                switch (species.id) {
967                case "e":
968                    name += " of electrons";
969                    break;
970                case "i":
971                    name += " of ions";
972                    break;
973                case "r":
974                    name += " of radiators";
975                    break;
976                }
977            }
978           
979            return name;
980        },
981       
982        evaluateEntityValue : function(entity, species)
983        {
984            var formula;
985            if (entity.nspecies == 1) {
986                var species_str = "this." + species.id;
987                formula = entity.formula.replace(/\%s1/g, species_str);
988            } else {
989                formula = entity.formula;
990            }
991            var v = eval(formula);
992           
993            return v;
994        },
995       
996        updateEntityValue : function()
997        {
998            var tree = this.entity_tree;
999            var leaf = tree.getSelectedElement();
1000           
1001            if (!leaf) {
1002                return;
1003            }
1004           
1005            var entity  = leaf.getUserData("entity");
1006            var species = leaf.getUserData("species");
1007           
1008            var name = this.getEntityFullName(entity, species);
1009            this.gui_entity_name.setValue(name);
1010
1011            this.gui_entity_section.setValue(entity.section);
1012           
1013            var v = this.evaluateEntityValue(entity, species);
1014
1015            var scale = this.gui_entity_units.getSelected().getValue();
1016
1017            this.gui_entity_value.setNumValue(v*scale);
1018        },
1019
1020        isFavorite : function(leaf)
1021        {
1022            var entity  = leaf.getUserData("entity");
1023            var species = leaf.getUserData("species");
1024
1025            for (var k = 0; k < this.favorites.length; k++) {
1026                var fav = this.favorites[k];
1027                if (fav.entity  == entity && fav.species == species) {
1028                    return true;
1029                    break;
1030                }
1031            }
1032           
1033            return false;
1034        },
1035
1036        populateTree : function()
1037        {
1038            var i, n = plasma_entities.length;
1039            var sa = new Array;
1040            if (this.showElectrons) {
1041                sa.push(this.e)
1042            }
1043            if (this.showIons) {
1044                sa.push(this.i)
1045            }
1046            if (this.showRadiators) {
1047                sa.push(this.r)
1048            }
1049           
1050            for (var i = 0; i < n; i++) {
1051                var entity = plasma_entities[i];
1052               
1053                if (entity.section == "fundamental" &&
1054                    this.showFundamental != true) {
1055                    continue;
1056                }
1057                if (entity.section == "spectroscopy" &&
1058                    this.showSpectroscopy != true) {
1059                    continue;
1060                }
1061               
1062                var folder;
1063                switch (entity.dimension) {
1064                case "frequency":
1065                    folder = this.gui_folder_freq;
1066                    break;
1067                case "length":
1068                    folder = this.gui_folder_length;
1069                    break;
1070                case "velocity":
1071                    folder = this.gui_folder_vel;
1072                    break;
1073                case "energy":
1074                    folder = this.gui_folder_energy;
1075                    break;
1076                case "pressure":
1077                    folder = this.gui_folder_pressure;
1078                    break;
1079                case "area":
1080                    folder = this.gui_folder_area;
1081                    break;
1082                case "power_density":
1083                    folder = this.gui_folder_power_density;
1084                    break;
1085                case "spectral_power_density":
1086                    folder = this.gui_folder_spectral_power_density;
1087                    break;
1088                case "none":
1089                    folder = this.gui_folder_none;
1090                    break;
1091                default:
1092                    folder = this.gui_folder_misc;
1093                    break;
1094                }
1095               
1096                var leaf;
1097               
1098                switch (entity.nspecies) {
1099                case 1:
1100                    for (var j = 0; j < sa.length; j++) {
1101                        var s = sa[j];
1102                        var icon = "pf/image/" + s.id + "_small.png";
1103
1104                        leaf = new qx.ui.tree.TreeFile(entity.name, icon);
1105                        leaf.addEventListener("changeSelected", clickEntityCB, this);
1106                        leaf.addEventListener("contextmenu", treeMenuCB, this);
1107                        leaf.setUserData("entity", entity);
1108                        leaf.setUserData("species", s);
1109                       
1110                        if (this.isFavorite(leaf)) {
1111                            leaf.setTextColor("red");
1112                        }
1113
1114                        folder.add(leaf);
1115                    }
1116                    break;
1117                default:
1118                    leaf = new qx.ui.tree.TreeFile(entity.name,
1119                        "pf/image/all_small.png");
1120                    leaf.addEventListener("changeSelected", clickEntityCB, this);
1121                    leaf.addEventListener("contextmenu", treeMenuCB, this);
1122                    leaf.setUserData("entity", entity);
1123
1124                    if (this.isFavorite(leaf)) {
1125                        leaf.setTextColor("red");
1126                    }
1127                   
1128                    folder.add(leaf);
1129                    break;
1130                }
1131            }
1132        }, 
1133
1134        cleanTree : function()
1135        {
1136            this.gui_folder_freq.destroyContent();
1137           
1138            this.gui_folder_length.destroyContent();
1139           
1140            this.gui_folder_vel.destroyContent();
1141           
1142            this.gui_folder_none.destroyContent();
1143           
1144            this.gui_folder_energy.destroyContent();
1145           
1146            this.gui_folder_pressure.destroyContent();
1147           
1148            this.gui_folder_power_area.destroyContent();
1149           
1150            this.gui_folder_power_density.destroyContent();
1151
1152            this.gui_folder_spectral_power_density.destroyContent();
1153           
1154            this.gui_folder_misc.destroyContent();
1155        },
1156
1157        rePopulateTree : function()
1158        {
1159            // this.entity_tree.hide();
1160
1161            this.cleanTree();
1162            this.populateTree();
1163
1164            this.gui_folder_freq.close();
1165            this.gui_folder_length.close();
1166            this.gui_folder_vel.close();
1167            this.gui_folder_none.close();
1168            this.gui_folder_energy.close();
1169            this.gui_folder_pressure.close();
1170            this.gui_folder_area.close();
1171            this.gui_folder_power_density.close();
1172            this.gui_folder_spectral_power_density.close();
1173            this.gui_folder_misc.close();
1174
1175            // this.entity_tree.show();
1176        },
1177
1178
1179        updateFavoritesListView : function()
1180        {
1181            var lv = this.favoritesListView;
1182            var rowData = lv.getData();
1183            rowData.length = 0;
1184           
1185            var dimension = this.gui_compare_dim.getSelectedValue();
1186           
1187            var scale = this.gui_compare_units.getSelectedValue();
1188           
1189            for (var i = 0; i < this.favorites.length; i++) {
1190                var fav = this.favorites[i];
1191                var entity = fav.entity;
1192               
1193                if (entity.dimension != dimension) {
1194                    continue;
1195                }
1196               
1197                var species = fav.species;
1198
1199                var icon;
1200                if (species) {
1201                    icon = "pf/image/" + species.id + "_small.png";
1202                } else {
1203                    icon = "pf/image/all_small.png";
1204                }
1205                var name = this.getEntityFullName(entity, species);
1206                var value = scale*this.evaluateEntityValue(entity, species);
1207
1208                rowData.push({ s_icon   : {icon       : icon,
1209                                           iconWidth  : 16, 
1210                                           iconHeight : 16             },
1211                               name     : {text       : name           },
1212                               section  : {text       : entity.section },
1213                               value    : {text       : NumPrint(value)}
1214                             });
1215            }
1216           
1217            lv.updateSort();
1218            lv.update();
1219        },
1220
1221        updateLegendListView : function()
1222        {
1223            var lv = this.legendListView;
1224            var rowData = lv.getData();
1225            rowData.length = 0;
1226           
1227            var dimension = this.gui_compare_dim.getSelectedValue();
1228           
1229            for (var i = 0; i < this.favorites.length; i++) {
1230                var fav = this.favorites[i];
1231                var entity = fav.entity;
1232               
1233                if (entity.dimension != dimension) {
1234                    continue;
1235                }
1236               
1237                var species = fav.species;
1238
1239                var icon;
1240                if (species) {
1241                    icon = "pf/image/" + species.id + "_small.png";
1242                } else {
1243                    icon = "pf/image/all_small.png";
1244                }
1245                var name  = this.getEntityFullName(entity, species);
1246                var color = fav.color;
1247
1248                rowData.push({ s_icon   : {icon       : icon,
1249                                           iconWidth  : 16, 
1250                                           iconHeight : 16    },
1251                               name     : {text       : name  },
1252                               color    : {text       : color,
1253                                           textColor  : color },
1254                               favorite : fav
1255                             });
1256            }
1257            lv.update();
1258        },
1259
1260
1261        renderTabPage : function(label, icon, checked)
1262        {
1263            var tab_id, page_id;
1264           
1265            tab_id = new qx.ui.pageview.tabview.Button(label, icon);
1266            this.tabbar.add(tab_id);
1267            page_id = new qx.ui.pageview.tabview.Page(tab_id);
1268            page_id.setHeight("100%");
1269            page_id.setPadding(10, 10, 10, 10);
1270            page_id.setBackgroundColor("white");
1271            this.tabpane.add(page_id);
1272
1273            if (checked) {
1274                tab_id.setChecked(true);
1275            }
1276           
1277            return page_id;
1278        },
1279
1280        renderParametersTab : function()
1281        {
1282            var page_id = this.renderTabPage("Parameters",
1283                "pf/image/tab-parameters.png", true);
1284
1285            var fr, gl;
1286           
1287            fr = new qx.ui.groupbox.GroupBox("Electrons",
1288                "pf/image/e_small.png");
1289            fr.setDimension("auto", "auto");
1290            fr.setBackgroundColor("#eeeeff");
1291
1292            page_id.add(fr);
1293
1294            gl = new qx.ui.layout.GridLayout;
1295            gl.setVerticalSpacing(4);
1296            gl.setHorizontalSpacing(6);
1297            gl.setColumnCount(2);
1298            gl.setColumnWidth(0, 100);
1299            gl.setColumnWidth(1, 260);
1300            gl.setRowCount(2);
1301            gl.setRowHeight(0, 30);
1302            gl.setRowHeight(1, 30);
1303
1304            fr.add(gl);
1305
1306            var l, e;
1307
1308            // N_e
1309            l = new qx.ui.basic.Label("N<sub>e</sub> (cm<sup>-3</sup>):");
1310            gl.add(l, 0, 0);
1311            e = new pf.ui.TextField(this.e.getN());
1312            gl.add(e, 1, 0);
1313            // e.setLiveUpdate(true);
1314            e.addEventListener("changeValue", changeN_e, this);
1315
1316            // T_e
1317            l = new qx.ui.basic.Label("T<sub>e</sub> (eV):");
1318            gl.add(l, 0, 1);
1319            e = new pf.ui.TextField(this.e.getT());
1320            gl.add(e, 1, 1);
1321            e.addEventListener("changeValue", changeT_e, this);
1322            e.setLiveUpdate(true);
1323
1324
1325            fr = new qx.ui.groupbox.GroupBox("Ions",
1326                "pf/image/i_small.png");
1327            fr.setDimension("auto", "auto");
1328            fr.setBackgroundColor("#ffeeee");
1329
1330            page_id.add(fr);
1331            fr.setTop(100);
1332
1333            gl = new qx.ui.layout.GridLayout;
1334            gl.setVerticalSpacing(4);
1335            gl.setHorizontalSpacing(6);
1336            gl.setColumnCount(2);
1337            gl.setColumnWidth(0, 100);
1338            gl.setColumnWidth(1, 260);
1339            gl.setRowCount(4);
1340            gl.setRowHeight(0, 30);
1341            gl.setRowHeight(1, 30);
1342            gl.setRowHeight(2, 30);
1343            gl.setRowHeight(3, 30);
1344
1345            fr.add(gl);
1346
1347            // Z_i
1348            l = new qx.ui.basic.Label("Z<sub>i</sub>:");
1349            gl.add(l, 0, 0);
1350            e = new pf.ui.Spinner(1, this.i.getQ(), 100);
1351            gl.add(e, 1, 0);
1352           
1353            e.addEventListener("change", changeZ_i, this);
1354           
1355            // M_i
1356            l = new qx.ui.basic.Label("M<sub>i</sub>:");
1357            gl.add(l, 0, 1);
1358            e = new pf.ui.Spinner(1, this.i.getM(), 200);
1359            gl.add(e, 1, 1);
1360            e.addEventListener("change", changeM_i, this);
1361           
1362            // T_i
1363            l = new qx.ui.basic.Label("T<sub>i</sub> (eV):");
1364            gl.add(l, 0, 2);
1365            e = new pf.ui.TextField(this.i.getT());
1366            gl.add(e, 1, 2);
1367            e.addEventListener("changeValue", changeT_i, this);
1368            e.setLiveUpdate(true);
1369            this.gui_T_i = e;
1370
1371            // N_i
1372            l = new qx.ui.basic.Label("N<sub>i</sub> (cm<sup>-3</sup>):");
1373            gl.add(l, 0, 3);
1374            e = new pf.ui.TextField(this.i.getN());
1375            gl.add(e, 1, 3);
1376            e.setReadOnly(true);
1377            this.gui_N_i = e;
1378           
1379           
1380            fr = new qx.ui.groupbox.GroupBox("Radiators",
1381                "pf/image/r_small.png");
1382            fr.setDimension("auto", "auto");
1383            fr.setBackgroundColor("#eeffee");
1384
1385            page_id.add(fr);
1386            fr.setLeft(390);
1387
1388            gl = new qx.ui.layout.GridLayout;
1389            gl.setVerticalSpacing(4);
1390            gl.setHorizontalSpacing(6);
1391            gl.setColumnCount(2);
1392            gl.setColumnWidth(0, 100);
1393            gl.setColumnWidth(1, 260);
1394            gl.setRowCount(5);
1395            gl.setRowHeight(0, 30);
1396            gl.setRowHeight(1, 30);
1397            gl.setRowHeight(2, 30);
1398            gl.setRowHeight(3, 30);
1399            gl.setRowHeight(4, 30);
1400
1401            fr.add(gl);
1402
1403
1404            // Z_r
1405            l = new qx.ui.basic.Label("Z<sub>r</sub>:");
1406            gl.add(l, 0, 0);
1407            e = new pf.ui.Spinner(0, this.Z_r, 100);
1408            gl.add(e, 1, 0);
1409            e.addEventListener("change", changeZ_r, this);
1410
1411            // M_r
1412            l = new qx.ui.basic.Label("M<sub>r</sub>:");
1413            gl.add(l, 0, 1);
1414            e = new pf.ui.Spinner(1, this.r.getM(), 200);
1415            gl.add(e, 1, 1);
1416            e.addEventListener("change", changeM_r, this);
1417
1418            // T_r
1419            l = new qx.ui.basic.Label("T<sub>r</sub> (eV):");
1420            gl.add(l, 0, 2);
1421            e = new pf.ui.TextField(this.r.getT());
1422            gl.add(e, 1, 2);
1423            e.addEventListener("changeValue", changeT_r, this);
1424            this.gui_T_r = e;
1425
1426            // P_r
1427            l = new qx.ui.basic.Label("P<sub>r</sub> (%):");
1428            gl.add(l, 0, 3);
1429            e = new pf.ui.Spinner(0, this.P_r, 100);
1430            gl.add(e, 1, 3);
1431            e.addEventListener("change", changeP_r, this);
1432
1433            // N_r
1434            l = new qx.ui.basic.Label("N<sub>r</sub> (cm<sup>-3</sup>):");
1435            gl.add(l, 0, 4);
1436            e = new pf.ui.TextField(this.r.getN());
1437            e.setReadOnly(true);
1438            gl.add(e, 1, 4);
1439            this.gui_N_r = e;
1440
1441
1442            fr = new qx.ui.groupbox.GroupBox("Fields",
1443                "pf/image/field_small.png");
1444            fr.setDimension("auto", "auto");
1445            fr.setBackgroundColor("#ffffdd");
1446
1447            page_id.add(fr);
1448
1449            gl = new qx.ui.layout.GridLayout;
1450            gl.setVerticalSpacing(4);
1451            gl.setHorizontalSpacing(6);
1452            gl.setColumnCount(2);
1453            gl.setColumnWidth(0, 100);
1454            gl.setColumnWidth(1, 260);
1455            gl.setRowCount(1);
1456            gl.setRowHeight(0, 30);
1457
1458            fr.add(gl);
1459            fr.setTop(268);
1460
1461
1462            l = new qx.ui.basic.Label("B (T):");
1463            gl.add(l, 0, 0);
1464            e = new pf.ui.TextField(this.B);
1465            gl.add(e, 1, 0);
1466            // e.setLiveUpdate(true);
1467            e.addEventListener("changeValue", changeB, this);
1468
1469            // Atomic system frame
1470            fr = new qx.ui.groupbox.GroupBox("Atomic system",
1471                "pf/image/all_small.png");
1472            fr.setDimension("auto", "auto");
1473            fr.setBackgroundColor("#ffffdd");
1474
1475            page_id.add(fr);
1476
1477            gl = new qx.ui.layout.GridLayout;
1478            gl.setVerticalSpacing(4);
1479            gl.setHorizontalSpacing(6);
1480            gl.setColumnCount(2);
1481            gl.setColumnWidth(0, 100);
1482            gl.setColumnWidth(1, 260);
1483            gl.setRowCount(3);
1484            gl.setRowHeight(0, 30);
1485            gl.setRowHeight(1, 30);
1486            gl.setRowHeight(2, 30);
1487
1488            fr.add(gl);
1489            fr.setLeft(390);
1490            fr.setTop(202);
1491
1492            l = new qx.ui.basic.Label("Z<sub>core</sub>:");
1493            gl.add(l, 0, 0);
1494            e = new qx.ui.form.TextField(this.r.getQ() + 1);
1495            e.setReadOnly(true);
1496            gl.add(e, 1, 0);
1497            this.gui_Zcore = e;
1498
1499            l = new qx.ui.basic.Label("n<sub>u</sub>:");
1500            gl.add(l, 0, 1);
1501            e = new pf.ui.Spinner(2, this.n_u, 1000);
1502            gl.add(e, 1, 1);
1503            e.addEventListener("change", changeN_u, this);
1504
1505            l = new qx.ui.basic.Label("n<sub>l</sub>:");
1506            gl.add(l, 0, 2);
1507            e = new pf.ui.Spinner(1, this.n_l, 1000);
1508            gl.add(e, 1, 2);
1509            e.addEventListener("change", changeN_l, this);
1510        },
1511
1512        renderExplorerTab : function()
1513        {
1514            var page_id = this.renderTabPage("Explorer",
1515                "pf/image/tab-explorer.png");
1516           
1517            var sp = new qx.ui.splitpane.HorizontalSplitPane(300, "1*");
1518            sp.set(
1519            {
1520                left            : 1,
1521                right           : 1,
1522                top             : 1,
1523                bottom          : 1,
1524                border          : "inset-thin",
1525                showKnob        : true
1526            });
1527            page_id.add(sp);
1528                       
1529            var left_pane  = sp.getLeftArea();
1530            left_pane.setBackgroundColor("white");
1531            left_pane.setBorder("inset-thin");
1532            var right_pane = sp.getRightArea();
1533            right_pane.setBackgroundColor("white");
1534            right_pane.setBorder("inset-thin");
1535            var tree = new qx.ui.tree.Tree("Browser");
1536            tree.set(
1537            {
1538                overflow        : "scroll",
1539                height          : "100%",
1540                width           : "100%",
1541                paddingLeft     : 4,
1542                paddingTop      : 4
1543            });
1544            left_pane.add(tree);
1545           
1546            this.entity_tree = tree;
1547           
1548            var folder;
1549           
1550            folder = new qx.ui.tree.TreeFolder("Frequency");
1551            folder.setAlwaysShowPlusMinusSymbol(true);
1552            tree.add(folder);
1553            this.gui_folder_freq = folder;
1554
1555            folder = new qx.ui.tree.TreeFolder("Length");
1556            folder.setAlwaysShowPlusMinusSymbol(true);
1557            tree.add(folder);
1558            this.gui_folder_length = folder;
1559           
1560            folder = new qx.ui.tree.TreeFolder("Velocity");
1561            folder.setAlwaysShowPlusMinusSymbol(true);
1562            tree.add(folder);
1563            this.gui_folder_vel = folder;
1564           
1565            folder = new qx.ui.tree.TreeFolder("Dimensionless");
1566            tree.add(folder);
1567            this.gui_folder_none = folder;
1568
1569            folder = new qx.ui.tree.TreeFolder("Energy");
1570            folder.setAlwaysShowPlusMinusSymbol(true);
1571            tree.add(folder);
1572            this.gui_folder_energy = folder;
1573
1574            folder = new qx.ui.tree.TreeFolder("Pressure");
1575            folder.setAlwaysShowPlusMinusSymbol(true);
1576            tree.add(folder);
1577            this.gui_folder_pressure = folder;
1578
1579            folder = new qx.ui.tree.TreeFolder("Area");
1580            folder.setAlwaysShowPlusMinusSymbol(true);
1581            tree.add(folder);
1582            this.gui_folder_area = folder;
1583
1584            folder = new qx.ui.tree.TreeFolder("Power density");
1585            folder.setAlwaysShowPlusMinusSymbol(true);
1586            tree.add(folder);
1587            this.gui_folder_power_density = folder;
1588
1589            folder = new qx.ui.tree.TreeFolder("Power spectral density");
1590            folder.setAlwaysShowPlusMinusSymbol(true);
1591            tree.add(folder);
1592            this.gui_folder_spectral_power_density = folder;
1593
1594            folder = new qx.ui.tree.TreeFolder("Miscellaneous");
1595            folder.setAlwaysShowPlusMinusSymbol(true);
1596            tree.add(folder);
1597            this.gui_folder_misc = folder;
1598
1599            this.populateTree();
1600
1601            tree.setHideNode(true);
1602            tree.setRootOpenClose(true);
1603           
1604            // Build context-sensitive popup menu
1605            this.treeMenu = new qx.ui.menu.Menu;
1606            var button;
1607           
1608            button = new qx.ui.menu.Button("Add to Favorites",
1609                "pf/image/favorite-add.png");
1610            button.addEventListener("execute", addToFavCB, this);
1611            this.treeMenu.add(button);
1612            this.treeMenuButtonAddToFav = button;
1613            button = new qx.ui.menu.Button("Remove from Favorites",
1614                "pf/image/favorite-delete.png");
1615            button.addEventListener("execute", removeFromFavCB, this);
1616            this.treeMenu.add(button);
1617            this.treeMenuButtonRemFromFav = button;
1618           
1619            this.doc.add(this.treeMenu);
1620
1621            var gl = new qx.ui.layout.GridLayout;
1622            gl.set(
1623            {
1624                left              : 4,
1625                right             : 4,
1626                top               : 4,
1627                verticalSpacing   : 4,
1628                horizontalSpacing : 6
1629            });
1630           
1631            gl.setColumnCount(3);
1632            gl.setColumnWidth(0, "15%");
1633            gl.setColumnWidth(1, "60%");
1634            gl.setColumnWidth(2, "20%");
1635            gl.setRowCount(3);
1636            gl.setRowHeight(0, 30);
1637            gl.setRowHeight(1, 30);
1638            gl.setRowHeight(2, 30);
1639
1640            var l, e;
1641
1642            l = new qx.ui.basic.Label("Name:");
1643            gl.add(l, 0, 0);
1644            e = new qx.ui.form.TextField();
1645            e.setReadOnly(true);
1646            this.gui_entity_name = e;
1647            gl.add(e, 1, 0);
1648
1649            l = new qx.ui.basic.Label("Value:");
1650            gl.add(l, 0, 1);
1651            e = new pf.ui.TextField("");
1652            e.setReadOnly(true);
1653            gl.add(e, 1, 1);
1654            this.gui_entity_value = e;
1655
1656            e = new pf.UnitSelector();
1657            e.addEventListener("changeSelected", changeUnitsCB, this);
1658            gl.add(e, 2, 1);
1659            this.gui_entity_units = e;
1660
1661            l = new qx.ui.basic.Label("Section:");
1662            gl.add(l, 0, 2);
1663            e = new qx.ui.form.TextField();
1664            e.setReadOnly(true);
1665            this.gui_entity_section = e;
1666            gl.add(e, 1, 2);
1667
1668            right_pane.add(gl);
1669        },
1670       
1671        renderCompareTab : function()
1672        {
1673            var page_id = this.renderTabPage("Compare",
1674                "pf/image/tab-compare.png");
1675           
1676            var bl = new qx.ui.layout.VerticalBoxLayout("vertical");
1677            bl.setWidth("100%");
1678            bl.setHeight("100%");
1679            bl.setSpacing(10);
1680            page_id.add(bl);
1681           
1682            var rc = new qx.ui.layout.HorizontalBoxLayout;
1683            rc.setWidth("100%");
1684            rc.setHeight("auto");
1685            rc.setSpacing(10);
1686            bl.add(rc);
1687
1688            var l, e;
1689            l = new qx.ui.basic.Label("Dimension:");
1690            e = new pf.ui.ComboBox;
1691            e.add(new qx.ui.form.ListItem("Frequency", null, "frequency"));
1692            e.add(new qx.ui.form.ListItem("Length", null, "length"));
1693            e.add(new qx.ui.form.ListItem("Velocity", null, "velocity"));
1694            e.add(new qx.ui.form.ListItem("Energy", null, "energy"));
1695            e.add(new qx.ui.form.ListItem("Pressure", null, "pressure"));
1696            e.add(new qx.ui.form.ListItem("Area", null, "area"));
1697            e.add(new qx.ui.form.ListItem("Power density", null, "power_density"));
1698            e.add(new qx.ui.form.ListItem("Power spectral density",
1699                null, "spectral_power_density"));
1700            e.add(new qx.ui.form.ListItem("Electric field", null, "efield"));
1701            e.add(new qx.ui.form.ListItem("None", null, "none"));
1702            e.addEventListener("changeSelected", function(ev) {
1703                    var dimension = this.gui_compare_dim.getSelectedValue();
1704                    this.gui_compare_units.update(dimension,
1705                        this.prefs.units[dimension]);
1706                    this.updateFavoritesListView();
1707                    this.updateLegendListView();
1708                }, this);
1709            rc.add(l, e);
1710            this.gui_compare_dim = e;
1711
1712            l = new qx.ui.basic.Label("Units:");
1713            e = new pf.UnitSelector();
1714            e.addEventListener("changeSelected", function(ev) {
1715                    this.updateFavoritesListView();
1716                }, this);
1717            rc.add(l, e);
1718            this.gui_compare_units = e;
1719
1720            var lc =
1721            {
1722                s_icon   : { label      : "",
1723                             width      : 24,
1724                             type       : "iconHtml",
1725                             align      : "center",                   
1726                             sortable   : false                         },
1727                name     : { label      : "Name",
1728                             width      : 300,
1729                             type       : "text",
1730                             align      : "left",
1731                             sortable   : true,
1732                             sortProp   : "text"                        },
1733                section  : { label      : "Section",
1734                             width      : 120,
1735                             type       : "text",
1736                             align      : "left",
1737                             sortable   : true,
1738                             sortProp   : "text"                        },
1739                value    : { label      : "Value",
1740                             width      : 120,
1741                             type       : "text",
1742                             align      : "right",
1743                             sortable   : true,
1744                             sortProp   : "text",
1745                             sortMethod : qx.util.Compare.byFloatString }
1746            };
1747
1748            var lv = new qx.ui.listview.ListView(new Array, lc);
1749
1750            lv.setWidth("100%");
1751            lv.setHeight("2*");
1752            lv.setBackgroundColor("white");
1753            lv.setBorder("dark-shadow");
1754
1755            bl.add(lv);
1756           
1757            this.favoritesListView = lv;
1758        },
1759       
1760        drawCB : function(ev)
1761        {
1762            var canvas = this.canvas;
1763           
1764            var pname = this.guiParameter.getValue();
1765            var vmin = this.guiMinParam.getNumValue();
1766            var vmax = this.guiMaxParam.getNumValue();
1767            var npoints = this.guiParamPoints.getValue();
1768           
1769            if (npoints < 2 || !pname) {
1770                return;
1771            }
1772
1773            var dimension = this.gui_compare_dim.getSelectedValue();
1774            var scale = this.gui_compare_units.getSelectedValue();
1775
1776            var par0;
1777            var label;
1778            switch (pname) {
1779            case "N_e":
1780                par0 = this.e.getN();
1781                label = "N<sub>e</sub> (cm<sup>-3</sup>)"
1782                break;
1783            case "T":
1784                par0 = this.e.getT();
1785                label = "T (eV)"
1786                break;
1787            case "T_e":
1788                par0 = this.e.getT();
1789                label = "T<sub>e</sub> (eV)"
1790                break;
1791            case "T_i":
1792                par0 = this.i.getT();
1793                label = "T<sub>i</sub> (eV)"
1794                break;
1795            case "T_r":
1796                par0 = this.r.getT();
1797                label = "T<sub>r</sub> (eV)"
1798                break;
1799            case "B":
1800                par0 = this.B;
1801                label = "B (T)"
1802                break;
1803            default:
1804                return;
1805            }
1806           
1807            var xdata = new Array;
1808            for (var j = 0; j < npoints; j++) {
1809                var x = par0*(vmin + (vmax - vmin)*j/(npoints - 1));
1810                xdata.push(x);
1811            }
1812                       
1813            var wxmin = xdata[0];
1814            var wxmax = xdata[xdata.length - 1];
1815
1816            var wymin = 0;
1817            var wymax = 0;
1818
1819            var sets = new Array;
1820            var first = true;
1821            for (var i = 0; i < this.favorites.length; i++) {
1822                var fav = this.favorites[i];
1823                var entity = fav.entity;
1824               
1825                if (entity.dimension != dimension) {
1826                    continue;
1827                }
1828               
1829                var species = fav.species;
1830                var vname = this.getEntityFullName(entity, species);
1831
1832                var set   = new Array;
1833                var ydata = new Array;
1834                for (var j = 0; j < npoints; j++) {
1835                    var par = xdata[j];
1836
1837                    switch (pname) {
1838                    case "N_e":
1839                        this.e.setN(par);
1840                        this.updatePlasmaParameters();
1841                        break;
1842                    case "T_e":
1843                        this.e.setT(par);
1844                        break;
1845                    case "T_i":
1846                        this.i.setT(par);
1847                        break;
1848                    case "T_r":
1849                        this.r.setT(par);
1850                        break;
1851                    case "T":
1852                        this.e.setT(par);
1853                        this.i.setT(par);
1854                        this.r.setT(par);
1855                        break;
1856                    case "B":
1857                        this.B = par;
1858                        break;
1859                    }
1860                   
1861                    var value = scale*this.evaluateEntityValue(entity, species);
1862                   
1863                    if (first) {
1864                        wymin = value;
1865                        wymax = value;
1866                        first = false;
1867                    } else {
1868                        if (value < wymin) {
1869                            wymin = value;
1870                        }
1871                        if (value > wymax) {
1872                            wymax = value;
1873                        }
1874                    }
1875                   
1876                    ydata.push(value);
1877                }
1878                set.x = xdata;
1879                set.y = ydata;
1880                set.legend = vname;
1881                set.color = fav.color;
1882                sets.push(set);
1883            }
1884           
1885            // Restore parameter
1886            switch (pname) {
1887            case "N_e":
1888                this.e.setN(par0);
1889                this.updatePlasmaParameters();
1890                break;
1891            case "T_e":
1892                this.e.setT(par0);
1893                break;
1894            case "T_i":
1895                this.i.setT(par0);
1896                break;
1897            case "T_r":
1898                this.r.setT(par0);
1899                break;
1900            case "T":
1901                this.e.setT(par0);
1902                this.i.setT(par0);
1903                this.r.setT(par0);
1904                break;
1905            case "B":
1906                this.B = par0;
1907                break;
1908            }
1909           
1910            canvas.clear();
1911           
1912            canvas.setViewportCoordinates(0.15, 0.1, 0.9, 0.9);
1913            dwx = Math.abs(wxmax - wxmin);
1914            if (dwx == 0) {
1915                dwx = wxmax;
1916            }
1917            dwy = Math.abs(wymax - wymin);
1918            if (dwy == 0) {
1919                wymin = 0.0;
1920                if (wymax == 0) {
1921                    wymax = 1.0;
1922                } else {
1923                    wymax *= 2;
1924                }
1925            }
1926            canvas.setWorldCoordinates(Math.max(0, wxmin - 0.05*dwx),
1927                Math.max(0, wymin - 0.05*dwy),
1928                wxmax + 0.05*dwx, wymax + 0.05*dwy);
1929           
1930            // Draw frame
1931            canvas.drawFrame("black");
1932
1933            // Mark initial value of the varied parameter
1934            canvas.setColor("#c0c0c0");
1935            canvas.drawPolyLineW(new Array(par0, par0),
1936                new Array(wymin, wymax));
1937           
1938            // Draw axis ticks
1939            canvas.drawTicks("x", "blue");
1940            canvas.drawTicks("y", "blue");
1941
1942            // Draw axis labels
1943            canvas.drawLabel("x", label, "black");
1944           
1945            // Draw sets
1946            for (var i = 0; i < sets.length; i++) {
1947                var set = sets[i];
1948                canvas.setColor(set.color);
1949                canvas.drawPolyLineW(set.x, set.y);
1950               
1951                delete set;
1952            }
1953           
1954            delete sets;
1955           
1956            canvas.paint();
1957        },
1958       
1959        renderPlotTab : function()
1960        {
1961            var page_id = this.renderTabPage("Plot",
1962                "pf/image/tab-plot.png");
1963
1964            var sp = new qx.ui.splitpane.HorizontalSplitPane("1*", 300);
1965            sp.set(
1966            {
1967                height          : "100%",
1968                width           : "100%",
1969                left            : 1,
1970                right           : 1,
1971                top             : 1,
1972                bottom          : 1,
1973                border          : "inset-thin",
1974                showKnob        : true
1975            });
1976            page_id.add(sp);
1977                       
1978            var left_pane  = sp.getLeftArea();
1979            left_pane.setBackgroundColor("white");
1980            left_pane.setBorder("inset-thin");
1981            var right_pane = sp.getRightArea();
1982            right_pane.setBackgroundColor("white");
1983            right_pane.setBorder("inset-thin");
1984
1985            var canvas = new pf.ui.canvas.Plotter();
1986            canvas.set(
1987            {
1988                height          : "100%",
1989                width           : "100%"
1990            });
1991            left_pane.add(canvas);
1992            this.canvas = canvas;
1993
1994
1995            var vbl = new qx.ui.layout.VerticalBoxLayout("vertical");
1996            vbl.set(
1997            {
1998                height          : "100%",
1999                width           : "100%",
2000                padding         : 4,
2001                spacing         : 10
2002            });
2003            right_pane.add(vbl);
2004
2005            var gl = new qx.ui.layout.GridLayout;
2006            gl.set(
2007            {
2008                height            : "auto",
2009                width             : "100%",
2010                left              : 4,
2011                right             : 4,
2012                top               : 4,
2013                verticalSpacing   : 4,
2014                verticalSpacing   : 4,
2015                horizontalSpacing : 6
2016            });
2017           
2018            gl.setColumnCount(2);
2019            gl.setColumnWidth(0, 150);
2020            gl.setColumnWidth(1, 100);
2021            gl.setRowCount(5);
2022            gl.setRowHeight(0, 30);
2023            gl.setRowHeight(1, 30);
2024            gl.setRowHeight(2, 30);
2025            gl.setRowHeight(3, 30);
2026            gl.setRowHeight(4, 30);
2027            vbl.add(gl);
2028
2029            var l, e;
2030
2031            var btn = new qx.ui.form.Button("Redraw", "pf/image/tab-plot.png");
2032            btn.addEventListener("execute", this.drawCB, this);
2033            gl.add(btn, 0, 0);
2034
2035            l = new qx.ui.basic.Label("Parameter to vary:");
2036            e = new pf.ui.ComboBox;
2037            e.add(new qx.ui.form.ListItem("N_e", null, "N_e"));
2038            e.add(new qx.ui.form.ListItem("T",   null, "T"));
2039            e.add(new qx.ui.form.ListItem("T_e", null, "T_e"));
2040            e.add(new qx.ui.form.ListItem("T_i", null, "T_i"));
2041            e.add(new qx.ui.form.ListItem("T_r", null, "T_r"));
2042            e.add(new qx.ui.form.ListItem("B",   null, "B"));
2043            e.selectByValue("N_e");
2044            this.guiParameter = e;
2045            gl.add(l, 0, 1);
2046            gl.add(e, 1, 1);
2047
2048            l = new qx.ui.basic.Label("Minimum scale:");
2049            e = new pf.ui.TextField(0.3);
2050            this.guiMinParam = e;
2051            gl.add(l, 0, 2);
2052            gl.add(e, 1, 2);
2053
2054            l = new qx.ui.basic.Label("Maximum scale:");
2055            e = new pf.ui.TextField(3.0);
2056            this.guiMaxParam = e;
2057            gl.add(l, 0, 3);
2058            gl.add(e, 1, 3);
2059
2060            l = new qx.ui.basic.Label("Number of points:");
2061            e = new pf.ui.Spinner(2, 10, 100);
2062            this.guiParamPoints = e;
2063            gl.add(l, 0, 4);
2064            gl.add(e, 1, 4);
2065
2066
2067            var lc =
2068            {
2069                s_icon   : { label      : "",
2070                             width      : 24,
2071                             type       : "iconHtml",
2072                             align      : "center",                   
2073                             sortable   : false                         },
2074                name     : { label      : "Name",
2075                             width      : 185,
2076                             type       : "text",
2077                             align      : "left",
2078                             sortable   : true,
2079                             sortProp   : "text"                        },
2080                color    : { label      : "Color",
2081                             width      : 55,
2082                             type       : "text",
2083                             align      : "left",
2084                             sortable   : false                         }
2085            };
2086
2087            var lv = new qx.ui.listview.ListView(new Array, lc);
2088
2089            lv.setWidth("100%");
2090            lv.setHeight("2*");
2091            // lv.setBackgroundColor("white");
2092            lv.setBorder("dark-shadow");
2093           
2094            lv.addEventListener("dblclick", function(ev) {
2095                    ev.setPropagationStopped(true);
2096                    var pane = this.getPane();
2097                    var item = pane.getSelectedItem();
2098                    if (!item) {
2099                        return;
2100                    }
2101                    var favorite = item.favorite;
2102                    if (!favorite) {
2103                        return;
2104                    }
2105                    mypop.setUserData("favorite", null); // avoid loop call
2106                    mypop.setValue(favorite.color);
2107                    mypop.setUserData("favorite", favorite);
2108                    var el = this.getElement();
2109                    mypop.setTop(qx.html.Location.getPageBoxTop(el));
2110                    mypop.setLeft(qx.html.Location.getPageBoxLeft(el) -
2111                        this.getWidthValue());
2112                    mypop.show();
2113                });
2114
2115            vbl.add(lv);
2116            this.legendListView = lv;
2117           
2118            var mytables =
2119            {
2120              core : {
2121                label : "Basic Colors",
2122                values : this.colorMap
2123              },
2124
2125              recent : {
2126                label : "Recent Colors",
2127                values : [ ]
2128              }
2129            }
2130
2131            var mypop = new qx.ui.component.ColorPopup(mytables);
2132            // A hack
2133            mypop._layout.remove(mypop._automaticBtn);
2134
2135            mypop.addToDocument();
2136
2137            mypop.addEventListener("changeValue", function(ev) {
2138                var color = ev.getValue();
2139                var mypop = ev.getTarget();
2140                var favorite = mypop.getUserData("favorite");
2141                if (!favorite || !color) {
2142                    return;
2143                }
2144                favorite.color = color;
2145                this.updateLegendListView();
2146            }, this);
2147   
2148        },
2149
2150
2151        aboutCB : function(ev)
2152        {
2153            this.aboutWindow.open();
2154        },
2155       
2156        prefsCB : function(ev)
2157        {
2158            this.prefsWindow.open();
2159        },
2160       
2161        buildMenu : function()
2162        {
2163            var menubar = this.menubar;
2164           
2165            var submenu, btn, q;
2166
2167            var theme = qx.theme.manager.Color.getInstance().getColorTheme();
2168            var bg = '#' +
2169                qx.util.ColorUtil.rgbToHexString(theme.colors['button']);
2170           
2171            submenu = new qx.ui.menu.Menu;
2172            submenu.setBackgroundColor(bg);
2173            this.doc.add(submenu);
2174            btn = new qx.ui.menu.Button("Open...", "pf/image/open.png");
2175            btn.addEventListener("execute", function (ev) {
2176                alert("Not implemented yet")}, this);
2177            submenu.add(btn);
2178            btn = new qx.ui.menu.Button("Save...", "pf/image/save.png");
2179            btn.addEventListener("execute", function (ev) {
2180                alert("Not implemented yet")}, this);
2181            submenu.add(btn);
2182            submenu.add(new qx.ui.menu.Separator);
2183            q = new qx.client.Command("Ctrl+P");
2184            q.addEventListener("execute", function(ev) {
2185                window.print();
2186            });
2187            btn = new qx.ui.menu.Button("Print...", "pf/image/print.png", q);
2188            submenu.add(btn);
2189            submenu.add(new qx.ui.menu.Separator);
2190            q = new qx.client.Command("Ctrl+R");
2191            q.addEventListener("execute", function(ev) {
2192                location.reload(true);
2193            });
2194            btn = new qx.ui.menu.Button("Reset", "pf/image/reset.png", q);
2195            submenu.add(btn);
2196            submenu.add(new qx.ui.menu.Separator);
2197            q = new qx.client.Command("Ctrl+Q");
2198            q.addEventListener("execute", function(ev) {
2199                window.close();
2200            });
2201            btn = new qx.ui.menu.Button("Quit", "pf/image/exit.png", q);
2202            submenu.add(btn);
2203               
2204            btn = new qx.ui.menubar.Button("File", submenu);
2205            btn.set({ paddingLeft : 7, paddingRight : 7 });
2206            menubar.add(btn);
2207
2208
2209            submenu = new qx.ui.menu.Menu;
2210            submenu.setBackgroundColor(bg);
2211            submenu.addEventListener("beforeAppear", editMenuCB, this);
2212            this.doc.add(submenu);
2213            btn = new qx.ui.menu.Button("Add to Favorites",
2214                "pf/image/favorite-add.png");
2215            btn.addEventListener("execute", addToFavCB, this);
2216            this.editMenuButtonAddToFav = btn;
2217            submenu.add(btn);
2218            btn = new qx.ui.menu.Button("Remove from Favorites",
2219                "pf/image/favorite-delete.png");
2220            btn.addEventListener("execute", removeFromFavCB, this);
2221            this.editMenuButtonRemFromFav = btn;
2222            submenu.add(btn);
2223            submenu.add(new qx.ui.menu.Separator);
2224            btn = new qx.ui.menu.Button("Preferences",
2225                "pf/image/preferences.png");
2226            btn.addEventListener("execute", this.prefsCB, this);
2227            submenu.add(btn);
2228
2229            btn = new qx.ui.menubar.Button("Edit", submenu);
2230            btn.set({ paddingLeft : 7, paddingRight : 7 });
2231            menubar.add(btn);
2232
2233
2234            submenu = new qx.ui.menu.Menu;
2235            submenu.setBackgroundColor(bg);
2236            submenu.addEventListener("beforeAppear", viewMenuCB, this);
2237
2238            var subMenu1 = new qx.ui.menu.Menu;
2239            subMenu1.setBackgroundColor(bg);
2240            button = new qx.ui.menu.CheckBox("Fundamental",
2241                null, this.showFundamental);
2242            button.addEventListener("execute", showFundamentalCB, this);
2243            subMenu1.add(button);
2244            button = new qx.ui.menu.CheckBox("Spectroscopy",
2245                null, this.showSpectroscopy);
2246            button.addEventListener("execute", showSpectroscopyCB, this);
2247            subMenu1.add(button);
2248            this.showSectionsButton = new qx.ui.menu.Button("Show Sections",
2249                null, null, subMenu1);
2250            submenu.add(this.showSectionsButton);
2251           
2252            submenu.add(new qx.ui.menu.Separator);
2253
2254            var subMenu2 = new qx.ui.menu.Menu;
2255            subMenu2.setBackgroundColor(bg);
2256            button = new qx.ui.menu.CheckBox("Electrons",
2257                null, this.showElectrons)
2258            button.addEventListener("execute", showElectronsCB, this);
2259            subMenu2.add(button);
2260            button = new qx.ui.menu.CheckBox("Ions",
2261                null, this.showIons)
2262            button.addEventListener("execute", showIonsCB, this);
2263            subMenu2.add(button);
2264            button = new qx.ui.menu.CheckBox("Radiators",
2265                null, this.showRadiators)
2266            button.addEventListener("execute", showRadiatorsCB, this);
2267            subMenu2.add(button);
2268            this.showSpeciesButton = new qx.ui.menu.Button("Show Species",
2269                null, null, subMenu2);
2270            submenu.add(this.showSpeciesButton);
2271           
2272            submenu.add(new qx.ui.menu.Separator);
2273            q = new qx.client.Command("Ctrl+L");
2274            q.addEventListener("execute", this.drawCB, this);
2275            btn = new qx.ui.menu.Button("Redraw Plot",
2276                "pf/image/tab-plot.png", q);
2277            submenu.add(btn);
2278            this.redrawButton = btn;
2279           
2280            this.doc.add(submenu, subMenu1, subMenu2);
2281
2282            btn = new qx.ui.menubar.Button("View", submenu);
2283            btn.set({ paddingLeft : 7, paddingRight : 7 });
2284            menubar.add(btn);
2285
2286
2287            submenu = new qx.ui.menu.Menu;
2288            submenu.setBackgroundColor(bg);
2289            this.doc.add(submenu);
2290            q = new qx.client.Command("F1");
2291            q.addEventListener("execute", function(ev) {
2292                alert("Help system not implemented yet");
2293            });
2294            btn = new qx.ui.menu.Button("Help Contents",
2295                "pf/image/help.png", q);
2296            submenu.add(btn);
2297            btn = new qx.ui.menu.Button("NRL Plasma Formulary",
2298                "pf/image/nrl.png");
2299            btn.addEventListener("execute", function (ev) {
2300                    var w = new qx.client.NativeWindow("http://wwwppd.nrl.navy.mil/nrlformulary/");
2301                    w.setDimension(800, 600);
2302                    w.open();
2303                }, this);
2304            submenu.add(btn);
2305            btn = new qx.ui.menu.Button("Plasma at Wikipedia",
2306                "pf/image/wikipedia.png");
2307            btn.addEventListener("execute", function (ev) {
2308                    var w = new qx.client.NativeWindow("http://en.wikipedia.org/wiki/Plasma_%28physics%29");
2309                    w.setDimension(800, 600);
2310                    w.open();
2311                }, this);
2312            submenu.add(btn);
2313            submenu.add(new qx.ui.menu.Separator);
2314            btn = new qx.ui.menu.Button("About Plasma Formulary",
2315                "pf/image/about.png");
2316            btn.addEventListener("execute", this.aboutCB, this);
2317            submenu.add(btn);
2318
2319            btn = new qx.ui.menubar.Button("Help", submenu);
2320            btn.set({ paddingLeft : 7, paddingRight : 7 });
2321            menubar.add(btn);
2322        },
2323       
2324        nextColor : function()
2325        {
2326            var color = this.colorMap[this.ncolor];
2327            this.ncolor++;
2328            if (this.ncolor == this.colorMap.length) {
2329                this.ncolor = 0;
2330            }
2331           
2332            return color;
2333        },
2334
2335        getWindowDimensions : function()
2336        {
2337            var dims = new Object;
2338           
2339            dims.w = qx.html.Window.getInnerWidth(this.win);
2340            dims.h = qx.html.Window.getInnerHeight(this.win);
2341           
2342            return dims;
2343        },
2344
2345        savePreferences : function()
2346        {
2347            if (this.prefs) {
2348                var prefstr = qx.io.Json.stringify(this.prefs);
2349                qx.io.local.CookieApi.set("prefs", prefstr);
2350            }
2351        },
2352       
2353        loadPreferences : function()
2354        {
2355            var prefstr = qx.io.local.CookieApi.get("prefs");
2356            // this.warn(prefstr);
2357            if (prefstr) {
2358                this.prefs = qx.io.Json.parseQx(prefstr);
2359            }
2360           
2361            if (!this.prefs) {
2362                this.prefs = new Object;
2363            }
2364 
2365            if (!this.prefs.rememberWindowSize) {
2366                this.prefs.rememberWindowSize = false;
2367            }
2368           
2369            if (!this.prefs.units) {
2370                this.prefs.units = new Object;
2371            }
2372        },
2373       
2374
2375        createPrefsDialog : function()
2376        {
2377            var w;
2378            // "Preferences..." dialog
2379            w = new qx.ui.window.Window("Preferences",
2380                "pf/image/preferences.png");
2381            w.setSpace(200, "auto", 100, "auto");
2382            w.setModal(true);
2383            w.setShowMinimize(false);
2384            w.setShowMaximize(false);
2385
2386            var vbl = new qx.ui.layout.VerticalBoxLayout("vertical");
2387            vbl.setStretchChildrenOrthogonalAxis(false);
2388            w.add(vbl);
2389           
2390            var fr1, fr2, rc, l, e;
2391           
2392            fr1 = new qx.ui.groupbox.GroupBox("Default units");
2393            fr1.setDimension("auto", "auto");
2394            vbl.add(fr1);
2395           
2396            rc = new qx.ui.layout.HorizontalBoxLayout;
2397            rc.setWidth("100%");
2398            rc.setHeight("auto");
2399            rc.setSpacing(10);
2400            fr1.add(rc);
2401
2402            l = new qx.ui.basic.Label("Dimension:");
2403            e = new pf.ui.ComboBox;
2404            e.add(new qx.ui.form.ListItem("Frequency", null, "frequency"));
2405            e.add(new qx.ui.form.ListItem("Length", null, "length"));
2406            e.add(new qx.ui.form.ListItem("Velocity", null, "velocity"));
2407            e.add(new qx.ui.form.ListItem("Energy", null, "energy"));
2408            e.add(new qx.ui.form.ListItem("Pressure", null, "pressure"));
2409            e.add(new qx.ui.form.ListItem("Area", null, "area"));
2410            e.add(new qx.ui.form.ListItem("Power density", null, "power_density"));
2411            e.add(new qx.ui.form.ListItem("Power spectral density",
2412                null, "spectral_power_density"));
2413            e.add(new qx.ui.form.ListItem("Electric field", null, "efield"));
2414            e.addEventListener("changeSelected", function(ev) {
2415                    var dimension = ev.getTarget().getSelectedValue();
2416                    this.gui_prefs_units.update(dimension,
2417                        this.prefs.units[dimension]);
2418                }, this);
2419            rc.add(l, e);
2420            this.gui_prefs_dim = e;
2421
2422            l = new qx.ui.basic.Label("Units:");
2423            e = new pf.UnitSelector();
2424            e.addEventListener("changeSelected", function(ev) {
2425                    var dimension = this.gui_prefs_dim.getSelectedValue();
2426                    var units = ev.getTarget().getValue();
2427                    this.prefs.units[dimension] = units;
2428                }, this);
2429            rc.add(l, e);
2430            this.gui_prefs_units = e;
2431
2432            fr2 = new qx.ui.groupbox.GroupBox("Interface");
2433            fr2.setDimension("auto", "auto");
2434            vbl.add(fr2);
2435            // A hack...
2436            fr1.addEventListener("appear", function(ev) {
2437                    fr2.setWidth(this.getWidthValue());
2438                });
2439
2440            e = new qx.ui.form.CheckBox("Remember window dimensions on exit");
2441            e.setChecked(this.prefs.rememberWindowSize);
2442            e.addEventListener("changeChecked", function(ev) {
2443                this.prefs.rememberWindowSize = ev.getTarget().getChecked();
2444            }, this);
2445            fr2.add(e);
2446
2447            this.doc.add(w);
2448            this.prefsWindow = w;
2449        },
2450
2451        /**
2452         * TODOC
2453         *
2454         * @type member
2455         * @param e {Event} TODOC
2456         * @return {void}
2457         */
2458        main : function(e)
2459        {
2460            this.base(arguments);
2461           
2462            // Define alias for custom resource path
2463            qx.io.Alias.getInstance().add("pf",
2464                qx.core.Setting.get("pf.resourceUri"));
2465
2466            this.doc = qx.ui.core.ClientDocument.getInstance();
2467            this.win = this.doc.getWindowElement();
2468           
2469            // Load prefs
2470            this.loadPreferences();
2471           
2472            // Defaults
2473            this.r = new pf.base.Species("r", 1.0,           0, 0,    1.0, null);
2474            this.e = new pf.base.Species("e", (1.0/1836.2), -1, 1e16, 1.0, this.r);
2475            this.i = new pf.base.Species("i", 1.0,          +1, 1e16, 1.0, this.r);
2476           
2477            this.P_r = 0;
2478
2479            this.B   = 0;
2480           
2481            this.n_u = 2;
2482            this.n_l = 1;
2483           
2484            if (this.updatePlasmaParameters() != true) {
2485                this.error("Error updating plasma parameters!");
2486            }
2487           
2488            // Favorites
2489            this.favorites = new Array;
2490           
2491            this.colorMap = new Array("red", "blue", "green", "orange",
2492                "brown", "olive", "teal", "magenta", "grey", "black");
2493            this.ncolor = 0;
2494
2495            // Top-level container
2496            this.bl_top = new qx.ui.layout.VerticalBoxLayout("vertical");
2497            this.bl_top.setWidth("100%");
2498            this.bl_top.setHeight("100%");
2499
2500            this.bl_top.addToDocument();
2501
2502            // The menubar
2503            this.menubar = new qx.ui.menubar.MenuBar;
2504            this.bl_top.add(this.menubar);
2505           
2506            // The menu items
2507            this.buildMenu();
2508           
2509            var tf1 = new qx.ui.pageview.tabview.TabView;
2510            tf1.set({ width : '100%', height : '2*' });
2511
2512            this.bl_top.add(tf1);
2513
2514            this.tabbar  = tf1.getBar();
2515            this.tabpane = tf1.getPane();
2516            this.tabpane.setHeight('3*');
2517            this.tabpane.setPadding(0, 0, 0, 0);
2518
2519            // The "Parameters" tab
2520            this.renderParametersTab();
2521           
2522            // The "Explorer" tab
2523            this.renderExplorerTab();
2524           
2525            // The "Compare" tab
2526            this.renderCompareTab();
2527           
2528            // The "Plot" tab
2529            this.renderPlotTab();
2530           
2531            // "Preferences" dialog
2532            this.createPrefsDialog();
2533
2534            // "About..." dialog
2535            w = new qx.ui.window.Window("About Plasma Formulary",
2536                "pf/image/about.png");
2537            w.setSpace(200, "auto", 100, "auto");
2538            w.setModal(true);
2539            w.setShowMinimize(false);
2540            w.setShowMaximize(false);
2541           
2542            str = 'Plasma Formulary Interactive.<br/>'      +
2543                  '$Revision$.'                      +
2544                  '<p>Written by Evgeny Stambulchik.</p>'   +
2545                  '<p>GUI built with the Qooxdoo-'          + 
2546                  qx.core.Version + ' toolkit.<br/>'        + 
2547                  'Using Walter Zorn jsGraphics for drawing.</p>';
2548
2549            var a = new qx.ui.basic.Atom(str);
2550            a.set({ top: 4, left: 4 });
2551            w.add(a);
2552
2553            this.doc.add(w);
2554            this.aboutWindow = w;
2555           
2556            if (this.prefs.rememberWindowSize && this.prefs.dims) {
2557                self.resizeTo(this.prefs.dims.w,this.prefs.dims.h)
2558            }
2559
2560            // Handle resize events
2561            this.doc.addEventListener("windowresize", function(e) {
2562                if (this.prefs.rememberWindowSize) {
2563                    this.prefs.dims = this.getWindowDimensions();
2564                }
2565                this.drawCB();
2566            }, this);
2567        },
2568   
2569
2570        /**
2571         * TODOC
2572         *
2573         * @type member
2574         * @param e {Event} TODOC
2575         * @return {void}
2576         */
2577        close : function(e)
2578        {
2579            this.base(arguments);
2580
2581            // Prompt user
2582            // return "Do you really want to close the application?";
2583        },
2584
2585       /**
2586        * TODOC
2587        *
2588        * @type member
2589        * @param e {Event} TODOC
2590        * @return {void}
2591        */
2592        terminate : function(e) {
2593            // Save preferences
2594            this.savePreferences();
2595
2596            this.base(arguments);
2597        }
2598    },
2599
2600    /*
2601    *****************************************************************************
2602       SETTINGS
2603    *****************************************************************************
2604    */
2605
2606    settings : {
2607        "pf.resourceUri" : "./resource"
2608    }
2609});
Note: See TracBrowser for help on using the repository browser.
<