LCOV - code coverage report
Current view: top level - src/gui - GUIApplicationWindow.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 725 1328 54.6 %
Date: 2024-05-18 15:37:58 Functions: 42 105 40.0 %

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

Generated by: LCOV version 1.14