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