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 : /****************************************************************************/
|