Path: blob/main/src/netedit/dialogs/run/GNERunDialog.cpp
169685 views
/****************************************************************************/1// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo2// Copyright (C) 2001-2025 German Aerospace Center (DLR) and others.3// This program and the accompanying materials are made available under the4// terms of the Eclipse Public License 2.0 which is available at5// https://www.eclipse.org/legal/epl-2.0/6// This Source Code may also be made available under the following Secondary7// Licenses when the conditions for such availability set forth in the Eclipse8// Public License 2.0 are satisfied: GNU General Public License, version 29// or later which is available at10// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html11// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later12/****************************************************************************/13/// @file GNERunDialog.cpp14/// @author Pablo Alvarez Lopez15/// @date Aug 202516///17// Abstract dialog for running tools18/****************************************************************************/1920#include <netedit/GNEApplicationWindow.h>21#include <netedit/GNEExternalRunner.h>22#include <utils/gui/div/GUIDesigns.h>23#include <utils/gui/events/GUIEvent_Message.h>2425#include "GNERunDialog.h"2627// ===========================================================================28// FOX callback mapping29// ===========================================================================3031FXDEFMAP(GNERunDialog) GNERunDialogMap[] = {32FXMAPFUNC(SEL_COMMAND, MID_GNE_BUTTON_SAVE, GNERunDialog::onCmdSaveLog),33FXMAPFUNC(FXEX::SEL_THREAD_EVENT, ID_LOADTHREAD_EVENT, GNERunDialog::onThreadEvent),34FXMAPFUNC(FXEX::SEL_THREAD, ID_LOADTHREAD_EVENT, GNERunDialog::onThreadEvent)35};3637// Object implementation38FXIMPLEMENT_ABSTRACT(GNERunDialog, GNEDialog, GNERunDialogMap, ARRAYNUMBER(GNERunDialogMap))3940// ============================================-===============================41// member method definitions42// ===========================================================================4344GNERunDialog::GNERunDialog(GNEApplicationWindow* applicationWindow, const std::string& name, GUIIcon titleIcon) :45GNEDialog(applicationWindow, name, titleIcon, DialogType::RUN, GNEDialog::Buttons::RERUN_BACK_CLOSE,46OpenType::MODAL, GNEDialog::ResizeMode::RESIZABLE, 640, 480) {47// build the thread - io48myThreadEvent.setTarget(this);49myThreadEvent.setSelector(ID_LOADTHREAD_EVENT);50// create header frame51auto headerFrame = new FXHorizontalFrame(myContentFrame, GUIDesignHorizontalFrame);52// adjust padding53headerFrame->setPadLeft(0);54headerFrame->setPadRight(0);55GUIDesigns::buildFXButton(headerFrame, "", "", + TL("Save output"), GUIIconSubSys::getIcon(GUIIcon::SAVE),56this, MID_GNE_BUTTON_SAVE, GUIDesignButtonIcon);57new FXLabel(headerFrame, TL("Console output"), nullptr, GUIDesignLabelThick(JUSTIFY_LEFT));58// create text59auto textFrame = new FXVerticalFrame(myContentFrame, GUIDesignFrameThick);60myText = new FXText(textFrame, 0, 0, (TEXT_READONLY | LAYOUT_FILL_X | LAYOUT_FILL_Y));61// set styled62myText->setHiliteStyles(GUIMessageWindow::getStyles());63myText->setStyled(true);64// update dialog button65updateDialogButtons();66}676869GNERunDialog::~GNERunDialog() {}707172void73GNERunDialog::addEvent(GUIEvent* event, const bool signal) {74// add event to queue75myEvents.push_back(event);76// signal thread event77if (signal) {78myThreadEvent.signal();79}80}818283long84GNERunDialog::onCmdAbort(FXObject*, FXSelector, void*) {85// abort external runner86myApplicationWindow->getExternalRunner()->abort();87// hide dialog88return closeDialogCanceling();89}909192long93GNERunDialog::onCmdRun(FXObject*, FXSelector, void*) {94if (myApplicationWindow->getExternalRunner()->isRunning()) {95// abort external runner96myApplicationWindow->getExternalRunner()->abort();97} else {98// add line and info99std::string line("-------------------------------------------\n");100myText->appendStyledText(line.c_str(), (int)line.length(), 4, TRUE);101myText->appendStyledText("rerun tool\n", 1, TRUE);102myText->layout();103myText->update();104myError = false;105// abort external runner106myApplicationWindow->getExternalRunner()->runTool(this);107}108// update dialog button109updateDialogButtons();110return 1;111}112113114long115GNERunDialog::onCmdAccept(FXObject*, FXSelector, void*) {116// close run dialog and call postprocessing117closeDialogAccepting();118// reset text119myText->setText("", 0);120// call postprocessing dialog depending of myError121if (myError) {122return 1;123} else {124// don't run this again125myError = true;126return myApplicationWindow->handle(this, FXSEL(SEL_COMMAND, MID_GNE_POSTPROCESSINGNETGENERATE), nullptr);127}128}129130131long132GNERunDialog::onCmdSaveLog(FXObject*, FXSelector, void*) {133// create fileDialog134const auto saveLogFileDialog = GNEFileDialog(myApplicationWindow,135TL("tool log file"),136SUMOXMLDefinitions::TXTFileExtensions.getStrings(),137GNEFileDialog::OpenMode::SAVE,138GNEFileDialog::ConfigType::NETEDIT);139// check that file is valid140if (saveLogFileDialog.getResult() == GNEDialog::Result::ACCEPT) {141OutputDevice& dev = OutputDevice::getDevice(saveLogFileDialog.getFilename());142dev << myText->getText().text();143dev.close();144}145return 1;146}147148149long150GNERunDialog::onThreadEvent(FXObject*, FXSelector, void*) {151bool toolFinished = false;152while (!myEvents.empty()) {153// get the next event154GUIEvent* e = myEvents.top();155myEvents.pop();156// process157FXint style = -1;158switch (e->getOwnType()) {159case GUIEventType::TOOL_ENDED:160toolFinished = true;161break;162case GUIEventType::MESSAGE_OCCURRED:163style = 1;164break;165case GUIEventType::OUTPUT_OCCURRED:166style = 2;167break;168case GUIEventType::ERROR_OCCURRED:169style = 3;170myError = true;171break;172default:173break;174}175if (style >= 0) {176GUIEvent_Message* ec = static_cast<GUIEvent_Message*>(e);177myText->appendStyledText(ec->getMsg().c_str(), (int)ec->getMsg().length(), style, TRUE);178myText->layout();179myText->update();180}181delete e;182}183if (toolFinished) {184// check if close dialog immediately after running185if (myText->getText().find("Error") != -1) {186myError = true;187} else if ((myText->getText().find("Success") != -1) && (myText->getText().find("Warning") == -1)) {188//onCmdClose(nullptr, 0, nullptr);189}190}191updateDialogButtons();192return 1;193}194195196void197GNERunDialog::updateDialogButtons() {198// update buttons199if (myApplicationWindow->getExternalRunner()->isRunning()) {200// update run button201myRunButton->setText(TL("Abort"));202myRunButton->setTipText(TL("Abort running"));203myRunButton->setIcon(GUIIconSubSys::getIcon(GUIIcon::STOP));204// disable buttons205myBackButton->disable();206myAcceptButton->disable();207} else {208// update run button209myRunButton->setText(TL("Rerun"));210myRunButton->setTipText(TL("Rerun tool"));211myRunButton->setIcon(GUIIconSubSys::getIcon(GUIIcon::START));212// enable buttons213myBackButton->enable();214myAcceptButton->enable();215}216// update dialog217GNEDialog::update();218}219220/****************************************************************************/221222223