Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/gui/dialogs/GUIDialog_Breakpoints.cpp
193728 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2001-2026 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 GUIDialog_Breakpoints.cpp
15
/// @author Daniel Krajzewicz
16
/// @author Jakob Erdmann
17
/// @author Michael Behrisch
18
/// @date Thu, 17 Jun 2004
19
///
20
// Editor for simulation breakpoints
21
/****************************************************************************/
22
#include <config.h>
23
24
#include <string>
25
#include <vector>
26
#include <iostream>
27
#include <fstream>
28
#include <set>
29
#include <fxkeys.h>
30
#include <gui/GUIApplicationWindow.h>
31
#include <utils/gui/windows/GUIAppEnum.h>
32
#include <gui/GUIGlobals.h>
33
#include <utils/gui/globjects/GUIGlObject.h>
34
#include <utils/foxtools/MFXUtils.h>
35
#include <utils/common/ToString.h>
36
#include <utils/common/StringUtils.h>
37
#include <utils/gui/windows/GUISUMOAbstractView.h>
38
#include <utils/gui/settings/GUISettingsHandler.h>
39
#include <utils/common/FileHelpers.h>
40
#include <utils/common/MsgHandler.h>
41
#include <utils/options/OptionsCont.h>
42
#include <utils/gui/div/GUIIOGlobals.h>
43
#include <utils/gui/div/GUIDesigns.h>
44
#include <utils/gui/images/GUIIconSubSys.h>
45
#include <utils/iodevices/OutputDevice.h>
46
#include "GUIDialog_Breakpoints.h"
47
48
49
// ===========================================================================
50
// FOX callback mapping
51
// ===========================================================================
52
53
FXDEFMAP(GUIDialog_Breakpoints) GUIDialog_BreakpointsMap[] = {
54
FXMAPFUNC(SEL_COMMAND, MID_CHOOSEN_LOAD, GUIDialog_Breakpoints::onCmdLoad),
55
FXMAPFUNC(SEL_COMMAND, MID_CHOOSEN_SAVE, GUIDialog_Breakpoints::onCmdSave),
56
FXMAPFUNC(SEL_COMMAND, MID_CHOOSEN_CLEAR, GUIDialog_Breakpoints::onCmdClear),
57
FXMAPFUNC(SEL_COMMAND, MID_CANCEL, GUIDialog_Breakpoints::onCmdClose),
58
FXMAPFUNC(SEL_COMMAND, MID_TIMELINK_BREAKPOINT, GUIDialog_Breakpoints::onCmdUpdateBreakpoints),
59
FXMAPFUNC(SEL_REPLACED, MID_TABLE, GUIDialog_Breakpoints::onCmdEditTable),
60
FXMAPFUNC(SEL_KEYPRESS, 0, GUIDialog_Breakpoints::onKeyPress),
61
};
62
63
64
FXIMPLEMENT(GUIDialog_Breakpoints, FXMainWindow, GUIDialog_BreakpointsMap, ARRAYNUMBER(GUIDialog_BreakpointsMap))
65
66
67
// ===========================================================================
68
// method definitions
69
// ===========================================================================
70
GUIDialog_Breakpoints::GUIDialog_Breakpoints(GUIApplicationWindow* parent, std::vector<SUMOTime>& breakpoints, FXMutex& breakpointLock, const SUMOTime simBegin) :
71
FXMainWindow(parent->getApp(), TL("Breakpoints Editor"), GUIIconSubSys::getIcon(GUIIcon::APP_BREAKPOINTS), nullptr, GUIDesignChooserDialog),
72
myParent(parent),
73
myBreakpoints(&breakpoints),
74
myBreakpointLock(&breakpointLock),
75
mySimBegin(simBegin) {
76
// build main Frame
77
FXHorizontalFrame* hbox = new FXHorizontalFrame(this, GUIDesignAuxiliarFrame);
78
// build the table
79
FXVerticalFrame* layoutLeft = new FXVerticalFrame(hbox, GUIDesignChooserLayoutLeft);
80
myTable = new FXTable(layoutLeft, this, MID_TABLE, GUIDesignBreakpointTable);
81
myTable->setVisibleRows(20);
82
myTable->setVisibleColumns(1);
83
myTable->setTableSize(20, 1);
84
myTable->setBackColor(GUIDesignBackgroundColorWhite);
85
myTable->getRowHeader()->setWidth(0);
86
myBreakpointLock->lock();
87
rebuildList();
88
myBreakpointLock->unlock();
89
// build the layout
90
FXVerticalFrame* layoutRight = new FXVerticalFrame(hbox, GUIDesignChooserLayoutRight);
91
// create buttons ('&' in the label creates a hot key)
92
// "Load"
93
GUIDesigns::buildFXButton(layoutRight, TL("&Load"), "", "", GUIIconSubSys::getIcon(GUIIcon::OPEN), this, MID_CHOOSEN_LOAD, GUIDesignChooserButtons);
94
// "Save"
95
GUIDesigns::buildFXButton(layoutRight, TL("&Save"), "", "", GUIIconSubSys::getIcon(GUIIcon::SAVE), this, MID_CHOOSEN_SAVE, GUIDesignChooserButtons);
96
new FXHorizontalSeparator(layoutRight, GUIDesignHorizontalSeparator);
97
// "Clear List"
98
GUIDesigns::buildFXButton(layoutRight, TL("Clea&r"), "", "", GUIIconSubSys::getIcon(GUIIcon::CLEANJUNCTIONS), this, MID_CHOOSEN_CLEAR, GUIDesignChooserButtons);
99
new FXHorizontalSeparator(layoutRight, GUIDesignHorizontalSeparator);
100
// "Close"
101
GUIDesigns::buildFXButton(layoutRight, TL("&Close"), "", "", GUIIconSubSys::getIcon(GUIIcon::NO), this, MID_CANCEL, GUIDesignChooserButtons);
102
// add this dialog as child of GUIMainWindow parent
103
myParent->addChild(this);
104
myPersistentPos = std::unique_ptr<GUIPersistentWindowPos>(new GUIPersistentWindowPos(this, "DIALOG_BREAKPOINTS", true, 20, 40, 300, 350));
105
myPersistentPos->loadWindowPos();
106
create();
107
show();
108
}
109
110
111
GUIDialog_Breakpoints::~GUIDialog_Breakpoints() {
112
// remove this dialog as child of GUIMainWindow parent
113
myParent->removeChild(this);
114
myParent->eraseBreakpointDialog();
115
}
116
117
118
void
119
GUIDialog_Breakpoints::show() {
120
FXMainWindow::show();
121
myTable->startInput((int)myBreakpoints->size(), 0);
122
}
123
124
125
void
126
GUIDialog_Breakpoints::rebuildList() {
127
myTable->clearItems();
128
sort(myBreakpoints->begin(), myBreakpoints->end());
129
// set table attributes
130
myTable->setTableSize((FXint)myBreakpoints->size() + 1, 1);
131
myTable->setColumnText(0, TL("Time"));
132
FXHeader* header = myTable->getColumnHeader();
133
header->setHeight(GUIDesignHeight);
134
header->setItemJustify(0, JUSTIFY_CENTER_X);
135
// insert into table
136
for (int row = 0; row < (int)myBreakpoints->size(); row++) {
137
myTable->setItemText(row, 0, time2string((*myBreakpoints)[row]).c_str());
138
}
139
// insert dummy last field
140
myTable->setItemText((int)myBreakpoints->size(), 0, " ");
141
}
142
143
144
long
145
GUIDialog_Breakpoints::onKeyPress(FXObject* o, FXSelector sel, void* ptr) {
146
const FXEvent* e = (FXEvent*) ptr;
147
if (e->code == KEY_Escape) {
148
onCmdClose(nullptr, 0, nullptr);
149
return 1;
150
}
151
return FXMainWindow::onKeyPress(o, sel, ptr);
152
}
153
154
155
long
156
GUIDialog_Breakpoints::onCmdLoad(FXObject*, FXSelector, void*) {
157
FXFileDialog opendialog(this, TL("Load Breakpoints"));
158
opendialog.setIcon(GUIIconSubSys::getIcon(GUIIcon::EMPTY));
159
opendialog.setSelectMode(SELECTFILE_ANY);
160
opendialog.setPatternList(SUMOXMLDefinitions::TXTFileExtensions.getMultilineString().c_str());
161
if (gCurrentFolder.length() != 0) {
162
opendialog.setDirectory(gCurrentFolder);
163
}
164
if (opendialog.execute()) {
165
gCurrentFolder = opendialog.getDirectory();
166
std::string file = opendialog.getFilename().text();
167
std::vector<SUMOTime> newBreakpoints = GUISettingsHandler::loadBreakpoints(file);
168
FXMutexLock lock(*myBreakpointLock);
169
myBreakpoints->assign(newBreakpoints.begin(), newBreakpoints.end());
170
rebuildList();
171
}
172
return 1;
173
}
174
175
176
long
177
GUIDialog_Breakpoints::onCmdSave(FXObject*, FXSelector, void*) {
178
FXString file = MFXUtils::getFilename2Write(this, TL("Save Breakpoints"),
179
SUMOXMLDefinitions::TXTFileExtensions.getMultilineString().c_str(),
180
GUIIconSubSys::getIcon(GUIIcon::EMPTY), gCurrentFolder);
181
if (file == "") {
182
return 1;
183
}
184
std::string content = encode2TXT();
185
try {
186
OutputDevice& dev = OutputDevice::getDevice(file.text());
187
dev << content;
188
dev.close();
189
} catch (IOError& e) {
190
FXMessageBox::error(this, MBOX_OK, TL("Storing failed!"), "%s", e.what());
191
}
192
return 1;
193
}
194
195
196
std::string
197
GUIDialog_Breakpoints::encode2TXT() {
198
FXMutexLock lock(*myBreakpointLock);
199
std::ostringstream strm;
200
std::sort(myBreakpoints->begin(), myBreakpoints->end());
201
for (std::vector<SUMOTime>::iterator j = myBreakpoints->begin(); j != myBreakpoints->end(); ++j) {
202
strm << time2string(*j) << std::endl;
203
}
204
return strm.str();
205
}
206
207
208
long
209
GUIDialog_Breakpoints::onCmdClear(FXObject*, FXSelector, void*) {
210
FXMutexLock lock(*myBreakpointLock);
211
myBreakpoints->clear();
212
rebuildList();
213
return 1;
214
}
215
216
217
long
218
GUIDialog_Breakpoints::onCmdUpdateBreakpoints(FXObject*, FXSelector, void*) {
219
FXMutexLock lock(*myBreakpointLock);
220
rebuildList();
221
return 1;
222
}
223
224
225
long
226
GUIDialog_Breakpoints::onCmdClose(FXObject*, FXSelector, void*) {
227
close(true);
228
return 1;
229
}
230
231
232
long
233
GUIDialog_Breakpoints::onCmdEditTable(FXObject*, FXSelector, void* ptr) {
234
FXMutexLock lock(*myBreakpointLock);
235
const FXTablePos* const i = (FXTablePos*) ptr;
236
const std::string value = StringUtils::prune(myTable->getItemText(i->row, i->col).text());
237
// check whether the inserted value is empty
238
const bool empty = value.find_first_not_of(" ") == std::string::npos;
239
try {
240
SUMOTime t = -1;
241
if (!empty) {
242
t = string2time(value);
243
// round down to nearest reachable time step
244
t -= (t - mySimBegin) % DELTA_T;
245
}
246
if (i->row == (int)myBreakpoints->size()) {
247
if (!empty) {
248
myBreakpoints->push_back(t);
249
}
250
} else {
251
if (empty) {
252
myBreakpoints->erase(myBreakpoints->begin() + i->row);
253
} else {
254
(*myBreakpoints)[i->row] = t;
255
}
256
}
257
} catch (NumberFormatException&) {
258
std::string msg = "The value must be a number, is:" + value;
259
FXMessageBox::error(this, MBOX_OK, TL("Time format error"), "%s", msg.c_str());
260
} catch (ProcessError&) {
261
std::string msg = "The value must be a number or a string of the form hh:mm:ss, is:" + value;
262
FXMessageBox::error(this, MBOX_OK, TL("Time format error"), "%s", msg.c_str());
263
}
264
rebuildList();
265
return 1;
266
}
267
268
269
void
270
GUIDialog_Breakpoints::layout() {
271
FXMainWindow::layout();
272
myTable->setColumnWidth(0, myTable->getWidth() - 1);
273
}
274
275
276
/****************************************************************************/
277
278