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-2026 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
22#include <netedit/GNENet.h>
24#include <netedit/GNEUndoList.h>
25#include <netedit/GNEViewNet.h>
36
37#include "GNEMatchAttribute.h"
38#include "GNESelectorFrame.h"
39
40// ===========================================================================
41// FOX callback mapping
42// ===========================================================================
43
47
51
60
66
67// Object implementation
68FXIMPLEMENT(GNESelectorFrame::ModificationMode, GNEGroupBoxModule, ModificationModeMap, ARRAYNUMBER(ModificationModeMap))
69FXIMPLEMENT(GNESelectorFrame::VisualScaling, GNEGroupBoxModule, VisualScalingMap, ARRAYNUMBER(VisualScalingMap))
70FXIMPLEMENT(GNESelectorFrame::SelectionOperation, GNEGroupBoxModule, SelectionOperationMap, ARRAYNUMBER(SelectionOperationMap))
71FXIMPLEMENT(GNESelectorFrame::SelectionHierarchy, GNEGroupBoxModule, SelectionHierarchyMap, ARRAYNUMBER(SelectionHierarchyMap))
72
73// ===========================================================================
74// method definitions
75// ===========================================================================
76
77// ---------------------------------------------------------------------------
78// ModificationMode::SelectionInformation - methods
79// ---------------------------------------------------------------------------
80
82 GNEGroupBoxModule(selectorFrameParent, TL("Selection information")),
83 mySelectorFrameParent(selectorFrameParent) {
84 // information label
85 myInformationLabel = new FXLabel(getCollapsableFrame(), "", nullptr, GUIDesignLabelFrameInformation);
86}
87
88
90
91
92void
94 // first clear information
95 myInformation.clear();
96 // get attribute carriers
97 const auto ACs = mySelectorFrameParent->getViewNet()->getNet()->getAttributeCarriers();
98 // continue depending of supermode
99 if (mySelectorFrameParent->getViewNet()->getEditModes().isCurrentSupermodeNetwork()) {
100 updateInformationLabel(TL("Junctions"), ACs->getNumberOfSelectedJunctions());
101 updateInformationLabel(TL("Edges"), ACs->getNumberOfSelectedEdges());
102 updateInformationLabel(TL("Lanes"), ACs->getNumberOfSelectedLanes());
103 updateInformationLabel(TL("Connections"), ACs->getNumberOfSelectedConnections());
104 updateInformationLabel(TL("Crossings"), ACs->getNumberOfSelectedCrossings());
105 updateInformationLabel(TL("WalkingAreas"), ACs->getNumberOfSelectedWalkingAreas());
106 updateInformationLabel(TL("Additionals"), ACs->getNumberOfSelectedPureAdditionals());
107 updateInformationLabel(TL("Wires"), ACs->getNumberOfSelectedWires());
108 updateInformationLabel(TL("TAZs"), ACs->getNumberOfSelectedTAZs());
109 updateInformationLabel(TL("Polygons"), ACs->getNumberOfSelectedPolygons());
110 updateInformationLabel(TL("POIs"), ACs->getNumberOfSelectedPOIs());
111 updateInformationLabel(TL("JuPedSim elements"),
112 ACs->getNumberOfSelectedJpsWalkableAreas() +
113 ACs->getNumberOfSelectedJpsObstacles());
114 } else if (mySelectorFrameParent->getViewNet()->getEditModes().isCurrentSupermodeDemand()) {
115 updateInformationLabel(TL("Routes"), ACs->getNumberOfSelectedRoutes());
116 updateInformationLabel(TL("Vehicles"), ACs->getNumberOfSelectedVehicles());
117 updateInformationLabel(TL("Persons"), ACs->getNumberOfSelectedPersons());
118 updateInformationLabel(TL("Person trips"), ACs->getNumberOfSelectedPersonTrips());
119 updateInformationLabel(TL("Walks"), ACs->getNumberOfSelectedWalks());
120 updateInformationLabel(TL("Rides"), ACs->getNumberOfSelectedRides());
121 updateInformationLabel(TL("Containers"), ACs->getNumberOfSelectedContainers());
122 updateInformationLabel(TL("Transport"), ACs->getNumberOfSelectedTransport());
123 updateInformationLabel(TL("Tranships"), ACs->getNumberOfSelectedTranships());
124 updateInformationLabel(TL("Stops"), ACs->getNumberOfSelectedStops());
125 } else if (mySelectorFrameParent->getViewNet()->getEditModes().isCurrentSupermodeData()) {
126 updateInformationLabel(TL("EdgeDatas"), ACs->getNumberOfSelectedEdgeDatas());
127 updateInformationLabel(TL("EdgeRelDatas"), ACs->getNumberOfSelectedEdgeRelDatas());
128 updateInformationLabel(TL("EdgeTAZRel"), ACs->getNumberOfSelectedEdgeTAZRel());
129 }
130 // adjust format
131 const auto numberLines = std::count(myInformation.begin(), myInformation.end(), ':');
132 if (numberLines == 0) {
133 myInformation.append(" \n \n");
134 } else if (numberLines > 1) {
135 myInformation.pop_back();
136 }
137 // set label
138 myInformationLabel->setText(myInformation.c_str());
139}
140
141
142void
144 // check number
145 if (number > 0) {
146 myInformation.append(element + ": " + toString(number) + "\n");
147 }
148}
149
150// ---------------------------------------------------------------------------
151// ModificationMode::ModificationMode - methods
152// ---------------------------------------------------------------------------
153
155 GNEGroupBoxModule(selectorFrameParent, TL("Modification Mode")),
156 myModificationModeType(Operation::ADD) {
157 // Create all options buttons
158 myAddRadioButton = GUIDesigns::buildFXRadioButton(getCollapsableFrame(), TL("add"), "", TL("Selected objects are added to the previous selection"),
160 myRemoveRadioButton = GUIDesigns::buildFXRadioButton(getCollapsableFrame(), TL("remove"), "", TL("Selected objects are removed from the previous selection"),
162 myKeepRadioButton = GUIDesigns::buildFXRadioButton(getCollapsableFrame(), TL("keep"), "", TL("Restrict previous selection by the current selection"),
164 myReplaceRadioButton = GUIDesigns::buildFXRadioButton(getCollapsableFrame(), TL("replace"), "", TL("Replace previous selection by the current selection"),
166 myAddRadioButton->setCheck(true);
167}
168
169
171
172
175 return myModificationModeType;
176}
177
178
179long
181 if (obj == myAddRadioButton) {
182 myModificationModeType = Operation::ADD;
183 myAddRadioButton->setCheck(true);
184 myRemoveRadioButton->setCheck(false);
185 myKeepRadioButton->setCheck(false);
186 myReplaceRadioButton->setCheck(false);
187 return 1;
188 } else if (obj == myRemoveRadioButton) {
189 myModificationModeType = Operation::SUB;
190 myAddRadioButton->setCheck(false);
191 myRemoveRadioButton->setCheck(true);
192 myKeepRadioButton->setCheck(false);
193 myReplaceRadioButton->setCheck(false);
194 return 1;
195 } else if (obj == myKeepRadioButton) {
196 myModificationModeType = Operation::RESTRICT;
197 myAddRadioButton->setCheck(false);
198 myRemoveRadioButton->setCheck(false);
199 myKeepRadioButton->setCheck(true);
200 myReplaceRadioButton->setCheck(false);
201 return 1;
202 } else if (obj == myReplaceRadioButton) {
203 myModificationModeType = Operation::REPLACE;
204 myAddRadioButton->setCheck(false);
205 myRemoveRadioButton->setCheck(false);
206 myKeepRadioButton->setCheck(false);
207 myReplaceRadioButton->setCheck(true);
208 return 1;
209 } else {
210 return 0;
211 }
212}
213
214// ---------------------------------------------------------------------------
215// ModificationMode::VisualScaling - methods
216// ---------------------------------------------------------------------------
217
219 GNEGroupBoxModule(selectorFrameParent, TL("Visual Scaling")),
220 mySelectorFrameParent(selectorFrameParent) {
221 // Create spin button and configure it
223 //mySelectionScaling->setNumberFormat(1);
224 //mySelectionScaling->setIncrements(0.1, .5, 1);
225 mySelectionScaling->setIncrement(0.5);
226 mySelectionScaling->setRange(1, 100000);
227 mySelectionScaling->setValue(1);
228 mySelectionScaling->setHelpText(TL("Enlarge selected objects"));
229}
230
231
233
234
235long
237 // set scale in viewnet
238 mySelectorFrameParent->myViewNet->setSelectorFrameScale(mySelectionScaling->getValue());
239 mySelectorFrameParent->myViewNet->updateViewNet();
240 return 1;
241}
242
243// ---------------------------------------------------------------------------
244// ModificationMode::SelectionHierarchy - methods
245// ---------------------------------------------------------------------------
246
248 GNEGroupBoxModule(selectorFrameParent, TL("Selection operations")),
249 mySelectorFrameParent(selectorFrameParent) {
250 // tabular buttons, see GNETLSEditorFrame
251
252 FXHorizontalFrame* selectionButtons = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame);
253 FXVerticalFrame* col1 = new FXVerticalFrame(selectionButtons, LAYOUT_FILL_X, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); // left button columm
254 FXVerticalFrame* col2 = new FXVerticalFrame(selectionButtons, LAYOUT_FILL_X, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); // right button column
255
256 // Create "Clear List" Button
257 GUIDesigns::buildFXButton(col1, TL("Clear"), "", TL("Deselect all objects (hotkey: ESC)"), nullptr, this, MID_CHOOSEN_CLEAR, GUIDesignButton);
258 // Create "Invert" Button
259 GUIDesigns::buildFXButton(col2, TL("Invert"), "", TL("Invert selection status of all objects"), nullptr, this, MID_CHOOSEN_INVERT, GUIDesignButton);
260 // Create "Save" Button
261 GUIDesigns::buildFXButton(col1, TL("Save"), "", TL("Save ids of currently selected objects to a file."), nullptr, this, MID_CHOOSEN_SAVE, GUIDesignButton);
262 // Create "Load" Button
263 GUIDesigns::buildFXButton(col2, TL("Load"), "", TL("Load ids from a file according to the current modification mode."), nullptr, this, MID_CHOOSEN_LOAD, GUIDesignButton);
264 // Create "Delete" Button
265 GUIDesigns::buildFXButton(col1, TL("Delete"), "", TL("Delete all selected objects (hotkey: DEL)"), nullptr, this, MID_CHOOSEN_DELETE, GUIDesignButton);
266 // Create "reduce" Button
267 GUIDesigns::buildFXButton(col2, TL("Reduce"), "", TL("Reduce network to current selection."), nullptr, this, MID_CHOOSEN_REDUCE, GUIDesignButton);
268}
269
270
272
273
274void
276 std::vector<GNEAttributeCarrier*> loadedACs;
277 std::ifstream strm(file.c_str());
278 // check if file can be opened
279 if (!strm.good()) {
280 WRITE_ERRORF(TL("Could not open '%'."), file);
281 } else {
282 // convert all glObjects into GNEAttributeCarriers
283 std::map<const std::string, GNEAttributeCarrier*> GLFUllNameAC;
284 const auto GLObjects = GUIGlObjectStorage::gIDStorage.getAllGLObjects();
285 for (const auto& GLObject : GLObjects) {
286 // try to parse GLObject to AC
287 GNEAttributeCarrier* AC = dynamic_cast<GNEAttributeCarrier*>(GLObject);
288 // if was successfully parsed and is NOT a template, add into GLFUllNameAC using fullName
289 if (AC && !AC->isTemplate()) {
290 GLFUllNameAC[GUIGlObject::TypeNames.getString(GLObject->getType()) + ":" + AC->getID()] = AC;
291 }
292 }
293 // continue while stream exist
294 while (strm.good()) {
295 std::string line;
296 strm >> line;
297 // check if line isn't empty
298 if (line.length() != 0) {
299 // obtain AC from GLFUllNameAC
300 if (StringUtils::startsWith(line, "node:")) {
301 line = StringUtils::replace(line, "node:", "junction:");
302 }
303 GNEAttributeCarrier* AC = GLFUllNameAC.count(line) > 0 ? GLFUllNameAC.at(line) : nullptr;
304 // check if AC exist, is selectable, and isn't locked
305 if (AC && AC->getTagProperty()->isSelectable() && !mySelectorFrameParent->getViewNet()->getLockManager().isObjectLocked(AC->getGUIGlObject()->getType(), false)) {
306 // now check if we're in the correct supermode to load this element
307 if (((mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeNetwork()) && !AC->getTagProperty()->isDemandElement()) ||
308 ((mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeDemand()) && AC->getTagProperty()->isDemandElement()) ||
309 ((mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeData()) && AC->getTagProperty()->isDataElement())) {
310 loadedACs.push_back(AC);
311 }
312 }
313 }
314 }
315 // change selected attribute in loaded ACs allowing undo/redo
316 if (loadedACs.size() > 0) {
317 mySelectorFrameParent->myViewNet->getUndoList()->begin(GUIIcon::MODESELECT, TL("load selection"));
318 mySelectorFrameParent->handleIDs(loadedACs);
319 mySelectorFrameParent->myViewNet->getUndoList()->end();
320 }
321 }
322}
323
324
325long
327 // get the new file name
328 FXFileDialog opendialog(getCollapsableFrame(), TL("Open List of Selected Items"));
329 opendialog.setIcon(GUIIconSubSys::getIcon(GUIIcon::OPEN));
330 opendialog.setSelectMode(SELECTFILE_EXISTING);
331 opendialog.setPatternList(SUMOXMLDefinitions::TXTFileExtensions.getMultilineString().c_str());
332 if (gCurrentFolder.length() != 0) {
333 opendialog.setDirectory(gCurrentFolder);
334 }
335 if (opendialog.execute()) {
336 gCurrentFolder = opendialog.getDirectory();
337 loadFromFile(opendialog.getFilename().text());
338 }
339 return 1;
340}
341
342
343long
345 FXString file = MFXUtils::getFilename2Write(this, TL("Save List of selected Items"),
346 SUMOXMLDefinitions::TXTFileExtensions.getMultilineString().c_str(),
348 if (file == "") {
349 return 1;
350 }
351 try {
352 OutputDevice& dev = OutputDevice::getDevice(file.text());
353 // get selected attribute carriers
354 const auto selectedACs = mySelectorFrameParent->myViewNet->getNet()->getAttributeCarriers()->getSelectedAttributeCarriers(false);
355 for (const auto& selectedAC : selectedACs) {
356 GUIGlObject* object = dynamic_cast<GUIGlObject*>(selectedAC);
357 if (object) {
358 dev << GUIGlObject::TypeNames.getString(object->getType()) << ":" << selectedAC->getID() << "\n";
359 }
360 }
361 dev.close();
362 } catch (IOError& e) {
363 // open message box error
364 GNEErrorBasicDialog(mySelectorFrameParent->getViewNet()->getViewParent()->getGNEAppWindows(),
365 TL("Storing Selection failed"), e.what());
366 }
367 return 1;
368}
369
370
371long
373 const auto& editModes = mySelectorFrameParent->myViewNet->getEditModes();
374 GNEUndoList* undoList = mySelectorFrameParent->myViewNet->getUndoList();
375 // declare massive selection
376 MassiveSelection massiveSelection =
377 editModes.isCurrentSupermodeNetwork() ? processMassiveNetworkElementSelection(false) :
378 editModes.isCurrentSupermodeDemand() ? processMassiveDemandElementSelection() :
379 processMassiveDataElementSelection();
380 // only continue if there are elements to unselect
381 if (massiveSelection.isElementToProcess()) {
382 // check if add locked elements
383 bool askedContinueIfLock = false;
384 bool addLockedElements = false;
385 bool unlockedElements = false;
386 for (const auto& ACToUnselect : massiveSelection.ACsToUnselect) {
387 if (ACToUnselect.second == false) {
388 // there are unlocked elements
389 unlockedElements = true;
390 } else if (!askedContinueIfLock) {
391 addLockedElements = askContinueIfLock();
392 // only ask one time for locking
393 askedContinueIfLock = true;
394 }
395 }
396 if (unlockedElements || addLockedElements) {
397 mySelectorFrameParent->myViewNet->getUndoList()->begin(GUIIcon::MODESELECT, TL("clear selection"));
398 for (const auto& ACToUnselect : massiveSelection.ACsToUnselect) {
399 if (addLockedElements || !ACToUnselect.second) {
400 ACToUnselect.first->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
401 }
402 }
403 mySelectorFrameParent->myViewNet->getUndoList()->end();
404 }
405 }
406 mySelectorFrameParent->myViewNet->updateViewNet();
407 return 1;
408}
409
410long
412 // acts like the 'del' hotkey
413 mySelectorFrameParent->getViewNet()->hotkeyDel();
414 return 1;
415}
416
417
418long
420 const auto& editModes = mySelectorFrameParent->myViewNet->getEditModes();
421 GNEUndoList* undoList = mySelectorFrameParent->myViewNet->getUndoList();
422 // declare massive selection
423 MassiveSelection massiveSelection =
424 editModes.isCurrentSupermodeNetwork() ? processMassiveNetworkElementSelection(true) :
425 editModes.isCurrentSupermodeDemand() ? processMassiveDemandElementSelection() :
426 processMassiveDataElementSelection();
427 // only continue if there are elements to select and unselect
428 if (massiveSelection.isElementToProcess()) {
429 // check if add locked elements
430 bool askedContinueIfLock = false;
431 bool addLockedElements = false;
432 bool unlockedElements = false;
433 for (const auto& ACToSelect : massiveSelection.ACsToSelect) {
434 if (ACToSelect.second == false) {
435 // there are unlocked elements
436 unlockedElements = true;
437 } else if (!askedContinueIfLock) {
438 addLockedElements = askContinueIfLock();
439 // only ask one time for locking
440 askedContinueIfLock = true;
441 }
442 }
443 for (const auto& ACToUnselect : massiveSelection.ACsToUnselect) {
444 if (ACToUnselect.second == false) {
445 // there are unlocked elements
446 unlockedElements = true;
447 } else if (!askedContinueIfLock) {
448 addLockedElements = askContinueIfLock();
449 // only ask one time for locking
450 askedContinueIfLock = true;
451 }
452 }
453 if (unlockedElements || addLockedElements) {
454 mySelectorFrameParent->myViewNet->getUndoList()->begin(GUIIcon::MODESELECT, TL("invert selection"));
455 for (const auto& ACToSelect : massiveSelection.ACsToSelect) {
456 if (addLockedElements || !ACToSelect.second) {
457 ACToSelect.first->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
458 }
459 }
460 for (const auto& ACToUnselect : massiveSelection.ACsToUnselect) {
461 if (addLockedElements || !ACToUnselect.second) {
462 ACToUnselect.first->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
463 }
464 }
465 mySelectorFrameParent->myViewNet->getUndoList()->end();
466 }
467 }
468 return 1;
469}
470
471
472long
474 // begin undoList operation
475 mySelectorFrameParent->getViewNet()->getUndoList()->begin(Supermode::NETWORK, GUIIcon::SIMPLIFYNETWORK, TL("reduce network"));
476 // invert and clear
477 if (mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeNetwork()) {
478 // special case for network elements. we take only the junction and edges
479 std::unordered_set<GNENetworkElement*> networkElementsToRemove;
480 std::unordered_set<GNENetworkElement*> edgesToKeep;
481 // add non selected junction and edges
482 for (const auto& junction : mySelectorFrameParent->myViewNet->getNet()->getAttributeCarriers()->getJunctions()) {
483 if (!junction.second->isAttributeCarrierSelected()) {
484 networkElementsToRemove.insert(junction.second);
485 }
486 // due we iterate over all junctions, only it's necessary iterate over incoming edges
487 for (const auto& incomingEdge : junction.second->getGNEIncomingEdges()) {
488 if (!incomingEdge->isAttributeCarrierSelected()) {
489 networkElementsToRemove.insert(incomingEdge);
490 } else {
491 edgesToKeep.insert(incomingEdge);
492 }
493 }
494 }
495 // now special case: we need to save all junctions related with the edges to keep
496 for (const auto& edge : edgesToKeep) {
497 for (const auto& junctionParent : edge->getParentJunctions()) {
498 auto it = networkElementsToRemove.find(junctionParent);
499 if (it != networkElementsToRemove.end()) {
500 networkElementsToRemove.erase(it);
501 }
502 }
503 }
504 // also remove shape elements that aren't selected
505 const auto shapeElementsToRemove = mySelectorFrameParent->myViewNet->getNet()->getAttributeCarriers()->getUnselectedShapes();
506 // remove elements (first start with shapes due POILanes)
507 for (const auto shapeElement : shapeElementsToRemove) {
508 mySelectorFrameParent->getViewNet()->getNet()->deleteAdditional(shapeElement, mySelectorFrameParent->getViewNet()->getUndoList());
509 }
510 for (const auto networkElement : networkElementsToRemove) {
511 mySelectorFrameParent->getViewNet()->getNet()->deleteNetworkElement(networkElement, mySelectorFrameParent->getViewNet()->getUndoList());
512 }
513 } else {
514 onCmdInvert(0, 0, 0);
515 onCmdDelete(0, 0, 0);
516 }
517 // end undoList operation
518 mySelectorFrameParent->getViewNet()->getUndoList()->end();
519 return 1;
520}
521
522
525 const auto& ACs = mySelectorFrameParent->myViewNet->getNet()->getAttributeCarriers();
526 const bool selectEdges = mySelectorFrameParent->getViewNet()->getNetworkViewOptions().selectEdges();
527 // extract all network elements
528 std::unordered_set<GNEAttributeCarrier*> networkACs;
529 // add junctions
530 for (const auto& junction : ACs->getJunctions()) {
531 networkACs.insert(junction.second);
532 // due we iterate over all junctions, only it's necessary iterate over incoming edges
533 for (const auto& incomingEdge : junction.second->getGNEIncomingEdges()) {
534 if (!filterLanes || selectEdges) {
535 networkACs.insert(incomingEdge);
536 }
537 // add lanes
538 if (!filterLanes || !selectEdges) {
539 for (const auto& lane : incomingEdge->getChildLanes()) {
540 networkACs.insert(lane);
541 }
542 }
543 // add connections
544 for (const auto& connection : incomingEdge->getGNEConnections()) {
545 networkACs.insert(connection);
546 }
547 }
548 // add crossings
549 for (const auto& crossing : junction.second->getGNECrossings()) {
550 networkACs.insert(crossing);
551 }
552 // add walkingArea
553 for (const auto& walkingArea : junction.second->getGNEWalkingAreas()) {
554 networkACs.insert(walkingArea);
555 }
556 }
557 // add additionals
558 for (const auto& additionalTags : ACs->getAdditionals()) {
559 for (const auto& additional : additionalTags.second) {
560 if (additional.second->getTagProperty()->isSelectable()) {
561 networkACs.insert(additional.second);
562 }
563 }
564 }
565 // declare massive selection
566 GNESelectorFrame::SelectionOperation::MassiveSelection massiveSelection(ACs->getNumberOfNetworkElements());
567 // iterate over network ACs
568 for (const auto& networkAC : networkACs) {
569 const auto networkACObjectType = networkAC->getGUIGlObject()->getType();
570 // save locking status in lockedTypes
571 if (massiveSelection.lockedTypes.find(networkACObjectType) == massiveSelection.lockedTypes.end()) {
572 massiveSelection.lockedTypes[networkACObjectType] = networkAC->getGUIGlObject()->isGLObjectLocked();
573 }
574 // save element and their locking status
575 if (networkAC->isAttributeCarrierSelected()) {
576 massiveSelection.ACsToUnselect[networkAC] = massiveSelection.lockedTypes.at(networkACObjectType);
577 } else {
578 massiveSelection.ACsToSelect[networkAC] = massiveSelection.lockedTypes.at(networkACObjectType);
579 }
580 }
581 return massiveSelection;
582}
583
584
587 const auto& ACs = mySelectorFrameParent->myViewNet->getNet()->getAttributeCarriers();
588 // declare massive selection
589 GNESelectorFrame::SelectionOperation::MassiveSelection massiveSelection(ACs->getNumberOfDemandElements());
590 // iterate over selectable demand elements
591 for (const auto& demandElementTag : ACs->getDemandElements()) {
592 for (const auto& demandElement : demandElementTag.second) {
593 if (demandElement.second->getTagProperty()->isSelectable()) {
594 const auto networkACObjectType = demandElement.first->getType();
595 // save locking status in lockedTypes
596 if (massiveSelection.lockedTypes.find(networkACObjectType) == massiveSelection.lockedTypes.end()) {
597 massiveSelection.lockedTypes[networkACObjectType] = demandElement.first->isGLObjectLocked();
598 }
599 // save element and their locking status
600 if (demandElement.second->isAttributeCarrierSelected()) {
601 massiveSelection.ACsToUnselect[demandElement.second] = massiveSelection.lockedTypes.at(networkACObjectType);
602 } else {
603 massiveSelection.ACsToSelect[demandElement.second] = massiveSelection.lockedTypes.at(networkACObjectType);
604 }
605 }
606 }
607 }
608 return massiveSelection;
609}
610
611
614 const auto& ACs = mySelectorFrameParent->myViewNet->getNet()->getAttributeCarriers();
615 // declare massive selection
616 GNESelectorFrame::SelectionOperation::MassiveSelection massiveSelection(ACs->getNumberOfDataElements());
617 // iterate over selectable demand elements
618 for (const auto& genericDataTag : mySelectorFrameParent->myViewNet->getNet()->getAttributeCarriers()->getGenericDatas()) {
619 for (const auto& genericData : genericDataTag.second) {
620 if (genericData.second->getTagProperty()->isSelectable()) {
621 const auto networkACObjectType = genericData.first->getType();
622 // save locking status in lockedTypes
623 if (massiveSelection.lockedTypes.find(networkACObjectType) == massiveSelection.lockedTypes.end()) {
624 massiveSelection.lockedTypes[networkACObjectType] = genericData.first->isGLObjectLocked();
625 }
626 // save element and their locking status
627 if (genericData.second->isAttributeCarrierSelected()) {
628 massiveSelection.ACsToUnselect[genericData.second] = massiveSelection.lockedTypes.at(networkACObjectType);
629 } else {
630 massiveSelection.ACsToSelect[genericData.second] = massiveSelection.lockedTypes.at(networkACObjectType);
631 }
632 }
633 }
634 }
635 return massiveSelection;
636}
637
638
639bool
641 // open question dialog box
642 const GNEQuestionBasicDialog questionDialog(mySelectorFrameParent->getViewNet()->getViewParent()->getGNEAppWindows(),
644 TL("Confirm selection operation"),
645 TL("There are locked elements in the current selection."),
646 TL("Apply operation to locked elements?"));
647 // check result
648 return (questionDialog.getResult() == GNEDialog::Result::ACCEPT);
649}
650
651// ---------------------------------------------------------------------------
652// ModificationMode::SelectionOperation::SelectionHierarchy - methods
653// ---------------------------------------------------------------------------
654
656 ACsToSelect.reserve(bucketSize);
657 ACsToUnselect.reserve(bucketSize);
658}
659
660
662
663
665 return (ACsToSelect.size() + ACsToUnselect.size()) > 0;
666}
667
668
670
671// ---------------------------------------------------------------------------
672// ModificationMode::SelectionHierarchy - methods
673// ---------------------------------------------------------------------------
674
676 GNEGroupBoxModule(selectorFrameParent, TL("Hierarchy operations")),
677 mySelectorFrameParent(selectorFrameParent),
678 myCurrentSelectedParent(Selection::ALL),
679 myCurrentSelectedChild(Selection::ALL) {
680 const auto staticTooltipMenu = selectorFrameParent->getViewNet()->getViewParent()->getGNEAppWindows()->getStaticTooltipMenu();
681 // create label for parents
682 new FXLabel(getCollapsableFrame(), TL("Select parents"), nullptr, GUIDesignLabelThick(JUSTIFY_NORMAL));
683 // Create MFXComboBoxIcon for parent comboBox
686 // create parent buttons
687 FXHorizontalFrame* parentButtons = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame);
688 // Create "select" Button
690 // Create "unselect" Button
692 // create label for parents
693 new FXLabel(getCollapsableFrame(), TL("Select children"), nullptr, GUIDesignLabelThick(JUSTIFY_NORMAL));
694 // Create MFXComboBoxIcon for parent comboBox
697 // create children buttons
698 FXHorizontalFrame* childrenButtons = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame);
699 // Create "select" Button
701 // Create "unselect" Button
703 // fill comboBoxes
704 for (const auto& item : myItems) {
705 myParentsComboBox->appendIconItem(item.second.c_str());
706 myChildrenComboBox->appendIconItem(item.second.c_str());
707 }
708}
709
710
712
713
714long
716 if (obj == myParentsComboBox) {
717 for (const auto& item : myItems) {
718 if (item.second == myParentsComboBox->getText().text()) {
719 // enable buttons
720 mySelectParentsButton->enable();
721 myUnselectParentsButton->enable();
722 // change text color
723 myParentsComboBox->setTextColor(GUIDesignTextColorBlack);
724 // set current selected parent
725 myCurrentSelectedParent = item.first;
726 return 1;
727 }
728 }
729 // item not found
730 myCurrentSelectedParent = Selection::NOTHING;
731 // disable buttons
732 mySelectParentsButton->disable();
733 myUnselectParentsButton->disable();
734 myParentsComboBox->setTextColor(GUIDesignTextColorRed);
735 return 1;
736 } else if (obj == myChildrenComboBox) {
737 for (const auto& item : myItems) {
738 if (item.second == myChildrenComboBox->getText().text()) {
739 // enable buttons
740 mySelectChildrenButton->enable();
741 myUnselectChildrenButton->enable();
742 // change text color
743 myChildrenComboBox->setTextColor(GUIDesignTextColorBlack);
744 // set current selected parent
745 myCurrentSelectedChild = item.first;
746 return 1;
747 }
748 }
749 // item not found
750 myCurrentSelectedChild = Selection::NOTHING;
751 // disable buttons
752 mySelectChildrenButton->disable();
753 myUnselectChildrenButton->disable();
754 myChildrenComboBox->setTextColor(GUIDesignTextColorRed);
755 return 1;
756 }
757 return 0;
758}
759
760
761long
762GNESelectorFrame::SelectionHierarchy::onCmdParents(FXObject* obj, FXSelector, void*) {
763 const auto viewNet = mySelectorFrameParent->getViewNet();
764 // get selected elements
765 const auto selectedACs = viewNet->getNet()->getAttributeCarriers()->getSelectedAttributeCarriers(true);
766 // check if there is selected ACs
767 if ((selectedACs.size() > 0) && (myCurrentSelectedParent != Selection::NOTHING)) {
768 // vector of of element to select or unselect
769 std::vector<GNEAttributeCarrier*> editedParents;
770 for (const auto& selectedAC : selectedACs) {
771 if (selectedAC->getTagProperty()->getTag() == SUMO_TAG_CONNECTION) {
772 const auto connection = viewNet->getNet()->getAttributeCarriers()->retrieveConnection(selectedAC->getGUIGlObject());
773 editedParents.push_back(connection->getLaneFrom());
774 editedParents.push_back(connection->getLaneTo());
775 } else if (selectedAC->getTagProperty()->getTag() == SUMO_TAG_CROSSING) {
776 const auto crossing = viewNet->getNet()->getAttributeCarriers()->retrieveCrossing(selectedAC->getGUIGlObject());
777 editedParents.push_back(crossing->getParentJunctions().front());
778 } else {
779 // get hierarchical element
780 const auto hierarchicalElement = selectedAC->getHierarchicalElement();
781 // get parent junctions
782 if ((myCurrentSelectedParent == Selection::ALL) || (myCurrentSelectedParent == Selection::JUNCTION)) {
783 editedParents.insert(editedParents.end(), hierarchicalElement->getParentJunctions().begin(), hierarchicalElement->getParentJunctions().end());
784 }
785 // get parent edges
786 if ((myCurrentSelectedParent == Selection::ALL) || (myCurrentSelectedParent == Selection::EDGE)) {
787 if (selectedAC->getTagProperty()->getTag() == SUMO_TAG_LANE) {
788 // special case for lanes
789 editedParents.push_back(dynamic_cast<GNELane*>(selectedAC)->getParentEdge());
790 } else if (selectedAC->getTagProperty()->getTag() == SUMO_TAG_TAZ) {
791 // special case for taz: select edges of source/sinks directly
792 for (const auto& tss : selectedAC->getHierarchicalElement()->getChildTAZSourceSinks()) {
793 editedParents.push_back(tss->getParentEdges().front());
794 }
795 } else {
796 editedParents.insert(editedParents.end(), hierarchicalElement->getParentEdges().begin(), hierarchicalElement->getParentEdges().end());
797 }
798 }
799 // get parent lanes
800 if ((myCurrentSelectedParent == Selection::ALL) || (myCurrentSelectedParent == Selection::LANE)) {
801 editedParents.insert(editedParents.end(), hierarchicalElement->getParentLanes().begin(), hierarchicalElement->getParentLanes().end());
802 }
803 // get parent additional
804 if ((myCurrentSelectedParent == Selection::ALL) || (myCurrentSelectedParent == Selection::ADDITIONAL)) {
805 editedParents.insert(editedParents.end(), hierarchicalElement->getParentAdditionals().begin(), hierarchicalElement->getParentAdditionals().end());
806 }
807 // get parent wire
808 if ((myCurrentSelectedParent == Selection::ALL) || (myCurrentSelectedParent == Selection::WIRE)) {
809 editedParents.insert(editedParents.end(), hierarchicalElement->getParentAdditionals().begin(), hierarchicalElement->getParentAdditionals().end());
810 }
811 // get parent demand
812 if ((myCurrentSelectedParent == Selection::ALL) || (myCurrentSelectedParent == Selection::DEMAND)) {
813 editedParents.insert(editedParents.end(), hierarchicalElement->getParentDemandElements().begin(), hierarchicalElement->getParentDemandElements().end());
814 }
815 // get parent data
816 if ((myCurrentSelectedParent == Selection::ALL) || (myCurrentSelectedParent == Selection::DATA)) {
817 editedParents.insert(editedParents.end(), hierarchicalElement->getParentGenericDatas().begin(), hierarchicalElement->getParentGenericDatas().end());
818 }
819 }
820 }
821 // select HE
822 if (editedParents.size() > 0) {
823 if (editedParents.size() > 1) {
824 viewNet->getUndoList()->begin(GUIIcon::SELECT, TL("select parents"));
825 }
826 for (const auto& HE : editedParents) {
827 if (obj == mySelectParentsButton) {
828 HE->setAttribute(GNE_ATTR_SELECTED, "true", viewNet->getUndoList());
829 } else {
830 HE->setAttribute(GNE_ATTR_SELECTED, "false", viewNet->getUndoList());
831 }
832 }
833 if (editedParents.size() > 1) {
834 viewNet->getUndoList()->end();
835 }
836 }
837 // update information label
838 mySelectorFrameParent->mySelectionInformation->updateInformationLabel();
839 // update viewNet
840 viewNet->update();
841 }
842 return 1;
843}
844
845
846long
848 // get selected elements
849 const auto selectedACs = mySelectorFrameParent->getViewNet()->getNet()->getAttributeCarriers()->getSelectedAttributeCarriers(true);
850 // check if there is selected ACs
851 if ((selectedACs.size() > 0) && (myCurrentSelectedChild != Selection::NOTHING)) {
852 // vector of of element to select or unselect
853 std::vector<GNEAttributeCarrier*> editedChildren;
854 for (const auto& selectedAC : selectedACs) {
855 // get hierarchical element
856 const auto hierarchicalElement = selectedAC->getHierarchicalElement();
857 // junctions
858 if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::JUNCTION)) {
859 if (selectedAC->getTagProperty()->getTag() == SUMO_TAG_JUNCTION) {
860 // special case for junction
861 const auto junction = dynamic_cast<GNEJunction*>(selectedAC);
862 // insert edges
863 editedChildren.insert(editedChildren.end(), junction->getGNEIncomingEdges().begin(), junction->getGNEIncomingEdges().end());
864 editedChildren.insert(editedChildren.end(), junction->getGNEOutgoingEdges().begin(), junction->getGNEOutgoingEdges().end());
865 } else {
866 editedChildren.insert(editedChildren.end(), hierarchicalElement->getChildJunctions().begin(), hierarchicalElement->getChildJunctions().end());
867 }
868 }
869 // edges
870 if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::EDGE)) {
871 if (selectedAC->getTagProperty()->getTag() == SUMO_TAG_EDGE) {
872 // special case for edges
873 const auto edge = dynamic_cast<GNEEdge*>(selectedAC);
874 // insert lanes
875 editedChildren.insert(editedChildren.end(), edge->getChildLanes().begin(), edge->getChildLanes().end());
876 } else {
877 editedChildren.insert(editedChildren.end(), hierarchicalElement->getChildEdges().begin(), hierarchicalElement->getChildEdges().end());
878 }
879 }
880 // connections
881 if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::CONNECTION)) {
882 if (selectedAC->getTagProperty()->getTag() == SUMO_TAG_EDGE) {
883 // case for edges
884 const auto edge = dynamic_cast<GNEEdge*>(selectedAC);
885 // insert connections
886 editedChildren.insert(editedChildren.end(), edge->getGNEConnections().begin(), edge->getGNEConnections().end());
887 } else if (selectedAC->getTagProperty()->getTag() == SUMO_TAG_LANE) {
888 // case for lanes
889 const auto lane = dynamic_cast<GNELane*>(selectedAC);
890 // insert connections
891 for (const auto& connection : lane->getParentEdge()->getGNEConnections()) {
892 if (connection->getAttribute(SUMO_ATTR_FROM_LANE) == lane->getAttribute(SUMO_ATTR_INDEX)) {
893 editedChildren.push_back(connection);
894 }
895 }
896 } else if (selectedAC->getTagProperty()->getTag() == SUMO_TAG_JUNCTION) {
897 // case for junction
898 const auto junction = dynamic_cast<GNEJunction*>(selectedAC);
899 // get connections
900 const auto connections = junction->getGNEConnections();
901 // insert connections
902 editedChildren.insert(editedChildren.end(), connections.begin(), connections.end());
903 }
904 }
905 // crossings
906 if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::CROSSING)) {
907 if (selectedAC->getTagProperty()->getTag() == SUMO_TAG_JUNCTION) {
908 // case for junction
909 const auto junction = dynamic_cast<GNEJunction*>(selectedAC);
910 // insert crossings
911 editedChildren.insert(editedChildren.end(), junction->getGNECrossings().begin(), junction->getGNECrossings().end());
912 }
913 }
914 // lanes
915 if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::LANE)) {
916 editedChildren.insert(editedChildren.end(), hierarchicalElement->getChildLanes().begin(), hierarchicalElement->getChildLanes().end());
917 }
918 // additional
919 if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::ADDITIONAL)) {
920 // avoid insert symbols
921 for (const auto& additionalChild : hierarchicalElement->getChildAdditionals()) {
922 if (!additionalChild->getTagProperty()->isWireElement() && !additionalChild->getTagProperty()->isSymbol()) {
923 editedChildren.push_back(additionalChild);
924 }
925 }
926 }
927 // wire
928 if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::WIRE)) {
929 // avoid insert symbols
930 for (const auto& wireChild : hierarchicalElement->getChildAdditionals()) {
931 if (wireChild->getTagProperty()->isWireElement() && !wireChild->getTagProperty()->isSymbol()) {
932 editedChildren.push_back(wireChild);
933 }
934 }
935 }
936 // demand
937 if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::DEMAND)) {
938 editedChildren.insert(editedChildren.end(), hierarchicalElement->getChildDemandElements().begin(), hierarchicalElement->getChildDemandElements().end());
939 }
940 // data
941 if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::DATA)) {
942 editedChildren.insert(editedChildren.end(), hierarchicalElement->getChildGenericDatas().begin(), hierarchicalElement->getChildGenericDatas().end());
943 }
944 }
945 // select HE
946 if (editedChildren.size() > 0) {
947 if (editedChildren.size() > 1) {
948 mySelectorFrameParent->getViewNet()->getUndoList()->begin(GUIIcon::SELECT, TL("select children"));
949 }
950 for (const auto& HE : editedChildren) {
951 if (obj == mySelectChildrenButton) {
952 HE->setAttribute(GNE_ATTR_SELECTED, "true", mySelectorFrameParent->getViewNet()->getUndoList());
953 } else {
954 HE->setAttribute(GNE_ATTR_SELECTED, "false", mySelectorFrameParent->getViewNet()->getUndoList());
955 }
956 }
957 if (editedChildren.size() > 1) {
958 mySelectorFrameParent->getViewNet()->getUndoList()->end();
959 }
960 }
961 // update information label
962 mySelectorFrameParent->mySelectionInformation->updateInformationLabel();
963 // update viewNet
964 mySelectorFrameParent->getViewNet()->update();
965 }
966 return 1;
967}
968
969// ---------------------------------------------------------------------------
970// GNECrossingFrame::Legend - methods
971// ---------------------------------------------------------------------------
972
974 GNEGroupBoxModule(selectorFrameParent, TL("Information")) {
975 // Create Selection Hint
976 new MFXDynamicLabel(getCollapsableFrame(), (std::string("- ") + TL("Hold <SHIFT> for rectangle selection.") + std::string("\n- ") + TL("Press <DEL> to delete selected objects.")).c_str(), nullptr, GUIDesignLabelFrameInformation);
977}
978
979
981
982// ---------------------------------------------------------------------------
983// GNESelectorFrame - methods
984// ---------------------------------------------------------------------------
985
987 GNEFrame(viewParent, viewNet, TL("Selection")) {
988 // create selection information
990 // create Modification Mode modul
992 // create ElementSet modul
994 // create VisualScaling modul
995 myVisualScaling = new VisualScaling(this);
996 // create SelectionOperation modul
998 // create SelectionHierarchy modul
1000 // create Information modul
1001 myInformation = new Information(this);
1002}
1003
1004
1006
1007
1008void
1011 // update information label
1013 // Show frame
1015}
1016
1017
1018void
1020 // hide frame
1022}
1023
1024
1025void
1030
1031
1032void
1036
1037
1038bool
1040 // get front AC
1041 auto AC = viewObjects.getAttributeCarrierFront();
1042 // check AC
1043 if (AC == nullptr) {
1044 return false;
1045 }
1046 // check locking
1047 if (myViewNet->getLockManager().isObjectLocked(AC->getGUIGlObject()->getType(), AC->isAttributeCarrierSelected())) {
1048 return false;
1049 }
1050 // check modes
1051 if ((AC->getTagProperty()->isNetworkElement() || AC->getTagProperty()->isAdditionalElement()) &&
1053 return false;
1054 }
1055 if (AC->getTagProperty()->isDemandElement() && !myViewNet->getEditModes().isCurrentSupermodeDemand()) {
1056 return false;
1057 }
1058 if (AC->getTagProperty()->isDataElement() && !myViewNet->getEditModes().isCurrentSupermodeData()) {
1059 return false;
1060 }
1061 // filter GLObjects by layer
1062 auto filteredGLObjects = GNEViewNetHelper::filterElementsByLayer(viewObjects.getGLObjects());
1063 // check if we have to open dialog
1064 if (filteredGLObjects.size() > 1) {
1065 myViewNet->openSelectDialogAtCursor(filteredGLObjects);
1066 } else {
1067 // toggle selection
1068 if (AC->isAttributeCarrierSelected()) {
1069 AC->unselectAttributeCarrier();
1070 } else {
1071 AC->selectAttributeCarrier();
1072 }
1073 // update information label
1075 }
1076 return true;
1077}
1078
1079
1080void
1081GNESelectorFrame::handleIDs(const std::vector<GNEAttributeCarrier*>& ACs, const ModificationMode::Operation setop) {
1082 // declare set operation
1084 // declare two sets of attribute carriers, one for select and another for unselect
1085 std::set<std::pair<std::string, GNEAttributeCarrier*> > ACsToSelect, ACsToUnselect;
1086 // in restrict AND replace mode all current selected attribute carriers will be unselected
1087 if ((setOperation == ModificationMode::Operation::REPLACE) || (setOperation == ModificationMode::Operation::RESTRICT)) {
1088 // obtain selected ACs depending of current supermode
1089 auto selectedACs = myViewNet->getNet()->getAttributeCarriers()->getSelectedAttributeCarriers(false);
1090 // add id into ACs to unselect
1091 for (const auto& selectedAC : selectedACs) {
1092 ACsToUnselect.insert(std::make_pair(selectedAC->getID(), selectedAC));
1093 }
1094 }
1095 // handle ids
1096 for (const auto& AC : ACs) {
1097 // iterate over AttributeCarriers an place it in ACsToSelect or ACsToUnselect
1098 switch (setOperation) {
1100 ACsToUnselect.insert(std::make_pair(AC->getID(), AC));
1101 break;
1103 if (ACsToUnselect.find(std::make_pair(AC->getID(), AC)) != ACsToUnselect.end()) {
1104 ACsToSelect.insert(std::make_pair(AC->getID(), AC));
1105 }
1106 break;
1107 default:
1108 ACsToSelect.insert(std::make_pair(AC->getID(), AC));
1109 break;
1110 }
1111 }
1112 // select junctions and their connections if Auto select junctions is enabled (note: only for "add mode")
1114 std::set<GNEEdge*> edgesToSelect;
1115 // iterate over ACsToSelect and extract edges
1116 for (const auto& AC : ACsToSelect) {
1117 if (AC.second->getTagProperty()->getTag() == SUMO_TAG_EDGE) {
1118 edgesToSelect.insert(myViewNet->getNet()->getAttributeCarriers()->retrieveEdge(AC.second->getID()));
1119 }
1120 }
1121 // iterate over extracted edges
1122 for (const auto& edgeToSelect : edgesToSelect) {
1123 // select junction source and all connections, crossings and walkingAreas
1124 ACsToSelect.insert(std::make_pair(edgeToSelect->getFromJunction()->getID(), edgeToSelect->getFromJunction()));
1125 for (const auto& connectionToSelect : edgeToSelect->getFromJunction()->getGNEConnections()) {
1126 ACsToSelect.insert(std::make_pair(connectionToSelect->getID(), connectionToSelect));
1127 }
1128 for (const auto& fromCrossingToSelect : edgeToSelect->getFromJunction()->getGNECrossings()) {
1129 ACsToSelect.insert(std::make_pair(fromCrossingToSelect->getID(), fromCrossingToSelect));
1130 }
1131 for (const auto& fromWalkingAreaToSelect : edgeToSelect->getFromJunction()->getGNEWalkingAreas()) {
1132 ACsToSelect.insert(std::make_pair(fromWalkingAreaToSelect->getID(), fromWalkingAreaToSelect));
1133 }
1134 // select junction destination and all connections, crossings and walkingAreas
1135 ACsToSelect.insert(std::make_pair(edgeToSelect->getToJunction()->getID(), edgeToSelect->getToJunction()));
1136 for (const auto& connectionToSelect : edgeToSelect->getToJunction()->getGNEConnections()) {
1137 ACsToSelect.insert(std::make_pair(connectionToSelect->getID(), connectionToSelect));
1138 }
1139 for (const auto& toCrossingToSelect : edgeToSelect->getToJunction()->getGNECrossings()) {
1140 ACsToSelect.insert(std::make_pair(toCrossingToSelect->getID(), toCrossingToSelect));
1141 }
1142 for (const auto& toWalkingAreaToSelect : edgeToSelect->getToJunction()->getGNEWalkingAreas()) {
1143 ACsToSelect.insert(std::make_pair(toWalkingAreaToSelect->getID(), toWalkingAreaToSelect));
1144 }
1145 }
1146 }
1147 // only continue if there is ACs to select or unselect
1148 if ((ACsToSelect.size() + ACsToUnselect.size()) > 0) {
1149 // first unselect AC of ACsToUnselect and then selects AC of ACsToSelect
1151 for (const auto& ACToUnselect : ACsToUnselect) {
1152 if (ACToUnselect.second->getTagProperty()->isSelectable()) {
1153 ACToUnselect.second->setAttribute(GNE_ATTR_SELECTED, "false", myViewNet->getUndoList());
1154 }
1155 }
1156 for (const auto& ACToSelect : ACsToSelect) {
1157 if (ACToSelect.second->getTagProperty()->isSelectable()) {
1158 ACToSelect.second->setAttribute(GNE_ATTR_SELECTED, "true", myViewNet->getUndoList());
1159 }
1160 }
1161 // finish operation
1163 }
1164}
1165
1166
1167FXVerticalFrame*
1171
1172
1177
1178
1183
1184
1189
1190/****************************************************************************/
FXDEFMAP(GNESelectorFrame::ModificationMode) ModificationModeMap[]
@ NETWORK
Network mode (Edges, junctions, 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:605
@ MID_CHOOSEN_INVERT
Deselect selected items.
Definition GUIAppEnum.h:617
@ MID_CHOOSEN_DELETE
delete set
Definition GUIAppEnum.h:609
@ MID_CHOOSEN_OPERATION
set type of selection
Definition GUIAppEnum.h:599
@ MID_CHOOSEN_LOAD
Load set.
Definition GUIAppEnum.h:603
@ MID_CHOOSEN_REDUCE
simplify network reduction
Definition GUIAppEnum.h:621
@ MID_CHOOSEN_CLEAR
Clear set.
Definition GUIAppEnum.h:607
@ MID_GNE_SELECT
select element
@ MID_GNE_SELECTORFRAME_PARENTS
select/unselect parents
#define GUIDesignSpinDial
Definition GUIDesigns.h:516
#define GUIDesignTextColorRed
red color (for invalid text)
Definition GUIDesigns.h:44
#define GUIDesignButton
Definition GUIDesigns.h:100
#define GUIDesignComboBox
Definition GUIDesigns.h:295
#define GUIDesignAuxiliarHorizontalFrame
design for auxiliar (Without borders) horizontal frame used to pack another frames
Definition GUIDesigns.h:430
#define GUIDesignComboBoxVisibleItems
Definition GUIDesigns.h:64
#define GUIDesignLabelThick(justify)
label extended over frame with thick and with text justify to left
Definition GUIDesigns.h:251
#define GUIDesignTextColorBlack
black color (for correct text)
Definition GUIDesigns.h:38
#define GUIDesignRadioButton
Definition GUIDesigns.h:231
#define GUIDesignLabelFrameInformation
label extended over frame without thick and with text justify to left, used to show information in fr...
Definition GUIDesigns.h:281
FXString gCurrentFolder
The folder used as last.
@ OPEN
open icons
@ SIMPLIFYNETWORK
@ SAVE
save icons
#define WRITE_ERRORF(...)
Definition MsgHandler.h:296
#define TL(string)
Definition MsgHandler.h:304
@ SUMO_TAG_TAZ
a traffic assignment zone
@ SUMO_TAG_CONNECTION
connectioon between two lanes
@ SUMO_TAG_JUNCTION
begin/end of the description of a junction
@ SUMO_TAG_CROSSING
crossing between edges for pedestrians
@ SUMO_TAG_LANE
begin/end of the description of a single lane
@ SUMO_TAG_EDGE
begin/end of the description of an edge
@ SUMO_ATTR_FROM_LANE
@ GNE_ATTR_SELECTED
element is selected
@ SUMO_ATTR_INDEX
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:49
const std::string getID() const override
get ID (all Attribute Carriers have one)
bool isTemplate() const
check if this AC is template
const GNETagProperties * getTagProperty() const
get tagProperty associated with this Attribute Carrier
virtual GUIGlObject * getGUIGlObject()=0
get GUIGlObject associated with this AttributeCarrier
Result getResult() const
get result to indicate if this dialog was closed accepting or rejecting changes
GNEViewNet * getViewNet() const
get view net
Definition GNEFrame.cpp:145
GNEViewNet * myViewNet
FOX need this.
Definition GNEFrame.h:122
FXVerticalFrame * myContentFrame
Vertical frame that holds all widgets of frame.
Definition GNEFrame.h:125
virtual void show()
show Frame
Definition GNEFrame.cpp:110
virtual void hide()
hide Frame
Definition GNEFrame.cpp:119
GNEGroupBoxModule (based on FXGroupBox)
void setText(const std::string &text)
set text
FXVerticalFrame * getCollapsableFrame()
get collapsable frame (used by all elements that will be collapsed if button is toggled)
std::vector< GNEConnection * > getGNEConnections() const
Returns all GNEConnections vinculated with this junction.
void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList) override
GNEEdge * getParentEdge() const
get parent edge
Definition GNELane.cpp:214
void showMatchAttribute()
show match attributes
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:174
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
SelectionHierarchy(GNESelectorFrame *selectorFrameParent)
FOX-declaration.
MFXComboBoxIcon * myChildrenComboBox
comboBox for children
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
MFXComboBoxIcon * myParentsComboBox
comboBox for parents
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.
MassiveSelection processMassiveNetworkElementSelection(const bool filterLanes) const
process massive network 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
MassiveSelection processMassiveDataElementSelection() const
process massive dataelement selection
MassiveSelection processMassiveDemandElementSelection() const
process massive demand element selection
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
void updateFrameAfterUndoRedo()
function called after undo/redo in the current frame
ModificationMode * getModificationModeModul() const
get modification mode modul
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
GNESelectorFrame::Information * myInformation
information modul
GNESelectorFrame::SelectionHierarchy * mySelectionHierarchy
modul for selection hierarchy
GNESelectorFrame::ModificationMode * myModificationMode
modul for change modification mode
GNEMatchAttribute * myMatchAttribute
modul for match attribute
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 selectAttributeCarrier(const GNEViewNetHelper::ViewObjectsSelector &viewObjects)
select attribute carrier (element)
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 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
GNEAttributeCarrier * getAttributeCarrierFront() const
get front attribute carrier or a pointer to nullptr
const std::vector< GUIGlObject * > & getGLObjects() const
get vector with GL objects
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
GNEViewParent * getViewParent() const
get the net object
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.
GNEApplicationWindow * getGNEAppWindows() const
get GNE Application Windows
static FXButton * buildFXButton(FXComposite *p, const std::string &text, const std::string &tip, const std::string &help, FXIcon *ic, FXObject *tgt, FXSelector sel, FXuint opts=BUTTON_NORMAL, FXint x=0, FXint y=0, FXint w=0, FXint h=0, FXint pl=DEFAULT_PAD, FXint pr=DEFAULT_PAD, FXint pt=DEFAULT_PAD, FXint pb=DEFAULT_PAD)
build button
static FXRadioButton * buildFXRadioButton(FXComposite *p, const std::string &text, const std::string &tip, const std::string &help, FXObject *tgt, FXSelector sel, FXuint opts=RADIOBUTTON_NORMAL, FXint x=0, FXint y=0, FXint w=0, FXint h=0, FXint pl=DEFAULT_PAD, FXint pr=DEFAULT_PAD, FXint pt=DEFAULT_PAD, FXint pb=DEFAULT_PAD)
build radio button
static StringBijection< GUIGlObjectType > TypeNames
associates object types with strings
Definition GUIGlObject.h:72
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
MFXStaticToolTip * getStaticTooltipMenu() const
get static toolTip for menus
FXint appendIconItem(const FXString &text, FXIcon *icon=nullptr, FXColor bgColor=FXRGB(255, 255, 255), void *ptr=nullptr)
append icon item in the last position
A list item which allows for custom coloring.
static FXString getFilename2Write(FXWindow *parent, const FXString &header, const FXString &extensions, FXIcon *icon, FXString &currentFolder)
Returns the file name to write.
Definition MFXUtils.cpp:117
Static storage of an output device and its base (abstract) implementation.
void close()
Closes the device and removes it from the dictionary.
static OutputDevice & getDevice(const std::string &name, bool usePrefix=true)
Returns the described OutputDevice.
static StringBijection< TXTFileExtension > TXTFileExtensions
TXT file Extensions.
const std::string & getString(const T key) const
get string
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.
std::unordered_map< GNEAttributeCarrier *, bool > ACsToSelect
ACs to select (the bool flag shows if element is locked)
std::map< GUIGlObjectType, bool > lockedTypes
locked types
std::unordered_map< GNEAttributeCarrier *, bool > ACsToUnselect
ACs to select (the bool flag shows if element is locked)
bool isElementToProcess() const
check if there are element to process
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