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