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 // obtain undoList (only for improve code legibly)
376 GNEUndoList* undoList = mySelectorFrameParent->myViewNet->getUndoList();
377 // get element to select/unselect depending of current supermode
378 std::pair<std::vector<std::pair<bool, GNEAttributeCarrier*> >, std::vector<std::pair<bool, GNEAttributeCarrier*> > > ACsToSelectUnselect;
379 if (mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeNetwork()) {
380 ACsToSelectUnselect = processMassiveNetworkElementSelection(false);
381 } else if (mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeDemand()) {
382 ACsToSelectUnselect = processMassiveDemandElementSelection();
383 } else if (mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeData()) {
384 ACsToSelectUnselect = processMassiveDataElementSelection();
385 }
386 // only continue if there are elements to unselect
387 if (ACsToSelectUnselect.second.size() > 0) {
388 // check if add locked elements
389 bool askedContinueIfLock = false;
390 bool addLockedElements = false;
391 bool unlockedElements = false;
392 for (const auto& AC : ACsToSelectUnselect.second) {
393 if (AC.first == false) {
394 // there are unlocked elements
395 unlockedElements = true;
396 } else if (!askedContinueIfLock) {
397 addLockedElements = askContinueIfLock();
398 // only ask one time for locking
399 askedContinueIfLock = true;
400 }
401 }
402 if (unlockedElements || addLockedElements) {
403 mySelectorFrameParent->myViewNet->getUndoList()->begin(GUIIcon::MODESELECT, TL("clear selection"));
404 for (const auto& AC : ACsToSelectUnselect.second) {
405 if (addLockedElements || !AC.first) {
406 AC.second->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
407 }
408 }
409 mySelectorFrameParent->myViewNet->getUndoList()->end();
410 }
411 }
412 return 1;
413}
414
415long
417 // acts like the 'del' hotkey
418 mySelectorFrameParent->getViewNet()->hotkeyDel();
419 return 1;
420}
421
422
423long
425 // obtain undoList (only for improve code legibly)
426 GNEUndoList* undoList = mySelectorFrameParent->myViewNet->getUndoList();
427 // get element to select/unselect depending of current supermode
428 std::pair<std::vector<std::pair<bool, GNEAttributeCarrier*> >, std::vector<std::pair<bool, GNEAttributeCarrier*> > > ACsToSelectUnselect;
429 if (mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeNetwork()) {
430 ACsToSelectUnselect = processMassiveNetworkElementSelection(true);
431 } else if (mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeDemand()) {
432 ACsToSelectUnselect = processMassiveDemandElementSelection();
433 } else if (mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeData()) {
434 ACsToSelectUnselect = processMassiveDataElementSelection();
435 }
436 // only continue if there are elements to select and unselect
437 if ((ACsToSelectUnselect.first.size() + ACsToSelectUnselect.second.size()) > 0) {
438 // check if add locked elements
439 bool askedContinueIfLock = false;
440 bool addLockedElements = false;
441 bool unlockedElements = false;
442 for (const auto& AC : ACsToSelectUnselect.first) {
443 if (AC.first == false) {
444 // there are unlocked elements
445 unlockedElements = true;
446 } else if (!askedContinueIfLock) {
447 addLockedElements = askContinueIfLock();
448 // only ask one time for locking
449 askedContinueIfLock = true;
450 }
451 }
452 for (const auto& AC : ACsToSelectUnselect.second) {
453 if (AC.first == false) {
454 // there are unlocked elements
455 unlockedElements = true;
456 } else if (!askedContinueIfLock) {
457 addLockedElements = askContinueIfLock();
458 // only ask one time for locking
459 askedContinueIfLock = true;
460 }
461 }
462 if (unlockedElements || addLockedElements) {
463 mySelectorFrameParent->myViewNet->getUndoList()->begin(GUIIcon::MODESELECT, TL("invert selection"));
464 for (const auto& AC : ACsToSelectUnselect.first) {
465 if (addLockedElements || !AC.first) {
466 AC.second->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
467 }
468 }
469 for (const auto& AC : ACsToSelectUnselect.second) {
470 if (addLockedElements || !AC.first) {
471 AC.second->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
472 }
473 }
474 mySelectorFrameParent->myViewNet->getUndoList()->end();
475 }
476 }
477 return 1;
478}
479
480
481long
483 // begin undoList operation
484 mySelectorFrameParent->getViewNet()->getUndoList()->begin(Supermode::NETWORK, GUIIcon::SIMPLIFYNETWORK, TL("reduce network"));
485 // invert and clear
486 onCmdInvert(0, 0, 0);
487 onCmdDelete(0, 0, 0);
488 // end undoList operation
489 mySelectorFrameParent->getViewNet()->getUndoList()->end();
490 return 1;
491}
492
493
494std::pair<std::vector<std::pair<bool, GNEAttributeCarrier*> >, std::vector<std::pair<bool, GNEAttributeCarrier*> > >
496 // get attribute carriers (only for improve code legibly)
497 const auto& ACs = mySelectorFrameParent->myViewNet->getNet()->getAttributeCarriers();
498 // extract all network elements
499 std::vector<GNEAttributeCarrier*> networkACs;
500 // add junctions
501 for (const auto& junction : ACs->getJunctions()) {
502 networkACs.push_back(junction.second);
503 // due we iterate over all junctions, only it's necessary iterate over incoming edges
504 for (const auto& incomingEdge : junction.second->getGNEIncomingEdges()) {
505 if (!filterLanes || mySelectorFrameParent->getViewNet()->getNetworkViewOptions().selectEdges()) {
506 networkACs.push_back(incomingEdge);
507 }
508 // add lanes
509 if (!filterLanes || !mySelectorFrameParent->getViewNet()->getNetworkViewOptions().selectEdges()) {
510 for (const auto& lane : incomingEdge->getLanes()) {
511 networkACs.push_back(lane);
512 }
513 }
514 // add connections
515 for (const auto& connection : incomingEdge->getGNEConnections()) {
516 networkACs.push_back(connection);
517 }
518 }
519 // add crossings
520 for (const auto& crossing : junction.second->getGNECrossings()) {
521 networkACs.push_back(crossing);
522 }
523 // add walkingArea
524 for (const auto& walkingArea : junction.second->getGNEWalkingAreas()) {
525 networkACs.push_back(walkingArea);
526 }
527 }
528 // add additionals
529 for (const auto& additionalTags : ACs->getAdditionals()) {
530 for (const auto& additional : additionalTags.second) {
531 if (additional.second->getTagProperty().isSelectable()) {
532 networkACs.push_back(additional.second);
533 }
534 }
535 }
536 // declare set of checked GLTypes to avoid unnecessary calls to isGLObjectLocked()
537 std::map<GUIGlObjectType, bool> checkedTypes;
538 // declare vector in which save ACs to select and unselect
539 std::pair<std::vector<std::pair<bool, GNEAttributeCarrier*> >, std::vector<std::pair<bool, GNEAttributeCarrier*> > > ACsToSelectUnselect;
540 // iterate over network ACs
541 for (const auto& networkAC : networkACs) {
542 const auto networkACObjectType = networkAC->getGUIGlObject()->getType();
543 // save locking status in checkedTypes
544 if (checkedTypes.find(networkACObjectType) == checkedTypes.end()) {
545 checkedTypes[networkACObjectType] = networkAC->getGUIGlObject()->isGLObjectLocked();
546 }
547 // save element and their locking status
548 if (networkAC->isAttributeCarrierSelected()) {
549 ACsToSelectUnselect.second.push_back(std::make_pair(checkedTypes.at(networkACObjectType), networkAC));
550 } else {
551 ACsToSelectUnselect.first.push_back(std::make_pair(checkedTypes.at(networkACObjectType), networkAC));
552 }
553 }
554 return ACsToSelectUnselect;
555}
556
557
558std::pair<std::vector<std::pair<bool, GNEAttributeCarrier*> >, std::vector<std::pair<bool, GNEAttributeCarrier*> > >
560 // declare set of checked GLTypes to avoid unnecessary calls to isGLObjectLocked()
561 std::map<GUIGlObjectType, bool> checkedTypes;
562 // declare vector in which save ACs to select and unselect
563 std::pair<std::vector<std::pair<bool, GNEAttributeCarrier*> >, std::vector<std::pair<bool, GNEAttributeCarrier*> > > ACsToSelectUnselect;
564 // iterate over selectable demand elements
565 for (const auto& demandElementTag : mySelectorFrameParent->myViewNet->getNet()->getAttributeCarriers()->getDemandElements()) {
566 for (const auto& demandElement : demandElementTag.second) {
567 if (demandElement.second->getTagProperty().isSelectable()) {
568 const auto networkACObjectType = demandElement.first->getType();
569 // save locking status in checkedTypes
570 if (checkedTypes.find(networkACObjectType) == checkedTypes.end()) {
571 checkedTypes[networkACObjectType] = demandElement.first->isGLObjectLocked();
572 }
573 // save element and their locking status
574 if (demandElement.second->isAttributeCarrierSelected()) {
575 ACsToSelectUnselect.second.push_back(std::make_pair(checkedTypes.at(networkACObjectType), demandElement.second));
576 } else {
577 ACsToSelectUnselect.first.push_back(std::make_pair(checkedTypes.at(networkACObjectType), demandElement.second));
578 }
579 }
580 }
581 }
582 return ACsToSelectUnselect;
583}
584
585
586std::pair<std::vector<std::pair<bool, GNEAttributeCarrier*> >, std::vector<std::pair<bool, GNEAttributeCarrier*> > >
588 // declare set of checked GLTypes to avoid unnecessary calls to isGLObjectLocked()
589 std::map<GUIGlObjectType, bool> checkedTypes;
590 // declare vector in which save ACs to select and unselect
591 std::pair<std::vector<std::pair<bool, GNEAttributeCarrier*> >, std::vector<std::pair<bool, GNEAttributeCarrier*> > > ACsToSelectUnselect;
592 // iterate over selectable demand elements
593 for (const auto& genericDataTag : mySelectorFrameParent->myViewNet->getNet()->getAttributeCarriers()->getGenericDatas()) {
594 for (const auto& genericData : genericDataTag.second) {
595 if (genericData.second->getTagProperty().isSelectable()) {
596 const auto networkACObjectType = genericData.first->getType();
597 // save locking status in checkedTypes
598 if (checkedTypes.find(networkACObjectType) == checkedTypes.end()) {
599 checkedTypes[networkACObjectType] = genericData.first->isGLObjectLocked();
600 }
601 // save element and their locking status
602 if (genericData.second->isAttributeCarrierSelected()) {
603 ACsToSelectUnselect.second.push_back(std::make_pair(checkedTypes.at(networkACObjectType), genericData.second));
604 } else {
605 ACsToSelectUnselect.first.push_back(std::make_pair(checkedTypes.at(networkACObjectType), genericData.second));
606 }
607 }
608 }
609 }
610 return ACsToSelectUnselect;
611}
612
613
614bool
616 WRITE_DEBUG("Opening FXMessageBox 'confirm selection operation'");
617 // open question box
618 const FXuint answer = FXMessageBox::question(mySelectorFrameParent->getViewNet()->getApp(),
619 MBOX_YES_NO, "Confirm selection operation", "There are locked elements in the current selection.\nApply operation to locked elements?");
620 if (answer != 1) { //1:yes, 2:no, 4:esc
621 // write warning if netedit is running in testing mode
622 if (answer == 2) {
623 WRITE_DEBUG("Closed FXMessageBox 'confirm selection operation' with 'No'");
624 } else if (answer == 4) {
625 WRITE_DEBUG("Closed FXMessageBox 'confirm selection operation' with 'ESC'");
626 }
627 return false;
628 } else {
629 // write warning if netedit is running in testing mode
630 WRITE_DEBUG("Closed FXMessageBox 'confirm selection operation' with 'Yes'");
631 return true;
632 }
633}
634
635// ---------------------------------------------------------------------------
636// ModificationMode::SelectionHierarchy - methods
637// ---------------------------------------------------------------------------
638
640 MFXGroupBoxModule(selectorFrameParent, TL("Hierarchy operations")),
641 mySelectorFrameParent(selectorFrameParent),
642 myCurrentSelectedParent(Selection::ALL),
643 myCurrentSelectedChild(Selection::ALL) {
644 // create label for parents
645 new FXLabel(getCollapsableFrame(), TL("Select parents"), nullptr, GUIDesignLabelThick(JUSTIFY_NORMAL));
646 // Create MFXComboBoxIcon for parent comboBox
649 // create parent buttons
650 FXHorizontalFrame* parentButtons = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame);
651 // Create "select" Button
653 // Create "unselect" Button
655 // create label for parents
656 new FXLabel(getCollapsableFrame(), TL("Select children"), nullptr, GUIDesignLabelThick(JUSTIFY_NORMAL));
657 // Create MFXComboBoxIcon for parent comboBox
660 // create children buttons
661 FXHorizontalFrame* childrenButtons = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame);
662 // Create "select" Button
664 // Create "unselect" Button
666 // fill comboBoxes
667 for (const auto& item : myItems) {
668 myParentsComboBox->appendIconItem(item.second.c_str());
669 myChildrenComboBox->appendIconItem(item.second.c_str());
670 }
671}
672
673
675
676
677long
679 if (obj == myParentsComboBox) {
680 for (const auto& item : myItems) {
681 if (item.second == myParentsComboBox->getText().text()) {
682 // enable buttons
683 mySelectParentsButton->enable();
684 myUnselectParentsButton->enable();
685 // change text color
686 myParentsComboBox->setTextColor(FXRGB(0, 0, 0));
687 // set current selected parent
688 myCurrentSelectedParent = item.first;
689 return 1;
690 }
691 }
692 // item not found
693 myCurrentSelectedParent = Selection::NOTHING;
694 // disable buttons
695 mySelectParentsButton->disable();
696 myUnselectParentsButton->disable();
697 myParentsComboBox->setTextColor(FXRGB(255, 0, 0));
698 return 1;
699 } else if (obj == myChildrenComboBox) {
700 for (const auto& item : myItems) {
701 if (item.second == myChildrenComboBox->getText().text()) {
702 // enable buttons
703 mySelectChildrenButton->enable();
704 myUnselectChildrenButton->enable();
705 // change text color
706 myChildrenComboBox->setTextColor(FXRGB(0, 0, 0));
707 // set current selected parent
708 myCurrentSelectedChild = item.first;
709 return 1;
710 }
711 }
712 // item not found
713 myCurrentSelectedChild = Selection::NOTHING;
714 // disable buttons
715 mySelectChildrenButton->disable();
716 myUnselectChildrenButton->disable();
717 myChildrenComboBox->setTextColor(FXRGB(255, 0, 0));
718 return 1;
719 }
720 return 0;
721}
722
723
724long
725GNESelectorFrame::SelectionHierarchy::onCmdParents(FXObject* obj, FXSelector, void*) {
726 // get selected elements
727 const auto selectedACs = mySelectorFrameParent->getViewNet()->getNet()->getAttributeCarriers()->getSelectedAttributeCarriers(true);
728 // check if there is selected ACs
729 if ((selectedACs.size() > 0) && (myCurrentSelectedParent != Selection::NOTHING)) {
730 // vector of hierarchical elements to select
731 std::vector<GNEHierarchicalElement*> HEToSelect;
732 for (const auto& selectedAC : selectedACs) {
733 // get hierarchical element
734 const auto HE = selectedAC->getHierarchicalElement();
735 // junctions
736 if ((myCurrentSelectedParent == Selection::ALL) || (myCurrentSelectedParent == Selection::JUNCTION)) {
737 HEToSelect.insert(HEToSelect.end(), HE->getParentJunctions().begin(), HE->getParentJunctions().end());
738 }
739 // edges
740 if ((myCurrentSelectedParent == Selection::ALL) || (myCurrentSelectedParent == Selection::EDGE)) {
741 if (selectedAC->getTagProperty().getTag() == SUMO_TAG_LANE) {
742 // special case for lanes
743 HEToSelect.push_back(dynamic_cast<GNELane*>(selectedAC)->getParentEdge());
744 } else {
745 HEToSelect.insert(HEToSelect.end(), HE->getParentEdges().begin(), HE->getParentEdges().end());
746 }
747 }
748 // lanes
749 if ((myCurrentSelectedParent == Selection::ALL) || (myCurrentSelectedParent == Selection::LANE)) {
750 HEToSelect.insert(HEToSelect.end(), HE->getParentLanes().begin(), HE->getParentLanes().end());
751 }
752 // additional
753 if ((myCurrentSelectedParent == Selection::ALL) || (myCurrentSelectedParent == Selection::ADDITIONAL)) {
754 HEToSelect.insert(HEToSelect.end(), HE->getParentAdditionals().begin(), HE->getParentAdditionals().end());
755 }
756 // wire
757 if ((myCurrentSelectedParent == Selection::ALL) || (myCurrentSelectedParent == Selection::WIRE)) {
758 HEToSelect.insert(HEToSelect.end(), HE->getParentAdditionals().begin(), HE->getParentAdditionals().end());
759 }
760 // demand
761 if ((myCurrentSelectedParent == Selection::ALL) || (myCurrentSelectedParent == Selection::DEMAND)) {
762 HEToSelect.insert(HEToSelect.end(), HE->getParentDemandElements().begin(), HE->getParentDemandElements().end());
763 }
764 // data
765 if ((myCurrentSelectedParent == Selection::ALL) || (myCurrentSelectedParent == Selection::DATA)) {
766 HEToSelect.insert(HEToSelect.end(), HE->getParentGenericDatas().begin(), HE->getParentGenericDatas().end());
767 }
768 }
769 // select HE
770 if (HEToSelect.size() > 0) {
771 if (HEToSelect.size() > 1) {
772 mySelectorFrameParent->getViewNet()->getUndoList()->begin(GUIIcon::SELECT, TL("select parents"));
773 }
774 for (const auto& HE : HEToSelect) {
775 if (obj == mySelectParentsButton) {
776 HE->setAttribute(GNE_ATTR_SELECTED, "true", mySelectorFrameParent->getViewNet()->getUndoList());
777 } else {
778 HE->setAttribute(GNE_ATTR_SELECTED, "false", mySelectorFrameParent->getViewNet()->getUndoList());
779 }
780 }
781 if (HEToSelect.size() > 1) {
782 mySelectorFrameParent->getViewNet()->getUndoList()->end();
783 }
784 }
785 // update information label
786 mySelectorFrameParent->mySelectionInformation->updateInformationLabel();
787 // update viewNet
788 mySelectorFrameParent->getViewNet()->update();
789 }
790 return 1;
791}
792
793
794long
796 // get selected elements
797 const auto selectedACs = mySelectorFrameParent->getViewNet()->getNet()->getAttributeCarriers()->getSelectedAttributeCarriers(true);
798 // check if there is selected ACs
799 if ((selectedACs.size() > 0) && (myCurrentSelectedChild != Selection::NOTHING)) {
800 // vector of hierarchical elements to select
801 std::vector<GNEHierarchicalElement*> HEToSelect;
802 for (const auto& selectedAC : selectedACs) {
803 // get hierarchical element
804 const auto HE = selectedAC->getHierarchicalElement();
805 // junctions
806 if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::JUNCTION)) {
807 if (selectedAC->getTagProperty().getTag() == SUMO_TAG_JUNCTION) {
808 // special case for junction
809 const auto junction = dynamic_cast<GNEJunction*>(selectedAC);
810 // insert edges
811 HEToSelect.insert(HEToSelect.end(), junction->getGNEIncomingEdges().begin(), junction->getGNEIncomingEdges().end());
812 HEToSelect.insert(HEToSelect.end(), junction->getGNEOutgoingEdges().begin(), junction->getGNEOutgoingEdges().end());
813 } else {
814 HEToSelect.insert(HEToSelect.end(), HE->getChildJunctions().begin(), HE->getChildJunctions().end());
815 }
816 }
817 // edges
818 if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::EDGE)) {
819 if (selectedAC->getTagProperty().getTag() == SUMO_TAG_EDGE) {
820 // special case for edges
821 const auto edge = dynamic_cast<GNEEdge*>(selectedAC);
822 // insert lanes
823 HEToSelect.insert(HEToSelect.end(), edge->getLanes().begin(), edge->getLanes().end());
824 } else {
825 HEToSelect.insert(HEToSelect.end(), HE->getChildEdges().begin(), HE->getChildEdges().end());
826 }
827 }
828 // connections
829 if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::CONNECTION)) {
830 if (selectedAC->getTagProperty().getTag() == SUMO_TAG_EDGE) {
831 // case for edges
832 const auto edge = dynamic_cast<GNEEdge*>(selectedAC);
833 // insert connections
834 HEToSelect.insert(HEToSelect.end(), edge->getGNEConnections().begin(), edge->getGNEConnections().end());
835 } else if (selectedAC->getTagProperty().getTag() == SUMO_TAG_LANE) {
836 // case for lanes
837 const auto lane = dynamic_cast<GNELane*>(selectedAC);
838 // insert connections
839 for (const auto& connection : lane->getParentEdge()->getGNEConnections()) {
840 if (connection->getAttribute(SUMO_ATTR_FROM_LANE) == lane->getAttribute(SUMO_ATTR_INDEX)) {
841 HEToSelect.push_back(connection);
842 }
843 }
844 } else if (selectedAC->getTagProperty().getTag() == SUMO_TAG_JUNCTION) {
845 // case for junction
846 const auto junction = dynamic_cast<GNEJunction*>(selectedAC);
847 // get connections
848 const auto connections = junction->getGNEConnections();
849 // insert connections
850 HEToSelect.insert(HEToSelect.end(), connections.begin(), connections.end());
851 }
852 }
853 // crossings
854 if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::CROSSING)) {
855 if (selectedAC->getTagProperty().getTag() == SUMO_TAG_JUNCTION) {
856 // case for junction
857 const auto junction = dynamic_cast<GNEJunction*>(selectedAC);
858 // insert crossings
859 HEToSelect.insert(HEToSelect.end(), junction->getGNECrossings().begin(), junction->getGNECrossings().end());
860 }
861 }
862 // lanes
863 if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::LANE)) {
864 HEToSelect.insert(HEToSelect.end(), HE->getChildLanes().begin(), HE->getChildLanes().end());
865 }
866 // additional
867 if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::ADDITIONAL)) {
868 // avoid insert symbols
869 for (const auto& additionalChild : HE->getChildAdditionals()) {
870 if (!additionalChild->getTagProperty().isWireElement() && !additionalChild->getTagProperty().isSymbol()) {
871 HEToSelect.push_back(additionalChild);
872 }
873 }
874 }
875 // wire
876 if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::WIRE)) {
877 // avoid insert symbols
878 for (const auto& wireChild : HE->getChildAdditionals()) {
879 if (wireChild->getTagProperty().isWireElement() && !wireChild->getTagProperty().isSymbol()) {
880 HEToSelect.push_back(wireChild);
881 }
882 }
883 }
884 // demand
885 if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::DEMAND)) {
886 HEToSelect.insert(HEToSelect.end(), HE->getChildDemandElements().begin(), HE->getChildDemandElements().end());
887 }
888 // data
889 if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::DATA)) {
890 HEToSelect.insert(HEToSelect.end(), HE->getChildGenericDatas().begin(), HE->getChildGenericDatas().end());
891 }
892 }
893 // select HE
894 if (HEToSelect.size() > 0) {
895 if (HEToSelect.size() > 1) {
896 mySelectorFrameParent->getViewNet()->getUndoList()->begin(GUIIcon::SELECT, TL("select children"));
897 }
898 for (const auto& HE : HEToSelect) {
899 if (obj == mySelectChildrenButton) {
900 HE->setAttribute(GNE_ATTR_SELECTED, "true", mySelectorFrameParent->getViewNet()->getUndoList());
901 } else {
902 HE->setAttribute(GNE_ATTR_SELECTED, "false", mySelectorFrameParent->getViewNet()->getUndoList());
903 }
904 }
905 if (HEToSelect.size() > 1) {
906 mySelectorFrameParent->getViewNet()->getUndoList()->end();
907 }
908 }
909 // update information label
910 mySelectorFrameParent->mySelectionInformation->updateInformationLabel();
911 // update viewNet
912 mySelectorFrameParent->getViewNet()->update();
913 }
914 return 1;
915}
916
917// ---------------------------------------------------------------------------
918// GNECrossingFrame::Legend - methods
919// ---------------------------------------------------------------------------
920
922 MFXGroupBoxModule(selectorFrameParent, TL("Information")) {
923 // Create Selection Hint
924 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);
925}
926
927
929
930// ---------------------------------------------------------------------------
931// GNESelectorFrame - methods
932// ---------------------------------------------------------------------------
933
935 GNEFrame(viewParent, viewNet, TL("Selection")) {
936 // create selection information
938 // create Modification Mode modul
940 // create ElementSet modul
944 // create VisualScaling modul
945 myVisualScaling = new VisualScaling(this);
946 // create SelectionOperation modul
948 // create SelectionHierarchy modul
950 // create Information modul
951 myInformation = new Information(this);
952}
953
954
956
957
958void
960 // refresh element set
962 // only show network element set
967 // only show demand element set
972 // only show data element set
976 }
977 // update information label
979 // Show frame
981}
982
983
984void
986 // hide frame
988}
989
990
991void
996
997
998void
1002
1003
1004bool
1006 // get front AC
1007 auto AC = viewObjects.getAttributeCarrierFront();
1008 // check AC
1009 if (AC == nullptr) {
1010 return false;
1011 }
1012 // check locking
1013 if (myViewNet->getLockManager().isObjectLocked(AC->getGUIGlObject()->getType(), AC->isAttributeCarrierSelected())) {
1014 return false;
1015 }
1016 // check modes
1017 if ((AC->getTagProperty().isNetworkElement() || AC->getTagProperty().isAdditionalElement()) &&
1019 return false;
1020 }
1021 if (AC->getTagProperty().isDemandElement() && !myViewNet->getEditModes().isCurrentSupermodeDemand()) {
1022 return false;
1023 }
1024 if (AC->getTagProperty().isDataElement() && !myViewNet->getEditModes().isCurrentSupermodeData()) {
1025 return false;
1026 }
1027 // filter GLObjects by layer
1028 auto filteredGLObjects = GNEViewNetHelper::filterElementsByLayer(viewObjects.getGLObjects());
1029 // check if we have to open dialog
1030 if (filteredGLObjects.size() > 1) {
1031 myViewNet->openSelectDialogAtCursor(filteredGLObjects);
1032 } else {
1033 // toggle selection
1034 if (AC->isAttributeCarrierSelected()) {
1035 AC->unselectAttributeCarrier();
1036 } else {
1037 AC->selectAttributeCarrier();
1038 }
1039 // update information label
1041 }
1042 return true;
1043}
1044
1045
1046void
1047GNESelectorFrame::handleIDs(const std::vector<GNEAttributeCarrier*>& ACs, const ModificationMode::Operation setop) {
1048 // declare set operation
1050 // declare two sets of attribute carriers, one for select and another for unselect
1051 std::set<std::pair<std::string, GNEAttributeCarrier*> > ACsToSelect, ACsToUnselect;
1052 // in restrict AND replace mode all current selected attribute carriers will be unselected
1053 if ((setOperation == ModificationMode::Operation::REPLACE) || (setOperation == ModificationMode::Operation::RESTRICT)) {
1054 // obtain selected ACs depending of current supermode
1055 std::vector<GNEAttributeCarrier*> selectedACs = myViewNet->getNet()->getAttributeCarriers()->getSelectedAttributeCarriers(false);
1056 // add id into ACs to unselect
1057 for (const auto& selectedAC : selectedACs) {
1058 ACsToUnselect.insert(std::make_pair(selectedAC->getID(), selectedAC));
1059 }
1060 }
1061 // handle ids
1062 for (const auto& AC : ACs) {
1063 // iterate over AttributeCarriers an place it in ACsToSelect or ACsToUnselect
1064 switch (setOperation) {
1066 ACsToUnselect.insert(std::make_pair(AC->getID(), AC));
1067 break;
1069 if (ACsToUnselect.find(std::make_pair(AC->getID(), AC)) != ACsToUnselect.end()) {
1070 ACsToSelect.insert(std::make_pair(AC->getID(), AC));
1071 }
1072 break;
1073 default:
1074 ACsToSelect.insert(std::make_pair(AC->getID(), AC));
1075 break;
1076 }
1077 }
1078 // select junctions and their connections if Auto select junctions is enabled (note: only for "add mode")
1080 std::set<GNEEdge*> edgesToSelect;
1081 // iterate over ACsToSelect and extract edges
1082 for (const auto& AC : ACsToSelect) {
1083 if (AC.second->getTagProperty().getTag() == SUMO_TAG_EDGE) {
1084 edgesToSelect.insert(myViewNet->getNet()->getAttributeCarriers()->retrieveEdge(AC.second->getID()));
1085 }
1086 }
1087 // iterate over extracted edges
1088 for (const auto& edgeToSelect : edgesToSelect) {
1089 // select junction source and all connections, crossings and walkingAreas
1090 ACsToSelect.insert(std::make_pair(edgeToSelect->getFromJunction()->getID(), edgeToSelect->getFromJunction()));
1091 for (const auto& connectionToSelect : edgeToSelect->getFromJunction()->getGNEConnections()) {
1092 ACsToSelect.insert(std::make_pair(connectionToSelect->getID(), connectionToSelect));
1093 }
1094 for (const auto& fromCrossingToSelect : edgeToSelect->getFromJunction()->getGNECrossings()) {
1095 ACsToSelect.insert(std::make_pair(fromCrossingToSelect->getID(), fromCrossingToSelect));
1096 }
1097 for (const auto& fromWalkingAreaToSelect : edgeToSelect->getFromJunction()->getGNEWalkingAreas()) {
1098 ACsToSelect.insert(std::make_pair(fromWalkingAreaToSelect->getID(), fromWalkingAreaToSelect));
1099 }
1100 // select junction destination and all connections, crossings and walkingAreas
1101 ACsToSelect.insert(std::make_pair(edgeToSelect->getToJunction()->getID(), edgeToSelect->getToJunction()));
1102 for (const auto& connectionToSelect : edgeToSelect->getToJunction()->getGNEConnections()) {
1103 ACsToSelect.insert(std::make_pair(connectionToSelect->getID(), connectionToSelect));
1104 }
1105 for (const auto& toCrossingToSelect : edgeToSelect->getToJunction()->getGNECrossings()) {
1106 ACsToSelect.insert(std::make_pair(toCrossingToSelect->getID(), toCrossingToSelect));
1107 }
1108 for (const auto& toWalkingAreaToSelect : edgeToSelect->getToJunction()->getGNEWalkingAreas()) {
1109 ACsToSelect.insert(std::make_pair(toWalkingAreaToSelect->getID(), toWalkingAreaToSelect));
1110 }
1111 }
1112 }
1113 // only continue if there is ACs to select or unselect
1114 if ((ACsToSelect.size() + ACsToUnselect.size()) > 0) {
1115 // first unselect AC of ACsToUnselect and then selects AC of ACsToSelect
1117 for (const auto& ACToUnselect : ACsToUnselect) {
1118 if (ACToUnselect.second->getTagProperty().isSelectable()) {
1119 ACToUnselect.second->setAttribute(GNE_ATTR_SELECTED, "false", myViewNet->getUndoList());
1120 }
1121 }
1122 for (const auto& ACToSelect : ACsToSelect) {
1123 if (ACToSelect.second->getTagProperty().isSelectable()) {
1124 ACToSelect.second->setAttribute(GNE_ATTR_SELECTED, "true", myViewNet->getUndoList());
1125 }
1126 }
1127 // finish operation
1129 }
1130}
1131
1132
1133std::vector<GNEAttributeCarrier*>
1134GNESelectorFrame::getMatches(const SumoXMLTag ACTag, const SumoXMLAttr ACAttr, const char compOp, const double val, const std::string& expr) {
1135 std::vector<GNEAttributeCarrier*> result;
1136 // first retrieve all ACs using ACTag
1137 const auto allACbyTag = myViewNet->getNet()->getAttributeCarriers()->retrieveAttributeCarriers(ACTag);
1138 // get Tag value
1139 const auto& tagValue = GNEAttributeCarrier::getTagProperty(ACTag);
1140 // iterate over all ACs
1141 for (const auto& AC : allACbyTag) {
1142 if (expr == "" && compOp == '@') {
1143 result.push_back(AC);
1144 } else if (tagValue.hasAttribute(ACAttr) && tagValue.getAttributeProperties(ACAttr).isNumerical()) {
1145 double acVal;
1146 std::istringstream buf(AC->getAttribute(ACAttr));
1147 buf >> acVal;
1148 switch (compOp) {
1149 case '<':
1150 if (acVal < val) {
1151 result.push_back(AC);
1152 }
1153 break;
1154 case '>':
1155 if (acVal > val) {
1156 result.push_back(AC);
1157 }
1158 break;
1159 case '=':
1160 if (acVal == val) {
1161 result.push_back(AC);
1162 }
1163 break;
1164 }
1165 } else {
1166 // string match
1167 std::string acVal = AC->getAttributeForSelection(ACAttr);
1168 switch (compOp) {
1169 case '@':
1170 if (acVal.find(expr) != std::string::npos) {
1171 result.push_back(AC);
1172 }
1173 break;
1174 case '!':
1175 if (acVal.find(expr) == std::string::npos) {
1176 result.push_back(AC);
1177 }
1178 break;
1179 case '=':
1180 if (acVal == expr) {
1181 result.push_back(AC);
1182 }
1183 break;
1184 case '^':
1185 if (acVal != expr) {
1186 result.push_back(AC);
1187 }
1188 break;
1189 }
1190 }
1191 }
1192 return result;
1193}
1194
1195
1196std::vector<GNEAttributeCarrier*>
1197GNESelectorFrame::getGenericMatches(const std::vector<GNEGenericData*>& genericDatas, const std::string& attr, const char compOp, const double val, const std::string& expr) {
1198 std::vector<GNEAttributeCarrier*> result;
1199 // iterate over generic datas
1200 for (const auto& genericData : genericDatas) {
1201 if (expr == "" && compOp == '@') {
1202 result.push_back(genericData);
1203 } else if (attr != toString(GNE_ATTR_PARENT)) {
1204 double acVal;
1205 std::istringstream buf(genericData->getParameter(attr, "0"));
1206 buf >> acVal;
1207 switch (compOp) {
1208 case '<':
1209 if (acVal < val) {
1210 result.push_back(genericData);
1211 }
1212 break;
1213 case '>':
1214 if (acVal > val) {
1215 result.push_back(genericData);
1216 }
1217 break;
1218 case '=':
1219 if (acVal == val) {
1220 result.push_back(genericData);
1221 }
1222 break;
1223 }
1224 } else {
1225 // string match
1226 std::string acVal = genericData->getAttributeForSelection(GNE_ATTR_PARENT);
1227 switch (compOp) {
1228 case '@':
1229 if (acVal.find(expr) != std::string::npos) {
1230 result.push_back(genericData);
1231 }
1232 break;
1233 case '!':
1234 if (acVal.find(expr) == std::string::npos) {
1235 result.push_back(genericData);
1236 }
1237 break;
1238 case '=':
1239 if (acVal == expr) {
1240 result.push_back(genericData);
1241 }
1242 break;
1243 case '^':
1244 if (acVal != expr) {
1245 result.push_back(genericData);
1246 }
1247 break;
1248 }
1249 }
1250 }
1251 return result;
1252}
1253
1254
1255FXVerticalFrame*
1259
1260
1265
1266
1271
1272
1277
1278/****************************************************************************/
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:125
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.
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.
std::pair< std::vector< std::pair< bool, GNEAttributeCarrier * > >, std::vector< std::pair< bool, GNEAttributeCarrier * > > > processMassiveNetworkElementSelection(const bool filterLanes)
FOX need this.
std::pair< std::vector< std::pair< bool, GNEAttributeCarrier * > >, std::vector< std::pair< bool, GNEAttributeCarrier * > > > processMassiveDataElementSelection()
process massive dataelement selection
std::pair< std::vector< std::pair< bool, GNEAttributeCarrier * > >, std::vector< std::pair< bool, GNEAttributeCarrier * > > > processMassiveDemandElementSelection()
process massive demand element selection
void loadFromFile(const std::string &file) const
load from file
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.
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