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-2024 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>
33
34#include "GNESelectorFrame.h"
35#include "GNEElementSet.h"
36
37
38// ===========================================================================
39// FOX callback mapping
40// ===========================================================================
44
48
57
63
64// Object implementation
65FXIMPLEMENT(GNESelectorFrame::ModificationMode, MFXGroupBoxModule, ModificationModeMap, ARRAYNUMBER(ModificationModeMap))
66FXIMPLEMENT(GNESelectorFrame::VisualScaling, MFXGroupBoxModule, VisualScalingMap, ARRAYNUMBER(VisualScalingMap))
67FXIMPLEMENT(GNESelectorFrame::SelectionOperation, MFXGroupBoxModule, SelectionOperationMap, ARRAYNUMBER(SelectionOperationMap))
68FXIMPLEMENT(GNESelectorFrame::SelectionHierarchy, MFXGroupBoxModule, SelectionHierarchyMap, ARRAYNUMBER(SelectionHierarchyMap))
69
70// ===========================================================================
71// method definitions
72// ===========================================================================
73
74// ---------------------------------------------------------------------------
75// ModificationMode::SelectionInformation - methods
76// ---------------------------------------------------------------------------
77
79 MFXGroupBoxModule(selectorFrameParent, TL("Selection information")),
80 mySelectorFrameParent(selectorFrameParent) {
81 // information label
82 myInformationLabel = new FXLabel(getCollapsableFrame(), "", nullptr, GUIDesignLabelFrameInformation);
83}
84
85
87
88
89void
91 // first clear information
92 myInformation.clear();
93 // get attribute carriers
94 const auto ACs = mySelectorFrameParent->getViewNet()->getNet()->getAttributeCarriers();
95 // continue depending of supermode
96 if (mySelectorFrameParent->getViewNet()->getEditModes().isCurrentSupermodeNetwork()) {
97 updateInformationLabel(TL("Junctions"), ACs->getNumberOfSelectedJunctions());
98 updateInformationLabel(TL("Edges"), ACs->getNumberOfSelectedEdges());
99 updateInformationLabel(TL("Lanes"), ACs->getNumberOfSelectedLanes());
100 updateInformationLabel(TL("Connections"), ACs->getNumberOfSelectedConnections());
101 updateInformationLabel(TL("Crossings"), ACs->getNumberOfSelectedCrossings());
102 updateInformationLabel(TL("WalkingAreas"), ACs->getNumberOfSelectedWalkingAreas());
103 updateInformationLabel(TL("Additionals"), ACs->getNumberOfSelectedPureAdditionals());
104 updateInformationLabel(TL("Wires"), ACs->getNumberOfSelectedWires());
105 updateInformationLabel(TL("TAZs"), ACs->getNumberOfSelectedTAZs());
106 updateInformationLabel(TL("TAZSources"), ACs->getNumberOfSelectedTAZSources());
107 updateInformationLabel(TL("TAZSinks"), ACs->getNumberOfSelectedTAZSinks());
108 updateInformationLabel(TL("Polygons"), ACs->getNumberOfSelectedPolygons());
109 updateInformationLabel(TL("POIs"), ACs->getNumberOfSelectedPOIs());
110 updateInformationLabel(TL("JuPedSim elements"),
111 ACs->getNumberOfSelectedJpsWalkableAreas() +
112 ACs->getNumberOfSelectedJpsObstacles());
113 } else if (mySelectorFrameParent->getViewNet()->getEditModes().isCurrentSupermodeDemand()) {
114 updateInformationLabel(TL("Routes"), ACs->getNumberOfSelectedRoutes());
115 updateInformationLabel(TL("Vehicles"), ACs->getNumberOfSelectedVehicles());
116 updateInformationLabel(TL("Persons"), ACs->getNumberOfSelectedPersons());
117 updateInformationLabel(TL("Person trips"), ACs->getNumberOfSelectedPersonTrips());
118 updateInformationLabel(TL("Walks"), ACs->getNumberOfSelectedWalks());
119 updateInformationLabel(TL("Rides"), ACs->getNumberOfSelectedRides());
120 updateInformationLabel(TL("Containers"), ACs->getNumberOfSelectedContainers());
121 updateInformationLabel(TL("Transport"), ACs->getNumberOfSelectedTransport());
122 updateInformationLabel(TL("Tranships"), ACs->getNumberOfSelectedTranships());
123 updateInformationLabel(TL("Stops"), ACs->getNumberOfSelectedStops());
124 } else if (mySelectorFrameParent->getViewNet()->getEditModes().isCurrentSupermodeData()) {
125 updateInformationLabel(TL("EdgeDatas"), ACs->getNumberOfSelectedEdgeDatas());
126 updateInformationLabel(TL("EdgeRelDatas"), ACs->getNumberOfSelectedEdgeRelDatas());
127 updateInformationLabel(TL("EdgeTAZRel"), ACs->getNumberOfSelectedEdgeTAZRel());
128 }
129 // adjust format
130 const auto numberLines = std::count(myInformation.begin(), myInformation.end(), ':');
131 if (numberLines == 0) {
132 myInformation.append(" \n \n");
133 } else if (numberLines > 1) {
134 myInformation.pop_back();
135 }
136 // set label
137 myInformationLabel->setText(myInformation.c_str());
138}
139
140
141void
143 // check number
144 if (number > 0) {
145 myInformation.append(element + ": " + toString(number) + "\n");
146 }
147}
148
149// ---------------------------------------------------------------------------
150// ModificationMode::ModificationMode - methods
151// ---------------------------------------------------------------------------
152
154 MFXGroupBoxModule(selectorFrameParent, TL("Modification Mode")),
155 myModificationModeType(Operation::ADD) {
156 // Create all options buttons
157 myAddRadioButton = GUIDesigns::buildFXRadioButton(getCollapsableFrame(), TL("add"), "", TL("Selected objects are added to the previous selection"),
159 myRemoveRadioButton = GUIDesigns::buildFXRadioButton(getCollapsableFrame(), TL("remove"), "", TL("Selected objects are removed from the previous selection"),
161 myKeepRadioButton = GUIDesigns::buildFXRadioButton(getCollapsableFrame(), TL("keep"), "", TL("Restrict previous selection by the current selection"),
163 myReplaceRadioButton = GUIDesigns::buildFXRadioButton(getCollapsableFrame(), TL("replace"), "", TL("Replace previous selection by the current selection"),
165 myAddRadioButton->setCheck(true);
166}
167
168
170
171
174 return myModificationModeType;
175}
176
177
178long
180 if (obj == myAddRadioButton) {
181 myModificationModeType = Operation::ADD;
182 myAddRadioButton->setCheck(true);
183 myRemoveRadioButton->setCheck(false);
184 myKeepRadioButton->setCheck(false);
185 myReplaceRadioButton->setCheck(false);
186 return 1;
187 } else if (obj == myRemoveRadioButton) {
188 myModificationModeType = Operation::SUB;
189 myAddRadioButton->setCheck(false);
190 myRemoveRadioButton->setCheck(true);
191 myKeepRadioButton->setCheck(false);
192 myReplaceRadioButton->setCheck(false);
193 return 1;
194 } else if (obj == myKeepRadioButton) {
195 myModificationModeType = Operation::RESTRICT;
196 myAddRadioButton->setCheck(false);
197 myRemoveRadioButton->setCheck(false);
198 myKeepRadioButton->setCheck(true);
199 myReplaceRadioButton->setCheck(false);
200 return 1;
201 } else if (obj == myReplaceRadioButton) {
202 myModificationModeType = Operation::REPLACE;
203 myAddRadioButton->setCheck(false);
204 myRemoveRadioButton->setCheck(false);
205 myKeepRadioButton->setCheck(false);
206 myReplaceRadioButton->setCheck(true);
207 return 1;
208 } else {
209 return 0;
210 }
211}
212
213// ---------------------------------------------------------------------------
214// ModificationMode::VisualScaling - methods
215// ---------------------------------------------------------------------------
216
218 MFXGroupBoxModule(selectorFrameParent, TL("Visual Scaling")),
219 mySelectorFrameParent(selectorFrameParent) {
220 // Create spin button and configure it
222 //mySelectionScaling->setNumberFormat(1);
223 //mySelectionScaling->setIncrements(0.1, .5, 1);
224 mySelectionScaling->setIncrement(0.5);
225 mySelectionScaling->setRange(1, 100000);
226 mySelectionScaling->setValue(1);
227 mySelectionScaling->setHelpText(TL("Enlarge selected objects"));
228}
229
230
232
233
234long
236 // set scale in viewnet
237 mySelectorFrameParent->myViewNet->setSelectorFrameScale(mySelectionScaling->getValue());
238 mySelectorFrameParent->myViewNet->updateViewNet();
239 return 1;
240}
241
242// ---------------------------------------------------------------------------
243// ModificationMode::SelectionHierarchy - methods
244// ---------------------------------------------------------------------------
245
247 MFXGroupBoxModule(selectorFrameParent, TL("Selection operations")),
248 mySelectorFrameParent(selectorFrameParent) {
249 // tabular buttons, see GNETLSEditorFrame
250
251 FXHorizontalFrame* selectionButtons = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame);
252 FXVerticalFrame* col1 = new FXVerticalFrame(selectionButtons, LAYOUT_FILL_X, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); // left button columm
253 FXVerticalFrame* col2 = new FXVerticalFrame(selectionButtons, LAYOUT_FILL_X, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); // right button column
254
255 // Create "Clear List" Button
256 GUIDesigns::buildFXButton(col1, TL("Clear"), "", TL("Deselect all objects (hotkey: ESC)"), nullptr, this, MID_CHOOSEN_CLEAR, GUIDesignButton);
257 // Create "Invert" Button
258 GUIDesigns::buildFXButton(col2, TL("Invert"), "", TL("Invert selection status of all objects"), nullptr, this, MID_CHOOSEN_INVERT, GUIDesignButton);
259 // Create "Save" Button
260 GUIDesigns::buildFXButton(col1, TL("Save"), "", TL("Save ids of currently selected objects to a file."), nullptr, this, MID_CHOOSEN_SAVE, GUIDesignButton);
261 // Create "Load" Button
262 GUIDesigns::buildFXButton(col2, TL("Load"), "", TL("Load ids from a file according to the current modification mode."), nullptr, this, MID_CHOOSEN_LOAD, GUIDesignButton);
263 // Create "Delete" Button
264 GUIDesigns::buildFXButton(col1, TL("Delete"), "", TL("Delete all selected objects (hotkey: DEL)"), nullptr, this, MID_CHOOSEN_DELETE, GUIDesignButton);
265 // Create "reduce" Button
266 GUIDesigns::buildFXButton(col2, TL("Reduce"), "", TL("Reduce network to current selection."), nullptr, this, MID_CHOOSEN_REDUCE, GUIDesignButton);
267}
268
269
271
272
273void
275 std::vector<GNEAttributeCarrier*> loadedACs;
276 std::ifstream strm(file.c_str());
277 // check if file can be opened
278 if (!strm.good()) {
279 WRITE_ERRORF(TL("Could not open '%'."), file);
280 } else {
281 // convert all glObjects into GNEAttributeCarriers
282 std::map<const std::string, GNEAttributeCarrier*> GLFUllNameAC;
283 const auto GLObjects = GUIGlObjectStorage::gIDStorage.getAllGLObjects();
284 for (const auto& GLObject : GLObjects) {
285 // try to parse GLObject to AC
286 GNEAttributeCarrier* AC = dynamic_cast<GNEAttributeCarrier*>(GLObject);
287 // if was successfully parsed and is NOT a template, add into GLFUllNameAC using fullName
288 if (AC && !AC->isTemplate()) {
289 GLFUllNameAC[GUIGlObject::TypeNames.getString(GLObject->getType()) + ":" + AC->getID()] = AC;
290 }
291 }
292 // continue while stream exist
293 while (strm.good()) {
294 std::string line;
295 strm >> line;
296 // check if line isn't empty
297 if (line.length() != 0) {
298 // obtain AC from GLFUllNameAC
299 if (StringUtils::startsWith(line, "node:")) {
300 line = StringUtils::replace(line, "node:", "junction:");
301 }
302 GNEAttributeCarrier* AC = GLFUllNameAC.count(line) > 0 ? GLFUllNameAC.at(line) : nullptr;
303 // check if AC exist, is selectable, and isn't locked
304 if (AC && AC->getTagProperty().isSelectable() && !mySelectorFrameParent->getViewNet()->getLockManager().isObjectLocked(AC->getGUIGlObject()->getType(), false)) {
305 // now check if we're in the correct supermode to load this element
306 if (((mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeNetwork()) && !AC->getTagProperty().isDemandElement()) ||
307 ((mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeDemand()) && AC->getTagProperty().isDemandElement()) ||
308 ((mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeData()) && AC->getTagProperty().isDataElement())) {
309 loadedACs.push_back(AC);
310 }
311 }
312 }
313 }
314 // change selected attribute in loaded ACs allowing undo/redo
315 if (loadedACs.size() > 0) {
316 mySelectorFrameParent->myViewNet->getUndoList()->begin(GUIIcon::MODESELECT, TL("load selection"));
317 mySelectorFrameParent->handleIDs(loadedACs);
318 mySelectorFrameParent->myViewNet->getUndoList()->end();
319 }
320 }
321}
322
323
324long
326 // get the new file name
327 FXFileDialog opendialog(getCollapsableFrame(), TL("Open List of Selected Items"));
328 opendialog.setIcon(GUIIconSubSys::getIcon(GUIIcon::OPEN));
329 opendialog.setSelectMode(SELECTFILE_EXISTING);
330 opendialog.setPatternList("Selection files (*.txt)\nAll files (*)");
331 if (gCurrentFolder.length() != 0) {
332 opendialog.setDirectory(gCurrentFolder);
333 }
334 if (opendialog.execute()) {
335 gCurrentFolder = opendialog.getDirectory();
336 loadFromFile(opendialog.getFilename().text());
337 }
338 return 1;
339}
340
341
342long
344 FXString file = MFXUtils::getFilename2Write(this,
345 TL("Save List of selected Items"), ".txt",
347 if (file == "") {
348 return 1;
349 }
350 try {
351 OutputDevice& dev = OutputDevice::getDevice(file.text());
352 // get selected attribute carriers
353 const auto selectedACs = mySelectorFrameParent->myViewNet->getNet()->getAttributeCarriers()->getSelectedAttributeCarriers(false);
354 for (const auto& selectedAC : selectedACs) {
355 GUIGlObject* object = dynamic_cast<GUIGlObject*>(selectedAC);
356 if (object) {
357 dev << GUIGlObject::TypeNames.getString(object->getType()) << ":" << selectedAC->getID() << "\n";
358 }
359 }
360 dev.close();
361 } catch (IOError& e) {
362 // write warning if netedit is running in testing mode
363 WRITE_DEBUG("Opening FXMessageBox 'error storing selection'");
364 // open message box error
365 FXMessageBox::error(getCollapsableFrame(), MBOX_OK, "Storing Selection failed", "%s", e.what());
366 // write warning if netedit is running in testing mode
367 WRITE_DEBUG("Closed FXMessageBox 'error storing selection' with 'OK'");
368 }
369 return 1;
370}
371
372
373long
375 const auto& editModes = mySelectorFrameParent->myViewNet->getEditModes();
376 GNEUndoList* undoList = mySelectorFrameParent->myViewNet->getUndoList();
377 // declare massive selection
378 MassiveSelection massiveSelection =
379 editModes.isCurrentSupermodeNetwork() ? processMassiveNetworkElementSelection(false) :
380 editModes.isCurrentSupermodeDemand() ? processMassiveDemandElementSelection() :
381 processMassiveDataElementSelection();
382 // only continue if there are elements to unselect
383 if (massiveSelection.isElementToProcess()) {
384 // check if add locked elements
385 bool askedContinueIfLock = false;
386 bool addLockedElements = false;
387 bool unlockedElements = false;
388 for (const auto& ACToUnselect : massiveSelection.ACsToUnselect) {
389 if (ACToUnselect.second == false) {
390 // there are unlocked elements
391 unlockedElements = true;
392 } else if (!askedContinueIfLock) {
393 addLockedElements = askContinueIfLock();
394 // only ask one time for locking
395 askedContinueIfLock = true;
396 }
397 }
398 if (unlockedElements || addLockedElements) {
399 mySelectorFrameParent->myViewNet->getUndoList()->begin(GUIIcon::MODESELECT, TL("clear selection"));
400 for (const auto& ACToUnselect : massiveSelection.ACsToUnselect) {
401 if (addLockedElements || !ACToUnselect.second) {
402 ACToUnselect.first->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
403 }
404 }
405 mySelectorFrameParent->myViewNet->getUndoList()->end();
406 }
407 }
408 return 1;
409}
410
411long
413 // acts like the 'del' hotkey
414 mySelectorFrameParent->getViewNet()->hotkeyDel();
415 return 1;
416}
417
418
419long
421 const auto& editModes = mySelectorFrameParent->myViewNet->getEditModes();
422 GNEUndoList* undoList = mySelectorFrameParent->myViewNet->getUndoList();
423 // declare massive selection
424 MassiveSelection massiveSelection =
425 editModes.isCurrentSupermodeNetwork() ? processMassiveNetworkElementSelection(true) :
426 editModes.isCurrentSupermodeDemand() ? processMassiveDemandElementSelection() :
427 processMassiveDataElementSelection();
428 // only continue if there are elements to select and unselect
429 if (massiveSelection.isElementToProcess()) {
430 // check if add locked elements
431 bool askedContinueIfLock = false;
432 bool addLockedElements = false;
433 bool unlockedElements = false;
434 for (const auto& ACToSelect : massiveSelection.ACsToSelect) {
435 if (ACToSelect.second == false) {
436 // there are unlocked elements
437 unlockedElements = true;
438 } else if (!askedContinueIfLock) {
439 addLockedElements = askContinueIfLock();
440 // only ask one time for locking
441 askedContinueIfLock = true;
442 }
443 }
444 for (const auto& ACToUnselect : massiveSelection.ACsToUnselect) {
445 if (ACToUnselect.second == false) {
446 // there are unlocked elements
447 unlockedElements = true;
448 } else if (!askedContinueIfLock) {
449 addLockedElements = askContinueIfLock();
450 // only ask one time for locking
451 askedContinueIfLock = true;
452 }
453 }
454 if (unlockedElements || addLockedElements) {
455 mySelectorFrameParent->myViewNet->getUndoList()->begin(GUIIcon::MODESELECT, TL("invert selection"));
456 for (const auto& ACToSelect : massiveSelection.ACsToSelect) {
457 if (addLockedElements || !ACToSelect.second) {
458 ACToSelect.first->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
459 }
460 }
461 for (const auto& ACToUnselect : massiveSelection.ACsToUnselect) {
462 if (addLockedElements || !ACToUnselect.second) {
463 ACToUnselect.first->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
464 }
465 }
466 mySelectorFrameParent->myViewNet->getUndoList()->end();
467 }
468 }
469 return 1;
470}
471
472
473long
475 // begin undoList operation
476 mySelectorFrameParent->getViewNet()->getUndoList()->begin(Supermode::NETWORK, GUIIcon::SIMPLIFYNETWORK, TL("reduce network"));
477 // invert and clear
478 onCmdInvert(0, 0, 0);
479 onCmdDelete(0, 0, 0);
480 // end undoList operation
481 mySelectorFrameParent->getViewNet()->getUndoList()->end();
482 return 1;
483}
484
485
488 const auto& ACs = mySelectorFrameParent->myViewNet->getNet()->getAttributeCarriers();
489 const bool selectEdges = mySelectorFrameParent->getViewNet()->getNetworkViewOptions().selectEdges();
490 // extract all network elements
491 std::unordered_set<GNEAttributeCarrier*> networkACs;
492 // add junctions
493 for (const auto& junction : ACs->getJunctions()) {
494 networkACs.insert(junction.second);
495 // due we iterate over all junctions, only it's necessary iterate over incoming edges
496 for (const auto& incomingEdge : junction.second->getGNEIncomingEdges()) {
497 if (!filterLanes || selectEdges) {
498 networkACs.insert(incomingEdge);
499 }
500 // add lanes
501 if (!filterLanes || !selectEdges) {
502 for (const auto& lane : incomingEdge->getLanes()) {
503 networkACs.insert(lane);
504 }
505 }
506 // add connections
507 for (const auto& connection : incomingEdge->getGNEConnections()) {
508 networkACs.insert(connection);
509 }
510 }
511 // add crossings
512 for (const auto& crossing : junction.second->getGNECrossings()) {
513 networkACs.insert(crossing);
514 }
515 // add walkingArea
516 for (const auto& walkingArea : junction.second->getGNEWalkingAreas()) {
517 networkACs.insert(walkingArea);
518 }
519 }
520 // add additionals
521 for (const auto& additionalTags : ACs->getAdditionals()) {
522 for (const auto& additional : additionalTags.second) {
523 if (additional.second->getTagProperty().isSelectable()) {
524 networkACs.insert(additional.second);
525 }
526 }
527 }
528 // declare massive selection
529 GNESelectorFrame::SelectionOperation::MassiveSelection massiveSelection(ACs->getNumberOfNetworkElements());
530 // iterate over network ACs
531 for (const auto& networkAC : networkACs) {
532 const auto networkACObjectType = networkAC->getGUIGlObject()->getType();
533 // save locking status in lockedTypes
534 if (massiveSelection.lockedTypes.find(networkACObjectType) == massiveSelection.lockedTypes.end()) {
535 massiveSelection.lockedTypes[networkACObjectType] = networkAC->getGUIGlObject()->isGLObjectLocked();
536 }
537 // save element and their locking status
538 if (networkAC->isAttributeCarrierSelected()) {
539 massiveSelection.ACsToUnselect[networkAC] = massiveSelection.lockedTypes.at(networkACObjectType);
540 } else {
541 massiveSelection.ACsToSelect[networkAC] = massiveSelection.lockedTypes.at(networkACObjectType);
542 }
543 }
544 return massiveSelection;
545}
546
547
550 const auto& ACs = mySelectorFrameParent->myViewNet->getNet()->getAttributeCarriers();
551 // declare massive selection
552 GNESelectorFrame::SelectionOperation::MassiveSelection massiveSelection(ACs->getNumberOfDemandElements());
553 // iterate over selectable demand elements
554 for (const auto& demandElementTag : ACs->getDemandElements()) {
555 for (const auto& demandElement : demandElementTag.second) {
556 if (demandElement.second->getTagProperty().isSelectable()) {
557 const auto networkACObjectType = demandElement.first->getType();
558 // save locking status in lockedTypes
559 if (massiveSelection.lockedTypes.find(networkACObjectType) == massiveSelection.lockedTypes.end()) {
560 massiveSelection.lockedTypes[networkACObjectType] = demandElement.first->isGLObjectLocked();
561 }
562 // save element and their locking status
563 if (demandElement.second->isAttributeCarrierSelected()) {
564 massiveSelection.ACsToUnselect[demandElement.second] = massiveSelection.lockedTypes.at(networkACObjectType);
565 } else {
566 massiveSelection.ACsToSelect[demandElement.second] = massiveSelection.lockedTypes.at(networkACObjectType);
567 }
568 }
569 }
570 }
571 return massiveSelection;
572}
573
574
577 const auto& ACs = mySelectorFrameParent->myViewNet->getNet()->getAttributeCarriers();
578 // declare massive selection
579 GNESelectorFrame::SelectionOperation::MassiveSelection massiveSelection(ACs->getNumberOfDataElements());
580 // iterate over selectable demand elements
581 for (const auto& genericDataTag : mySelectorFrameParent->myViewNet->getNet()->getAttributeCarriers()->getGenericDatas()) {
582 for (const auto& genericData : genericDataTag.second) {
583 if (genericData.second->getTagProperty().isSelectable()) {
584 const auto networkACObjectType = genericData.first->getType();
585 // save locking status in lockedTypes
586 if (massiveSelection.lockedTypes.find(networkACObjectType) == massiveSelection.lockedTypes.end()) {
587 massiveSelection.lockedTypes[networkACObjectType] = genericData.first->isGLObjectLocked();
588 }
589 // save element and their locking status
590 if (genericData.second->isAttributeCarrierSelected()) {
591 massiveSelection.ACsToUnselect[genericData.second] = massiveSelection.lockedTypes.at(networkACObjectType);
592 } else {
593 massiveSelection.ACsToSelect[genericData.second] = massiveSelection.lockedTypes.at(networkACObjectType);
594 }
595 }
596 }
597 }
598 return massiveSelection;
599}
600
601
602bool
604 WRITE_DEBUG("Opening FXMessageBox 'confirm selection operation'");
605 // open question box
606 const FXuint answer = FXMessageBox::question(mySelectorFrameParent->getViewNet()->getApp(),
607 MBOX_YES_NO, "Confirm selection operation", "There are locked elements in the current selection.\nApply operation to locked elements?");
608 if (answer != 1) { //1:yes, 2:no, 4:esc
609 // write warning if netedit is running in testing mode
610 if (answer == 2) {
611 WRITE_DEBUG("Closed FXMessageBox 'confirm selection operation' with 'No'");
612 } else if (answer == 4) {
613 WRITE_DEBUG("Closed FXMessageBox 'confirm selection operation' with 'ESC'");
614 }
615 return false;
616 } else {
617 // write warning if netedit is running in testing mode
618 WRITE_DEBUG("Closed FXMessageBox 'confirm selection operation' with 'Yes'");
619 return true;
620 }
621}
622
623// ---------------------------------------------------------------------------
624// ModificationMode::SelectionOperation::SelectionHierarchy - methods
625// ---------------------------------------------------------------------------
626
628 ACsToSelect.reserve(bucketSize);
629 ACsToUnselect.reserve(bucketSize);
630}
631
632
634
635
637 return (ACsToSelect.size() + ACsToUnselect.size()) > 0;
638}
639
640
642
643// ---------------------------------------------------------------------------
644// ModificationMode::SelectionHierarchy - methods
645// ---------------------------------------------------------------------------
646
648 MFXGroupBoxModule(selectorFrameParent, TL("Hierarchy operations")),
649 mySelectorFrameParent(selectorFrameParent),
650 myCurrentSelectedParent(Selection::ALL),
651 myCurrentSelectedChild(Selection::ALL) {
652 // create label for parents
653 new FXLabel(getCollapsableFrame(), TL("Select parents"), nullptr, GUIDesignLabelThick(JUSTIFY_NORMAL));
654 // Create MFXComboBoxIcon for parent comboBox
657 // create parent buttons
658 FXHorizontalFrame* parentButtons = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame);
659 // Create "select" Button
661 // Create "unselect" Button
663 // create label for parents
664 new FXLabel(getCollapsableFrame(), TL("Select children"), nullptr, GUIDesignLabelThick(JUSTIFY_NORMAL));
665 // Create MFXComboBoxIcon for parent comboBox
668 // create children buttons
669 FXHorizontalFrame* childrenButtons = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame);
670 // Create "select" Button
672 // Create "unselect" Button
674 // fill comboBoxes
675 for (const auto& item : myItems) {
676 myParentsComboBox->appendIconItem(item.second.c_str());
677 myChildrenComboBox->appendIconItem(item.second.c_str());
678 }
679}
680
681
683
684
685long
687 if (obj == myParentsComboBox) {
688 for (const auto& item : myItems) {
689 if (item.second == myParentsComboBox->getText().text()) {
690 // enable buttons
691 mySelectParentsButton->enable();
692 myUnselectParentsButton->enable();
693 // change text color
694 myParentsComboBox->setTextColor(FXRGB(0, 0, 0));
695 // set current selected parent
696 myCurrentSelectedParent = item.first;
697 return 1;
698 }
699 }
700 // item not found
701 myCurrentSelectedParent = Selection::NOTHING;
702 // disable buttons
703 mySelectParentsButton->disable();
704 myUnselectParentsButton->disable();
705 myParentsComboBox->setTextColor(FXRGB(255, 0, 0));
706 return 1;
707 } else if (obj == myChildrenComboBox) {
708 for (const auto& item : myItems) {
709 if (item.second == myChildrenComboBox->getText().text()) {
710 // enable buttons
711 mySelectChildrenButton->enable();
712 myUnselectChildrenButton->enable();
713 // change text color
714 myChildrenComboBox->setTextColor(FXRGB(0, 0, 0));
715 // set current selected parent
716 myCurrentSelectedChild = item.first;
717 return 1;
718 }
719 }
720 // item not found
721 myCurrentSelectedChild = Selection::NOTHING;
722 // disable buttons
723 mySelectChildrenButton->disable();
724 myUnselectChildrenButton->disable();
725 myChildrenComboBox->setTextColor(FXRGB(255, 0, 0));
726 return 1;
727 }
728 return 0;
729}
730
731
732long
733GNESelectorFrame::SelectionHierarchy::onCmdParents(FXObject* obj, FXSelector, void*) {
734 // get selected elements
735 const auto selectedACs = mySelectorFrameParent->getViewNet()->getNet()->getAttributeCarriers()->getSelectedAttributeCarriers(true);
736 // check if there is selected ACs
737 if ((selectedACs.size() > 0) && (myCurrentSelectedParent != Selection::NOTHING)) {
738 // vector of hierarchical elements to select
739 std::vector<GNEHierarchicalElement*> HEToSelect;
740 for (const auto& selectedAC : selectedACs) {
741 // get hierarchical element
742 const auto HE = selectedAC->getHierarchicalElement();
743 // junctions
744 if ((myCurrentSelectedParent == Selection::ALL) || (myCurrentSelectedParent == Selection::JUNCTION)) {
745 HEToSelect.insert(HEToSelect.end(), HE->getParentJunctions().begin(), HE->getParentJunctions().end());
746 }
747 // edges
748 if ((myCurrentSelectedParent == Selection::ALL) || (myCurrentSelectedParent == Selection::EDGE)) {
749 if (selectedAC->getTagProperty().getTag() == SUMO_TAG_LANE) {
750 // special case for lanes
751 HEToSelect.push_back(dynamic_cast<GNELane*>(selectedAC)->getParentEdge());
752 } else {
753 HEToSelect.insert(HEToSelect.end(), HE->getParentEdges().begin(), HE->getParentEdges().end());
754 }
755 }
756 // lanes
757 if ((myCurrentSelectedParent == Selection::ALL) || (myCurrentSelectedParent == Selection::LANE)) {
758 HEToSelect.insert(HEToSelect.end(), HE->getParentLanes().begin(), HE->getParentLanes().end());
759 }
760 // additional
761 if ((myCurrentSelectedParent == Selection::ALL) || (myCurrentSelectedParent == Selection::ADDITIONAL)) {
762 HEToSelect.insert(HEToSelect.end(), HE->getParentAdditionals().begin(), HE->getParentAdditionals().end());
763 }
764 // wire
765 if ((myCurrentSelectedParent == Selection::ALL) || (myCurrentSelectedParent == Selection::WIRE)) {
766 HEToSelect.insert(HEToSelect.end(), HE->getParentAdditionals().begin(), HE->getParentAdditionals().end());
767 }
768 // demand
769 if ((myCurrentSelectedParent == Selection::ALL) || (myCurrentSelectedParent == Selection::DEMAND)) {
770 HEToSelect.insert(HEToSelect.end(), HE->getParentDemandElements().begin(), HE->getParentDemandElements().end());
771 }
772 // data
773 if ((myCurrentSelectedParent == Selection::ALL) || (myCurrentSelectedParent == Selection::DATA)) {
774 HEToSelect.insert(HEToSelect.end(), HE->getParentGenericDatas().begin(), HE->getParentGenericDatas().end());
775 }
776 }
777 // select HE
778 if (HEToSelect.size() > 0) {
779 if (HEToSelect.size() > 1) {
780 mySelectorFrameParent->getViewNet()->getUndoList()->begin(GUIIcon::SELECT, TL("select parents"));
781 }
782 for (const auto& HE : HEToSelect) {
783 if (obj == mySelectParentsButton) {
784 HE->setAttribute(GNE_ATTR_SELECTED, "true", mySelectorFrameParent->getViewNet()->getUndoList());
785 } else {
786 HE->setAttribute(GNE_ATTR_SELECTED, "false", mySelectorFrameParent->getViewNet()->getUndoList());
787 }
788 }
789 if (HEToSelect.size() > 1) {
790 mySelectorFrameParent->getViewNet()->getUndoList()->end();
791 }
792 }
793 // update information label
794 mySelectorFrameParent->mySelectionInformation->updateInformationLabel();
795 // update viewNet
796 mySelectorFrameParent->getViewNet()->update();
797 }
798 return 1;
799}
800
801
802long
804 // get selected elements
805 const auto selectedACs = mySelectorFrameParent->getViewNet()->getNet()->getAttributeCarriers()->getSelectedAttributeCarriers(true);
806 // check if there is selected ACs
807 if ((selectedACs.size() > 0) && (myCurrentSelectedChild != Selection::NOTHING)) {
808 // vector of hierarchical elements to select
809 std::vector<GNEHierarchicalElement*> HEToSelect;
810 for (const auto& selectedAC : selectedACs) {
811 // get hierarchical element
812 const auto HE = selectedAC->getHierarchicalElement();
813 // junctions
814 if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::JUNCTION)) {
815 if (selectedAC->getTagProperty().getTag() == SUMO_TAG_JUNCTION) {
816 // special case for junction
817 const auto junction = dynamic_cast<GNEJunction*>(selectedAC);
818 // insert edges
819 HEToSelect.insert(HEToSelect.end(), junction->getGNEIncomingEdges().begin(), junction->getGNEIncomingEdges().end());
820 HEToSelect.insert(HEToSelect.end(), junction->getGNEOutgoingEdges().begin(), junction->getGNEOutgoingEdges().end());
821 } else {
822 HEToSelect.insert(HEToSelect.end(), HE->getChildJunctions().begin(), HE->getChildJunctions().end());
823 }
824 }
825 // edges
826 if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::EDGE)) {
827 if (selectedAC->getTagProperty().getTag() == SUMO_TAG_EDGE) {
828 // special case for edges
829 const auto edge = dynamic_cast<GNEEdge*>(selectedAC);
830 // insert lanes
831 HEToSelect.insert(HEToSelect.end(), edge->getLanes().begin(), edge->getLanes().end());
832 } else {
833 HEToSelect.insert(HEToSelect.end(), HE->getChildEdges().begin(), HE->getChildEdges().end());
834 }
835 }
836 // connections
837 if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::CONNECTION)) {
838 if (selectedAC->getTagProperty().getTag() == SUMO_TAG_EDGE) {
839 // case for edges
840 const auto edge = dynamic_cast<GNEEdge*>(selectedAC);
841 // insert connections
842 HEToSelect.insert(HEToSelect.end(), edge->getGNEConnections().begin(), edge->getGNEConnections().end());
843 } else if (selectedAC->getTagProperty().getTag() == SUMO_TAG_LANE) {
844 // case for lanes
845 const auto lane = dynamic_cast<GNELane*>(selectedAC);
846 // insert connections
847 for (const auto& connection : lane->getParentEdge()->getGNEConnections()) {
848 if (connection->getAttribute(SUMO_ATTR_FROM_LANE) == lane->getAttribute(SUMO_ATTR_INDEX)) {
849 HEToSelect.push_back(connection);
850 }
851 }
852 } else if (selectedAC->getTagProperty().getTag() == SUMO_TAG_JUNCTION) {
853 // case for junction
854 const auto junction = dynamic_cast<GNEJunction*>(selectedAC);
855 // get connections
856 const auto connections = junction->getGNEConnections();
857 // insert connections
858 HEToSelect.insert(HEToSelect.end(), connections.begin(), connections.end());
859 }
860 }
861 // crossings
862 if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::CROSSING)) {
863 if (selectedAC->getTagProperty().getTag() == SUMO_TAG_JUNCTION) {
864 // case for junction
865 const auto junction = dynamic_cast<GNEJunction*>(selectedAC);
866 // insert crossings
867 HEToSelect.insert(HEToSelect.end(), junction->getGNECrossings().begin(), junction->getGNECrossings().end());
868 }
869 }
870 // lanes
871 if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::LANE)) {
872 HEToSelect.insert(HEToSelect.end(), HE->getChildLanes().begin(), HE->getChildLanes().end());
873 }
874 // additional
875 if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::ADDITIONAL)) {
876 // avoid insert symbols
877 for (const auto& additionalChild : HE->getChildAdditionals()) {
878 if (!additionalChild->getTagProperty().isWireElement() && !additionalChild->getTagProperty().isSymbol()) {
879 HEToSelect.push_back(additionalChild);
880 }
881 }
882 }
883 // wire
884 if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::WIRE)) {
885 // avoid insert symbols
886 for (const auto& wireChild : HE->getChildAdditionals()) {
887 if (wireChild->getTagProperty().isWireElement() && !wireChild->getTagProperty().isSymbol()) {
888 HEToSelect.push_back(wireChild);
889 }
890 }
891 }
892 // demand
893 if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::DEMAND)) {
894 HEToSelect.insert(HEToSelect.end(), HE->getChildDemandElements().begin(), HE->getChildDemandElements().end());
895 }
896 // data
897 if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::DATA)) {
898 HEToSelect.insert(HEToSelect.end(), HE->getChildGenericDatas().begin(), HE->getChildGenericDatas().end());
899 }
900 }
901 // select HE
902 if (HEToSelect.size() > 0) {
903 if (HEToSelect.size() > 1) {
904 mySelectorFrameParent->getViewNet()->getUndoList()->begin(GUIIcon::SELECT, TL("select children"));
905 }
906 for (const auto& HE : HEToSelect) {
907 if (obj == mySelectChildrenButton) {
908 HE->setAttribute(GNE_ATTR_SELECTED, "true", mySelectorFrameParent->getViewNet()->getUndoList());
909 } else {
910 HE->setAttribute(GNE_ATTR_SELECTED, "false", mySelectorFrameParent->getViewNet()->getUndoList());
911 }
912 }
913 if (HEToSelect.size() > 1) {
914 mySelectorFrameParent->getViewNet()->getUndoList()->end();
915 }
916 }
917 // update information label
918 mySelectorFrameParent->mySelectionInformation->updateInformationLabel();
919 // update viewNet
920 mySelectorFrameParent->getViewNet()->update();
921 }
922 return 1;
923}
924
925// ---------------------------------------------------------------------------
926// GNECrossingFrame::Legend - methods
927// ---------------------------------------------------------------------------
928
930 MFXGroupBoxModule(selectorFrameParent, TL("Information")) {
931 // Create Selection Hint
932 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);
933}
934
935
937
938// ---------------------------------------------------------------------------
939// GNESelectorFrame - methods
940// ---------------------------------------------------------------------------
941
943 GNEFrame(viewParent, viewNet, TL("Selection")) {
944 // create selection information
946 // create Modification Mode modul
948 // create ElementSet modul
952 // create VisualScaling modul
953 myVisualScaling = new VisualScaling(this);
954 // create SelectionOperation modul
956 // create SelectionHierarchy modul
958 // create Information modul
959 myInformation = new Information(this);
960}
961
962
964
965
966void
968 // refresh element set
970 // only show network element set
975 // only show demand element set
980 // only show data element set
984 }
985 // update information label
987 // Show frame
989}
990
991
992void
994 // hide frame
996}
997
998
999void
1004
1005
1006void
1010
1011
1012bool
1014 // get front AC
1015 auto AC = viewObjects.getAttributeCarrierFront();
1016 // check AC
1017 if (AC == nullptr) {
1018 return false;
1019 }
1020 // check locking
1021 if (myViewNet->getLockManager().isObjectLocked(AC->getGUIGlObject()->getType(), AC->isAttributeCarrierSelected())) {
1022 return false;
1023 }
1024 // check modes
1025 if ((AC->getTagProperty().isNetworkElement() || AC->getTagProperty().isAdditionalElement()) &&
1027 return false;
1028 }
1029 if (AC->getTagProperty().isDemandElement() && !myViewNet->getEditModes().isCurrentSupermodeDemand()) {
1030 return false;
1031 }
1032 if (AC->getTagProperty().isDataElement() && !myViewNet->getEditModes().isCurrentSupermodeData()) {
1033 return false;
1034 }
1035 // filter GLObjects by layer
1036 auto filteredGLObjects = GNEViewNetHelper::filterElementsByLayer(viewObjects.getGLObjects());
1037 // check if we have to open dialog
1038 if (filteredGLObjects.size() > 1) {
1039 myViewNet->openSelectDialogAtCursor(filteredGLObjects);
1040 } else {
1041 // toggle selection
1042 if (AC->isAttributeCarrierSelected()) {
1043 AC->unselectAttributeCarrier();
1044 } else {
1045 AC->selectAttributeCarrier();
1046 }
1047 // update information label
1049 }
1050 return true;
1051}
1052
1053
1054void
1055GNESelectorFrame::handleIDs(const std::vector<GNEAttributeCarrier*>& ACs, const ModificationMode::Operation setop) {
1056 // declare set operation
1058 // declare two sets of attribute carriers, one for select and another for unselect
1059 std::set<std::pair<std::string, GNEAttributeCarrier*> > ACsToSelect, ACsToUnselect;
1060 // in restrict AND replace mode all current selected attribute carriers will be unselected
1061 if ((setOperation == ModificationMode::Operation::REPLACE) || (setOperation == ModificationMode::Operation::RESTRICT)) {
1062 // obtain selected ACs depending of current supermode
1063 auto selectedACs = myViewNet->getNet()->getAttributeCarriers()->getSelectedAttributeCarriers(false);
1064 // add id into ACs to unselect
1065 for (const auto& selectedAC : selectedACs) {
1066 ACsToUnselect.insert(std::make_pair(selectedAC->getID(), selectedAC));
1067 }
1068 }
1069 // handle ids
1070 for (const auto& AC : ACs) {
1071 // iterate over AttributeCarriers an place it in ACsToSelect or ACsToUnselect
1072 switch (setOperation) {
1074 ACsToUnselect.insert(std::make_pair(AC->getID(), AC));
1075 break;
1077 if (ACsToUnselect.find(std::make_pair(AC->getID(), AC)) != ACsToUnselect.end()) {
1078 ACsToSelect.insert(std::make_pair(AC->getID(), AC));
1079 }
1080 break;
1081 default:
1082 ACsToSelect.insert(std::make_pair(AC->getID(), AC));
1083 break;
1084 }
1085 }
1086 // select junctions and their connections if Auto select junctions is enabled (note: only for "add mode")
1088 std::set<GNEEdge*> edgesToSelect;
1089 // iterate over ACsToSelect and extract edges
1090 for (const auto& AC : ACsToSelect) {
1091 if (AC.second->getTagProperty().getTag() == SUMO_TAG_EDGE) {
1092 edgesToSelect.insert(myViewNet->getNet()->getAttributeCarriers()->retrieveEdge(AC.second->getID()));
1093 }
1094 }
1095 // iterate over extracted edges
1096 for (const auto& edgeToSelect : edgesToSelect) {
1097 // select junction source and all connections, crossings and walkingAreas
1098 ACsToSelect.insert(std::make_pair(edgeToSelect->getFromJunction()->getID(), edgeToSelect->getFromJunction()));
1099 for (const auto& connectionToSelect : edgeToSelect->getFromJunction()->getGNEConnections()) {
1100 ACsToSelect.insert(std::make_pair(connectionToSelect->getID(), connectionToSelect));
1101 }
1102 for (const auto& fromCrossingToSelect : edgeToSelect->getFromJunction()->getGNECrossings()) {
1103 ACsToSelect.insert(std::make_pair(fromCrossingToSelect->getID(), fromCrossingToSelect));
1104 }
1105 for (const auto& fromWalkingAreaToSelect : edgeToSelect->getFromJunction()->getGNEWalkingAreas()) {
1106 ACsToSelect.insert(std::make_pair(fromWalkingAreaToSelect->getID(), fromWalkingAreaToSelect));
1107 }
1108 // select junction destination and all connections, crossings and walkingAreas
1109 ACsToSelect.insert(std::make_pair(edgeToSelect->getToJunction()->getID(), edgeToSelect->getToJunction()));
1110 for (const auto& connectionToSelect : edgeToSelect->getToJunction()->getGNEConnections()) {
1111 ACsToSelect.insert(std::make_pair(connectionToSelect->getID(), connectionToSelect));
1112 }
1113 for (const auto& toCrossingToSelect : edgeToSelect->getToJunction()->getGNECrossings()) {
1114 ACsToSelect.insert(std::make_pair(toCrossingToSelect->getID(), toCrossingToSelect));
1115 }
1116 for (const auto& toWalkingAreaToSelect : edgeToSelect->getToJunction()->getGNEWalkingAreas()) {
1117 ACsToSelect.insert(std::make_pair(toWalkingAreaToSelect->getID(), toWalkingAreaToSelect));
1118 }
1119 }
1120 }
1121 // only continue if there is ACs to select or unselect
1122 if ((ACsToSelect.size() + ACsToUnselect.size()) > 0) {
1123 // first unselect AC of ACsToUnselect and then selects AC of ACsToSelect
1125 for (const auto& ACToUnselect : ACsToUnselect) {
1126 if (ACToUnselect.second->getTagProperty().isSelectable()) {
1127 ACToUnselect.second->setAttribute(GNE_ATTR_SELECTED, "false", myViewNet->getUndoList());
1128 }
1129 }
1130 for (const auto& ACToSelect : ACsToSelect) {
1131 if (ACToSelect.second->getTagProperty().isSelectable()) {
1132 ACToSelect.second->setAttribute(GNE_ATTR_SELECTED, "true", myViewNet->getUndoList());
1133 }
1134 }
1135 // finish operation
1137 }
1138}
1139
1140
1141std::vector<GNEAttributeCarrier*>
1142GNESelectorFrame::getMatches(const SumoXMLTag ACTag, const SumoXMLAttr ACAttr, const char compOp, const double val, const std::string& expr) {
1143 std::vector<GNEAttributeCarrier*> result;
1144 // first retrieve all ACs using ACTag
1145 const auto allACbyTag = myViewNet->getNet()->getAttributeCarriers()->retrieveAttributeCarriers(ACTag);
1146 // get Tag value
1147 const auto& tagValue = GNEAttributeCarrier::getTagProperty(ACTag);
1148 // iterate over all ACs
1149 for (const auto& AC : allACbyTag) {
1150 if (expr == "" && compOp == '@') {
1151 result.push_back(AC);
1152 } else if (tagValue.hasAttribute(ACAttr) && tagValue.getAttributeProperties(ACAttr).isNumerical()) {
1153 double acVal;
1154 std::istringstream buf(AC->getAttribute(ACAttr));
1155 buf >> acVal;
1156 switch (compOp) {
1157 case '<':
1158 if (acVal < val) {
1159 result.push_back(AC);
1160 }
1161 break;
1162 case '>':
1163 if (acVal > val) {
1164 result.push_back(AC);
1165 }
1166 break;
1167 case '=':
1168 if (acVal == val) {
1169 result.push_back(AC);
1170 }
1171 break;
1172 }
1173 } else {
1174 // string match
1175 std::string acVal = AC->getAttributeForSelection(ACAttr);
1176 switch (compOp) {
1177 case '@':
1178 if (acVal.find(expr) != std::string::npos) {
1179 result.push_back(AC);
1180 }
1181 break;
1182 case '!':
1183 if (acVal.find(expr) == std::string::npos) {
1184 result.push_back(AC);
1185 }
1186 break;
1187 case '=':
1188 if (acVal == expr) {
1189 result.push_back(AC);
1190 }
1191 break;
1192 case '^':
1193 if (acVal != expr) {
1194 result.push_back(AC);
1195 }
1196 break;
1197 }
1198 }
1199 }
1200 return result;
1201}
1202
1203
1204std::vector<GNEAttributeCarrier*>
1205GNESelectorFrame::getGenericMatches(const std::vector<GNEGenericData*>& genericDatas, const std::string& attr, const char compOp, const double val, const std::string& expr) {
1206 std::vector<GNEAttributeCarrier*> result;
1207 // iterate over generic datas
1208 for (const auto& genericData : genericDatas) {
1209 if (expr == "" && compOp == '@') {
1210 result.push_back(genericData);
1211 } else if (attr != toString(GNE_ATTR_PARENT)) {
1212 double acVal;
1213 std::istringstream buf(genericData->getParameter(attr, "0"));
1214 buf >> acVal;
1215 switch (compOp) {
1216 case '<':
1217 if (acVal < val) {
1218 result.push_back(genericData);
1219 }
1220 break;
1221 case '>':
1222 if (acVal > val) {
1223 result.push_back(genericData);
1224 }
1225 break;
1226 case '=':
1227 if (acVal == val) {
1228 result.push_back(genericData);
1229 }
1230 break;
1231 }
1232 } else {
1233 // string match
1234 std::string acVal = genericData->getAttributeForSelection(GNE_ATTR_PARENT);
1235 switch (compOp) {
1236 case '@':
1237 if (acVal.find(expr) != std::string::npos) {
1238 result.push_back(genericData);
1239 }
1240 break;
1241 case '!':
1242 if (acVal.find(expr) == std::string::npos) {
1243 result.push_back(genericData);
1244 }
1245 break;
1246 case '=':
1247 if (acVal == expr) {
1248 result.push_back(genericData);
1249 }
1250 break;
1251 case '^':
1252 if (acVal != expr) {
1253 result.push_back(genericData);
1254 }
1255 break;
1256 }
1257 }
1258 }
1259 return result;
1260}
1261
1262
1263FXVerticalFrame*
1267
1268
1273
1274
1279
1280
1285
1286/****************************************************************************/
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:603
@ MID_CHOOSEN_INVERT
Deselect selected items.
Definition GUIAppEnum.h:615
@ MID_CHOOSEN_DELETE
delete set
Definition GUIAppEnum.h:607
@ MID_CHOOSEN_OPERATION
set type of selection
Definition GUIAppEnum.h:597
@ MID_CHOOSEN_LOAD
Load set.
Definition GUIAppEnum.h:601
@ MID_CHOOSEN_REDUCE
simplify network reduction
Definition GUIAppEnum.h:619
@ MID_CHOOSEN_CLEAR
Clear set.
Definition GUIAppEnum.h:605
@ MID_GNE_SELECT
select element
Definition GUIAppEnum.h:957
@ MID_GNE_SELECTORFRAME_PARENTS
select/unselect parents
#define GUIDesignSpinDial
Definition GUIDesigns.h:488
#define GUIDesignButton
Definition GUIDesigns.h:88
#define GUIDesignComboBox
Definition GUIDesigns.h:299
#define GUIDesignComboBoxNCol
number of column of every combo box
Definition GUIDesigns.h:317
#define GUIDesignAuxiliarHorizontalFrame
design for auxiliar (Without borders) horizontal frame used to pack another frames
Definition GUIDesigns.h:405
#define GUIDesignComboBoxVisibleItemsMedium
combo box medium small
Definition GUIDesigns.h:53
#define GUIDesignLabelThick(justify)
label extended over frame with thick and with text justify to left
Definition GUIDesigns.h:255
#define GUIDesignRadioButton
Definition GUIDesigns.h:235
#define GUIDesignLabelFrameInformation
label extended over frame without thick and with text justify to left, used to show information in fr...
Definition GUIDesigns.h:285
FXString gCurrentFolder
The folder used as last.
@ OPEN
open icons
@ SIMPLIFYNETWORK
@ SAVE
save icons
#define WRITE_DEBUG(msg)
Definition MsgHandler.h:306
#define WRITE_ERRORF(...)
Definition MsgHandler.h:305
#define TL(string)
Definition MsgHandler.h:315
SumoXMLTag
Numbers representing SUMO-XML - element names.
@ GNE_TAG_EDGEREL_SINGLE
@ SUMO_TAG_VEHICLE
description of a vehicle
@ SUMO_TAG_JUNCTION
begin/end of the description of a junction
@ SUMO_TAG_LANE
begin/end of the description of a single lane
@ 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:196
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:127
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
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
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 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
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 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:71
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
ComboBox with icon.
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.
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.
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.
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