Eclipse SUMO - Simulation of Urban MObility
GNESelectorFrame.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3// Copyright (C) 2001-2022 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// The Widget for modifying selections of network-elements
19/****************************************************************************/
20#include <config.h>
21
22#include <netedit/GNENet.h>
23#include <netedit/GNEUndoList.h>
24#include <netedit/GNEViewNet.h>
31
32#include "GNESelectorFrame.h"
33#include "GNEElementSet.h"
34
35
36// ===========================================================================
37// FOX callback mapping
38// ===========================================================================
41};
42
45};
46
54};
55
60};
61
62// Object implementation
63FXIMPLEMENT(GNESelectorFrame::ModificationMode, MFXGroupBoxModule, ModificationModeMap, ARRAYNUMBER(ModificationModeMap))
64FXIMPLEMENT(GNESelectorFrame::VisualScaling, MFXGroupBoxModule, VisualScalingMap, ARRAYNUMBER(VisualScalingMap))
65FXIMPLEMENT(GNESelectorFrame::SelectionOperation, MFXGroupBoxModule, SelectionOperationMap, ARRAYNUMBER(SelectionOperationMap))
66FXIMPLEMENT(GNESelectorFrame::SelectionHierarchy, MFXGroupBoxModule, SelectionHierarchyMap, ARRAYNUMBER(SelectionHierarchyMap))
67
68// ===========================================================================
69// method definitions
70// ===========================================================================
71
72// ---------------------------------------------------------------------------
73// ModificationMode::SelectionInformation - methods
74// ---------------------------------------------------------------------------
75
77 MFXGroupBoxModule(selectorFrameParent, TL("Selection information")),
78 mySelectorFrameParent(selectorFrameParent) {
79 // information label
80 myInformationLabel = new FXLabel(getCollapsableFrame(), "", nullptr, GUIDesignLabelFrameInformation);
81}
82
83
85
86
87void
89 // first clear information
90 myInformation.clear();
91 // get attribute carriers
92 const auto ACs = mySelectorFrameParent->getViewNet()->getNet()->getAttributeCarriers();
93 // continue depending of supermode
94 if (mySelectorFrameParent->getViewNet()->getEditModes().isCurrentSupermodeNetwork()) {
95 updateInformationLabel("Junctions", ACs->getNumberOfSelectedJunctions());
96 updateInformationLabel("Edges", ACs->getNumberOfSelectedEdges());
97 updateInformationLabel("Lanes", ACs->getNumberOfSelectedLanes());
98 updateInformationLabel("Connections", ACs->getNumberOfSelectedConnections());
99 updateInformationLabel("Crossings", ACs->getNumberOfSelectedCrossings());
100 updateInformationLabel("WalkingAreas", ACs->getNumberOfSelectedWalkingAreas());
101 updateInformationLabel("Additionals", ACs->getNumberOfSelectedPureAdditionals());
102 updateInformationLabel("Wires", ACs->getNumberOfSelectedWires());
103 updateInformationLabel("TAZs", ACs->getNumberOfSelectedTAZs());
104 updateInformationLabel("TAZSources", ACs->getNumberOfSelectedTAZSources());
105 updateInformationLabel("TAZSinks", ACs->getNumberOfSelectedTAZSinks());
106 updateInformationLabel("Polygon", ACs->getNumberOfSelectedPolygons());
107 updateInformationLabel("POIs", ACs->getNumberOfSelectedPOIs());
108 } else if (mySelectorFrameParent->getViewNet()->getEditModes().isCurrentSupermodeDemand()) {
109 updateInformationLabel("Routes", ACs->getNumberOfSelectedRoutes());
110 updateInformationLabel("Vehicles", ACs->getNumberOfSelectedVehicles());
111 updateInformationLabel("Persons", ACs->getNumberOfSelectedPersons());
112 updateInformationLabel("Person trips", ACs->getNumberOfSelectedPersonTrips());
113 updateInformationLabel("Walks", ACs->getNumberOfSelectedWalks());
114 updateInformationLabel("Rides", ACs->getNumberOfSelectedRides());
115 updateInformationLabel("Containers", ACs->getNumberOfSelectedContainers());
116 updateInformationLabel("Transport", ACs->getNumberOfSelectedTransport());
117 updateInformationLabel("Tranships", ACs->getNumberOfSelectedTranships());
118 updateInformationLabel("Stops", ACs->getNumberOfSelectedStops());
119 } else if (mySelectorFrameParent->getViewNet()->getEditModes().isCurrentSupermodeData()) {
120 updateInformationLabel("EdgeDatas", ACs->getNumberOfSelectedEdgeDatas());
121 updateInformationLabel("EdgeRelDatas", ACs->getNumberOfSelectedEdgeRelDatas());
122 updateInformationLabel("EdgeTAZRel", ACs->getNumberOfSelectedEdgeTAZRel());
123 }
124 // adjust format
125 const auto numberLines = std::count(myInformation.begin(), myInformation.end(), ':');
126 if (numberLines == 0) {
127 myInformation.append(" \n \n");
128 } else if (numberLines > 1) {
129 myInformation.pop_back();
130 }
131 // set label
132 myInformationLabel->setText(myInformation.c_str());
133}
134
135
136void
138 // check number
139 if (number > 0) {
140 myInformation.append(element + ": " + toString(number) + "\n");
141 }
142}
143
144// ---------------------------------------------------------------------------
145// ModificationMode::ModificationMode - methods
146// ---------------------------------------------------------------------------
147
149 MFXGroupBoxModule(selectorFrameParent, TL("Modification Mode")),
150 myModificationModeType(Operation::ADD) {
151 // Create all options buttons
152 myAddRadioButton = new FXRadioButton(getCollapsableFrame(), TL("add\t\tSelected objects are added to the previous selection"),
154 myRemoveRadioButton = new FXRadioButton(getCollapsableFrame(), TL("remove\t\tSelected objects are removed from the previous selection"),
156 myKeepRadioButton = new FXRadioButton(getCollapsableFrame(), TL("keep\t\tRestrict previous selection by the current selection"),
158 myReplaceRadioButton = new FXRadioButton(getCollapsableFrame(), TL("replace\t\tReplace previous selection by the current selection"),
160 myAddRadioButton->setCheck(true);
161}
162
163
165
166
169 return myModificationModeType;
170}
171
172
173long
175 if (obj == myAddRadioButton) {
176 myModificationModeType = Operation::ADD;
177 myAddRadioButton->setCheck(true);
178 myRemoveRadioButton->setCheck(false);
179 myKeepRadioButton->setCheck(false);
180 myReplaceRadioButton->setCheck(false);
181 return 1;
182 } else if (obj == myRemoveRadioButton) {
183 myModificationModeType = Operation::SUB;
184 myAddRadioButton->setCheck(false);
185 myRemoveRadioButton->setCheck(true);
186 myKeepRadioButton->setCheck(false);
187 myReplaceRadioButton->setCheck(false);
188 return 1;
189 } else if (obj == myKeepRadioButton) {
190 myModificationModeType = Operation::RESTRICT;
191 myAddRadioButton->setCheck(false);
192 myRemoveRadioButton->setCheck(false);
193 myKeepRadioButton->setCheck(true);
194 myReplaceRadioButton->setCheck(false);
195 return 1;
196 } else if (obj == myReplaceRadioButton) {
197 myModificationModeType = Operation::REPLACE;
198 myAddRadioButton->setCheck(false);
199 myRemoveRadioButton->setCheck(false);
200 myKeepRadioButton->setCheck(false);
201 myReplaceRadioButton->setCheck(true);
202 return 1;
203 } else {
204 return 0;
205 }
206}
207
208// ---------------------------------------------------------------------------
209// ModificationMode::VisualScaling - methods
210// ---------------------------------------------------------------------------
211
213 MFXGroupBoxModule(selectorFrameParent, TL("Visual Scaling")),
214 mySelectorFrameParent(selectorFrameParent) {
215 // Create spin button and configure it
217 //mySelectionScaling->setNumberFormat(1);
218 //mySelectionScaling->setIncrements(0.1, .5, 1);
219 mySelectionScaling->setIncrement(0.5);
220 mySelectionScaling->setRange(1, 100000);
221 mySelectionScaling->setValue(1);
222 mySelectionScaling->setHelpText("Enlarge selected objects");
223}
224
225
227
228
229long
231 // set scale in viewnet
232 mySelectorFrameParent->myViewNet->setSelectorFrameScale(mySelectionScaling->getValue());
233 mySelectorFrameParent->myViewNet->updateViewNet();
234 return 1;
235}
236
237// ---------------------------------------------------------------------------
238// ModificationMode::SelectionHierarchy - methods
239// ---------------------------------------------------------------------------
240
242 MFXGroupBoxModule(selectorFrameParent, TL("Selection operations")),
243 mySelectorFrameParent(selectorFrameParent) {
244 // tabular buttons, see GNETLSEditorFrame
245
246 FXHorizontalFrame* selectionButtons = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame);
247 FXVerticalFrame* col1 = new FXVerticalFrame(selectionButtons, LAYOUT_FILL_X, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); // left button columm
248 FXVerticalFrame* col2 = new FXVerticalFrame(selectionButtons, LAYOUT_FILL_X, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); // right button column
249
250 // Create "Clear List" Button
251 new FXButton(col1, "Clear\t\tDeselect all objects (hotkey: ESC)", nullptr, this, MID_CHOOSEN_CLEAR, GUIDesignButton);
252 // Create "Invert" Button
253 new FXButton(col2, "Invert\t\tInvert selection status of all objects", nullptr, this, MID_CHOOSEN_INVERT, GUIDesignButton);
254 // Create "Save" Button
255 new FXButton(col1, "Save\t\tSave ids of currently selected objects to a file.", nullptr, this, MID_CHOOSEN_SAVE, GUIDesignButton);
256 // Create "Load" Button
257 new FXButton(col2, "Load\t\tLoad ids from a file according to the current modfication mode.", nullptr, this, MID_CHOOSEN_LOAD, GUIDesignButton);
258 // Create "Delete" Button
259 new FXButton(col1, "Delete\t\tDelete all selected objects (hotkey: DEL)", nullptr, this, MID_CHOOSEN_DELETE, GUIDesignButton);
260 // Create "reduce" Button
261 new FXButton(col2, "Reduce\t\tReduce network to current selection.", nullptr, this, MID_CHOOSEN_REDUCE, GUIDesignButton);
262}
263
264
266
267
268long
270 // get the new file name
271 FXFileDialog opendialog(getCollapsableFrame(), "Open List of Selected Items");
272 opendialog.setIcon(GUIIconSubSys::getIcon(GUIIcon::OPEN_CONFIG));
273 opendialog.setSelectMode(SELECTFILE_EXISTING);
274 opendialog.setPatternList("Selection files (*.txt)\nAll files (*)");
275 if (gCurrentFolder.length() != 0) {
276 opendialog.setDirectory(gCurrentFolder);
277 }
278 if (opendialog.execute()) {
279 std::vector<GNEAttributeCarrier*> loadedACs;
280 gCurrentFolder = opendialog.getDirectory();
281 std::string file = opendialog.getFilename().text();
282 std::ostringstream msg;
283 std::ifstream strm(file.c_str());
284 // check if file can be opened
285 if (!strm.good()) {
286 WRITE_ERROR("Could not open '" + file + "'.");
287 return 0;
288 }
289 // convert all glObjects into GNEAttributeCarriers
290 std::map<const std::string, GNEAttributeCarrier*> GLFUllNameAC;
291 const auto GLObjects = GUIGlObjectStorage::gIDStorage.getAllGLObjects();
292 for (const auto& GLObject : GLObjects) {
293 // try to parse GLObject to AC
294 GNEAttributeCarrier* AC = dynamic_cast<GNEAttributeCarrier*>(GLObject);
295 // if was sucesfully parsed and is NOT a template, add into GLFUllNameAC using fullName
296 if (AC && !AC->isTemplate()) {
297 GLFUllNameAC[GUIGlObject::TypeNames.getString(GLObject->getType()) + ":" + AC->getID()] = AC;
298 }
299 }
300 // continue while stream exist
301 while (strm.good()) {
302 std::string line;
303 strm >> line;
304 // check if line isn't empty
305 if (line.length() != 0) {
306 // obtain AC from GLFUllNameAC
307 GNEAttributeCarrier* AC = GLFUllNameAC.count(line) > 0 ? GLFUllNameAC.at(line) : nullptr;
308 // check if AC exist, is selectable, and isn't locked
309 if (AC && AC->getTagProperty().isSelectable() && !mySelectorFrameParent->getViewNet()->getLockManager().isObjectLocked(AC->getGUIGlObject()->getType(), false)) {
310 // now check if we're in the correct supermode to load this element
311 if (((mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeNetwork()) && !AC->getTagProperty().isDemandElement()) ||
312 ((mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeDemand()) && AC->getTagProperty().isDemandElement()) ||
313 ((mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeData()) && AC->getTagProperty().isDataElement())) {
314 loadedACs.push_back(AC);
315 }
316 }
317 }
318 }
319 // change selected attribute in loaded ACs allowing undo/redo
320 if (loadedACs.size() > 0) {
321 mySelectorFrameParent->myViewNet->getUndoList()->begin(GUIIcon::MODESELECT, "load selection");
322 mySelectorFrameParent->handleIDs(loadedACs);
323 mySelectorFrameParent->myViewNet->getUndoList()->end();
324 }
325 }
326 mySelectorFrameParent->myViewNet->updateViewNet();
327 return 1;
328}
329
330
331long
333 FXString file = MFXUtils::getFilename2Write(this,
334 TL("Save List of selected Items"), ".txt",
336 if (file == "") {
337 return 1;
338 }
339 try {
340 OutputDevice& dev = OutputDevice::getDevice(file.text());
341 // get selected attribute carriers
342 const auto selectedACs = mySelectorFrameParent->myViewNet->getNet()->getAttributeCarriers()->getSelectedAttributeCarriers(false);
343 for (const auto& selectedAC : selectedACs) {
344 GUIGlObject* object = dynamic_cast<GUIGlObject*>(selectedAC);
345 if (object) {
346 dev << GUIGlObject::TypeNames.getString(object->getType()) << ":" << selectedAC->getID() << "\n";
347 }
348 }
349 dev.close();
350 } catch (IOError& e) {
351 // write warning if netedit is running in testing mode
352 WRITE_DEBUG("Opening FXMessageBox 'error storing selection'");
353 // open message box error
354 FXMessageBox::error(getCollapsableFrame(), MBOX_OK, "Storing Selection failed", "%s", e.what());
355 // write warning if netedit is running in testing mode
356 WRITE_DEBUG("Closed FXMessageBox 'error storing selection' with 'OK'");
357 }
358 return 1;
359}
360
361
362long
364 bool ignoreLocking = false;
365 // only continue if there is element for selecting
366 if ((mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeNetwork() && processNetworkElementSelection(true, false, ignoreLocking)) ||
367 (mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeDemand() && processDemandElementSelection(true, false, ignoreLocking)) ||
368 (mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeData() && processDataElementSelection(true, false, ignoreLocking))) {
369 // for invert selection, first clean current selection and next select elements of set "unselectedElements"
370 mySelectorFrameParent->myViewNet->getUndoList()->begin(GUIIcon::MODESELECT, "invert selection");
371 // invert selection of elements depending of current supermode
372 if (mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeNetwork()) {
373 processNetworkElementSelection(false, true, ignoreLocking);
374 } else if (mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeDemand()) {
375 processDemandElementSelection(false, true, ignoreLocking);
376 } else if (mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeData()) {
377 processDataElementSelection(false, true, ignoreLocking);
378 }
379 // finish selection operation
380 mySelectorFrameParent->myViewNet->getUndoList()->end();
381 }
382 return 1;
383}
384
385long
387 // acts like the 'del' hotkey
388 mySelectorFrameParent->getViewNet()->hotkeyDel();
389 return 1;
390}
391
392
393long
395 bool ignoreLocking = false;
396 // only continue if there is element for selecting
397 if ((mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeNetwork() && processNetworkElementSelection(true, false, ignoreLocking)) ||
398 (mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeDemand() && processDemandElementSelection(true, false, ignoreLocking)) ||
399 (mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeData() && processDataElementSelection(true, false, ignoreLocking))) {
400 // for invert selection, first clean current selection and next select elements of set "unselectedElements"
401 mySelectorFrameParent->myViewNet->getUndoList()->begin(GUIIcon::MODESELECT, "invert selection");
402 // invert selection of elements depending of current supermode
403 if (mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeNetwork()) {
404 // invert network elements
405 processNetworkElementSelection(false, false, ignoreLocking);
406 } else if (mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeDemand()) {
407 // invert demand elements
408 processDemandElementSelection(false, false, ignoreLocking);
409 } else if (mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeData()) {
410 // invert data elements
411 processDataElementSelection(false, false, ignoreLocking);
412 }
413 // finish selection operation
414 mySelectorFrameParent->myViewNet->getUndoList()->end();
415 }
416 return 1;
417}
418
419
420long
422 // begin undoList operation
423 mySelectorFrameParent->getViewNet()->getUndoList()->begin(Supermode::NETWORK, GUIIcon::SIMPLIFYNETWORK, "simplify network");
424 // invert and clear
425 onCmdInvert(0, 0, 0);
426 onCmdDelete(0, 0, 0);
427 // end undoList operation
428 mySelectorFrameParent->getViewNet()->getUndoList()->end();
429 return 1;
430}
431
432
433bool
434GNESelectorFrame::SelectionOperation::processNetworkElementSelection(const bool onlyCount, const bool onlyUnselect, bool& ignoreLocking) {
435 // obtan locks (only for improve code legibly)
436 const auto& locks = mySelectorFrameParent->getViewNet()->getLockManager();
437 // get attribute carriers (only for improve code legibly)
438 const auto& ACs = mySelectorFrameParent->myViewNet->getNet()->getAttributeCarriers();
439 // obtain undoList (only for improve code legibly)
440 GNEUndoList* undoList = mySelectorFrameParent->myViewNet->getUndoList();
441 // iterate over junctions
442 for (const auto& junction : ACs->getJunctions()) {
443 // check if junction selection is locked
444 if (ignoreLocking || !locks.isObjectLocked(GLO_JUNCTION, false)) {
445 if (onlyCount) {
446 return true;
447 } else if (onlyUnselect || junction.second->isAttributeCarrierSelected()) {
448 junction.second->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
449 } else {
450 junction.second->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
451 }
452 } else if (onlyCount) {
453 ignoreLocking = askContinueIfLock();
454 return true;
455 }
456 // due we iterate over all junctions, only it's neccesary iterate over incoming edges
457 for (const auto& incomingEdge : junction.second->getGNEIncomingEdges()) {
458 // special case for clear
459 if (onlyUnselect) {
460 // check if edge selection is locked
461 if (ignoreLocking || !locks.isObjectLocked(GLO_EDGE, false)) {
462 if (onlyCount) {
463 return true;
464 } else {
465 incomingEdge->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
466 }
467 } else if (onlyCount) {
468 ignoreLocking = askContinueIfLock();
469 return true;
470 }
471 // check if lane selection is locked
472 if (ignoreLocking || !locks.isObjectLocked(GLO_LANE, false)) {
473 for (const auto& lane : incomingEdge->getLanes()) {
474 if (onlyCount) {
475 return true;
476 } else {
477 lane->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
478 }
479 }
480 } else if (onlyCount) {
481 ignoreLocking = askContinueIfLock();
482 return true;
483 }
484 } else if (mySelectorFrameParent->myViewNet->getNetworkViewOptions().selectEdges()) {
485 // check if edge selection is locked
486 if (ignoreLocking || !locks.isObjectLocked(GLO_EDGE, false)) {
487 if (onlyCount) {
488 return true;
489 } else if (onlyUnselect || incomingEdge->isAttributeCarrierSelected()) {
490 incomingEdge->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
491 } else {
492 incomingEdge->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
493 }
494 } else if (onlyCount) {
495 ignoreLocking = askContinueIfLock();
496 return true;
497 }
498 } else {
499 // check if lane selection is locked
500 if (ignoreLocking || !locks.isObjectLocked(GLO_LANE, false)) {
501 for (const auto& lane : incomingEdge->getLanes()) {
502 if (onlyCount) {
503 return true;
504 } else if (onlyUnselect || lane->isAttributeCarrierSelected()) {
505 lane->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
506 } else {
507 lane->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
508 }
509 }
510 } else if (onlyCount) {
511 ignoreLocking = askContinueIfLock();
512 return true;
513 }
514 }
515 // check if connection selection is locked
516 if (ignoreLocking || !locks.isObjectLocked(GLO_CONNECTION, false)) {
517 for (const auto& connection : incomingEdge->getGNEConnections()) {
518 if (onlyCount) {
519 return true;
520 } else if (onlyUnselect || connection->isAttributeCarrierSelected()) {
521 connection->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
522 } else {
523 connection->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
524 }
525 }
526 } else if (onlyCount) {
527 ignoreLocking = askContinueIfLock();
528 return true;
529 }
530 }
531 // check if crossing selection is locked
532 if (ignoreLocking || !locks.isObjectLocked(GLO_CROSSING, false)) {
533 for (const auto& crossing : junction.second->getGNECrossings()) {
534 if (onlyCount) {
535 return true;
536 } else if (onlyUnselect || crossing->isAttributeCarrierSelected()) {
537 crossing->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
538 } else {
539 crossing->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
540 }
541 }
542 } else if (onlyCount) {
543 ignoreLocking = askContinueIfLock();
544 return true;
545 }
546 // check if walkingArea selection is locked
547 if (ignoreLocking || !locks.isObjectLocked(GLO_WALKINGAREA, false)) {
548 for (const auto& walkingArea : junction.second->getGNEWalkingAreas()) {
549 if (onlyCount) {
550 return true;
551 } else if (onlyUnselect || walkingArea->isAttributeCarrierSelected()) {
552 walkingArea->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
553 } else {
554 walkingArea->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
555 }
556 }
557 } else if (onlyCount) {
558 ignoreLocking = askContinueIfLock();
559 return true;
560 }
561 }
562 // check if additionals selection is locked
563 if (ignoreLocking || !locks.isObjectLocked(GLO_ADDITIONALELEMENT, false)) {
564 for (const auto& additionalTag : ACs->getAdditionals()) {
565 // first check if additional is selectable
567 for (const auto& additional : additionalTag.second) {
568 if (onlyCount) {
569 return true;
570 } else if (onlyUnselect || additional->isAttributeCarrierSelected()) {
571 additional->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
572 } else {
573 additional->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
574 }
575 }
576 }
577 }
578 } else if (onlyCount) {
579 ignoreLocking = askContinueIfLock();
580 return true;
581 }
582 // check if wires selection is locked
583 if (ignoreLocking || !locks.isObjectLocked(GLO_WIRE, false)) {
584 for (const auto& wireTag : ACs->getAdditionals()) {
585 // first check if wire is selectable
587 for (const auto& wire : wireTag.second) {
588 if (onlyCount) {
589 return true;
590 } else if (onlyUnselect || wire->isAttributeCarrierSelected()) {
591 wire->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
592 } else {
593 wire->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
594 }
595 }
596 }
597 }
598 } else if (onlyCount) {
599 ignoreLocking = askContinueIfLock();
600 return true;
601 }
602 // invert polygons
603 if (ignoreLocking || !locks.isObjectLocked(GLO_POLYGON, false)) {
604 for (const auto& polygon : ACs->getAdditionals().at(SUMO_TAG_POLY)) {
605 if (onlyCount) {
606 return true;
607 } else if (onlyUnselect || polygon->isAttributeCarrierSelected()) {
608 polygon->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
609 } else {
610 polygon->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
611 }
612 }
613 } else if (onlyCount) {
614 ignoreLocking = askContinueIfLock();
615 return true;
616 }
617 // invert TAZs
618 if (ignoreLocking || !locks.isObjectLocked(GLO_TAZ, false)) {
619 for (const auto& TAZ : ACs->getAdditionals().at(SUMO_TAG_TAZ)) {
620 if (onlyCount) {
621 return true;
622 } else if (onlyUnselect || TAZ->isAttributeCarrierSelected()) {
623 TAZ->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
624 } else {
625 TAZ->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
626 }
627 }
628 for (const auto& TAZSource : ACs->getAdditionals().at(SUMO_TAG_TAZSOURCE)) {
629 if (onlyCount) {
630 return true;
631 } else if (onlyUnselect || TAZSource->isAttributeCarrierSelected()) {
632 TAZSource->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
633 } else {
634 TAZSource->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
635 }
636 }
637 for (const auto& TAZSink : ACs->getAdditionals().at(SUMO_TAG_TAZSINK)) {
638 if (onlyCount) {
639 return true;
640 } else if (onlyUnselect || TAZSink->isAttributeCarrierSelected()) {
641 TAZSink->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
642 } else {
643 TAZSink->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
644 }
645 }
646 } else if (onlyCount) {
647 ignoreLocking = askContinueIfLock();
648 return true;
649 }
650 // invert POIs and POILanes
651 if (ignoreLocking || !locks.isObjectLocked(GLO_POI, false)) {
652 for (const auto& POI : ACs->getAdditionals().at(SUMO_TAG_POI)) {
653 if (onlyCount) {
654 return true;
655 } else if (onlyUnselect || POI->isAttributeCarrierSelected()) {
656 POI->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
657 } else {
658 POI->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
659 }
660 }
661 for (const auto& POILane : ACs->getAdditionals().at(GNE_TAG_POILANE)) {
662 if (onlyCount) {
663 return true;
664 } else if (onlyUnselect || POILane->isAttributeCarrierSelected()) {
665 POILane->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
666 } else {
667 POILane->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
668 }
669 }
670 for (const auto& POIGeo : ACs->getAdditionals().at(GNE_TAG_POIGEO)) {
671 if (onlyCount) {
672 return true;
673 } else if (onlyUnselect || POIGeo->isAttributeCarrierSelected()) {
674 POIGeo->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
675 } else {
676 POIGeo->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
677 }
678 }
679 } else if (onlyCount) {
680 ignoreLocking = askContinueIfLock();
681 return true;
682 }
683 return false;
684}
685
686
687bool
688GNESelectorFrame::SelectionOperation::processDemandElementSelection(const bool onlyCount, const bool onlyUnselect, bool& ignoreLocking) {
689 // obtan locks (only for improve code legibly)
690 const auto& locks = mySelectorFrameParent->getViewNet()->getLockManager();
691 // obtain undoList (only for improve code legibly)
692 GNEUndoList* undoList = mySelectorFrameParent->myViewNet->getUndoList();
693 // get demand elements
694 const auto& demandElements = mySelectorFrameParent->myViewNet->getNet()->getAttributeCarriers()->getDemandElements();
695 // invert routes
696 if (ignoreLocking || !locks.isObjectLocked(GLO_ROUTE, false)) {
697 for (const auto& route : demandElements.at(SUMO_TAG_ROUTE)) {
698 if (onlyCount) {
699 return true;
700 } else if (onlyUnselect || route->isAttributeCarrierSelected()) {
701 route->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
702 } else {
703 route->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
704 }
705 }
706 // iterate over all embedded routes
707 for (const auto& vehicle : demandElements.at(GNE_TAG_VEHICLE_WITHROUTE)) {
708 if (onlyCount) {
709 return true;
710 } else if (onlyUnselect || vehicle->getChildDemandElements().front()->isAttributeCarrierSelected()) {
711 vehicle->getChildDemandElements().front()->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
712 } else {
713 vehicle->getChildDemandElements().front()->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
714 }
715 }
716 for (const auto& routeFlow : demandElements.at(GNE_TAG_FLOW_WITHROUTE)) {
717 if (onlyCount) {
718 return true;
719 } else if (onlyUnselect || routeFlow->getChildDemandElements().front()->isAttributeCarrierSelected()) {
720 routeFlow->getChildDemandElements().front()->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
721 } else {
722 routeFlow->getChildDemandElements().front()->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
723 }
724 }
725 } else if (onlyCount) {
726 ignoreLocking = askContinueIfLock();
727 return true;
728 }
729 // invert vehicles
730 if (ignoreLocking || !locks.isObjectLocked(GLO_VEHICLE, false)) {
731 for (const auto& vehicle : demandElements.at(SUMO_TAG_VEHICLE)) {
732 if (onlyCount) {
733 return true;
734 } else if (onlyUnselect || vehicle->isAttributeCarrierSelected()) {
735 vehicle->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
736 } else {
737 vehicle->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
738 }
739 }
740 for (const auto& vehicle : demandElements.at(GNE_TAG_VEHICLE_WITHROUTE)) {
741 if (onlyCount) {
742 return true;
743 } else if (onlyUnselect || vehicle->isAttributeCarrierSelected()) {
744 vehicle->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
745 } else {
746 vehicle->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
747 }
748 }
749 for (const auto& trip : demandElements.at(SUMO_TAG_TRIP)) {
750 if (onlyCount) {
751 return true;
752 } else if (onlyUnselect || trip->isAttributeCarrierSelected()) {
753 trip->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
754 } else {
755 trip->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
756 }
757 }
758 for (const auto& flow : demandElements.at(SUMO_TAG_FLOW)) {
759 if (onlyCount) {
760 return true;
761 } else if (onlyUnselect || flow->isAttributeCarrierSelected()) {
762 flow->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
763 } else {
764 flow->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
765 }
766 }
767 for (const auto& routeFlow : demandElements.at(GNE_TAG_FLOW_ROUTE)) {
768 if (onlyCount) {
769 return true;
770 } else if (onlyUnselect || routeFlow->isAttributeCarrierSelected()) {
771 routeFlow->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
772 } else {
773 routeFlow->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
774 }
775 }
776 for (const auto& routeFlow : demandElements.at(GNE_TAG_FLOW_WITHROUTE)) {
777 if (onlyCount) {
778 return true;
779 } else if (onlyUnselect || routeFlow->isAttributeCarrierSelected()) {
780 routeFlow->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
781 } else {
782 routeFlow->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
783 }
784 }
785 for (const auto& routeFlow : demandElements.at(GNE_TAG_TRIP_JUNCTIONS)) {
786 if (onlyCount) {
787 return true;
788 } else if (onlyUnselect || routeFlow->isAttributeCarrierSelected()) {
789 routeFlow->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
790 } else {
791 routeFlow->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
792 }
793 }
794 for (const auto& routeFlow : demandElements.at(GNE_TAG_FLOW_JUNCTIONS)) {
795 if (onlyCount) {
796 return true;
797 } else if (onlyUnselect || routeFlow->isAttributeCarrierSelected()) {
798 routeFlow->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
799 } else {
800 routeFlow->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
801 }
802 }
803 } else if (onlyCount) {
804 ignoreLocking = askContinueIfLock();
805 return true;
806 }
807 // invert persons
808 if (ignoreLocking || !locks.isObjectLocked(GLO_PERSON, false)) {
809 for (const auto& person : demandElements.at(SUMO_TAG_PERSON)) {
810 if (onlyCount) {
811 return true;
812 } else if (onlyUnselect || person->isAttributeCarrierSelected()) {
813 person->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
814 } else {
815 person->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
816 }
817 }
818 for (const auto& personFlow : demandElements.at(SUMO_TAG_PERSONFLOW)) {
819 if (onlyCount) {
820 return true;
821 } else if (onlyUnselect || personFlow->isAttributeCarrierSelected()) {
822 personFlow->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
823 } else {
824 personFlow->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
825 }
826 }
827 } else if (onlyCount) {
828 ignoreLocking = askContinueIfLock();
829 return true;
830 }
831 // invert person trip
832 if (ignoreLocking || !locks.isObjectLocked(GLO_PERSONTRIP, false)) {
833 for (const auto& person : demandElements.at(SUMO_TAG_PERSON)) {
834 for (const auto& personPlan : person->getChildDemandElements()) {
835 if (onlyCount) {
836 return true;
837 } else if (personPlan->getTagProperty().isPersonTrip()) {
838 if (onlyUnselect || personPlan->isAttributeCarrierSelected()) {
839 personPlan->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
840 } else {
841 personPlan->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
842 }
843 }
844 }
845 }
846 for (const auto& personFlow : demandElements.at(SUMO_TAG_PERSONFLOW)) {
847 for (const auto& personPlan : personFlow->getChildDemandElements()) {
848 if (onlyCount) {
849 return true;
850 } else if (personPlan->getTagProperty().isPersonTrip()) {
851 if (onlyUnselect || personPlan->isAttributeCarrierSelected()) {
852 personPlan->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
853 } else {
854 personPlan->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
855 }
856 }
857 }
858 }
859 } else if (onlyCount) {
860 ignoreLocking = askContinueIfLock();
861 return true;
862 }
863 // invert ride
864 if (ignoreLocking || !locks.isObjectLocked(GLO_PERSONTRIP, false)) {
865 for (const auto& person : demandElements.at(SUMO_TAG_PERSON)) {
866 for (const auto& personPlan : person->getChildDemandElements()) {
867 if (personPlan->getTagProperty().isRide()) {
868 if (onlyCount) {
869 return true;
870 } else if (onlyUnselect || personPlan->isAttributeCarrierSelected()) {
871 personPlan->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
872 } else {
873 personPlan->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
874 }
875 }
876 }
877 }
878 for (const auto& personFlow : demandElements.at(SUMO_TAG_PERSONFLOW)) {
879 for (const auto& personPlan : personFlow->getChildDemandElements()) {
880 if (personPlan->getTagProperty().isRide()) {
881 if (onlyCount) {
882 return true;
883 } else if (onlyUnselect || personPlan->isAttributeCarrierSelected()) {
884 personPlan->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
885 } else {
886 personPlan->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
887 }
888 }
889 }
890 }
891 } else if (onlyCount) {
892 ignoreLocking = askContinueIfLock();
893 return true;
894 }
895 // invert walks
896 if (ignoreLocking || !locks.isObjectLocked(GLO_PERSONTRIP, false)) {
897 for (const auto& person : demandElements.at(SUMO_TAG_PERSON)) {
898 for (const auto& personPlan : person->getChildDemandElements()) {
899 if (personPlan->getTagProperty().isWalk()) {
900 if (onlyCount) {
901 return true;
902 } else if (onlyUnselect || personPlan->isAttributeCarrierSelected()) {
903 personPlan->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
904 } else {
905 personPlan->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
906 }
907 }
908 }
909 }
910 for (const auto& personFlow : demandElements.at(SUMO_TAG_PERSONFLOW)) {
911 for (const auto& personPlan : personFlow->getChildDemandElements()) {
912 if (personPlan->getTagProperty().isWalk()) {
913 if (onlyCount) {
914 return true;
915 } else if (onlyUnselect || personPlan->isAttributeCarrierSelected()) {
916 personPlan->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
917 } else {
918 personPlan->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
919 }
920 }
921 }
922 }
923 } else if (onlyCount) {
924 ignoreLocking = askContinueIfLock();
925 return true;
926 }
927 // invert containers
928 if (ignoreLocking || !locks.isObjectLocked(GLO_CONTAINER, false)) {
929 for (const auto& container : demandElements.at(SUMO_TAG_CONTAINER)) {
930 if (onlyCount) {
931 return true;
932 } else if (onlyUnselect || container->isAttributeCarrierSelected()) {
933 container->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
934 } else {
935 container->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
936 }
937 }
938 for (const auto& containerFlow : demandElements.at(SUMO_TAG_CONTAINERFLOW)) {
939 if (onlyCount) {
940 return true;
941 } else if (onlyUnselect || containerFlow->isAttributeCarrierSelected()) {
942 containerFlow->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
943 } else {
944 containerFlow->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
945 }
946 }
947 } else if (onlyCount) {
948 ignoreLocking = askContinueIfLock();
949 return true;
950 }
951 // invert container
952 if (ignoreLocking || !locks.isObjectLocked(GLO_TRANSPORT, false)) {
953 for (const auto& container : demandElements.at(SUMO_TAG_CONTAINER)) {
954 for (const auto& containerPlan : container->getChildDemandElements()) {
955 if (containerPlan->getTagProperty().isTransportPlan()) {
956 if (onlyCount) {
957 return true;
958 } else if (onlyUnselect || containerPlan->isAttributeCarrierSelected()) {
959 containerPlan->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
960 } else {
961 containerPlan->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
962 }
963 }
964 }
965 }
966 for (const auto& containerFlow : demandElements.at(SUMO_TAG_CONTAINERFLOW)) {
967 for (const auto& containerPlan : containerFlow->getChildDemandElements()) {
968 if (containerPlan->getTagProperty().isTransportPlan()) {
969 if (onlyCount) {
970 return true;
971 } else if (onlyUnselect || containerPlan->isAttributeCarrierSelected()) {
972 containerPlan->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
973 } else {
974 containerPlan->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
975 }
976 }
977 }
978 }
979 } else if (onlyCount) {
980 ignoreLocking = askContinueIfLock();
981 return true;
982 }
983 // invert ride
984 if (ignoreLocking || !locks.isObjectLocked(GLO_TRANSHIP, false)) {
985 for (const auto& container : demandElements.at(SUMO_TAG_CONTAINER)) {
986 for (const auto& containerPlan : container->getChildDemandElements()) {
987 if (containerPlan->getTagProperty().isTranshipPlan()) {
988 if (onlyCount) {
989 return true;
990 } else if (onlyUnselect || containerPlan->isAttributeCarrierSelected()) {
991 containerPlan->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
992 } else {
993 containerPlan->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
994 }
995 }
996 }
997 }
998 for (const auto& containerFlow : demandElements.at(SUMO_TAG_CONTAINERFLOW)) {
999 for (const auto& containerPlan : containerFlow->getChildDemandElements()) {
1000 if (containerPlan->getTagProperty().isTranshipPlan()) {
1001 if (onlyCount) {
1002 return true;
1003 } else if (onlyUnselect || containerPlan->isAttributeCarrierSelected()) {
1004 containerPlan->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
1005 } else {
1006 containerPlan->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
1007 }
1008 }
1009 }
1010 }
1011 } else if (onlyCount) {
1012 ignoreLocking = askContinueIfLock();
1013 return true;
1014 }
1015 // invert stops
1016 if (ignoreLocking || !locks.isObjectLocked(GLO_STOP, false)) {
1017 for (const auto& demandElementTag : demandElements) {
1018 for (const auto& demandElement : demandElementTag.second) {
1019 // avoid vTypes
1020 if (!demandElement->getTagProperty().isVehicleType()) {
1021 // iterate over every child
1022 for (const auto& stop : demandElement->getChildDemandElements()) {
1023 if (stop->getTagProperty().isStop() || stop->getTagProperty().isStopPerson() || stop->getTagProperty().isStopContainer()) {
1024 if (onlyCount) {
1025 return true;
1026 } else if (onlyUnselect || stop->isAttributeCarrierSelected()) {
1027 stop->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
1028 } else {
1029 stop->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
1030 }
1031 } else {
1032 // special case for embedded routes
1033 for (const auto& stopEmbeddedRoute : stop->getChildDemandElements()) {
1034 if (stopEmbeddedRoute->getTagProperty().isStop() ||
1035 stopEmbeddedRoute->getTagProperty().isStopPerson() ||
1036 stopEmbeddedRoute->getTagProperty().isStopContainer()) {
1037 if (onlyCount) {
1038 return true;
1039 } else if (onlyUnselect || stopEmbeddedRoute->isAttributeCarrierSelected()) {
1040 stopEmbeddedRoute->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
1041 } else {
1042 stopEmbeddedRoute->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
1043 }
1044 }
1045 }
1046 }
1047 }
1048 }
1049 }
1050 }
1051 } else if (onlyCount) {
1052 ignoreLocking = askContinueIfLock();
1053 return true;
1054 }
1055 return false;
1056}
1057
1058
1059bool
1060GNESelectorFrame::SelectionOperation::processDataElementSelection(const bool onlyCount, const bool onlyUnselect, bool& ignoreLocking) {
1061 // obtan locks (only for improve code legibly)
1062 const auto& locks = mySelectorFrameParent->getViewNet()->getLockManager();
1063 // invert dataSets
1064 for (const auto& genericDataTag : mySelectorFrameParent->myViewNet->getNet()->getAttributeCarriers()->getGenericDatas()) {
1065 for (const auto& genericData : genericDataTag.second) {
1066 if (onlyCount && locks.isObjectLocked(genericData->getType(), false)) {
1067 ignoreLocking = askContinueIfLock();
1068 return true;
1069 } else if ((ignoreLocking || (!locks.isObjectLocked(GLO_EDGEDATA, false) && genericData->getType() == GLO_EDGEDATA)) ||
1070 (ignoreLocking || (!locks.isObjectLocked(GLO_EDGERELDATA, false) && genericData->getType() == GLO_EDGERELDATA)) ||
1071 (ignoreLocking || (!locks.isObjectLocked(GLO_TAZRELDATA, false) && genericData->getType() == GLO_TAZRELDATA))) {
1072 if (onlyCount) {
1073 return true;
1074 } else if (onlyUnselect || genericData->isAttributeCarrierSelected()) {
1075 genericData->setAttribute(GNE_ATTR_SELECTED, "false", mySelectorFrameParent->myViewNet->getUndoList());
1076 } else {
1077 genericData->setAttribute(GNE_ATTR_SELECTED, "true", mySelectorFrameParent->myViewNet->getUndoList());
1078 }
1079 }
1080 }
1081 }
1082 return false;
1083}
1084
1085
1086bool
1088 WRITE_DEBUG("Opening FXMessageBox 'confirm selection operation'");
1089 // open question box
1090 const FXuint answer = FXMessageBox::question(mySelectorFrameParent->getViewNet()->getApp(),
1091 MBOX_YES_NO, "Confirm selection operation", "There are locked elements in currentselection.\nApply operation to locked elements?");
1092 if (answer != 1) { //1:yes, 2:no, 4:esc
1093 // write warning if netedit is running in testing mode
1094 if (answer == 2) {
1095 WRITE_DEBUG("Closed FXMessageBox 'confirm selection operation' with 'No'");
1096 } else if (answer == 4) {
1097 WRITE_DEBUG("Closed FXMessageBox 'confirm selection operation' with 'ESC'");
1098 }
1099 return false;
1100 } else {
1101 // write warning if netedit is running in testing mode
1102 WRITE_DEBUG("Closed FXMessageBox 'confirm selection operation' with 'Yes'");
1103 return true;
1104 }
1105}
1106
1107// ---------------------------------------------------------------------------
1108// ModificationMode::SelectionHierarchy - methods
1109// ---------------------------------------------------------------------------
1110
1112 MFXGroupBoxModule(selectorFrameParent, TL("Hierarchy operations")),
1113 mySelectorFrameParent(selectorFrameParent),
1114 myCurrentSelectedParent(Selection::ALL),
1115 myCurrentSelectedChild(Selection::ALL) {
1116 // create label for parents
1117 new FXLabel(getCollapsableFrame(), "Select parents", nullptr, GUIDesignLabelThickCenter);
1118 // Create FXComboBox for parent comboBox
1120 // create parent buttons
1121 FXHorizontalFrame* parentButtons = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame);
1122 // Create "select" Button
1124 // Create "unselect" Button
1126 // create label for parents
1127 new FXLabel(getCollapsableFrame(), "Select children", nullptr, GUIDesignLabelThickCenter);
1128 // Create FXComboBox for parent comboBox
1130 // create children buttons
1131 FXHorizontalFrame* childrenButtons = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame);
1132 // Create "select" Button
1134 // Create "unselect" Button
1136 // fill comboBoxes
1137 for (const auto& item : myItems) {
1138 myParentsComboBox->appendItem(item.second.c_str());
1139 myChildrenComboBox->appendItem(item.second.c_str());
1140 }
1141 myParentsComboBox->setNumVisible(5);
1142 myChildrenComboBox->setNumVisible(5);
1143}
1144
1145
1147
1148
1149long
1151 if (obj == myParentsComboBox) {
1152 for (const auto& item : myItems) {
1153 if (item.second == myParentsComboBox->getText().text()) {
1154 // enable buttons
1155 mySelectParentsButton->enable();
1156 myUnselectParentsButton->enable();
1157 // change text color
1158 myParentsComboBox->setTextColor(FXRGB(0, 0, 0));
1159 // set current selected parent
1160 myCurrentSelectedParent = item.first;
1161 return 1;
1162 }
1163 }
1164 // item not found
1165 myCurrentSelectedParent = Selection::NOTHING;
1166 // disable buttons
1167 mySelectParentsButton->disable();
1168 myUnselectParentsButton->disable();
1169 myParentsComboBox->setTextColor(FXRGB(255, 0, 0));
1170 return 1;
1171 } else if (obj == myChildrenComboBox) {
1172 for (const auto& item : myItems) {
1173 if (item.second == myChildrenComboBox->getText().text()) {
1174 // enable buttons
1175 mySelectChildrenButton->enable();
1176 myUnselectChildrenButton->enable();
1177 // change text color
1178 myChildrenComboBox->setTextColor(FXRGB(0, 0, 0));
1179 // set current selected parent
1180 myCurrentSelectedChild = item.first;
1181 return 1;
1182 }
1183 }
1184 // item not found
1185 myCurrentSelectedChild = Selection::NOTHING;
1186 // disable buttons
1187 mySelectChildrenButton->disable();
1188 myUnselectChildrenButton->disable();
1189 myChildrenComboBox->setTextColor(FXRGB(255, 0, 0));
1190 return 1;
1191 }
1192 return 0;
1193}
1194
1195
1196long
1198 // get selected elements
1199 const auto selectedACs = mySelectorFrameParent->getViewNet()->getNet()->getAttributeCarriers()->getSelectedAttributeCarriers(true);
1200 // check if there is selected ACs
1201 if ((selectedACs.size() > 0) && (myCurrentSelectedParent != Selection::NOTHING)) {
1202 // vector of hierarchical elements to select
1203 std::vector<GNEHierarchicalElement*> HEToSelect;
1204 for (const auto& selectedAC : selectedACs) {
1205 // get hierarchical element
1206 const auto HE = selectedAC->getHierarchicalElement();
1207 // junctions
1208 if ((myCurrentSelectedParent == Selection::ALL) || (myCurrentSelectedParent == Selection::JUNCTION)) {
1209 HEToSelect.insert(HEToSelect.end(), HE->getParentJunctions().begin(), HE->getParentJunctions().end());
1210 }
1211 // edges
1212 if ((myCurrentSelectedParent == Selection::ALL) || (myCurrentSelectedParent == Selection::EDGE)) {
1213 if (selectedAC->getTagProperty().getTag() == SUMO_TAG_LANE) {
1214 // special case for lanes
1215 HEToSelect.push_back(dynamic_cast<GNELane*>(selectedAC)->getParentEdge());
1216 } else {
1217 HEToSelect.insert(HEToSelect.end(), HE->getParentEdges().begin(), HE->getParentEdges().end());
1218 }
1219 }
1220 // lanes
1221 if ((myCurrentSelectedParent == Selection::ALL) || (myCurrentSelectedParent == Selection::LANE)) {
1222 HEToSelect.insert(HEToSelect.end(), HE->getParentLanes().begin(), HE->getParentLanes().end());
1223 }
1224 // additional
1225 if ((myCurrentSelectedParent == Selection::ALL) || (myCurrentSelectedParent == Selection::ADDITIONAL)) {
1226 HEToSelect.insert(HEToSelect.end(), HE->getParentAdditionals().begin(), HE->getParentAdditionals().end());
1227 }
1228 // wire
1229 if ((myCurrentSelectedParent == Selection::ALL) || (myCurrentSelectedParent == Selection::WIRE)) {
1230 HEToSelect.insert(HEToSelect.end(), HE->getParentAdditionals().begin(), HE->getParentAdditionals().end());
1231 }
1232 // demand
1233 if ((myCurrentSelectedParent == Selection::ALL) || (myCurrentSelectedParent == Selection::DEMAND)) {
1234 HEToSelect.insert(HEToSelect.end(), HE->getParentDemandElements().begin(), HE->getParentDemandElements().end());
1235 }
1236 // data
1237 if ((myCurrentSelectedParent == Selection::ALL) || (myCurrentSelectedParent == Selection::DATA)) {
1238 HEToSelect.insert(HEToSelect.end(), HE->getParentGenericDatas().begin(), HE->getParentGenericDatas().end());
1239 }
1240 }
1241 // select HE
1242 if (HEToSelect.size() > 0) {
1243 if (HEToSelect.size() > 1) {
1244 mySelectorFrameParent->getViewNet()->getUndoList()->begin(GUIIcon::SELECT, "select parents");
1245 }
1246 for (const auto& HE : HEToSelect) {
1247 if (obj == mySelectParentsButton) {
1248 HE->setAttribute(GNE_ATTR_SELECTED, "true", mySelectorFrameParent->getViewNet()->getUndoList());
1249 } else {
1250 HE->setAttribute(GNE_ATTR_SELECTED, "false", mySelectorFrameParent->getViewNet()->getUndoList());
1251 }
1252 }
1253 if (HEToSelect.size() > 1) {
1254 mySelectorFrameParent->getViewNet()->getUndoList()->end();
1255 }
1256 }
1257 // update information label
1258 mySelectorFrameParent->mySelectionInformation->updateInformationLabel();
1259 // update viewNet
1260 mySelectorFrameParent->getViewNet()->update();
1261 }
1262 return 1;
1263}
1264
1265
1266long
1268 // get selected elements
1269 const auto selectedACs = mySelectorFrameParent->getViewNet()->getNet()->getAttributeCarriers()->getSelectedAttributeCarriers(true);
1270 // check if there is selected ACs
1271 if ((selectedACs.size() > 0) && (myCurrentSelectedChild != Selection::NOTHING)) {
1272 // vector of hierarchical elements to select
1273 std::vector<GNEHierarchicalElement*> HEToSelect;
1274 for (const auto& selectedAC : selectedACs) {
1275 // get hierarchical element
1276 const auto HE = selectedAC->getHierarchicalElement();
1277 // junctions
1278 if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::JUNCTION)) {
1279 if (selectedAC->getTagProperty().getTag() == SUMO_TAG_JUNCTION) {
1280 // special case for junction
1281 const auto junction = dynamic_cast<GNEJunction*>(selectedAC);
1282 // insert edges
1283 HEToSelect.insert(HEToSelect.end(), junction->getGNEIncomingEdges().begin(), junction->getGNEIncomingEdges().end());
1284 HEToSelect.insert(HEToSelect.end(), junction->getGNEOutgoingEdges().begin(), junction->getGNEOutgoingEdges().end());
1285 } else {
1286 HEToSelect.insert(HEToSelect.end(), HE->getChildJunctions().begin(), HE->getChildJunctions().end());
1287 }
1288 }
1289 // edges
1290 if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::EDGE)) {
1291 if (selectedAC->getTagProperty().getTag() == SUMO_TAG_EDGE) {
1292 // special case for edges
1293 const auto edge = dynamic_cast<GNEEdge*>(selectedAC);
1294 // insert lanes
1295 HEToSelect.insert(HEToSelect.end(), edge->getLanes().begin(), edge->getLanes().end());
1296 } else {
1297 HEToSelect.insert(HEToSelect.end(), HE->getChildEdges().begin(), HE->getChildEdges().end());
1298 }
1299 }
1300 // connections
1301 if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::CONNECTION)) {
1302 if (selectedAC->getTagProperty().getTag() == SUMO_TAG_EDGE) {
1303 // case for edges
1304 const auto edge = dynamic_cast<GNEEdge*>(selectedAC);
1305 // insert connections
1306 HEToSelect.insert(HEToSelect.end(), edge->getGNEConnections().begin(), edge->getGNEConnections().end());
1307 } else if (selectedAC->getTagProperty().getTag() == SUMO_TAG_LANE) {
1308 // case for lanes
1309 const auto lane = dynamic_cast<GNELane*>(selectedAC);
1310 // insert connections
1311 for (const auto& connection : lane->getParentEdge()->getGNEConnections()) {
1312 if (connection->getAttribute(SUMO_ATTR_FROM_LANE) == lane->getAttribute(SUMO_ATTR_INDEX)) {
1313 HEToSelect.push_back(connection);
1314 }
1315 }
1316 } else if (selectedAC->getTagProperty().getTag() == SUMO_TAG_JUNCTION) {
1317 // case for junction
1318 const auto junction = dynamic_cast<GNEJunction*>(selectedAC);
1319 // get connections
1320 const auto connections = junction->getGNEConnections();
1321 // insert connections
1322 HEToSelect.insert(HEToSelect.end(), connections.begin(), connections.end());
1323 }
1324 }
1325 // crossings
1326 if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::CROSSING)) {
1327 if (selectedAC->getTagProperty().getTag() == SUMO_TAG_JUNCTION) {
1328 // case for junction
1329 const auto junction = dynamic_cast<GNEJunction*>(selectedAC);
1330 // insert crossings
1331 HEToSelect.insert(HEToSelect.end(), junction->getGNECrossings().begin(), junction->getGNECrossings().end());
1332 }
1333 }
1334 // lanes
1335 if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::LANE)) {
1336 HEToSelect.insert(HEToSelect.end(), HE->getChildLanes().begin(), HE->getChildLanes().end());
1337 }
1338 // additional
1339 if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::ADDITIONAL)) {
1340 // avoid insert symbols
1341 for (const auto& additionalChild : HE->getChildAdditionals()) {
1342 if (!additionalChild->getTagProperty().isWireElement() && !additionalChild->getTagProperty().isSymbol()) {
1343 HEToSelect.push_back(additionalChild);
1344 }
1345 }
1346 }
1347 // wire
1348 if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::WIRE)) {
1349 // avoid insert symbols
1350 for (const auto& wireChild : HE->getChildAdditionals()) {
1351 if (wireChild->getTagProperty().isWireElement() && !wireChild->getTagProperty().isSymbol()) {
1352 HEToSelect.push_back(wireChild);
1353 }
1354 }
1355 }
1356 // demand
1357 if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::DEMAND)) {
1358 HEToSelect.insert(HEToSelect.end(), HE->getChildDemandElements().begin(), HE->getChildDemandElements().end());
1359 }
1360 // data
1361 if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::DATA)) {
1362 HEToSelect.insert(HEToSelect.end(), HE->getChildGenericDatas().begin(), HE->getChildGenericDatas().end());
1363 }
1364 }
1365 // select HE
1366 if (HEToSelect.size() > 0) {
1367 if (HEToSelect.size() > 1) {
1368 mySelectorFrameParent->getViewNet()->getUndoList()->begin(GUIIcon::SELECT, "select children");
1369 }
1370 for (const auto& HE : HEToSelect) {
1371 if (obj == mySelectChildrenButton) {
1372 HE->setAttribute(GNE_ATTR_SELECTED, "true", mySelectorFrameParent->getViewNet()->getUndoList());
1373 } else {
1374 HE->setAttribute(GNE_ATTR_SELECTED, "false", mySelectorFrameParent->getViewNet()->getUndoList());
1375 }
1376 }
1377 if (HEToSelect.size() > 1) {
1378 mySelectorFrameParent->getViewNet()->getUndoList()->end();
1379 }
1380 }
1381 // update information label
1382 mySelectorFrameParent->mySelectionInformation->updateInformationLabel();
1383 // update viewNet
1384 mySelectorFrameParent->getViewNet()->update();
1385 }
1386 return 1;
1387}
1388
1389// ---------------------------------------------------------------------------
1390// GNECrossingFrame::Legend - methods
1391// ---------------------------------------------------------------------------
1392
1394 MFXGroupBoxModule(selectorFrameParent, TL("Information")) {
1395 // Create Selection Hint
1396 new FXLabel(getCollapsableFrame(), " - Hold <SHIFT> for \n rectangle selection.\n - Press <DEL> to\n delete selected objects.", nullptr, GUIDesignLabelFrameInformation);
1397}
1398
1399
1401
1402// ---------------------------------------------------------------------------
1403// GNESelectorFrame - methods
1404// ---------------------------------------------------------------------------
1405
1407 GNEFrame(viewParent, viewNet, "Selection") {
1408 // create selection information
1410 // create Modification Mode modul
1412 // create ElementSet modul
1416 // create VisualScaling modul
1417 myVisualScaling = new VisualScaling(this);
1418 // create SelectionOperation modul
1420 // create SelectionHierarchy modul
1422 // create Information modul
1423 myInformation = new Information(this);
1424}
1425
1426
1428
1429
1430void
1432 // refresh element set
1434 // only show network element set
1439 // only show demand element set
1444 // only show data element set
1448 }
1449 // update information label
1451 // Show frame
1453}
1454
1455
1456void
1458 // hide frame
1460}
1461
1462
1463void
1465 // update information label
1467}
1468
1469
1470void
1472 mySelectionOperation->onCmdClear(nullptr, 0, nullptr);
1473}
1474
1475
1476bool
1478 // get front AC
1479 auto AC = objectsUnderCursor.getAttributeCarrierFront();
1480 // check AC
1481 if (AC == nullptr) {
1482 return false;
1483 }
1484 // check locking
1485 if (myViewNet->getLockManager().isObjectLocked(AC->getGUIGlObject()->getType(), AC->isAttributeCarrierSelected())) {
1486 return false;
1487 }
1488 // check modes
1489 if ((AC->getTagProperty().isNetworkElement() || AC->getTagProperty().isAdditionalElement()) &&
1491 return false;
1492 }
1493 if (AC->getTagProperty().isDemandElement() && !myViewNet->getEditModes().isCurrentSupermodeDemand()) {
1494 return false;
1495 }
1496 if (AC->getTagProperty().isDataElement() && !myViewNet->getEditModes().isCurrentSupermodeData()) {
1497 return false;
1498 }
1499 // filter GLObjects by layer
1500 auto filteredGLObjects = GNEViewNetHelper::filterElementsByLayer(objectsUnderCursor.getClickedGLObjects());
1501 // check if we have to open dialog
1502 if (filteredGLObjects.size() > 1) {
1503 myViewNet->openSelectDialogAtCursor(filteredGLObjects);
1504 } else {
1505 // toggle selection
1506 if (AC->isAttributeCarrierSelected()) {
1507 AC->unselectAttributeCarrier();
1508 } else {
1509 AC->selectAttributeCarrier();
1510 }
1511 // update information label
1513 }
1514 return true;
1515}
1516
1517
1518void
1519GNESelectorFrame::handleIDs(const std::vector<GNEAttributeCarrier*>& ACs, const ModificationMode::Operation setop) {
1520 // declare set operation
1522 // declare two sets of attribute carriers, one for select and another for unselect
1523 std::set<std::pair<std::string, GNEAttributeCarrier*> > ACsToSelect, ACsToUnselect;
1524 // in restrict AND replace mode all current selected attribute carriers will be unselected
1525 if ((setOperation == ModificationMode::Operation::REPLACE) || (setOperation == ModificationMode::Operation::RESTRICT)) {
1526 // obtain selected ACs depending of current supermode
1527 std::vector<GNEAttributeCarrier*> selectedACs = myViewNet->getNet()->getAttributeCarriers()->getSelectedAttributeCarriers(false);
1528 // add id into ACs to unselect
1529 for (const auto& selectedAC : selectedACs) {
1530 ACsToUnselect.insert(std::make_pair(selectedAC->getID(), selectedAC));
1531 }
1532 }
1533 // handle ids
1534 for (const auto& AC : ACs) {
1535 // iterate over AtributeCarriers an place it in ACsToSelect or ACsToUnselect
1536 switch (setOperation) {
1538 ACsToUnselect.insert(std::make_pair(AC->getID(), AC));
1539 break;
1541 if (ACsToUnselect.find(std::make_pair(AC->getID(), AC)) != ACsToUnselect.end()) {
1542 ACsToSelect.insert(std::make_pair(AC->getID(), AC));
1543 }
1544 break;
1545 default:
1546 ACsToSelect.insert(std::make_pair(AC->getID(), AC));
1547 break;
1548 }
1549 }
1550 // select junctions and their connections if Auto select junctions is enabled (note: only for "add mode")
1552 std::set<GNEEdge*> edgesToSelect;
1553 // iterate over ACsToSelect and extract edges
1554 for (const auto& AC : ACsToSelect) {
1555 if (AC.second->getTagProperty().getTag() == SUMO_TAG_EDGE) {
1556 edgesToSelect.insert(myViewNet->getNet()->getAttributeCarriers()->retrieveEdge(AC.second->getID()));
1557 }
1558 }
1559 // iterate over extracted edges
1560 for (const auto& edgeToSelect : edgesToSelect) {
1561 // select junction source and all connections, crossings and walkingAreas
1562 ACsToSelect.insert(std::make_pair(edgeToSelect->getFromJunction()->getID(), edgeToSelect->getFromJunction()));
1563 for (const auto& connectionToSelect : edgeToSelect->getFromJunction()->getGNEConnections()) {
1564 ACsToSelect.insert(std::make_pair(connectionToSelect->getID(), connectionToSelect));
1565 }
1566 for (const auto& fromCrossingToSelect : edgeToSelect->getFromJunction()->getGNECrossings()) {
1567 ACsToSelect.insert(std::make_pair(fromCrossingToSelect->getID(), fromCrossingToSelect));
1568 }
1569 for (const auto& fromWalkingAreaToSelect : edgeToSelect->getFromJunction()->getGNEWalkingAreas()) {
1570 ACsToSelect.insert(std::make_pair(fromWalkingAreaToSelect->getID(), fromWalkingAreaToSelect));
1571 }
1572 // select junction destiny and all connections, crossings and walkingAreas
1573 ACsToSelect.insert(std::make_pair(edgeToSelect->getToJunction()->getID(), edgeToSelect->getToJunction()));
1574 for (const auto& connectionToSelect : edgeToSelect->getToJunction()->getGNEConnections()) {
1575 ACsToSelect.insert(std::make_pair(connectionToSelect->getID(), connectionToSelect));
1576 }
1577 for (const auto& toCrossingToSelect : edgeToSelect->getToJunction()->getGNECrossings()) {
1578 ACsToSelect.insert(std::make_pair(toCrossingToSelect->getID(), toCrossingToSelect));
1579 }
1580 for (const auto& toWalkingAreaToSelect : edgeToSelect->getToJunction()->getGNEWalkingAreas()) {
1581 ACsToSelect.insert(std::make_pair(toWalkingAreaToSelect->getID(), toWalkingAreaToSelect));
1582 }
1583 }
1584 }
1585 // only continue if there is ACs to select or unselect
1586 if ((ACsToSelect.size() + ACsToUnselect.size()) > 0) {
1587 // first unselect AC of ACsToUnselect and then selects AC of ACsToSelect
1589 for (const auto& ACToUnselect : ACsToUnselect) {
1590 if (ACToUnselect.second->getTagProperty().isSelectable()) {
1591 ACToUnselect.second->setAttribute(GNE_ATTR_SELECTED, "false", myViewNet->getUndoList());
1592 }
1593 }
1594 for (const auto& ACToSelect : ACsToSelect) {
1595 if (ACToSelect.second->getTagProperty().isSelectable()) {
1596 ACToSelect.second->setAttribute(GNE_ATTR_SELECTED, "true", myViewNet->getUndoList());
1597 }
1598 }
1599 // finish operation
1601 }
1602}
1603
1604
1605std::vector<GNEAttributeCarrier*>
1606GNESelectorFrame::getMatches(const SumoXMLTag ACTag, const SumoXMLAttr ACAttr, const char compOp, const double val, const std::string& expr) {
1607 std::vector<GNEAttributeCarrier*> result;
1608 // first retrieve all ACs using ACTag
1609 const auto allACbyTag = myViewNet->getNet()->getAttributeCarriers()->retrieveAttributeCarriers(ACTag);
1610 // get Tag value
1611 const auto& tagValue = GNEAttributeCarrier::getTagProperty(ACTag);
1612 // iterate over all ACs
1613 for (const auto& AC : allACbyTag) {
1614 if (expr == "" && compOp == '@') {
1615 result.push_back(AC);
1616 } else if (tagValue.hasAttribute(ACAttr) && tagValue.getAttributeProperties(ACAttr).isNumerical()) {
1617 double acVal;
1618 std::istringstream buf(AC->getAttribute(ACAttr));
1619 buf >> acVal;
1620 switch (compOp) {
1621 case '<':
1622 if (acVal < val) {
1623 result.push_back(AC);
1624 }
1625 break;
1626 case '>':
1627 if (acVal > val) {
1628 result.push_back(AC);
1629 }
1630 break;
1631 case '=':
1632 if (acVal == val) {
1633 result.push_back(AC);
1634 }
1635 break;
1636 }
1637 } else {
1638 // string match
1639 std::string acVal = AC->getAttributeForSelection(ACAttr);
1640 switch (compOp) {
1641 case '@':
1642 if (acVal.find(expr) != std::string::npos) {
1643 result.push_back(AC);
1644 }
1645 break;
1646 case '!':
1647 if (acVal.find(expr) == std::string::npos) {
1648 result.push_back(AC);
1649 }
1650 break;
1651 case '=':
1652 if (acVal == expr) {
1653 result.push_back(AC);
1654 }
1655 break;
1656 case '^':
1657 if (acVal != expr) {
1658 result.push_back(AC);
1659 }
1660 break;
1661 }
1662 }
1663 }
1664 return result;
1665}
1666
1667
1668std::vector<GNEAttributeCarrier*>
1669GNESelectorFrame::getGenericMatches(const std::vector<GNEGenericData*>& genericDatas, const std::string& attr, const char compOp, const double val, const std::string& expr) {
1670 std::vector<GNEAttributeCarrier*> result;
1671 // iterate over generic datas
1672 for (const auto& genericData : genericDatas) {
1673 if (expr == "" && compOp == '@') {
1674 result.push_back(genericData);
1675 } else if (attr != toString(GNE_ATTR_PARENT)) {
1676 double acVal;
1677 std::istringstream buf(genericData->getParameter(attr, "0"));
1678 buf >> acVal;
1679 switch (compOp) {
1680 case '<':
1681 if (acVal < val) {
1682 result.push_back(genericData);
1683 }
1684 break;
1685 case '>':
1686 if (acVal > val) {
1687 result.push_back(genericData);
1688 }
1689 break;
1690 case '=':
1691 if (acVal == val) {
1692 result.push_back(genericData);
1693 }
1694 break;
1695 }
1696 } else {
1697 // string match
1698 std::string acVal = genericData->getAttributeForSelection(GNE_ATTR_PARENT);
1699 switch (compOp) {
1700 case '@':
1701 if (acVal.find(expr) != std::string::npos) {
1702 result.push_back(genericData);
1703 }
1704 break;
1705 case '!':
1706 if (acVal.find(expr) == std::string::npos) {
1707 result.push_back(genericData);
1708 }
1709 break;
1710 case '=':
1711 if (acVal == expr) {
1712 result.push_back(genericData);
1713 }
1714 break;
1715 case '^':
1716 if (acVal != expr) {
1717 result.push_back(genericData);
1718 }
1719 break;
1720 }
1721 }
1722 }
1723 return result;
1724}
1725
1726
1727FXVerticalFrame*
1729 return myContentFrame;
1730}
1731
1732
1735 return myModificationMode;
1736}
1737
1738
1742}
1743
1744/****************************************************************************/
FXDEFMAP(GNESelectorFrame::ModificationMode) ModificationModeMap[]
@ NETWORK
Network mode (Edges, junctions, etc..)
@ DATA
Data mode (edgeData, LaneData etc..)
@ DEMAND
Demand mode (Routes, Vehicles etc..)
@ MID_GNE_SELECTORFRAME_SELECTSCALE
changes the visual scaling of selected items
Definition: GUIAppEnum.h:970
@ MID_GNE_SELECTORFRAME_CHILDREN
select/unselect children
Definition: GUIAppEnum.h:984
@ MID_CHOOSEN_SAVE
Save set.
Definition: GUIAppEnum.h:594
@ MID_CHOOSEN_INVERT
Deselect selected items.
Definition: GUIAppEnum.h:606
@ MID_CHOOSEN_DELETE
delete set
Definition: GUIAppEnum.h:598
@ MID_CHOOSEN_OPERATION
set type of selection
Definition: GUIAppEnum.h:588
@ MID_CHOOSEN_LOAD
Load set.
Definition: GUIAppEnum.h:592
@ MID_CHOOSEN_REDUCE
simplify network reduction
Definition: GUIAppEnum.h:610
@ MID_CHOOSEN_CLEAR
Clear set.
Definition: GUIAppEnum.h:596
@ MID_GNE_SELECT
select element
Definition: GUIAppEnum.h:886
@ MID_GNE_SELECTORFRAME_PARENTS
select/unselect parents
Definition: GUIAppEnum.h:982
#define GUIDesignSpinDial
Definition: GUIDesigns.h:474
#define GUIDesignButton
Definition: GUIDesigns.h:77
#define GUIDesignComboBox
Definition: GUIDesigns.h:306
#define GUIDesignComboBoxNCol
number of column of every combo box
Definition: GUIDesigns.h:321
#define GUIDesignAuxiliarHorizontalFrame
design for auxiliar (Without borders) horizontal frame used to pack another frames
Definition: GUIDesigns.h:397
#define GUIDesignLabelThickCenter
label with thick, text justify to left and extended with (used in selector frame)
Definition: GUIDesigns.h:265
#define GUIDesignRadioButton
Definition: GUIDesigns.h:203
#define GUIDesignLabelFrameInformation
label extended over frame without thick and with text justify to left, used to show information in fr...
Definition: GUIDesigns.h:271
@ GLO_EDGERELDATA
edge relation data
@ GLO_TAZRELDATA
TAZ relation data.
@ GLO_WALKINGAREA
a walkingArea
@ GLO_TRANSHIP
a container tranship
@ GLO_ROUTE
a route
@ GLO_WIRE
reserved GLO type for packing all wire elements
@ GLO_JUNCTION
a junction
@ GLO_LANE
a lane
@ GLO_TAZ
Traffic Assignment Zones (TAZs)
@ GLO_CONTAINER
a container
@ GLO_EDGEDATA
edge data
@ GLO_CONNECTION
a connection
@ GLO_ADDITIONALELEMENT
reserved GLO type for packing all additionals elements
@ GLO_PERSONTRIP
a person trip
@ GLO_EDGE
an edge
@ GLO_VEHICLE
a vehicle
@ GLO_PERSON
a person
@ GLO_TRANSPORT
a container transport
@ GLO_POI
a poi
@ GLO_STOP
a stop
@ GLO_POLYGON
a polygon
@ GLO_CROSSING
a tl-logic
FXString gCurrentFolder
The folder used as last.
@ SIMPLIFYNETWORK
#define WRITE_DEBUG(msg)
Definition: MsgHandler.h:276
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:274
#define TL(string)
Definition: MsgHandler.h:282
SumoXMLTag
Numbers representing SUMO-XML - element names.
@ GNE_TAG_TRIP_JUNCTIONS
a trip between junctions (used in NETEDIT)
@ SUMO_TAG_TAZ
a traffic assignment zone
@ SUMO_TAG_CONTAINERFLOW
@ SUMO_TAG_TAZSINK
a sink within a district (connection road)
@ SUMO_TAG_POI
begin/end of the description of a Point of interest
@ SUMO_TAG_VEHICLE
description of a vehicle
@ GNE_TAG_FLOW_ROUTE
a flow definition using a route instead of a from-to edges route (used in NETEDIT)
@ GNE_TAG_FLOW_JUNCTIONS
a flow between junctions (used in NETEDIT)
@ GNE_TAG_POIGEO
Point of interest over view with GEO attributes.
@ GNE_TAG_FLOW_WITHROUTE
description of a vehicle with an embedded route (used in NETEDIT)
@ SUMO_TAG_FLOW
a flow definitio nusing a from-to edges instead of a route (used by router)
@ SUMO_TAG_CONTAINER
@ SUMO_TAG_JUNCTION
begin/end of the description of a junction
@ SUMO_TAG_ROUTE
begin/end of the description of a route
@ SUMO_TAG_MEANDATA_EDGE
an edge based mean data detector
@ SUMO_TAG_POLY
begin/end of the description of a polygon
@ SUMO_TAG_LANE
begin/end of the description of a single lane
@ GNE_TAG_VEHICLE_WITHROUTE
description of a vehicle with an embedded route (used in NETEDIT)
@ GNE_TAG_POILANE
Point of interest over Lane.
@ SUMO_TAG_PERSON
@ SUMO_TAG_TAZSOURCE
a source within a district (connection road)
@ SUMO_TAG_PERSONFLOW
@ SUMO_TAG_TRIP
a single trip definition (used by router)
@ SUMO_TAG_EDGE
begin/end of the description of an edge
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
@ SUMO_ATTR_SPEED
@ SUMO_ATTR_FROM_LANE
@ GNE_ATTR_PARENT
parent of an additional element
@ GNE_ATTR_SELECTED
element is selected
@ GNE_ATTR_PARAMETERS
parameters "key1=value1|key2=value2|...|keyN=valueN"
@ SUMO_ATTR_INDEX
@ SUMO_ATTR_ID
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
const std::string getID() const
get ID (all Attribute Carriers have one)
const GNETagProperties & getTagProperty() const
get tagProperty associated with this Attribute Carrier
bool isTemplate() const
check if this AC is template
virtual GUIGlObject * getGUIGlObject()=0
A road/street connecting two junctions (netedit-version)
Definition: GNEEdge.h:53
void hideElementSet()
hide element set
void showElementSet()
show element set
GNEViewNet * myViewNet
FOX need this.
Definition: GNEFrame.h:117
FXVerticalFrame * myContentFrame
Vertical frame that holds all widgets of frame.
Definition: GNEFrame.h:120
virtual void show()
show Frame
Definition: GNEFrame.cpp:115
virtual void hide()
hide Frame
Definition: GNEFrame.cpp:124
void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
std::vector< GNEConnection * > getGNEConnections() const
Returns all GNEConnections vinculated with this junction.
This lane is powered by an underlying GNEEdge and basically knows how to draw itself.
Definition: GNELane.h:46
std::vector< GNEAttributeCarrier * > retrieveAttributeCarriers(SumoXMLTag tag=SUMO_TAG_NOTHING)
get the attribute carriers based on Type
GNEEdge * retrieveEdge(const std::string &id, bool hardFail=true) const
get edge by id
std::vector< GNEAttributeCarrier * > getSelectedAttributeCarriers(const bool ignoreCurrentSupermode)
get all selected attribute carriers (or only relative to current supermode
GNENetHelper::AttributeCarriers * getAttributeCarriers() const
get all attribute carriers used in this net
Definition: GNENet.cpp:132
Information(GNESelectorFrame *selectorFrameParent)
constructor
FXRadioButton * myReplaceRadioButton
replace radio button
ModificationMode(GNESelectorFrame *selectorFrameParent)
constructor
long onCmdSelectModificationMode(FXObject *, FXSelector, void *)
FXRadioButton * myAddRadioButton
FOX need this.
Operation getModificationMode() const
get current modification mode
FXRadioButton * myRemoveRadioButton
remove radio button
FXRadioButton * myKeepRadioButton
keep button
FXComboBox * myParentsComboBox
comboBox for parents
SelectionHierarchy(GNESelectorFrame *selectorFrameParent)
FOX-declaration.
FXButton * myUnselectParentsButton
unselect parents button
FXButton * mySelectParentsButton
select parents button
FXButton * myUnselectChildrenButton
unselect parents button
long onCmdParents(FXObject *obj, FXSelector, void *)
called when user press select/unselect parents button
long onCmdChildren(FXObject *obj, FXSelector, void *)
called when user press select/unselect children button
long onCmdSelectItem(FXObject *obj, FXSelector, void *)
called when user select an item in comboBox
FXComboBox * myChildrenComboBox
comboBox for children
const std::vector< std::pair< Selection, std::string > > myItems
FXButton * mySelectChildrenButton
select children button
void updateInformationLabel()
update information label
SelectionOperation(GNESelectorFrame *selectorFrameParent)
FOX-declaration.
long onCmdSave(FXObject *, FXSelector, void *)
Called when the user presses the Save-button.
bool processDataElementSelection(const bool onlyCount, const bool onlyUnselect, bool &ignoreLocking)
process data element selection
bool askContinueIfLock() const
ask if continue due locking
long onCmdDelete(FXObject *, FXSelector, void *)
Called when the user presses the delete-button.
long onCmdReduce(FXObject *, FXSelector, void *)
Called when the user presses the Reduce-button.
long onCmdInvert(FXObject *, FXSelector, void *)
Called when the user presses the Invert-button.
long onCmdClear(FXObject *, FXSelector, void *)
Called when the user presses the Clear-button.
long onCmdLoad(FXObject *, FXSelector, void *)
Called when the user presses the Load-button.
bool processDemandElementSelection(const bool onlyCount, const bool onlyUnselect, bool &ignoreLocking)
process demand element selection
bool processNetworkElementSelection(const bool onlyCount, const bool onlyUnselect, bool &ignoreLocking)
FOX need this.
long onCmdScaleSelection(FXObject *, FXSelector, void *)
Called when the user changes visual scaling.
VisualScaling(GNESelectorFrame *selectorFrameParent)
FOX-declaration.
FXRealSpinner * mySelectionScaling
Spinner for selection scaling.
FXVerticalFrame * getContentFrame() const
get vertical frame that holds all widgets of frame
std::vector< GNEAttributeCarrier * > getMatches(const SumoXMLTag ACTag, const SumoXMLAttr ACAttr, const char compOp, const double val, const std::string &expr)
return ACs of the given type with matching attrs
void updateFrameAfterUndoRedo()
function called after undo/redo in the current frame
std::vector< GNEAttributeCarrier * > getGenericMatches(const std::vector< GNEGenericData * > &genericDatas, const std::string &attr, const char compOp, const double val, const std::string &expr)
return GenericDatas of the given type with matching attrs
ModificationMode * getModificationModeModule() const
get modification mode modul
bool selectAttributeCarrier(const GNEViewNetHelper::ObjectsUnderCursor &objectsUnderCursor)
select attribute carrier (element)
void show()
show Frame
GNESelectorFrame::SelectionOperation * mySelectionOperation
modul for selection operations
~GNESelectorFrame()
Destructor.
GNESelectorFrame::SelectionInformation * mySelectionInformation
modul for selection information
GNESelectorFrame::VisualScaling * myVisualScaling
modul for visual scaling
GNEElementSet * myDemandElementSet
moduls for select demand element set
GNESelectorFrame::Information * myInformation
information modul
GNESelectorFrame::SelectionHierarchy * mySelectionHierarchy
modul for selection hierarchy
GNEElementSet * myNetworkElementSet
moduls for select network element set
GNEElementSet * myDataElementSet
moduls for select data element set
GNESelectorFrame::ModificationMode * myModificationMode
modul for change modification mode
void clearCurrentSelection() const
clear current selection with possibility of undo/redo
void hide()
hide Frame
void handleIDs(const std::vector< GNEAttributeCarrier * > &ACs, const ModificationMode::Operation setop=ModificationMode::Operation::DEFAULT)
apply list of ids to the current selection according to Operation,
GNESelectorFrame(GNEViewParent *viewParent, GNEViewNet *viewNet)
Constructor.
SelectionInformation * getSelectionInformation() const
get modul for selection information
bool isDataElement() const
return true if tag correspond to a data element
bool isSelectable() const
return true if tag correspond to a selectable element
bool isAdditionalPureElement() const
return true if tag correspond to a pure additional element
bool isWireElement() const
return true if tag correspond to a Wire element
bool isDemandElement() const
return true if tag correspond to a demand element
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...
bool isObjectLocked(GUIGlObjectType objectType, const bool selected) const
check if given GLObject is locked for inspect, select, delete and move
class used to group all variables related with objects under cursor after a click over view
const std::vector< GUIGlObject * > & getClickedGLObjects() const
get vector with clicked GL objects
GNEAttributeCarrier * getAttributeCarrierFront() const
get front attribute carrier or a pointer to nullptr
GNENet * getNet() const
get the net object
const GNEViewNetHelper::EditModes & getEditModes() const
get edit modes
Definition: GNEViewNet.cpp:632
void openSelectDialogAtCursor(const std::vector< GUIGlObject * > &GLObjects)
open select dialog at cursor
Definition: GNEViewNet.cpp:589
bool autoSelectNodes()
whether to autoselect nodes or to lanes
Definition: GNEViewNet.cpp:780
GNEUndoList * getUndoList() const
get the undoList object
GNEViewNetHelper::LockManager & getLockManager()
get lock manager
A single child window which contains a view of the simulation area.
Definition: GNEViewParent.h:84
static StringBijection< GUIGlObjectType > TypeNames
associates object types with strings
Definition: GUIGlObject.h:70
GUIGlObjectType getType() const
Returns the type of the object as coded in GUIGlObjectType.
Definition: GUIGlObject.h:154
const std::vector< GUIGlObject * > & getAllGLObjects() const
Returns the set of all known objects.
static GUIGlObjectStorage gIDStorage
A single static instance of this class.
static FXIcon * getIcon(const GUIIcon which)
returns a icon previously defined in the enum GUIIcon
MFXGroupBoxModule (based on FXGroupBox)
FXVerticalFrame * getCollapsableFrame()
get collapsable frame (used by all elements that will be collapsed if button is toggled)
void setText(const std::string &text)
set text
static FXString getFilename2Write(FXWindow *parent, const FXString &header, const FXString &extension, FXIcon *icon, FXString &currentFolder)
Returns the file name to write.
Definition: MFXUtils.cpp:82
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:61
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.
C++ TraCI client API implementation.
const std::string & getString(const T key) const
bool isCurrentSupermodeDemand() const
@check if current supermode is Demand
bool isCurrentSupermodeData() const
@check if current supermode is Data
bool isCurrentSupermodeNetwork() const
@check if current supermode is Network
static std::vector< GUIGlObject * > filterElementsByLayer(const std::vector< GUIGlObject * > &GLObjects)
filter elements based on the layer