LCOV - code coverage report
Current view: top level - src/gui - GUIApplicationWindow.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 53.3 % 1370 730
Test Date: 2025-12-06 15:35:27 Functions: 40.0 % 105 42

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2001-2025 German Aerospace Center (DLR) and others.
       4              : // This program and the accompanying materials are made available under the
       5              : // terms of the Eclipse Public License 2.0 which is available at
       6              : // https://www.eclipse.org/legal/epl-2.0/
       7              : // This Source Code may also be made available under the following Secondary
       8              : // Licenses when the conditions for such availability set forth in the Eclipse
       9              : // Public License 2.0 are satisfied: GNU General Public License, version 2
      10              : // or later which is available at
      11              : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
      12              : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
      13              : /****************************************************************************/
      14              : /// @file    GUIApplicationWindow.cpp
      15              : /// @author  Daniel Krajzewicz
      16              : /// @author  Jakob Erdmann
      17              : /// @author  Michael Behrisch
      18              : /// @author  Andreas Gaubatz
      19              : /// @author  Mirko Barthauer
      20              : /// @date    Sept 2002
      21              : ///
      22              : // The main window of the SUMO-gui.
      23              : /****************************************************************************/
      24              : #include <config.h>
      25              : 
      26              : #ifdef HAVE_VERSION_H
      27              : #include <version.h>
      28              : #endif
      29              : 
      30              : #include <fxkeys.h>
      31              : 
      32              : #include <guisim/GUILane.h>
      33              : #include <guisim/GUINet.h>
      34              : #include <guisim/GUITrafficLightLogicWrapper.h>
      35              : #include <microsim/MSEdgeControl.h>
      36              : #include <microsim/MSInsertionControl.h>
      37              : #include <microsim/MSStateHandler.h>
      38              : #include <microsim/transportables/MSTransportableControl.h>
      39              : #include <microsim/devices/MSRoutingEngine.h>
      40              : #include <microsim/traffic_lights/MSTLLogicControl.h>
      41              : #include <netload/NLHandler.h>
      42              : #include <traci-server/TraCIServer.h>
      43              : #include <utils/common/MsgHandler.h>
      44              : #include <utils/common/StringUtils.h>
      45              : #include <utils/foxtools/MFXButtonTooltip.h>
      46              : #include <utils/foxtools/MFXLabelTooltip.h>
      47              : #include <utils/foxtools/MFXLCDLabel.h>
      48              : #include <utils/foxtools/MFXLinkLabel.h>
      49              : #include <utils/foxtools/MFXRealSpinner.h>
      50              : #include <utils/gui/cursors/GUICursorSubSys.h>
      51              : #include <utils/gui/div/GLHelper.h>
      52              : #include <utils/gui/div/GUIDesigns.h>
      53              : #include <utils/gui/div/GUIDialog_GLChosenEditor.h>
      54              : #include <utils/gui/div/GUIGlobalSelection.h>
      55              : #include <utils/gui/div/GUIMessageWindow.h>
      56              : #include <utils/gui/div/GUIUserIO.h>
      57              : #include <utils/gui/events/GUIEvent_AddView.h>
      58              : #include <utils/gui/events/GUIEvent_CloseView.h>
      59              : #include <utils/gui/events/GUIEvent_Message.h>
      60              : #include <utils/gui/globjects/GUIShapeContainer.h>
      61              : #include <utils/gui/images/GUITexturesHelper.h>
      62              : #include <utils/gui/images/VClassIcons.h>
      63              : #include <utils/gui/images/GUITextureSubSys.h>
      64              : #include <utils/gui/settings/GUICompleteSchemeStorage.h>
      65              : #include <utils/gui/settings/GUISettingsHandler.h>
      66              : #include <utils/gui/shortcuts/GUIShortcutsSubSys.h>
      67              : #include <utils/gui/windows/GUIPerspectiveChanger.h>
      68              : #include <utils/xml/XMLSubSys.h>
      69              : 
      70              : #include "GUIApplicationWindow.h"
      71              : #include "GUIEvent_SimulationEnded.h"
      72              : #include "GUIEvent_SimulationLoaded.h"
      73              : #include "GUIGlobals.h"
      74              : #include "GUILoadThread.h"
      75              : #include "GUIRunThread.h"
      76              : #include "dialogs/GUIDialog_AboutSUMO.h"
      77              : #include "dialogs/GUIDialog_Feedback.h"
      78              : #include "dialogs/GUIDialog_AppSettings.h"
      79              : #include "dialogs/GUIDialog_Breakpoints.h"
      80              : #include "dialogs/GUIDialog_HallOfFame.h"
      81              : 
      82              : 
      83              : #define MIN_DRAW_DELAY 20
      84              : //#define HAVE_DANGEROUS_SOUNDS
      85              : 
      86              : // ===========================================================================
      87              : // FOX-declarations
      88              : // ===========================================================================
      89              : FXDEFMAP(GUIApplicationWindow) GUIApplicationWindowMap[] = {
      90              :     // close
      91              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_CTRL_Q_CLOSE,    GUIApplicationWindow::onCmdQuit),
      92              :     FXMAPFUNC(SEL_SIGNAL,   MID_HOTKEY_CTRL_Q_CLOSE,    GUIApplicationWindow::onCmdQuit),
      93              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_ALT_F4_CLOSE,    GUIApplicationWindow::onCmdQuit),
      94              :     FXMAPFUNC(SEL_CLOSE,    MID_WINDOW,                 GUIApplicationWindow::onCmdQuit),
      95              :     // toolbar
      96              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_CTRL_SHIFT_N_NEWWINDOW,                  GUIApplicationWindow::onCmdNewWindow),
      97              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_CTRL_O_OPENSIMULATION_OPENNETWORK,       GUIApplicationWindow::onCmdOpenConfiguration),
      98              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_CTRL_N_OPENNETWORK_NEWNETWORK,           GUIApplicationWindow::onCmdOpenNetwork),
      99              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_CTRL_P_OPENSHAPES,                       GUIApplicationWindow::onCmdOpenShapes),
     100              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_CTRL_U_OPENEDGEDATA,                     GUIApplicationWindow::onCmdOpenEdgeData),
     101              :     FXMAPFUNC(SEL_COMMAND,  MID_RECENTFILE,                                     GUIApplicationWindow::onCmdOpenRecent),
     102              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_CTRL_R_RELOAD,                           GUIApplicationWindow::onCmdReload),
     103              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_CTRL_QUICK_RELOAD,                       GUIApplicationWindow::onCmdQuickReload),
     104              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_CTRL_SHIFT_S_SAVESUMOCONFIG,             GUIApplicationWindow::onCmdSaveConfig),
     105              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_CTRL_W_CLOSESIMULATION,                  GUIApplicationWindow::onCmdClose),
     106              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_CTRL_E_EDITSELECTION_LOADNETEDITCONFIG,  GUIApplicationWindow::onCmdEditChosen),
     107              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_CTRL_B_EDITBREAKPOINT_OPENDATAELEMENTS,  GUIApplicationWindow::onCmdEditBreakpoints),
     108              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_F9_EDIT_VIEWSCHEME,                      GUIApplicationWindow::onCmdEditViewScheme),
     109              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_CTRL_I_EDITVIEWPORT,                     GUIApplicationWindow::onCmdEditViewport),
     110              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_CTRL_T_OPENNETEDIT_OPENSUMO,             GUIApplicationWindow::onCmdOpenInNetedit),
     111              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_CTRL_SHIFT_T_OPEN_NET,                   GUIApplicationWindow::onCmdOpenInNetedit),
     112              :     // gaming
     113              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_CTRL_H_APPSETTINGS_OPENEDGETYPES,    GUIApplicationWindow::onCmdAppSettings),
     114              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_CTRL_G_GAMINGMODE_TOGGLEGRID,        GUIApplicationWindow::onCmdGaming),
     115              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_CTRL_J_TOGGLEDRAWJUNCTIONSHAPE,      GUIApplicationWindow::onCmdToggleDrawJunctionShape),
     116              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_CTRL_K_OPENTLSPROGRAMS,              GUIApplicationWindow::onCmdToggleSecondaryShape),
     117              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_CTRL_F_FULSCREENMODE,                GUIApplicationWindow::onCmdFullScreen),
     118              :     FXMAPFUNC(SEL_COMMAND,  MID_LISTINTERNAL,                               GUIApplicationWindow::onCmdListInternal),
     119              :     FXMAPFUNC(SEL_COMMAND,  MID_LISTPARKING,                                GUIApplicationWindow::onCmdListParking),
     120              :     FXMAPFUNC(SEL_COMMAND,  MID_LISTTELEPORTING,                            GUIApplicationWindow::onCmdListTeleporting),
     121              :     FXMAPFUNC(SEL_COMMAND,  MID_NEW_MICROVIEW,                              GUIApplicationWindow::onCmdNewView),
     122              :     // OSG
     123              : #ifdef HAVE_OSG
     124              :     FXMAPFUNC(SEL_COMMAND,  MID_NEW_OSGVIEW,    GUIApplicationWindow::onCmdNewOSG),
     125              :     FXMAPFUNC(SEL_UPDATE,   MID_NEW_OSGVIEW,    GUIApplicationWindow::onUpdAddView),
     126              : 
     127              : #endif
     128              :     // Time
     129              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_A_MODE_STARTSIMULATION_ADDITIONALS_STOPS,        GUIApplicationWindow::onCmdStart),
     130              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_CTRL_A_STARTSIMULATION_OPENADDITIONALELEMENTS,   GUIApplicationWindow::onCmdStart),
     131              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_S_MODE_STOPSIMULATION_SELECT,                    GUIApplicationWindow::onCmdStop),
     132              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_CTRL_S_STOPSIMULATION_SAVENETWORK,               GUIApplicationWindow::onCmdStop),
     133              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_D_MODE_SINGLESIMULATIONSTEP_DELETE,              GUIApplicationWindow::onCmdStep),
     134              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_CTRL_D_SINGLESIMULATIONSTEP_OPENDEMANDELEMENTS,  GUIApplicationWindow::onCmdStep),
     135              :     FXMAPFUNC(SEL_COMMAND,  MID_DELAY_INC,                                              GUIApplicationWindow::onCmdDelayInc),
     136              :     FXMAPFUNC(SEL_COMMAND,  MID_DELAY_DEC,                                              GUIApplicationWindow::onCmdDelayDec),
     137              :     FXMAPFUNC(SEL_COMMAND,  MID_SIMSAVE,                                                GUIApplicationWindow::onCmdSaveState),
     138              :     FXMAPFUNC(SEL_COMMAND,  MID_SIMLOAD,                                                GUIApplicationWindow::onCmdLoadState),
     139              :     FXMAPFUNC(SEL_COMMAND,  MID_TIME_TOGGLE,                                            GUIApplicationWindow::onCmdTimeToggle),
     140              :     FXMAPFUNC(SEL_COMMAND,  MID_DELAY_TOGGLE,                                           GUIApplicationWindow::onCmdDelayToggle),
     141              :     FXMAPFUNC(SEL_COMMAND,  MID_DEMAND_SCALE,                                           GUIApplicationWindow::onCmdDemandScale),
     142              :     FXMAPFUNC(SEL_COMMAND,  MID_CLEARMESSAGEWINDOW,                                     GUIApplicationWindow::onCmdClearMsgWindow),
     143              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_B_BREAKPOINT,                                    GUIApplicationWindow::onCmdBreakpoint),
     144              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_ALT_B_BREAKPOINT_EARLY,                          GUIApplicationWindow::onCmdBreakpointEarly),
     145              :     // Stats
     146              :     FXMAPFUNC(SEL_COMMAND,  MID_SHOWNETSTATS,       GUIApplicationWindow::onCmdShowStats),
     147              :     FXMAPFUNC(SEL_COMMAND,  MID_SHOWVEHSTATS,       GUIApplicationWindow::onCmdShowStats),
     148              :     FXMAPFUNC(SEL_COMMAND,  MID_SHOWPERSONSTATS,    GUIApplicationWindow::onCmdShowStats),
     149              :     // these functions do not assign shortcut keys to commands, but rather affect the button enable status upon other events (e.g. simulation loaded)
     150              :     // since those events are invoked through pseudo key events (?), the same key shortcuts as in cmd must be supplied as well
     151              :     FXMAPFUNC(SEL_UPDATE,   MID_HOTKEY_CTRL_O_OPENSIMULATION_OPENNETWORK,               GUIApplicationWindow::onUpdOpen),
     152              :     FXMAPFUNC(SEL_UPDATE,   MID_HOTKEY_CTRL_N_OPENNETWORK_NEWNETWORK,                   GUIApplicationWindow::onUpdOpen),
     153              :     FXMAPFUNC(SEL_UPDATE,   MID_HOTKEY_CTRL_P_OPENSHAPES,                               GUIApplicationWindow::onUpdNeedsNetwork),
     154              :     FXMAPFUNC(SEL_UPDATE,   MID_HOTKEY_CTRL_U_OPENEDGEDATA,                             GUIApplicationWindow::onUpdNeedsNetwork),
     155              :     FXMAPFUNC(SEL_UPDATE,   MID_HOTKEY_CTRL_R_RELOAD,                                   GUIApplicationWindow::onUpdReload),
     156              :     FXMAPFUNC(SEL_UPDATE,   MID_HOTKEY_CTRL_QUICK_RELOAD,                               GUIApplicationWindow::onUpdReload),
     157              :     FXMAPFUNC(SEL_UPDATE,   MID_RECENTFILE,                                             GUIApplicationWindow::onUpdOpenRecent),
     158              :     FXMAPFUNC(SEL_UPDATE,   MID_NEW_MICROVIEW,                                          GUIApplicationWindow::onUpdAddView),
     159              :     FXMAPFUNC(SEL_UPDATE,   MID_HOTKEY_CTRL_A_STARTSIMULATION_OPENADDITIONALELEMENTS,   GUIApplicationWindow::onUpdStart),
     160              :     FXMAPFUNC(SEL_UPDATE,   MID_HOTKEY_CTRL_S_STOPSIMULATION_SAVENETWORK,               GUIApplicationWindow::onUpdStop),
     161              :     FXMAPFUNC(SEL_UPDATE,   MID_HOTKEY_CTRL_D_SINGLESIMULATIONSTEP_OPENDEMANDELEMENTS,  GUIApplicationWindow::onUpdStep),
     162              :     FXMAPFUNC(SEL_UPDATE,   MID_SIMSAVE,                                                GUIApplicationWindow::onUpdNeedsNetwork),
     163              :     FXMAPFUNC(SEL_UPDATE,   MID_SIMLOAD,                                                GUIApplicationWindow::onUpdNeedsNetwork),
     164              :     FXMAPFUNC(SEL_UPDATE,   MID_HOTKEY_CTRL_E_EDITSELECTION_LOADNETEDITCONFIG,          GUIApplicationWindow::onUpdNeedsNetwork),
     165              :     FXMAPFUNC(SEL_UPDATE,   MID_HOTKEY_CTRL_B_EDITBREAKPOINT_OPENDATAELEMENTS,          GUIApplicationWindow::onUpdNeedsNetwork),
     166              :     FXMAPFUNC(SEL_UPDATE,   MID_HOTKEY_B_BREAKPOINT,                                    GUIApplicationWindow::onUpdNeedsNetwork),
     167              :     FXMAPFUNC(SEL_UPDATE,   MID_HOTKEY_ALT_B_BREAKPOINT_EARLY,                          GUIApplicationWindow::onUpdNeedsNetwork),
     168              :     FXMAPFUNC(SEL_UPDATE,   MID_HOTKEY_F9_EDIT_VIEWSCHEME,                              GUIApplicationWindow::onUpdNeedsNetwork),
     169              :     FXMAPFUNC(SEL_UPDATE,   MID_HOTKEY_CTRL_I_EDITVIEWPORT,                             GUIApplicationWindow::onUpdNeedsNetwork),
     170              :     FXMAPFUNC(SEL_UPDATE,   MID_HOTKEY_CTRL_T_OPENNETEDIT_OPENSUMO,                     GUIApplicationWindow::onUpdNeedsNetwork),
     171              :     FXMAPFUNC(SEL_UPDATE,   MID_HOTKEY_CTRL_SHIFT_T_OPEN_NET,                           GUIApplicationWindow::onUpdNeedsNetwork),
     172              :     FXMAPFUNC(SEL_UPDATE,   MID_TOOLBAREDIT_LOADADDITIONALS,                            GUIApplicationWindow::onUpdNeedsSumoConfig),
     173              :     FXMAPFUNC(SEL_UPDATE,   MID_TOOLBAREDIT_LOADDEMAND,                                 GUIApplicationWindow::onUpdNeedsSumoConfig),
     174              :     FXMAPFUNC(SEL_UPDATE,   MID_DEMAND_SCALE,                                           GUIApplicationWindow::onUpdNeedsNetwork),
     175              :     FXMAPFUNC(SEL_UPDATE,   MID_HOTKEY_CTRL_G_GAMINGMODE_TOGGLEGRID,                    GUIApplicationWindow::onUpdNeedsNetwork),
     176              :     FXMAPFUNC(SEL_UPDATE,   MID_HOTKEY_CTRL_F_FULSCREENMODE,                            GUIApplicationWindow::onUpdNeedsNetwork),
     177              :     FXMAPFUNC(SEL_UPDATE,   MID_TRACI_STATUS,                                           GUIApplicationWindow::onUpdTraCIStatus),
     178              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_F1_ONLINEDOCUMENTATION,                          GUIApplicationWindow::onCmdHelp),
     179              :     FXMAPFUNC(SEL_COMMAND,  MID_CHANGELOG,                                              GUIApplicationWindow::onCmdChangelog),
     180              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEYS,                                                GUIApplicationWindow::onCmdHotkeys),
     181              :     FXMAPFUNC(SEL_COMMAND,  MID_TUTORIAL,                                               GUIApplicationWindow::onCmdTutorial),
     182              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_SHIFT_F11_HALLOFFAME,                            GUIApplicationWindow::onCmdHallOfFame),
     183              :     FXMAPFUNC(SEL_COMMAND,  MID_FEEDBACK,                                               GUIApplicationWindow::onCmdFeedback),
     184              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_F12_ABOUT,                                       GUIApplicationWindow::onCmdAbout),
     185              :     // forward requests to the active view
     186              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_SHIFT_J_LOCATEJUNCTION,      GUIApplicationWindow::onCmdLocate),
     187              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_SHIFT_E_LOCATEEDGE,          GUIApplicationWindow::onCmdLocate),
     188              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_SHIFT_V_LOCATEVEHICLE,       GUIApplicationWindow::onCmdLocate),
     189              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_SHIFT_P_LOCATEPERSON,        GUIApplicationWindow::onCmdLocate),
     190              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_SHIFT_C_LOCATECONTAINER,     GUIApplicationWindow::onCmdLocate),
     191              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_SHIFT_T_LOCATETLS,           GUIApplicationWindow::onCmdLocate),
     192              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_SHIFT_A_LOCATEADDITIONAL,    GUIApplicationWindow::onCmdLocate),
     193              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_SHIFT_O_LOCATEPOI,           GUIApplicationWindow::onCmdLocate),
     194              :     FXMAPFUNC(SEL_COMMAND,  MID_HOTKEY_SHIFT_L_LOCATEPOLY,          GUIApplicationWindow::onCmdLocate),
     195              :     FXMAPFUNC(SEL_UPDATE,   MID_HOTKEY_SHIFT_J_LOCATEJUNCTION,      GUIApplicationWindow::onUpdNeedsNetwork),
     196              :     FXMAPFUNC(SEL_UPDATE,   MID_HOTKEY_SHIFT_E_LOCATEEDGE,          GUIApplicationWindow::onUpdNeedsNetwork),
     197              :     FXMAPFUNC(SEL_UPDATE,   MID_HOTKEY_SHIFT_V_LOCATEVEHICLE,       GUIApplicationWindow::onUpdNeedsNetwork),
     198              :     FXMAPFUNC(SEL_UPDATE,   MID_HOTKEY_SHIFT_P_LOCATEPERSON,        GUIApplicationWindow::onUpdNeedsNetwork),
     199              :     FXMAPFUNC(SEL_UPDATE,   MID_HOTKEY_SHIFT_C_LOCATECONTAINER,     GUIApplicationWindow::onUpdNeedsNetwork),
     200              :     FXMAPFUNC(SEL_UPDATE,   MID_HOTKEY_SHIFT_T_LOCATETLS,           GUIApplicationWindow::onUpdNeedsNetwork),
     201              :     FXMAPFUNC(SEL_UPDATE,   MID_HOTKEY_SHIFT_A_LOCATEADDITIONAL,    GUIApplicationWindow::onUpdNeedsNetwork),
     202              :     FXMAPFUNC(SEL_UPDATE,   MID_HOTKEY_SHIFT_O_LOCATEPOI,           GUIApplicationWindow::onUpdNeedsNetwork),
     203              :     FXMAPFUNC(SEL_UPDATE,   MID_HOTKEY_SHIFT_L_LOCATEPOLY,          GUIApplicationWindow::onUpdNeedsNetwork),
     204              :     // languages
     205              :     FXMAPFUNC(SEL_COMMAND,  MID_LANGUAGE_EN,    GUIApplicationWindow::onCmdChangeLanguage),
     206              :     FXMAPFUNC(SEL_UPDATE,   MID_LANGUAGE_EN,    GUIApplicationWindow::onUpdChangeLanguage),
     207              :     FXMAPFUNC(SEL_COMMAND,  MID_LANGUAGE_DE,    GUIApplicationWindow::onCmdChangeLanguage),
     208              :     FXMAPFUNC(SEL_UPDATE,   MID_LANGUAGE_DE,    GUIApplicationWindow::onUpdChangeLanguage),
     209              :     FXMAPFUNC(SEL_COMMAND,  MID_LANGUAGE_ES,    GUIApplicationWindow::onCmdChangeLanguage),
     210              :     FXMAPFUNC(SEL_UPDATE,   MID_LANGUAGE_ES,    GUIApplicationWindow::onUpdChangeLanguage),
     211              :     FXMAPFUNC(SEL_COMMAND,  MID_LANGUAGE_FR,    GUIApplicationWindow::onCmdChangeLanguage),
     212              :     FXMAPFUNC(SEL_UPDATE,   MID_LANGUAGE_FR,    GUIApplicationWindow::onUpdChangeLanguage),
     213              :     FXMAPFUNC(SEL_COMMAND,  MID_LANGUAGE_IT,    GUIApplicationWindow::onCmdChangeLanguage),
     214              :     FXMAPFUNC(SEL_UPDATE,   MID_LANGUAGE_IT,    GUIApplicationWindow::onUpdChangeLanguage),
     215              :     FXMAPFUNC(SEL_COMMAND,  MID_LANGUAGE_ZH,    GUIApplicationWindow::onCmdChangeLanguage),
     216              :     FXMAPFUNC(SEL_UPDATE,   MID_LANGUAGE_ZH,    GUIApplicationWindow::onUpdChangeLanguage),
     217              :     FXMAPFUNC(SEL_COMMAND,  MID_LANGUAGE_ZHT,   GUIApplicationWindow::onCmdChangeLanguage),
     218              :     FXMAPFUNC(SEL_UPDATE,   MID_LANGUAGE_ZHT,   GUIApplicationWindow::onUpdChangeLanguage),
     219              :     FXMAPFUNC(SEL_COMMAND,  MID_LANGUAGE_TR,    GUIApplicationWindow::onCmdChangeLanguage),
     220              :     FXMAPFUNC(SEL_UPDATE,   MID_LANGUAGE_TR,    GUIApplicationWindow::onUpdChangeLanguage),
     221              :     FXMAPFUNC(SEL_COMMAND,  MID_LANGUAGE_HU,    GUIApplicationWindow::onCmdChangeLanguage),
     222              :     FXMAPFUNC(SEL_UPDATE,   MID_LANGUAGE_HU,    GUIApplicationWindow::onUpdChangeLanguage),
     223              :     FXMAPFUNC(SEL_COMMAND,  MID_LANGUAGE_JA,    GUIApplicationWindow::onCmdChangeLanguage),
     224              :     FXMAPFUNC(SEL_UPDATE,   MID_LANGUAGE_JA,    GUIApplicationWindow::onUpdChangeLanguage),
     225              :     // keys
     226              :     FXMAPFUNC(SEL_KEYPRESS,              0,     GUIApplicationWindow::onKeyPress),
     227              :     FXMAPFUNC(SEL_KEYRELEASE,            0,     GUIApplicationWindow::onKeyRelease),
     228              :     // clipboard
     229              :     FXMAPFUNC(SEL_CLIPBOARD_REQUEST, 0, GUIApplicationWindow::onClipboardRequest),
     230              :     // events
     231              :     FXMAPFUNC(FXEX::SEL_THREAD_EVENT, ID_LOADTHREAD_EVENT,  GUIApplicationWindow::onLoadThreadEvent),
     232              :     FXMAPFUNC(FXEX::SEL_THREAD_EVENT, ID_RUNTHREAD_EVENT,   GUIApplicationWindow::onRunThreadEvent),
     233              :     FXMAPFUNC(FXEX::SEL_THREAD,       ID_LOADTHREAD_EVENT,  GUIApplicationWindow::onLoadThreadEvent),
     234              :     FXMAPFUNC(FXEX::SEL_THREAD,       ID_RUNTHREAD_EVENT,   GUIApplicationWindow::onRunThreadEvent),
     235              : };
     236              : 
     237              : // Object implementation
     238     81052117 : FXIMPLEMENT(GUIApplicationWindow, FXMainWindow, GUIApplicationWindowMap, ARRAYNUMBER(GUIApplicationWindowMap))
     239              : 
     240              : // ===========================================================================
     241              : // static members
     242              : // ===========================================================================
     243              : std::mt19937 GUIApplicationWindow::myGamingRNG;
     244              : 
     245              : 
     246              : // ===========================================================================
     247              : // member method definitions
     248              : // ===========================================================================
     249              : #ifdef _MSC_VER
     250              : #pragma warning(push)
     251              : #pragma warning(disable: 4355) // mask warning about "this" in initializers
     252              : #endif
     253         8030 : GUIApplicationWindow::GUIApplicationWindow(FXApp* a) :
     254              :     GUIMainWindow(a),
     255         8030 :     myFileMenuRecentNetworks(new FXMenuPane(this)),
     256         8030 :     myFileMenuRecentConfigs(new FXMenuPane(this)),
     257         8030 :     myRecentNetworks(a, "networks"),
     258         8030 :     myRecentConfigs(a, "configs"),
     259        24090 :     myLastStepEventMillis(SysUtils::getCurrentMillis() - MIN_DRAW_DELAY) {
     260              :     // init icons
     261         8030 :     GUIIconSubSys::initIcons(a);
     262              :     // init Textures
     263         8030 :     GUITextureSubSys::initTextures(a);
     264              :     // init cursors
     265         8030 :     GUICursorSubSys::initCursors(a);
     266              :     // disable tooltips
     267         8030 :     a->setTooltipTime(1000000000);
     268         8030 :     a->setTooltipPause(1000000000);
     269         8030 : }
     270              : #ifdef _MSC_VER
     271              : #pragma warning(pop)
     272              : #endif
     273              : 
     274              : 
     275              : GUIRunThread*
     276        85025 : GUIApplicationWindow::getRunner() {
     277        85025 :     return myRunThread;
     278              : }
     279              : 
     280              : 
     281              : void
     282         8030 : GUIApplicationWindow::dependentBuild(const bool isLibsumo) {
     283              :     // don't do this twice
     284         8030 :     if (hadDependentBuild) {
     285              :         return;
     286              :     }
     287         8030 :     hadDependentBuild = true;
     288         8030 :     setTarget(this);
     289              :     setSelector(MID_WINDOW);
     290              :     // build menu bar
     291         8030 :     myMenuBarDrag = new FXToolBarShell(this, GUIDesignToolBar);
     292         8030 :     myMenuBar = new FXMenuBar(myTopDock, myMenuBarDrag, GUIDesignToolbarMenuBar);
     293         8030 :     new FXToolBarGrip(myMenuBar, myMenuBar, FXMenuBar::ID_TOOLBARGRIP, GUIDesignToolBarGrip);
     294         8030 :     buildToolBars();
     295              :     // build the thread - io
     296              :     myLoadThreadEvent.setTarget(this);
     297              :     myLoadThreadEvent.setSelector(ID_LOADTHREAD_EVENT);
     298              :     myRunThreadEvent.setTarget(this);
     299              :     myRunThreadEvent.setSelector(ID_RUNTHREAD_EVENT);
     300              :     // build the status bar
     301         8030 :     myStatusbar = new FXStatusBar(this, GUIDesignStatusBar);
     302              :     {
     303              :         // build TraCi info
     304         8030 :         myTraCiFrame = new FXHorizontalFrame(myStatusbar, GUIDesignHorizontalFrameStatusBar);
     305        16060 :         auto button = GUIDesigns::buildFXButton(myTraCiFrame, "TraCI", "", "", nullptr, this, MID_TRACI_STATUS, GUIDesignButtonStatusBarFixed);
     306         8030 :         button->setBackColor(FXRGBA(253, 255, 206, 255));
     307         8030 :         if (TraCIServer::getInstance() == nullptr) {
     308         8030 :             myTraCiFrame->hide();
     309              :         }
     310              :         // build geo coordiantes
     311         8030 :         myGeoFrame = new FXHorizontalFrame(myStatusbar, GUIDesignHorizontalFrameStatusBar);
     312         8030 :         myGeoCoordinate = GUIDesigns::buildFXLabel(myGeoFrame, TL("N/A"), "", TL("Original coordinate (before coordinate transformation in netconvert)"), nullptr, LAYOUT_CENTER_Y);
     313              :         // build cartesian coordinates
     314         8030 :         myCartesianFrame = new FXHorizontalFrame(myStatusbar, GUIDesignHorizontalFrameStatusBar);
     315         8030 :         myCartesianCoordinate = GUIDesigns::buildFXLabel(myCartesianFrame, TL("N/A"), "", TL("Network coordinate"), nullptr, LAYOUT_CENTER_Y);
     316              :         // build buttons
     317        16060 :         myStatButtons.push_back(GUIDesigns::buildFXButton(myStatusbar, "-", "", "", GUIIconSubSys::getIcon(GUIIcon::GREENVEHICLE), this, MID_SHOWVEHSTATS));
     318        16060 :         myStatButtons.push_back(GUIDesigns::buildFXButton(myStatusbar, "-", "", "", GUIIconSubSys::getIcon(GUIIcon::GREENPERSON), this, MID_SHOWPERSONSTATS));
     319         8030 :         myStatButtons.back()->hide();
     320        16060 :         myStatButtons.push_back(GUIDesigns::buildFXButton(myStatusbar, "-", "", "", GUIIconSubSys::getIcon(GUIIcon::GREENCONTAINER), this, MID_SHOWVEHSTATS));
     321         8030 :         myStatButtons.back()->hide();
     322              :     }
     323              :     // make the window a mdi-window
     324         8030 :     myMainSplitter = new FXSplitter(this, GUIDesignSplitter | SPLITTER_VERTICAL | SPLITTER_REVERSED);
     325         8030 :     myMDIClient = new FXMDIClient(myMainSplitter, GUIDesignSplitterMDI);
     326         8030 :     myMDIMenu = new FXMDIMenu(this, myMDIClient);
     327         8030 :     new FXMDIWindowButton(myMenuBar, myMDIMenu, myMDIClient, FXMDIClient::ID_MDI_MENUWINDOW, GUIDesignMDIButtonLeft);
     328         8030 :     new FXMDIDeleteButton(myMenuBar, myMDIClient, FXMDIClient::ID_MDI_MENUCLOSE, GUIDesignMDIButtonRight);
     329         8030 :     new FXMDIRestoreButton(myMenuBar, myMDIClient, FXMDIClient::ID_MDI_MENURESTORE, GUIDesignMDIButtonRight);
     330         8030 :     new FXMDIMinimizeButton(myMenuBar, myMDIClient, FXMDIClient::ID_MDI_MENUMINIMIZE, GUIDesignMDIButtonRight);
     331              :     // build the message window
     332         8030 :     myMessageWindow = new GUIMessageWindow(myMainSplitter, this);
     333              :     // fill menu and tool bar
     334         8030 :     fillMenuBar();
     335         8030 :     myToolBar6->hide();
     336         8030 :     myToolBar7->hide();
     337         8030 :     myToolBar9->hide();
     338         8030 :     myToolBar10->hide();
     339              :     // build additional threads
     340         8030 :     myLoadThread = new GUILoadThread(getApp(), this, myEvents, myLoadThreadEvent, isLibsumo);
     341         8030 :     myRunThread = new GUIRunThread(getApp(), this, mySimDelay, myEvents, myRunThreadEvent);
     342              :     // set the status bar
     343         8030 :     setStatusBarText(TL("Ready."));
     344              :     // set the caption
     345         8030 :     setTitle(MFXUtils::getTitleText("SUMO " VERSION_STRING));
     346              :     // start the simulation-thread (it will loop until the application ends deciding by itself whether to perform a step or not)
     347         8030 :     myRunThread->start();
     348         8030 :     setIcon(GUIIconSubSys::getIcon(GUIIcon::SUMO));
     349         8030 :     setMiniIcon(GUIIconSubSys::getIcon(GUIIcon::SUMO_MINI));
     350              : }
     351              : 
     352              : 
     353              : void
     354         8030 : GUIApplicationWindow::create() {
     355         8030 :     setWindowSizeAndPos();
     356         8030 :     gCurrentFolder = getApp()->reg().readStringEntry("SETTINGS", "basedir", "");
     357         8030 :     FXMainWindow::create();
     358         8030 :     myMenuBarDrag->create();
     359         8030 :     myToolBarDrag1->create();
     360         8030 :     myToolBarDrag2->create();
     361         8030 :     myToolBarDrag3->create();
     362         8030 :     myToolBarDrag4->create();
     363         8030 :     myToolBarDrag5->create();
     364         8030 :     myToolBarDrag6->create();
     365         8030 :     myToolBarDrag7->create();
     366         8030 :     myFileMenu->create();
     367         8030 :     mySelectByPermissions->create();
     368         8030 :     myEditMenu->create();
     369         8030 :     mySettingsMenu->create();
     370         8030 :     myLocatorMenu->create();
     371         8030 :     myControlMenu->create();
     372         8030 :     myWindowMenu->create();
     373         8030 :     myLanguageMenu->create();
     374         8030 :     myHelpMenu->create();
     375         8030 :     FXint textWidth = getApp()->getNormalFont()->getTextWidth("8", 1) * 24;
     376         8030 :     myCartesianFrame->setWidth(textWidth);
     377         8030 :     myGeoFrame->setWidth(textWidth);
     378         8030 :     if (myTestFrame) {
     379            0 :         myTestFrame->setWidth(textWidth);
     380              :     }
     381              : 
     382         8030 :     show(PLACEMENT_DEFAULT);
     383        16060 :     if (!OptionsCont::getOptions().isSet("window-size")) {
     384         8026 :         if (getApp()->reg().readIntEntry("SETTINGS", "maximized", 0) == 1) {
     385            0 :             maximize();
     386              :         }
     387              :     }
     388         8030 :     myShowTimeAsHMS = (getApp()->reg().readIntEntry("gui", "timeasHMS", 0) == 1);
     389         8030 :     myAlternateSimDelay = getApp()->reg().readIntEntry("gui", "alternateSimDelay", 100);
     390         8030 :     const std::string& onlineMaps = getApp()->reg().readStringEntry("gui", "onlineMaps", "");
     391        24090 :     for (const std::string& entry : StringTokenizer(onlineMaps, "\n").getVector()) {
     392            0 :         const std::vector<std::string> split = StringTokenizer(entry, "\t").getVector();
     393            0 :         if (split.size() == 2) {
     394            0 :             myOnlineMaps[split[0]] = split[1];
     395              :         }
     396         8030 :     }
     397         8030 :     if (myOnlineMaps.empty()) {
     398         8030 :         myOnlineMaps["GeoHack"] = "https://geohack.toolforge.org/geohack.php?params=%lat;%lon_scale:1000";
     399         8030 :         myOnlineMaps["Google Maps"] = "https://www.google.com/maps?ll=%lat,%lon&t=h&z=18";
     400        16060 :         myOnlineMaps["OSM"] = "https://www.openstreetmap.org/?mlat=%lat&mlon=%lon&zoom=18&layers=M";
     401              :     }
     402         8030 :     updateTimeLCDTooltip();
     403         8030 : }
     404              : 
     405              : 
     406        16010 : GUIApplicationWindow::~GUIApplicationWindow() {
     407         8005 :     myRunThread->prepareDestruction();
     408         8005 :     myRunThread->join();
     409         8004 :     closeAllWindows();
     410              :     // close icons
     411         8004 :     GUIIconSubSys::close();
     412         8004 :     GUICursorSubSys::close();
     413              :     // delete visual
     414         8004 :     delete myGLVisual;
     415              :     // delete some non-parented windows
     416         8004 :     delete myToolBarDrag1;
     417         8004 :     delete mySimDelayTarget;
     418              :     // delete rest of elements
     419         8004 :     delete myFileMenuRecentNetworks;
     420         8004 :     delete myFileMenuRecentConfigs;
     421         8004 :     delete myRunThread;
     422         8004 :     delete myFileMenu;
     423         8004 :     delete myEditMenu;
     424         8004 :     delete mySelectByPermissions;
     425         8004 :     delete mySettingsMenu;
     426         8004 :     delete myLocatorMenu;
     427         8004 :     delete myControlMenu;
     428         8004 :     delete myLanguageMenu;
     429         8004 :     delete myWindowMenu;
     430         8004 :     delete myHelpMenu;
     431         8004 :     delete myLoadThread;
     432              : 
     433        15890 :     while (!myEvents.empty()) {
     434              :         // get the next event
     435         7886 :         GUIEvent* e = myEvents.top();
     436         7886 :         myEvents.pop();
     437         7886 :         delete e;
     438              :     }
     439         8004 :     for (auto item : myHotkeyPress) {
     440            0 :         delete item.second;
     441              :     }
     442         8004 :     for (auto item : myHotkeyRelease) {
     443            0 :         delete item.second;
     444              :     }
     445        24013 : }
     446              : 
     447              : 
     448              : void
     449            0 : GUIApplicationWindow::detach() {
     450            0 :     FXMainWindow::detach();
     451            0 :     myMenuBarDrag->detach();
     452            0 :     myToolBarDrag1->detach();
     453            0 : }
     454              : 
     455              : 
     456              : void
     457         8030 : GUIApplicationWindow::addToWindowsMenu(FXMenuPane* /*menuPane*/) {
     458              :     // unused, implement in children
     459         8030 : }
     460              : 
     461              : 
     462              : void
     463         8030 : GUIApplicationWindow::fillMenuBar() {
     464              :     // build file menu
     465         8030 :     myFileMenu = new FXMenuPane(this);
     466         8030 :     GUIDesigns::buildFXMenuTitle(myMenuBar, TL("&File"), nullptr, myFileMenu);
     467        24090 :     GUIDesigns::buildFXMenuCommandShortcut(myFileMenu,
     468        16060 :                                            TL("New Window"), "Ctrl+Shift+N", TL("Open a new sumo-gui window."),
     469              :                                            nullptr, this, MID_HOTKEY_CTRL_SHIFT_N_NEWWINDOW);
     470         8030 :     new FXMenuSeparator(myFileMenu);
     471        32120 :     GUIDesigns::buildFXMenuCommandShortcut(myFileMenu,
     472        16060 :                                            TL("&Open Simulation..."), "Ctrl+O", TL("Open a simulation (Configuration file)."),
     473              :                                            GUIIconSubSys::getIcon(GUIIcon::OPEN_SUMOCONFIG), this, MID_HOTKEY_CTRL_O_OPENSIMULATION_OPENNETWORK);
     474        32120 :     GUIDesigns::buildFXMenuCommandShortcut(myFileMenu,
     475        16060 :                                            TL("Open &Network..."), "Ctrl+N", TL("Open a network."),
     476              :                                            GUIIconSubSys::getIcon(GUIIcon::OPEN_NET), this, MID_HOTKEY_CTRL_N_OPENNETWORK_NEWNETWORK);
     477        32120 :     GUIDesigns::buildFXMenuCommandShortcut(myFileMenu,
     478        16060 :                                            TL("Open Shapes "), "Ctrl+P", TL("Load POIs and Polygons for visualization."),
     479              :                                            GUIIconSubSys::getIcon(GUIIcon::OPEN_SHAPES), this, MID_HOTKEY_CTRL_P_OPENSHAPES);
     480        32120 :     GUIDesigns::buildFXMenuCommandShortcut(myFileMenu,
     481        16060 :                                            TL("Open EdgeData "), "Ctrl+U", TL("Load edge related data for visualization."),
     482              :                                            GUIIconSubSys::getIcon(GUIIcon::OPEN_NET), this, MID_HOTKEY_CTRL_U_OPENEDGEDATA);
     483        32120 :     GUIDesigns::buildFXMenuCommandShortcut(myFileMenu,
     484        16060 :                                            TL("&Reload"), "Ctrl+R", TL("Reloads the simulation / the network."),
     485              :                                            GUIIconSubSys::getIcon(GUIIcon::RELOAD), this, MID_HOTKEY_CTRL_R_RELOAD);
     486        32120 :     GUIDesigns::buildFXMenuCommandShortcut(myFileMenu,
     487        16060 :                                            TL("Quick-Reload"), "Ctrl+0", TL("Reloads the simulation (but not network)."),
     488              :                                            GUIIconSubSys::getIcon(GUIIcon::RELOAD), this, MID_HOTKEY_CTRL_QUICK_RELOAD);
     489         8030 :     new FXMenuSeparator(myFileMenu);
     490        32120 :     GUIDesigns::buildFXMenuCommandShortcut(myFileMenu,
     491        16060 :                                            TL("Save Configuration"), "Ctrl+Shift+S", TL("Save current options as a configuration file."),
     492              :                                            GUIIconSubSys::getIcon(GUIIcon::SAVE_SUMOCONFIG), this, MID_HOTKEY_CTRL_SHIFT_S_SAVESUMOCONFIG);
     493        32120 :     GUIDesigns::buildFXMenuCommandShortcut(myFileMenu,
     494        16060 :                                            TL("Close"), "Ctrl+W", TL("Close the simulation."),
     495              :                                            GUIIconSubSys::getIcon(GUIIcon::CLOSE), this, MID_HOTKEY_CTRL_W_CLOSESIMULATION);
     496         8030 :     new FXMenuSeparator(myFileMenu);
     497              :     // build recent files
     498         8030 :     buildRecentNetworks(myFileMenu, myFileMenuRecentNetworks);
     499         8030 :     buildRecentConfigs(myFileMenu, myFileMenuRecentConfigs);
     500         8030 :     new FXMenuSeparator(myFileMenu);
     501        24090 :     GUIDesigns::buildFXMenuCommandShortcut(myFileMenu,
     502        16060 :                                            TL("&Quit"), "Ctrl+Q", TL("Quit the Application."),
     503              :                                            nullptr, this, MID_HOTKEY_CTRL_Q_CLOSE);
     504              :     // build edit menu
     505         8030 :     mySelectByPermissions = new FXMenuPane(this);
     506         8030 :     std::vector<std::string> vehicleClasses = SumoVehicleClassStrings.getStrings();
     507       281050 :     for (const auto& vehicleClass : vehicleClasses) {
     508       273020 :         GUIDesigns::buildFXMenuCommand(mySelectByPermissions, vehicleClass, VClassIcons::getVClassIcon(SumoVehicleClassStrings.get(vehicleClass)), this, MID_HOTKEY_CTRL_E_EDITSELECTION_LOADNETEDITCONFIG);
     509              :     }
     510         8030 :     myEditMenu = new FXMenuPane(this);
     511         8030 :     GUIDesigns::buildFXMenuTitle(myMenuBar, TL("&Edit"), nullptr, myEditMenu);
     512        32120 :     GUIDesigns::buildFXMenuCommandShortcut(myEditMenu,
     513        16060 :                                            TL("Edit Selected..."), "Ctrl+E", TL("Opens a dialog for editing the list of selected items."),
     514              :                                            GUIIconSubSys::getIcon(GUIIcon::FLAG), this, MID_HOTKEY_CTRL_E_EDITSELECTION_LOADNETEDITCONFIG);
     515         8030 :     mySelectLanesMenuCascade = new FXMenuCascade(myEditMenu, TL("Select lanes which allow..."), GUIIconSubSys::getIcon(GUIIcon::FLAG), mySelectByPermissions);
     516         8030 :     mySelectLanesMenuCascade->setHelpText(TL("Opens a menu for selecting a vehicle class by which to selected lanes."));
     517         8030 :     new FXMenuSeparator(myEditMenu);
     518        32120 :     GUIDesigns::buildFXMenuCommandShortcut(myEditMenu,
     519        16060 :                                            TL("Set Breakpoint"), "B", TL("Sets a breakpoint at the current simulation step"),
     520              :                                            GUIIconSubSys::getIcon(GUIIcon::APP_BREAKPOINTS), this, MID_HOTKEY_B_BREAKPOINT);
     521        32120 :     GUIDesigns::buildFXMenuCommandShortcut(myEditMenu,
     522        16060 :                                            TL("Set Breakpoint with offset"), "Alt+B", TL("Sets a breakpoint at the current simulation step + offset configured in application settings"),
     523              :                                            GUIIconSubSys::getIcon(GUIIcon::APP_BREAKPOINTS), this, MID_HOTKEY_ALT_B_BREAKPOINT_EARLY);
     524        32120 :     GUIDesigns::buildFXMenuCommandShortcut(myEditMenu,
     525        16060 :                                            TL("Edit Breakpoints"), "Ctrl+B", TL("Opens a dialog for editing breakpoints."),
     526              :                                            GUIIconSubSys::getIcon(GUIIcon::APP_BREAKPOINTS), this, MID_HOTKEY_CTRL_B_EDITBREAKPOINT_OPENDATAELEMENTS);
     527        32120 :     GUIDesigns::buildFXMenuCommandShortcut(myEditMenu,
     528        16060 :                                            TL("Edit Visualisation"), "F9", TL("Opens a dialog for editing visualization settings."),
     529              :                                            GUIIconSubSys::getIcon(GUIIcon::COLORWHEEL), this, MID_HOTKEY_F9_EDIT_VIEWSCHEME);
     530        32120 :     GUIDesigns::buildFXMenuCommandShortcut(myEditMenu,
     531        16060 :                                            TL("Edit Viewport"), "Ctrl+I", TL("Opens a dialog for editing viewing area, zoom and rotation."),
     532              :                                            GUIIconSubSys::getIcon(GUIIcon::EDITVIEWPORT), this, MID_HOTKEY_CTRL_I_EDITVIEWPORT);
     533         8030 :     new FXMenuSeparator(myEditMenu);
     534              :     // add open in sumo options
     535         8030 :     myLoadAdditionalsInNetedit = GUIDesigns::buildFXMenuCheckbox(myEditMenu, TL("Load additionals in netedit"), TL("Load additionals in netedit."), this, MID_TOOLBAREDIT_LOADADDITIONALS);
     536         8030 :     myLoadAdditionalsInNetedit->setCheck(TRUE);
     537         8030 :     myLoadDemandInNetedit = GUIDesigns::buildFXMenuCheckbox(myEditMenu, TL("Load demand in netedit"), TL("Load demand in netedit."), this, MID_TOOLBAREDIT_LOADDEMAND);
     538         8030 :     myLoadDemandInNetedit->setCheck(FALSE);
     539        24090 :     myOpenInNetedit = GUIDesigns::buildFXMenuCommandShortcut(myEditMenu,
     540        16060 :                       TL("Open in netedit"), "Ctrl+T", TL("Opens current simulation in NETEDIT."),
     541              :                       GUIIconSubSys::getIcon(GUIIcon::NETEDIT_MINI), this, MID_HOTKEY_CTRL_T_OPENNETEDIT_OPENSUMO);
     542        24090 :     myOpenNetInNetedit = GUIDesigns::buildFXMenuCommandShortcut(myEditMenu,
     543        16060 :                       TL("Open network in netedit"), "Ctrl+Shift+T", TL("Opens current network in NETEDIT."),
     544              :                       GUIIconSubSys::getIcon(GUIIcon::NETEDIT_MINI), this, MID_HOTKEY_CTRL_SHIFT_T_OPEN_NET);
     545              :     // build settings menu
     546         8030 :     mySettingsMenu = new FXMenuPane(this);
     547         8030 :     GUIDesigns::buildFXMenuTitle(myMenuBar, TL("&Settings"), nullptr, mySettingsMenu);
     548        24090 :     GUIDesigns::buildFXMenuCommandShortcut(mySettingsMenu,
     549        16060 :                                            TL("Application Settings"), "Ctrl+H", TL("Open a Dialog for Application Settings editing."),
     550              :                                            nullptr, this, MID_HOTKEY_CTRL_H_APPSETTINGS_OPENEDGETYPES);
     551        16060 :     myGamingModeCheckbox = new FXMenuCheck(mySettingsMenu,
     552         8030 :                                            TL("Gaming Mode\tCtrl+G\tToggle gaming mode on/off."),
     553         8030 :                                            this, MID_HOTKEY_CTRL_G_GAMINGMODE_TOGGLEGRID);
     554        32120 :     GUIDesigns::buildFXMenuCommandShortcut(mySettingsMenu,
     555        16060 :                                            TL("Full Screen Mode"), "Ctrl+F", TL("Toggle full screen mode on/off."),
     556              :                                            GUIIconSubSys::getIcon(GUIIcon::FULL_SCREEN), this, MID_HOTKEY_CTRL_F_FULSCREENMODE);
     557              :     // build Locate menu
     558         8030 :     myLocatorMenu = new FXMenuPane(this);
     559         8030 :     GUIDesigns::buildFXMenuTitle(myMenuBar, TL("&Locate"), nullptr, myLocatorMenu);
     560        32120 :     GUIDesigns::buildFXMenuCommandShortcut(myLocatorMenu,
     561        16060 :                                            TL("&Junctions"), "Shift+J", TL("Open a dialog for locating a Junction."),
     562              :                                            GUIIconSubSys::getIcon(GUIIcon::LOCATEJUNCTION), this, MID_HOTKEY_SHIFT_J_LOCATEJUNCTION);
     563        32120 :     GUIDesigns::buildFXMenuCommandShortcut(myLocatorMenu,
     564        16060 :                                            TL("&Edges"), "Shift+E", TL("Open a dialog for locating an Edge."),
     565              :                                            GUIIconSubSys::getIcon(GUIIcon::LOCATEEDGE), this, MID_HOTKEY_SHIFT_E_LOCATEEDGE);
     566        32120 :     GUIDesigns::buildFXMenuCommandShortcut(myLocatorMenu,
     567        16060 :                                            TL("&Vehicles"), "Shift+V", TL("Open a dialog for locating a Vehicle."),
     568              :                                            GUIIconSubSys::getIcon(GUIIcon::LOCATEVEHICLE), this, MID_HOTKEY_SHIFT_V_LOCATEVEHICLE);
     569        32120 :     GUIDesigns::buildFXMenuCommandShortcut(myLocatorMenu,
     570        16060 :                                            TL("&Persons"), "Shift+P", TL("Open a dialog for locating a Person."),
     571              :                                            GUIIconSubSys::getIcon(GUIIcon::LOCATEPERSON), this, MID_HOTKEY_SHIFT_P_LOCATEPERSON);
     572        32120 :     GUIDesigns::buildFXMenuCommandShortcut(myLocatorMenu,
     573        16060 :                                            TL("&Container"), "Shift+C", TL("Open a dialog for locating a Container."),
     574              :                                            GUIIconSubSys::getIcon(GUIIcon::LOCATECONTAINER), this, MID_HOTKEY_SHIFT_C_LOCATECONTAINER);
     575        32120 :     GUIDesigns::buildFXMenuCommandShortcut(myLocatorMenu,
     576        16060 :                                            TL("&TLS"), "Shift+T", TL("Open a dialog for locating a Traffic Light."),
     577              :                                            GUIIconSubSys::getIcon(GUIIcon::LOCATETLS), this, MID_HOTKEY_SHIFT_T_LOCATETLS);
     578        32120 :     GUIDesigns::buildFXMenuCommandShortcut(myLocatorMenu,
     579        16060 :                                            TL("&Additional"), "Shift+A", TL("Open a dialog for locating an Additional Structure."),
     580              :                                            GUIIconSubSys::getIcon(GUIIcon::LOCATEADD), this, MID_HOTKEY_SHIFT_A_LOCATEADDITIONAL);
     581        32120 :     GUIDesigns::buildFXMenuCommandShortcut(myLocatorMenu,
     582        16060 :                                            TL("P&oI"), "Shift+O", TL("Open a dialog for locating a Point of Interest."),
     583              :                                            GUIIconSubSys::getIcon(GUIIcon::LOCATEPOI), this, MID_HOTKEY_SHIFT_O_LOCATEPOI);
     584        32120 :     GUIDesigns::buildFXMenuCommandShortcut(myLocatorMenu,
     585        16060 :                                            TL("Po&lygon"), "Shift+L", TL("Open a dialog for locating a Polygon."),
     586              :                                            GUIIconSubSys::getIcon(GUIIcon::LOCATEPOLY), this, MID_HOTKEY_SHIFT_L_LOCATEPOLY);
     587         8030 :     new FXMenuSeparator(myLocatorMenu);
     588        16060 :     GUIDesigns::buildFXMenuCheckbox(myLocatorMenu, TL("Show Internal Structures"), TL("Show internal junctions and streets in locator dialog."), this, MID_LISTINTERNAL);
     589        16060 :     FXMenuCheck* listParking = GUIDesigns::buildFXMenuCheckbox(myLocatorMenu, TL("Show Parking Vehicles"), TL("Show parking vehicles in locator dialog."), this, MID_LISTPARKING);
     590         8030 :     listParking->setCheck(myListParking);
     591        16060 :     GUIDesigns::buildFXMenuCheckbox(myLocatorMenu, TL("Show vehicles outside the road network"), TL("Show vehicles that are teleporting or driving remote-controlled outside the road network in locator dialog."), this, MID_LISTTELEPORTING);
     592              :     // build control menu
     593              :     // the shortcut designator is not only at text in the submenu but also defines the real shortcut key assigned with it!
     594              :     // secondary shortcuts (ctrl+A, ctrl+S, ctrl+D) are defined in GUIShortcutsSubSys::buildSUMOAccelerators
     595         8030 :     myControlMenu = new FXMenuPane(this);
     596         8030 :     GUIDesigns::buildFXMenuTitle(myMenuBar, TL("Simulation"), nullptr, myControlMenu);
     597        32120 :     GUIDesigns::buildFXMenuCommandShortcut(myControlMenu,
     598        16060 :                                            TL("Run"), "A,space", TL("Start/ Resume the simulation."),
     599              :                                            GUIIconSubSys::getIcon(GUIIcon::START), this, MID_HOTKEY_CTRL_A_STARTSIMULATION_OPENADDITIONALELEMENTS);
     600        32120 :     GUIDesigns::buildFXMenuCommandShortcut(myControlMenu,
     601         8030 :                                            TLC("Simulation", "Stop"), "S,space", TL("Halt the simulation."),
     602              :                                            GUIIconSubSys::getIcon(GUIIcon::STOP), this, MID_HOTKEY_CTRL_S_STOPSIMULATION_SAVENETWORK);
     603        32120 :     GUIDesigns::buildFXMenuCommandShortcut(myControlMenu,
     604        16060 :                                            TL("Step"), "D", TL("Perform one simulation step."),
     605              :                                            GUIIconSubSys::getIcon(GUIIcon::STEP), this, MID_HOTKEY_CTRL_D_SINGLESIMULATIONSTEP_OPENDEMANDELEMENTS);
     606        24090 :     GUIDesigns::buildFXMenuCommandShortcut(myControlMenu,
     607        16060 :                                            TL("Delay+"), "PgUp", TL("Increase simulation step delay."), nullptr, this, MID_DELAY_INC);
     608        24090 :     GUIDesigns::buildFXMenuCommandShortcut(myControlMenu,
     609        16060 :                                            TL("Delay-"), "PgDn", TL("Decrease simulation step delay."), nullptr, this, MID_DELAY_DEC);
     610        32120 :     GUIDesigns::buildFXMenuCommandShortcut(myControlMenu,
     611        16060 :                                            TL("Save"), "", TL("Save the current simulation state to a file."),
     612              :                                            GUIIconSubSys::getIcon(GUIIcon::SAVE), this, MID_SIMSAVE);
     613        32120 :     GUIDesigns::buildFXMenuCommandShortcut(myControlMenu,
     614        16060 :                                            TL("Load"), "", TL("Load simulation state for the current network from file."),
     615              :                                            GUIIconSubSys::getIcon(GUIIcon::OPEN), this, MID_SIMLOAD);
     616              :     // build windows menu
     617         8030 :     myWindowMenu = new FXMenuPane(this);
     618         8030 :     GUIDesigns::buildFXMenuTitle(myMenuBar, TL("&Window"), nullptr, myWindowMenu);
     619        16060 :     GUIDesigns::buildFXMenuCommandShortcut(myWindowMenu, TL("Open new view"), "", TL("Open a new microscopic view."), GUIIconSubSys::getIcon(GUIIcon::MICROVIEW), this, MID_NEW_MICROVIEW);
     620              : #ifdef HAVE_OSG
     621        16060 :     GUIDesigns::buildFXMenuCommandShortcut(myWindowMenu, TL("Open new 3D view"), "", TL("Open a new 3D view."), GUIIconSubSys::getIcon(GUIIcon::OSGVIEW), this, MID_NEW_OSGVIEW);
     622              : #endif
     623        24090 :     GUIDesigns::buildFXMenuCommandShortcut(myWindowMenu,
     624        16060 :                                            TL("Tile &Horizontally"), "", TL("Tile the views horizontally."),
     625         8030 :                                            GUIIconSubSys::getIcon(GUIIcon::WINDOWS_TILE_HORI), myMDIClient, FXMDIClient::ID_MDI_TILEHORIZONTAL);
     626        24090 :     GUIDesigns::buildFXMenuCommandShortcut(myWindowMenu,
     627        16060 :                                            TL("Tile &Vertically"), "", TL("Tile the views vertically."),
     628         8030 :                                            GUIIconSubSys::getIcon(GUIIcon::WINDOWS_TILE_VERT), myMDIClient, FXMDIClient::ID_MDI_TILEVERTICAL);
     629        24090 :     GUIDesigns::buildFXMenuCommandShortcut(myWindowMenu,
     630        16060 :                                            TL("Cascade"), "", TL("Cascade the views."),
     631              :                                            GUIIconSubSys::getIcon(GUIIcon::WINDOWS_CASCADE),
     632         8030 :                                            myMDIClient, FXMDIClient::ID_MDI_CASCADE);
     633        24090 :     GUIDesigns::buildFXMenuCommandShortcut(myWindowMenu,
     634         8030 :                                            TL("&Close"), "", TL("Close the selected view."),
     635         8030 :                                            nullptr, myMDIClient, FXMDIClient::ID_MDI_CLOSE);
     636         8030 :     FXMenuSeparator* sep2 = new FXMenuSeparator(myWindowMenu);
     637         8030 :     sep2->setTarget(myMDIClient);
     638              :     sep2->setSelector(FXMDIClient::ID_MDI_ANY);
     639              :     // for whatever reason, sonar complains in the next line that sep2 may leak, but fox does the cleanup
     640         8030 :     GUIDesigns::buildFXMenuCommand(myWindowMenu, "", nullptr, myMDIClient, FXMDIClient::ID_MDI_1);  // NOSONAR
     641         8030 :     GUIDesigns::buildFXMenuCommand(myWindowMenu, "", nullptr, myMDIClient, FXMDIClient::ID_MDI_2);
     642         8030 :     GUIDesigns::buildFXMenuCommand(myWindowMenu, "", nullptr, myMDIClient, FXMDIClient::ID_MDI_3);
     643         8030 :     GUIDesigns::buildFXMenuCommand(myWindowMenu, "", nullptr, myMDIClient, FXMDIClient::ID_MDI_4);
     644         8030 :     GUIDesigns::buildFXMenuCommand(myWindowMenu, TL("&Others..."), nullptr, myMDIClient, FXMDIClient::ID_MDI_OVER_5);
     645              : 
     646         8030 :     new FXMenuSeparator(myWindowMenu);
     647        16060 :     GUIDesigns::buildFXMenuCheckbox(myWindowMenu, TL("Show Status Line"), TL("Toggle the Status Bar on/off."), myStatusbar, FXWindow::ID_TOGGLESHOWN);
     648        16060 :     GUIDesigns::buildFXMenuCheckbox(myWindowMenu, TL("Show Message Window"), TL("Toggle the Message Window on/off."), myMessageWindow, FXWindow::ID_TOGGLESHOWN);
     649        16060 :     GUIDesigns::buildFXMenuCheckbox(myWindowMenu, TL("Show Simulation Time"), TL("Toggle the Simulation Time on/off."), myToolBar3, FXWindow::ID_TOGGLESHOWN);
     650        16060 :     GUIDesigns::buildFXMenuCheckbox(myWindowMenu, TL("Show Simulation Delay"), TL("Toggle the Simulation Delay Entry on/off."), myToolBar4, FXWindow::ID_TOGGLESHOWN);
     651         8030 :     addToWindowsMenu(myWindowMenu);
     652              : 
     653         8030 :     new FXMenuSeparator(myWindowMenu);
     654        32120 :     GUIDesigns::buildFXMenuCommandShortcut(myWindowMenu,
     655        16060 :                                            TL("Clear Message Window"), "", TL("Clear the message window."),
     656              :                                            GUIIconSubSys::getIcon(GUIIcon::CLEARMESSAGEWINDOW), this, MID_CLEARMESSAGEWINDOW);
     657              :     // build windows menu
     658         8030 :     buildLanguageMenu(myMenuBar);
     659              :     // build help menu
     660         8030 :     myHelpMenu = new FXMenuPane(this);
     661         8030 :     GUIDesigns::buildFXMenuTitle(myMenuBar,
     662         8030 :                                  TL("&Help"),
     663              :                                  nullptr, myHelpMenu);
     664        16060 :     GUIDesigns::buildFXMenuCommandShortcut(myHelpMenu, TL("&Online Documentation"), "F1", TL("Open Online documentation."),
     665              :                                            nullptr, this, MID_HOTKEY_F1_ONLINEDOCUMENTATION);
     666         8030 :     new FXMenuSeparator(myHelpMenu);
     667        16060 :     GUIDesigns::buildFXMenuCommandShortcut(myHelpMenu, TL("&Changelog"), "", TL("Open Changelog."),
     668              :                                            nullptr, this, MID_CHANGELOG);
     669        16060 :     GUIDesigns::buildFXMenuCommandShortcut(myHelpMenu, TL("&Hotkeys"), "", TL("Open Hotkeys."),
     670              :                                            nullptr, this, MID_HOTKEYS);
     671        16060 :     GUIDesigns::buildFXMenuCommandShortcut(myHelpMenu, TL("&Tutorial"), "", TL("Open Tutorial."),
     672              :                                            nullptr, this, MID_TUTORIAL);
     673        16060 :     GUIDesigns::buildFXMenuCommandShortcut(myHelpMenu, TL("&Feedback"), "", TL("Open feedback dialog."),
     674              :                                            nullptr, this, MID_FEEDBACK);
     675         8030 :     new FXMenuSeparator(myHelpMenu);
     676        16060 :     GUIDesigns::buildFXMenuCommandShortcut(myHelpMenu, TL("&About"), "F12", TL("About sumo-gui."),
     677              :                                            GUIIconSubSys::getIcon(GUIIcon::SUMO_MINI), this, MID_HOTKEY_F12_ABOUT);
     678              :     // build SUMO Accelerators (hotkeys)
     679         8030 :     GUIShortcutsSubSys::buildAccelerators(getAccelTable(), this, true);
     680         8030 : }
     681              : 
     682              : 
     683              : void
     684         8030 : GUIApplicationWindow::buildToolBars() {
     685              :     // file and simulation tool bar
     686              :     {
     687         8030 :         myToolBarDrag1 = new FXToolBarShell(this, GUIDesignToolBar);
     688         8030 :         myToolBar1 = new FXToolBar(myTopDock, myToolBarDrag1, GUIDesignToolBarRaisedNextTop);
     689         8030 :         new FXToolBarGrip(myToolBar1, myToolBar1, FXToolBar::ID_TOOLBARGRIP, GUIDesignToolBarGrip);
     690              :         // build file tools
     691        16060 :         new MFXButtonTooltip(myToolBar1, myStaticTooltipMenu, TL("\tOpen simulation\tOpen a simulation (Configuration file)."),
     692         8030 :                              GUIIconSubSys::getIcon(GUIIcon::OPEN_SUMOCONFIG), this, MID_HOTKEY_CTRL_O_OPENSIMULATION_OPENNETWORK, GUIDesignButtonToolbar);
     693        16060 :         new MFXButtonTooltip(myToolBar1, myStaticTooltipMenu, TL("\tOpen network\tOpen a network."),
     694         8030 :                              GUIIconSubSys::getIcon(GUIIcon::OPEN_NET), this, MID_HOTKEY_CTRL_N_OPENNETWORK_NEWNETWORK, GUIDesignButtonToolbar);
     695        16060 :         new MFXButtonTooltip(myToolBar1, myStaticTooltipMenu, TL("\tReload\tReloads the simulation / the network."),
     696         8030 :                              GUIIconSubSys::getIcon(GUIIcon::RELOAD), this, MID_HOTKEY_CTRL_R_RELOAD, GUIDesignButtonToolbar);
     697              :     }
     698              :     // simulation toolbar
     699              :     {
     700         8030 :         myToolBarDrag2 = new FXToolBarShell(this, GUIDesignToolBar);
     701         8030 :         myToolBar2 = new FXToolBar(myTopDock, myToolBarDrag2, GUIDesignToolBarRaisedSameTop);
     702         8030 :         new FXToolBarGrip(myToolBar2, myToolBar2, FXToolBar::ID_TOOLBARGRIP, GUIDesignToolBarGrip);
     703              :         // build simulation tools
     704        16060 :         new MFXButtonTooltip(myToolBar2, myStaticTooltipMenu, TL("\tRun\tStart/Resume the loaded simulation."),
     705         8030 :                              GUIIconSubSys::getIcon(GUIIcon::START), this, MID_HOTKEY_CTRL_A_STARTSIMULATION_OPENADDITIONALELEMENTS, GUIDesignButtonToolbar);
     706        16060 :         new MFXButtonTooltip(myToolBar2, myStaticTooltipMenu, TL("\tStop\tHalt the running simulation."),
     707         8030 :                              GUIIconSubSys::getIcon(GUIIcon::STOP), this, MID_HOTKEY_CTRL_S_STOPSIMULATION_SAVENETWORK, GUIDesignButtonToolbar);
     708        16060 :         new MFXButtonTooltip(myToolBar2, myStaticTooltipMenu, TL("\tStep\tPerform a single simulation step."),
     709         8030 :                              GUIIconSubSys::getIcon(GUIIcon::STEP), this, MID_HOTKEY_CTRL_D_SINGLESIMULATIONSTEP_OPENDEMANDELEMENTS, GUIDesignButtonToolbar);
     710              :     }
     711              :     // Simulation Step Display
     712              :     {
     713         8030 :         myToolBarDrag3 = new FXToolBarShell(this, GUIDesignToolBar);
     714         8030 :         myToolBar3 = new FXToolBar(myTopDock, myToolBarDrag3, GUIDesignToolBarRaisedSameTop);
     715         8030 :         new FXToolBarGrip(myToolBar3, myToolBar3, FXToolBar::ID_TOOLBARGRIP, GUIDesignToolBarGrip);
     716         8030 :         new MFXButtonTooltip(myToolBar3, myStaticTooltipMenu, TL("Time:\tToggle between time formats\tToggle between seconds and hour:minute:seconds display."), nullptr, this, MID_TIME_TOGGLE, GUIDesignButtonToolbarText);
     717              : 
     718         8030 :         myLCDLabel = new MFXLCDLabel(myToolBar3, myStaticTooltipMenu, 16, nullptr, 0, JUSTIFY_RIGHT);
     719         8030 :         myLCDLabel->setHorizontal(2);
     720         8030 :         myLCDLabel->setVertical(6);
     721         8030 :         myLCDLabel->setThickness(2);
     722         8030 :         myLCDLabel->setGroove(2);
     723         8030 :         myLCDLabel->setText("----------------");
     724              :     }
     725              :     // Simulation Delay
     726              :     {
     727         8030 :         myToolBarDrag4 = new FXToolBarShell(this, GUIDesignToolBar);
     728         8030 :         myToolBar4 = new FXToolBar(myTopDock, myToolBarDrag4, GUIDesignToolBarRaisedSameTop);
     729         8030 :         new FXToolBarGrip(myToolBar4, myToolBar4, FXToolBar::ID_TOOLBARGRIP, GUIDesignToolBarGrip);
     730         8030 :         new MFXButtonTooltip(myToolBar4, myStaticTooltipMenu, TL("Delay (ms):\tDelay per simulated second\tDelay per simulated second. Click to toggle between the last two delay values."), nullptr, this, MID_DELAY_TOGGLE, GUIDesignButtonToolbarText);
     731              :         // create spinner for delay
     732         8030 :         mySimDelay = 0;
     733         8030 :         mySimDelayTarget = new FXDataTarget(mySimDelay);
     734         8030 :         mySimDelaySpinner = new MFXRealSpinner(myToolBar4, 7, mySimDelayTarget, FXDataTarget::ID_VALUE, GUIDesignSpinDial);
     735              :         // create slider
     736         8030 :         mySimDelaySlider = new FXSlider(myToolBar4, mySimDelayTarget, FXDataTarget::ID_VALUE, GUIDesignSlider);
     737         8030 :         mySimDelaySlider->setRange(0, 1000);
     738         8030 :         mySimDelaySlider->setHeadSize(10);
     739         8030 :         mySimDelaySlider->setIncrement(50);
     740         8030 :         mySimDelaySlider->setTickDelta(100);
     741         8030 :         mySimDelaySlider->setValue((int)mySimDelay);
     742              :         //mySimDelayTarget->setNumberFormat(0);
     743              :         //mySimDelayTarget->setIncrements(1, 10, 10);
     744         8030 :         mySimDelaySpinner->setIncrement(10);
     745         8030 :         mySimDelaySpinner->setRange(0, 10000);
     746         8030 :         mySimDelaySpinner->setValue(mySimDelay);
     747              :     }
     748              :     // Scale traffic (flows and incrementally loaded vehicles)
     749              :     {
     750         8030 :         myToolBarDrag8 = new FXToolBarShell(this, GUIDesignToolBar);
     751         8030 :         myToolBar8 = new FXToolBar(myTopDock, myToolBarDrag8, GUIDesignToolBarRaisedSameTop);
     752         8030 :         new FXToolBarGrip(myToolBar8, myToolBar8, FXToolBar::ID_TOOLBARGRIP, GUIDesignToolBarGrip);
     753         8030 :         myScaleTrafficTooltip = new MFXLabelTooltip(myToolBar8, myStaticTooltipMenu, TL("Scale Traffic:"), nullptr, LAYOUT_TOP | LAYOUT_LEFT);
     754        16060 :         myScaleTrafficTooltip->setHelpText(TL("Scale traffic volume from running flows and from vehicles that are loaded incrementally from route files."));
     755         8030 :         myDemandScaleSpinner = new MFXRealSpinner(myToolBar8, 7, this, MID_DEMAND_SCALE, GUIDesignSpinDial);
     756         8030 :         myDemandScaleSpinner->setIncrement(0.5);
     757         8030 :         myDemandScaleSpinner->setRange(0, 1000);
     758         8030 :         myDemandScaleSpinner->setValue(1);
     759              :     }
     760              :     // Views
     761              :     {
     762         8030 :         myToolBarDrag5 = new FXToolBarShell(this, GUIDesignToolBar);
     763         8030 :         myToolBar5 = new FXToolBar(myTopDock, myToolBarDrag5, GUIDesignToolBarRaisedSameTop);
     764         8030 :         new FXToolBarGrip(myToolBar5, myToolBar5, FXToolBar::ID_TOOLBARGRIP, GUIDesignToolBarGrip);
     765              :         // build view tools
     766        24090 :         new MFXButtonTooltip(myToolBar5, myStaticTooltipMenu, (std::string("\t") + TL("Open new view") + std::string("\t") + TL("Open a new microscopic view.")).c_str(),
     767        16060 :                              GUIIconSubSys::getIcon(GUIIcon::MICROVIEW), this, MID_NEW_MICROVIEW, GUIDesignButtonToolbar);
     768              : #ifdef HAVE_OSG
     769        24090 :         new MFXButtonTooltip(myToolBar5, myStaticTooltipMenu, (std::string("\t") + TL("Open new 3D view") + std::string("\t") + TL("Open a new 3D view.")).c_str(),
     770        16060 :                              GUIIconSubSys::getIcon(GUIIcon::OSGVIEW), this, MID_NEW_OSGVIEW, GUIDesignButtonToolbar);
     771              : #endif
     772              :     }
     773              :     /// game specific stuff
     774              :     {
     775              :         // total waitingTime
     776         8030 :         myToolBarDrag6 = new FXToolBarShell(this, GUIDesignToolBar);
     777         8030 :         myToolBar6 = new FXToolBar(myTopDock, myToolBarDrag6, GUIDesignToolBarRaisedSameTop);
     778         8030 :         new FXToolBarGrip(myToolBar6, myToolBar6, FXToolBar::ID_TOOLBARGRIP, GUIDesignToolBarGrip);
     779        16060 :         GUIDesigns::buildFXLabel(myToolBar6, TL("Waiting Time:"), "", TL("Time spent waiting accumulated for all vehicles"), nullptr, LAYOUT_TOP | LAYOUT_LEFT);
     780         8030 :         myWaitingTimeLabel = new MFXLCDLabel(myToolBar6, myStaticTooltipMenu, 13, nullptr, 0, JUSTIFY_RIGHT);
     781         8030 :         myWaitingTimeLabel->setHorizontal(2);
     782         8030 :         myWaitingTimeLabel->setVertical(6);
     783         8030 :         myWaitingTimeLabel->setThickness(2);
     784         8030 :         myWaitingTimeLabel->setGroove(2);
     785         8030 :         myWaitingTimeLabel->setText("-------------");
     786              :         // idealistic time loss
     787         8030 :         myToolBarDrag7 = new FXToolBarShell(this, GUIDesignToolBar);
     788         8030 :         myToolBar7 = new FXToolBar(myTopDock, myToolBarDrag7, GUIDesignToolBarRaisedSameTop);
     789         8030 :         new FXToolBarGrip(myToolBar7, myToolBar7, FXToolBar::ID_TOOLBARGRIP, GUIDesignToolBarGrip);
     790        16060 :         GUIDesigns::buildFXLabel(myToolBar7, TL("Time Loss:"), "", TL("Time lost due to being unable to drive with maximum speed for all vehicles"), nullptr, LAYOUT_TOP | LAYOUT_LEFT);
     791         8030 :         myTimeLossLabel = new MFXLCDLabel(myToolBar7, myStaticTooltipMenu, 13, nullptr, 0, JUSTIFY_RIGHT);
     792         8030 :         myTimeLossLabel->setHorizontal(2);
     793         8030 :         myTimeLossLabel->setVertical(6);
     794         8030 :         myTimeLossLabel->setThickness(2);
     795         8030 :         myTimeLossLabel->setGroove(2);
     796         8030 :         myTimeLossLabel->setText("-------------");
     797              :         // total driving distance
     798         8030 :         myToolBarDrag9 = new FXToolBarShell(this, GUIDesignToolBar);
     799         8030 :         myToolBar9 = new FXToolBar(myTopDock, myToolBarDrag9, GUIDesignToolBarRaisedSameTop);
     800         8030 :         new FXToolBarGrip(myToolBar9, myToolBar9, FXToolBar::ID_TOOLBARGRIP, GUIDesignToolBarGrip);
     801        16060 :         GUIDesigns::buildFXLabel(myToolBar9, TL("Distance (km):"), "", TL("Total distance driven by DRT vehicles"), nullptr, LAYOUT_TOP | LAYOUT_LEFT);
     802         8030 :         myTotalDistanceLabel = new MFXLCDLabel(myToolBar9, myStaticTooltipMenu, 13, nullptr, 0, JUSTIFY_RIGHT);
     803         8030 :         myTotalDistanceLabel->setHorizontal(2);
     804         8030 :         myTotalDistanceLabel->setVertical(6);
     805         8030 :         myTotalDistanceLabel->setThickness(2);
     806         8030 :         myTotalDistanceLabel->setGroove(2);
     807         8030 :         myTotalDistanceLabel->setText("-------------");
     808              :         // emergency vehicle counts
     809         8030 :         myToolBarDrag10 = new FXToolBarShell(this, GUIDesignToolBar);
     810         8030 :         myToolBar10 = new FXToolBar(myTopDock, myToolBarDrag10, GUIDesignToolBarRaisedSameTop);
     811         8030 :         new FXToolBarGrip(myToolBar10, myToolBar10, FXToolBar::ID_TOOLBARGRIP, GUIDesignToolBarGrip);
     812        16060 :         GUIDesigns::buildFXLabel(myToolBar10, TL("Emergency Vehicle waiting time:"), "", TL("Time spent waiting accumulated for emergency vehicles"), nullptr, LAYOUT_TOP | LAYOUT_LEFT);
     813         8030 :         myEmergencyVehicleLabel = new MFXLCDLabel(myToolBar10, myStaticTooltipMenu, 13, nullptr, 0, JUSTIFY_RIGHT);
     814         8030 :         myEmergencyVehicleLabel->setHorizontal(2);
     815         8030 :         myEmergencyVehicleLabel->setVertical(6);
     816         8030 :         myEmergencyVehicleLabel->setThickness(2);
     817         8030 :         myEmergencyVehicleLabel->setGroove(2);
     818         8030 :         myEmergencyVehicleLabel->setText("-------------");
     819              :     }
     820         8030 : }
     821              : 
     822              : 
     823              : void
     824         8030 : GUIApplicationWindow::buildRecentNetworks(FXMenuPane* fileMenu, FXMenuPane* fileMenuRecentNetworks) {
     825              :     // for whatever reason, sonar complains in the next line that sep1 may leak, but fox does the cleanup
     826         8030 :     GUIDesigns::buildFXMenuCommandRecentFile(fileMenuRecentNetworks, "", &myRecentNetworks, FXRecentFiles::ID_FILE_1);
     827         8030 :     GUIDesigns::buildFXMenuCommandRecentFile(fileMenuRecentNetworks, "", &myRecentNetworks, FXRecentFiles::ID_FILE_2);
     828         8030 :     GUIDesigns::buildFXMenuCommandRecentFile(fileMenuRecentNetworks, "", &myRecentNetworks, FXRecentFiles::ID_FILE_3);
     829         8030 :     GUIDesigns::buildFXMenuCommandRecentFile(fileMenuRecentNetworks, "", &myRecentNetworks, FXRecentFiles::ID_FILE_4);
     830         8030 :     GUIDesigns::buildFXMenuCommandRecentFile(fileMenuRecentNetworks, "", &myRecentNetworks, FXRecentFiles::ID_FILE_5);
     831         8030 :     GUIDesigns::buildFXMenuCommandRecentFile(fileMenuRecentNetworks, "", &myRecentNetworks, FXRecentFiles::ID_FILE_6);
     832         8030 :     GUIDesigns::buildFXMenuCommandRecentFile(fileMenuRecentNetworks, "", &myRecentNetworks, FXRecentFiles::ID_FILE_7);
     833         8030 :     GUIDesigns::buildFXMenuCommandRecentFile(fileMenuRecentNetworks, "", &myRecentNetworks, FXRecentFiles::ID_FILE_8);
     834         8030 :     GUIDesigns::buildFXMenuCommandRecentFile(fileMenuRecentNetworks, "", &myRecentNetworks, FXRecentFiles::ID_FILE_9);
     835         8030 :     GUIDesigns::buildFXMenuCommandRecentFile(fileMenuRecentNetworks, "", &myRecentNetworks, FXRecentFiles::ID_FILE_10);
     836         8030 :     new FXMenuSeparator(fileMenuRecentNetworks);  // NOSONAR, Fox does the cleanup
     837         8030 :     GUIDesigns::buildFXMenuCommand(fileMenuRecentNetworks, TL("Cl&ear Recent Networks"), nullptr, &myRecentNetworks, FXRecentFiles::ID_CLEAR);
     838         8030 :     GUIDesigns::buildFXMenuCommand(fileMenuRecentNetworks, TL("No Recent Networks"), nullptr, &myRecentNetworks, MFXRecentNetworks::ID_NOFILES);
     839              :     // set target
     840         8030 :     myRecentNetworks.setTarget(this);
     841              :     myRecentNetworks.setSelector(MID_RECENTFILE);
     842         8030 :     new FXMenuCascade(fileMenu, TL("Recent Networks"), nullptr, fileMenuRecentNetworks);
     843         8030 : }
     844              : 
     845              : 
     846              : void
     847         8030 : GUIApplicationWindow::buildRecentConfigs(FXMenuPane* fileMenu, FXMenuPane* fileMenuRecentConfigs) {
     848              :     // for whatever reason, sonar complains in the next line that sep1 may leak, but fox does the cleanup
     849         8030 :     GUIDesigns::buildFXMenuCommandRecentFile(fileMenuRecentConfigs, "", &myRecentConfigs, FXRecentFiles::ID_FILE_1);
     850         8030 :     GUIDesigns::buildFXMenuCommandRecentFile(fileMenuRecentConfigs, "", &myRecentConfigs, FXRecentFiles::ID_FILE_2);
     851         8030 :     GUIDesigns::buildFXMenuCommandRecentFile(fileMenuRecentConfigs, "", &myRecentConfigs, FXRecentFiles::ID_FILE_3);
     852         8030 :     GUIDesigns::buildFXMenuCommandRecentFile(fileMenuRecentConfigs, "", &myRecentConfigs, FXRecentFiles::ID_FILE_4);
     853         8030 :     GUIDesigns::buildFXMenuCommandRecentFile(fileMenuRecentConfigs, "", &myRecentConfigs, FXRecentFiles::ID_FILE_5);
     854         8030 :     GUIDesigns::buildFXMenuCommandRecentFile(fileMenuRecentConfigs, "", &myRecentConfigs, FXRecentFiles::ID_FILE_6);
     855         8030 :     GUIDesigns::buildFXMenuCommandRecentFile(fileMenuRecentConfigs, "", &myRecentConfigs, FXRecentFiles::ID_FILE_7);
     856         8030 :     GUIDesigns::buildFXMenuCommandRecentFile(fileMenuRecentConfigs, "", &myRecentConfigs, FXRecentFiles::ID_FILE_8);
     857         8030 :     GUIDesigns::buildFXMenuCommandRecentFile(fileMenuRecentConfigs, "", &myRecentConfigs, FXRecentFiles::ID_FILE_9);
     858         8030 :     GUIDesigns::buildFXMenuCommandRecentFile(fileMenuRecentConfigs, "", &myRecentConfigs, FXRecentFiles::ID_FILE_10);
     859         8030 :     new FXMenuSeparator(fileMenuRecentConfigs);  // NOSONAR, Fox does the cleanup
     860         8030 :     GUIDesigns::buildFXMenuCommand(fileMenuRecentConfigs, TL("Cl&ear Recent Configs"), nullptr, &myRecentConfigs, FXRecentFiles::ID_CLEAR);
     861         8030 :     GUIDesigns::buildFXMenuCommand(fileMenuRecentConfigs, TL("No Recent Configs"), nullptr, &myRecentConfigs, MFXRecentNetworks::ID_NOFILES);
     862              :     // set target
     863         8030 :     myRecentConfigs.setTarget(this);
     864              :     myRecentConfigs.setSelector(MID_RECENTFILE);
     865         8030 :     new FXMenuCascade(fileMenu, TL("Recent Configs"), nullptr, fileMenuRecentConfigs);
     866         8030 : }
     867              : 
     868              : 
     869              : long
     870            0 : GUIApplicationWindow::onCmdQuit(FXObject*, FXSelector, void*) {
     871            0 :     storeWindowSizeAndPos();
     872            0 :     getApp()->reg().writeStringEntry("SETTINGS", "basedir", gCurrentFolder.text());
     873            0 :     getApp()->reg().writeIntEntry("SETTINGS", "maximized", isMaximized() ? 1 : 0);
     874            0 :     getApp()->reg().writeIntEntry("gui", "timeasHMS", myShowTimeAsHMS ? 1 : 0);
     875            0 :     getApp()->reg().writeIntEntry("gui", "alternateSimDelay", (int)myAlternateSimDelay);
     876            0 :     closeAllWindows();
     877            0 :     getApp()->exit(0);
     878            0 :     return 1;
     879              : }
     880              : 
     881              : 
     882              : long
     883            0 : GUIApplicationWindow::onCmdEditChosen(FXObject* menu, FXSelector, void*) {
     884            0 :     FXMenuCommand* mc = dynamic_cast<FXMenuCommand*>(menu);
     885            0 :     if (mc->getText() == StringUtils::replace(TL("Edit Selected..."), "&", "").c_str()) {
     886            0 :         GUIDialog_GLChosenEditor* chooser = new GUIDialog_GLChosenEditor(this, &gSelected);
     887            0 :         chooser->create();
     888            0 :         chooser->show();
     889              :     } else {
     890            0 :         if (!myAmLoading && myRunThread->networkAvailable()) {
     891            0 :             const SUMOVehicleClass svc = SumoVehicleClassStrings.get(mc->getText().text());
     892            0 :             for (MSEdgeVector::const_iterator i = MSEdge::getAllEdges().begin(); i != MSEdge::getAllEdges().end(); ++i) {
     893            0 :                 const std::vector<MSLane*>& lanes = (*i)->getLanes();
     894            0 :                 for (std::vector<MSLane*>::const_iterator it = lanes.begin(); it != lanes.end(); ++it) {
     895            0 :                     GUILane* lane = dynamic_cast<GUILane*>(*it);
     896              :                     assert(lane != 0);
     897            0 :                     if ((lane->getPermissions() & svc) != 0) {
     898            0 :                         gSelected.select(lane->getGlID());
     899              :                     }
     900              :                 }
     901              :             }
     902            0 :             if (myMDIClient->numChildren() > 0) {
     903            0 :                 GUISUMOViewParent* w = dynamic_cast<GUISUMOViewParent*>(myMDIClient->getActiveChild());
     904            0 :                 if (w != nullptr) {
     905              :                     // color by selection
     906            0 :                     w->getView()->editVisualisationSettings()->laneColorer.setActive(1);
     907              :                 }
     908              :             }
     909              :         }
     910            0 :         updateChildren();
     911              :     }
     912            0 :     return 1;
     913              : }
     914              : 
     915              : 
     916              : long
     917            0 : GUIApplicationWindow::onCmdEditBreakpoints(FXObject*, FXSelector, void*) {
     918            0 :     if (myBreakpointDialog == nullptr) {
     919            0 :         myBreakpointDialog = new GUIDialog_Breakpoints(this, myRunThread->getBreakpoints(), myRunThread->getBreakpointLock(), myRunThread->getSimBegin());
     920              :     } else {
     921            0 :         myBreakpointDialog->restore();
     922            0 :         myBreakpointDialog->setFocus();
     923            0 :         myBreakpointDialog->raise();
     924              :     }
     925            0 :     return 1;
     926              : }
     927              : 
     928              : 
     929              : long
     930            0 : GUIApplicationWindow::onCmdEditViewport(FXObject*, FXSelector, void*) {
     931            0 :     if (!myGLWindows.empty()) {
     932            0 :         myGLWindows[0]->getView()->showViewportEditor();
     933              :     }
     934            0 :     return 1;
     935              : }
     936              : 
     937              : 
     938              : long
     939            0 : GUIApplicationWindow::onCmdEditViewScheme(FXObject*, FXSelector, void*) {
     940            0 :     if (!myGLWindows.empty()) {
     941            0 :         myGLWindows[0]->getView()->showViewschemeEditor();
     942              :     }
     943            0 :     return 1;
     944              : }
     945              : 
     946              : 
     947              : long
     948            0 : GUIApplicationWindow::onCmdHelp(FXObject*, FXSelector, void*) {
     949            0 :     MFXLinkLabel::fxexecute("https://sumo.dlr.de/docs/sumo-gui.html");
     950            0 :     return 1;
     951              : }
     952              : 
     953              : 
     954              : long
     955            0 : GUIApplicationWindow::onCmdChangelog(FXObject*, FXSelector, void*) {
     956              :     // update in every version
     957            0 :     MFXLinkLabel::fxexecute("https://sumo.dlr.de/docs/ChangeLog.html");
     958            0 :     return 1;
     959              : }
     960              : 
     961              : 
     962              : long
     963            0 : GUIApplicationWindow::onCmdHotkeys(FXObject*, FXSelector, void*) {
     964            0 :     MFXLinkLabel::fxexecute("https://sumo.dlr.de/docs/sumo-gui.html#keyboard_shortcuts");
     965            0 :     return 1;
     966              : }
     967              : 
     968              : 
     969              : long
     970            0 : GUIApplicationWindow::onCmdTutorial(FXObject*, FXSelector, void*) {
     971            0 :     MFXLinkLabel::fxexecute("https://sumo.dlr.de/docs/Tutorials/index.html");
     972            0 :     return 1;
     973              : }
     974              : 
     975              : 
     976              : long
     977            0 : GUIApplicationWindow::onCmdOpenInNetedit(FXObject* sender, FXSelector, void* ptr) {
     978            0 :     if (myGLWindows.empty()) {
     979              :         return 1;
     980              :     }
     981              :     bool onlyNet;
     982            0 :     if (sender == myOpenNetInNetedit) {
     983              :         onlyNet = true;
     984            0 :     } else if (sender == myOpenInNetedit) {
     985              :         onlyNet = false;
     986              :     } else {
     987              :         // we have to check (menu-item) sender first because ptr is only valid when
     988              :         // triggered via hotkey
     989              :         FXEvent* e = (FXEvent*) ptr;
     990            0 :         onlyNet = (e->state & SHIFTMASK) != 0;
     991              :     }
     992            0 :     FXRegistry reg("SUMO netedit", "netedit");
     993            0 :     reg.read();
     994            0 :     const GUISUMOAbstractView* const v = myGLWindows[0]->getView();
     995            0 :     reg.writeRealEntry("viewport", "x", v->getChanger().getXPos());
     996            0 :     reg.writeRealEntry("viewport", "y", v->getChanger().getYPos());
     997            0 :     reg.writeRealEntry("viewport", "z", v->getChanger().getZPos());
     998            0 :     reg.write();
     999            0 :     std::string netedit = "netedit";
    1000            0 :     const char* sumoPath = getenv("SUMO_HOME");
    1001            0 :     if (sumoPath != nullptr) {
    1002            0 :         std::string newPath = std::string(sumoPath) + "/bin/netedit";
    1003            0 :         if (FileHelpers::isReadable(newPath) || FileHelpers::isReadable(newPath + ".exe")) {
    1004            0 :             netedit = "\"" + newPath + "\"";
    1005              :         }
    1006              :     }
    1007              :     // declare command for calling netedit using the viewport saved in registry
    1008            0 :     std::string cmd = netedit + " --registry-viewport";
    1009              :     // continue depending if we're loading only a network or the entire sumo config
    1010            0 :     if (myLoadAdditionalsInNetedit->shown() && !onlyNet) {
    1011            0 :         cmd += " --sumocfg-file \"" + OptionsCont::getOptions().getString("configuration-file") + "\"";
    1012              :         // check if ignore additional or demand elements
    1013            0 :         if (myLoadAdditionalsInNetedit->getCheck() == FALSE) {
    1014              :             cmd += " --ignore.additionalelements";
    1015              :         }
    1016            0 :         if (myLoadDemandInNetedit->getCheck() == FALSE) {
    1017              :             cmd += " --ignore.routeelements";
    1018              :         }
    1019              :     } else {
    1020            0 :         cmd += " -s \"" + OptionsCont::getOptions().getString("net-file") + "\"";
    1021              :     }
    1022              :     // start in background
    1023              : #ifndef WIN32
    1024            0 :     cmd = cmd + " &";
    1025              : #else
    1026              :     // see "help start" for the parameters
    1027              :     cmd = "start /B \"\" " + cmd;
    1028              : #endif
    1029            0 :     WRITE_MESSAGEF(TL("Running %."), cmd);
    1030              :     // yay! fun with dangerous commands... Never use this over the internet
    1031            0 :     SysUtils::runHiddenCommand(cmd);
    1032              :     return 1;
    1033            0 : }
    1034              : 
    1035              : 
    1036              : long
    1037            0 : GUIApplicationWindow::onCmdNewWindow(FXObject*, FXSelector, void*) {
    1038            0 :     FXRegistry reg("SUMO sumo-gui", "sumo-gui");
    1039            0 :     std::string sumo_gui = "sumo-gui";
    1040            0 :     const char* sumoPath = getenv("SUMO_HOME");
    1041            0 :     if (sumoPath != nullptr) {
    1042            0 :         std::string newPath = std::string(sumoPath) + "/bin/sumo_gui";
    1043            0 :         if (FileHelpers::isReadable(newPath) || FileHelpers::isReadable(newPath + ".exe")) {
    1044            0 :             sumo_gui = "\"" + newPath + "\"";
    1045              :         }
    1046              :     }
    1047              :     std::string cmd = sumo_gui;
    1048              :     // start in background
    1049              : #ifndef WIN32
    1050            0 :     cmd = cmd + " &";
    1051              : #else
    1052              :     // see "help start" for the parameters
    1053              :     cmd = "start /B \"\" " + cmd;
    1054              : #endif
    1055            0 :     WRITE_MESSAGEF(TL("Running %."), cmd);
    1056              :     // yay! fun with dangerous commands... Never use this over the internet
    1057            0 :     SysUtils::runHiddenCommand(cmd);
    1058            0 :     return 1;
    1059            0 : }
    1060              : 
    1061              : 
    1062              : long
    1063            0 : GUIApplicationWindow::onCmdOpenConfiguration(FXObject*, FXSelector, void*) {
    1064              :     // get the new file name
    1065            0 :     FXFileDialog opendialog(this, TL("Open Simulation Configuration"));
    1066            0 :     opendialog.setIcon(GUIIconSubSys::getIcon(GUIIcon::OPEN_SUMOCONFIG));
    1067            0 :     opendialog.setSelectMode(SELECTFILE_EXISTING);
    1068            0 :     opendialog.setPatternList(SUMOXMLDefinitions::SumoConfigFileExtensions.getMultilineString().c_str());
    1069            0 :     if (gCurrentFolder.length() != 0) {
    1070            0 :         opendialog.setDirectory(gCurrentFolder);
    1071              :     }
    1072            0 :     if (opendialog.execute()) {
    1073            0 :         gCurrentFolder = opendialog.getDirectory();
    1074            0 :         std::string file = opendialog.getFilename().text();
    1075            0 :         loadConfigOrNet(file);
    1076            0 :         myRecentConfigs.appendFile(file.c_str());
    1077              :     }
    1078            0 :     return 1;
    1079            0 : }
    1080              : 
    1081              : 
    1082              : long
    1083            0 : GUIApplicationWindow::onCmdOpenNetwork(FXObject*, FXSelector, void*) {
    1084              :     // get the new file name
    1085            0 :     FXFileDialog opendialog(this, TL("Open Network"));
    1086            0 :     opendialog.setIcon(GUIIconSubSys::getIcon(GUIIcon::OPEN_NET));
    1087            0 :     opendialog.setSelectMode(SELECTFILE_EXISTING);
    1088            0 :     opendialog.setPatternList(SUMOXMLDefinitions::NetFileExtensions.getMultilineString().c_str());
    1089            0 :     if (gCurrentFolder.length() != 0) {
    1090            0 :         opendialog.setDirectory(gCurrentFolder);
    1091              :     }
    1092            0 :     if (opendialog.execute()) {
    1093            0 :         gCurrentFolder = opendialog.getDirectory();
    1094            0 :         std::string file = opendialog.getFilename().text();
    1095            0 :         loadConfigOrNet(file);
    1096            0 :         myRecentNetworks.appendFile(file.c_str());
    1097              :     }
    1098            0 :     return 1;
    1099            0 : }
    1100              : 
    1101              : 
    1102              : long
    1103            0 : GUIApplicationWindow::onCmdOpenShapes(FXObject*, FXSelector, void*) {
    1104              :     // get the shape file name
    1105            0 :     FXFileDialog opendialog(this, TL("Open Shapes"));
    1106            0 :     opendialog.setIcon(GUIIconSubSys::getIcon(GUIIcon::OPEN_SHAPES));
    1107            0 :     opendialog.setSelectMode(SELECTFILE_EXISTING);
    1108            0 :     opendialog.setPatternList(SUMOXMLDefinitions::ShapesFileExtensions.getMultilineString().c_str());
    1109            0 :     if (gCurrentFolder.length() != 0) {
    1110            0 :         opendialog.setDirectory(gCurrentFolder);
    1111              :     }
    1112            0 :     if (opendialog.execute()) {
    1113            0 :         gCurrentFolder = opendialog.getDirectory();
    1114            0 :         std::string file = opendialog.getFilename().text();
    1115              : 
    1116            0 :         dynamic_cast<GUIShapeContainer&>(myRunThread->getNet().getShapeContainer()).allowReplacement();
    1117            0 :         NLShapeHandler handler(file, myRunThread->getNet().getShapeContainer());
    1118            0 :         if (!XMLSubSys::runParser(handler, file, false)) {
    1119            0 :             WRITE_MESSAGEF(TL("Loading of % failed."), file);
    1120              :         }
    1121            0 :         update();
    1122            0 :         if (myMDIClient->numChildren() > 0) {
    1123            0 :             GUISUMOViewParent* w = dynamic_cast<GUISUMOViewParent*>(myMDIClient->getActiveChild());
    1124            0 :             if (w != nullptr) {
    1125            0 :                 w->getView()->update();
    1126              :             }
    1127              :         }
    1128              :     }
    1129            0 :     return 1;
    1130            0 : }
    1131              : 
    1132              : 
    1133              : long
    1134            0 : GUIApplicationWindow::onCmdOpenEdgeData(FXObject*, FXSelector, void*) {
    1135              :     // get the shape file name
    1136            0 :     FXFileDialog opendialog(this, TL("Open EdgeData"));
    1137            0 :     opendialog.setIcon(GUIIconSubSys::getIcon(GUIIcon::OPEN_NET));
    1138            0 :     opendialog.setSelectMode(SELECTFILE_EXISTING);
    1139            0 :     opendialog.setPatternList(SUMOXMLDefinitions::EdgeDataFileExtensions.getMultilineString().c_str());
    1140            0 :     if (gCurrentFolder.length() != 0) {
    1141            0 :         opendialog.setDirectory(gCurrentFolder);
    1142              :     }
    1143            0 :     if (opendialog.execute()) {
    1144            0 :         gCurrentFolder = opendialog.getDirectory();
    1145            0 :         std::string file = opendialog.getFilename().text();
    1146            0 :         if (!GUINet::getGUIInstance()->loadEdgeData(file)) {
    1147            0 :             WRITE_MESSAGEF(TL("Loading of % failed."), file);
    1148              :         }
    1149            0 :         update();
    1150            0 :         if (myMDIClient->numChildren() > 0) {
    1151            0 :             GUISUMOViewParent* w = dynamic_cast<GUISUMOViewParent*>(myMDIClient->getActiveChild());
    1152            0 :             if (w != nullptr) {
    1153            0 :                 w->getView()->update();
    1154              :             }
    1155              :         }
    1156              :     }
    1157            0 :     return 1;
    1158            0 : }
    1159              : 
    1160              : 
    1161              : long
    1162            0 : GUIApplicationWindow::onCmdReload(FXObject* sender, FXSelector sel, void*) {
    1163            0 :     if (!myAmLoading && (sender == nullptr || TraCIServer::getInstance() == nullptr)) {
    1164            0 :         storeWindowSizeAndPos();
    1165            0 :         getApp()->beginWaitCursor();
    1166            0 :         myAmLoading = true;
    1167            0 :         myIsReload = sender != nullptr || sel == 1;
    1168            0 :         closeAllWindows();
    1169            0 :         myLoadThread->start();
    1170            0 :         if (sender == nullptr) {
    1171            0 :             setStatusBarText(sel == 1 ? TL("Auto-Reloading.") : TL("TraCI-Loading."));
    1172              :         } else {
    1173            0 :             setStatusBarText(TL("Reloading."));
    1174              :         }
    1175            0 :         update();
    1176              :     }
    1177            0 :     return 1;
    1178              : }
    1179              : 
    1180              : 
    1181              : long
    1182            0 : GUIApplicationWindow::onCmdQuickReload(FXObject*, FXSelector, void*) {
    1183            0 :     if (!myAmLoading) {
    1184            0 :         setStatusBarText(TL("Quick-Reloading."));
    1185            0 :         MSNet::getInstance()->quickReload();
    1186              :     }
    1187            0 :     return 1;
    1188              : }
    1189              : 
    1190              : 
    1191              : long
    1192            0 : GUIApplicationWindow::onCmdOpenRecent(FXObject* /* sender */, FXSelector, void* ptr) {
    1193            0 :     if (myAmLoading) {
    1194            0 :         myStatusbar->getStatusLine()->setText(TL("Already loading!"));
    1195            0 :         return 1;
    1196              :     }
    1197            0 :     std::string file((const char*)ptr);
    1198            0 :     loadConfigOrNet(file);
    1199              :     return 1;
    1200              : }
    1201              : 
    1202              : 
    1203              : long
    1204            0 : GUIApplicationWindow::onCmdSaveConfig(FXObject*, FXSelector, void*) {
    1205              :     // get the new file name
    1206            0 :     FXFileDialog opendialog(this, TL("Save SUMO Configuration"));
    1207            0 :     opendialog.setIcon(GUIIconSubSys::getIcon(GUIIcon::SAVE));
    1208            0 :     opendialog.setSelectMode(SELECTFILE_ANY);
    1209            0 :     opendialog.setPatternList(SUMOXMLDefinitions::SumoConfigFileExtensions.getMultilineString().c_str());
    1210            0 :     if (gCurrentFolder.length() != 0) {
    1211            0 :         opendialog.setDirectory(gCurrentFolder);
    1212              :     }
    1213            0 :     if (!opendialog.execute() || !MFXUtils::userPermitsOverwritingWhenFileExists(this, opendialog.getFilename())) {
    1214              :         return 1;
    1215              :     }
    1216            0 :     const std::string file = MFXUtils::assureExtension(opendialog).text();
    1217            0 :     std::ofstream out(StringUtils::transcodeToLocal(file));
    1218            0 :     if (out.good()) {
    1219            0 :         OptionsCont::getOptions().writeConfiguration(out, true, false, false, file, true);
    1220            0 :         setStatusBarText(TLF("Configuration saved to %.", file));
    1221              :     } else {
    1222            0 :         setStatusBarText(TLF("Could not save configuration to %.", file));
    1223              :     }
    1224            0 :     out.close();
    1225              :     return 1;
    1226            0 : }
    1227              : 
    1228              : 
    1229              : long
    1230            0 : GUIApplicationWindow::onCmdClose(FXObject*, FXSelector, void*) {
    1231            0 :     closeAllWindows();
    1232            0 :     return 1;
    1233              : }
    1234              : 
    1235              : 
    1236              : long
    1237      1735954 : GUIApplicationWindow::onUpdOpen(FXObject* sender, FXSelector, void* ptr) {
    1238      1735954 :     sender->handle(this,
    1239      1735954 :                    myAmLoading ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
    1240              :                    ptr);
    1241      1735954 :     return 1;
    1242              : }
    1243              : 
    1244              : 
    1245              : long
    1246      1300598 : GUIApplicationWindow::onUpdReload(FXObject* sender, FXSelector, void* ptr) {
    1247      1300598 :     sender->handle(this,
    1248      1300598 :                    myAmLoading || myLoadThread->getFileName() == "" || TraCIServer::getInstance() != nullptr
    1249              :                    ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
    1250              :                    ptr);
    1251      1300598 :     return 1;
    1252              : }
    1253              : 
    1254              : 
    1255              : long
    1256            0 : GUIApplicationWindow::onUpdOpenRecent(FXObject* sender, FXSelector, void* ptr) {
    1257            0 :     sender->handle(this,
    1258            0 :                    myAmLoading ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
    1259              :                    ptr);
    1260            0 :     return 1;
    1261              : }
    1262              : 
    1263              : 
    1264              : long
    1265      1732993 : GUIApplicationWindow::onUpdAddView(FXObject* sender, FXSelector, void* ptr) {
    1266      1732993 :     sender->handle(this,
    1267      1732993 :                    myAmLoading || !myRunThread->networkAvailable()
    1268              :                    ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
    1269              :                    ptr);
    1270      1732993 :     return 1;
    1271              : }
    1272              : 
    1273              : 
    1274              : long
    1275         7577 : GUIApplicationWindow::onCmdStart(FXObject*, FXSelector, void*) {
    1276              :     // check whether a net was loaded successfully
    1277         7577 :     if (!myRunThread->networkAvailable()) {
    1278            0 :         myStatusbar->getStatusLine()->setText(TL("No simulation loaded!"));
    1279            0 :         return 1;
    1280              :     }
    1281              :     // check whether it was started before and paused;
    1282         7577 :     if (!myWasStarted) {
    1283         7577 :         myRunThread->begin();
    1284         7577 :         myWasStarted = true;
    1285              :     }
    1286         7577 :     myRunThread->resume();
    1287         7577 :     getApp()->forceRefresh(); // only calling myToolBar2->forceRefresh somehow looses keyboard focus
    1288         7577 :     return 1;
    1289              : }
    1290              : 
    1291              : 
    1292              : long
    1293         7056 : GUIApplicationWindow::onCmdStop(FXObject*, FXSelector, void*) {
    1294         7056 :     myRunThread->stop();
    1295         7056 :     getApp()->forceRefresh(); // only calling myToolBar2->forceRefresh somehow looses keyboard focus
    1296         7056 :     return 1;
    1297              : }
    1298              : 
    1299              : 
    1300              : long
    1301            0 : GUIApplicationWindow::onCmdStep(FXObject*, FXSelector, void*) {
    1302              :     // check whether a net was loaded successfully
    1303            0 :     if (!myRunThread->networkAvailable()) {
    1304            0 :         myStatusbar->getStatusLine()->setText(TL("No simulation loaded!"));
    1305            0 :         return 1;
    1306              :     }
    1307              :     // check whether it was started before and paused;
    1308            0 :     if (!myWasStarted) {
    1309            0 :         myRunThread->begin();
    1310            0 :         myWasStarted = true;
    1311              :     }
    1312            0 :     myRunThread->singleStep();
    1313            0 :     return 1;
    1314              : }
    1315              : 
    1316              : 
    1317              : long
    1318            0 : GUIApplicationWindow::onCmdSaveState(FXObject*, FXSelector, void*) {
    1319              :     // get the new file name
    1320            0 :     FXFileDialog opendialog(this, TL("Save Simulation State"));
    1321            0 :     opendialog.setIcon(GUIIconSubSys::getIcon(GUIIcon::SAVE));
    1322            0 :     opendialog.setSelectMode(SELECTFILE_ANY);
    1323            0 :     opendialog.setPatternList(SUMOXMLDefinitions::StateFileExtensions.getMultilineString().c_str());
    1324            0 :     if (gCurrentFolder.length() != 0) {
    1325            0 :         opendialog.setDirectory(gCurrentFolder);
    1326              :     }
    1327            0 :     if (!opendialog.execute() || !MFXUtils::userPermitsOverwritingWhenFileExists(this, opendialog.getFilename())) {
    1328              :         return 1;
    1329              :     }
    1330            0 :     const std::string file = MFXUtils::assureExtension(opendialog).text();
    1331            0 :     MSStateHandler::saveState(file, MSNet::getInstance()->getCurrentTimeStep(), false);
    1332            0 :     setStatusBarText(TLF("Simulation state saved to '%'.", file));
    1333              :     return 1;
    1334            0 : }
    1335              : 
    1336              : 
    1337              : long
    1338            0 : GUIApplicationWindow::onCmdLoadState(FXObject*, FXSelector, void*) {
    1339              :     // get the new file name
    1340            0 :     FXFileDialog opendialog(this, TL("Load Simulation State"));
    1341            0 :     opendialog.setIcon(GUIIconSubSys::getIcon(GUIIcon::OPEN));
    1342            0 :     opendialog.setSelectMode(SELECTFILE_ANY);
    1343            0 :     opendialog.setPatternList(SUMOXMLDefinitions::StateFileExtensions.getMultilineString().c_str());
    1344            0 :     if (gCurrentFolder.length() != 0) {
    1345            0 :         opendialog.setDirectory(gCurrentFolder);
    1346              :     }
    1347            0 :     if (opendialog.execute() && FXStat::exists(opendialog.getFilename())) {
    1348            0 :         gCurrentFolder = opendialog.getDirectory();
    1349            0 :         const std::string file = opendialog.getFilename().text();
    1350              :         try {
    1351            0 :             MSNet::getInstance()->loadState(file, true);
    1352            0 :             setStatusBarText(TLF("State loaded from '%'.", file));
    1353            0 :         } catch (ProcessError& e) {
    1354            0 :             setStatusBarText(TLF("Failed to load state from '%' (%).", file, e.what()));
    1355            0 :         }
    1356              :     }
    1357            0 :     return 1;
    1358            0 : }
    1359              : 
    1360              : 
    1361              : long
    1362            0 : GUIApplicationWindow::onCmdTimeToggle(FXObject*, FXSelector, void*) {
    1363              :     // toggle show time as HMS
    1364            0 :     myShowTimeAsHMS = !myShowTimeAsHMS;
    1365            0 :     updateTimeLCDTooltip();
    1366            0 :     if (myRunThread->networkAvailable()) {
    1367            0 :         updateTimeLCD(myRunThread->getNet().getCurrentTimeStep());
    1368              :     }
    1369            0 :     return 1;
    1370              : }
    1371              : 
    1372              : 
    1373              : long
    1374            0 : GUIApplicationWindow::onCmdDelayInc(FXObject*, FXSelector, void*) {
    1375            0 :     if (mySimDelay < 10) {
    1376            0 :         mySimDelay = 10;
    1377            0 :     } else if (mySimDelay >= 20 && mySimDelay < 50) {
    1378            0 :         mySimDelay = 50;
    1379            0 :     } else if (mySimDelay >= 200 && mySimDelay < 500) {
    1380            0 :         mySimDelay = 500;
    1381              :     } else {
    1382            0 :         mySimDelay *= 2;
    1383              :     }
    1384            0 :     if (mySimDelay > 1000) {
    1385              :         // setting high delay by pressing the key too often is hard to recover from
    1386            0 :         mySimDelay = 1000;
    1387              :     }
    1388            0 :     mySimDelaySlider->setValue((int)mySimDelay);
    1389            0 :     mySimDelaySpinner->setValue(mySimDelay);
    1390            0 :     return 1;
    1391              : }
    1392              : 
    1393              : 
    1394              : long
    1395            0 : GUIApplicationWindow::onCmdDelayDec(FXObject*, FXSelector, void*) {
    1396            0 :     if (mySimDelay <= 10) {
    1397            0 :         mySimDelay = 0;
    1398            0 :     } else if (mySimDelay > 20 && mySimDelay <= 50) {
    1399            0 :         mySimDelay = 20;
    1400            0 :     } else if (mySimDelay > 200 && mySimDelay <= 500) {
    1401            0 :         mySimDelay = 200;
    1402              :     } else {
    1403            0 :         mySimDelay /= 2;
    1404              :     }
    1405            0 :     mySimDelaySlider->setValue((int)mySimDelay);
    1406            0 :     mySimDelaySpinner->setValue(mySimDelay);
    1407            0 :     return 1;
    1408              : }
    1409              : 
    1410              : 
    1411              : long
    1412            0 : GUIApplicationWindow::onCmdDelayToggle(FXObject*, FXSelector, void*) {
    1413            0 :     const double tmp = myAlternateSimDelay;
    1414            0 :     myAlternateSimDelay = mySimDelay;
    1415            0 :     mySimDelay = tmp;
    1416            0 :     return 1;
    1417              : }
    1418              : 
    1419              : 
    1420              : long
    1421            0 : GUIApplicationWindow::onCmdDemandScale(FXObject*, FXSelector, void*) {
    1422            0 :     if (myRunThread->networkAvailable()) {
    1423            0 :         myRunThread->getNet().getVehicleControl().setScale(myDemandScaleSpinner->getValue());
    1424              :     }
    1425            0 :     return 1;
    1426              : }
    1427              : 
    1428              : 
    1429              : long
    1430            0 : GUIApplicationWindow::onCmdClearMsgWindow(FXObject*, FXSelector, void*) {
    1431            0 :     myMessageWindow->clear();
    1432            0 :     return 1;
    1433              : }
    1434              : 
    1435              : 
    1436              : long
    1437            0 : GUIApplicationWindow::onCmdBreakpoint(FXObject*, FXSelector, void*) {
    1438              :     // see updateTimeLCD for the DELTA_T
    1439            0 :     if (myRunThread->networkAvailable()) {
    1440            0 :         addBreakpoint(SIMSTEP - DELTA_T);
    1441              :     }
    1442            0 :     return 1;
    1443              : }
    1444              : 
    1445              : 
    1446              : long
    1447            0 : GUIApplicationWindow::onCmdBreakpointEarly(FXObject*, FXSelector, void*) {
    1448              :     // see updateTimeLCD for the DELTA_T
    1449            0 :     if (myRunThread->networkAvailable()) {
    1450            0 :         addBreakpoint(SIMSTEP - DELTA_T + GUIMessageWindow::getBreakPointOffset());
    1451              :     }
    1452            0 :     return 1;
    1453              : }
    1454              : 
    1455              : 
    1456              : long
    1457      6646779 : GUIApplicationWindow::onUpdStart(FXObject* sender, FXSelector, void* ptr) {
    1458     13293558 :     sender->handle(this,
    1459      7467246 :                    !myRunThread->simulationIsStartable() || myAmLoading
    1460              :                    ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
    1461              :                    ptr);
    1462      6646779 :     if (myRunThread->simulationIsStartable() && !myAmLoading) {
    1463              :         // bind start simulation with space key
    1464       820474 :         GUIShortcutsSubSys::changeAccelerator(getAccelTable(), this, KEY_SPACE, MID_HOTKEY_CTRL_A_STARTSIMULATION_OPENADDITIONALELEMENTS);
    1465              :     }
    1466      6646779 :     return 1;
    1467              : }
    1468              : 
    1469              : 
    1470              : long
    1471      6646764 : GUIApplicationWindow::onUpdStop(FXObject* sender, FXSelector, void* ptr) {
    1472     13293528 :     sender->handle(this,
    1473     12415111 :                    !myRunThread->simulationIsStopable() || myAmLoading
    1474              :                    ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
    1475              :                    ptr);
    1476      6646764 :     if (myRunThread->simulationIsStopable() && !myAmLoading) {
    1477              :         // bind stop simulation with space key
    1478      5768344 :         GUIShortcutsSubSys::changeAccelerator(getAccelTable(), this, KEY_SPACE, MID_HOTKEY_CTRL_S_STOPSIMULATION_SAVENETWORK);
    1479              :     }
    1480      6646764 :     return 1;
    1481              : }
    1482              : 
    1483              : 
    1484              : long
    1485      6646749 : GUIApplicationWindow::onUpdStep(FXObject* sender, FXSelector, void* ptr) {
    1486     13293498 :     sender->handle(this,
    1487      7467249 :                    !myRunThread->simulationIsStepable() || myAmLoading
    1488              :                    ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
    1489              :                    ptr);
    1490      6646749 :     return 1;
    1491              : }
    1492              : 
    1493              : 
    1494              : long
    1495     25071986 : GUIApplicationWindow::onUpdNeedsNetwork(FXObject* sender, FXSelector, void* ptr) {
    1496              :     // check if there is a loaded network and gui isn't loading
    1497     25071986 :     if (myRunThread->networkAvailable() && !myAmLoading) {
    1498     24792506 :         sender->handle(this, FXSEL(SEL_COMMAND, ID_ENABLE), ptr);
    1499              :         // enable certain elements manually
    1500     24792506 :         mySelectLanesMenuCascade->enable();
    1501     49585012 :         myScaleTrafficTooltip->setTipText(TL("Scale number of vehicles in simulation"));
    1502              :     } else {
    1503       279480 :         sender->handle(this, FXSEL(SEL_COMMAND, ID_DISABLE), ptr);
    1504              :         // disable certain elements manually
    1505       279480 :         mySelectLanesMenuCascade->disable();
    1506       558960 :         myScaleTrafficTooltip->setTipText("");
    1507              :     }
    1508     25071986 :     return 1;
    1509              : }
    1510              : 
    1511              : 
    1512              : long
    1513       864046 : GUIApplicationWindow::onUpdNeedsSumoConfig(FXObject* sender, FXSelector, void* ptr) {
    1514              :     // check if there is a loaded network and gui isn't loading
    1515      1718853 :     if (myRunThread->networkAvailable() && !myAmLoading && OptionsCont::getOptions().isSet("configuration-file")) {
    1516         4571 :         sender->handle(this, FXSEL(SEL_COMMAND, ID_ENABLE), ptr);
    1517         4571 :         sender->handle(this, FXSEL(SEL_COMMAND, ID_SHOW), ptr);
    1518         4571 :         myOpenInNetedit->setText(TL("Open sumo config in netedit"));
    1519              :     } else {
    1520       859475 :         sender->handle(this, FXSEL(SEL_COMMAND, ID_DISABLE), ptr);
    1521       859475 :         sender->handle(this, FXSEL(SEL_COMMAND, ID_HIDE), ptr);
    1522       859475 :         myOpenInNetedit->setText(TL("Open network in netedit"));
    1523              :     }
    1524       864046 :     return 1;
    1525              : }
    1526              : 
    1527              : 
    1528              : long
    1529       434006 : GUIApplicationWindow::onUpdTraCIStatus(FXObject* /*sender*/, FXSelector, void* /*ptr*/) {
    1530       434006 :     if (TraCIServer::getInstance()) {
    1531          673 :         myTraCiFrame->show();
    1532              :     } else {
    1533       433333 :         myTraCiFrame->hide();
    1534              :     }
    1535       434006 :     return 1;
    1536              : }
    1537              : 
    1538              : 
    1539              : long
    1540            0 : GUIApplicationWindow::onCmdLocate(FXObject*, FXSelector sel, void*) {
    1541            0 :     if (myMDIClient->numChildren() > 0) {
    1542            0 :         GUISUMOViewParent* w = dynamic_cast<GUISUMOViewParent*>(myMDIClient->getActiveChild());
    1543            0 :         if (w != nullptr) {
    1544            0 :             w->onCmdLocate(nullptr, sel, nullptr);
    1545              :         }
    1546              :     }
    1547            0 :     return 1;
    1548              : }
    1549              : 
    1550              : 
    1551              : long
    1552            0 : GUIApplicationWindow::onCmdShowStats(FXObject*, FXSelector, void*) {
    1553            0 :     if (myMDIClient->numChildren() > 0) {
    1554            0 :         GUISUMOViewParent* w = dynamic_cast<GUISUMOViewParent*>(myMDIClient->getActiveChild());
    1555            0 :         GUINet::getGUIInstance()->getParameterWindow(*this, *w->getView());
    1556              :     }
    1557            0 :     return 1;
    1558              : }
    1559              : 
    1560              : 
    1561              : long
    1562            0 : GUIApplicationWindow::onCmdAppSettings(FXObject*, FXSelector, void*) {
    1563            0 :     GUIDialog_AppSettings* d = new GUIDialog_AppSettings(this);
    1564            0 :     d->create();
    1565            0 :     d->show(PLACEMENT_OWNER);
    1566            0 :     return 1;
    1567              : }
    1568              : 
    1569              : 
    1570              : long
    1571            0 : GUIApplicationWindow::onCmdGaming(FXObject*, FXSelector, void*) {
    1572            0 :     if (myGLWindows.empty()) {
    1573              :         return 1;
    1574              :     }
    1575            0 :     myAmGaming = !myAmGaming;
    1576            0 :     myGLWindows[0]->getView()->editVisualisationSettings()->gaming = myAmGaming;
    1577            0 :     if (myAmGaming) {
    1578            0 :         myGamingModeCheckbox->setCheck(TRUE);
    1579            0 :         myMenuBar->hide();
    1580            0 :         myStatusbar->hide();
    1581            0 :         myToolBar1->hide();
    1582            0 :         myToolBar2->hide();
    1583            0 :         myToolBar4->hide();
    1584            0 :         myToolBar5->hide();
    1585            0 :         myToolBar6->show();
    1586            0 :         myToolBar8->hide();
    1587            0 :         myToolBar10->show();
    1588            0 :         if (myTLSGame) {
    1589            0 :             myToolBar7->show();
    1590              :         } else {
    1591            0 :             myToolBar9->show();
    1592              :         }
    1593            0 :         myMessageWindow->hide();
    1594            0 :         myLCDLabel->setFgColor(MFXUtils::getFXColor(RGBColor::RED));
    1595            0 :         myWaitingTimeLabel->setFgColor(MFXUtils::getFXColor(RGBColor::RED));
    1596            0 :         myTimeLossLabel->setFgColor(MFXUtils::getFXColor(RGBColor::RED));
    1597            0 :         myEmergencyVehicleLabel->setFgColor(MFXUtils::getFXColor(RGBColor::RED));
    1598            0 :         myTotalDistanceLabel->setFgColor(MFXUtils::getFXColor(RGBColor::RED));
    1599              :     } else {
    1600            0 :         myGamingModeCheckbox->setCheck(FALSE);
    1601            0 :         myMenuBar->show();
    1602            0 :         myStatusbar->show();
    1603            0 :         myToolBar1->show();
    1604            0 :         myToolBar2->show();
    1605            0 :         myToolBar4->show();
    1606            0 :         myToolBar5->show();
    1607            0 :         myToolBar6->hide();
    1608            0 :         myToolBar7->hide();
    1609            0 :         myToolBar8->show();
    1610            0 :         myToolBar9->hide();
    1611            0 :         myToolBar10->hide();
    1612            0 :         myMessageWindow->show();
    1613            0 :         myLCDLabel->setFgColor(MFXUtils::getFXColor(RGBColor::GREEN));
    1614              :     }
    1615            0 :     if (myMDIClient->numChildren() > 0) {
    1616            0 :         GUISUMOViewParent* w = dynamic_cast<GUISUMOViewParent*>(myMDIClient->getActiveChild());
    1617            0 :         if (w != nullptr) {
    1618            0 :             w->setToolBarVisibility(!myAmGaming && !myAmFullScreen);
    1619              :         }
    1620              :     }
    1621            0 :     update();
    1622            0 :     return 1;
    1623              : }
    1624              : 
    1625              : 
    1626              : long
    1627            0 : GUIApplicationWindow::onCmdToggleDrawJunctionShape(FXObject*, FXSelector, void*) {
    1628            0 :     GUISUMOViewParent* w = dynamic_cast<GUISUMOViewParent*>(myMDIClient->getActiveChild());
    1629            0 :     if (w != nullptr) {
    1630              :         // show or hide grid depending of myNetworkViewOptions.menuCheckToggleGrid
    1631            0 :         if (w->getView()->getVisualisationSettings().drawJunctionShape) {
    1632            0 :             w->getView()->editVisualisationSettings()->drawJunctionShape = false;
    1633              :         } else {
    1634            0 :             w->getView()->editVisualisationSettings()->drawJunctionShape = true;
    1635              :         }
    1636            0 :         w->getView()->update();
    1637              :     }
    1638            0 :     return 1;
    1639              : }
    1640              : 
    1641              : 
    1642              : long
    1643            0 : GUIApplicationWindow::onCmdToggleSecondaryShape(FXObject*, FXSelector, void*) {
    1644            0 :     GUISUMOViewParent* w = dynamic_cast<GUISUMOViewParent*>(myMDIClient->getActiveChild());
    1645            0 :     if (w != nullptr) {
    1646              :         // toggle secondary shape visualization
    1647            0 :         w->getView()->editVisualisationSettings()->secondaryShape = !w->getView()->getVisualisationSettings().secondaryShape;
    1648            0 :         w->getView()->update();
    1649              :     }
    1650            0 :     return 1;
    1651              : }
    1652              : 
    1653              : 
    1654              : long
    1655            0 : GUIApplicationWindow::onCmdFullScreen(FXObject*, FXSelector, void*) {
    1656            0 :     if (myGLWindows.empty()) {
    1657              :         return 1;
    1658              :     }
    1659            0 :     myAmFullScreen = !myAmFullScreen;
    1660            0 :     if (myAmFullScreen) {
    1661            0 :         getApp()->reg().writeIntEntry("SETTINGS", "x", getX());
    1662            0 :         getApp()->reg().writeIntEntry("SETTINGS", "y", getY());
    1663            0 :         getApp()->reg().writeIntEntry("SETTINGS", "width", getWidth());
    1664            0 :         getApp()->reg().writeIntEntry("SETTINGS", "height", getHeight());
    1665            0 :         maximize();
    1666            0 :         setDecorations(DECOR_NONE);
    1667            0 :         place(PLACEMENT_MAXIMIZED);
    1668            0 :         myMenuBar->hide();
    1669            0 :         myStatusbar->hide();
    1670            0 :         myToolBar1->hide();
    1671            0 :         myToolBar2->hide();
    1672            0 :         myToolBar3->hide();
    1673            0 :         myToolBar4->hide();
    1674            0 :         myToolBar5->hide();
    1675            0 :         myToolBar6->hide();
    1676            0 :         myToolBar7->hide();
    1677            0 :         myToolBar8->hide();
    1678            0 :         myMessageWindow->hide();
    1679            0 :         if (myMDIClient->numChildren() > 0) {
    1680            0 :             GUISUMOViewParent* w = dynamic_cast<GUISUMOViewParent*>(myMDIClient->getActiveChild());
    1681            0 :             if (w != nullptr) {
    1682            0 :                 w->setToolBarVisibility(false);
    1683              :             }
    1684              :         }
    1685            0 :         update();
    1686              :     } else {
    1687            0 :         place(PLACEMENT_VISIBLE);
    1688            0 :         setDecorations(DECOR_ALL);
    1689            0 :         restore();
    1690            0 :         myToolBar3->show();
    1691            0 :         myAmGaming = !myAmGaming;
    1692            0 :         onCmdGaming(nullptr, 0, nullptr);
    1693            0 :         setWidth(getApp()->reg().readIntEntry("SETTINGS", "width", 600));
    1694            0 :         setHeight(getApp()->reg().readIntEntry("SETTINGS", "height", 400));
    1695            0 :         setX(getApp()->reg().readIntEntry("SETTINGS", "x", 150));
    1696            0 :         setY(getApp()->reg().readIntEntry("SETTINGS", "y", 150));
    1697              :     }
    1698              :     return 1;
    1699              : }
    1700              : 
    1701              : 
    1702              : long
    1703            0 : GUIApplicationWindow::onCmdListInternal(FXObject*, FXSelector, void*) {
    1704            0 :     myListInternal = !myListInternal;
    1705            0 :     return 1;
    1706              : }
    1707              : 
    1708              : 
    1709              : long
    1710            0 : GUIApplicationWindow::onCmdListParking(FXObject*, FXSelector, void*) {
    1711            0 :     myListParking = !myListParking;
    1712            0 :     return 1;
    1713              : }
    1714              : 
    1715              : long
    1716            0 : GUIApplicationWindow::onCmdListTeleporting(FXObject*, FXSelector, void*) {
    1717            0 :     myListTeleporting = !myListTeleporting;
    1718            0 :     return 1;
    1719              : }
    1720              : 
    1721              : 
    1722              : long
    1723            0 : GUIApplicationWindow::onCmdNewView(FXObject*, FXSelector, void*) {
    1724            0 :     openNewView(GUISUMOViewParent::VIEW_2D_OPENGL);
    1725            0 :     return 1;
    1726              : }
    1727              : 
    1728              : 
    1729              : #ifdef HAVE_OSG
    1730              : long
    1731            0 : GUIApplicationWindow::onCmdNewOSG(FXObject*, FXSelector, void*) {
    1732            0 :     openNewView(GUISUMOViewParent::VIEW_3D_OSG);
    1733            0 :     return 1;
    1734              : }
    1735              : #endif
    1736              : 
    1737              : 
    1738              : long
    1739            0 : GUIApplicationWindow::onCmdFeedback(FXObject*, FXSelector, void*) {
    1740              :     // create and open feedback dialog
    1741            0 :     GUIDialog_Feedback* feedback = new GUIDialog_Feedback(this);
    1742            0 :     feedback->create();
    1743            0 :     feedback->show(PLACEMENT_OWNER);
    1744            0 :     return 1;
    1745              : }
    1746              : 
    1747              : 
    1748              : long
    1749            0 : GUIApplicationWindow::onCmdAbout(FXObject*, FXSelector, void*) {
    1750            0 :     GUIDialog_AboutSUMO* about = new GUIDialog_AboutSUMO(this);
    1751            0 :     about->create();
    1752            0 :     about->show(PLACEMENT_OWNER);
    1753            0 :     return 1;
    1754              : }
    1755              : 
    1756              : 
    1757              : long
    1758            0 : GUIApplicationWindow::onCmdHallOfFame(FXObject*, FXSelector, void*) {
    1759            0 :     GUIDialog_HallOfFame* hall = new GUIDialog_HallOfFame(this);
    1760            0 :     hall->create();
    1761            0 :     hall->show(PLACEMENT_OWNER);
    1762            0 :     return 1;
    1763              : }
    1764              : 
    1765              : 
    1766            0 : long GUIApplicationWindow::onClipboardRequest(FXObject* /* sender */, FXSelector /* sel */, void* ptr) {
    1767              :     FXEvent* event = (FXEvent*)ptr;
    1768            0 :     FXString string = GUIUserIO::clipped.c_str();
    1769            0 :     setDNDData(FROM_CLIPBOARD, event->target, string);
    1770            0 :     return 1;
    1771            0 : }
    1772              : 
    1773              : 
    1774              : long
    1775        60663 : GUIApplicationWindow::onLoadThreadEvent(FXObject*, FXSelector, void*) {
    1776        60663 :     eventOccurred();
    1777        60662 :     return 1;
    1778              : }
    1779              : 
    1780              : 
    1781              : long
    1782      5719199 : GUIApplicationWindow::onRunThreadEvent(FXObject*, FXSelector, void*) {
    1783      5719199 :     eventOccurred();
    1784      5719199 :     return 1;
    1785              : }
    1786              : 
    1787              : 
    1788              : void
    1789      5779862 : GUIApplicationWindow::eventOccurred() {
    1790     12356436 :     while (!myEvents.empty()) {
    1791              :         // get the next event
    1792      6576575 :         GUIEvent* e = myEvents.top();
    1793      6576575 :         myEvents.pop();
    1794              :         // process
    1795      6576575 :         switch (e->getOwnType()) {
    1796         8030 :             case GUIEventType::SIMULATION_LOADED:
    1797         8030 :                 handleEvent_SimulationLoaded(e);
    1798         8029 :                 setFocus();
    1799         8029 :                 break;
    1800      6482346 :             case GUIEventType::SIMULATION_STEP:
    1801      6482346 :                 if (myRunThread->networkAvailable()) { // avoid race-condition related crash if reload was pressed
    1802      6482346 :                     handleEvent_SimulationStep(e);
    1803              :                 }
    1804              :                 break;
    1805        79137 :             case GUIEventType::MESSAGE_OCCURRED:
    1806              :             case GUIEventType::WARNING_OCCURRED:
    1807              :             case GUIEventType::ERROR_OCCURRED:
    1808              :             case GUIEventType::DEBUG_OCCURRED:
    1809              :             case GUIEventType::GLDEBUG_OCCURRED:
    1810              :             case GUIEventType::STATUS_OCCURRED:
    1811        79137 :                 handleEvent_Message(e);
    1812        79137 :                 break;
    1813              :             case GUIEventType::ADD_VIEW: {
    1814            3 :                 GUIEvent_AddView* ave = dynamic_cast<GUIEvent_AddView*>(e);
    1815            9 :                 auto v = openNewView(ave->in3D() ? GUISUMOViewParent::VIEW_3D_OSG : GUISUMOViewParent::VIEW_2D_OPENGL, ave->getCaption());
    1816            3 :                 if (ave->getSchemeName() != "") {
    1817            3 :                     MFXComboBoxIcon* sCombo = v->getColoringSchemesCombo();
    1818            3 :                     int index = sCombo->findItem(ave->getSchemeName().c_str());
    1819            3 :                     if (index >= 0) {
    1820            3 :                         sCombo->setCurrentItem(index);
    1821              :                     }
    1822            3 :                     v->setColorScheme(ave->getSchemeName());
    1823              :                 }
    1824              :                 break;
    1825              :             }
    1826              :             case GUIEventType::CLOSE_VIEW: {
    1827            3 :                 GUIEvent_CloseView* ave = dynamic_cast<GUIEvent_CloseView*>(e);
    1828            3 :                 removeViewByID(ave->getCaption());
    1829            3 :                 break;
    1830              :             }
    1831         7056 :             case GUIEventType::SIMULATION_ENDED:
    1832         7056 :                 handleEvent_SimulationEnded(e);
    1833         7056 :                 break;
    1834              :             default:
    1835              :                 break;
    1836              :         }
    1837      6576574 :         delete e;
    1838              :     }
    1839      5779861 :     myToolBar2->forceRefresh();
    1840      5779861 :     myToolBar3->forceRefresh();
    1841      5779861 : }
    1842              : 
    1843              : 
    1844              : void
    1845         8030 : GUIApplicationWindow::handleEvent_SimulationLoaded(GUIEvent* e) {
    1846         8030 :     myAmLoading = false;
    1847              :     GUIEvent_SimulationLoaded* ec = static_cast<GUIEvent_SimulationLoaded*>(e);
    1848              :     // check whether the loading was successful
    1849         8030 :     if (ec->myNet == nullptr) {
    1850              :         // report failure
    1851          562 :         setStatusBarText(TLF("Loading of '%' failed!", ec->myFile));
    1852          281 :         if (GUIGlobals::gQuitOnEnd) {
    1853          281 :             closeAllWindows();
    1854          281 :             getApp()->exit(1);
    1855              :         }
    1856              :     } else {
    1857              :         // initialise simulation thread
    1858         7749 :         if (!myRunThread->init(ec->myNet, ec->myBegin, ec->myEnd)) {
    1859          171 :             if (GUIGlobals::gQuitOnEnd) {
    1860          171 :                 closeAllWindows();
    1861          171 :                 getApp()->exit(1);
    1862              :             }
    1863              :         } else {
    1864              :             // report success
    1865        15156 :             setStatusBarText(TLF("'%' loaded.", ec->myFile));
    1866         7578 :             setWindowSizeAndPos();
    1867         7578 :             myWasStarted = false;
    1868         7578 :             myHaveNotifiedAboutSimEnd = false;
    1869              :             // initialise views
    1870         7578 :             myViewNumber = 0;
    1871         7578 :             const GUISUMOViewParent::ViewType defaultType = ec->myOsgView ? GUISUMOViewParent::VIEW_3D_OSG : GUISUMOViewParent::VIEW_2D_OPENGL;
    1872              :             // check/record settings file modification time
    1873         7578 :             long long mTime = myGuiSettingsFileMTime;
    1874         7578 :             if (ec->mySettingsFiles.size() > 0) {
    1875           75 :                 for (std::string fname : ec->mySettingsFiles) {
    1876           38 :                     mTime = MAX2(mTime, SysUtils::getModifiedTime(fname));
    1877              :                 }
    1878              :             }
    1879              :             // always reload if settings were modified or to restore multiple views
    1880         7578 :             if (!myIsReload) {
    1881              :                 gSchemeStorage.clearDecals();
    1882              :             }
    1883         7578 :             if (ec->mySettingsFiles.size() > 0 && (!myIsReload || myGuiSettingsFileMTime < mTime || ec->mySettingsFiles.size() > 1)) {
    1884              :                 // open a view for each file and apply settings
    1885           74 :                 for (std::string fname : ec->mySettingsFiles) {
    1886           38 :                     GUISettingsHandler settings(fname);
    1887              :                     GUISUMOViewParent::ViewType vt = defaultType;
    1888           38 :                     if (settings.getViewType() == "osg" || settings.getViewType() == "3d") {
    1889              :                         vt = GUISUMOViewParent::VIEW_3D_OSG;
    1890              :                     }
    1891           38 :                     if (settings.getViewType() == "opengl" || settings.getViewType() == "2d") {
    1892              :                         vt = GUISUMOViewParent::VIEW_2D_OPENGL;
    1893              :                     }
    1894           38 :                     GUISUMOAbstractView* view = openNewView(vt);
    1895           37 :                     if (view == nullptr) {
    1896              :                         break;
    1897              :                     }
    1898           37 :                     if (settings.getSettingName() != "") {
    1899           37 :                         view->setColorScheme(settings.getSettingName());
    1900           37 :                         MFXComboBoxIcon* sCombo = view->getColoringSchemesCombo();
    1901           37 :                         int index = sCombo->findItem(settings.getSettingName().c_str());
    1902           37 :                         if (index >= 0) {
    1903           34 :                             sCombo->setCurrentItem(index);
    1904              :                         }
    1905              :                     }
    1906           37 :                     view->addDecals(settings.getDecals());
    1907           37 :                     settings.applyViewport(view);
    1908           37 :                     settings.setSnapshots(view);
    1909           37 :                     if (settings.getDelay() > 0.) {
    1910            5 :                         mySimDelay = settings.getDelay();
    1911              :                     }
    1912           37 :                     if (settings.getBreakpoints().size() > 0) {
    1913            0 :                         myRunThread->getBreakpointLock().lock();
    1914            0 :                         myRunThread->getBreakpoints().assign(settings.getBreakpoints().begin(), settings.getBreakpoints().end());
    1915            0 :                         myRunThread->getBreakpointLock().unlock();
    1916              :                     }
    1917           37 :                     myJamSounds = settings.getEventDistribution("jam");
    1918           74 :                     myCollisionSounds = settings.getEventDistribution("collision");
    1919           37 :                     if (settings.getJamSoundTime() > 0) {
    1920            0 :                         myJamSoundTime = settings.getJamSoundTime();
    1921              :                     }
    1922           37 :                     for (const std::string& tlsID : settings.getTrackers()) {
    1923            0 :                         if (MSNet::getInstance()->getTLSControl().knows(tlsID)) {
    1924            0 :                             MSTrafficLightLogic* tll = MSNet::getInstance()->getTLSControl().get(tlsID).getActive();
    1925            0 :                             GUITrafficLightLogicWrapper* tllW = GUINet::getGUIInstance()->getTLLWrapper(tll);
    1926            0 :                             if (tllW) {
    1927            0 :                                 tllW->begin2TrackPhases(this);
    1928              :                             }
    1929              :                         } else {
    1930            0 :                             WRITE_WARNINGF("Tracker for unknown tlLogic '%' in settings file '%'", tlsID, fname);
    1931              :                         }
    1932           37 :                     }
    1933           37 :                 }
    1934              :             } else {
    1935        15082 :                 openNewView(defaultType);
    1936              :             }
    1937         7577 :             myGuiSettingsFileMTime = mTime;
    1938        15154 :             if (!OptionsCont::getOptions().isDefault("delay")) {
    1939            4 :                 setDelay(OptionsCont::getOptions().getFloat("delay"));
    1940            4 :                 mySimDelaySlider->setValue((int)mySimDelay);
    1941            4 :                 mySimDelaySpinner->setValue(mySimDelay);
    1942              :             }
    1943        15154 :             if (!OptionsCont::getOptions().isDefault("breakpoints") && !myIsReload) {
    1944              :                 std::vector<SUMOTime> breakpoints;
    1945            0 :                 for (const std::string& val : OptionsCont::getOptions().getStringVector("breakpoints")) {
    1946            0 :                     SUMOTime t = string2time(val);
    1947              :                     // round down to nearest reachable time step
    1948            0 :                     t -= t % DELTA_T;
    1949            0 :                     breakpoints.push_back(t);
    1950              :                 }
    1951            0 :                 std::sort(breakpoints.begin(), breakpoints.end());
    1952            0 :                 myRunThread->getBreakpointLock().lock();
    1953            0 :                 myRunThread->getBreakpoints().assign(breakpoints.begin(), breakpoints.end());
    1954            0 :                 myRunThread->getBreakpointLock().unlock();
    1955            0 :             }
    1956        15154 :             if (!OptionsCont::getOptions().isDefault("selection-file")) {
    1957            0 :                 delete myDynamicSelection;
    1958            0 :                 myDynamicSelection = new std::stringstream();
    1959            0 :                 std::string msg = gSelected.load(OptionsCont::getOptions().getString("selection-file"), GLO_MAX, myDynamicSelection);
    1960            0 :                 if (msg != "") {
    1961            0 :                     WRITE_ERRORF("Errors while loading selection: %", msg.c_str());
    1962              :                 }
    1963            0 :                 if (!myDynamicSelection->str().empty()) {
    1964              :                     std::string dummy;
    1965              :                     int numNotFound = 0;
    1966            0 :                     while (myDynamicSelection->good()) {
    1967            0 :                         (*myDynamicSelection) >> dummy;
    1968            0 :                         numNotFound++;
    1969              :                     }
    1970            0 :                     myDynamicSelection->clear(); // first clear error state before seek works
    1971            0 :                     myDynamicSelection->seekg(0);
    1972              :                     // @note for some reason the last line is read twice
    1973            0 :                     WRITE_MESSAGEF("% dynamic objects not present while loading selection", numNotFound - 1);
    1974              :                 }
    1975              :             }
    1976         7577 :             myTLSGame = OptionsCont::getOptions().getString("game.mode") == "tls";
    1977        15154 :             if (OptionsCont::getOptions().getBool("game")) {
    1978            0 :                 if (myTLSGame) {
    1979            0 :                     setTitle(TL("SUMO Interactive Traffic Light"));
    1980              :                 } else {
    1981            0 :                     setTitle(TL("SUMO Interactive Demand-Responsive-Transport"));
    1982              :                 }
    1983            0 :                 onCmdGaming(nullptr, 0, nullptr);
    1984              :             } else {
    1985              :                 // set simulation name on the caption
    1986         7577 :                 setTitle(MFXUtils::getTitleText("SUMO " VERSION_STRING, ec->myFile.c_str()));
    1987              :             }
    1988         7577 :             if (ec->myViewportFromRegistry) {
    1989              :                 Position off;
    1990            0 :                 off.set(getApp()->reg().readRealEntry("viewport", "x"),
    1991              :                         getApp()->reg().readRealEntry("viewport", "y"),
    1992              :                         getApp()->reg().readRealEntry("viewport", "z"));
    1993              :                 Position p(off.x(), off.y(), 0);
    1994            0 :                 GUISUMOAbstractView* view = myGLWindows[0]->getView();
    1995            0 :                 view->setViewportFromToRot(off, p, 0);
    1996              :             }
    1997              :             // set simulation step begin information
    1998         7577 :             myLCDLabel->setText("----------------");
    1999        30308 :             for (std::vector<FXButton*>::const_iterator it = myStatButtons.begin(); it != myStatButtons.end(); ++it) {
    2000        22731 :                 (*it)->setText("-");
    2001              :             }
    2002              :             // initialize scale from options unless already set in the UI
    2003         7577 :             if (myDemandScaleSpinner->getValue() == 1 || !OptionsCont::getOptions().isDefault("scale")) {
    2004        15154 :                 myDemandScaleSpinner->setValue(OptionsCont::getOptions().getFloat("scale"));
    2005              :             }
    2006         7577 :             myRunThread->getNet().getVehicleControl().setScale(myDemandScaleSpinner->getValue());
    2007              :         }
    2008              :     }
    2009         8029 :     getApp()->endWaitCursor();
    2010              :     // start if wished
    2011         8029 :     if (GUIGlobals::gRunAfterLoad && ec->myNet != nullptr && myRunThread->simulationIsStartable()) {
    2012         7577 :         onCmdStart(nullptr, 0, nullptr);
    2013              :     }
    2014         8029 :     update();
    2015         8029 : }
    2016              : 
    2017              : 
    2018              : void
    2019      6482389 : GUIApplicationWindow::handleEvent_SimulationStep(GUIEvent*) {
    2020              : #ifdef WIN32
    2021              :     long t = SysUtils::getCurrentMillis();
    2022              :     // only skip if the simulation is running
    2023              :     if (t - myLastStepEventMillis < MIN_DRAW_DELAY && myRunThread->simulationIsStopable()) {
    2024              :         // do not try to redraw with more than 50FPS (#6371)
    2025              :         return;
    2026              :     }
    2027              :     myLastStepEventMillis = t;
    2028              : #endif
    2029      6482389 :     updateTimeLCD(myRunThread->getNet().getCurrentTimeStep());
    2030      6482389 :     const int running = myRunThread->getNet().getVehicleControl().getRunningVehicleNo();
    2031      6482389 :     const int backlog = myRunThread->getNet().getInsertionControl().getWaitingVehicleNo();
    2032      6482389 :     if (backlog > running) {
    2033       524791 :         if (myStatButtons.front()->getIcon() == GUIIconSubSys::getIcon(GUIIcon::GREENVEHICLE)) {
    2034         1477 :             myStatButtons.front()->setIcon(GUIIconSubSys::getIcon(GUIIcon::YELLOWVEHICLE));
    2035              :         }
    2036              :     } else {
    2037      5957598 :         if (myStatButtons.front()->getIcon() == GUIIconSubSys::getIcon(GUIIcon::YELLOWVEHICLE)) {
    2038         1372 :             myStatButtons.front()->setIcon(GUIIconSubSys::getIcon(GUIIcon::GREENVEHICLE));
    2039              :         }
    2040              :     }
    2041      6482389 :     myStatButtons.front()->setText(toString(running).c_str());
    2042      6482389 :     if (myRunThread->getNet().hasPersons()) {
    2043      1215860 :         if (!myStatButtons[1]->shown()) {
    2044         1504 :             myStatButtons[1]->show();
    2045              :         }
    2046      2431720 :         myStatButtons[1]->setText(toString(myRunThread->getNet().getPersonControl().getRunningNumber()).c_str());
    2047              :     }
    2048      6482389 :     if (myRunThread->getNet().hasContainers()) {
    2049       108117 :         if (!myStatButtons[2]->shown()) {
    2050          170 :             myStatButtons[2]->show();
    2051              :         }
    2052       216234 :         myStatButtons[2]->setText(toString(myRunThread->getNet().getContainerControl().getRunningNumber()).c_str());
    2053              :     }
    2054      6482389 :     if (myAmGaming) {
    2055            0 :         if (myTLSGame) {
    2056            0 :             checkGamingEvents();
    2057              :         } else {
    2058            0 :             checkGamingEventsDRT();
    2059              :         }
    2060              :     }
    2061      6482389 :     if (myRunThread->simulationIsStartable()) {
    2062       403256 :         getApp()->forceRefresh(); // restores keyboard focus
    2063              :     }
    2064              :     // try to load dynamic selection
    2065      6482389 :     if (myDynamicSelection != nullptr) {
    2066            0 :         std::stringstream tmp;
    2067            0 :         gSelected.load(*myDynamicSelection, GLO_MAX, &tmp);
    2068            0 :         if (tmp.str().empty()) {
    2069            0 :             delete myDynamicSelection;
    2070            0 :             myDynamicSelection = nullptr;
    2071              :         } else {
    2072            0 :             myDynamicSelection->str(tmp.str());
    2073            0 :             myDynamicSelection->clear(); // first clear error state before seek works
    2074            0 :             myDynamicSelection->seekg(0);
    2075              :         }
    2076            0 :     }
    2077      6482389 :     updateChildren();
    2078      6482389 :     update();
    2079      6482389 : }
    2080              : 
    2081              : 
    2082              : void
    2083        79137 : GUIApplicationWindow::handleEvent_Message(GUIEvent* e) {
    2084              :     GUIEvent_Message* ec = static_cast<GUIEvent_Message*>(e);
    2085        79137 :     if (ec->getOwnType() == GUIEventType::STATUS_OCCURRED) {
    2086         8028 :         setStatusBarText(ec->getMsg());
    2087              :     } else {
    2088        71109 :         myMessageWindow->appendMsg(ec->getOwnType(), ec->getMsg());
    2089              :     }
    2090        79137 : }
    2091              : 
    2092              : 
    2093              : void
    2094         7056 : GUIApplicationWindow::handleEvent_SimulationEnded(GUIEvent* e) {
    2095              :     GUIEvent_SimulationEnded* ec = static_cast<GUIEvent_SimulationEnded*>(e);
    2096         7056 :     onCmdStop(nullptr, 0, nullptr);
    2097         7056 :     if (ec->getReason() == MSNet::SIMSTATE_LOADING) {
    2098            0 :         onCmdReload(nullptr, 0, nullptr);
    2099         7056 :     } else if (GUIGlobals::gQuitOnEnd) {
    2100         7056 :         closeAllWindows();
    2101         7056 :         getApp()->exit(ec->getReason() == MSNet::SIMSTATE_ERROR_IN_SIM);
    2102            0 :     } else if (GUIGlobals::gDemoAutoReload) {
    2103            0 :         onCmdReload(nullptr, 1, nullptr);
    2104            0 :     } else if (!myHaveNotifiedAboutSimEnd) {
    2105              :         // GUIRunThread::deleteSim() triggers the final message to the log file
    2106              :         // (this will never reach the GUI but we cannot use WRITE_MESSAGE here
    2107              :         // to avoid a duplicate log entry)
    2108            0 :         myMessageWindow->appendMsg(GUIEventType::MESSAGE_OCCURRED,
    2109            0 :                                    TLF("Simulation ended at time: %. (%)",
    2110            0 :                                        time2string(ec->getTimeStep()), MSNet::getStateMessage(ec->getReason())) + "\n");
    2111              :         // build the text
    2112            0 :         const std::string text = TLF("Simulation ended at time: %.", time2string(ec->getTimeStep())) + "\n" +
    2113            0 :                                  TL("Reason:") + MSNet::getStateMessage(ec->getReason()) + "\n" +
    2114            0 :                                  TL("Do you want to close all open files and views?");
    2115            0 :         FXuint answer = FXMessageBox::question(this, MBOX_YES_NO, TL("Simulation ended"), "%s", text.c_str());
    2116            0 :         if (answer == 1) { //1:yes, 2:no, 4:esc
    2117            0 :             closeAllWindows();
    2118              :         } else {
    2119            0 :             GUINet::getGUIInstance()->flushOutputsAtEnd();
    2120            0 :             updateChildren();
    2121            0 :             update();
    2122              :         }
    2123            0 :         myHaveNotifiedAboutSimEnd = true;
    2124              :     }
    2125         7056 : }
    2126              : 
    2127              : 
    2128              : void
    2129            0 : GUIApplicationWindow::checkGamingEvents() {
    2130            0 :     MSVehicleControl& vc = MSNet::getInstance()->getVehicleControl();
    2131              :     MSVehicleControl::constVehIt it = vc.loadedVehBegin();
    2132              :     MSVehicleControl::constVehIt end = vc.loadedVehEnd();
    2133              : #ifdef HAVE_DANGEROUS_SOUNDS // disable user-configurable command execution for public build
    2134              :     if (myJamSounds.getOverallProb() > 0) {
    2135              :         // play honking sound if some vehicle is waiting too long
    2136              :         for (; it != end; ++it) {
    2137              :             // XXX use impatience instead of waiting time ?
    2138              :             if (it->second->getWaitingTime() > TIME2STEPS(myJamSoundTime)) {
    2139              :                 const std::string cmd = myJamSounds.get(&myGamingRNG);
    2140              :                 if (cmd != "") {
    2141              :                     // yay! fun with dangerous commands... Never use this over the internet
    2142              :                     SysUtils::runHiddenCommand(cmd);
    2143              :                     // one sound per simulation step is enough
    2144              :                     break;
    2145              :                 }
    2146              :             }
    2147              :         }
    2148              :     }
    2149              :     if (myCollisionSounds.getOverallProb() > 0) {
    2150              :         int collisions = MSNet::getInstance()->getVehicleControl().getCollisionCount();
    2151              :         if (myPreviousCollisionNumber != collisions) {
    2152              :             const std::string cmd = myCollisionSounds.get(&myGamingRNG);
    2153              :             if (cmd != "") {
    2154              :                 // yay! fun with dangerous commands... Never use this over the internet
    2155              :                 SysUtils::runHiddenCommand(cmd);
    2156              :             }
    2157              :             myPreviousCollisionNumber = collisions;
    2158              :         }
    2159              :     }
    2160              : #endif
    2161              :     // update performance indicators
    2162            0 :     for (it = vc.loadedVehBegin(); it != end; ++it) {
    2163            0 :         const MSVehicle* veh = dynamic_cast<MSVehicle*>(it->second);
    2164              :         assert(veh != 0);
    2165            0 :         if (veh->isOnRoad() && !veh->isStopped()) {
    2166            0 :             const double vmax = veh->getLane()->getVehicleMaxSpeed(veh);
    2167            0 :             if (veh->getSpeed() < SUMO_const_haltingSpeed) {
    2168            0 :                 myWaitingTime += DELTA_T;
    2169            0 :                 if (veh->getVClass() == SVC_EMERGENCY) {
    2170            0 :                     myEmergencyVehicleCount += DELTA_T;
    2171              :                 }
    2172              :             }
    2173            0 :             myTimeLoss += TIME2STEPS(TS * (vmax - veh->getSpeed()) / vmax); // may be negative with speedFactor > 1
    2174              :         }
    2175              : 
    2176              :     }
    2177            0 :     myWaitingTimeLabel->setText(time2string(myWaitingTime, myShowTimeAsHMS).c_str());
    2178            0 :     myTimeLossLabel->setText(time2string(myTimeLoss, myShowTimeAsHMS).c_str());
    2179            0 :     myEmergencyVehicleLabel->setText(time2string(myEmergencyVehicleCount, myShowTimeAsHMS).c_str());
    2180            0 : }
    2181              : 
    2182              : 
    2183              : void
    2184            0 : GUIApplicationWindow::checkGamingEventsDRT() {
    2185              :     // update performance indicators
    2186            0 :     MSTransportableControl& pc = myRunThread->getNet().getPersonControl();
    2187            0 :     myWaitingTime += pc.getWaitingForVehicleNumber() * DELTA_T;
    2188            0 :     myWaitingTimeLabel->setText(time2string(myWaitingTime).c_str());
    2189              : 
    2190            0 :     MSVehicleControl& vc = MSNet::getInstance()->getVehicleControl();
    2191              :     MSVehicleControl::constVehIt end = vc.loadedVehEnd();
    2192            0 :     for (auto it = vc.loadedVehBegin(); it != end; ++it) {
    2193            0 :         const MSVehicle* veh = dynamic_cast<MSVehicle*>(it->second);
    2194              :         assert(veh != 0);
    2195            0 :         if (veh->isOnRoad() && !veh->isStopped()) {
    2196            0 :             myTotalDistance += SPEED2DIST(veh->getSpeed());
    2197              :         }
    2198              :     }
    2199            0 :     myTotalDistanceLabel->setText(toString(myTotalDistance / 100).c_str());
    2200            0 : }
    2201              : 
    2202              : 
    2203              : void
    2204         8030 : GUIApplicationWindow::loadConfigOrNet(const std::string& file) {
    2205         8030 :     if (!myAmLoading) {
    2206         8030 :         storeWindowSizeAndPos();
    2207         8030 :         getApp()->beginWaitCursor();
    2208         8030 :         myAmLoading = true;
    2209         8030 :         myIsReload = false;
    2210         8030 :         closeAllWindows();
    2211         8030 :         gSchemeStorage.saveViewport(0, 0, -1, 0); // recenter view
    2212         8030 :         myLoadThread->loadConfigOrNet(file);
    2213        16060 :         setStatusBarText(TLF("Loading '%'.", file));
    2214         8030 :         update();
    2215              :     }
    2216         8030 : }
    2217              : 
    2218              : 
    2219              : GUISUMOAbstractView*
    2220         7582 : GUIApplicationWindow::openNewView(GUISUMOViewParent::ViewType vt, std::string caption) {
    2221         7582 :     if (!myRunThread->networkAvailable()) {
    2222            0 :         myStatusbar->getStatusLine()->setText(TL("No simulation loaded!"));
    2223            0 :         return nullptr;
    2224              :     }
    2225              :     GUISUMOAbstractView* oldView = nullptr;
    2226         7582 :     if (myMDIClient->numChildren() > 0) {
    2227            4 :         GUISUMOViewParent* w = dynamic_cast<GUISUMOViewParent*>(myMDIClient->getActiveChild());
    2228            4 :         if (w != nullptr) {
    2229            4 :             oldView = w->getView();
    2230              :         }
    2231              :     }
    2232         7582 :     if (caption == "") {
    2233        22737 :         caption = "View #" + toString(myViewNumber++);
    2234              :     }
    2235              :     FXuint opts = MDI_TRACKING;
    2236        15164 :     GUISUMOViewParent* w = new GUISUMOViewParent(myMDIClient, myMDIMenu, FXString(caption.c_str()),
    2237         7582 :             this, GUIIconSubSys::getIcon(GUIIcon::SUMO_MINI), opts, 10, 10, 200, 100);
    2238         7582 :     GUISUMOAbstractView* v = w->init(getBuildGLCanvas(), myRunThread->getNet(), vt);
    2239         7582 :     if (oldView != nullptr) {
    2240              :         // copy viewport
    2241            4 :         oldView->copyViewportTo(v);
    2242              :     }
    2243         7582 :     w->create();
    2244         7581 :     if (myMDIClient->numChildren() == 1) {
    2245         7577 :         w->maximize();
    2246              :     } else {
    2247            4 :         myMDIClient->vertical(true);
    2248              :     }
    2249         7581 :     myMDIClient->setActiveChild(w);
    2250              : 
    2251         7581 :     return v;
    2252              : }
    2253              : 
    2254              : 
    2255              : FXGLCanvas*
    2256         7582 : GUIApplicationWindow::getBuildGLCanvas() const {
    2257         7582 :     if (myMDIClient->numChildren() == 0) {
    2258              :         return nullptr;
    2259              :     }
    2260              :     GUISUMOViewParent* share_tmp1 =
    2261         7582 :         static_cast<GUISUMOViewParent*>(myMDIClient->childAtIndex(0));
    2262         7582 :     return share_tmp1->getBuildGLCanvas();
    2263              : }
    2264              : 
    2265              : 
    2266              : void
    2267        23542 : GUIApplicationWindow::closeAllWindows() {
    2268        23542 :     myTrackerLock.lock();
    2269        23542 :     myLCDLabel->setText("----------------");
    2270        94168 :     for (std::vector<FXButton*>::const_iterator it = myStatButtons.begin(); it != myStatButtons.end(); ++it) {
    2271        70626 :         (*it)->setText("-");
    2272        70626 :         if (it != myStatButtons.begin()) {
    2273        47084 :             (*it)->hide();
    2274              :         }
    2275              :     }
    2276              :     // delete the simulation
    2277        23542 :     myRunThread->deleteSim();
    2278              :     // reset the caption
    2279        23542 :     setTitle(MFXUtils::getTitleText("SUMO " VERSION_STRING));
    2280              :     // remove trackers and other external windows (must be delayed until deleteSim)
    2281        54637 :     while (!myGLWindows.empty()) {
    2282         7553 :         delete myGLWindows.front();
    2283              :     }
    2284              :     // make a copy because deleting modifyes the vector;
    2285        23542 :     std::vector<FXMainWindow*> trackerWindows = myTrackerWindows;
    2286        23542 :     for (FXMainWindow* const window : trackerWindows) {
    2287            0 :         delete window;
    2288              :     }
    2289              :     myTrackerWindows.clear();
    2290              :     // clear selected items
    2291        23542 :     gSelected.clear();
    2292              :     // add a separator to the log
    2293        23542 :     myMessageWindow->addSeparator();
    2294        23542 :     myTrackerLock.unlock();
    2295              :     // remove coordinate information
    2296        23542 :     myGeoCoordinate->setText(TL("N/A"));
    2297        23542 :     myCartesianCoordinate->setText(TL("N/A"));
    2298        23542 :     if (myTestCoordinate) {
    2299            0 :         myTestCoordinate->setText(TL("N/A"));
    2300              :     }
    2301              :     //
    2302        23542 :     GUITexturesHelper::clearTextures();
    2303        23542 :     GLHelper::resetFont();
    2304        23542 :     update();
    2305        23542 : }
    2306              : 
    2307              : 
    2308              : FXCursor*
    2309            0 : GUIApplicationWindow::getDefaultCursor() {
    2310            0 :     return getApp()->getDefaultCursor(DEF_ARROW_CURSOR);
    2311              : }
    2312              : 
    2313              : 
    2314              : SUMOTime
    2315            0 : GUIApplicationWindow::getCurrentSimTime() const {
    2316            0 :     return myRunThread->getNet().getCurrentTimeStep();
    2317              : }
    2318              : 
    2319              : 
    2320              : double
    2321            0 : GUIApplicationWindow::getTrackerInterval() const {
    2322            0 :     return GUIGlobals::gTrackerInterval;
    2323              : }
    2324              : 
    2325              : 
    2326              : void
    2327         8030 : GUIApplicationWindow::loadOnStartup(const bool wait) {
    2328         8030 :     loadConfigOrNet("");
    2329         8030 :     if (wait) {
    2330         1289 :         while (myAmLoading) {
    2331          767 :             myRunThread->sleep(50);
    2332              :         }
    2333              :     }
    2334         8030 : }
    2335              : 
    2336              : 
    2337              : void
    2338        31947 : GUIApplicationWindow::setStatusBarText(const std::string& text) {
    2339        31947 :     myStatusbar->getStatusLine()->setText(text.c_str());
    2340        31947 :     myStatusbar->getStatusLine()->setNormalText(text.c_str());
    2341        31947 : }
    2342              : 
    2343              : 
    2344              : void
    2345         7725 : GUIApplicationWindow::addRecentNetwork(const FX::FXString& f) {
    2346         7725 :     myRecentNetworks.appendFile(f);
    2347         7725 : }
    2348              : 
    2349              : 
    2350              : void
    2351          303 : GUIApplicationWindow::addRecentConfig(const FX::FXString& f) {
    2352          303 :     myRecentConfigs.appendFile(f);
    2353          303 : }
    2354              : 
    2355              : 
    2356              : void
    2357         8030 : GUIApplicationWindow::updateTimeLCDTooltip() {
    2358         8030 :     if (myShowTimeAsHMS) {
    2359            0 :         myLCDLabel->setToolTipText("HH:MM:SS");
    2360            0 :         if (myAmGaming) {
    2361            0 :             myWaitingTimeLabel->setToolTipText("HH:MM:SS");
    2362            0 :             myTimeLossLabel->setToolTipText("HH:MM:SS");
    2363            0 :             myEmergencyVehicleLabel->setToolTipText("HH:MM:SS");
    2364              :         }
    2365              :     } else {
    2366         8030 :         myLCDLabel->setToolTipText(TL("seconds"));
    2367         8030 :         if (myAmGaming) {
    2368            0 :             myWaitingTimeLabel->setToolTipText(TL("seconds"));
    2369            0 :             myTimeLossLabel->setToolTipText(TL("seconds"));
    2370            0 :             myEmergencyVehicleLabel->setToolTipText(TL("seconds"));
    2371              :         }
    2372              :     }
    2373         8030 : }
    2374              : 
    2375              : 
    2376              : void
    2377      6482389 : GUIApplicationWindow::updateTimeLCD(SUMOTime time) {
    2378      6482389 :     time -= DELTA_T; // synchronize displayed time with netstate output
    2379      6482389 :     if (time < 0) {
    2380            6 :         myLCDLabel->setText("----------------");
    2381            6 :         return;
    2382              :     }
    2383      6482383 :     if (myAmGaming) {
    2384              :         // show time counting backwards
    2385            0 :         time = myRunThread->getSimEndTime() - time;
    2386              :     }
    2387      6482383 :     std::ostringstream str;
    2388              :     str << std::setfill('0');
    2389      6482383 :     const bool hideFraction = myAmGaming || DELTA_T % 1000 == 0;
    2390      6482383 :     if (myShowTimeAsHMS) {
    2391            0 :         SUMOTime day = time / 86400000;
    2392            0 :         if (day > 0) {
    2393            0 :             str << day << '-';
    2394            0 :             time %= 86400000;
    2395              :         }
    2396              :         str << std::setw(2);
    2397            0 :         str << time / 3600000 << '-';
    2398            0 :         time %= 3600000;
    2399            0 :         str << std::setw(2) << time / 60000 << '-';
    2400            0 :         time %= 60000;
    2401              :     }
    2402      6482383 :     str << std::setw(2) << time / 1000;
    2403      6482383 :     if (!hideFraction) {
    2404      1473642 :         str << '.' << std::setw(3) << time % 1000;
    2405              :     }
    2406      6482383 :     myLCDLabel->setText(str.str().c_str());
    2407      6482383 : }
    2408              : 
    2409              : 
    2410              : void
    2411            0 : GUIApplicationWindow::addHotkey(int key, Command* press, Command* release) {
    2412            0 :     if (press != nullptr) {
    2413            0 :         myHotkeyPress[key] = press;
    2414              :     }
    2415            0 :     if (release != nullptr) {
    2416            0 :         myHotkeyRelease[key] = release;
    2417              :     }
    2418            0 : }
    2419              : 
    2420              : 
    2421              : long
    2422            0 : GUIApplicationWindow::onKeyPress(FXObject* o, FXSelector sel, void* ptr) {
    2423              :     FXEvent* e = (FXEvent*) ptr;
    2424              :     // PgUp and PgDown switch between widgets by default and binding them via menu shortcuts does not work reliably
    2425              :     // so we must intercept them before FXMainWindow can handle it
    2426            0 :     if (e->code == FX::KEY_Page_Up) {
    2427            0 :         onCmdDelayInc(nullptr, 0, nullptr);
    2428            0 :     } else if (e->code == FX::KEY_Page_Down) {
    2429            0 :         onCmdDelayDec(nullptr, 0, nullptr);
    2430              :     } else {
    2431              :         // disable hotkeys without modifiers for the game
    2432            0 :         const bool ignoreSimple = myAmGaming && (e->state & (CONTROLMASK | SHIFTMASK | ALTMASK)) == 0;
    2433            0 :         const long handled = ignoreSimple ? 0 : FXMainWindow::onKeyPress(o, sel, ptr);
    2434            0 :         if (handled == 0 && myMDIClient->numChildren() > 0) {
    2435              :             auto it = myHotkeyPress.find(e->code);
    2436            0 :             if (it != myHotkeyPress.end()) {
    2437            0 :                 it->second->execute(SIMSTEP);
    2438              :             }
    2439            0 :             if (!ignoreSimple) {
    2440            0 :                 GUISUMOViewParent* w = dynamic_cast<GUISUMOViewParent*>(myMDIClient->getActiveChild());
    2441            0 :                 if (w != nullptr) {
    2442            0 :                     w->onKeyPress(nullptr, sel, ptr);
    2443              :                 }
    2444              :             }
    2445              :         }
    2446              :     }
    2447            0 :     return 0;
    2448              : }
    2449              : 
    2450              : 
    2451              : long
    2452            0 : GUIApplicationWindow::onKeyRelease(FXObject* o, FXSelector sel, void* ptr) {
    2453            0 :     const long handled = FXMainWindow::onKeyRelease(o, sel, ptr);
    2454            0 :     if (handled == 0 && myMDIClient->numChildren() > 0) {
    2455              :         FXEvent* e = (FXEvent*) ptr;
    2456              :         auto it = myHotkeyRelease.find(e->code);
    2457            0 :         if (it != myHotkeyRelease.end()) {
    2458            0 :             it->second->execute(SIMSTEP);
    2459              :         }
    2460            0 :         GUISUMOViewParent* w = dynamic_cast<GUISUMOViewParent*>(myMDIClient->getActiveChild());
    2461            0 :         if (w != nullptr) {
    2462            0 :             w->onKeyRelease(nullptr, sel, ptr);
    2463              :         }
    2464              :     }
    2465            0 :     return 0;
    2466              : }
    2467              : 
    2468              : 
    2469              : double
    2470            0 : GUIApplicationWindow::getDelay() const {
    2471            0 :     return mySimDelay;
    2472              : }
    2473              : 
    2474              : 
    2475              : void
    2476            4 : GUIApplicationWindow::setDelay(double delay) {
    2477            4 :     mySimDelay = delay;
    2478            4 : }
    2479              : 
    2480              : 
    2481              : void
    2482            6 : GUIApplicationWindow::sendBlockingEvent(GUIEvent* event) {
    2483            6 :     myEventMutex.lock();
    2484            6 :     myEvents.push_back(event);
    2485            6 :     myRunThreadEvent.signal();
    2486              :     //myEventCondition.wait(myEventMutex);
    2487            6 :     myEventMutex.unlock();
    2488            6 : }
    2489              : 
    2490              : 
    2491              : void
    2492            0 : GUIApplicationWindow::setBreakpoints(const std::vector<SUMOTime>& breakpoints) {
    2493            0 :     if (myRunThread != nullptr) {
    2494            0 :         myRunThread->getBreakpointLock().lock();
    2495            0 :         myRunThread->getBreakpoints().assign(breakpoints.begin(), breakpoints.end());
    2496            0 :         myRunThread->getBreakpointLock().unlock();
    2497            0 :         updateChildren(MID_TIMELINK_BREAKPOINT);
    2498              :     }
    2499            0 : }
    2500              : 
    2501              : 
    2502              : void
    2503            0 : GUIApplicationWindow::addBreakpoint(SUMOTime time) {
    2504            0 :     const SUMOTime begin = string2time(OptionsCont::getOptions().getString("begin"));
    2505            0 :     if (time >= begin) {
    2506              :         // ensure breakpoint is valid
    2507            0 :         time -= (time - begin) % DELTA_T;
    2508            0 :         std::vector<SUMOTime> breakpoints = retrieveBreakpoints();
    2509            0 :         if (std::find(breakpoints.begin(), breakpoints.end(), time) == breakpoints.end()) {
    2510            0 :             breakpoints.push_back(time);
    2511            0 :             std::sort(breakpoints.begin(), breakpoints.end());
    2512            0 :             setBreakpoints(breakpoints);
    2513            0 :             setStatusBarText(TLF("Set breakpoint at %", time2string(time)));
    2514              :         }
    2515            0 :     }
    2516            0 : }
    2517              : 
    2518              : 
    2519              : const std::vector<SUMOTime>
    2520            0 : GUIApplicationWindow::retrieveBreakpoints() const {
    2521            0 :     myRunThread->getBreakpointLock().lock();
    2522            0 :     std::vector<SUMOTime> result = myRunThread->getBreakpoints();
    2523            0 :     myRunThread->getBreakpointLock().unlock();
    2524            0 :     return result;
    2525            0 : }
    2526              : 
    2527              : 
    2528              : void
    2529            0 : GUIApplicationWindow::eraseBreakpointDialog() {
    2530            0 :     myBreakpointDialog = nullptr;
    2531            0 : }
    2532              : 
    2533              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1