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