source: PSPA/Interface_Web/trunk/pspaWT/sources/userInterface/src/GWt_pspaApplication.cc @ 479

Last change on this file since 479 was 479, checked in by garnier, 10 years ago

Modification en vue du passage de Parmela. Restauration du fichier Phyl ok

File size: 20.6 KB
Line 
1#include <stdio.h>
2#include <ctime>
3
4#include "GWt_pspaApplication.h"
5#include "GWt_draggableImage.h"
6#include "GWt_abstractElementFactory.h"
7#include "GWt_serverFileSelector.h"
8#include "GWt_accelerator.h"
9#include "particleBeam.h"
10#include "bareParticle.h"
11#include "nomDeLogiciel.h"
12#include "mixedTools.h"
13#include "nomdElements.h"
14#include "environmentVariables.h"
15#include "trivaluedBool.h"
16
17#include <Wt/WGridLayout>
18#include <Wt/WVBoxLayout>
19#include <Wt/WHBoxLayout>
20#include <Wt/WImage>
21#include <Wt/WMenu>
22#include <Wt/WStackedWidget>
23#include <Wt/WBreak>
24#include <Wt/WStandardItemModel>
25#include <Wt/WFileUpload>
26#include <Wt/WPainter>
27#include <Wt/WScrollArea>
28#include <Wt/WRadioButton>
29#include <Wt/WMessageBox>
30#include <Wt/WScrollArea>
31#include <Wt/WLabel>
32
33#define HAS_IMAGEMAGIC 1
34
35using namespace Wt::Chart;
36
37/*
38 * The env argument contains information about the new session, and
39 * the initial request. It must be passed to the WApplication
40 * constructor so it is typically also an argument for your custom
41 * application constructor.
42 */
43
44PspaApplication::PspaApplication(const WEnvironment& env) : 
45  WApplication(env),
46  applicationDefaultTitle_("portail PSPA"),
47  extensionFile_(0)
48{
49  workingDir_ = WApplication::docRoot()+ "/"+WORKINGAREA;
50  nameOfCase_ = "pspa"; // default
51   
52  setTitle(applicationDefaultTitle_);  // application title
53  if (!wApp->environment().javaScript()) {
54    new WText("<i>This examples requires that javascript support is enabled.</i>",root());
55  }
56   
57  // register the absractElementFactory
58  abstractElementFactory_ = new GWt_abstractElementFactory();
59  abstractElementFactory_->setRFGunEnable(true);
60  abstractElementFactory_->setDriftEnable(true);
61  abstractElementFactory_->setCellEnable(true);
62  abstractElementFactory_->setBendEnable(true);
63  abstractElementFactory_->setSolenoEnable(true);
64  abstractElementFactory_->setBeamEnable(true);
65  abstractElementFactory_->setFitEnable(true);
66  abstractElementFactory_->setSnapshotEnable(true);
67  abstractElementFactory_->setMPoleEnable(true);
68 
69  // include the styleSheetcd
70  WContainerWidget *mainContainerWidget = root();
71  useStyleSheet("htdocs/pspa.css");
72  dtmanage_ = new dataManager(this);
73
74  // The main layout is a 4x3 grid layout.
75  WHBoxLayout *toolbarLayout = new WHBoxLayout();
76 
77  WPushButton* boutonSauve = new WPushButton();
78  WPushButton* boutonRestaure = new WPushButton();
79  WPushButton* boutonLoadNew = new WPushButton();
80  WPushButton* boutonTrash = new WPushButton();
81 
82  boutonSauve->setStyleClass("saveButton");
83  boutonRestaure->setStyleClass("restoreButton");
84  boutonLoadNew->setStyleClass("loadNewButton");
85  boutonTrash->setStyleClass("trashButton");
86 
87  boutonSauve->setToolTip ("sauvegarder votre configuration");
88  boutonRestaure->setToolTip ("restaurer la configuration depuis le serveur");
89  boutonLoadNew->setToolTip ("charger une configuration");
90  boutonTrash->setToolTip ("supprimer l'accélerateur"); // FIXME ! a terminer
91 
92  boutonSauve->setMaximumSize(38,38);
93  boutonSauve->setMinimumSize(38,38);
94  boutonRestaure->setMaximumSize(38,38);
95  boutonRestaure->setMinimumSize(38,38);
96  boutonLoadNew->setMaximumSize(38,38);
97  boutonLoadNew->setMinimumSize(38,38);
98  boutonTrash->setMaximumSize(38,38);
99  boutonTrash->setMinimumSize(38,38);
100 
101  boutonSauve->clicked().connect(this, &PspaApplication::sauver);
102  boutonRestaure->clicked().connect(this, &PspaApplication::restaurer);
103  // Upload when the button is clicked. React to a succesfull upload.
104  boutonLoadNew->clicked().connect(this, &PspaApplication::openFileSelector);
105  toolbarLayout->addWidget(boutonSauve , 0,Wt::AlignMiddle);
106  toolbarLayout->addWidget(boutonRestaure , 0,Wt::AlignMiddle);
107  toolbarLayout->addWidget(boutonLoadNew , 0,Wt::AlignMiddle);
108  toolbarLayout->addWidget(boutonTrash , 0,Wt::AlignMiddle);
109  toolbarLayout->addWidget(new WText("") , 1,Wt::AlignMiddle);
110 
111  WGridLayout* gridLayout = new WGridLayout(mainContainerWidget);
112
113  WContainerWidget * toolbarLayoutContainer = new WContainerWidget();
114  toolbarLayoutContainer->setLayout(toolbarLayout);
115  toolbarLayoutContainer->decorationStyle().setBackgroundImage ("/htdocs/fond_toolbar.png");
116  // menu menu on the top
117  gridLayout->addWidget(toolbarLayoutContainer, 1,0,1,2);
118  // palette on the left
119  gridLayout->addWidget(createPalette(mainContainerWidget), 2, 0);
120 
121  // create accelerator main widget
122  acceleratorContainerWidget_ = new WContainerWidget();
123  gridLayout->addWidget(acceleratorContainerWidget_, 2, 1);
124
125  // Let column 2 take the excess space.
126  gridLayout->setColumnStretch(1,1);
127  // Let row 1 take the excess space.
128  gridLayout->setRowStretch(2,1);
129
130 
131  // FIXME : Have to be move in GWt_accelerator
132  createAccelerator();
133
134  // set auto scrollbar if needed
135  mainContainerWidget->setOverflow(WContainerWidget::OverflowAuto);
136}
137
138
139void PspaApplication::createAccelerator() {
140  new GWt_accelerator(acceleratorContainerWidget_,dtmanage_);
141  new WBreak(acceleratorContainerWidget_);
142
143
144  // ---------------------------------------------------------------
145  // ********************* Ancien code : A supprimer ***************
146  // ---------------------------------------------------------------
147  beamLine_deprecated_ = NULL;
148  /*
149   WScrollArea* scroll = new  WScrollArea(acceleratorContainerWidget_);
150   scroll->setWidget(createBeamLine__deprecated());
151   scroll->setMinimumSize(300,150);
152   */
153 
154  new WBreak(acceleratorContainerWidget_);
155  //-----------
156
157  // A supprimer et a mettre en fenetre
158  // xx globalParam_ = createGlobalParamWidget();
159  // xx mainGridLayout->addWidget(globalParam_,3,1);
160
161  globalParam_ = new GWt_globalParameters(dtmanage_);
162  sectorParam_ = new GWt_sectorParameters();
163  WWidget* dboard = createDashBoard(acceleratorContainerWidget_);
164  dboard->setMinimumSize(300,100);
165
166  new WBreak(acceleratorContainerWidget_);
167
168  //-----------
169
170 
171  new WBreak(acceleratorContainerWidget_);
172 
173  console_ = new GWt_console(acceleratorContainerWidget_);
174  console_->setMinimumSize(300,100);
175
176 
177}
178
179WWidget* PspaApplication::createDashBoard(WContainerWidget* parent)
180{
181  WContainerWidget *wt= new WContainerWidget();
182  wt->setStyleClass("text");
183  WText *st= new WText("Go ahead...",wt); 
184
185  WContainerWidget *buttons = new WContainerWidget();
186  buttons->setStyleClass("buttons");
187  WPushButton *button;
188  button = new WPushButton("globalParameters",buttons);
189  button->clicked().connect(this, &PspaApplication::messageBox1);
190  button = new WPushButton("sectors", buttons);
191  button->clicked().connect(this, &PspaApplication::messageBox2);
192 
193  styleSheet().addRule(".buttons","padding: 5px;");
194  styleSheet().addRule(".text", "padding: 4px 8px");
195  styleSheet().addRule("body", "margin: 0px;");
196
197  WContainerWidget *cnt = new WContainerWidget();
198  cnt->addWidget(buttons);
199  cnt->addWidget(wt);
200
201  WContainerWidget *result = new WContainerWidget(parent);
202  WPanel *panel = new WPanel(result);
203  panel->setTitle("dashboard");
204  panel->setCentralWidget(cnt);
205
206  globalParam_->setText(st);
207  sectorParam_->setText(st);
208  return result;
209}
210
211void PspaApplication::messageBox1()
212{
213  globalParam_->initilializeDialog();
214  return;
215}
216
217void PspaApplication::messageBox2()
218{
219  sectorParam_->execDialog_deprecated();
220  return;
221}
222
223WWidget* PspaApplication::createPalette(WContainerWidget* parent)
224{
225  WContainerWidget* palette = new WContainerWidget(parent);
226  vector <GWt_abstractElement*> elems = abstractElementFactory_->getAllElements();
227  for (unsigned a = 0; a < elems.size(); a++) {
228    elems[a]->createDragImage(palette);
229    new WBreak(palette);
230  }
231  return palette; 
232}
233
234void PspaApplication::createDragImage(const char *url,const char *smallurl,const char *mimeType,WContainerWidget *p,WString())
235{
236  GWt_draggableImage *result = new GWt_draggableImage(url,p);
237 
238  /*
239   * Set the image to be draggable, showing the other image (dragImage)
240   * to be used as the widget that is visually dragged.
241   */
242  result->setDraggable(mimeType,new WImage(smallurl,p),true);
243}
244
245/*Wt::WWidget* PspaApplication::createBeamLine__deprecated()
246{
247  extensionFile_= 0;
248  if (!beamLine__deprecated_) {
249    // FIXME : get the one of the first app/sector for the moment
250    beamLine__deprecated_ = accel_toBeRenameAsLocal->firstSector__deprecated()->getUIBeamLine ?
251  } else {
252    beamLine_->clear();
253  }
254  beamLine_->setMinimumSize(300,100);
255  setTitle(applicationDefaultTitle_);
256
257  return beamLine__deprecated_;
258}
259*/
260
261void PspaApplication::sauver()
262{
263  cout << "***********************************" << endl;
264  cout << " on sauve " << endl<<endl;
265 
266  console_->addConsoleMessage("sauvegarde \n"); 
267  dialogSave_ = new WDialog("save");
268  new WText("name of case : ",dialogSave_->contents());
269  saveNameEdit_ = new WLineEdit(nameOfCase_.c_str(), dialogSave_->contents());
270  WPushButton *annule = new WPushButton("cancel",dialogSave_->contents());
271  WPushButton *submit = new WPushButton("OK",dialogSave_->contents());
272  annule->clicked().connect(dialogSave_, &Wt::WDialog::reject);
273  submit->clicked().connect(dialogSave_, &Wt::WDialog::accept);
274  dialogSave_->finished().connect(this, &PspaApplication::dialogSaveDone);
275  dialogSave_->show();
276}
277
278void PspaApplication::dialogSaveDone(WDialog::DialogCode code)
279{
280  if ( code != Wt::WDialog::Accepted ) {
281    return;
282  }
283  nameOfCase_ = saveNameEdit_->text().toUTF8();
284  delete dialogSave_;
285  dialogSave_ = NULL;
286
287  //globalParam_->updateGlobals();
288
289  //  dtmanage_->saveConfiguration(nameOfCase_);
290  dtmanage_->saveConfiguration(sessionId(),nameOfCase_);
291
292  // en test: j'ajoute la sauvegarde sur .aml
293  dtmanage_->writeToAMLFile(nameOfCase_);
294}
295
296void PspaApplication::restaurer()
297{
298  cout << "***********************************" << endl;
299  cout << " on restaure " << endl<<endl;
300
301  GWt_serverFileSelector * fs = new GWt_serverFileSelector("Select a configuration file",workingDir_);
302  string fileName = fs->exec();
303  nameOfCase_ = fileName;
304  if (fileName == "") {
305    return;
306  }
307   
308  removePathFromConfigName(nameOfCase_);
309  cout << " nom sans path " << nameOfCase_ << endl;
310  removeExtensionFromConfigName(nameOfCase_);
311  cout << " nom sans extension " << nameOfCase_ << endl;
312  if (nameOfCase_ == "") return;
313  cout << " PspaApplication::restaure le fichier   : " << fileName << endl;
314  dialogSave_ = NULL;
315 
316  bool test = dtmanage_->restoreElements(fileName);
317  if ( !test ) {
318    GWt_dialog restoreWarning(" element restoring", "failure in restoring elements from file : " + fileName , GWt_dialog::Error, false,true);
319    restoreWarning.exec();
320  } else {
321    // Change the window title
322    unsigned long found = fileName.find_last_of("/");
323    setTitle(applicationDefaultTitle_+" : "+fileName.substr(found+1));
324  }
325 
326  // reload new elements in the GUI
327// FIXME : Don't do that in the futur !
328  // In the futur, we should be able to have lot of accelerator at the same time and each with ONE datamanager
329  acceleratorContainerWidget_->clear();
330  createAccelerator();
331
332  globalParam_->renew();
333  //sectorParam_->renew();
334  console_->addConsoleMessage(WString("restauration terminee \n"));
335}
336
337void PspaApplication::openFileSelector()
338{
339  WContainerWidget *result = new WContainerWidget();
340  WVBoxLayout* myLayout = new WVBoxLayout(); 
341  uploadFileSelectorWidget_ = new WFileUpload();
342  uploadFileSelectorWidget_->setFileTextSize(40);
343  myLayout->addWidget(new WText("Select the configuration file for pspa : "));
344  myLayout->addWidget(uploadFileSelectorWidget_);
345  result->setLayout (myLayout);
346   
347  // Upload automatically when the user entered a file.
348  uploadFileSelectorWidget_->changed().connect(uploadFileSelectorWidget_, &WFileUpload::upload);
349 
350  // React to a succesfull upload.
351  uploadFileSelectorWidget_->uploaded().connect(this, &PspaApplication::chargerConfig);
352 
353  // React to a fileupload problem.
354  uploadFileSelectorWidget_->fileTooLarge().connect(this, &PspaApplication::fileTooLarge);
355 
356  GWt_dialog* fileSelectorDialog = new GWt_dialog("Load a file",result,false);
357  fileSelectorDialog->exec();
358}
359
360void PspaApplication::chargerConfig()
361{
362  GWt_dialog*  message= new GWt_dialog("File successfully upload","The file has been correctly upload to" + uploadFileSelectorWidget_->spoolFileName(),GWt_dialog::Warning,false,true);
363   
364  string nomDuFichier = (uploadFileSelectorWidget_->clientFileName()).toUTF8();
365  cout << " fichier client : " << nomDuFichier << endl;
366  bool test = removeExtensionFromConfigName(nomDuFichier);
367  cout << " fichier client sans extension : " << nomDuFichier << endl;
368 
369  if ( test ) {
370    nameOfCase_ = nomDuFichier;
371    console_->addConsoleMessage(string("restauration..."));
372     
373    if ( !dtmanage_->restoreElements(uploadFileSelectorWidget_->spoolFileName()) ) {
374      GWt_dialog restoreWarning(" element restoring", "failure in restoring elements !", GWt_dialog::Error, false,true);
375      restoreWarning.exec();
376    }
377     
378    globalParam_->renew(); 
379    //sectorParam_->renew();
380    console_->addConsoleMessage(string("rechargement de la config termine"));
381    message->show();
382  }
383}
384
385void PspaApplication::fileTooLarge()
386{
387  std::stringstream stream;
388  stream << maximumRequestSize ();
389  std::string maxRequestSize(stream.str());
390 
391  std::string message = "This file is too large, please select a one\n";
392  message += "Maximum file size is "+ maxRequestSize;
393  message += " bytes\n";
394   
395  GWt_dialog*  messageBox= new GWt_dialog("Error during upload file" ,message ,GWt_dialog::Error,false,true); 
396  messageBox->show();
397}
398
399
400
401// void PspaApplication::faireDessinParmela(WContainerWidget* toto, particleBeam* beam, string namex, string namey )
402// {
403//   cout << " faireDessinParmela " << endl;
404//   GWt_dialog* pointsDialog = new GWt_dialog("space phase",toto,false);
405//   eDialog_.push_back(pointsDialog);
406//   pointsDialog->setMinimumSize(400,400);
407//   pointsDialog->setClosable(true);
408//   // pointsDialog->show();
409     
410//   new WText(nameOfCase_, pointsDialog->contents());
411
412
413//   vector<double> xcor;
414//   vector<double> ycor;
415//   vector<string> legende;
416//   beam->particlesPhaseSpaceData(xcor, ycor, legende, namex, namey);
417//   for (int k=0 ; k < legende.size(); k++) {
418//     new WBreak(pointsDialog->contents());
419//     new WText(legende.at(k), pointsDialog->contents());
420//   }
421//   string titre = " phase space ";
422//   chartPlot2vec(pointsDialog->contents(), xcor, ycor, true,titre,namex, namey,400,400);
423
424
425   
426//   pointsDialog->show();
427   
428//   //  chart->setMargin(10, Top | Bottom);            // add margin vertically
429//   //  chart->setMargin(WLength::Auto, Left | Right); // center horizontally
430// }
431
432// void PspaApplication::faireDessinTransport(WContainerWidget* toto, particleBeam* beam, string namex, string namey)
433// {
434//   GWt_dialog* ellipseDialog = new GWt_dialog("ellipse",toto,false);
435//   eDialog_.push_back(ellipseDialog);
436//   ellipseDialog->setMinimumSize(400,400);
437//   ellipseDialog->setClosable(true);
438//   ellipseDialog->show();
439//   new WText(nameOfCase_, ellipseDialog->contents());
440 
441//   vector<double> xcor;
442//   vector<double> ycor;
443//   vector<string> legende;
444//   beam->donneesDessinEllipse(xcor,ycor,legende, namex, namey);
445
446//   for (int k=0 ; k < legende.size(); k++) {
447//     new WBreak(ellipseDialog->contents());
448//     new WText(legende.at(k), ellipseDialog->contents());
449//   }
450//   string titre = "phase space rms";
451//   chartPlot2vec(ellipseDialog->contents(), xcor, ycor, false,titre, namex, namey,500,300);
452// }
453
454
455// // parametre drawPoints : true = on trace des points (phase space) ; false = on trace des lignes (enveloppes...)
456// void PspaApplication::chartPlot2vec(WContainerWidget* toto, vector<double>& xcor, vector<double>& ycor, bool drawPoints,string title,string legendx, string legendy,int width, int height, bool makeIcon)
457// {
458//     int nbpts = xcor.size();
459//     cout << " PspaApplication::chartPlot2vec nbpts = " << nbpts << endl;
460//     WStandardItemModel *model = new WStandardItemModel(nbpts, 2, toto);
461//     for (int i = 0; i < nbpts; ++i) {
462//         model->setData(i, 0, xcor.at(i));
463//         model->setData(i, 1, ycor.at(i));
464//         //    cout << " PspaApplication::chartPlot2vec el= " << i+1 << " x= " << xcor.at(i) << " y= " << ycor.at(i) << endl;
465//     }
466   
467//     WCartesianChart *chart = new WCartesianChart(toto);
468//     if (!makeIcon) {
469//         chart->setTitle(title);
470//     }
471//     chart->initLayout();
472   
473//     chart->setModel(model);        // set the model
474//     chart->setXSeriesColumn(0);    // set the column that holds the X data
475//     if (!makeIcon) {
476//         chart->setLegendEnabled(true); // enable the legend
477//     } else {
478//         chart->setLegendEnabled(false); // enable the legend
479//     }
480   
481//     chart->setType(ScatterPlot);   // set type to ScatterPlot
482   
483//     // Typically, for mathematical functions, you want the axes to cross
484//     // at the 0 mark:
485//     chart->axis(XAxis).setLocation(ZeroValue);
486//     chart->axis(YAxis).setLocation(ZeroValue);
487
488//     // Provide space for the X and Y axis and title.
489//     chart->setPlotAreaPadding(80, Left);  // ?
490//     chart->setPlotAreaPadding(40, Bottom);
491//     chart->setPlotAreaPadding(60, Top);
492//     if ( drawPoints ) {
493//       WDataSeries s(1, PointSeries, Y1Axis);
494//       chart->addSeries(s);   
495//     } else {
496//       WDataSeries s(1, LineSeries, Y1Axis);
497//       chart->addSeries(s);   
498//     }
499//     chart->resize(width, height); // WPaintedWidget must be given explicit size
500   
501   
502//     WAxis& axis = chart->axis(XAxis);
503//     axis.setLabelFormat("%.3f");
504//     //       axis.setGridLinesEnabled(true);
505//     axis.setTitle(legendx);
506   
507//     WAxis& axey = chart->axis(YAxis);
508//     axey.setTitle(legendy);
509//     // axis = chart->axis(YAxis);
510//     // axis.setLabelFormat("%.3f");
511//     // axis.setGridLinesEnabled(true);
512//     // axis.setTitle(legendy);
513   
514//     if (makeIcon) {
515//       chart->setPlotAreaPadding(0);
516//       chart->setAxisPadding(0);
517//       WFont xAxisFont = chart->axis(XAxis).labelFont();
518//       xAxisFont.setSize(8);
519//       WFont yAxisFont = chart->axis(YAxis).labelFont();
520//       yAxisFont.setSize(8);
521//       chart->axis(XAxis).setLabelFont(xAxisFont);
522//       chart->axis(YAxis).setLabelFont(yAxisFont);
523//     }
524
525// #ifdef HAS_IMAGEMAGIC
526// /*    Wt::WRasterImage pngImage("png", 600, 600);
527//     Wt::WPainter p(&pngImage);
528//     chart->paint(p);
529//     std::string name;
530//     name = workingDir_ + "/chart-"+sessionId ()+".png";
531//     std::ofstream f(name.c_str(), std::ios::out |std::ios::trunc | std::ios::binary);
532//     pngImage.write(f);   
533//     new WText("<a href='workingArea/chart-"+sessionId ()+".png' target='_blank'>Afficher l'image</a>",toto);
534   
535//   Wt::WPdfImage pdfImage("30cm", "30cm");
536//     Wt::WPainter p1(&pdfImage);
537//     pdfImage.init();
538//     chart->paint(p1);
539//     name = workingDir_ + "/chart-"+sessionId ()+".pdf";
540//     std::ofstream f1(name.c_str(), std::ios::out |std::ios::trunc | std::ios::binary);
541//     pdfImage.write(f1);
542//  */
543// #endif
544// }
545
546
547WText* PspaApplication::createTitle(const WString& title)
548{
549  WText *result = new WText(title);
550  result->setInline(false);
551  result->setStyleClass("title");
552  result->setMinimumSize(30,30);
553 
554  return result;
555}
556
557// void PspaApplication::addConsoleMessage(WString msg) {
558//   WText *w = new WText(console_);
559//   w->setTextFormat(PlainText);
560//   w->setText(msg);
561//   w->setInline(false);
562
563//   /*
564//    * Little javascript trick to make sure we scroll along with new content
565//    */
566//   WApplication *app = WApplication::instance();
567//   app->doJavaScript(console_->jsRef() + ".scrollTop += "
568//                     + console_->jsRef() + ".scrollHeight;");
569
570// }
571
572bool PspaApplication::removePathFromConfigName(string& config) {
573  string toExtract = workingDir_ + "/";
574  string::size_type nn = config.find(toExtract);
575  if ( nn == string::npos ) {
576        GWt_dialog checkremovePath(" checking config file name", " failed to recognize path name for file  " + config, GWt_dialog::Error,true,true);
577        checkremovePath.exec();
578    return false;
579  }
580  config.replace(nn, toExtract.size(), "");
581  return true;
582}
583
584bool PspaApplication::removeExtensionFromConfigName(string& config)
585{
586    //  string configName;
587    string extension(".save");
588    bool test = true;
589    string::size_type nn = config.rfind('.');
590    if ( nn == string::npos )
591    {
592        // pas de point
593        test = false;
594    }
595    string fin = config.substr(nn);
596    if ( fin != extension )
597    {
598        // l'extension n'est pas la bonne
599        test = false;
600    }
601    if ( test )
602    {
603        string::size_type count = config.length() - extension.length();
604        config = config.substr(0, count);
605    }
606    else
607    {
608        GWt_dialog checkConfigNameDialog(" checking config file name", " the file must have the extension " + extension, GWt_dialog::Error,true,true);
609        checkConfigNameDialog.exec();
610    }
611    return test;
612}
613
614
615/*
616void PspaApplication::removeBeamLine() {
617  createBeamLine__deprecated();
618  executeWidget_->updateSections();
619}
620*/
621
Note: See TracBrowser for help on using the repository browser.