Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
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
22#include <netedit/GNENet.h>
24#include <netedit/GNEUndoList.h>
26
28
29// ===========================================================================
30// FOX callback mapping
31// ===========================================================================
32
38
39// Object implementation
40FXIMPLEMENT(GNEFixNetworkElements, GNEFixElementsDialog, GNEFixNetworkElementsMap, ARRAYNUMBER(GNEFixNetworkElementsMap))
41
42// ===========================================================================
43// member method definitions
44// ===========================================================================
45
46// ---------------------------------------------------------------------------
47// GNEFixNetworkElements - methods
48// ---------------------------------------------------------------------------
49
51 GNEFixElementsDialog(viewNet, TL("Fix network elements problems"), GUIIcon::SUPERMODEDEMAND, 600, 620) {
52 // create frames for options
53 FXHorizontalFrame* optionsFrame = new FXHorizontalFrame(myMainFrame, GUIDesignAuxiliarFrame);
54 myLeftFrame = new FXVerticalFrame(optionsFrame, GUIDesignAuxiliarFrame);
55 myRightFrame = new FXVerticalFrame(optionsFrame, GUIDesignAuxiliarFrame);
56 // create fix edge options
57 myFixEdgeOptions = new FixEdgeOptions(this, viewNet);
58 // create fix crossing options
59 myFixCrossingOptions = new FixCrossingOptions(this, viewNet);
60 // create buttons
61 myButtons = new Buttons(this);
62}
63
64
66
67
68FXuint
69GNEFixNetworkElements::openDialog(const std::vector<GNENetworkElement*>& invalidNetworkElements) {
70 // split invalidNetworkElements in four groups
71 std::vector<GNENetworkElement*> invalidEdges, invalidCrossings;
72 // fill groups
73 for (const auto& invalidNetworkElement : invalidNetworkElements) {
74 if (invalidNetworkElement->getTagProperty()->getTag() == SUMO_TAG_EDGE) {
75 invalidEdges.push_back(invalidNetworkElement);
76 } else if (invalidNetworkElement->getTagProperty()->getTag() == SUMO_TAG_CROSSING) {
77 invalidCrossings.push_back(invalidNetworkElement);
78 }
79 }
80 // fill options
83 // set focus in accept button
84 myButtons->myAcceptButton->setFocus();
85 // open modal dialog
86 return openFixDialog();
87}
88
89
90void
92 // chooose solution
93 if (dialogTest->fixSolution == "removeInvalidCrossings") {
94 myFixCrossingOptions->removeInvalidCrossings->setCheck(TRUE, TRUE);
95 } else if (dialogTest->fixSolution == "saveInvalidCrossings") {
96 myFixCrossingOptions->saveInvalidCrossings->setCheck(TRUE, TRUE);
97 } else if (dialogTest->fixSolution == "selectInvalidCrossings") {
98 myFixCrossingOptions->selectInvalidCrossings->setCheck(TRUE, TRUE);
99 }
100 // accept changes
101 onCmdAccept(nullptr, 0, nullptr);
102}
103
104
105long
106GNEFixNetworkElements::onCmdSelectOption(FXObject* obj, FXSelector, void*) {
107 // select options
110 return 1;
111}
112
113
114long
115GNEFixNetworkElements::onCmdAccept(FXObject*, FXSelector, void*) {
116 bool abortSaving = false;
117 // fix elements
118 myFixEdgeOptions->fixElements(abortSaving);
119 myFixCrossingOptions->fixElements(abortSaving);
120 // stop dialog
121 return closeFixDialog(abortSaving);
122}
123
124
125long
126GNEFixNetworkElements::onCmdCancel(FXObject*, FXSelector, void*) {
127 // stop dialog
128 return closeFixDialog(false);
129}
130
131// ---------------------------------------------------------------------------
132// GNEFixNetworkElements::FixOptions - methods
133// ---------------------------------------------------------------------------
134
135GNEFixNetworkElements::FixOptions::FixOptions(FXVerticalFrame* frameParent, const std::string& title, GNEViewNet* viewNet) :
136 MFXGroupBoxModule(frameParent, title, MFXGroupBoxModule::Options::SAVE),
137 myViewNet(viewNet) {
138 // Create table
139 myTable = new FXTable(this, this, MID_TABLE, GUIDesignTableFixElements);
140 myTable->disable();
141 // create horizontal frame
142 FXHorizontalFrame* horizontalFrame = new FXHorizontalFrame(this, GUIDesignAuxiliarHorizontalFrame);
143 // create vertical frames
144 myLeftFrame = new FXVerticalFrame(horizontalFrame, GUIDesignAuxiliarVerticalFrame);
145 myRightFrame = new FXVerticalFrame(horizontalFrame, GUIDesignAuxiliarVerticalFrame);
146}
147
148
149void
150GNEFixNetworkElements::FixOptions::setInvalidElements(const std::vector<GNENetworkElement*>& invalidElements) {
151 // update invalid elements
152 myInvalidElements = invalidElements;
153 // configure table
154 myTable->setTableSize((int)(myInvalidElements.size()), 3);
155 myTable->setSelBackColor(FXRGBA(255, 255, 255, 255));
156 myTable->setSelTextColor(FXRGBA(0, 0, 0, 255));
157 myTable->setEditable(false);
158 // configure header
159 myTable->setVisibleColumns(4);
160 myTable->setColumnWidth(0, GUIDesignHeight);
161 myTable->setColumnWidth(1, 150);
162 myTable->setColumnWidth(2, 390);
163 myTable->setColumnText(0, "");
164 myTable->setColumnText(1, toString(SUMO_ATTR_ID).c_str());
165 myTable->setColumnText(2, TL("Conflict"));
166 myTable->getRowHeader()->setWidth(0);
167 // Declare pointer to FXTableItem
168 FXTableItem* item = nullptr;
169 // iterate over invalid edges
170 for (int i = 0; i < (int)myInvalidElements.size(); i++) {
171 // Set icon
172 item = new FXTableItem("", myInvalidElements.at(i)->getACIcon());
173 item->setIconPosition(FXTableItem::CENTER_X);
174 myTable->setItem(i, 0, item);
175 // Set ID
176 item = new FXTableItem(myInvalidElements.at(i)->getID().c_str());
177 item->setJustify(FXTableItem::LEFT | FXTableItem::CENTER_Y);
178 myTable->setItem(i, 1, item);
179 // Set conflict
180 item = new FXTableItem(myInvalidElements.at(i)->getNetworkElementProblem().c_str());
181 item->setJustify(FXTableItem::LEFT | FXTableItem::CENTER_Y);
182 myTable->setItem(i, 2, item);
183 }
184 // check if enable or disable options
185 if (invalidElements.size() > 0) {
186 enableOptions();
187 toggleSaveButton(true);
188 } else {
189 disableOptions();
190 toggleSaveButton(false);
191 }
192}
193
194
195bool
197 const FXString file = MFXUtils::getFilename2Write(myTable,
198 TL("Save list of conflicted items"),
199 SUMOXMLDefinitions::TXTFileExtensions.getMultilineString().c_str(),
201 if (file == "") {
202 return false;
203 }
204 try {
205 // open output device
206 OutputDevice& dev = OutputDevice::getDevice(file.text());
207 // get invalid element ID and problem
208 for (const auto& invalidElement : myInvalidElements) {
209 dev << invalidElement->getID() << ":" << invalidElement->getNetworkElementProblem() << "\n";
210 }
211 // close output device
212 dev.close();
213 // open message box error
214 FXMessageBox::information(myTable, MBOX_OK, TL("Saving successfully"), "%s", "List of conflicted items was successfully saved");
215 } catch (IOError& e) {
216 // open message box error
217 FXMessageBox::error(myTable, MBOX_OK, TL("Saving list of conflicted items failed"), "%s", e.what());
218 }
219 return true;
220}
221
222// ---------------------------------------------------------------------------
223// GNEFixNetworkElements::FixEdgeOptions - methods
224// ---------------------------------------------------------------------------
225
227 FixOptions(fixNetworkElementsParent->myLeftFrame, "Edges", viewNet) {
228 // Remove invalid edges
229 removeInvalidEdges = new FXRadioButton(myLeftFrame, TL("Remove invalid edges"),
230 fixNetworkElementsParent, MID_CHOOSEN_OPERATION, GUIDesignRadioButtonFix);
231 // Save invalid edges
232 saveInvalidEdges = new FXRadioButton(myLeftFrame, TL("Save invalid edges"),
233 fixNetworkElementsParent, MID_CHOOSEN_OPERATION, GUIDesignRadioButtonFix);
234 // Select invalid edges
235 selectInvalidEdgesAndCancel = new FXRadioButton(myRightFrame, TL("Select conflicted edges"),
236 fixNetworkElementsParent, MID_CHOOSEN_OPERATION, GUIDesignRadioButtonFix);
237 // leave option "removeInvalidEdges" as default
238 removeInvalidEdges->setCheck(true);
239}
240
241
242void
244 if (option == removeInvalidEdges) {
245 removeInvalidEdges->setCheck(true);
246 saveInvalidEdges->setCheck(false);
247 selectInvalidEdgesAndCancel->setCheck(false);
248 } else if (option == saveInvalidEdges) {
249 removeInvalidEdges->setCheck(false);
250 saveInvalidEdges->setCheck(true);
251 selectInvalidEdgesAndCancel->setCheck(false);
252 } else if (option == selectInvalidEdgesAndCancel) {
253 removeInvalidEdges->setCheck(false);
254 saveInvalidEdges->setCheck(false);
255 selectInvalidEdgesAndCancel->setCheck(true);
256 }
257}
258
259
260void
262 if (myInvalidElements.size() > 0) {
263 if (removeInvalidEdges->getCheck() == TRUE) {
264 // begin undo list
265 myViewNet->getUndoList()->begin(GUIIcon::EDGE, TL("delete invalid edges"));
266 // iterate over invalid edges to delete it
267 for (const auto& invalidEdge : myInvalidElements) {
269 }
270 // end undo list
272 } else if (selectInvalidEdgesAndCancel->getCheck() == TRUE) {
273 // begin undo list
274 myViewNet->getUndoList()->begin(GUIIcon::EDGE, TL("select invalid edges"));
275 // iterate over invalid single lane elements to select all elements
276 for (const auto& invalidEdge : myInvalidElements) {
277 invalidEdge->setAttribute(GNE_ATTR_SELECTED, "true", myViewNet->getUndoList());
278 }
279 // end undo list
281 // abort saving
282 abortSaving = true;
283 }
284 }
285}
286
287
288void
290 removeInvalidEdges->enable();
291 saveInvalidEdges->enable();
292 selectInvalidEdgesAndCancel->enable();
293}
294
295
296void
298 removeInvalidEdges->disable();
299 saveInvalidEdges->disable();
300 selectInvalidEdgesAndCancel->disable();
301}
302
303// ---------------------------------------------------------------------------
304// GNEFixNetworkElements::FixCrossingOptions - methods
305// ---------------------------------------------------------------------------
306
308 FixOptions(fixNetworkElementsParent->myLeftFrame, "Crossings", viewNet) {
309 // Remove invalid crossings
310 removeInvalidCrossings = new FXRadioButton(myLeftFrame, TL("Remove invalid crossings"),
311 fixNetworkElementsParent, MID_CHOOSEN_OPERATION, GUIDesignRadioButtonFix);
312 // Save invalid crossings
313 saveInvalidCrossings = new FXRadioButton(myLeftFrame, TL("Save invalid crossings"),
314 fixNetworkElementsParent, MID_CHOOSEN_OPERATION, GUIDesignRadioButtonFix);
315 // Select invalid crossing
316 selectInvalidCrossings = new FXRadioButton(myRightFrame, TL("Select conflicted crossing"),
317 fixNetworkElementsParent, MID_CHOOSEN_OPERATION, GUIDesignRadioButtonFix);
318 // by default remove invalid crossings
319 removeInvalidCrossings->setCheck(TRUE);
320}
321
322
323void
325 if (option == removeInvalidCrossings) {
326 removeInvalidCrossings->setCheck(true);
327 saveInvalidCrossings->setCheck(false);
328 selectInvalidCrossings->setCheck(false);
329 } else if (option == saveInvalidCrossings) {
330 removeInvalidCrossings->setCheck(false);
331 saveInvalidCrossings->setCheck(true);
332 selectInvalidCrossings->setCheck(false);
333 } else if (option == selectInvalidCrossings) {
334 removeInvalidCrossings->setCheck(false);
335 saveInvalidCrossings->setCheck(false);
336 selectInvalidCrossings->setCheck(true);
337 }
338}
339
340
341void
343 if (myInvalidElements.size() > 0) {
344 if (removeInvalidCrossings->getCheck() == TRUE) {
345 // begin undo list
346 myViewNet->getUndoList()->begin(GUIIcon::CROSSING, TL("delete invalid crossings"));
347 // iterate over invalid crossings to delete it
348 for (const auto& invalidCrossing : myInvalidElements) {
350 }
351 // end undo list
353 } else if (selectInvalidCrossings->getCheck() == TRUE) {
354 // begin undo list
355 myViewNet->getUndoList()->begin(GUIIcon::CROSSING, TL("select invalid crossings"));
356 // iterate over invalid single lane elements to select all elements
357 for (const auto& invalidCrossing : myInvalidElements) {
358 invalidCrossing->setAttribute(GNE_ATTR_SELECTED, "true", myViewNet->getUndoList());
359 }
360 // end undo list
362 // abort saving
363 abortSaving = true;
364 }
365 }
366}
367
368
369void
371 removeInvalidCrossings->enable();
372 saveInvalidCrossings->enable();
373 selectInvalidCrossings->enable();
374}
375
376
377void
379 removeInvalidCrossings->disable();
380 saveInvalidCrossings->disable();
381 selectInvalidCrossings->disable();
382}
383
384/****************************************************************************/
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 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
FXString gCurrentFolder
The folder used as last.
GUIIcon
An enumeration of icons used by the gui applications.
Definition GUIIcons.h:33
@ 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:36
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:46
FXButton * myAcceptButton
accept button
long openFixDialog()
open dialog
GNEViewNet * myViewNet
view net
long closeFixDialog(const bool success)
stop fix elements dialog accepting changes
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 * selectInvalidCrossings
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
long onCmdCancel(FXObject *, FXSelector, void *)
event after press cancel button
FixEdgeOptions * myFixEdgeOptions
fix edge options
FixCrossingOptions * myFixCrossingOptions
fix crossing options
long onCmdSelectOption(FXObject *obj, FXSelector, void *)
event when user select a option
FXVerticalFrame * myLeftFrame
vertical left frame
FXuint openDialog(const std::vector< GNENetworkElement * > &invalidNetworkElements)
open fix network elements dialog
long onCmdAccept(FXObject *, FXSelector, void *)
event after press accept button
void runInternalTest(const InternalTestStep::DialogTest *modalArguments)
run internal test
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:461
void deleteCrossing(GNECrossing *crossing, GNEUndoList *undoList)
remove crossing
Definition GNENet.cpp:697
GNENetHelper::AttributeCarriers * getAttributeCarriers() const
get all attribute carriers used in this net
Definition GNENet.cpp:147
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 FXIcon * getIcon(const GUIIcon which)
returns a icon previously defined in the enum GUIIcon
dialog arguments (used for certain functions that opens modal dialogs)
const std::string fixSolution
solution for fix dialogs
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.