Eclipse SUMO - Simulation of Urban MObility
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
GNEFixNetworkElements.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2001-2025 German Aerospace Center (DLR) and others.
4// This program and the accompanying materials are made available under the
5// terms of the Eclipse Public License 2.0 which is available at
6// https://www.eclipse.org/legal/epl-2.0/
7// This Source Code may also be made available under the following Secondary
8// Licenses when the conditions for such availability set forth in the Eclipse
9// Public License 2.0 are satisfied: GNU General Public License, version 2
10// or later which is available at
11// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13/****************************************************************************/
18// Dialog used to fix network elements during saving
19/****************************************************************************/
20
21#include <netedit/GNENet.h>
23#include <netedit/GNEUndoList.h>
24#include <netedit/GNEViewNet.h>
27
29
30// ===========================================================================
31// FOX callback mapping
32// ===========================================================================
33
39
40// Object implementation
41FXIMPLEMENT(GNEFixNetworkElements, FXDialogBox, GNEFixNetworkElementsMap, ARRAYNUMBER(GNEFixNetworkElementsMap))
42
43// ===========================================================================
44// member method definitions
45// ===========================================================================
46
47// ---------------------------------------------------------------------------
48// GNEFixNetworkElements - methods
49// ---------------------------------------------------------------------------
50
51GNEFixNetworkElements::GNEFixNetworkElements(GNEViewNet* viewNet, const std::vector<GNENetworkElement*>& invalidNetworkElements) :
52 FXDialogBox(viewNet->getApp(), TL("Fix network elements problems"), GUIDesignDialogBoxExplicitStretchable(600, 620)),
53 myViewNet(viewNet) {
54 // set busStop icon for this dialog
56 // create main frame
57 myMainFrame = new FXVerticalFrame(this, GUIDesignAuxiliarFrame);
58 // create frames for options
59 FXHorizontalFrame* optionsFrame = new FXHorizontalFrame(myMainFrame, GUIDesignAuxiliarFrame);
60 myLeftFrame = new FXVerticalFrame(optionsFrame, GUIDesignAuxiliarFrame);
61 myRightFrame = new FXVerticalFrame(optionsFrame, GUIDesignAuxiliarFrame);
62 // create fix edge options
63 myFixEdgeOptions = new FixEdgeOptions(this, viewNet);
64 // create fix crossing options
65 myFixCrossingOptions = new FixCrossingOptions(this, viewNet);
66 // create buttons
67 myButtons = new Buttons(this);
68 // split invalidNetworkElements in four groups
69 std::vector<GNENetworkElement*> invalidEdges, invalidCrossings;
70 // fill groups
71 for (const auto& invalidNetworkElement : invalidNetworkElements) {
72 if (invalidNetworkElement->getTagProperty()->getTag() == SUMO_TAG_EDGE) {
73 invalidEdges.push_back(invalidNetworkElement);
74 } else if (invalidNetworkElement->getTagProperty()->getTag() == SUMO_TAG_CROSSING) {
75 invalidCrossings.push_back(invalidNetworkElement);
76 }
77 }
78 // fill options
79 myFixEdgeOptions->setInvalidElements(invalidEdges);
80 myFixCrossingOptions->setInvalidElements(invalidCrossings);
81}
82
83
86
87
88long
89GNEFixNetworkElements::onCmdSelectOption(FXObject* obj, FXSelector, void*) {
90 // select options
93 return 1;
94}
95
96
97long
98GNEFixNetworkElements::onCmdAccept(FXObject*, FXSelector, void*) {
99 bool abortSaving = false;
100 // fix elements
101 myFixEdgeOptions->fixElements(abortSaving);
102 myFixCrossingOptions->fixElements(abortSaving);
103 // check if abort saving
104 if (abortSaving) {
105 // stop modal with TRUE (abort saving)
106 getApp()->stopModal(this, FALSE);
107 } else {
108 // stop modal with TRUE (continue saving)
109 getApp()->stopModal(this, TRUE);
110 }
111 return 1;
112}
113
114
115long
116GNEFixNetworkElements::onCmdCancel(FXObject*, FXSelector, void*) {
117 // Stop Modal (abort saving)
118 getApp()->stopModal(this, FALSE);
119 return 1;
120}
121
122// ---------------------------------------------------------------------------
123// GNEFixNetworkElements::FixOptions - methods
124// ---------------------------------------------------------------------------
125
126GNEFixNetworkElements::FixOptions::FixOptions(FXVerticalFrame* frameParent, const std::string& title, GNEViewNet* viewNet) :
127 MFXGroupBoxModule(frameParent, title, MFXGroupBoxModule::Options::SAVE),
128 myViewNet(viewNet) {
129 // Create table
130 myTable = new FXTable(this, this, MID_TABLE, GUIDesignTableFixElements);
131 myTable->disable();
132 // create horizontal frame
133 FXHorizontalFrame* horizontalFrame = new FXHorizontalFrame(this, GUIDesignAuxiliarHorizontalFrame);
134 // create vertical frames
135 myLeftFrame = new FXVerticalFrame(horizontalFrame, GUIDesignAuxiliarVerticalFrame);
136 myRightFrame = new FXVerticalFrame(horizontalFrame, GUIDesignAuxiliarVerticalFrame);
137}
138
139
140void
141GNEFixNetworkElements::FixOptions::setInvalidElements(const std::vector<GNENetworkElement*>& invalidElements) {
142 // update invalid elements
143 myInvalidElements = invalidElements;
144 // configure table
145 myTable->setTableSize((int)(myInvalidElements.size()), 3);
146 myTable->setSelBackColor(FXRGBA(255, 255, 255, 255));
147 myTable->setSelTextColor(FXRGBA(0, 0, 0, 255));
148 myTable->setEditable(false);
149 // configure header
150 myTable->setVisibleColumns(4);
151 myTable->setColumnWidth(0, GUIDesignHeight);
152 myTable->setColumnWidth(1, 150);
153 myTable->setColumnWidth(2, 390);
154 myTable->setColumnText(0, "");
155 myTable->setColumnText(1, toString(SUMO_ATTR_ID).c_str());
156 myTable->setColumnText(2, TL("Conflict"));
157 myTable->getRowHeader()->setWidth(0);
158 // Declare pointer to FXTableItem
159 FXTableItem* item = nullptr;
160 // iterate over invalid edges
161 for (int i = 0; i < (int)myInvalidElements.size(); i++) {
162 // Set icon
163 item = new FXTableItem("", myInvalidElements.at(i)->getACIcon());
164 item->setIconPosition(FXTableItem::CENTER_X);
165 myTable->setItem(i, 0, item);
166 // Set ID
167 item = new FXTableItem(myInvalidElements.at(i)->getID().c_str());
168 item->setJustify(FXTableItem::LEFT | FXTableItem::CENTER_Y);
169 myTable->setItem(i, 1, item);
170 // Set conflict
171 item = new FXTableItem(myInvalidElements.at(i)->getNetworkElementProblem().c_str());
172 item->setJustify(FXTableItem::LEFT | FXTableItem::CENTER_Y);
173 myTable->setItem(i, 2, item);
174 }
175 // check if enable or disable options
176 if (invalidElements.size() > 0) {
177 enableOptions();
178 toggleSaveButton(true);
179 } else {
180 disableOptions();
181 toggleSaveButton(false);
182 }
183}
184
185
186bool
188 const FXString file = MFXUtils::getFilename2Write(myTable,
189 TL("Save list of conflicted items"),
190 SUMOXMLDefinitions::TXTFileExtensions.getMultilineString().c_str(),
192 if (file == "") {
193 return false;
194 }
195 try {
196 // open output device
197 OutputDevice& dev = OutputDevice::getDevice(file.text());
198 // get invalid element ID and problem
199 for (const auto& invalidElement : myInvalidElements) {
200 dev << invalidElement->getID() << ":" << invalidElement->getNetworkElementProblem() << "\n";
201 }
202 // close output device
203 dev.close();
204 // open message box error
205 FXMessageBox::information(myTable, MBOX_OK, TL("Saving successfully"), "%s", "List of conflicted items was successfully saved");
206 } catch (IOError& e) {
207 // open message box error
208 FXMessageBox::error(myTable, MBOX_OK, TL("Saving list of conflicted items failed"), "%s", e.what());
209 }
210 return true;
211}
212
213// ---------------------------------------------------------------------------
214// GNEFixNetworkElements::FixEdgeOptions - methods
215// ---------------------------------------------------------------------------
216
218 FixOptions(fixNetworkElementsParent->myLeftFrame, "Edges", viewNet) {
219 // Remove invalid edges
220 removeInvalidEdges = new FXRadioButton(myLeftFrame, TL("Remove invalid edges"),
221 fixNetworkElementsParent, MID_CHOOSEN_OPERATION, GUIDesignRadioButtonFix);
222 // Save invalid edges
223 saveInvalidEdges = new FXRadioButton(myLeftFrame, TL("Save invalid edges"),
224 fixNetworkElementsParent, MID_CHOOSEN_OPERATION, GUIDesignRadioButtonFix);
225 // Select invalid edges
226 selectInvalidEdgesAndCancel = new FXRadioButton(myRightFrame, TL("Select conflicted edges"),
227 fixNetworkElementsParent, MID_CHOOSEN_OPERATION, GUIDesignRadioButtonFix);
228 // leave option "removeInvalidEdges" as default
229 removeInvalidEdges->setCheck(true);
230}
231
232
233void
235 if (option == removeInvalidEdges) {
236 removeInvalidEdges->setCheck(true);
237 saveInvalidEdges->setCheck(false);
238 selectInvalidEdgesAndCancel->setCheck(false);
239 } else if (option == saveInvalidEdges) {
240 removeInvalidEdges->setCheck(false);
241 saveInvalidEdges->setCheck(true);
242 selectInvalidEdgesAndCancel->setCheck(false);
243 } else if (option == selectInvalidEdgesAndCancel) {
244 removeInvalidEdges->setCheck(false);
245 saveInvalidEdges->setCheck(false);
246 selectInvalidEdgesAndCancel->setCheck(true);
247 }
248}
249
250
251void
253 if (myInvalidElements.size() > 0) {
254 if (removeInvalidEdges->getCheck() == TRUE) {
255 // begin undo list
256 myViewNet->getUndoList()->begin(GUIIcon::EDGE, TL("delete invalid edges"));
257 // iterate over invalid edges to delete it
258 for (const auto& invalidEdge : myInvalidElements) {
260 }
261 // end undo list
263 } else if (selectInvalidEdgesAndCancel->getCheck() == TRUE) {
264 // begin undo list
265 myViewNet->getUndoList()->begin(GUIIcon::EDGE, TL("select invalid edges"));
266 // iterate over invalid single lane elements to select all elements
267 for (const auto& invalidEdge : myInvalidElements) {
268 invalidEdge->setAttribute(GNE_ATTR_SELECTED, "true", myViewNet->getUndoList());
269 }
270 // end undo list
272 // abort saving
273 abortSaving = true;
274 }
275 }
276}
277
278
279void
281 removeInvalidEdges->enable();
282 saveInvalidEdges->enable();
283 selectInvalidEdgesAndCancel->enable();
284}
285
286
287void
289 removeInvalidEdges->disable();
290 saveInvalidEdges->disable();
291 selectInvalidEdgesAndCancel->disable();
292}
293
294// ---------------------------------------------------------------------------
295// GNEFixNetworkElements::FixCrossingOptions - methods
296// ---------------------------------------------------------------------------
297
299 FixOptions(fixNetworkElementsParent->myLeftFrame, "Crossings", viewNet) {
300 // Remove invalid crossings
301 removeInvalidCrossings = new FXRadioButton(myLeftFrame, TL("Remove invalid crossings"),
302 fixNetworkElementsParent, MID_CHOOSEN_OPERATION, GUIDesignRadioButtonFix);
303 // Save invalid crossings
304 saveInvalidCrossings = new FXRadioButton(myLeftFrame, TL("Save invalid crossings"),
305 fixNetworkElementsParent, MID_CHOOSEN_OPERATION, GUIDesignRadioButtonFix);
306 // Select invalid crossing
307 selectInvalidCrossingsAndCancel = new FXRadioButton(myRightFrame, TL("Select conflicted crossing"),
308 fixNetworkElementsParent, MID_CHOOSEN_OPERATION, GUIDesignRadioButtonFix);
309 // by default remove invalid crossings
310 removeInvalidCrossings->setCheck(TRUE);
311}
312
313
314void
316 if (option == removeInvalidCrossings) {
317 removeInvalidCrossings->setCheck(true);
318 saveInvalidCrossings->setCheck(false);
319 selectInvalidCrossingsAndCancel->setCheck(false);
320 } else if (option == saveInvalidCrossings) {
321 removeInvalidCrossings->setCheck(false);
322 saveInvalidCrossings->setCheck(true);
323 selectInvalidCrossingsAndCancel->setCheck(false);
324 } else if (option == selectInvalidCrossingsAndCancel) {
325 removeInvalidCrossings->setCheck(false);
326 saveInvalidCrossings->setCheck(false);
327 selectInvalidCrossingsAndCancel->setCheck(true);
328 }
329}
330
331
332void
334 if (myInvalidElements.size() > 0) {
335 if (removeInvalidCrossings->getCheck() == TRUE) {
336 // begin undo list
337 myViewNet->getUndoList()->begin(GUIIcon::CROSSING, TL("delete invalid crossings"));
338 // iterate over invalid crossings to delete it
339 for (const auto& invalidCrossing : myInvalidElements) {
341 }
342 // end undo list
344 } else if (selectInvalidCrossingsAndCancel->getCheck() == TRUE) {
345 // begin undo list
346 myViewNet->getUndoList()->begin(GUIIcon::CROSSING, TL("select invalid crossings"));
347 // iterate over invalid single lane elements to select all elements
348 for (const auto& invalidCrossing : myInvalidElements) {
349 invalidCrossing->setAttribute(GNE_ATTR_SELECTED, "true", myViewNet->getUndoList());
350 }
351 // end undo list
353 // abort saving
354 abortSaving = true;
355 }
356 }
357}
358
359
360void
362 removeInvalidCrossings->enable();
363 saveInvalidCrossings->enable();
364 selectInvalidCrossingsAndCancel->enable();
365}
366
367
368void
370 removeInvalidCrossings->disable();
371 saveInvalidCrossings->disable();
372 selectInvalidCrossingsAndCancel->disable();
373}
374
375// ---------------------------------------------------------------------------
376// GNEFixNetworkElements::Buttons - methods
377// ---------------------------------------------------------------------------
378
380 FXHorizontalFrame(fixNetworkElementsParent->myMainFrame, GUIDesignHorizontalFrame) {
381 new FXHorizontalFrame(this, GUIDesignAuxiliarHorizontalFrame);
384 new FXHorizontalFrame(this, GUIDesignAuxiliarHorizontalFrame);
385 // set focus in accept button
386 myKeepOldButton->setFocus();
387}
388
389/****************************************************************************/
FXDEFMAP(GNEFixNetworkElements) GNEFixNetworkElementsMap[]
@ MID_GNE_BUTTON_CANCEL
cancel button
@ MID_TABLE
The Table.
Definition GUIAppEnum.h:539
@ MID_CHOOSEN_OPERATION
set type of selection
Definition GUIAppEnum.h:597
@ MID_GNE_BUTTON_ACCEPT
accept button
#define GUIDesignRadioButtonFix
design for radio button with fixed height (used in fix elements dialogs)
Definition GUIDesigns.h:235
#define GUIDesignButtonAccept
Accept Button.
Definition GUIDesigns.h:156
#define GUIDesignButtonCancel
Cancel Button.
Definition GUIDesigns.h:162
#define GUIDesignAuxiliarHorizontalFrame
design for auxiliar (Without borders) horizontal frame used to pack another frames
Definition GUIDesigns.h:399
#define GUIDesignAuxiliarVerticalFrame
design for auxiliar (Without borders) horizontal frame used to pack another frames
Definition GUIDesigns.h:408
#define GUIDesignTableFixElements
design for tables used in GNEFixDemandElements dialogs
Definition GUIDesigns.h:637
#define GUIDesignAuxiliarFrame
design for auxiliar (Without borders) frame extended in all directions
Definition GUIDesigns.h:390
#define GUIDesignHorizontalFrame
Horizontal frame extended over frame parent with padding and spacing.
Definition GUIDesigns.h:328
#define GUIDesignDialogBoxExplicitStretchable(width, height)
design for dialog box with specific width and height that can be stretched (But not shrunk)
Definition GUIDesigns.h:617
FXString gCurrentFolder
The folder used as last.
@ SUPERMODEDEMAND
@ SAVE
save icons
#define TL(string)
Definition MsgHandler.h:305
@ SUMO_TAG_CROSSING
crossing between edges for pedestrians
@ SUMO_TAG_EDGE
begin/end of the description of an edge
@ GNE_ATTR_SELECTED
element is selected
@ SUMO_ATTR_ID
int GUIDesignHeight
the default size for GUI elements
Definition StdDefs.cpp:35
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:46
horizontal frame for buttons
FXButton * myCancelButton
cancel button
FXButton * myKeepOldButton
accept button
Buttons(GNEFixNetworkElements *fixNetworkElementsParent)
build Position Options
groupbox for all radio buttons related with fix crossing options
FXRadioButton * saveInvalidCrossings
Option "save invalid crossings".
FixCrossingOptions(GNEFixNetworkElements *fixNetworkElementsParent, GNEViewNet *viewNet)
constructor
void fixElements(bool &abortSaving)
fix elements
FXRadioButton * removeInvalidCrossings
Option "remove invalid elements".
void selectOption(FXObject *option)
select option
FXRadioButton * selectInvalidCrossingsAndCancel
Option "Select invalid crossings and cancel".
groupbox for all radio buttons related with fix edges options
void selectOption(FXObject *option)
select option
FXRadioButton * selectInvalidEdgesAndCancel
Option "Select invalid edges and cancel".
void fixElements(bool &abortSaving)
fix elements
FXRadioButton * saveInvalidEdges
Option "Save invalid edges".
FXRadioButton * removeInvalidEdges
Option "Remove invalid edges".
FixEdgeOptions(GNEFixNetworkElements *fixNetworkElementsParent, GNEViewNet *viewNet)
constructor
FixOptions(FXVerticalFrame *frameParent, const std::string &title, GNEViewNet *viewNet)
constructor
FXTable * myTable
Table with the network elements.
FXVerticalFrame * myLeftFrame
vertical left frame
void setInvalidElements(const std::vector< GNENetworkElement * > &invalidElements)
set invalid network elements
FXVerticalFrame * myRightFrame
vertical right frame
Dialog fix network elements.
FXVerticalFrame * myMainFrame
main frame
long onCmdCancel(FXObject *, FXSelector, void *)
event after press cancel button
FixEdgeOptions * myFixEdgeOptions
fix edge options
FixCrossingOptions * myFixCrossingOptions
fix crossing options
GNEViewNet * myViewNet
view net
long onCmdSelectOption(FXObject *obj, FXSelector, void *)
FXVerticalFrame * myLeftFrame
vertical left frame
long onCmdAccept(FXObject *, FXSelector, void *)
event after press accept button
GNECrossing * retrieveCrossing(const GUIGlObject *glObject, bool hardFail=true) const
get Crossing by AC
GNEEdge * retrieveEdge(const std::string &id, bool hardFail=true) const
get edge by id
void deleteEdge(GNEEdge *edge, GNEUndoList *undoList, bool recomputeConnections)
removes edge
Definition GNENet.cpp:460
void deleteCrossing(GNECrossing *crossing, GNEUndoList *undoList)
remove crossing
Definition GNENet.cpp:696
GNENetHelper::AttributeCarriers * getAttributeCarriers() const
get all attribute carriers used in this net
Definition GNENet.cpp:146
void end()
End undo command sub-group. If the sub-group is still empty, it will be deleted; otherwise,...
void begin(GUIIcon icon, const std::string &description)
Begin undo command sub-group with current supermode. This begins a new group of commands that are tre...
GNENet * getNet() const
get the net object
GNEUndoList * getUndoList() const
get the undoList object
static FXButton * buildFXButton(FXComposite *p, const std::string &text, const std::string &tip, const std::string &help, FXIcon *ic, FXObject *tgt, FXSelector sel, FXuint opts=BUTTON_NORMAL, FXint x=0, FXint y=0, FXint w=0, FXint h=0, FXint pl=DEFAULT_PAD, FXint pr=DEFAULT_PAD, FXint pt=DEFAULT_PAD, FXint pb=DEFAULT_PAD)
build button
static FXIcon * getIcon(const GUIIcon which)
returns a icon previously defined in the enum GUIIcon
MFXGroupBoxModule (based on FXGroupBox)
Options
GroupBoxModule options.
static FXString getFilename2Write(FXWindow *parent, const FXString &header, const FXString &extensions, FXIcon *icon, FXString &currentFolder)
Returns the file name to write.
Definition MFXUtils.cpp:116
Static storage of an output device and its base (abstract) implementation.
void close()
Closes the device and removes it from the dictionary.
static OutputDevice & getDevice(const std::string &name, bool usePrefix=true)
Returns the described OutputDevice.
static StringBijection< TXTFileExtension > TXTFileExtensions
TXT file Extensions.
Definition json.hpp:4471