source: source/class/pf/Application.js @ 341:a7cbe51aa3f3

Last change on this file since 341:a7cbe51aa3f3 was 341:a7cbe51aa3f3, checked in by Evgeny Stambulchik <Evgeny.Stambulchik@…>, 11 years ago

"q" var is global in qx-3.

File size: 102.3 KB
Line 
1/* ************************************************************************
2
3   Copyright: Weizmann Institute of Science
4
5   License: GPL
6
7   Authors: Evgeny Stambulchik
8
9************************************************************************ */
10
11/* ************************************************************************
12
13#asset(pf/image/*.png)
14#asset(pf/html/*.html)
15
16************************************************************************ */
17
18// global
19var plasma_entities;
20
21function changeN_e(ev)
22{
23    var e = ev.getTarget();
24    var N_e = e.getNumValue();
25   
26    if (isFinite(N_e) && this.plasma.e.setN(N_e)) {
27        this.updatePlasmaParameters();
28        this.updateGUI();
29    }
30}
31
32function changeT_e(ev)
33{
34    var e = ev.getTarget();
35    var T_e = e.getNumValue();
36   
37    if (isFinite(T_e)) {
38        this.plasma.e.setT(T_e);
39        if (!this.gui_locked) {
40            this.plasma.i.setT(T_e);
41            this.plasma.r.setT(T_e);
42            this.updateGUI();
43        }
44    }
45}
46
47function changeZ_i(ev)
48{
49    var e = ev.getTarget();
50    var Z_i = parseInt(e.getValue());
51   
52    if (isFinite(Z_i)) {
53        this.plasma.i.setQ(Z_i);
54        this.updatePlasmaParameters();
55        this.updateGUI();
56    }
57}
58
59function changeT_i(ev)
60{
61    var e = ev.getTarget();
62    var T_i = e.getNumValue();
63   
64    if (isFinite(T_i)) {
65        this.plasma.i.setT(T_i);
66        if (!this.gui_locked) {
67            this.plasma.r.setT(T_i);
68            this.updateGUI();
69        }
70    }
71}
72
73function changeZ_r(ev)
74{
75    var e = ev.getTarget();
76    var Z_r = parseInt(e.getValue());
77   
78    if (isFinite(Z_r)) {
79        this.plasma.r.setQ(Z_r);
80        this.updatePlasmaParameters();
81        this.updateGUI();
82    }
83}
84
85function changeP_r(ev)
86{
87    var e = ev.getTarget();
88    var P_r = parseFloat(e.getValue())/100.0;
89   
90    if (isFinite(P_r)) {
91        this.plasma.P_r = P_r;
92        this.updatePlasmaParameters();
93        this.updateGUI();
94    }
95}
96
97function changeT_r(ev)
98{
99    var e = ev.getTarget();
100    var T_r = e.getNumValue();
101   
102    if (isFinite(T_r)) {
103        this.plasma.r.setT(T_r);
104        this.updateGUI();
105    }
106}
107
108function changeM_i(ev)
109{
110    var e = ev.getTarget();
111    var M_i = e.getNumValue();
112   
113    if (isFinite(M_i)) {
114        this.plasma.i.setM(M_i);
115        this.updateGUI();
116    }
117}
118
119function changeM_r(ev)
120{
121    var e = ev.getTarget();
122    var M_r = e.getNumValue();
123   
124    if (isFinite(M_r)) {
125        this.plasma.r.setM(M_r);
126        this.updateGUI();
127    }
128}
129
130function changeN_u(ev)
131{
132    var e = ev.getTarget();
133    var n_u = parseInt(e.getValue());
134   
135    this.gui_n_l.setMaximum(n_u - 1);
136   
137    this.plasma.r.setN_u(n_u);
138    this.updateGUI();
139}
140
141function changeN_l(ev)
142{
143    var e = ev.getTarget();
144    var n_l = parseInt(e.getValue());
145   
146    this.gui_n_u.setMinimum(n_l + 1);
147   
148    this.plasma.r.setN_l(n_l);
149    this.updateGUI();
150}
151
152function changeB(ev)
153{
154    var e = ev.getTarget();
155    var v = e.getNumValue();
156   
157    if (isFinite(v)) {
158        this.plasma.B = v;
159        this.updateGUI();
160    }
161}
162
163function viewMenuCB(ev)
164{
165    var explorer_is_seen;
166   
167    if (this.entity_tree.isSeeable()) {
168        explorer_is_seen = true;
169    } else {
170        explorer_is_seen = false;
171    }
172   
173    this.showSectionsButton.setEnabled(explorer_is_seen);
174    this.showSpeciesButton.setEnabled(explorer_is_seen);
175    this.redrawButton.setEnabled(this.canvas.isSeeable());
176
177    if (this.prefs.autoLoadWiki) {
178        this.loadWikiButton.setEnabled(false);
179    } else {
180        var tree = this.entity_tree;
181        var leaf = getSingleTreeSelectedItem(tree);
182        if (leaf && leaf.classname == "qx.ui.tree.TreeFile" && explorer_is_seen) {
183            this.loadWikiButton.setEnabled(true);
184        } else {
185            this.loadWikiButton.setEnabled(false);
186        }
187    }
188}
189
190function editMenuCB(ev)
191{
192    var explorer_is_seen;
193   
194    if (this.entity_tree.isSeeable()) {
195        explorer_is_seen = true;
196    } else {
197        explorer_is_seen = false;
198    }
199
200    var tree = this.entity_tree;
201    var leaf = getSingleTreeSelectedItem(tree);
202
203    if (leaf && leaf.classname == "qx.ui.tree.TreeFile" && explorer_is_seen) {
204        if (this.isFavorite(leaf)) {
205            this.editMenuButtonAddToFav.setEnabled(false);
206            this.editMenuButtonRemFromFav.setEnabled(true);
207        } else {
208            this.editMenuButtonAddToFav.setEnabled(true);
209            this.editMenuButtonRemFromFav.setEnabled(false);
210        }
211    } else {
212        this.editMenuButtonAddToFav.setEnabled(false);
213        this.editMenuButtonRemFromFav.setEnabled(false);
214    }
215}
216
217function getSingleTreeSelectedItem(tree)
218{
219    var sels = tree.getSelection();
220    if (sels && sels.length == 1) {
221        return sels[0];
222    } else {
223        return null;
224    }
225}
226
227function treeMenuCB(ev)
228{
229    if (ev.getButton() == "right") {
230        var menu = this.treeMenu;
231
232        if (menu.isSeeable()) {
233            menu.hide();
234        } else {
235            var w = ev.getTarget();
236            var leaf = null;
237            if (w.classname == "qx.ui.tree.TreeFile") {
238                leaf = w;
239            } else
240            if (w.getLayoutParent().classname == "qx.ui.tree.TreeFile") {
241                leaf = w.getLayoutParent();
242            }
243           
244            if (leaf) {
245                if (this.isFavorite(leaf)) {
246                    this.treeMenuButtonAddToFav.setEnabled(false);
247                    this.treeMenuButtonRemFromFav.setEnabled(true);
248                } else {
249                    this.treeMenuButtonAddToFav.setEnabled(true);
250                    this.treeMenuButtonRemFromFav.setEnabled(false);
251                }
252            } else {
253                this.treeMenuButtonAddToFav.setEnabled(false);
254                this.treeMenuButtonRemFromFav.setEnabled(false);
255            }
256           
257            // position & show the menu
258            menu.placeToMouse(ev);
259            menu.show();
260        };
261
262        // ev.stopPropagation();
263    }
264}
265
266function showFundamentalCB(ev)
267{
268    this.showFundamental = !this.showFundamental;
269    this.rePopulateTree();
270}
271
272function showSpectroscopyCB(ev)
273{
274    this.showSpectroscopy = !this.showSpectroscopy;
275    this.rePopulateTree();
276}
277
278function showWavesCB(ev)
279{
280    this.showWaves = !this.showWaves;
281    this.rePopulateTree();
282}
283
284function showCollisionsCB(ev)
285{
286    this.showCollisions = !this.showCollisions;
287    this.rePopulateTree();
288}
289
290function showRadiationCB(ev)
291{
292    this.showRadiation = !this.showRadiation;
293    this.rePopulateTree();
294}
295
296function showElectronsCB(ev)
297{
298    this.showElectrons = !this.showElectrons;
299    this.rePopulateTree();
300}
301
302function showIonsCB(ev)
303{
304    this.showIons = !this.showIons;
305    this.rePopulateTree();
306}
307
308function showRadiatorsCB(ev)
309{
310    this.showRadiators = !this.showRadiators;
311    this.rePopulateTree();
312}
313
314function addToFavCB(ev)
315{
316    var tree = this.entity_tree;
317    var leaf = getSingleTreeSelectedItem(tree);
318
319    if (!leaf) {
320        return;
321    }
322
323    leaf.setTextColor(this.leafFavColor);
324
325    // Add to the list of favorites
326    var fav = new Object;
327    fav.entity = leaf.getUserData("entity");
328    fav.s1     = leaf.getUserData("s1");
329    fav.s2     = leaf.getUserData("s2");
330    fav.color  = this.nextColor();
331    this.favorites.push(fav);
332   
333    // Switch the dimension selector ...
334    this.gui_compare_dim.selectByValue(fav.entity.dimension);
335    // ... and update the list of favorites
336    this.updateFavoritesListView();
337    this.updateLegendListView();
338   
339    this.saveFavorites();
340}
341
342function removeFromFavCB(ev)
343{
344    var tree = this.entity_tree;
345    var leaf = getSingleTreeSelectedItem(tree);
346
347    if (!leaf) {
348        return;
349    }
350    leaf.setTextColor(this.leafColor);
351
352    var entity = leaf.getUserData("entity");
353    var s1     = leaf.getUserData("s1");
354    var s2     = leaf.getUserData("s2");
355
356    // Remove from the list of favorites
357    for (var k = 0; k < this.favorites.length; k++) {
358        var fav = this.favorites[k];
359        if (fav.entity  == entity && fav.s1 == s1 && fav.s2 == s2) {
360            this.favorites.splice(k, 1);
361            break;
362        }
363    }
364
365    // Switch the dimension selector ...
366    this.gui_compare_dim.selectByValue(entity.dimension);
367    // ... and update the list of favorites
368    this.updateFavoritesListView();
369    this.updateLegendListView();
370   
371    this.saveFavorites();
372}
373
374function clickTreeCB(ev)
375{
376    var tree = ev.getTarget();
377    var e = getSingleTreeSelectedItem(tree);
378    if (e) {
379        var entity = e.getUserData("entity");
380       
381        if (entity) {
382            this.gui_entity_units.update(entity.dimension,
383                this.prefs.units[entity.dimension]);
384        } else {
385            this.gui_entity_units.update(null, null);
386        }
387       
388        this.updateEntityValue();
389    }
390}
391
392function changeUnitsCB(ev)
393{
394    this.updateEntityValue();
395}
396
397/**
398 * The application
399 */
400qx.Class.define("pf.Application",
401{
402    extend : qx.application.Standalone,
403
404    /*
405    *****************************************************************************
406       MEMBERS
407    *****************************************************************************
408    */
409
410    members :
411    {
412        showFundamental  : true,
413        showSpectroscopy : true,
414        showWaves        : true,
415        showCollisions   : true,
416        showRadiation    : true,
417
418        showElectrons  : true,
419        showIons       : true,
420        showRadiators  : true,
421       
422        leafColor      : "black",
423        leafFavColor   : "red",
424       
425        plasma : null,
426
427        updatePlasmaParameters : function()
428        {
429            return this.plasma.updateParameters();
430        },
431       
432        updateGUI : function()
433        {
434            if (this.gui_locked) {
435                return;
436            }
437           
438            this.gui_locked = true;
439           
440            // Make sure GUI does not remain locked forever...
441            try {
442                if (this.prefs.currentConfigName) {
443                    this.gui_configName.setLabel(this.prefs.currentConfigName);
444                }
445
446                this.gui_N_e.setNumValue(this.plasma.e.getN());
447                this.gui_T_e.setNumValue(this.plasma.e.getT());
448
449                this.gui_N_i.setNumValue(this.plasma.i.getN());
450                this.gui_T_i.setNumValue(this.plasma.i.getT());
451                this.gui_Z_i.setValue(this.plasma.i.getQ());
452                this.gui_M_i.setNumValue(this.plasma.i.getM());
453
454                this.gui_P_r.setValue(100*this.plasma.P_r);
455
456                this.gui_N_r.setNumValue(this.plasma.r.getN());
457                this.gui_T_r.setNumValue(this.plasma.r.getT());
458                this.gui_Z_r.setValue(this.plasma.r.getQ());
459                this.gui_Zcore.setValue((this.plasma.r.getQ() + 1) + '');
460                this.gui_M_r.setNumValue(this.plasma.r.getM());
461
462                this.gui_B.setNumValue(this.plasma.B);
463
464                // Make sure n_u > n_l holds during update
465                if (this.gui_n_l.getValue() >= this.plasma.r.getN_u()) {
466                    this.gui_n_l.setValue(this.plasma.r.getN_l());
467                    this.gui_n_u.setValue(this.plasma.r.getN_u());
468                } else {
469                    this.gui_n_u.setValue(this.plasma.r.getN_u());
470                    this.gui_n_l.setValue(this.plasma.r.getN_l());
471                }
472
473                // Update the currently selected entity
474                this.updateEntityValue();
475
476                // Update the list of favorites
477                this.updateFavoritesListView();
478                this.updateLegendListView();
479            } catch (err) {
480                this.error(err);
481            }
482           
483            this.gui_locked = false;
484        },
485       
486
487        getSpeciesName : function(species) {
488            var name;
489           
490            switch (species.id) {
491            case "e":
492                name = "electrons";
493                break;
494            case "i":
495                name = "ions";
496                break;
497            case "r":
498                name = "radiators";
499                break;
500            default:
501                name = null;
502                break;
503            }
504           
505            return name;
506        },
507       
508        getEntityFullName : function(entity, s1, s2)
509        {
510            var name = entity.name;
511            switch (entity.nspecies) { 
512            case 2:
513                name += " (" + this.getSpeciesName(s1) + "/" +
514                               this.getSpeciesName(s2) + ")";
515                break;
516            case 1:
517                var prepos = entity.prepos;
518                if (!prepos) {
519                    prepos = "of";
520                }
521                name += " " + prepos + " " + this.getSpeciesName(s1);
522                break;
523            default:
524                break;
525            }
526           
527            return name;
528        },
529       
530        evaluateEntityValue : function(entity, s1, s2)
531        {
532            var formula;
533            switch (entity.nspecies) {
534            case 1:
535                var s1_str = "this.plasma." + s1.id;
536                formula = entity.formula.replace(/\%s1/g, s1_str);
537                break;
538            case 2:
539                var s1_str = "this.plasma." + s1.id;
540                var s2_str = "this.plasma." + s2.id;
541                formula = entity.formula.replace(/\%s1/g, s1_str);
542                formula = formula.replace(/\%s2/g, s2_str);
543                break;
544            default:
545                formula = entity.formula;
546                break;
547            }
548            var v = eval(formula);
549           
550            return v;
551        },
552       
553        updateEntityValue : function()
554        {
555            var tree = this.entity_tree;
556            var leaf = getSingleTreeSelectedItem(tree);
557           
558            if (!leaf) {
559                return;
560            }
561           
562            var entity = leaf.getUserData("entity");
563            var s1     = leaf.getUserData("s1");
564            var s2     = leaf.getUserData("s2");
565           
566            var name, section, value;
567            if (entity) {
568                var v     = this.evaluateEntityValue(entity, s1, s2);
569                var scale = this.gui_entity_units.getSelectedValue();
570               
571                name    = this.getEntityFullName(entity, s1, s2);
572                section = entity.section;
573                value   = v*scale
574            } else {
575                name    = null;
576                section = null;
577                value   = 0;
578            }
579           
580            this.gui_entity_name.setValue(name);
581
582            this.gui_entity_section.setValue(section);
583
584            if (isFinite(value)) {
585                this.gui_entity_value.setNumValue(value);
586            } else {
587                this.gui_entity_value.setValue("");
588            }
589           
590            if (this.prefs.autoLoadWiki) {
591                this.showWikiPage(entity);
592            } else {
593                this.showWikiPage(null);
594            }
595        },
596
597        isFavorite : function(leaf)
598        {
599            var entity = leaf.getUserData("entity");
600            var s1     = leaf.getUserData("s1");
601            var s2     = leaf.getUserData("s2");
602
603            for (var k = 0; k < this.favorites.length; k++) {
604                var fav = this.favorites[k];
605                if (fav.entity  == entity && fav.s1 == s1 && fav.s2 == s2) {
606                    return true;
607                    break;
608                }
609            }
610           
611            return false;
612        },
613       
614        addEntityLeaf : function(entity, s1, s2)
615        {
616            var icon;
617           
618            if (s1 && s2) {
619                icon = "pf/image/" + s1.id + s2.id + "_small.png";
620            } else
621            if (s1) {
622                icon = "pf/image/" + s1.id + "_small.png";
623            } else {
624                icon = "pf/image/all_small.png";
625            }
626           
627            var leaf = new qx.ui.tree.TreeFile(entity.name);
628            leaf.setIcon(icon);
629            leaf.addListener("contextmenu", treeMenuCB, this);
630
631            leaf.setUserData("entity", entity);
632            leaf.setUserData("s1", s1);
633            leaf.setUserData("s2", s2);
634
635            if (this.isFavorite(leaf)) {
636                leaf.setTextColor(this.leafFavColor);
637            } else {
638                leaf.setTextColor(this.leafColor);
639            }
640           
641            return leaf;
642        },
643
644        populateTree : function()
645        {
646            var n = plasma_entities.length;
647            var sa = new Array;
648            if (this.showElectrons) {
649                sa.push(this.plasma.e)
650            }
651            if (this.showIons) {
652                sa.push(this.plasma.i)
653            }
654            if (this.showRadiators) {
655                sa.push(this.plasma.r)
656            }
657           
658            for (var i = 0; i < n; i++) {
659                var entity = plasma_entities[i];
660               
661                if (entity.section == "fundamental" &&
662                    this.showFundamental != true) {
663                    continue;
664                }
665                if (entity.section == "spectroscopy" &&
666                    this.showSpectroscopy != true) {
667                    continue;
668                }
669                if (entity.section == "waves" &&
670                    this.showWaves != true) {
671                    continue;
672                }
673                if (entity.section == "collisions" &&
674                    this.showCollisions != true) {
675                    continue;
676                }
677                if (entity.section == "radiation" &&
678                    this.showRadiation != true) {
679                    continue;
680                }
681               
682                var folder;
683                switch (entity.dimension) {
684                case "frequency":
685                    folder = this.gui_folder_freq;
686                    break;
687                case "length":
688                    folder = this.gui_folder_length;
689                    break;
690                case "velocity":
691                    folder = this.gui_folder_vel;
692                    break;
693                case "energy":
694                    folder = this.gui_folder_energy;
695                    break;
696                case "mass_density":
697                    folder = this.gui_folder_mass_density;
698                    break;
699                case "pressure":
700                    folder = this.gui_folder_pressure;
701                    break;
702                case "area":
703                    folder = this.gui_folder_area;
704                    break;
705                case "power_density":
706                    folder = this.gui_folder_power_density;
707                    break;
708                case "spectral_power_density":
709                    folder = this.gui_folder_spectral_power_density;
710                    break;
711                case "efield":
712                    folder = this.gui_folder_efield;
713                    break;
714                case "none":
715                    folder = this.gui_folder_none;
716                    break;
717                default:
718                    continue;
719                    break;
720                }
721               
722                var leaf;
723               
724                switch (entity.nspecies) {
725                case 1:
726                    for (var j = 0; j < sa.length; j++) {
727                        var s = sa[j];
728                        leaf = this.addEntityLeaf(entity, s, null);
729                        folder.add(leaf);
730                    }
731                    break;
732                case 2:
733                    for (var j = 0; j < sa.length; j++) {
734                        var s1 = sa[j];
735                        for (var k = j; k < sa.length; k++) {
736                            var s2 = sa[k];
737                            leaf = this.addEntityLeaf(entity, s1, s2);
738                            folder.add(leaf);
739                        }
740                    }
741                    break;
742                default:
743                    leaf = this.addEntityLeaf(entity, null, null);
744                    folder.add(leaf);
745                    break;
746                }
747            }
748        }, 
749
750        cleanTree : function()
751        {
752            this.gui_folder_freq.removeAll();
753           
754            this.gui_folder_length.removeAll();
755           
756            this.gui_folder_vel.removeAll();
757           
758            this.gui_folder_none.removeAll();
759           
760            this.gui_folder_energy.removeAll();
761           
762            this.gui_folder_mass_density.removeAll();
763
764            this.gui_folder_pressure.removeAll();
765           
766            this.gui_folder_area.removeAll();
767           
768            this.gui_folder_power_density.removeAll();
769
770            this.gui_folder_spectral_power_density.removeAll();
771           
772            this.gui_folder_efield.removeAll();
773        },
774
775        rePopulateTree : function()
776        {
777            this.cleanTree();
778           
779            this.populateTree();
780        },
781
782
783        updateFavoritesListView : function()
784        {
785            var lv = this.favoritesListView;
786            var tm = lv.getTableModel();
787           
788            var dimension = this.gui_compare_dim.getSelectedValue();
789           
790            var scale = this.gui_compare_units.getSelectedValue();
791           
792            var rowData = new Array();
793           
794            for (var i = 0; i < this.favorites.length; i++) {
795                var fav = this.favorites[i];
796                var entity = fav.entity;
797               
798                if (entity.dimension != dimension) {
799                    continue;
800                }
801               
802                var s1 = fav.s1;
803                var s2 = fav.s2;
804
805                var icon;
806                if (s1 && s2) {
807                    icon = "pf/image/" + s1.id + s2.id + "_small.png";
808                } else
809                if (s1) {
810                    icon = "pf/image/" + s1.id + "_small.png";
811                } else {
812                    icon = "pf/image/all_small.png";
813                }
814                var name = this.getEntityFullName(entity, s1, s2);
815                var value = scale*this.evaluateEntityValue(entity, s1, s2);
816
817                rowData.push([icon, name, entity.section,
818                    pf.util.Format.numPrint(value)]);
819            }
820           
821            tm.setData(rowData, false);
822            var sidx = tm.getSortColumnIndex();
823            tm.sortByColumn(sidx, tm.isSortAscending());
824           
825            lv.updateContent();
826            // lv.updateSort();
827            // lv.update();
828        },
829
830        updateLegendListView : function()
831        {
832            var lv = this.legendListView;
833            var tm = lv.getTableModel();
834
835            var rowData = new Array();
836           
837            var dimension = this.gui_compare_dim.getSelectedValue();
838           
839            for (var i = 0; i < this.favorites.length; i++) {
840                var fav = this.favorites[i];
841                var entity = fav.entity;
842               
843                if (entity.dimension != dimension) {
844                    continue;
845                }
846               
847                var s1    = fav.s1;
848                var s2    = fav.s2;
849
850                var name  = this.getEntityFullName(entity, s1, s2);
851                var color = fav.color;
852
853                rowData.push({"color": color, "name": name, "favorite": fav});
854            }
855           
856            tm.setDataAsMapArray(rowData);
857            // lv.updateContent();
858        },
859
860
861        renderTabPage : function(label, icon, checked)
862        {
863            var page_id;
864           
865            page_id = new qx.ui.tabview.Page(label, icon);
866            this.tabview.add(page_id, {height: "100%"});
867
868            if (checked) {
869                this.tabview.setSelection(page_id);
870            }
871           
872            return page_id;
873        },
874
875        renderParametersTab : function()
876        {
877            var fr, gl, rc, rc1, rc2;
878           
879            var page_id = this.renderTabPage("Parameters",
880                "pf/image/tab-parameters.png", true);
881            page_id.setLayout(new qx.ui.layout.VBox(10));
882
883            fr = new qx.ui.groupbox.GroupBox("Configuration name",
884                "pf/image/info.png");
885            fr.setLayout(new qx.ui.layout.VBox());
886
887            this.gui_configName =
888                new qx.ui.basic.Atom(this.prefs.currentConfigName);
889            this.gui_configName.setRich(true)
890            fr.add(this.gui_configName);
891            page_id.add(fr);
892           
893
894            rc = new qx.ui.container.Composite(new qx.ui.layout.HBox(10));
895            page_id.add(rc);
896           
897            rc1 = new qx.ui.container.Composite(new qx.ui.layout.VBox(10));
898            rc.add(rc1, {flex : 1});
899           
900            rc2 = new qx.ui.container.Composite(new qx.ui.layout.VBox(27));
901            rc.add(rc2, {flex : 1});
902           
903           
904            fr = new qx.ui.groupbox.GroupBox("Electrons",
905                "pf/image/e_small.png");
906            fr.setLayout(new qx.ui.layout.VBox());
907
908            rc1.add(fr);
909
910            var layout = new qx.ui.layout.Grid(4, 6);
911            layout.setColumnWidth(0, 80);
912            layout.setColumnFlex(1, 1);
913            gl = new qx.ui.container.Composite(layout);
914
915            fr.add(gl);
916
917            var l, e, au_fn, au_fT;
918           
919            au_fn = pf.base.Bohr.n0;
920            au_fT = pf.base.Bohr.E0;
921
922            // N_e
923            l = new qx.ui.basic.Label("N<sub>e</sub> (cm<sup>-3</sup>):");
924            l.setRich(true);
925            gl.add(l, {row: 0, column: 0});
926            e = new pf.ui.TextField(this.plasma.e.getN(), au_fn);
927            gl.add(e, {row: 0, column: 1});
928            e.addListener("changeValue", changeN_e, this);
929            this.gui_N_e = e;
930
931            // T_e
932            l = new qx.ui.basic.Label("T<sub>e</sub> (eV):");
933            l.setRich(true);
934            gl.add(l, {row: 1, column: 0});
935            e = new pf.ui.TextField(this.plasma.e.getT(), au_fT);
936            gl.add(e, {row: 1, column: 1});
937            e.addListener("changeValue", changeT_e, this);
938            this.gui_T_e = e;
939           
940            fr = new qx.ui.groupbox.GroupBox("Ions",
941                "pf/image/i_small.png");
942            fr.setLayout(new qx.ui.layout.VBox());
943
944            rc1.add(fr);
945
946            layout = new qx.ui.layout.Grid(4, 6);
947            layout.setColumnWidth(0, 80);
948            layout.setColumnFlex(1, 1);
949            gl = new qx.ui.container.Composite(layout);
950
951            fr.add(gl);
952
953            // Z_i
954            l = new qx.ui.basic.Label("Z<sub>i</sub>:");
955            l.setRich(true);
956            gl.add(l, {row: 0, column: 0});
957            e = new qx.ui.form.Spinner(1, this.plasma.i.getQ(), 100);
958            gl.add(e, {row: 0, column: 1});
959            e.addListener("changeValue", changeZ_i, this);
960            this.gui_Z_i = e;
961           
962            // M_i
963            l = new qx.ui.basic.Label("M<sub>i</sub>:");
964            l.setRich(true);
965            gl.add(l, {row: 1, column: 0});
966            e = new pf.ui.TextField(this.plasma.i.getM(), 1/pf.base.Bohr.m_p);
967            gl.add(e, {row: 1, column: 1});
968            e.addListener("changeValue", changeM_i, this);
969            this.gui_M_i = e;
970           
971            // T_i
972            l = new qx.ui.basic.Label("T<sub>i</sub> (eV):");
973            l.setRich(true);
974            gl.add(l, {row: 2, column: 0});
975            e = new pf.ui.TextField(this.plasma.i.getT(), au_fT);
976            gl.add(e, {row: 2, column: 1});
977            e.addListener("changeValue", changeT_i, this);
978            this.gui_T_i = e;
979
980            // N_i
981            l = new qx.ui.basic.Label("N<sub>i</sub> (cm<sup>-3</sup>):");
982            l.setRich(true);
983            gl.add(l, {row: 3, column: 0});
984            e = new pf.ui.TextField(this.plasma.i.getN(), au_fn);
985            gl.add(e, {row: 3, column: 1});
986            e.setReadOnly(true);
987            this.gui_N_i = e;
988           
989            fr = new qx.ui.groupbox.GroupBox("Radiators",
990                "pf/image/r_small.png");
991            fr.setLayout(new qx.ui.layout.VBox());
992
993            rc2.add(fr);
994
995            layout = new qx.ui.layout.Grid(4, 6);
996            layout.setColumnWidth(0, 80);
997            layout.setColumnFlex(1, 1);
998            gl = new qx.ui.container.Composite(layout);
999
1000            fr.add(gl);
1001
1002            // Z_r
1003            l = new qx.ui.basic.Label("Z<sub>r</sub>:");
1004            l.setRich(true);
1005            gl.add(l, {row: 0, column: 0});
1006            e = new qx.ui.form.Spinner(0, this.plasma.r.getQ(), 100);
1007            gl.add(e, {row: 0, column: 1});
1008            e.addListener("changeValue", changeZ_r, this);
1009            this.gui_Z_r = e;
1010
1011            // M_r
1012            l = new qx.ui.basic.Label("M<sub>r</sub>:");
1013            l.setRich(true);
1014            gl.add(l, {row: 1, column: 0});
1015            e = new pf.ui.TextField(this.plasma.r.getM(), 1/pf.base.Bohr.m_p);
1016            gl.add(e, {row: 1, column: 1});
1017            e.addListener("changeValue", changeM_r, this);
1018            this.gui_M_r = e;
1019
1020            // T_r
1021            l = new qx.ui.basic.Label("T<sub>r</sub> (eV):");
1022            l.setRich(true);
1023            gl.add(l, {row: 2, column: 0});
1024            e = new pf.ui.TextField(this.plasma.r.getT(), au_fT);
1025            gl.add(e, {row: 2, column: 1});
1026            e.addListener("changeValue", changeT_r, this);
1027            this.gui_T_r = e;
1028
1029            // P_r
1030            l = new qx.ui.basic.Label("P<sub>r</sub> (%):");
1031            l.setRich(true);
1032            gl.add(l, {row: 3, column: 0});
1033            e = new qx.ui.form.Spinner(0, 100*this.plasma.P_r, 100);
1034            var nf = new qx.util.format.NumberFormat();
1035            nf.setMaximumFractionDigits(3);
1036            e.setNumberFormat(nf);
1037            gl.add(e, {row: 3, column: 1});
1038            e.addListener("changeValue", changeP_r, this);
1039            this.gui_P_r = e;
1040
1041            // N_r
1042            l = new qx.ui.basic.Label("N<sub>r</sub> (cm<sup>-3</sup>):");
1043            l.setRich(true);
1044            gl.add(l, {row: 4, column: 0});
1045            e = new pf.ui.TextField(this.plasma.r.getN(), au_fn);
1046            e.setReadOnly(true);
1047            gl.add(e, {row: 4, column: 1});
1048            this.gui_N_r = e;
1049
1050
1051            fr = new qx.ui.groupbox.GroupBox("Fields",
1052                "pf/image/field_small.png");
1053            fr.setLayout(new qx.ui.layout.VBox());
1054
1055            rc1.add(fr);
1056
1057            layout = new qx.ui.layout.Grid(4, 6);
1058            layout.setColumnWidth(0, 80);
1059            layout.setColumnFlex(1, 1);
1060            gl = new qx.ui.container.Composite(layout);
1061
1062            fr.add(gl);
1063
1064
1065            l = new qx.ui.basic.Label("B (T):");
1066            l.setRich(true);
1067            gl.add(l, {row: 0, column: 0});
1068            e = new pf.ui.TextField(this.plasma.B, pf.base.Bohr.B0);
1069            gl.add(e, {row: 0, column: 1});
1070            e.addListener("changeValue", changeB, this);
1071            this.gui_B = e;
1072
1073            // Atomic system frame
1074            fr = new qx.ui.groupbox.GroupBox("Atomic system",
1075                "pf/image/all_small.png");
1076            fr.setLayout(new qx.ui.layout.VBox());
1077
1078            rc2.add(fr);
1079
1080            layout = new qx.ui.layout.Grid(4, 6);
1081            layout.setColumnWidth(0, 80);
1082            layout.setColumnFlex(1, 1);
1083            gl = new qx.ui.container.Composite(layout);
1084
1085            fr.add(gl);
1086
1087            l = new qx.ui.basic.Label("Z<sub>core</sub>:");
1088            l.setRich(true);
1089            gl.add(l, {row: 0, column: 0});
1090            e = new qx.ui.form.TextField((this.plasma.r.getQ() + 1) + '');
1091            e.setReadOnly(true);
1092            gl.add(e, {row: 0, column: 1});
1093            this.gui_Zcore = e;
1094
1095            l = new qx.ui.basic.Label("n<sub>u</sub>:");
1096            l.setRich(true);
1097            gl.add(l, {row: 1, column: 0});
1098            e = new qx.ui.form.Spinner(this.plasma.r.getN_l() + 1,
1099                this.plasma.r.getN_u(), 1000);
1100            gl.add(e, {row: 1, column: 1});
1101            e.addListener("changeValue", changeN_u, this);
1102            this.gui_n_u = e;
1103
1104            l = new qx.ui.basic.Label("n<sub>l</sub>:");
1105            l.setRich(true);
1106            gl.add(l, {row: 2, column: 0});
1107            e = new qx.ui.form.Spinner(1, this.plasma.r.getN_l(),
1108                this.plasma.r.getN_u() - 1);
1109            gl.add(e, {row: 2, column: 1});
1110            e.addListener("changeValue", changeN_l, this);
1111            this.gui_n_l = e;
1112        },
1113
1114        renderExplorerTab : function()
1115        {
1116            var page_id = this.renderTabPage("Explorer",
1117                "pf/image/tab-explorer.png", false);
1118            page_id.setLayout(new qx.ui.layout.VBox);
1119
1120            var sp = new qx.ui.splitpane.Pane("horizontal");
1121            sp.setDecorator("main");
1122            page_id.add(sp, {height: "100%"});
1123           
1124            // Create container with fixed dimensions for the left:
1125            var left_pane = new qx.ui.container.Composite(new qx.ui.layout.Grow).set({
1126              width: 250
1127            });
1128
1129            // Create container for the right:
1130            var right_pane = new qx.ui.container.Composite(new qx.ui.layout.VBox(4)).set({
1131              padding : 4
1132            });
1133
1134            sp.add(left_pane,  0, {flex: 1});
1135            sp.add(right_pane, 1, {flex: 2});
1136
1137           
1138            var tree = new qx.ui.tree.Tree("Browser");
1139            tree.setDecorator(null);
1140            left_pane.add(tree);
1141           
1142            this.entity_tree = tree;
1143           
1144            var folder;
1145           
1146            var root = new qx.ui.tree.TreeFolder("Root");
1147            root.setOpen(true);
1148            tree.setRoot(root);
1149            tree.setHideRoot(true);
1150            tree.setRootOpenClose(true);
1151            tree.setOpenMode("dblclick");
1152
1153            tree.addListener("changeSelection", clickTreeCB, this);
1154           
1155            folder = new qx.ui.tree.TreeFolder("Dimensionless");
1156            root.add(folder);
1157            this.gui_folder_none = folder;
1158
1159            folder = new qx.ui.tree.TreeFolder("Length");
1160            root.add(folder);
1161            this.gui_folder_length = folder;
1162           
1163            folder = new qx.ui.tree.TreeFolder("Frequency");
1164            root.add(folder);
1165            this.gui_folder_freq = folder;
1166
1167            folder = new qx.ui.tree.TreeFolder("Velocity");
1168            root.add(folder);
1169            this.gui_folder_vel = folder;
1170           
1171            folder = new qx.ui.tree.TreeFolder("Area");
1172            root.add(folder);
1173            this.gui_folder_area = folder;
1174
1175            folder = new qx.ui.tree.TreeFolder("Mass density");
1176            root.add(folder);
1177            this.gui_folder_mass_density = folder;
1178
1179            folder = new qx.ui.tree.TreeFolder("Energy");
1180            root.add(folder);
1181            this.gui_folder_energy = folder;
1182
1183            folder = new qx.ui.tree.TreeFolder("Pressure");
1184            root.add(folder);
1185            this.gui_folder_pressure = folder;
1186
1187            folder = new qx.ui.tree.TreeFolder("Power density");
1188            root.add(folder);
1189            this.gui_folder_power_density = folder;
1190
1191            folder = new qx.ui.tree.TreeFolder("Power spectral density");
1192            root.add(folder);
1193            this.gui_folder_spectral_power_density = folder;
1194
1195            folder = new qx.ui.tree.TreeFolder("Electric field");
1196            root.add(folder);
1197            this.gui_folder_efield = folder;
1198
1199           
1200
1201            this.populateTree();
1202
1203            // Build context-sensitive popup menu
1204            this.treeMenu = new qx.ui.menu.Menu;
1205            var button;
1206           
1207            button = new qx.ui.menu.Button("Add to Favorites",
1208                "pf/image/favorite-add.png");
1209            button.addListener("execute", addToFavCB, this);
1210            this.treeMenu.add(button);
1211            this.treeMenuButtonAddToFav = button;
1212            button = new qx.ui.menu.Button("Remove from Favorites",
1213                "pf/image/favorite-delete.png");
1214            button.addListener("execute", removeFromFavCB, this);
1215            this.treeMenu.add(button);
1216            this.treeMenuButtonRemFromFav = button;
1217           
1218            this.doc.add(this.treeMenu);
1219
1220
1221            var layout = new qx.ui.layout.Grid(4, 6);
1222            layout.setColumnFlex(0, 3);
1223            layout.setColumnFlex(1, 12);
1224            layout.setColumnFlex(2, 4);
1225            layout.setColumnMinWidth(0,  50);
1226            layout.setColumnMaxWidth(2, 150);
1227            var gl = new qx.ui.container.Composite(layout);
1228           
1229            var l, e;
1230           
1231
1232            l = new qx.ui.basic.Label("Name:");
1233            gl.add(l, {row: 0, column: 0});
1234            e = new qx.ui.form.TextField();
1235            e.setReadOnly(true);
1236            this.gui_entity_name = e;
1237            gl.add(e, {row: 0, column: 1, colSpan: 2});
1238
1239            l = new qx.ui.basic.Label("Value:");
1240            gl.add(l, {row: 1, column: 0});
1241            e = new pf.ui.TextField("");
1242            e.setReadOnly(true);
1243            gl.add(e, {row: 1, column: 1});
1244            this.gui_entity_value = e;
1245
1246            e = new pf.UnitSelector();
1247            e.addListener("changeSelection", changeUnitsCB, this);
1248            gl.add(e, {row: 1, column: 2});
1249            this.gui_entity_units = e;
1250
1251            l = new qx.ui.basic.Label("Section:");
1252            gl.add(l, {row: 2, column: 0});
1253            e = new qx.ui.form.TextField();
1254            e.setReadOnly(true);
1255            this.gui_entity_section = e;
1256            gl.add(e, {row: 2, column: 1, colSpan: 2});
1257
1258            right_pane.add(gl);
1259
1260            var fr = new qx.ui.groupbox.GroupBox("Wikipedia article",
1261                "pf/image/wikipedia.png");
1262            fr.setLayout(new qx.ui.layout.Grow());
1263           
1264            var iframe = new qx.ui.embed.Iframe();
1265            iframe.addListener("load", function(ev) {
1266                    this.setCursor("default");
1267                });
1268           
1269            fr.add(iframe);
1270            right_pane.add(fr, {flex: 1});
1271           
1272            this.gui_wiki = iframe;
1273        },
1274       
1275        renderCompareTab : function()
1276        {
1277            var page_id = this.renderTabPage("Compare",
1278                "pf/image/tab-compare.png");
1279            page_id.setLayout(new qx.ui.layout.VBox(1));
1280           
1281            var bl = new qx.ui.container.Composite(new qx.ui.layout.VBox(10));
1282            page_id.add(bl, {height: "100%"});
1283           
1284            var rc = new qx.ui.container.Composite(new qx.ui.layout.HBox(10));
1285            bl.add(rc);
1286
1287            var l, e;
1288            l = new qx.ui.basic.Label("Dimension:");
1289            rc.add(l);
1290            e = new pf.ui.SelectBox;
1291            e.addItem("None", "none");
1292            e.addItem("Length", "length");
1293            e.addItem("Frequency", "frequency");
1294            e.addItem("Velocity", "velocity");
1295            e.addItem("Area", "area");
1296            e.addItem("Energy", "energy");
1297            e.addItem("Mass density", "mass_density");
1298            e.addItem("Pressure", "pressure");
1299            e.addItem("Power density", "power_density");
1300            e.addItem("Power spectral density", "spectral_power_density");
1301            e.addItem("Electric field", "efield");
1302            e.addListener("changeSelection", function(ev) {
1303                    var dimension = this.gui_compare_dim.getSelectedValue();
1304                    this.gui_compare_units.update(dimension,
1305                        this.prefs.units[dimension]);
1306                    this.updateFavoritesListView();
1307                    this.updateLegendListView();
1308                }, this);
1309            rc.add(e);
1310            this.gui_compare_dim = e;
1311           
1312            l = new qx.ui.basic.Label("Units:");
1313            rc.add(l);
1314            e = new pf.UnitSelector();
1315            e.update("none");
1316            e.addListener("changeSelection", function(ev) {
1317                    this.updateFavoritesListView();
1318                }, this);
1319            rc.add(e);
1320            this.gui_compare_units = e;
1321
1322            // table model
1323            var tm = new qx.ui.table.model.Simple();
1324            tm.setColumns([ "", "Name", "Section", "Value" ]);
1325           
1326            tm.setColumnEditable(0, false);
1327            tm.setColumnEditable(1, false);
1328            tm.setColumnEditable(2, false);
1329            tm.setColumnEditable(3, false);
1330           
1331            tm.setColumnSortable(0, false);
1332           
1333            tm.setSortMethods(3, function(row1, row2) {
1334                var obj1 = parseFloat(row1[arguments.callee.columnIndex]);
1335                var obj2 = parseFloat(row2[arguments.callee.columnIndex]);
1336                return (obj1 > obj2) ? 1 : ((obj1 == obj2) ? 0 : -1);
1337            });
1338           
1339            // table list
1340            var lv = new qx.ui.table.Table(tm);
1341
1342            lv.setStatusBarVisible(false);
1343            lv.setShowCellFocusIndicator(false);
1344            lv.setColumnVisibilityButtonVisible(false);
1345           
1346            lv.setColumnWidth(0,  24);
1347            lv.setColumnWidth(1, 300);
1348            lv.setColumnWidth(2, 120);
1349           
1350            var renderer = new qx.ui.table.cellrenderer.Image(16, 16);
1351            lv.getTableColumnModel().setDataCellRenderer(0, renderer);
1352
1353            bl.add(lv, {flex: 1});
1354           
1355            this.favoritesListView = lv;
1356        },
1357       
1358        drawAll : function(ev)
1359        {
1360            var canvas = this.canvas;
1361           
1362            canvas.setPrintable(true);
1363           
1364            var pname = this.guiParameter.getSelectedValue();
1365            var vmin = this.guiMinParam.getNumValue();
1366            var vmax = this.guiMaxParam.getNumValue();
1367            var npoints = this.guiParamPoints.getValue();
1368           
1369            if (npoints < 2 || !pname) {
1370                return;
1371            }
1372
1373            var dimension = this.gui_compare_dim.getSelectedValue();
1374            var scale = this.gui_compare_units.getSelectedValue();
1375
1376            var par0, au_f;
1377            var xlabel, ylabel;
1378            if (dimension == "none") {
1379                ylabel = "";
1380            } else {
1381                ylabel = this.gui_compare_dim.getSelectedLabel() + " (" +
1382                         this.gui_compare_units.getSelectedLabel() + ")";
1383            }
1384            switch (pname) {
1385            case "N_e":
1386                par0 = this.plasma.e.getN();
1387                au_f = pf.base.Bohr.n0;
1388                xlabel = "N<sub>e</sub> (cm<sup>-3</sup>)"
1389                break;
1390            case "T":
1391                par0 = this.plasma.e.getT();
1392                if (par0 != this.plasma.i.getT()) {
1393                    this.msgWindow.error("Cannot vary T since T<sub>e</sub> &ne; T<sub>i</sub>");
1394                    return;
1395                }
1396                if (par0 != this.plasma.r.getT()) {
1397                    this.msgWindow.error("Cannot vary T since T<sub>e</sub> &ne; T<sub>r</sub>");
1398                    return;
1399                }
1400                au_f = pf.base.Bohr.E0;
1401                xlabel = "T (eV)"
1402                break;
1403            case "T_e":
1404                par0 = this.plasma.e.getT();
1405                au_f = pf.base.Bohr.E0;
1406                xlabel = "T<sub>e</sub> (eV)"
1407                break;
1408            case "T_i":
1409                par0 = this.plasma.i.getT();
1410                au_f = pf.base.Bohr.E0;
1411                xlabel = "T<sub>i</sub> (eV)"
1412                break;
1413            case "T_r":
1414                par0 = this.plasma.r.getT();
1415                au_f = pf.base.Bohr.E0;
1416                xlabel = "T<sub>r</sub> (eV)"
1417                break;
1418            case "T_i,r":
1419                par0 = this.plasma.i.getT();
1420                if (par0 != this.plasma.r.getT()) {
1421                    this.msgWindow.error("Cannot vary T<sub>i,r</sub> since T<sub>i</sub> &ne; T<sub>r</sub>");
1422                    return;
1423                }
1424                au_f = pf.base.Bohr.E0;
1425                xlabel = "T<sub>i,r</sub> (eV)"
1426                break;
1427            case "P_r":
1428                par0 = this.plasma.P_r;
1429                au_f = 100;
1430                xlabel = "P<sub>r</sub> (%)"
1431                break;
1432            case "B":
1433                par0 = this.plasma.B;
1434                au_f = pf.base.Bohr.B0;
1435                xlabel = "B (T)"
1436                break;
1437            default:
1438                return;
1439            }
1440           
1441            if (par0 == 0) {
1442                this.msgWindow.error("Cannot vary a null parameter</sub>");
1443                return;
1444            }
1445            if (vmin >= vmax) {
1446                this.msgWindow.error("Min. scale must be less than max. one");
1447                return;
1448            }
1449            if (vmin <= 0) {
1450                this.msgWindow.error("Non-positive scale values are not allowed");
1451                return;
1452            }
1453           
1454            var x_au  = new Array;
1455            var xdata = new Array;
1456            for (var j = 0; j < npoints; j++) {
1457                var x = par0*(vmin + (vmax - vmin)*j/(npoints - 1));
1458                x_au.push(x);
1459                xdata.push(au_f*x);
1460            }
1461                       
1462            var wxmin = xdata[0];
1463            var wxmax = xdata[xdata.length - 1];
1464
1465            var wymin = 0;
1466            var wymax = 0;
1467
1468            this.sets = new Array;
1469            var first = true;
1470            for (var i = 0; i < this.favorites.length; i++) {
1471                var fav = this.favorites[i];
1472                var entity = fav.entity;
1473               
1474                if (entity.dimension != dimension) {
1475                    continue;
1476                }
1477               
1478                var s1    = fav.s1;
1479                var s2    = fav.s2;
1480                var vname = this.getEntityFullName(entity, s1, s2);
1481
1482                var set   = new Object;
1483                var ydata = new Array;
1484                for (var j = 0; j < npoints; j++) {
1485                    var par = x_au[j];
1486
1487                    switch (pname) {
1488                    case "N_e":
1489                        this.plasma.e.setN(par);
1490                        this.updatePlasmaParameters();
1491                        break;
1492                    case "T_e":
1493                        this.plasma.e.setT(par);
1494                        break;
1495                    case "T_i":
1496                        this.plasma.i.setT(par);
1497                        break;
1498                    case "T_r":
1499                        this.plasma.r.setT(par);
1500                        break;
1501                    case "T_i,r":
1502                        this.plasma.i.setT(par);
1503                        this.plasma.r.setT(par);
1504                        break;
1505                    case "T":
1506                        this.plasma.e.setT(par);
1507                        this.plasma.i.setT(par);
1508                        this.plasma.r.setT(par);
1509                        break;
1510                    case "P_r":
1511                        this.plasma.P_r = par;
1512                        this.updatePlasmaParameters();
1513                        break;
1514                    case "B":
1515                        this.plasma.B = par;
1516                        break;
1517                    }
1518                   
1519                    var value = scale*this.evaluateEntityValue(entity, s1, s2);
1520                   
1521                    if (first) {
1522                        wymin = value;
1523                        wymax = value;
1524                        first = false;
1525                    } else {
1526                        if (value < wymin) {
1527                            wymin = value;
1528                        }
1529                        if (value > wymax) {
1530                            wymax = value;
1531                        }
1532                    }
1533                   
1534                    ydata.push(value);
1535                }
1536                set.x = xdata;
1537                set.y = ydata;
1538                set.legend = vname;
1539                set.color = fav.color;
1540                this.sets.push(set);
1541            }
1542           
1543            // Restore parameter
1544            switch (pname) {
1545            case "N_e":
1546                this.plasma.e.setN(par0);
1547                this.updatePlasmaParameters();
1548                break;
1549            case "T_e":
1550                this.plasma.e.setT(par0);
1551                break;
1552            case "T_i":
1553                this.plasma.i.setT(par0);
1554                break;
1555            case "T_r":
1556                this.plasma.r.setT(par0);
1557                break;
1558            case "T_i,r":
1559                this.plasma.i.setT(par0);
1560                this.plasma.r.setT(par0);
1561                break;
1562            case "T":
1563                this.plasma.e.setT(par0);
1564                this.plasma.i.setT(par0);
1565                this.plasma.r.setT(par0);
1566                break;
1567            case "P_r":
1568                this.plasma.P_r = par0;
1569                this.updatePlasmaParameters();
1570                break;
1571            case "B":
1572                this.plasma.B = par0;
1573                break;
1574            }
1575           
1576            canvas.clear();
1577           
1578            canvas.setViewportCoordinates(0.15, 0.1, 0.9, 0.9);
1579            var dwx = Math.abs(wxmax - wxmin);
1580            if (dwx == 0) {
1581                dwx = wxmax;
1582            }
1583            var dwy = Math.abs(wymax - wymin);
1584            if (dwy == 0) {
1585                wymin = 0.0;
1586                if (wymax == 0) {
1587                    wymax = 1.0;
1588                } else {
1589                    wymax *= 2;
1590                }
1591            }
1592           
1593            // If Y max & min of the same sign and differ significantly, set
1594            // the smallest (by abs value) limit to 0
1595            var wymin_r, wymax_r;
1596            if (wymin > 0 && wymax/wymin > 3) {
1597                wymin_r = 0;
1598                wymax_r = wymax + 0.05*dwy;
1599            } else
1600            if (wymax < 0 && wymin/wymax > 3) {
1601                wymin_r = wymin - 0.05*dwy
1602                wymax_r = 0;
1603            } else {
1604                wymin_r = wymin < 0 ?
1605                    (wymin - 0.05*dwy) : Math.max(0, wymin - 0.05*dwy);
1606                wymax_r = wymax + 0.05*dwy;
1607            }
1608           
1609            var wxmin_r =
1610                wxmin < 0 ? (wxmin - 0.05*dwx) : Math.max(0, wxmin - 0.05*dwx);
1611            canvas.setWorldCoordinates(wxmin_r, wymin_r,
1612                wxmax + 0.05*dwx, wymax_r);
1613           
1614            // Draw frame
1615            canvas.setStroke(1);
1616            canvas.drawFrame("black");
1617
1618            // Mark initial value of the varied parameter
1619            canvas.setColor("#c0c0c0");
1620            canvas.setStroke(-1);
1621            canvas.drawPolyLineW([par0*au_f, par0*au_f], [wymin_r, wymax_r]);
1622           
1623            // Draw title
1624            canvas.drawTitle(this.prefs.currentConfigName, "black");
1625           
1626            // Draw axis ticks
1627            canvas.setStroke(1);
1628            canvas.drawTicks("x", "blue");
1629            canvas.drawTicks("y", "blue");
1630
1631            // Draw axis labels
1632            canvas.drawLabel("x", xlabel, "black");
1633            canvas.drawLabel("y", ylabel, "black");
1634           
1635            // Draw sets
1636            canvas.setStroke(2);
1637            for (var i = 0; i < this.sets.length; i++) {
1638                var set = this.sets[i];
1639                canvas.setColor(set.color);
1640                canvas.drawPolyLineW(set.x, set.y);
1641            }
1642           
1643            canvas.paint();
1644        },
1645
1646        showWikiPage : function(entity)
1647        {
1648            var url = "about:blank";
1649            if (entity && entity.wikiLink) {
1650                url = "http://en.wikipedia.org/w/index.php?title=" +
1651                      entity.wikiLink + "&printable=yes";
1652            }
1653           
1654            this.gui_wiki.setCursor("wait");
1655            this.gui_wiki.setSource(url);
1656        },
1657       
1658        loadWikiCB : function(ev)
1659        {
1660            var tree = this.entity_tree;
1661            var leaf = getSingleTreeSelectedItem(tree);
1662           
1663            if (!leaf) {
1664                return;
1665            }
1666           
1667            var entity = leaf.getUserData("entity");
1668           
1669            this.showWikiPage(entity);
1670        },
1671       
1672        drawCB : function(ev)
1673        {
1674            this.drawAll();
1675        },
1676       
1677        exportSet : function(set)
1678        {
1679            var str = "";
1680           
1681            str += "# legend: " + set.legend + "\n";
1682            str += "# color: "  + set.color + "\n";
1683
1684            var xdata = set.x;
1685            var ydata = set.y;
1686            var slen  = xdata.length;
1687
1688            for (var j = 0; j < slen; j++) {
1689                str += pf.util.Format.sprintf("%.6e\t%.6e\n",
1690                    xdata[j], ydata[j]);
1691            }
1692           
1693            return str;
1694        },
1695
1696        exportDataCB : function(ev)
1697        {
1698            if (!this.sets || !this.sets.length) {
1699                return false;
1700            }
1701           
1702            var str = "";
1703            for (var i = 0; i < this.sets.length; i++) {
1704                str += this.exportSet(this.sets[i]);
1705               
1706                if (i < this.sets.length - 1) {
1707                    str += "\n";
1708                }
1709            }
1710           
1711            var w = this.dataExportWindow;
1712
1713            var text_area = w.textArea;
1714           
1715            text_area.setValue(str);
1716
1717            w.open();
1718        },
1719       
1720        renderPlotTab : function()
1721        {
1722            var page_id = this.renderTabPage("Plot",
1723                "pf/image/tab-plot.png");
1724            page_id.setLayout(new qx.ui.layout.VBox);
1725
1726            var sp = new qx.ui.splitpane.Pane("horizontal");
1727            sp.setDecorator("main");
1728            page_id.add(sp, {height: "100%"});
1729                       
1730            var left_pane = new qx.ui.container.Composite(new qx.ui.layout.Grow);
1731            var right_pane = new qx.ui.container.Composite(new qx.ui.layout.VBox(4)).set({
1732              padding : 4
1733            });
1734
1735            sp.add(left_pane,  2);
1736            sp.add(right_pane, 1);
1737           
1738            var canvas = new pf.ui.canvas.Plotter();
1739            left_pane.add(canvas);
1740            this.canvas = canvas;
1741
1742            var layout = new qx.ui.layout.Grid(4, 6);
1743            layout.setColumnWidth(0, 100);
1744            layout.setColumnFlex(1, 1);
1745            var gl = new qx.ui.container.Composite(layout);
1746
1747            var l, e;
1748
1749            var btn = new qx.ui.form.Button("Redraw", "pf/image/tab-plot.png");
1750            btn.addListener("execute", this.drawCB, this);
1751            gl.add(btn, {row: 0, column: 0});
1752
1753            var btn = new qx.ui.form.Button("Export Data",
1754                "pf/image/export.png");
1755            btn.addListener("execute", this.exportDataCB, this);
1756            gl.add(btn, {row: 0, column: 1});
1757
1758            l = new qx.ui.basic.Label("Parameter to vary:");
1759            e = new pf.ui.SelectBox;
1760            e.addItem("N<sub>e</sub>",   "N_e", true);
1761            e.addItem("T",               "T");
1762            e.addItem("T<sub>e</sub>",   "T_e", true);
1763            e.addItem("T<sub>i</sub>",   "T_i", true);
1764            e.addItem("T<sub>r</sub>",   "T_r", true);
1765            e.addItem("T<sub>i,r</sub>", "T_i,r", true);
1766            e.addItem("P<sub>r</sub>",   "P_r", true);
1767            e.addItem("B",               "B");
1768            e.selectByValue("N_e");
1769            this.guiParameter = e;
1770            gl.add(l, {row: 1, column: 0});
1771            gl.add(e, {row: 1, column: 1});
1772
1773            l = new qx.ui.basic.Label("Minimum scale:");
1774            e = new pf.ui.TextField(0.5);
1775            this.guiMinParam = e;
1776            gl.add(l, {row: 2, column: 0});
1777            gl.add(e, {row: 2, column: 1});
1778
1779            l = new qx.ui.basic.Label("Maximum scale:");
1780            e = new pf.ui.TextField(2.0);
1781            this.guiMaxParam = e;
1782            gl.add(l, {row: 3, column: 0});
1783            gl.add(e, {row: 3, column: 1});
1784
1785            l = new qx.ui.basic.Label("Number of points:");
1786            e = new qx.ui.form.Spinner(2, 20, 100);
1787            this.guiParamPoints = e;
1788            gl.add(l, {row: 4, column: 0});
1789            gl.add(e, {row: 4, column: 1});
1790
1791            right_pane.add(gl);
1792
1793
1794
1795            var tm = new qx.ui.table.model.Simple();
1796            tm.setColumns(["", "Name", "Favorite"],
1797                          ["color", "name", "favorite"]);
1798           
1799            tm.setColumnEditable(0, false);
1800            tm.setColumnEditable(1, false);
1801           
1802            tm.setColumnSortable(0, false);
1803           
1804            // table list
1805            var lv = new qx.ui.table.Table(tm);
1806
1807            var cm = lv.getTableColumnModel();
1808            cm.setColumnVisible(2, false);
1809           
1810            lv.setStatusBarVisible(false);
1811            lv.setShowCellFocusIndicator(false);
1812            lv.setColumnVisibilityButtonVisible(false);
1813           
1814            lv.setColumnWidth(0,  22);
1815            lv.setColumnWidth(1, 220);
1816           
1817            var renderer = new pf.ui.table.cellrenderer.BgColor();
1818            lv.getTableColumnModel().setDataCellRenderer(0, renderer);
1819
1820            right_pane.add(lv, {flex: 1});
1821            this.legendListView = lv;
1822           
1823            var sm = lv.getSelectionModel();
1824           
1825            lv.addListener("dblclick", function(ev) {
1826                    ev.stopPropagation();
1827
1828                    if (sm.isSelectionEmpty()) {
1829                        return;
1830                    }
1831                   
1832                    var index = sm.getLeadSelectionIndex();
1833                    var item = tm.getRowDataAsMap(index);
1834
1835                    var favorite = item.favorite;
1836                    if (!favorite) {
1837                        return;
1838                    }
1839                    cpop.setUserData("favorite", null); // avoid loop call
1840                    cpop.setValue(favorite.color);
1841                    cpop.setUserData("favorite", favorite);
1842                   
1843                    cpop.placeToMouse(ev);
1844                    cpop.open();
1845                });
1846
1847            var cpop = new pf.ui.ColorPopup(this.colorMap);
1848            cpop.exclude();
1849
1850            this.doc.add(cpop);
1851
1852            cpop.addListener("changeValue", function(ev) {
1853                    var color = ev.getData();
1854                    var cpop = ev.getTarget();
1855                    var favorite = cpop.getUserData("favorite");
1856                    if (!favorite || !color) {
1857                        return;
1858                    }
1859                    favorite.color = color;
1860                    this.updateLegendListView();
1861                    this.drawAll();
1862                    this.saveFavorites();
1863                }, this);
1864       
1865            // drawAll is an expensive operation, so call it only when
1866            // this tab is selected
1867            this.tabview.addListener("changeSelection", function(ev) {
1868                    if (ev.getData()[0] == page_id) {
1869                        this.drawAll();
1870                    }
1871                }, this);
1872        },
1873
1874
1875        aboutCB : function(ev)
1876        {
1877            this.aboutWindow.open();
1878        },
1879       
1880        prefsCB : function(ev)
1881        {
1882            this.prefsWindow.open();
1883        },
1884       
1885        updateSaveLoadList : function()
1886        {
1887            var lv = this.saveLoadConfigList;
1888            var tm = lv.getTableModel();
1889           
1890            var configPtrs = this.prefs.configPtrs;
1891           
1892            var rowData = new Array();
1893
1894            var i;
1895            var d = new Date();
1896            var df = new qx.util.format.DateFormat("yyyy-MM-dd HH:mm:ss");
1897           
1898            for (i = 0; i < configPtrs.length; i++) {
1899                var configPtr = configPtrs[i];
1900
1901                d.setTime(configPtr.time);
1902
1903                rowData.push([configPtr.name, df.format(d)]);
1904            }
1905           
1906            tm.setData(rowData, false);
1907            var sidx = tm.getSortColumnIndex();
1908            tm.sortByColumn(sidx, tm.isSortAscending());
1909           
1910            lv.updateContent();
1911        },
1912       
1913        saveAsCB : function(ev)
1914        {
1915            var w = this.saveLoadWindow;
1916           
1917            this.updateSaveLoadList();
1918            this.saveLoadTextField.setValue(null);
1919            this.saveLoadTextField.setReadOnly(false);
1920           
1921            w.setCaption("Save configuration")
1922            w.setIcon("pf/image/save.png");
1923            w.setUserData("type", "save");
1924           
1925            w.open();
1926        },
1927       
1928        saveConfigCB : function(ev)
1929        {
1930            if (this.prefs.currentConfigName &&
1931                this.prefs.currentConfigName != "Untitled") {
1932                if (this.saveConfig(this.prefs.currentConfigName) != true) {
1933                    this.msgWindow.error("Save failed!");
1934                }
1935            } else {
1936                this.saveAsCB(ev);
1937            }
1938        },
1939       
1940        openCB : function(ev)
1941        {
1942            var w = this.saveLoadWindow;
1943           
1944            this.updateSaveLoadList();
1945            this.saveLoadTextField.setValue(null);
1946            this.saveLoadTextField.setReadOnly(true);
1947           
1948            w.setCaption("Open configuration")
1949            w.setIcon("pf/image/open.png");
1950            w.setUserData("type", "open");
1951           
1952            w.open();
1953        },
1954       
1955        restart : function(force)
1956        {
1957            if (force || this.intendedExit || !this.prefs.warnOnExit) {
1958                location.reload(true);
1959            } else {
1960                this.confirmDialog.confirm("Restart Plasma Formulary?",
1961                    function(yesno) {
1962                            if (yesno) {
1963                                this.intendedExit = true;
1964                                this.restart(true);
1965                            }
1966                        }, this);
1967            }
1968        },
1969       
1970        quit : function(force)
1971        {
1972            if (force || this.intendedExit || !this.prefs.warnOnExit) {
1973                window.close(true);
1974            } else {
1975                this.confirmDialog.confirm("Quit Plasma Formulary?",
1976                    function(yesno) {
1977                            if (yesno) {
1978                                this.intendedExit = true;
1979                                this.quit(true);
1980                            }
1981                        }, this);
1982            }
1983        },
1984       
1985        buildMenu : function()
1986        {
1987            var menubar = this.menubar;
1988           
1989            var submenu, btn, qc;
1990
1991            submenu = new qx.ui.menu.Menu;
1992            this.doc.add(submenu);
1993            qc = new qx.ui.core.Command("Ctrl+O");
1994            qc.addListener("execute", this.openCB, this);
1995            btn = new qx.ui.menu.Button("Open...", "pf/image/open.png", qc);
1996            submenu.add(btn);
1997            qc = new qx.ui.core.Command("Ctrl+S");
1998            qc.addListener("execute", this.saveConfigCB, this);
1999            btn = new qx.ui.menu.Button("Save", "pf/image/save.png", qc);
2000            submenu.add(btn);
2001            btn = new qx.ui.menu.Button("Save as...", "pf/image/save.png");
2002            btn.addListener("execute", this.saveAsCB, this);
2003            submenu.add(btn);
2004            submenu.add(new qx.ui.menu.Separator);
2005            qc = new qx.ui.core.Command("Ctrl+P");
2006            qc.addListener("execute", function(ev) {
2007                window.print();
2008            });
2009            btn = new qx.ui.menu.Button("Print...", "pf/image/print.png", qc);
2010            submenu.add(btn);
2011            submenu.add(new qx.ui.menu.Separator);
2012            qc = new qx.ui.core.Command("Ctrl+R");
2013            qc.addListener("execute", function(ev) {
2014                    this.restart(false);
2015                }, this);
2016            btn = new qx.ui.menu.Button("Restart", "pf/image/reset.png", qc);
2017            submenu.add(btn);
2018            submenu.add(new qx.ui.menu.Separator);
2019            qc = new qx.ui.core.Command("Ctrl+Q");
2020            qc.addListener("execute", function(ev) {
2021                    this.quit(false);
2022                }, this);
2023            btn = new qx.ui.menu.Button("Quit", "pf/image/exit.png", qc);
2024            submenu.add(btn);
2025               
2026            btn = new qx.ui.menubar.Button("File", null, submenu);
2027            menubar.add(btn);
2028
2029
2030            submenu = new qx.ui.menu.Menu;
2031            submenu.addListener("appear", editMenuCB, this);
2032            this.doc.add(submenu);
2033            btn = new qx.ui.menu.Button("Add to Favorites",
2034                "pf/image/favorite-add.png");
2035            btn.addListener("execute", addToFavCB, this);
2036            this.editMenuButtonAddToFav = btn;
2037            submenu.add(btn);
2038            btn = new qx.ui.menu.Button("Remove from Favorites",
2039                "pf/image/favorite-delete.png");
2040            btn.addListener("execute", removeFromFavCB, this);
2041            this.editMenuButtonRemFromFav = btn;
2042            submenu.add(btn);
2043            submenu.add(new qx.ui.menu.Separator);
2044            btn = new qx.ui.menu.Button("Preferences",
2045                "pf/image/preferences.png");
2046            btn.addListener("execute", this.prefsCB, this);
2047            submenu.add(btn);
2048
2049            btn = new qx.ui.menubar.Button("Edit", null, submenu);
2050            menubar.add(btn);
2051
2052
2053            submenu = new qx.ui.menu.Menu;
2054            submenu.addListener("appear", viewMenuCB, this);
2055
2056            var subMenu1 = new qx.ui.menu.Menu;
2057            btn = new qx.ui.menu.CheckBox("Fundamental");
2058            btn.setValue(this.showFundamental);
2059            btn.addListener("execute", showFundamentalCB, this);
2060            subMenu1.add(btn);
2061            btn = new qx.ui.menu.CheckBox("Spectroscopy");
2062            btn.setValue(this.showSpectroscopy);
2063            btn.addListener("execute", showSpectroscopyCB, this);
2064            subMenu1.add(btn);
2065            btn = new qx.ui.menu.CheckBox("Waves");
2066            btn.setValue(this.showWaves);
2067            btn.addListener("execute", showWavesCB, this);
2068            subMenu1.add(btn);
2069            btn = new qx.ui.menu.CheckBox("Collisions");
2070            btn.setValue(this.showCollisions);
2071            btn.addListener("execute", showCollisionsCB, this);
2072            subMenu1.add(btn);
2073            btn = new qx.ui.menu.CheckBox("Radiation");
2074            btn.setValue(this.showRadiation);
2075            btn.addListener("execute", showRadiationCB, this);
2076            subMenu1.add(btn);
2077            this.showSectionsButton = new qx.ui.menu.Button("Show Sections",
2078                null, null, subMenu1);
2079            submenu.add(this.showSectionsButton);
2080           
2081            submenu.add(new qx.ui.menu.Separator);
2082
2083            var subMenu2 = new qx.ui.menu.Menu;
2084            btn = new qx.ui.menu.CheckBox("Electrons");
2085            btn.setValue(this.showElectrons);
2086            btn.addListener("execute", showElectronsCB, this);
2087            subMenu2.add(btn);
2088            btn = new qx.ui.menu.CheckBox("Ions");
2089            btn.setValue(this.showIons);
2090            btn.addListener("execute", showIonsCB, this);
2091            subMenu2.add(btn);
2092            btn = new qx.ui.menu.CheckBox("Radiators");
2093            btn.setValue(this.showRadiators);
2094            btn.addListener("execute", showRadiatorsCB, this);
2095            subMenu2.add(btn);
2096            this.showSpeciesButton = new qx.ui.menu.Button("Show Species",
2097                null, null, subMenu2);
2098            submenu.add(this.showSpeciesButton);
2099           
2100            submenu.add(new qx.ui.menu.Separator);
2101            qc = new qx.ui.core.Command("Ctrl+W");
2102            qc.addListener("execute", this.loadWikiCB, this);
2103            btn = new qx.ui.menu.Button("Load Wikipedia Article",
2104                "pf/image/wikipedia.png", qc);
2105            submenu.add(btn);
2106            this.loadWikiButton = btn;
2107            this.doc.add(submenu);
2108            this.doc.add(subMenu1);
2109            this.doc.add(subMenu2);
2110
2111            submenu.add(new qx.ui.menu.Separator);
2112            qc = new qx.ui.core.Command("Ctrl+L");
2113            qc.addListener("execute", this.drawCB, this);
2114            btn = new qx.ui.menu.Button("Redraw Plot",
2115                "pf/image/tab-plot.png", qc);
2116            submenu.add(btn);
2117            this.redrawButton = btn;
2118           
2119           
2120            btn = new qx.ui.menubar.Button("View", null, submenu);
2121            menubar.add(btn);
2122
2123
2124            var nvOptions = {
2125                width: 850,
2126                scrollbars : true,
2127                resizable : true,
2128                menubar : false,
2129                status : false
2130            };
2131            submenu = new qx.ui.menu.Menu;
2132            this.doc.add(submenu);
2133            qc = new qx.ui.core.Command("F1");
2134            qc.addListener("execute", function(ev) {
2135                    var url = "resource/pf/html/ug.html";
2136                    var w = qx.bom.Window.open(url, null, nvOptions);
2137                }, this);
2138            btn = new qx.ui.menu.Button("Help Contents",
2139                "pf/image/help.png", qc);
2140            submenu.add(btn);
2141            btn = new qx.ui.menu.Button("Reference Paper",
2142                "pf/image/jinst.png");
2143            btn.addListener("execute", function (ev) {
2144                    var url = "http://dx.doi.org/10.1088/1748-0221/6/10/P10009";
2145                    var w = qx.bom.Window.open(url, null, nvOptions);
2146                }, this);
2147            submenu.add(btn);
2148            submenu.add(new qx.ui.menu.Separator);
2149            btn = new qx.ui.menu.Button("NRL Plasma Formulary",
2150                "pf/image/nrl.png");
2151            btn.addListener("execute", function (ev) {
2152                    var url = "http://wwwppd.nrl.navy.mil/nrlformulary/";
2153                    var w = qx.bom.Window.open(url, null, nvOptions);
2154                }, this);
2155            submenu.add(btn);
2156            btn = new qx.ui.menu.Button("Plasma at Wikipedia",
2157                "pf/image/wikipedia.png");
2158            btn.addListener("execute", function (ev) {
2159                    var url = "http://en.wikipedia.org/wiki/Plasma_%28physics%29";
2160                    var w = qx.bom.Window.open(url, null, nvOptions);
2161                }, this);
2162            submenu.add(btn);
2163            submenu.add(new qx.ui.menu.Separator);
2164            btn = new qx.ui.menu.Button("License Terms",
2165                "pf/image/gnu.png");
2166            btn.addListener("execute", function (ev) {
2167                    var url = "resource/pf/html/GPL.html";
2168                    var w = qx.bom.Window.open(url, null, nvOptions);
2169                }, this);
2170            submenu.add(btn);
2171            btn = new qx.ui.menu.Button("About...",
2172                "pf/image/about.png");
2173            btn.addListener("execute", this.aboutCB, this);
2174            submenu.add(btn);
2175
2176            btn = new qx.ui.menubar.Button("Help", null, submenu);
2177            menubar.add(btn);
2178        },
2179       
2180        getEntityById : function(id)
2181        {
2182            var len = plasma_entities.length;
2183           
2184            for (var i = 0; i < len; i++) {
2185                var entity = plasma_entities[i];
2186                if (entity.id == id) {
2187                    return entity;
2188                }
2189            }
2190           
2191            return null;
2192        },
2193       
2194        getSpeciesById : function(id)
2195        {
2196            switch (id) {
2197            case "e":
2198                return this.plasma.e;
2199                break;
2200            case "i":
2201                return this.plasma.i;
2202                break;
2203            case "r":
2204                return this.plasma.r;
2205                break;
2206            default:
2207                return null;
2208                break;
2209            }
2210        },
2211       
2212        nextColor : function()
2213        {
2214            var color = this.colorMap[this.ncolor];
2215            this.ncolor++;
2216            if (this.ncolor == this.colorMap.length) {
2217                this.ncolor = 0;
2218            }
2219           
2220            return color;
2221        },
2222
2223        exportFavorites : function()
2224        {
2225            var sfavs = new Array;
2226            var len = this.favorites.length;
2227           
2228            for (var k = 0; k < len; k++) {
2229                var fav  = this.favorites[k];
2230                var sfav = new Object;
2231                sfav.entity_id  = fav.entity.id;
2232                if (fav.s1) {
2233                    sfav.s1_id = fav.s1.id;
2234                } else {
2235                    sfav.s1_id = null;
2236                }
2237                if (fav.s2) {
2238                    sfav.s2_id = fav.s2.id;
2239                } else {
2240                    sfav.s2_id = null;
2241                }
2242                sfav.color     = fav.color;
2243                sfavs.push(sfav);
2244            }
2245           
2246            return sfavs;
2247        },
2248
2249        importFavorites : function(sfavs)
2250        {
2251            if (!sfavs) {
2252                return false;
2253            }
2254
2255            this.favorites = new Array;
2256           
2257            var len = sfavs.length;
2258            for (var k = 0; k < len; k++) {
2259                var sfav = sfavs[k];
2260                var fav  = new Object;
2261                fav.entity = this.getEntityById(sfav.entity_id);
2262                // old format
2263                if (sfav.species_id) {
2264                    fav.s1 = this.getSpeciesById(sfav.species_id);
2265                } else
2266                if (sfav.s1_id) {
2267                    fav.s1 = this.getSpeciesById(sfav.s1_id);
2268                }
2269
2270                if (sfav.s2_id) {
2271                    fav.s2 = this.getSpeciesById(sfav.s2_id);
2272                }
2273                fav.color = sfav.color;
2274
2275                if (fav.entity && fav.color) {
2276                    this.favorites.push(fav);
2277                }
2278            }
2279           
2280            return true;
2281        },
2282
2283        getConfig : function(name)
2284        {
2285            if (!name) {
2286                return null;
2287            }
2288
2289            var configPtrs = this.prefs.configPtrs;
2290           
2291            var i, configPtr = null;
2292            for (i = 0; i < configPtrs.length; i++) {
2293                if (configPtrs[i].name == name) {
2294                    configPtr = configPtrs[i];
2295                    return configPtr;
2296                    break;
2297                }
2298            }
2299           
2300            return null;
2301        },
2302       
2303        savePreferences : function()
2304        {
2305            if (this.prefs) {
2306                var prefstr = qx.lang.Json.stringify(this.prefs);
2307                qx.bom.Cookie.set("pf_prefs", prefstr, 3650);
2308            }
2309        },
2310       
2311        loadPreferences : function()
2312        {
2313            var prefstr = qx.bom.Cookie.get("pf_prefs");
2314           
2315            if (prefstr) {
2316                this.prefs = qx.lang.Json.parse(prefstr);
2317            }
2318           
2319            if (!this.prefs) {
2320                this.prefs = new Object;
2321            }
2322 
2323            if (undefined === this.prefs.saveFavsWithConfig) {
2324                this.prefs.saveFavsWithConfig = true;
2325            }
2326           
2327            if (undefined === this.prefs.rememberWindowSize) {
2328                this.prefs.rememberWindowSize = false;
2329            }
2330
2331            if (undefined === this.prefs.autoLoadWiki) {
2332                this.prefs.autoLoadWiki = true;
2333            }
2334           
2335            if (undefined === this.prefs.warnOnExit) {
2336                this.prefs.warnOnExit = true;
2337            }
2338           
2339            if (!this.prefs.units) {
2340                this.prefs.units = new Object;
2341            }
2342           
2343            if (!this.prefs.currentConfigName) {
2344                this.prefs.currentConfigName = "Untitled";
2345            }
2346           
2347            if (!this.prefs.configPtrs) {
2348                this.prefs.configPtrs = new Array;
2349            }
2350        },
2351       
2352        saveFavorites : function()
2353        {
2354            var sfavs = this.exportFavorites();
2355           
2356            var favstr = qx.lang.Json.stringify(sfavs);
2357           
2358            qx.bom.Cookie.set("pf_favs", favstr, 3650);
2359        },
2360       
2361        loadFavorites : function()
2362        {
2363            this.favorites = new Array;
2364           
2365            var favstr = qx.bom.Cookie.get("pf_favs");
2366           
2367            if (favstr) {
2368                var sfavs = qx.lang.Json.parse(favstr);
2369               
2370                this.importFavorites(sfavs);
2371            }
2372        },
2373       
2374        saveConfig : function(name)
2375        {
2376            if (!name) {
2377                return false;
2378            }
2379
2380            var configPtr = this.getConfig(name);
2381           
2382            var d = new Date();
2383            var time = d.getTime();
2384           
2385            if (!configPtr) {
2386                configPtr = new Object;
2387                configPtr.name = name;
2388                configPtr.hash = time;
2389                this.prefs.configPtrs.push(configPtr);
2390            }
2391           
2392            configPtr.time = time;
2393           
2394            var cookie_name = "pf_config_" + configPtr.hash;
2395           
2396            var config = new Object;
2397           
2398            // version of config format
2399            config.format_v = 1;
2400           
2401            config.N_e = this.plasma.e.getN();
2402
2403            config.T_e = this.plasma.e.getT();
2404            config.T_i = this.plasma.i.getT();
2405            config.T_r = this.plasma.r.getT();
2406
2407            config.M_i = this.plasma.i.getM();
2408            config.M_r = this.plasma.r.getM();
2409           
2410            config.Q_i = this.plasma.i.getQ();
2411            config.Q_r = this.plasma.r.getQ();
2412
2413            config.P_r = this.plasma.P_r;
2414
2415            config.B   = this.plasma.B  ;
2416
2417            config.n_u = this.plasma.r.getN_u();
2418            config.n_l = this.plasma.r.getN_l();
2419           
2420            if (this.prefs.saveFavsWithConfig) {
2421                config.favorites = this.exportFavorites();
2422            }
2423           
2424            var configstr = qx.lang.Json.stringify(config);
2425            qx.bom.Cookie.set(cookie_name, configstr, 3650);
2426           
2427            this.prefs.currentConfigName = name;
2428            this.savePreferences();
2429           
2430            return true;
2431        },
2432       
2433        loadConfig : function(name)
2434        {
2435            var configPtr = this.getConfig(name);
2436            if (!configPtr) {
2437                return false;
2438            }
2439
2440            var cookie_name = "pf_config_" + configPtr.hash;
2441
2442            var configstr = qx.bom.Cookie.get(cookie_name);
2443            if (!configstr) {
2444                // Cookie was deleted???
2445                qx.lang.Array.remove(this.prefs.configPtrs, configPtr);
2446                return false;
2447            }
2448
2449            var config = qx.lang.Json.parse(configstr);
2450           
2451            if (config) {
2452                var au_fn, au_fT, au_fM, au_fB;
2453                if (!config.format_v) {
2454                    // old format, rescale data
2455                    au_fn = pf.base.Bohr.n0;
2456                    au_fT = pf.base.Bohr.E0;
2457                    au_fM = 1/pf.base.Bohr.m_p;
2458                    au_fB = pf.base.Bohr.B0;
2459                } else {
2460                    au_fn = 1;
2461                    au_fT = 1;
2462                    au_fM = 1;
2463                    au_fB = 1;
2464                }
2465               
2466                this.plasma.e.setN(config.N_e/au_fn);
2467
2468                this.plasma.e.setT(config.T_e/au_fT);
2469                this.plasma.i.setT(config.T_i/au_fT);
2470                this.plasma.r.setT(config.T_r/au_fT);
2471
2472                this.plasma.i.setM(config.M_i/au_fM);
2473                this.plasma.r.setM(config.M_r/au_fM);
2474
2475                this.plasma.i.setQ(config.Q_i);
2476                this.plasma.r.setQ(config.Q_r);
2477
2478                this.plasma.P_r = config.P_r;
2479
2480                this.plasma.B   = config.B/au_fB;
2481
2482                this.plasma.r.setN_u(config.n_u);
2483                this.plasma.r.setN_l(config.n_l);
2484               
2485                if (this.prefs.saveFavsWithConfig && config.favorites) {
2486                    this.importFavorites(config.favorites);
2487                }
2488
2489                this.prefs.currentConfigName = name;
2490               
2491                this.savePreferences();
2492
2493                return true;
2494            } else {
2495                return false;
2496            }
2497        },
2498       
2499        removeConfig : function(name)
2500        {
2501            var configPtr = this.getConfig(name);
2502            if (configPtr) {
2503                qx.lang.Array.remove(this.prefs.configPtrs, configPtr);
2504                var cookie_name = "pf_config_" + configPtr.hash;
2505                qx.bom.Cookie.del(cookie_name);
2506                this.savePreferences();
2507            }
2508        },
2509       
2510        renameConfig : function(oldname, newname)
2511        {
2512            var configPtr = this.getConfig(oldname);
2513            if (configPtr) {
2514                configPtr.name = newname;
2515                this.savePreferences();
2516            }
2517        },
2518       
2519        createSaveLoadDialog : function()
2520        {
2521            var w, layout, rc1, e, btn;
2522            // "Save as..." dialog
2523            w = new pf.ui.DialogWindow();
2524            w.setLayout(new qx.ui.layout.VBox(0));
2525            w.setContentPadding(0);
2526               
2527            this.doc.add(w);
2528            this.saveLoadWindow = w;
2529
2530            var tb = new qx.ui.toolbar.ToolBar();
2531            var tbpart = new qx.ui.toolbar.Part();
2532            var btn_delete = new qx.ui.toolbar.Button("Delete",
2533                "pf/image/delete.png");
2534            var btn_rename = new qx.ui.toolbar.Button("Rename",
2535                "pf/image/rename.png");
2536            var btn_export = new qx.ui.toolbar.Button("Export",
2537                "pf/image/export.png");
2538            var btn_import = new qx.ui.toolbar.Button("Import",
2539                "pf/image/import.png");
2540            btn_delete.setEnabled(false);
2541            btn_rename.setEnabled(false);
2542            btn_export.setEnabled(false);
2543            tbpart.add(btn_delete);
2544            tbpart.add(btn_rename);
2545            tbpart.add(new qx.ui.toolbar.Separator());
2546            tbpart.add(btn_export);
2547            tbpart.add(btn_import);
2548            tb.add(tbpart);
2549            w.add(tb);
2550
2551            // table model
2552            var tm = new qx.ui.table.model.Simple();
2553            tm.setColumns([ "Configuration", "Last Modified" ]);
2554           
2555            tm.setColumnEditable(0, false);
2556            tm.setColumnEditable(1, false);
2557           
2558            // table list
2559            var lv = new qx.ui.table.Table(tm);
2560            lv.set({
2561                height: 250
2562            });
2563
2564            lv.setStatusBarVisible(false);
2565            lv.setShowCellFocusIndicator(false);
2566            lv.setColumnVisibilityButtonVisible(false);
2567           
2568            lv.setColumnWidth(0, 250);
2569            lv.setColumnWidth(1, 150);
2570           
2571            var renderer = new qx.ui.table.cellrenderer.Html();
2572            lv.getTableColumnModel().setDataCellRenderer(0, renderer);
2573           
2574            this.saveLoadConfigList = lv;
2575            w.add(lv);
2576
2577            var sm = lv.getSelectionModel();
2578            sm.setSelectionMode(qx.ui.table.selection.Model.SINGLE_SELECTION);
2579           
2580            // Export/import window
2581            var eiw = new pf.ui.DialogWindow();
2582            eiw.set({
2583                width:  350,
2584                height: 400
2585            });
2586            eiw.setResizable(true);
2587            eiw.setLayout(new qx.ui.layout.VBox(0));
2588            eiw.setContentPadding(0);
2589           
2590            var note = new qx.ui.basic.Label("Label", {height: 20});
2591            eiw.add(note);
2592               
2593            var text_area = new qx.ui.form.TextArea();
2594            text_area.setWrap(true);
2595            eiw.add(text_area, {flex: 1});
2596
2597
2598            layout = new qx.ui.layout.HBox(10, "right");
2599            rc1 = new qx.ui.container.Composite(layout);
2600            rc1.setMargin(10, 10, 10, 10);
2601            eiw.add(rc1);
2602
2603            btn = new qx.ui.form.Button("Cancel", "pf/image/cancel.png");
2604            btn.addListener("execute", function(ev) {
2605                    eiw.close();
2606                }, this);
2607            rc1.add(btn);
2608
2609            btn = new qx.ui.form.Button("OK", "pf/image/ok.png");
2610            btn.addListener("execute", function(ev) {
2611                    var type = eiw.getUserData("type");
2612                    if (type == "import") {
2613                        var configstr = text_area.getValue();
2614                       
2615                        var config;
2616                        try {
2617                            config = qx.lang.Json.parse(configstr);
2618                        } catch (err) {
2619                            this.error(err);
2620                        }
2621
2622                        if (config) {
2623                            var name = config.name;
2624                           
2625                            var d = new Date();
2626                            var time = d.getTime();
2627           
2628                            var configPtr = new Object;
2629                            configPtr.name = name;
2630                            configPtr.hash = time;
2631                            configPtr.time = time;
2632                           
2633                            this.prefs.configPtrs.push(configPtr);
2634                           
2635                            var cookie_name = "pf_config_" + configPtr.hash;
2636                            qx.bom.Cookie.set(cookie_name, configstr, 3650);
2637                           
2638                            this.savePreferences();
2639                            this.updateSaveLoadList();
2640                           
2641                            eiw.close();
2642                        } else {
2643                            this.msgWindow.error("Cannot parse the configuration!");
2644                        }
2645                    } else {
2646                        eiw.close();
2647                    }
2648                }, this);
2649            rc1.add(btn);
2650           
2651            this.doc.add(eiw);
2652
2653            btn_delete.addListener("execute", function(ev) {
2654                    if (!sm.isSelectionEmpty()) {
2655                        var index = sm.getLeadSelectionIndex();
2656                        var rowData = tm.getRowData(index);
2657                        var name = rowData[0];
2658                        if (name == this.prefs.currentConfigName) {
2659                            this.msgWindow.error("Cannot delete current configuration!");
2660                        } else {
2661                            this.confirmDialog.confirm("Delete \"" + name + "\"?",
2662                                function(yesno) {
2663                                        if (yesno) {
2664                                            this.removeConfig(name);
2665                                            this.updateSaveLoadList();
2666                                        }
2667                                    }, this);
2668                        }
2669                    }
2670                }, this);
2671
2672            btn_rename.addListener("execute", function(ev) {
2673                    if (!sm.isSelectionEmpty()) {
2674                        var index = sm.getLeadSelectionIndex();
2675                        var rowData = tm.getRowData(index);
2676                        var name = rowData[0];
2677                       
2678                        this.promptDialog.prompt("Rename \"" + name + "\" to",
2679                            name, function(newname) {
2680                                    if (newname  && newname != name) {
2681                                        this.renameConfig(name, newname);
2682                                        this.updateSaveLoadList();
2683                                        if (name == this.prefs.currentConfigName) {
2684                                            this.prefs.currentConfigName = newname;
2685                                            this.gui_configName.setLabel(newname);
2686                                        }
2687                                        this.saveLoadTextField.setValue(newname);
2688                                    }
2689                                }, this);
2690                    }
2691                }, this);
2692
2693            btn_export.addListener("execute", function(ev) {
2694                    if (!sm.isSelectionEmpty()) {
2695                        var index = sm.getLeadSelectionIndex();
2696                        var rowData = tm.getRowData(index);
2697                        var name = rowData[0];
2698                       
2699                        var configPtr = this.getConfig(name);
2700                        if (!configPtr) {
2701                            return false;
2702                        }
2703
2704                        var cookie_name = "pf_config_" + configPtr.hash;
2705
2706                        var configstr = qx.bom.Cookie.get(cookie_name);
2707                        if (!configstr) {
2708                            return false;
2709                        }
2710
2711                        var config = qx.lang.Json.parse(configstr);
2712                        config.name = name;
2713
2714                        text_area.setValue(
2715                            qx.lang.Json.stringify(config, undefined, 4));
2716                       
2717                        eiw.setCaption("Export configuration")
2718                        eiw.setIcon("pf/image/export.png");
2719                        eiw.setUserData("type", "export");
2720                       
2721                        text_area.setReadOnly(true);
2722                       
2723                        var nstr =
2724                            "Copy the contents below to a text editor and save";
2725                        note.setValue(nstr);
2726                       
2727                        eiw.open();
2728                    }
2729                }, this);
2730
2731            btn_import.addListener("execute", function(ev) {
2732                    eiw.setCaption("Import configuration")
2733                    eiw.setIcon("pf/image/import.png");
2734                    eiw.setUserData("type", "import");
2735
2736                    text_area.setReadOnly(false);
2737                    text_area.setValue("");
2738
2739                    var nstr =
2740                        "Copy a previously saved config to the space below";
2741                    note.setValue(nstr);
2742
2743                    eiw.open();
2744                }, this);
2745
2746            e = new qx.ui.form.TextField();
2747            e.setMarginTop(1);
2748            w.add(e);
2749            this.saveLoadTextField = e;
2750           
2751            sm.addListener("changeSelection", function(ev) {
2752                    if (sm.isSelectionEmpty()) {
2753                        e.setValue(null);
2754                        btn_delete.setEnabled(false);
2755                        btn_rename.setEnabled(false);
2756                        btn_export.setEnabled(false);
2757                    } else {
2758                        var index = sm.getLeadSelectionIndex();
2759                        var rowData = tm.getRowData(index);
2760                        e.setValue(rowData[0]);
2761                        btn_rename.setEnabled(true);
2762                        btn_delete.setEnabled(true);
2763                        btn_export.setEnabled(true);
2764                    }
2765                });
2766           
2767            layout = new qx.ui.layout.HBox(10, "right");
2768            rc1 = new qx.ui.container.Composite(layout);
2769            rc1.setMargin(10, 10, 10, 10);
2770            w.add(rc1);
2771
2772            btn = new qx.ui.form.Button("Cancel",
2773                "pf/image/cancel.png");
2774            btn.addListener("execute", function(ev) {
2775                    this.saveLoadWindow.close();
2776                }, this);
2777            rc1.add(btn);
2778
2779            btn = new qx.ui.form.Button("OK",
2780                "pf/image/ok.png");
2781            btn.setEnabled(false);
2782            btn.addListener("execute", function(ev) {
2783                    var cfgname = this.saveLoadTextField.getValue(); 
2784                    if (!cfgname) {
2785                        this.msgWindow.error("Please enter a name!");
2786                    } else {
2787                        var type = w.getUserData("type");
2788                        if (type == "save") {
2789                            if (this.saveConfig(cfgname) == true) {
2790                                this.saveLoadWindow.close();
2791                                if (this.prefs.currentConfigName) {
2792                                    this.gui_configName.setLabel(this.prefs.currentConfigName);
2793                                }
2794                            } else {
2795                                this.msgWindow.error("Save failed!");
2796                            }
2797                        } else {
2798                            if (this.loadConfig(cfgname) == true) {
2799                                this.updatePlasmaParameters();
2800                                this.updateGUI();
2801                                if (this.prefs.saveFavsWithConfig) {
2802                                    this.rePopulateTree();
2803                                }
2804                                this.drawAll();
2805                                this.saveLoadWindow.close();
2806                            } else {
2807                                this.msgWindow.error("Load failed!");
2808                            }
2809                        }
2810                    }
2811                }, this);
2812            rc1.add(btn);
2813
2814            e.setLiveUpdate(true);
2815            e.addListener("changeValue", function(ev) {
2816                    var name = this.getValue();
2817                    btn.setEnabled(null != name && name.length != 0);
2818                });
2819        },
2820
2821        createPrefsDialog : function()
2822        {
2823            // "Preferences..." dialog
2824            var w = new pf.ui.DialogWindow("Preferences",
2825                "pf/image/preferences.png");
2826            w.setLayout(new qx.ui.layout.VBox(10));
2827
2828            this.doc.add(w);
2829            this.prefsWindow = w;
2830           
2831            var fr, l, e;
2832
2833            fr = new qx.ui.groupbox.GroupBox("General");
2834            fr.setLayout(new qx.ui.layout.VBox(10));
2835            w.add(fr);
2836
2837            e = new qx.ui.form.CheckBox("Save favorites with configurations");
2838            e.setValue(this.prefs.saveFavsWithConfig);
2839            e.addListener("changeValue", function(ev) {
2840                this.prefs.saveFavsWithConfig = ev.getTarget().getValue();
2841                this.savePreferences();
2842            }, this);
2843            fr.add(e);
2844           
2845            fr = new qx.ui.groupbox.GroupBox("Default units");
2846            fr.setLayout(new qx.ui.layout.HBox(10));
2847            w.add(fr);
2848           
2849            var unit_cb_enabled = false;
2850           
2851            l = new qx.ui.basic.Label("Dimension:");
2852            e = new pf.ui.SelectBox;
2853            e.addItem("Length", "length");
2854            e.addItem("Frequency", "frequency");
2855            e.addItem("Velocity", "velocity");
2856            e.addItem("Energy", "energy");
2857            e.addItem("Mass density", "mass_density");
2858            e.addItem("Pressure", "pressure");
2859            e.addItem("Area", "area");
2860            e.addItem("Power density", "power_density");
2861            e.addItem("Power spectral density", "spectral_power_density");
2862            e.addItem("Electric field", "efield");
2863            e.addListener("changeSelection", function(ev) {
2864                    var dimension = ev.getTarget().getSelectedValue();
2865                    unit_cb_enabled = false;
2866                    this.gui_prefs_units.update(dimension,
2867                        this.prefs.units[dimension]);
2868                    unit_cb_enabled = true;
2869                }, this);
2870            fr.add(l);
2871            fr.add(e);
2872            this.gui_prefs_dim = e;
2873
2874            l = new qx.ui.basic.Label("Units:");
2875            e = new pf.UnitSelector();
2876            e.addListener("changeSelection", function(ev) {
2877                    if (unit_cb_enabled) {
2878                        var dimension = this.gui_prefs_dim.getSelectedValue();
2879                        var units = ev.getTarget().getSelectedValue();
2880                        this.prefs.units[dimension] = units;
2881                        this.savePreferences();
2882                    }
2883                }, this);
2884            fr.add(l);
2885            fr.add(e);
2886            e.update("length", this.prefs.units["length"]);
2887            this.gui_prefs_units = e;
2888           
2889            unit_cb_enabled = true;
2890
2891            fr = new qx.ui.groupbox.GroupBox("Interface");
2892            fr.setLayout(new qx.ui.layout.VBox(10));
2893            w.add(fr);
2894
2895            e = new qx.ui.form.CheckBox("Load Wikipedia articles automatically");
2896            e.setValue(this.prefs.autoLoadWiki);
2897            e.addListener("changeValue", function(ev) {
2898                this.prefs.autoLoadWiki = ev.getTarget().getValue();
2899                this.savePreferences();
2900            }, this);
2901            fr.add(e);
2902
2903            e = new qx.ui.form.CheckBox("Remember window dimensions on exit");
2904            e.setValue(this.prefs.rememberWindowSize);
2905            e.addListener("changeValue", function(ev) {
2906                this.prefs.rememberWindowSize = ev.getTarget().getValue();
2907                this.savePreferences();
2908            }, this);
2909            fr.add(e);
2910
2911            e = new qx.ui.form.CheckBox("Warn on exit or restart");
2912            e.setValue(this.prefs.warnOnExit);
2913            e.addListener("changeValue", function(ev) {
2914                this.prefs.warnOnExit = ev.getTarget().getValue();
2915                this.savePreferences();
2916            }, this);
2917            fr.add(e);
2918
2919            fr = new qx.ui.groupbox.GroupBox("Theme");
2920            fr.setLayout(new qx.ui.layout.VBox(10));
2921            w.add(fr);
2922           
2923            var btn1 = new qx.ui.form.RadioButton("Modern");
2924            btn1.setModel("modern");
2925            var btn2 = new qx.ui.form.RadioButton("Classic");
2926            btn2.setModel("classic");
2927            var btn3 = new qx.ui.form.RadioButton("Simple");
2928            btn3.setModel("simple");
2929            var btn4 = new qx.ui.form.RadioButton("Indigo");
2930            btn4.setModel("indigo");
2931           
2932            fr.add(btn1);
2933            fr.add(btn2);
2934            fr.add(btn3);
2935            fr.add(btn4);
2936           
2937            var rm = new qx.ui.form.RadioGroup(btn1, btn2, btn3, btn4);
2938            var sels;
2939            switch (this.prefs.themeName) {
2940            case "classic":
2941                sels = new Array(btn2);
2942                break;
2943            case "simple":
2944                sels = new Array(btn3);
2945                break;
2946            case "indigo":
2947                sels = new Array(btn4);
2948                break;
2949            default:
2950                sels = new Array(btn1);
2951                break;
2952            }
2953            rm.setSelection(sels);
2954            rm.addListener("changeSelection", function(ev) {
2955                    var btn = ev.getData()[0];
2956                    this.prefs.themeName = btn.getModel();
2957                    this.savePreferences();
2958                   
2959                    this.msgWindow.info("New theme will be applied after restart of the application");
2960                }, this);
2961
2962        },
2963
2964        createDataExportDialog : function()
2965        {
2966            // Data export window
2967            var w = new pf.ui.DialogWindow();
2968            w.set({
2969                width:  350,
2970                height: 400
2971            });
2972            w.setResizable(true);
2973            w.setLayout(new qx.ui.layout.VBox(0));
2974            w.setContentPadding(0);
2975           
2976            var nstr = "Copy the contents below to a text editor and save";
2977            var note = new qx.ui.basic.Label(nstr, {height: 20});
2978            w.add(note);
2979               
2980            var text_area = new qx.ui.form.TextArea();
2981            text_area.setWrap(true);
2982            text_area.setReadOnly(true);
2983           
2984            w.add(text_area, {flex: 1});
2985
2986            w.setCaption("Export plot data")
2987            w.setIcon("pf/image/export.png");
2988           
2989            w.textArea = text_area;
2990           
2991            this.dataExportWindow = w;
2992        },           
2993
2994        applyTheme : function()
2995        {
2996            var theme;
2997            switch (this.prefs.themeName) {
2998            case "classic":
2999                theme = pf.theme.Classic;
3000                break;
3001            case "simple":
3002                theme = qx.theme.Simple;
3003                break;
3004            case "indigo":
3005                theme = qx.theme.Indigo;
3006                break;
3007            default:
3008                theme = pf.theme.Modern;
3009                break;
3010            }
3011            var thm = qx.theme.manager.Meta.getInstance();
3012            thm.setTheme(theme);
3013        },
3014
3015        main : function(e)
3016        {
3017            this.base(arguments);
3018
3019            // Enable logging in debug variant
3020            if (qx.core.Environment.get("qx.debug")) {
3021                // support native logging capabilities, e.g. Firebug
3022                qx.log.appender.Native;
3023                // support additional cross-browser console. (Press F7)
3024                qx.log.appender.Console;
3025            }
3026           
3027            this.doc = this.getRoot();
3028           
3029            // Load prefs
3030            this.loadPreferences();
3031           
3032            // Apply theme
3033            this.applyTheme();
3034           
3035            if (this.prefs.rememberWindowSize && this.prefs.dims) {
3036                self.resizeTo(this.prefs.dims.width, this.prefs.dims.height);
3037            }
3038
3039            this.plasma = new pf.Plasma();
3040           
3041            // Load config from the previous session
3042            if (this.prefs.currentConfigName) {
3043                this.loadConfig(this.prefs.currentConfigName);
3044            }
3045           
3046            if (this.updatePlasmaParameters() != true) {
3047                this.error("Error updating plasma parameters!");
3048            }
3049           
3050            // Favorites
3051            this.loadFavorites();
3052           
3053            this.colorMap = new Array("red", "blue", "green", "orange",
3054                "brown", "olive", "teal", "magenta", "gray", "black");
3055            this.ncolor = 0;
3056
3057            // Top-level container
3058            var layout = new qx.ui.layout.VBox;
3059            this.bl_top = new qx.ui.container.Composite(layout);
3060
3061            this.doc.add(this.bl_top, {width :"100%", height: "100%"});
3062
3063            // The menubar
3064            this.menubar = new qx.ui.menubar.MenuBar;
3065            this.bl_top.add(this.menubar);
3066           
3067            // The menu items
3068            this.buildMenu();
3069           
3070            this.tabview = new qx.ui.tabview.TabView;
3071            this.tabview.setContentPadding(6);
3072           
3073            this.bl_top.add(this.tabview, {flex: 1});
3074            // The "Parameters" tab
3075            this.renderParametersTab();
3076           
3077            // The "Explorer" tab
3078            this.renderExplorerTab();
3079           
3080            // The "Compare" tab
3081            this.renderCompareTab();
3082            this.updateFavoritesListView();
3083           
3084            // The "Plot" tab
3085            this.renderPlotTab();
3086            this.updateLegendListView();
3087           
3088            // "Preferences" dialog
3089            this.createPrefsDialog();
3090
3091            // "Save as" dialog
3092            this.createSaveLoadDialog();
3093
3094            // Export data dialog
3095            this.createDataExportDialog();
3096
3097            // "About..." dialog
3098            var w = new pf.ui.DialogWindow("About Plasma Formulary",
3099                "pf/image/about.png");
3100            w.setLayout(new qx.ui.layout.VBox(10));
3101
3102            var pf_version = qx.core.Environment.get("pf.version");
3103            var qx_version = qx.core.Environment.get("qx.version");
3104            var str = 'Plasma Formulary Interactive '            +
3105                      pf_version + '.<br/>'                      +
3106                      '<p>Created by Evgeny Stambulchik.</p>'    +
3107                      'GUI built with the qooxdoo-' + qx_version +
3108                      ' toolkit.<br/>'                           + 
3109                      'Using Walter Zorn jsGraphics for drawing.';
3110
3111            var a = new qx.ui.basic.Atom(str);
3112            a.setRich(true);
3113            w.add(a);
3114
3115            this.doc.add(w);
3116            this.aboutWindow = w;
3117           
3118            this.msgWindow = new pf.ui.MessageWindow();
3119            this.doc.add(this.msgWindow);
3120            this.confirmDialog = new pf.ui.ConfirmDialog();
3121            this.doc.add(this.confirmDialog);
3122            this.promptDialog = new pf.ui.PromptDialog();
3123            this.doc.add(this.promptDialog);
3124           
3125            // Handle resize events
3126            this.doc.addListener("resize", function(e) {
3127                if (this.prefs.rememberWindowSize) {
3128                    this.prefs.dims = this.doc.getInnerSize();
3129                    this.savePreferences();
3130                }
3131                this.drawAll();
3132            }, this);
3133        },
3134   
3135
3136        close : function(e)
3137        {
3138            this.base(arguments);
3139           
3140            // Prompt user
3141            if (this.prefs.warnOnExit && !this.intendedExit) {
3142                return "This will end your Plasma Formulary session.";
3143            }
3144        }
3145    }
3146});
Note: See TracBrowser for help on using the repository browser.