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

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

prise en charge de la restauration dun fichier de sauvegarde

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