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