Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
GNEFixAdditionalElementsDialog.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 additional elements
19/****************************************************************************/
20
22#include <netedit/GNENet.h>
24#include <netedit/GNEUndoList.h>
25
27
28// ===========================================================================
29// FOX callback mapping
30// ===========================================================================
31
35
39
40// Object abstract implementation
41FXIMPLEMENT(GNEFixAdditionalElementsDialog::PositionOptions, MFXGroupBoxModule, PositionOptionsMap, ARRAYNUMBER(PositionOptionsMap))
42FXIMPLEMENT(GNEFixAdditionalElementsDialog::ConsecutiveLaneOptions, MFXGroupBoxModule, ConsecutiveLaneOptionsMap, ARRAYNUMBER(ConsecutiveLaneOptionsMap))
43
44// ===========================================================================
45// member method definitions
46// ===========================================================================
47
48// ---------------------------------------------------------------------------
49// GNEFixAdditionalElementsDialog::PositionOptions - methods
50// ---------------------------------------------------------------------------
51
53 GNEFixElementsDialog<GNEAdditional*>::FixOptions(fixAdditionalPositions, fixAdditionalPositions->myLeftFrame,
54 TL("Select a solution for StoppingPlaces and E2 detectors")) {
55 // activate friendly position
56 myActivateFriendlyPosition = GUIDesigns::buildFXRadioButton(myLeftFrameOptions,
57 TL("Activate friendlyPos and save"), "",
58 TL("Friendly pos parameter will be activated in all stopping places and E2 detectors"),
60 // save invalid positions
61 mySaveInvalids = GUIDesigns::buildFXRadioButton(myLeftFrameOptions,
62 TL("Save invalid positions"), "",
63 TL("Save stopping places and E2 detectors with invalid positions"),
65 // fix positions
66 myFixPositions = GUIDesigns::buildFXRadioButton(myRightFrameOptions,
67 TL("Fix positions and save"), "",
68 TL("Position of stopping places and E2 detectors will be fixed"),
70 // select invalids
71 mySelectInvalids = GUIDesigns::buildFXRadioButton(myRightFrameOptions,
72 TL("Select invalid additionals"), "",
73 TL("Cancel saving of additionals and select invalid stopping places and E2 detectors"),
75 // register options
76 registerOption(myActivateFriendlyPosition);
77 registerOption(mySaveInvalids);
78 registerOption(myFixPositions);
79 registerOption(mySelectInvalids);
80 // set option "activateFriendlyPosition" as default
81 myActivateFriendlyPosition->setCheck(true);
82}
83
84
85void
87 // choose solution
88 if (solution == "savePositionInvalids") {
89 mySaveInvalids->setCheck(TRUE, TRUE);
90 } else if (solution == "fixPositions") {
91 myFixPositions->setCheck(TRUE, TRUE);
92 } else if (solution == "selectPositionInvalids") {
93 mySelectInvalids->setCheck(TRUE, TRUE);
94 } else if (solution == "activatePositionFriendlyPos") {
95 myActivateFriendlyPosition->setCheck(TRUE, TRUE);
96 }
97}
98
99
100bool
102 if (myConflictedElements.size() > 0) {
103 auto undoList = myFixElementDialogParent->getApplicationWindow()->getUndoList();
104 // continue depending of solution
105 if (myActivateFriendlyPosition->getCheck() == TRUE) {
106 undoList->begin(myConflictedElements.front().getElement(),
107 TLF("change % of invalid additionals", toString(SUMO_ATTR_FRIENDLY_POS)));
108 // iterate over invalid single lane elements to enable friendly position
109 for (const auto& conflictedElement : myConflictedElements) {
110 conflictedElement.getElement()->setAttribute(SUMO_ATTR_FRIENDLY_POS, "true", undoList);
111 }
112 undoList->end();
113 } else if (myFixPositions->getCheck() == TRUE) {
114 undoList->begin(myConflictedElements.front().getElement(),
115 TL("fix positions of invalid additionals"));
116 // iterate over invalid single lane elements to fix positions
117 for (const auto& conflictedElement : myConflictedElements) {
118 conflictedElement.getElement()->fixAdditionalProblem();
119 }
120 undoList->end();
121 } else if (mySelectInvalids->getCheck() == TRUE) {
122 undoList->begin(myConflictedElements.front().getElement(),
123 TL("select invalid additionals"));
124 // iterate over invalid single lane elements to select all elements
125 for (const auto& conflictedElement : myConflictedElements) {
126 conflictedElement.getElement()->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
127 }
128 undoList->end();
129 // abort saving
130 return false;
131 }
132 }
133 return true;
134}
135
136
137long
139 if (obj == myActivateFriendlyPosition) {
140 myActivateFriendlyPosition->setCheck(true);
141 myFixPositions->setCheck(false);
142 mySaveInvalids->setCheck(false);
143 mySelectInvalids->setCheck(false);
144 } else if (obj == myFixPositions) {
145 myActivateFriendlyPosition->setCheck(false);
146 myFixPositions->setCheck(true);
147 mySaveInvalids->setCheck(false);
148 mySelectInvalids->setCheck(false);
149 } else if (obj == mySaveInvalids) {
150 myActivateFriendlyPosition->setCheck(false);
151 myFixPositions->setCheck(false);
152 mySaveInvalids->setCheck(true);
153 mySelectInvalids->setCheck(false);
154 } else if (obj == mySelectInvalids) {
155 myActivateFriendlyPosition->setCheck(false);
156 myFixPositions->setCheck(false);
157 mySaveInvalids->setCheck(false);
158 mySelectInvalids->setCheck(true);
159 }
160 return 1;
161}
162
163// ---------------------------------------------------------------------------
164// GNEFixAdditionalElementsDialog::ConsecutiveLaneOptions - methods
165// ---------------------------------------------------------------------------
166
168 GNEFixElementsDialog<GNEAdditional*>::FixOptions(fixAdditionalPositions, fixAdditionalPositions->myLeftFrame,
169 TL("Select a solution for Multilane E2 detectors")) {
170 // build connection between lanes
172 TL("Build connections between lanes"), "",
173 TL("New connections will be created between non-connected lanes"),
175 // remove invalid elements
177 TL("Remove invalid E2 detectors"), "",
178 TL("Remove Multilane E2 Detectors with non-connected lanes"),
180 // activate friendly position
182 TL("Activate friendlyPos and save"), "",
183 TL("Friendly pos parameter will be activated in all stopping places and E2 detectors"),
185 // fix positions
187 TL("Fix positions and save"), "",
188 TL("Position of stopping places and E2 detectors will be fixed"),
190 // register options
195 // leave option "buildConnectionBetweenLanes" and "activateFriendlyPosition" as default
196 myBuildConnectionBetweenLanes->setCheck(true);
197 myActivateFriendlyPosition->setCheck(true);
198}
199
200
201void
204
205
206bool
208 if (myConflictedElements.size() > 0) {
209 auto net = myFixElementDialogParent->getApplicationWindow()->getViewNet()->getNet();
210 auto undoList = myFixElementDialogParent->getApplicationWindow()->getUndoList();
211 // all fix implies undo-redo
212 undoList->begin(myConflictedElements.front().getElement(),
213 TL("fix multilane additionals problems"));
214 // continue depending of solution
215 if (myBuildConnectionBetweenLanes->getCheck() == TRUE) {
216 // iterate over invalid single lane elements to enable friendly position
217 for (const auto& conflictedElement : myConflictedElements) {
218 conflictedElement.getElement()->fixAdditionalProblem();
219 }
220 // we need to check if after first fix there is still invalid MultiLane Additionals with errors
221 const std::vector<ConflictElement> copyOfConflictedElements = myConflictedElements;
222 myConflictedElements.clear();
223 for (const auto& conflictedElement : copyOfConflictedElements) {
224 if (!conflictedElement.getElement()->isAdditionalValid()) {
225 myConflictedElements.push_back(conflictedElement);
226 }
227 }
228 } else if (myRemoveInvalidElements->getCheck() == TRUE) {
229 // iterate over invalid single lane elements to fix positions
230 for (const auto& conflictedElement : myConflictedElements) {
231 net->deleteAdditional(conflictedElement.getElement(), undoList);
232 }
233 // clear myInvalidMultiLaneAdditionals due there isn't more invalid multi lane additionals
234 myConflictedElements.clear();
235 }
236 // fix problem of positions
237 if (myActivateFriendlyPosition->getCheck() == TRUE) {
238 // iterate over invalid single lane elements to enable friendly position
239 for (const auto& conflictedElement : myConflictedElements) {
240 conflictedElement.getElement()->setAttribute(SUMO_ATTR_FRIENDLY_POS, "true", undoList);
241 }
242 } else if (myFixPositions->getCheck() == TRUE) {
243 // iterate over invalid single lane elements to fix positions
244 for (const auto& conflictedElement : myConflictedElements) {
245 conflictedElement.getElement()->fixAdditionalProblem();
246 }
247 }
248 // end undo list
249 undoList->end();
250 }
251 return true;
252}
253
254
255long
257 // set top buttons
258 if (obj == myBuildConnectionBetweenLanes) {
259 myBuildConnectionBetweenLanes->setCheck(true);
260 myRemoveInvalidElements->setCheck(false);
261 } else if (obj == myRemoveInvalidElements) {
262 myBuildConnectionBetweenLanes->setCheck(false);
263 myRemoveInvalidElements->setCheck(true);
264 }
265 // set down buttons
266 if (obj == myActivateFriendlyPosition) {
267 myActivateFriendlyPosition->setCheck(true);
268 myFixPositions->setCheck(false);
269 } else if (obj == myFixPositions) {
270 myActivateFriendlyPosition->setCheck(false);
271 myFixPositions->setCheck(true);
272 }
273 return true;
274}
275
276// ---------------------------------------------------------------------------
277// GNEFixAdditionalElementsDialog - methods
278// ---------------------------------------------------------------------------
279
281 const std::vector<GNEAdditional*>& elements) :
282 GNEFixElementsDialog(mainWindow, TL("Fix additional problems"), GUIIcon::MODEADDITIONAL) {
283 // create position options
285 // create consecutive lane options
287 // split invalidDemandElements in four groups
288 std::vector<ConflictElement> invalidSingleLanes, invalidMultiLanes;
289 // fill groups
290 for (const auto& invalidAdditionalElement : elements) {
291 // create conflict element
292 auto fixElement = ConflictElement(invalidAdditionalElement,
293 invalidAdditionalElement->getID(),
294 invalidAdditionalElement->getACIcon(),
295 invalidAdditionalElement->getAdditionalProblem());
296 // add depending of element type
297 if (invalidAdditionalElement->getTagProperty()->hasAttribute(SUMO_ATTR_LANE)) {
298 invalidSingleLanes.push_back(fixElement);
299 } else if (invalidAdditionalElement->getTagProperty()->hasAttribute(SUMO_ATTR_LANES)) {
300 invalidMultiLanes.push_back(fixElement);
301 }
302 }
303 // fill options
304 myPositionOptions->setInvalidElements(invalidSingleLanes);
306 // open modal dialog
307 openDialog();
308}
309
310
313
314/****************************************************************************/
FXDEFMAP(GNEFixAdditionalElementsDialog::PositionOptions) PositionOptionsMap[]
@ MID_CHOOSEN_OPERATION
set type of selection
Definition GUIAppEnum.h:597
#define GUIDesignRadioButtonFix
design for radio button with fixed height (used in fix elements dialogs)
Definition GUIDesigns.h:237
GUIIcon
An enumeration of icons used by the gui applications.
Definition GUIIcons.h:33
@ MODEADDITIONAL
#define TL(string)
Definition MsgHandler.h:305
#define TLF(string,...)
Definition MsgHandler.h:307
@ SUMO_ATTR_LANE
@ GNE_ATTR_SELECTED
element is selected
@ SUMO_ATTR_LANES
@ SUMO_ATTR_FRIENDLY_POS
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:46
The main window of Netedit.
void openDialog(FXWindow *focusableElement=nullptr)
open dialog
long onCmdSelectOption(FXObject *obj, FXSelector, void *)
called when user select a option
FXRadioButton * myFixPositions
Option "Fix Positions and save".
FXRadioButton * myRemoveInvalidElements
Option "remove invalid elements".
void selectInternalTestSolution(const std::string &solution)
select internal test solution
FXRadioButton * myActivateFriendlyPosition
Option "Activate friendlyPos and save".
ConsecutiveLaneOptions(GNEFixAdditionalElementsDialog *fixAdditionalPositions)
FOX-declaration.
long onCmdSelectOption(FXObject *obj, FXSelector, void *)
called when user select a option
FXRadioButton * mySelectInvalids
Option "Select invalid stops and cancel".
FXRadioButton * myFixPositions
Option "Fix Positions and save".
void selectInternalTestSolution(const std::string &solution)
select internal test solution
GNEFixAdditionalElementsDialog(GNEApplicationWindow *mainWindow, const std::vector< GNEAdditional * > &elements)
Constructor.
ConsecutiveLaneOptions * myConsecutiveLaneOptions
consecutive lane options
PositionOptions * myPositionOptions
position options
void registerOption(FXWindow *option)
add option to options container (used for adjust width and enable/disable)
void setInvalidElements(const std::vector< ConflictElement > &conflictedElements)
set invalid elements to fix
FXVerticalFrame * myRightFrameOptions
vertical right frame for options
FXVerticalFrame * myLeftFrameOptions
vertical left frame for options
FXVerticalFrame * myLeftFrame
left frame for fix options
static FXRadioButton * buildFXRadioButton(FXComposite *p, const std::string &text, const std::string &tip, const std::string &help, FXObject *tgt, FXSelector sel, FXuint opts=RADIOBUTTON_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 radio button
MFXGroupBoxModule (based on FXGroupBox)