#include #include #include "GWt_pspaApplication.h" #include "GWt_draggableImage.h" #include "GWt_abstractElementFactory.h" #include "GWt_serverFileSelector.h" #include "GWt_accelerator.h" #include "particleBeam.h" #include "bareParticle.h" #include "nomDeLogiciel.h" #include "mixedTools.h" #include "nomdElements.h" #include "environmentVariables.h" #include "trivaluedBool.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define HAS_IMAGEMAGIC 1 using namespace Wt::Chart; /* * The env argument contains information about the new session, and * the initial request. It must be passed to the WApplication * constructor so it is typically also an argument for your custom * application constructor. */ PspaApplication::PspaApplication(const WEnvironment& env) : WApplication(env), applicationDefaultTitle_("portail PSPA"), extensionFile_(0) { workingDir_ = WApplication::docRoot()+ "/"+WORKINGAREA; nameOfCase_ = "pspa"; // default setTitle(applicationDefaultTitle_); // application title if (!wApp->environment().javaScript()) { new WText("This examples requires that javascript support is enabled.",root()); } // register the absractElementFactory abstractElementFactory_ = new GWt_abstractElementFactory(); abstractElementFactory_->setRFGunEnable(true); abstractElementFactory_->setDriftEnable(true); abstractElementFactory_->setCellEnable(true); abstractElementFactory_->setBendEnable(true); abstractElementFactory_->setSolenoEnable(true); abstractElementFactory_->setBeamEnable(true); abstractElementFactory_->setFitEnable(true); abstractElementFactory_->setSnapshotEnable(true); abstractElementFactory_->setMPoleEnable(true); // include the styleSheetcd WContainerWidget *mainContainerWidget = root(); useStyleSheet("htdocs/pspa.css"); dtmanage_ = new dataManager(this); // The main layout is a 4x3 grid layout. WHBoxLayout *toolbarLayout = new WHBoxLayout(); WPushButton* boutonSauve = new WPushButton(); WPushButton* boutonRestaure = new WPushButton(); WPushButton* boutonLoadNew = new WPushButton(); WPushButton* boutonTrash = new WPushButton(); boutonSauve->setStyleClass("saveButton"); boutonRestaure->setStyleClass("restoreButton"); boutonLoadNew->setStyleClass("loadNewButton"); boutonTrash->setStyleClass("trashButton"); boutonSauve->setToolTip ("sauvegarder votre configuration"); boutonRestaure->setToolTip ("restaurer la configuration depuis le serveur"); boutonLoadNew->setToolTip ("charger une configuration"); boutonTrash->setToolTip ("supprimer l'accélerateur"); // FIXME ! a terminer boutonSauve->setMaximumSize(38,38); boutonSauve->setMinimumSize(38,38); boutonRestaure->setMaximumSize(38,38); boutonRestaure->setMinimumSize(38,38); boutonLoadNew->setMaximumSize(38,38); boutonLoadNew->setMinimumSize(38,38); boutonTrash->setMaximumSize(38,38); boutonTrash->setMinimumSize(38,38); boutonSauve->clicked().connect(this, &PspaApplication::sauver); boutonRestaure->clicked().connect(this, &PspaApplication::restaurer); // Upload when the button is clicked. React to a succesfull upload. boutonLoadNew->clicked().connect(this, &PspaApplication::openFileSelector); toolbarLayout->addWidget(boutonSauve , 0,Wt::AlignMiddle); toolbarLayout->addWidget(boutonRestaure , 0,Wt::AlignMiddle); toolbarLayout->addWidget(boutonLoadNew , 0,Wt::AlignMiddle); toolbarLayout->addWidget(boutonTrash , 0,Wt::AlignMiddle); toolbarLayout->addWidget(new WText("") , 1,Wt::AlignMiddle); WGridLayout* gridLayout = new WGridLayout(mainContainerWidget); WContainerWidget * toolbarLayoutContainer = new WContainerWidget(); toolbarLayoutContainer->setLayout(toolbarLayout); toolbarLayoutContainer->decorationStyle().setBackgroundImage ("/htdocs/fond_toolbar.png"); // menu menu on the top gridLayout->addWidget(toolbarLayoutContainer, 1,0,1,2); // palette on the left gridLayout->addWidget(createPalette(mainContainerWidget), 2, 0); // create accelerator main widget acceleratorContainerWidget_ = new WContainerWidget(); gridLayout->addWidget(acceleratorContainerWidget_, 2, 1); // Let column 2 take the excess space. gridLayout->setColumnStretch(1,1); // Let row 1 take the excess space. gridLayout->setRowStretch(2,1); // FIXME : Have to be move in GWt_accelerator createAccelerator(); // set auto scrollbar if needed mainContainerWidget->setOverflow(WContainerWidget::OverflowAuto); } void PspaApplication::createAccelerator() { new GWt_accelerator(acceleratorContainerWidget_,dtmanage_); new WBreak(acceleratorContainerWidget_); // --------------------------------------------------------------- // ********************* Ancien code : A supprimer *************** // --------------------------------------------------------------- /* WScrollArea* scroll = new WScrollArea(acceleratorContainerWidget_); scroll->setWidget(createBeamLine__deprecated()); scroll->setMinimumSize(300,150); */ new WBreak(acceleratorContainerWidget_); //----------- // A supprimer et a mettre en fenetre // xx globalParam_ = createGlobalParamWidget(); // xx mainGridLayout->addWidget(globalParam_,3,1); globalParam_ = new GWt_globalParameters(dtmanage_); sectorParam_ = new GWt_sectorParameters(); WWidget* dboard = createDashBoard(acceleratorContainerWidget_); dboard->setMinimumSize(300,100); new WBreak(acceleratorContainerWidget_); //----------- new WBreak(acceleratorContainerWidget_); console_ = new GWt_console(acceleratorContainerWidget_); console_->setMinimumSize(300,100); } WWidget* PspaApplication::createDashBoard(WContainerWidget* parent) { WContainerWidget *wt= new WContainerWidget(); wt->setStyleClass("text"); WText *st= new WText("Go ahead...",wt); WContainerWidget *buttons = new WContainerWidget(); buttons->setStyleClass("buttons"); WPushButton *button; button = new WPushButton("globalParameters",buttons); button->clicked().connect(this, &PspaApplication::messageBox1); button = new WPushButton("sectors", buttons); button->clicked().connect(this, &PspaApplication::messageBox2); styleSheet().addRule(".buttons","padding: 5px;"); styleSheet().addRule(".text", "padding: 4px 8px"); styleSheet().addRule("body", "margin: 0px;"); WContainerWidget *cnt = new WContainerWidget(); cnt->addWidget(buttons); cnt->addWidget(wt); WContainerWidget *result = new WContainerWidget(parent); WPanel *panel = new WPanel(result); panel->setTitle("dashboard"); panel->setCentralWidget(cnt); globalParam_->setText(st); sectorParam_->setText(st); return result; } void PspaApplication::messageBox1() { globalParam_->initilializeDialog(); return; } void PspaApplication::messageBox2() { sectorParam_->execDialog_deprecated(); return; } WWidget* PspaApplication::createPalette(WContainerWidget* parent) { WContainerWidget* palette = new WContainerWidget(parent); vector elems = abstractElementFactory_->getAllElements(); for (unsigned a = 0; a < elems.size(); a++) { elems[a]->createDragImage(palette); new WBreak(palette); } return palette; } void PspaApplication::createDragImage(const char *url,const char *smallurl,const char *mimeType,WContainerWidget *p,WString()) { GWt_draggableImage *result = new GWt_draggableImage(url,p); /* * Set the image to be draggable, showing the other image (dragImage) * to be used as the widget that is visually dragged. */ result->setDraggable(mimeType,new WImage(smallurl,p),true); } /*Wt::WWidget* PspaApplication::createBeamLine__deprecated() { extensionFile_= 0; if (!beamLine__deprecated_) { // FIXME : get the one of the first app/sector for the moment beamLine__deprecated_ = accel_toBeRenameAsLocal->firstSector__deprecated()->getUIBeamLine ? } else { beamLine_->clear(); } beamLine_->setMinimumSize(300,100); setTitle(applicationDefaultTitle_); return beamLine__deprecated_; } */ void PspaApplication::sauver() { cout << "***********************************" << endl; cout << " on sauve " << endl<addConsoleMessage("sauvegarde \n"); dialogSave_ = new WDialog("save"); new WText("name of case : ",dialogSave_->contents()); saveNameEdit_ = new WLineEdit(nameOfCase_.c_str(), dialogSave_->contents()); WPushButton *annule = new WPushButton("cancel",dialogSave_->contents()); WPushButton *submit = new WPushButton("OK",dialogSave_->contents()); annule->clicked().connect(dialogSave_, &Wt::WDialog::reject); submit->clicked().connect(dialogSave_, &Wt::WDialog::accept); dialogSave_->finished().connect(this, &PspaApplication::dialogSaveDone); dialogSave_->show(); } void PspaApplication::dialogSaveDone(WDialog::DialogCode code) { if ( code != Wt::WDialog::Accepted ) { return; } nameOfCase_ = saveNameEdit_->text().toUTF8(); delete dialogSave_; dialogSave_ = NULL; //globalParam_->updateGlobals(); // dtmanage_->saveConfiguration(nameOfCase_); dtmanage_->saveConfiguration(sessionId(),nameOfCase_); // en test: j'ajoute la sauvegarde sur .aml dtmanage_->writeToAMLFile(nameOfCase_); } void PspaApplication::restaurer() { cout << "***********************************" << endl; cout << " on restaure " << endl<exec(); nameOfCase_ = fileName; if (fileName == "") { return; } removePathFromConfigName(nameOfCase_); cout << " nom sans path " << nameOfCase_ << endl; removeExtensionFromConfigName(nameOfCase_); cout << " nom sans extension " << nameOfCase_ << endl; if (nameOfCase_ == "") return; cout << " PspaApplication::restaure le fichier : " << fileName << endl; dialogSave_ = NULL; bool test = dtmanage_->restoreElements(fileName); if ( !test ) { GWt_dialog restoreWarning(" element restoring", "failure in restoring elements from file : " + fileName , GWt_dialog::Error, false,true); restoreWarning.exec(); } else { // Change the window title unsigned long found = fileName.find_last_of("/"); setTitle(applicationDefaultTitle_+" : "+fileName.substr(found+1)); } // reload new elements in the GUI // FIXME : Don't do that in the futur ! // In the futur, we should be able to have lot of accelerator at the same time and each with ONE datamanager acceleratorContainerWidget_->clear(); createAccelerator(); globalParam_->renew(); //sectorParam_->renew(); console_->addConsoleMessage(WString("restauration terminee \n")); } void PspaApplication::openFileSelector() { WContainerWidget *result = new WContainerWidget(); WVBoxLayout* myLayout = new WVBoxLayout(); uploadFileSelectorWidget_ = new WFileUpload(); uploadFileSelectorWidget_->setFileTextSize(40); myLayout->addWidget(new WText("Select the configuration file for pspa : ")); myLayout->addWidget(uploadFileSelectorWidget_); result->setLayout (myLayout); // Upload automatically when the user entered a file. uploadFileSelectorWidget_->changed().connect(uploadFileSelectorWidget_, &WFileUpload::upload); // React to a succesfull upload. uploadFileSelectorWidget_->uploaded().connect(this, &PspaApplication::chargerConfig); // React to a fileupload problem. uploadFileSelectorWidget_->fileTooLarge().connect(this, &PspaApplication::fileTooLarge); GWt_dialog* fileSelectorDialog = new GWt_dialog("Load a file",result,false); fileSelectorDialog->exec(); } void PspaApplication::chargerConfig() { GWt_dialog* message= new GWt_dialog("File successfully upload","The file has been correctly upload to" + uploadFileSelectorWidget_->spoolFileName(),GWt_dialog::Warning,false,true); string nomDuFichier = (uploadFileSelectorWidget_->clientFileName()).toUTF8(); cout << " fichier client : " << nomDuFichier << endl; bool test = removeExtensionFromConfigName(nomDuFichier); cout << " fichier client sans extension : " << nomDuFichier << endl; if ( test ) { nameOfCase_ = nomDuFichier; console_->addConsoleMessage(string("restauration...")); if ( !dtmanage_->restoreElements(uploadFileSelectorWidget_->spoolFileName()) ) { GWt_dialog restoreWarning(" element restoring", "failure in restoring elements !", GWt_dialog::Error, false,true); restoreWarning.exec(); } globalParam_->renew(); //sectorParam_->renew(); console_->addConsoleMessage(string("rechargement de la config termine")); message->show(); } } void PspaApplication::fileTooLarge() { std::stringstream stream; stream << maximumRequestSize (); std::string maxRequestSize(stream.str()); std::string message = "This file is too large, please select a one\n"; message += "Maximum file size is "+ maxRequestSize; message += " bytes\n"; GWt_dialog* messageBox= new GWt_dialog("Error during upload file" ,message ,GWt_dialog::Error,false,true); messageBox->show(); } // void PspaApplication::faireDessinParmela(WContainerWidget* toto, particleBeam* beam, string namex, string namey ) // { // cout << " faireDessinParmela " << endl; // GWt_dialog* pointsDialog = new GWt_dialog("space phase",toto,false); // eDialog_.push_back(pointsDialog); // pointsDialog->setMinimumSize(400,400); // pointsDialog->setClosable(true); // // pointsDialog->show(); // new WText(nameOfCase_, pointsDialog->contents()); // vector xcor; // vector ycor; // vector legende; // beam->particlesPhaseSpaceData(xcor, ycor, legende, namex, namey); // for (int k=0 ; k < legende.size(); k++) { // new WBreak(pointsDialog->contents()); // new WText(legende.at(k), pointsDialog->contents()); // } // string titre = " phase space "; // chartPlot2vec(pointsDialog->contents(), xcor, ycor, true,titre,namex, namey,400,400); // pointsDialog->show(); // // chart->setMargin(10, Top | Bottom); // add margin vertically // // chart->setMargin(WLength::Auto, Left | Right); // center horizontally // } // void PspaApplication::faireDessinTransport(WContainerWidget* toto, particleBeam* beam, string namex, string namey) // { // GWt_dialog* ellipseDialog = new GWt_dialog("ellipse",toto,false); // eDialog_.push_back(ellipseDialog); // ellipseDialog->setMinimumSize(400,400); // ellipseDialog->setClosable(true); // ellipseDialog->show(); // new WText(nameOfCase_, ellipseDialog->contents()); // vector xcor; // vector ycor; // vector legende; // beam->donneesDessinEllipse(xcor,ycor,legende, namex, namey); // for (int k=0 ; k < legende.size(); k++) { // new WBreak(ellipseDialog->contents()); // new WText(legende.at(k), ellipseDialog->contents()); // } // string titre = "phase space rms"; // chartPlot2vec(ellipseDialog->contents(), xcor, ycor, false,titre, namex, namey,500,300); // } // // parametre drawPoints : true = on trace des points (phase space) ; false = on trace des lignes (enveloppes...) // void PspaApplication::chartPlot2vec(WContainerWidget* toto, vector& xcor, vector& ycor, bool drawPoints,string title,string legendx, string legendy,int width, int height, bool makeIcon) // { // int nbpts = xcor.size(); // cout << " PspaApplication::chartPlot2vec nbpts = " << nbpts << endl; // WStandardItemModel *model = new WStandardItemModel(nbpts, 2, toto); // for (int i = 0; i < nbpts; ++i) { // model->setData(i, 0, xcor.at(i)); // model->setData(i, 1, ycor.at(i)); // // cout << " PspaApplication::chartPlot2vec el= " << i+1 << " x= " << xcor.at(i) << " y= " << ycor.at(i) << endl; // } // WCartesianChart *chart = new WCartesianChart(toto); // if (!makeIcon) { // chart->setTitle(title); // } // chart->initLayout(); // chart->setModel(model); // set the model // chart->setXSeriesColumn(0); // set the column that holds the X data // if (!makeIcon) { // chart->setLegendEnabled(true); // enable the legend // } else { // chart->setLegendEnabled(false); // enable the legend // } // chart->setType(ScatterPlot); // set type to ScatterPlot // // Typically, for mathematical functions, you want the axes to cross // // at the 0 mark: // chart->axis(XAxis).setLocation(ZeroValue); // chart->axis(YAxis).setLocation(ZeroValue); // // Provide space for the X and Y axis and title. // chart->setPlotAreaPadding(80, Left); // ? // chart->setPlotAreaPadding(40, Bottom); // chart->setPlotAreaPadding(60, Top); // if ( drawPoints ) { // WDataSeries s(1, PointSeries, Y1Axis); // chart->addSeries(s); // } else { // WDataSeries s(1, LineSeries, Y1Axis); // chart->addSeries(s); // } // chart->resize(width, height); // WPaintedWidget must be given explicit size // WAxis& axis = chart->axis(XAxis); // axis.setLabelFormat("%.3f"); // // axis.setGridLinesEnabled(true); // axis.setTitle(legendx); // WAxis& axey = chart->axis(YAxis); // axey.setTitle(legendy); // // axis = chart->axis(YAxis); // // axis.setLabelFormat("%.3f"); // // axis.setGridLinesEnabled(true); // // axis.setTitle(legendy); // if (makeIcon) { // chart->setPlotAreaPadding(0); // chart->setAxisPadding(0); // WFont xAxisFont = chart->axis(XAxis).labelFont(); // xAxisFont.setSize(8); // WFont yAxisFont = chart->axis(YAxis).labelFont(); // yAxisFont.setSize(8); // chart->axis(XAxis).setLabelFont(xAxisFont); // chart->axis(YAxis).setLabelFont(yAxisFont); // } // #ifdef HAS_IMAGEMAGIC // /* Wt::WRasterImage pngImage("png", 600, 600); // Wt::WPainter p(&pngImage); // chart->paint(p); // std::string name; // name = workingDir_ + "/chart-"+sessionId ()+".png"; // std::ofstream f(name.c_str(), std::ios::out |std::ios::trunc | std::ios::binary); // pngImage.write(f); // new WText("Afficher l'image",toto); // Wt::WPdfImage pdfImage("30cm", "30cm"); // Wt::WPainter p1(&pdfImage); // pdfImage.init(); // chart->paint(p1); // name = workingDir_ + "/chart-"+sessionId ()+".pdf"; // std::ofstream f1(name.c_str(), std::ios::out |std::ios::trunc | std::ios::binary); // pdfImage.write(f1); // */ // #endif // } WText* PspaApplication::createTitle(const WString& title) { WText *result = new WText(title); result->setInline(false); result->setStyleClass("title"); result->setMinimumSize(30,30); return result; } // void PspaApplication::addConsoleMessage(WString msg) { // WText *w = new WText(console_); // w->setTextFormat(PlainText); // w->setText(msg); // w->setInline(false); // /* // * Little javascript trick to make sure we scroll along with new content // */ // WApplication *app = WApplication::instance(); // app->doJavaScript(console_->jsRef() + ".scrollTop += " // + console_->jsRef() + ".scrollHeight;"); // } bool PspaApplication::removePathFromConfigName(string& config) { string toExtract = workingDir_ + "/"; string::size_type nn = config.find(toExtract); if ( nn == string::npos ) { GWt_dialog checkremovePath(" checking config file name", " failed to recognize path name for file " + config, GWt_dialog::Error,true,true); checkremovePath.exec(); return false; } config.replace(nn, toExtract.size(), ""); return true; } bool PspaApplication::removeExtensionFromConfigName(string& config) { // string configName; string extension(".save"); bool test = true; string::size_type nn = config.rfind('.'); if ( nn == string::npos ) { // pas de point test = false; } string fin = config.substr(nn); if ( fin != extension ) { // l'extension n'est pas la bonne test = false; } if ( test ) { string::size_type count = config.length() - extension.length(); config = config.substr(0, count); } else { GWt_dialog checkConfigNameDialog(" checking config file name", " the file must have the extension " + extension, GWt_dialog::Error,true,true); checkConfigNameDialog.exec(); } return test; } /* void PspaApplication::removeBeamLine() { createBeamLine__deprecated(); executeWidget_->updateSections(); } */