Eclipse SUMO - Simulation of Urban MObility
GNESelectorFrame.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2022 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
18 // The Widget for modifying selections of network-elements
19 /****************************************************************************/
20 #include <config.h>
21 
22 #include <netedit/GNENet.h>
23 #include <netedit/GNEUndoList.h>
24 #include <netedit/GNEViewNet.h>
31 
32 #include "GNESelectorFrame.h"
33 #include "GNEElementSet.h"
34 #include "GNEMatchAttribute.h"
36 
37 
38 // ===========================================================================
39 // FOX callback mapping
40 // ===========================================================================
41 FXDEFMAP(GNESelectorFrame::ModificationMode) ModificationModeMap[] = {
43 };
44 
47 };
48 
49 FXDEFMAP(GNESelectorFrame::SelectionOperation) SelectionOperationMap[] = {
55 };
56 
57 FXDEFMAP(GNESelectorFrame::SelectionHierarchy) SelectionHierarchyMap[] = {
61 };
62 
63 // Object implementation
64 FXIMPLEMENT(GNESelectorFrame::ModificationMode, FXGroupBoxModule, ModificationModeMap, ARRAYNUMBER(ModificationModeMap))
65 FXIMPLEMENT(GNESelectorFrame::VisualScaling, FXGroupBoxModule, VisualScalingMap, ARRAYNUMBER(VisualScalingMap))
66 FXIMPLEMENT(GNESelectorFrame::SelectionOperation, FXGroupBoxModule, SelectionOperationMap, ARRAYNUMBER(SelectionOperationMap))
67 FXIMPLEMENT(GNESelectorFrame::SelectionHierarchy, FXGroupBoxModule, SelectionHierarchyMap, ARRAYNUMBER(SelectionHierarchyMap))
68 
69 // ===========================================================================
70 // method definitions
71 // ===========================================================================
72 
73 // ---------------------------------------------------------------------------
74 // ModificationMode::SelectionInformation - methods
75 // ---------------------------------------------------------------------------
76 
78  FXGroupBoxModule(selectorFrameParent->myContentFrame, "Selection information"),
79  mySelectorFrameParent(selectorFrameParent) {
80  // information label
81  myInformationLabel = new FXLabel(getCollapsableFrame(), "", nullptr, GUIDesignLabelFrameInformation);
82 }
83 
84 
86 
87 
88 void
90  // first clear information
91  myInformation.clear();
92  // get attribute carriers
93  const auto ACs = mySelectorFrameParent->getViewNet()->getNet()->getAttributeCarriers();
94  // continue depending of supermode
95  if (mySelectorFrameParent->getViewNet()->getEditModes().isCurrentSupermodeNetwork()) {
96  updateInformationLabel("Junctions", ACs->getNumberOfSelectedJunctions());
97  updateInformationLabel("Edges", ACs->getNumberOfSelectedEdges());
98  updateInformationLabel("Lanes", ACs->getNumberOfSelectedLanes());
99  updateInformationLabel("Connections", ACs->getNumberOfSelectedConnections());
100  updateInformationLabel("Crossings", ACs->getNumberOfSelectedCrossings());
101  updateInformationLabel("Additionals", ACs->getNumberOfSelectedAdditionals());
102  updateInformationLabel("TAZs", ACs->getNumberOfSelectedTAZs());
103  updateInformationLabel("Polygon", ACs->getNumberOfSelectedPolygons());
104  updateInformationLabel("POIs", ACs->getNumberOfSelectedPOIs());
105  } else if (mySelectorFrameParent->getViewNet()->getEditModes().isCurrentSupermodeDemand()) {
106  updateInformationLabel("Routes", ACs->getNumberOfSelectedRoutes());
107  updateInformationLabel("Vehicles", ACs->getNumberOfSelectedVehicles());
108  updateInformationLabel("Persons", ACs->getNumberOfSelectedPersons());
109  updateInformationLabel("Person trips", ACs->getNumberOfSelectedPersonTrips());
110  updateInformationLabel("Walks", ACs->getNumberOfSelectedWalks());
111  updateInformationLabel("Rides", ACs->getNumberOfSelectedRides());
112  updateInformationLabel("Containers", ACs->getNumberOfSelectedContainers());
113  updateInformationLabel("Transport", ACs->getNumberOfSelectedTransport());
114  updateInformationLabel("Tranships", ACs->getNumberOfSelectedTranships());
115  updateInformationLabel("Stops", ACs->getNumberOfSelectedStops());
116  } else if (mySelectorFrameParent->getViewNet()->getEditModes().isCurrentSupermodeData()) {
117  updateInformationLabel("EdgeDatas", ACs->getNumberOfSelectedEdgeDatas());
118  updateInformationLabel("EdgeRelDatas", ACs->getNumberOfSelectedEdgeRelDatas());
119  updateInformationLabel("EdgeTAZRel", ACs->getNumberOfSelectedEdgeTAZRel());
120  }
121  // adjust format
122  const auto numberLines = std::count(myInformation.begin(), myInformation.end(), ':');
123  if (numberLines == 0) {
124  myInformation.append(" \n \n");
125  } else if (numberLines > 1) {
126  myInformation.pop_back();
127  }
128  // set label
129  myInformationLabel->setText(myInformation.c_str());
130 }
131 
132 
133 void
134 GNESelectorFrame::SelectionInformation::updateInformationLabel(const std::string& element, int number) {
135  // check number
136  if (number > 0) {
137  myInformation.append(element + ": " + toString(number) + "\n");
138  }
139 }
140 
141 // ---------------------------------------------------------------------------
142 // ModificationMode::ModificationMode - methods
143 // ---------------------------------------------------------------------------
144 
146  FXGroupBoxModule(selectorFrameParent->myContentFrame, "Modification Mode"),
147  myModificationModeType(Operation::ADD) {
148  // Create all options buttons
149  myAddRadioButton = new FXRadioButton(getCollapsableFrame(), "add\t\tSelected objects are added to the previous selection",
151  myRemoveRadioButton = new FXRadioButton(getCollapsableFrame(), "remove\t\tSelected objects are removed from the previous selection",
153  myKeepRadioButton = new FXRadioButton(getCollapsableFrame(), "keep\t\tRestrict previous selection by the current selection",
155  myReplaceRadioButton = new FXRadioButton(getCollapsableFrame(), "replace\t\tReplace previous selection by the current selection",
157  myAddRadioButton->setCheck(true);
158 }
159 
160 
162 
163 
166  return myModificationModeType;
167 }
168 
169 
170 long
172  if (obj == myAddRadioButton) {
173  myModificationModeType = Operation::ADD;
174  myAddRadioButton->setCheck(true);
175  myRemoveRadioButton->setCheck(false);
176  myKeepRadioButton->setCheck(false);
177  myReplaceRadioButton->setCheck(false);
178  return 1;
179  } else if (obj == myRemoveRadioButton) {
180  myModificationModeType = Operation::SUB;
181  myAddRadioButton->setCheck(false);
182  myRemoveRadioButton->setCheck(true);
183  myKeepRadioButton->setCheck(false);
184  myReplaceRadioButton->setCheck(false);
185  return 1;
186  } else if (obj == myKeepRadioButton) {
187  myModificationModeType = Operation::RESTRICT;
188  myAddRadioButton->setCheck(false);
189  myRemoveRadioButton->setCheck(false);
190  myKeepRadioButton->setCheck(true);
191  myReplaceRadioButton->setCheck(false);
192  return 1;
193  } else if (obj == myReplaceRadioButton) {
194  myModificationModeType = Operation::REPLACE;
195  myAddRadioButton->setCheck(false);
196  myRemoveRadioButton->setCheck(false);
197  myKeepRadioButton->setCheck(false);
198  myReplaceRadioButton->setCheck(true);
199  return 1;
200  } else {
201  return 0;
202  }
203 }
204 
205 // ---------------------------------------------------------------------------
206 // ModificationMode::VisualScaling - methods
207 // ---------------------------------------------------------------------------
208 
210  FXGroupBoxModule(selectorFrameParent->myContentFrame, "Visual Scaling"),
211  mySelectorFrameParent(selectorFrameParent) {
212  // Create spin button and configure it
214  //mySelectionScaling->setNumberFormat(1);
215  //mySelectionScaling->setIncrements(0.1, .5, 1);
216  mySelectionScaling->setIncrement(0.5);
217  mySelectionScaling->setRange(1, 100000);
218  mySelectionScaling->setValue(1);
219  mySelectionScaling->setHelpText("Enlarge selected objects");
220 }
221 
222 
224 
225 
226 long
228  // set scale in viewnet
229  mySelectorFrameParent->myViewNet->setSelectorFrameScale(mySelectionScaling->getValue());
230  mySelectorFrameParent->myViewNet->updateViewNet();
231  return 1;
232 }
233 
234 // ---------------------------------------------------------------------------
235 // ModificationMode::SelectionHierarchy - methods
236 // ---------------------------------------------------------------------------
237 
239  FXGroupBoxModule(selectorFrameParent->myContentFrame, "Selection operations"),
240  mySelectorFrameParent(selectorFrameParent) {
241  // tabular buttons, see GNETLSEditorFrame
242 
243  FXHorizontalFrame* selectionButtons = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame);
244  FXVerticalFrame* col1 = new FXVerticalFrame(selectionButtons, LAYOUT_FILL_X, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); // left button columm
245  FXVerticalFrame* col2 = new FXVerticalFrame(selectionButtons, LAYOUT_FILL_X, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); // right button column
246 
247  // Create "Clear List" Button
248  new FXButton(col1, "Clear\t\tDeselect all objects (hotkey: ESC)", nullptr, this, MID_CHOOSEN_CLEAR, GUIDesignButton);
249  // Create "Invert" Button
250  new FXButton(col2, "Invert\t\tInvert selection status of all objects", nullptr, this, MID_CHOOSEN_INVERT, GUIDesignButton);
251  // Create "Save" Button
252  new FXButton(col1, "Save\t\tSave ids of currently selected objects to a file.", nullptr, this, MID_CHOOSEN_SAVE, GUIDesignButton);
253  // Create "Load" Button
254  new FXButton(col2, "Load\t\tLoad ids from a file according to the current modfication mode.", nullptr, this, MID_CHOOSEN_LOAD, GUIDesignButton);
255  // Create "Delete" Button
256  new FXButton(col1, "Delete\t\tDelete all selected objects (hotkey: DEL)", nullptr, this, MID_CHOOSEN_DELETE, GUIDesignButton);
257 }
258 
259 
261 
262 
263 long
264 GNESelectorFrame::SelectionOperation::onCmdLoad(FXObject*, FXSelector, void*) {
265  // get the new file name
266  FXFileDialog opendialog(getCollapsableFrame(), "Open List of Selected Items");
267  opendialog.setIcon(GUIIconSubSys::getIcon(GUIIcon::OPEN_CONFIG));
268  opendialog.setSelectMode(SELECTFILE_EXISTING);
269  opendialog.setPatternList("Selection files (*.txt)\nAll files (*)");
270  if (gCurrentFolder.length() != 0) {
271  opendialog.setDirectory(gCurrentFolder);
272  }
273  if (opendialog.execute()) {
274  std::vector<GNEAttributeCarrier*> loadedACs;
275  gCurrentFolder = opendialog.getDirectory();
276  std::string file = opendialog.getFilename().text();
277  std::ostringstream msg;
278  std::ifstream strm(file.c_str());
279  // check if file can be opened
280  if (!strm.good()) {
281  WRITE_ERROR("Could not open '" + file + "'.");
282  return 0;
283  }
284  while (strm.good()) {
285  std::string line;
286  strm >> line;
287  // check if line isn't empty
288  if (line.length() != 0) {
289  // obtain GLObject
291  // check if GUIGlObject exist and their their GL type isn't blocked
292  if ((object != nullptr) && !mySelectorFrameParent->getViewNet()->getLockManager().isObjectLocked(object->getType(), false)) {
293  // obtain GNEAttributeCarrier
294  GNEAttributeCarrier* AC = mySelectorFrameParent->myViewNet->getNet()->getAttributeCarriers()->retrieveAttributeCarrier(object->getGlID(), false);
295  // check if AC exist and if is selectable
296  if (AC && AC->getTagProperty().isSelectable())
297  // now check if we're in the correct supermode to load this element
298  if (((mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeNetwork()) && !AC->getTagProperty().isDemandElement()) ||
299  ((mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeDemand()) && AC->getTagProperty().isDemandElement())) {
300  loadedACs.push_back(AC);
301  }
302  }
303  }
304  }
305  // change selected attribute in loaded ACs allowing undo/redo
306  if (loadedACs.size() > 0) {
307  mySelectorFrameParent->myViewNet->getUndoList()->begin(GUIIcon::MODESELECT, "load selection");
308  mySelectorFrameParent->handleIDs(loadedACs);
309  mySelectorFrameParent->myViewNet->getUndoList()->end();
310  }
311  }
312  mySelectorFrameParent->myViewNet->updateViewNet();
313  return 1;
314 }
315 
316 
317 long
318 GNESelectorFrame::SelectionOperation::onCmdSave(FXObject*, FXSelector, void*) {
319  FXString file = MFXUtils::getFilename2Write(this,
320  "Save List of selected Items", ".txt",
322  if (file == "") {
323  return 1;
324  }
325  try {
326  OutputDevice& dev = OutputDevice::getDevice(file.text());
327  // get selected attribute carriers
328  const auto selectedACs = mySelectorFrameParent->myViewNet->getNet()->getAttributeCarriers()->getSelectedAttributeCarriers(false);
329  for (const auto& selectedAC : selectedACs) {
330  GUIGlObject* object = dynamic_cast<GUIGlObject*>(selectedAC);
331  if (object) {
332  dev << GUIGlObject::TypeNames.getString(object->getType()) << ":" << selectedAC->getID() << "\n";
333  }
334  }
335  dev.close();
336  } catch (IOError& e) {
337  // write warning if netedit is running in testing mode
338  WRITE_DEBUG("Opening FXMessageBox 'error storing selection'");
339  // open message box error
340  FXMessageBox::error(getCollapsableFrame(), MBOX_OK, "Storing Selection failed", "%s", e.what());
341  // write warning if netedit is running in testing mode
342  WRITE_DEBUG("Closed FXMessageBox 'error storing selection' with 'OK'");
343  }
344  return 1;
345 }
346 
347 
348 long
350  bool ignoreLocking = false;
351  // only continue if there is element for selecting
352  if ((mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeNetwork() && processNetworkElementSelection(true, false, ignoreLocking)) ||
353  (mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeDemand() && processDemandElementSelection(true, false, ignoreLocking)) ||
354  (mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeData() && processDataElementSelection(true, false, ignoreLocking))) {
355  // for invert selection, first clean current selection and next select elements of set "unselectedElements"
356  mySelectorFrameParent->myViewNet->getUndoList()->begin(GUIIcon::MODESELECT, "invert selection");
357  // invert selection of elements depending of current supermode
358  if (mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeNetwork()) {
359  processNetworkElementSelection(false, true, ignoreLocking);
360  } else if (mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeDemand()) {
361  processDemandElementSelection(false, true, ignoreLocking);
362  } else if (mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeData()) {
363  processDataElementSelection(false, true, ignoreLocking);
364  }
365  // finish selection operation
366  mySelectorFrameParent->myViewNet->getUndoList()->end();
367  }
368  return 1;
369 }
370 
371 long
373  // acts like the 'del' hotkey
374  mySelectorFrameParent->getViewNet()->hotkeyDel();
375  return 1;
376 }
377 
378 
379 long
381  bool ignoreLocking = false;
382  // only continue if there is element for selecting
383  if ((mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeNetwork() && processNetworkElementSelection(true, false, ignoreLocking)) ||
384  (mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeDemand() && processDemandElementSelection(true, false, ignoreLocking)) ||
385  (mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeData() && processDataElementSelection(true, false, ignoreLocking))) {
386  // for invert selection, first clean current selection and next select elements of set "unselectedElements"
387  mySelectorFrameParent->myViewNet->getUndoList()->begin(GUIIcon::MODESELECT, "invert selection");
388  // invert selection of elements depending of current supermode
389  if (mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeNetwork()) {
390  // invert network elements
391  processNetworkElementSelection(false, false, ignoreLocking);
392  } else if (mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeDemand()) {
393  // invert demand elements
394  processDemandElementSelection(false, false, ignoreLocking);
395  } else if (mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeData()) {
396  // invert data elements
397  processDataElementSelection(false, false, ignoreLocking);
398  }
399  // finish selection operation
400  mySelectorFrameParent->myViewNet->getUndoList()->end();
401  }
402  return 1;
403 }
404 
405 
406 bool
407 GNESelectorFrame::SelectionOperation::processNetworkElementSelection(const bool onlyCount, const bool onlyUnselect, bool& ignoreLocking) {
408  // obtan locks (only for improve code legibly)
409  const auto& locks = mySelectorFrameParent->getViewNet()->getLockManager();
410  // get attribute carriers (only for improve code legibly)
411  const auto& ACs = mySelectorFrameParent->myViewNet->getNet()->getAttributeCarriers();
412  // obtain undoList (only for improve code legibly)
413  GNEUndoList* undoList = mySelectorFrameParent->myViewNet->getUndoList();
414  // iterate over junctions
415  for (const auto& junction : ACs->getJunctions()) {
416  // check if junction selection is locked
417  if (ignoreLocking || !locks.isObjectLocked(GLO_JUNCTION, false)) {
418  if (onlyCount) {
419  return true;
420  } else if (onlyUnselect || junction.second->isAttributeCarrierSelected()) {
421  junction.second->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
422  } else {
423  junction.second->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
424  }
425  } else if (onlyCount) {
426  ignoreLocking = askContinueIfLock();
427  return true;
428  }
429  // due we iterate over all junctions, only it's neccesary iterate over incoming edges
430  for (const auto& incomingEdge : junction.second->getGNEIncomingEdges()) {
431  // special case for clear
432  if (onlyUnselect) {
433  // check if edge selection is locked
434  if (ignoreLocking || !locks.isObjectLocked(GLO_EDGE, false)) {
435  if (onlyCount) {
436  return true;
437  } else {
438  incomingEdge->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
439  }
440  } else if (onlyCount) {
441  ignoreLocking = askContinueIfLock();
442  return true;
443  }
444  // check if lane selection is locked
445  if (ignoreLocking || !locks.isObjectLocked(GLO_LANE, false)) {
446  for (const auto& lane : incomingEdge->getLanes()) {
447  if (onlyCount) {
448  return true;
449  } else {
450  lane->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
451  }
452  }
453  } else if (onlyCount) {
454  ignoreLocking = askContinueIfLock();
455  return true;
456  }
457  } else if (mySelectorFrameParent->myViewNet->getNetworkViewOptions().selectEdges()) {
458  // check if edge selection is locked
459  if (ignoreLocking || !locks.isObjectLocked(GLO_EDGE, false)) {
460  if (onlyCount) {
461  return true;
462  } else if (onlyUnselect || incomingEdge->isAttributeCarrierSelected()) {
463  incomingEdge->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
464  } else {
465  incomingEdge->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
466  }
467  } else if (onlyCount) {
468  ignoreLocking = askContinueIfLock();
469  return true;
470  }
471  } else {
472  // check if lane selection is locked
473  if (ignoreLocking || !locks.isObjectLocked(GLO_LANE, false)) {
474  for (const auto& lane : incomingEdge->getLanes()) {
475  if (onlyCount) {
476  return true;
477  } else if (onlyUnselect || lane->isAttributeCarrierSelected()) {
478  lane->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
479  } else {
480  lane->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
481  }
482  }
483  } else if (onlyCount) {
484  ignoreLocking = askContinueIfLock();
485  return true;
486  }
487  }
488  // check if connection selection is locked
489  if (ignoreLocking || !locks.isObjectLocked(GLO_CONNECTION, false)) {
490  for (const auto& connection : incomingEdge->getGNEConnections()) {
491  if (onlyCount) {
492  return true;
493  } else if (onlyUnselect || connection->isAttributeCarrierSelected()) {
494  connection->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
495  } else {
496  connection->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
497  }
498  }
499  } else if (onlyCount) {
500  ignoreLocking = askContinueIfLock();
501  return true;
502  }
503  }
504  // check if crossing selection is locked
505  if (ignoreLocking || !locks.isObjectLocked(GLO_CROSSING, false)) {
506  for (const auto& crossing : junction.second->getGNECrossings()) {
507  if (onlyCount) {
508  return true;
509  } else if (onlyUnselect || crossing->isAttributeCarrierSelected()) {
510  crossing->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
511  } else {
512  crossing->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
513  }
514  }
515  } else if (onlyCount) {
516  ignoreLocking = askContinueIfLock();
517  return true;
518  }
519  }
520  // check if additionals selection is locked
521  if (ignoreLocking || !locks.isObjectLocked(GLO_ADDITIONALELEMENT, false)) {
522  for (const auto& additionalTag : ACs->getAdditionals()) {
523  // first check if additional is selectable
524  if (GNEAttributeCarrier::getTagProperty(additionalTag.first).isSelectable()) {
525  for (const auto& additional : additionalTag.second) {
526  if (onlyCount) {
527  return true;
528  } else if (onlyUnselect || additional->isAttributeCarrierSelected()) {
529  additional->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
530  } else {
531  additional->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
532  }
533  }
534  }
535  }
536  } else if (onlyCount) {
537  ignoreLocking = askContinueIfLock();
538  return true;
539  }
540  // invert polygons
541  if (ignoreLocking || !locks.isObjectLocked(GLO_POLYGON, false)) {
542  for (const auto& polygon : ACs->getShapes().at(SUMO_TAG_POLY)) {
543  if (onlyCount) {
544  return true;
545  } else if (onlyUnselect || polygon->isAttributeCarrierSelected()) {
546  polygon->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
547  } else {
548  polygon->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
549  }
550  }
551  } else if (onlyCount) {
552  ignoreLocking = askContinueIfLock();
553  return true;
554  }
555  // invert TAZs
556  if (ignoreLocking || !locks.isObjectLocked(GLO_TAZ, false)) {
557  for (const auto& TAZ : ACs->getTAZElements().at(SUMO_TAG_TAZ)) {
558  if (onlyCount) {
559  return true;
560  } else if (onlyUnselect || TAZ->isAttributeCarrierSelected()) {
561  TAZ->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
562  } else {
563  TAZ->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
564  }
565  }
566  } else if (onlyCount) {
567  ignoreLocking = askContinueIfLock();
568  return true;
569  }
570  // invert POIs and POILanes
571  if (ignoreLocking || !locks.isObjectLocked(GLO_POI, false)) {
572  for (const auto& shapeTag : ACs->getShapes()) {
573  if (shapeTag.first != SUMO_TAG_POLY) {
574  for (const auto& POI : shapeTag.second) {
575  if (onlyCount) {
576  return true;
577  } else if (onlyUnselect || POI->isAttributeCarrierSelected()) {
578  POI->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
579  } else {
580  POI->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
581  }
582  }
583  } else if (onlyCount) {
584  ignoreLocking = askContinueIfLock();
585  return true;
586  }
587  }
588  }
589  return false;
590 }
591 
592 
593 bool
594 GNESelectorFrame::SelectionOperation::processDemandElementSelection(const bool onlyCount, const bool onlyUnselect, bool& ignoreLocking) {
595  // obtan locks (only for improve code legibly)
596  const auto& locks = mySelectorFrameParent->getViewNet()->getLockManager();
597  // obtain undoList (only for improve code legibly)
598  GNEUndoList* undoList = mySelectorFrameParent->myViewNet->getUndoList();
599  // get demand elements
600  const auto& demandElements = mySelectorFrameParent->myViewNet->getNet()->getAttributeCarriers()->getDemandElements();
601  // invert routes
602  if (ignoreLocking || !locks.isObjectLocked(GLO_ROUTE, false)) {
603  for (const auto& route : demandElements.at(SUMO_TAG_ROUTE)) {
604  if (onlyCount) {
605  return true;
606  } else if (onlyUnselect || route->isAttributeCarrierSelected()) {
607  route->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
608  } else {
609  route->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
610  }
611  }
612  // iterate over all embedded routes
613  for (const auto& vehicle : demandElements.at(GNE_TAG_VEHICLE_WITHROUTE)) {
614  if (onlyCount) {
615  return true;
616  } else if (onlyUnselect || vehicle->getChildDemandElements().front()->isAttributeCarrierSelected()) {
617  vehicle->getChildDemandElements().front()->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
618  } else {
619  vehicle->getChildDemandElements().front()->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
620  }
621  }
622  for (const auto& routeFlow : demandElements.at(GNE_TAG_FLOW_WITHROUTE)) {
623  if (onlyCount) {
624  return true;
625  } else if (onlyUnselect || routeFlow->getChildDemandElements().front()->isAttributeCarrierSelected()) {
626  routeFlow->getChildDemandElements().front()->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
627  } else {
628  routeFlow->getChildDemandElements().front()->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
629  }
630  }
631  } else if (onlyCount) {
632  ignoreLocking = askContinueIfLock();
633  return true;
634  }
635  // invert vehicles
636  if (ignoreLocking || !locks.isObjectLocked(GLO_VEHICLE, false)) {
637  for (const auto& vehicle : demandElements.at(SUMO_TAG_VEHICLE)) {
638  if (onlyCount) {
639  return true;
640  } else if (onlyUnselect || vehicle->isAttributeCarrierSelected()) {
641  vehicle->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
642  } else {
643  vehicle->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
644  }
645  }
646  for (const auto& vehicle : demandElements.at(GNE_TAG_VEHICLE_WITHROUTE)) {
647  if (onlyCount) {
648  return true;
649  } else if (onlyUnselect || vehicle->isAttributeCarrierSelected()) {
650  vehicle->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
651  } else {
652  vehicle->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
653  }
654  }
655  for (const auto& trip : demandElements.at(SUMO_TAG_TRIP)) {
656  if (onlyCount) {
657  return true;
658  } else if (onlyUnselect || trip->isAttributeCarrierSelected()) {
659  trip->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
660  } else {
661  trip->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
662  }
663  }
664  for (const auto& flow : demandElements.at(SUMO_TAG_FLOW)) {
665  if (onlyCount) {
666  return true;
667  } else if (onlyUnselect || flow->isAttributeCarrierSelected()) {
668  flow->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
669  } else {
670  flow->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
671  }
672  }
673  for (const auto& routeFlow : demandElements.at(GNE_TAG_FLOW_ROUTE)) {
674  if (onlyCount) {
675  return true;
676  } else if (onlyUnselect || routeFlow->isAttributeCarrierSelected()) {
677  routeFlow->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
678  } else {
679  routeFlow->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
680  }
681  }
682  for (const auto& routeFlow : demandElements.at(GNE_TAG_FLOW_WITHROUTE)) {
683  if (onlyCount) {
684  return true;
685  } else if (onlyUnselect || routeFlow->isAttributeCarrierSelected()) {
686  routeFlow->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
687  } else {
688  routeFlow->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
689  }
690  }
691  } else if (onlyCount) {
692  ignoreLocking = askContinueIfLock();
693  return true;
694  }
695  // invert persons
696  if (ignoreLocking || !locks.isObjectLocked(GLO_PERSON, false)) {
697  for (const auto& person : demandElements.at(SUMO_TAG_PERSON)) {
698  if (onlyCount) {
699  return true;
700  } else if (onlyUnselect || person->isAttributeCarrierSelected()) {
701  person->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
702  } else {
703  person->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
704  }
705  }
706  for (const auto& personFlow : demandElements.at(SUMO_TAG_PERSONFLOW)) {
707  if (onlyCount) {
708  return true;
709  } else if (onlyUnselect || personFlow->isAttributeCarrierSelected()) {
710  personFlow->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
711  } else {
712  personFlow->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
713  }
714  }
715  } else if (onlyCount) {
716  ignoreLocking = askContinueIfLock();
717  return true;
718  }
719  // invert person trip
720  if (ignoreLocking || !locks.isObjectLocked(GLO_PERSONTRIP, false)) {
721  for (const auto& person : demandElements.at(SUMO_TAG_PERSON)) {
722  for (const auto& personPlan : person->getChildDemandElements()) {
723  if (onlyCount) {
724  return true;
725  } else if (personPlan->getTagProperty().isPersonTrip()) {
726  if (onlyUnselect || personPlan->isAttributeCarrierSelected()) {
727  personPlan->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
728  } else {
729  personPlan->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
730  }
731  }
732  }
733  }
734  for (const auto& personFlow : demandElements.at(SUMO_TAG_PERSONFLOW)) {
735  for (const auto& personPlan : personFlow->getChildDemandElements()) {
736  if (onlyCount) {
737  return true;
738  } else if (personPlan->getTagProperty().isPersonTrip()) {
739  if (onlyUnselect || personPlan->isAttributeCarrierSelected()) {
740  personPlan->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
741  } else {
742  personPlan->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
743  }
744  }
745  }
746  }
747  } else if (onlyCount) {
748  ignoreLocking = askContinueIfLock();
749  return true;
750  }
751  // invert ride
752  if (ignoreLocking || !locks.isObjectLocked(GLO_PERSONTRIP, false)) {
753  for (const auto& person : demandElements.at(SUMO_TAG_PERSON)) {
754  for (const auto& personPlan : person->getChildDemandElements()) {
755  if (personPlan->getTagProperty().isRide()) {
756  if (onlyCount) {
757  return true;
758  } else if (onlyUnselect || personPlan->isAttributeCarrierSelected()) {
759  personPlan->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
760  } else {
761  personPlan->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
762  }
763  }
764  }
765  }
766  for (const auto& personFlow : demandElements.at(SUMO_TAG_PERSONFLOW)) {
767  for (const auto& personPlan : personFlow->getChildDemandElements()) {
768  if (personPlan->getTagProperty().isRide()) {
769  if (onlyCount) {
770  return true;
771  } else if (onlyUnselect || personPlan->isAttributeCarrierSelected()) {
772  personPlan->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
773  } else {
774  personPlan->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
775  }
776  }
777  }
778  }
779  } else if (onlyCount) {
780  ignoreLocking = askContinueIfLock();
781  return true;
782  }
783  // invert walks
784  if (ignoreLocking || !locks.isObjectLocked(GLO_PERSONTRIP, false)) {
785  for (const auto& person : demandElements.at(SUMO_TAG_PERSON)) {
786  for (const auto& personPlan : person->getChildDemandElements()) {
787  if (personPlan->getTagProperty().isWalk()) {
788  if (onlyCount) {
789  return true;
790  } else if (onlyUnselect || personPlan->isAttributeCarrierSelected()) {
791  personPlan->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
792  } else {
793  personPlan->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
794  }
795  }
796  }
797  }
798  for (const auto& personFlow : demandElements.at(SUMO_TAG_PERSONFLOW)) {
799  for (const auto& personPlan : personFlow->getChildDemandElements()) {
800  if (personPlan->getTagProperty().isWalk()) {
801  if (onlyCount) {
802  return true;
803  } else if (onlyUnselect || personPlan->isAttributeCarrierSelected()) {
804  personPlan->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
805  } else {
806  personPlan->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
807  }
808  }
809  }
810  }
811  } else if (onlyCount) {
812  ignoreLocking = askContinueIfLock();
813  return true;
814  }
815  // invert containers
816  if (ignoreLocking || !locks.isObjectLocked(GLO_CONTAINER, false)) {
817  for (const auto& container : demandElements.at(SUMO_TAG_CONTAINER)) {
818  if (onlyCount) {
819  return true;
820  } else if (onlyUnselect || container->isAttributeCarrierSelected()) {
821  container->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
822  } else {
823  container->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
824  }
825  }
826  for (const auto& containerFlow : demandElements.at(SUMO_TAG_CONTAINERFLOW)) {
827  if (onlyCount) {
828  return true;
829  } else if (onlyUnselect || containerFlow->isAttributeCarrierSelected()) {
830  containerFlow->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
831  } else {
832  containerFlow->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
833  }
834  }
835  } else if (onlyCount) {
836  ignoreLocking = askContinueIfLock();
837  return true;
838  }
839  // invert container
840  if (ignoreLocking || !locks.isObjectLocked(GLO_TRANSPORT, false)) {
841  for (const auto& container : demandElements.at(SUMO_TAG_CONTAINER)) {
842  for (const auto& containerPlan : container->getChildDemandElements()) {
843  if (containerPlan->getTagProperty().isTransportPlan()) {
844  if (onlyCount) {
845  return true;
846  } else if (onlyUnselect || containerPlan->isAttributeCarrierSelected()) {
847  containerPlan->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
848  } else {
849  containerPlan->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
850  }
851  }
852  }
853  }
854  for (const auto& containerFlow : demandElements.at(SUMO_TAG_CONTAINERFLOW)) {
855  for (const auto& containerPlan : containerFlow->getChildDemandElements()) {
856  if (containerPlan->getTagProperty().isTransportPlan()) {
857  if (onlyCount) {
858  return true;
859  } else if (onlyUnselect || containerPlan->isAttributeCarrierSelected()) {
860  containerPlan->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
861  } else {
862  containerPlan->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
863  }
864  }
865  }
866  }
867  } else if (onlyCount) {
868  ignoreLocking = askContinueIfLock();
869  return true;
870  }
871  // invert ride
872  if (ignoreLocking || !locks.isObjectLocked(GLO_TRANSHIP, false)) {
873  for (const auto& container : demandElements.at(SUMO_TAG_CONTAINER)) {
874  for (const auto& containerPlan : container->getChildDemandElements()) {
875  if (containerPlan->getTagProperty().isTranshipPlan()) {
876  if (onlyCount) {
877  return true;
878  } else if (onlyUnselect || containerPlan->isAttributeCarrierSelected()) {
879  containerPlan->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
880  } else {
881  containerPlan->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
882  }
883  }
884  }
885  }
886  for (const auto& containerFlow : demandElements.at(SUMO_TAG_CONTAINERFLOW)) {
887  for (const auto& containerPlan : containerFlow->getChildDemandElements()) {
888  if (containerPlan->getTagProperty().isTranshipPlan()) {
889  if (onlyCount) {
890  return true;
891  } else if (onlyUnselect || containerPlan->isAttributeCarrierSelected()) {
892  containerPlan->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
893  } else {
894  containerPlan->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
895  }
896  }
897  }
898  }
899  } else if (onlyCount) {
900  ignoreLocking = askContinueIfLock();
901  return true;
902  }
903  // invert stops
904  if (ignoreLocking || !locks.isObjectLocked(GLO_STOP, false)) {
905  for (const auto& demandElementTag : demandElements) {
906  for (const auto& demandElement : demandElementTag.second) {
907  // avoid vTypes
908  if (!demandElement->getTagProperty().isVehicleType()) {
909  // iterate over every child
910  for (const auto& stop : demandElement->getChildDemandElements()) {
911  if (stop->getTagProperty().isStop() || stop->getTagProperty().isStopPerson() || stop->getTagProperty().isStopContainer()) {
912  if (onlyCount) {
913  return true;
914  } else if (onlyUnselect || stop->isAttributeCarrierSelected()) {
915  stop->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
916  } else {
917  stop->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
918  }
919  } else {
920  // special case for embedded routes
921  for (const auto& stopEmbeddedRoute : stop->getChildDemandElements()) {
922  if (stopEmbeddedRoute->getTagProperty().isStop() ||
923  stopEmbeddedRoute->getTagProperty().isStopPerson() ||
924  stopEmbeddedRoute->getTagProperty().isStopContainer()) {
925  if (onlyCount) {
926  return true;
927  } else if (onlyUnselect || stopEmbeddedRoute->isAttributeCarrierSelected()) {
928  stopEmbeddedRoute->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
929  } else {
930  stopEmbeddedRoute->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
931  }
932  }
933  }
934  }
935  }
936  }
937  }
938  }
939  } else if (onlyCount) {
940  ignoreLocking = askContinueIfLock();
941  return true;
942  }
943  return false;
944 }
945 
946 
947 bool
948 GNESelectorFrame::SelectionOperation::processDataElementSelection(const bool onlyCount, const bool onlyUnselect, bool& ignoreLocking) {
949  // obtan locks (only for improve code legibly)
950  const auto& locks = mySelectorFrameParent->getViewNet()->getLockManager();
951  // invert dataSets
952  for (const auto& genericDataTag : mySelectorFrameParent->myViewNet->getNet()->getAttributeCarriers()->getGenericDatas()) {
953  for (const auto& genericData : genericDataTag.second) {
954  if (onlyCount && locks.isObjectLocked(genericData->getType(), false)) {
955  ignoreLocking = askContinueIfLock();
956  return true;
957  } else if ((ignoreLocking || (!locks.isObjectLocked(GLO_EDGEDATA, false) && genericData->getType() == GLO_EDGEDATA)) ||
958  (ignoreLocking || (!locks.isObjectLocked(GLO_EDGERELDATA, false) && genericData->getType() == GLO_EDGERELDATA)) ||
959  (ignoreLocking || (!locks.isObjectLocked(GLO_TAZRELDATA, false) && genericData->getType() == GLO_TAZRELDATA))) {
960  if (onlyCount) {
961  return true;
962  } else if (onlyUnselect || genericData->isAttributeCarrierSelected()) {
963  genericData->setAttribute(GNE_ATTR_SELECTED, "false", mySelectorFrameParent->myViewNet->getUndoList());
964  } else {
965  genericData->setAttribute(GNE_ATTR_SELECTED, "true", mySelectorFrameParent->myViewNet->getUndoList());
966  }
967  }
968  }
969  }
970  return false;
971 }
972 
973 
974 bool
976  WRITE_DEBUG("Opening FXMessageBox 'confirm selection operation'");
977  // open question box
978  const FXuint answer = FXMessageBox::question(mySelectorFrameParent->getViewNet()->getApp(),
979  MBOX_YES_NO, "Confirm selection operation", "There are locked elements in currentselection.\nApply operation to locked elements?");
980  if (answer != 1) { //1:yes, 2:no, 4:esc
981  // write warning if netedit is running in testing mode
982  if (answer == 2) {
983  WRITE_DEBUG("Closed FXMessageBox 'confirm selection operation' with 'No'");
984  } else if (answer == 4) {
985  WRITE_DEBUG("Closed FXMessageBox 'confirm selection operation' with 'ESC'");
986  }
987  return false;
988  } else {
989  // write warning if netedit is running in testing mode
990  WRITE_DEBUG("Closed FXMessageBox 'confirm selection operation' with 'Yes'");
991  return true;
992  }
993 }
994 
995 // ---------------------------------------------------------------------------
996 // ModificationMode::SelectionHierarchy - methods
997 // ---------------------------------------------------------------------------
998 
1000  FXGroupBoxModule(selectorFrameParent->myContentFrame, "Hierarchy operations"),
1001  mySelectorFrameParent(selectorFrameParent),
1002  myCurrentSelectedParent(Selection::ALL),
1003  myCurrentSelectedChild(Selection::ALL) {
1004  // create label for parents
1005  new FXLabel(getCollapsableFrame(), "Select parents", nullptr, GUIDesignLabelThickCenter);
1006  // Create FXComboBox for parent comboBox
1008  // create parent buttons
1009  FXHorizontalFrame* parentButtons = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame);
1010  // Create "select" Button
1012  // Create "unselect" Button
1014  // create label for parents
1015  new FXLabel(getCollapsableFrame(), "Select children", nullptr, GUIDesignLabelThickCenter);
1016  // Create FXComboBox for parent comboBox
1018  // create children buttons
1019  FXHorizontalFrame* childrenButtons = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame);
1020  // Create "select" Button
1022  // Create "unselect" Button
1024  // fill comboBoxes
1025  for (const auto& item : myItems) {
1026  myParentsComboBox->appendItem(item.second.c_str());
1027  myChildrenComboBox->appendItem(item.second.c_str());
1028  }
1029  myParentsComboBox->setNumVisible(5);
1030  myChildrenComboBox->setNumVisible(5);
1031 }
1032 
1033 
1035 
1036 
1037 long
1039  if (obj == myParentsComboBox) {
1040  for (const auto& item : myItems) {
1041  if (item.second == myParentsComboBox->getText().text()) {
1042  // enable buttons
1043  mySelectParentsButton->enable();
1044  myUnselectParentsButton->enable();
1045  // change text color
1046  myParentsComboBox->setTextColor(FXRGB(0, 0, 0));
1047  // set current selected parent
1048  myCurrentSelectedParent = item.first;
1049  return 1;
1050  }
1051  }
1052  // item not found
1053  myCurrentSelectedParent = Selection::NOTHING;
1054  // disable buttons
1055  mySelectParentsButton->disable();
1056  myUnselectParentsButton->disable();
1057  myParentsComboBox->setTextColor(FXRGB(255, 0, 0));
1058  return 1;
1059  } else if (obj == myChildrenComboBox) {
1060  for (const auto& item : myItems) {
1061  if (item.second == myChildrenComboBox->getText().text()) {
1062  // enable buttons
1063  mySelectChildrenButton->enable();
1064  myUnselectChildrenButton->enable();
1065  // change text color
1066  myChildrenComboBox->setTextColor(FXRGB(0, 0, 0));
1067  // set current selected parent
1068  myCurrentSelectedChild = item.first;
1069  return 1;
1070  }
1071  }
1072  // item not found
1073  myCurrentSelectedChild = Selection::NOTHING;
1074  // disable buttons
1075  mySelectChildrenButton->disable();
1076  myUnselectChildrenButton->disable();
1077  myChildrenComboBox->setTextColor(FXRGB(255, 0, 0));
1078  return 1;
1079  }
1080  return 0;
1081 }
1082 
1083 
1084 long
1085 GNESelectorFrame::SelectionHierarchy::onCmdParents(FXObject* obj, FXSelector, void*) {
1086  // get selected elements
1087  const auto selectedACs = mySelectorFrameParent->getViewNet()->getNet()->getAttributeCarriers()->getSelectedAttributeCarriers(true);
1088  // check if there is selected ACs
1089  if ((selectedACs.size() > 0) && (myCurrentSelectedParent != Selection::NOTHING)) {
1090  // vector of hierarchical elements to select
1091  std::vector<GNEHierarchicalElement*> HEToSelect;
1092  for (const auto& selectedAC : selectedACs) {
1093  // get hierarchical element
1094  const auto HE = selectedAC->getHierarchicalElement();
1095  // junctions
1096  if ((myCurrentSelectedParent == Selection::ALL) || (myCurrentSelectedParent == Selection::JUNCTION)) {
1097  HEToSelect.insert(HEToSelect.end(), HE->getParentJunctions().begin(), HE->getParentJunctions().end());
1098  }
1099  // edges
1100  if ((myCurrentSelectedParent == Selection::ALL) || (myCurrentSelectedParent == Selection::EDGE)) {
1101  if (selectedAC->getTagProperty().getTag() == SUMO_TAG_LANE) {
1102  // special case for lanes
1103  HEToSelect.push_back(dynamic_cast<GNELane*>(selectedAC)->getParentEdge());
1104  } else {
1105  HEToSelect.insert(HEToSelect.end(), HE->getParentEdges().begin(), HE->getParentEdges().end());
1106  }
1107  }
1108  // lanes
1109  if ((myCurrentSelectedParent == Selection::ALL) || (myCurrentSelectedParent == Selection::LANE)) {
1110  HEToSelect.insert(HEToSelect.end(), HE->getParentLanes().begin(), HE->getParentLanes().end());
1111  }
1112  // additional
1113  if ((myCurrentSelectedParent == Selection::ALL) || (myCurrentSelectedParent == Selection::ADDITIONAL)) {
1114  HEToSelect.insert(HEToSelect.end(), HE->getParentAdditionals().begin(), HE->getParentAdditionals().end());
1115  }
1116  // shape
1117  if ((myCurrentSelectedParent == Selection::ALL) || (myCurrentSelectedParent == Selection::SHAPE)) {
1118  HEToSelect.insert(HEToSelect.end(), HE->getParentShapes().begin(), HE->getParentShapes().end());
1119  }
1120  // demand
1121  if ((myCurrentSelectedParent == Selection::ALL) || (myCurrentSelectedParent == Selection::DEMAND)) {
1122  HEToSelect.insert(HEToSelect.end(), HE->getParentDemandElements().begin(), HE->getParentDemandElements().end());
1123  }
1124  // data
1125  if ((myCurrentSelectedParent == Selection::ALL) || (myCurrentSelectedParent == Selection::DATA)) {
1126  HEToSelect.insert(HEToSelect.end(), HE->getParentGenericDatas().begin(), HE->getParentGenericDatas().end());
1127  }
1128  }
1129  // select HE
1130  if (HEToSelect.size() > 0) {
1131  for (const auto& HE : HEToSelect) {
1132  if (obj == mySelectParentsButton) {
1133  HE->setAttribute(GNE_ATTR_SELECTED, "true", mySelectorFrameParent->getViewNet()->getUndoList());
1134  } else {
1135  HE->setAttribute(GNE_ATTR_SELECTED, "false", mySelectorFrameParent->getViewNet()->getUndoList());
1136  }
1137  }
1138  }
1139  // update information label
1140  mySelectorFrameParent->mySelectionInformation->updateInformationLabel();
1141  // update viewNet
1142  mySelectorFrameParent->getViewNet()->update();
1143  }
1144  return 1;
1145 }
1146 
1147 
1148 long
1149 GNESelectorFrame::SelectionHierarchy::onCmdChildren(FXObject* obj, FXSelector, void*) {
1150  // get selected elements
1151  const auto selectedACs = mySelectorFrameParent->getViewNet()->getNet()->getAttributeCarriers()->getSelectedAttributeCarriers(true);
1152  // check if there is selected ACs
1153  if ((selectedACs.size() > 0) && (myCurrentSelectedChild != Selection::NOTHING)) {
1154  // vector of hierarchical elements to select
1155  std::vector<GNEHierarchicalElement*> HEToSelect;
1156  for (const auto& selectedAC : selectedACs) {
1157  // get hierarchical element
1158  const auto HE = selectedAC->getHierarchicalElement();
1159  // junctions
1160  if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::JUNCTION)) {
1161  if (selectedAC->getTagProperty().getTag() == SUMO_TAG_JUNCTION) {
1162  // special case for junction
1163  const auto junction = dynamic_cast<GNEJunction*>(selectedAC);
1164  // insert edges
1165  HEToSelect.insert(HEToSelect.end(), junction->getGNEIncomingEdges().begin(), junction->getGNEIncomingEdges().end());
1166  HEToSelect.insert(HEToSelect.end(), junction->getGNEOutgoingEdges().begin(), junction->getGNEOutgoingEdges().end());
1167  } else {
1168  HEToSelect.insert(HEToSelect.end(), HE->getChildJunctions().begin(), HE->getChildJunctions().end());
1169  }
1170  }
1171  // edges
1172  if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::EDGE)) {
1173  if (selectedAC->getTagProperty().getTag() == SUMO_TAG_EDGE) {
1174  // special case for edges
1175  const auto edge = dynamic_cast<GNEEdge*>(selectedAC);
1176  // insert lanes
1177  HEToSelect.insert(HEToSelect.end(), edge->getLanes().begin(), edge->getLanes().end());
1178  } else {
1179  HEToSelect.insert(HEToSelect.end(), HE->getChildEdges().begin(), HE->getChildEdges().end());
1180  }
1181  }
1182  // lanes
1183  if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::LANE)) {
1184  HEToSelect.insert(HEToSelect.end(), HE->getChildLanes().begin(), HE->getChildLanes().end());
1185  }
1186  // additional
1187  if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::ADDITIONAL)) {
1188  // avoid insert symbols
1189  for (const auto& additionalChild : HE->getChildAdditionals()) {
1190  if (!additionalChild->getTagProperty().isSymbol()) {
1191  HEToSelect.push_back(additionalChild);
1192  }
1193  }
1194  }
1195  // shape
1196  if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::SHAPE)) {
1197  HEToSelect.insert(HEToSelect.end(), HE->getChildShapes().begin(), HE->getChildShapes().end());
1198  }
1199  // demand
1200  if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::DEMAND)) {
1201  HEToSelect.insert(HEToSelect.end(), HE->getChildDemandElements().begin(), HE->getChildDemandElements().end());
1202  }
1203  // data
1204  if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::DATA)) {
1205  HEToSelect.insert(HEToSelect.end(), HE->getChildGenericDatas().begin(), HE->getChildGenericDatas().end());
1206  }
1207  }
1208  // select HE
1209  if (HEToSelect.size() > 0) {
1210  for (const auto& HE : HEToSelect) {
1211  if (obj == mySelectChildrenButton) {
1212  HE->setAttribute(GNE_ATTR_SELECTED, "true", mySelectorFrameParent->getViewNet()->getUndoList());
1213  } else {
1214  HE->setAttribute(GNE_ATTR_SELECTED, "false", mySelectorFrameParent->getViewNet()->getUndoList());
1215  }
1216  }
1217  }
1218  // update information label
1219  mySelectorFrameParent->mySelectionInformation->updateInformationLabel();
1220  // update viewNet
1221  mySelectorFrameParent->getViewNet()->update();
1222  }
1223  return 1;
1224 }
1225 
1226 // ---------------------------------------------------------------------------
1227 // GNECrossingFrame::Legend - methods
1228 // ---------------------------------------------------------------------------
1229 
1231  FXGroupBoxModule(selectorFrameParent->myContentFrame, "Information") {
1232  // Create Selection Hint
1233  new FXLabel(getCollapsableFrame(), " - Hold <SHIFT> for \n rectangle selection.\n - Press <DEL> to\n delete selected objects.", nullptr, GUIDesignLabelFrameInformation);
1234 }
1235 
1236 
1238 
1239 // ---------------------------------------------------------------------------
1240 // GNESelectorFrame - methods
1241 // ---------------------------------------------------------------------------
1242 
1243 GNESelectorFrame::GNESelectorFrame(FXHorizontalFrame* horizontalFrameParent, GNEViewNet* viewNet) :
1244  GNEFrame(horizontalFrameParent, viewNet, "Selection") {
1245  // create selection information
1247  // create Modification Mode modul
1249  // create ElementSet modul
1253  // create VisualScaling modul
1254  myVisualScaling = new VisualScaling(this);
1255  // create SelectionOperation modul
1257  // create SelectionHierarchy modul
1259  // create Information modul
1260  myInformation = new Information(this);
1261 }
1262 
1263 
1265 
1266 
1267 void
1269  // refresh element set
1271  // only show network element set
1276  // only show demand element set
1280  } else if (myViewNet->getEditModes().isCurrentSupermodeData()) {
1281  // only show data element set
1285  }
1286  // update information label
1288  // Show frame
1289  GNEFrame::show();
1290 }
1291 
1292 
1293 void
1295  // hide frame
1296  GNEFrame::hide();
1297 }
1298 
1299 
1300 void
1302  // update information label
1304 }
1305 
1306 
1307 void
1309  mySelectionOperation->onCmdClear(nullptr, 0, nullptr);
1310 }
1311 
1312 
1313 void
1314 GNESelectorFrame::handleIDs(const std::vector<GNEAttributeCarrier*>& ACs, const ModificationMode::Operation setop) {
1315  // declare set operation
1317  // declare two sets of attribute carriers, one for select and another for unselect
1318  std::set<std::pair<std::string, GNEAttributeCarrier*> > ACsToSelect, ACsToUnselect;
1319  // in restrict AND replace mode all current selected attribute carriers will be unselected
1320  if ((setOperation == ModificationMode::Operation::REPLACE) || (setOperation == ModificationMode::Operation::RESTRICT)) {
1321  // obtain selected ACs depending of current supermode
1322  std::vector<GNEAttributeCarrier*> selectedACs = myViewNet->getNet()->getAttributeCarriers()->getSelectedAttributeCarriers(false);
1323  // add id into ACs to unselect
1324  for (const auto& selectedAC : selectedACs) {
1325  ACsToUnselect.insert(std::make_pair(selectedAC->getID(), selectedAC));
1326  }
1327  }
1328  // handle ids
1329  for (const auto& AC : ACs) {
1330  // iterate over AtributeCarriers an place it in ACsToSelect or ACsToUnselect
1331  switch (setOperation) {
1333  ACsToUnselect.insert(std::make_pair(AC->getID(), AC));
1334  break;
1336  if (ACsToUnselect.find(std::make_pair(AC->getID(), AC)) != ACsToUnselect.end()) {
1337  ACsToSelect.insert(std::make_pair(AC->getID(), AC));
1338  }
1339  break;
1340  default:
1341  ACsToSelect.insert(std::make_pair(AC->getID(), AC));
1342  break;
1343  }
1344  }
1345  // select junctions and their connections if Auto select junctions is enabled (note: only for "add mode")
1347  std::set<GNEEdge*> edgesToSelect;
1348  // iterate over ACsToSelect and extract edges
1349  for (const auto& AC : ACsToSelect) {
1350  if (AC.second->getTagProperty().getTag() == SUMO_TAG_EDGE) {
1351  edgesToSelect.insert(myViewNet->getNet()->getAttributeCarriers()->retrieveEdge(AC.second->getID()));
1352  }
1353  }
1354  // iterate over extracted edges
1355  for (const auto& edgeToSelect : edgesToSelect) {
1356  // select junction source and all connections and crossings
1357  ACsToSelect.insert(std::make_pair(edgeToSelect->getFromJunction()->getID(), edgeToSelect->getFromJunction()));
1358  for (const auto& connectionToSelect : edgeToSelect->getFromJunction()->getGNEConnections()) {
1359  ACsToSelect.insert(std::make_pair(connectionToSelect->getID(), connectionToSelect));
1360  }
1361  for (const auto& crossingToSelect : edgeToSelect->getFromJunction()->getGNECrossings()) {
1362  ACsToSelect.insert(std::make_pair(crossingToSelect->getID(), crossingToSelect));
1363  }
1364  // select junction destiny and all connections and crossings
1365  ACsToSelect.insert(std::make_pair(edgeToSelect->getToJunction()->getID(), edgeToSelect->getToJunction()));
1366  for (const auto& connectionToSelect : edgeToSelect->getToJunction()->getGNEConnections()) {
1367  ACsToSelect.insert(std::make_pair(connectionToSelect->getID(), connectionToSelect));
1368  }
1369  for (const auto& crossingToSelect : edgeToSelect->getToJunction()->getGNECrossings()) {
1370  ACsToSelect.insert(std::make_pair(crossingToSelect->getID(), crossingToSelect));
1371  }
1372  }
1373  }
1374  // only continue if there is ACs to select or unselect
1375  if ((ACsToSelect.size() + ACsToUnselect.size()) > 0) {
1376  // first unselect AC of ACsToUnselect and then selects AC of ACsToSelect
1377  myViewNet->getUndoList()->begin(GUIIcon::MODESELECT, "selection");
1378  for (const auto& ACToUnselect : ACsToUnselect) {
1379  if (ACToUnselect.second->getTagProperty().isSelectable()) {
1380  ACToUnselect.second->setAttribute(GNE_ATTR_SELECTED, "false", myViewNet->getUndoList());
1381  }
1382  }
1383  for (const auto& ACToSelect : ACsToSelect) {
1384  if (ACToSelect.second->getTagProperty().isSelectable()) {
1385  ACToSelect.second->setAttribute(GNE_ATTR_SELECTED, "true", myViewNet->getUndoList());
1386  }
1387  }
1388  // finish operation
1389  myViewNet->getUndoList()->end();
1390  }
1391 }
1392 
1393 
1394 std::vector<GNEAttributeCarrier*>
1395 GNESelectorFrame::getMatches(const SumoXMLTag ACTag, const SumoXMLAttr ACAttr, const char compOp, const double val, const std::string& expr) {
1396  std::vector<GNEAttributeCarrier*> result;
1397  // first retrieve all ACs using ACTag
1398  const auto allACbyTag = myViewNet->getNet()->getAttributeCarriers()->retrieveAttributeCarriers(ACTag);
1399  // get Tag value
1400  const auto& tagValue = GNEAttributeCarrier::getTagProperty(ACTag);
1401  // iterate over all ACs
1402  for (const auto& AC : allACbyTag) {
1403  if (expr == "" && compOp == '@') {
1404  result.push_back(AC);
1405  } else if (tagValue.hasAttribute(ACAttr) && tagValue.getAttributeProperties(ACAttr).isNumerical()) {
1406  double acVal;
1407  std::istringstream buf(AC->getAttribute(ACAttr));
1408  buf >> acVal;
1409  switch (compOp) {
1410  case '<':
1411  if (acVal < val) {
1412  result.push_back(AC);
1413  }
1414  break;
1415  case '>':
1416  if (acVal > val) {
1417  result.push_back(AC);
1418  }
1419  break;
1420  case '=':
1421  if (acVal == val) {
1422  result.push_back(AC);
1423  }
1424  break;
1425  }
1426  } else {
1427  // string match
1428  std::string acVal = AC->getAttributeForSelection(ACAttr);
1429  switch (compOp) {
1430  case '@':
1431  if (acVal.find(expr) != std::string::npos) {
1432  result.push_back(AC);
1433  }
1434  break;
1435  case '!':
1436  if (acVal.find(expr) == std::string::npos) {
1437  result.push_back(AC);
1438  }
1439  break;
1440  case '=':
1441  if (acVal == expr) {
1442  result.push_back(AC);
1443  }
1444  break;
1445  case '^':
1446  if (acVal != expr) {
1447  result.push_back(AC);
1448  }
1449  break;
1450  }
1451  }
1452  }
1453  return result;
1454 }
1455 
1456 
1457 std::vector<GNEAttributeCarrier*>
1458 GNESelectorFrame::getGenericMatches(const std::vector<GNEGenericData*>& genericDatas, const std::string& attr, const char compOp, const double val, const std::string& expr) {
1459  std::vector<GNEAttributeCarrier*> result;
1460  // iterate over generic datas
1461  for (const auto& genericData : genericDatas) {
1462  if (expr == "" && compOp == '@') {
1463  result.push_back(genericData);
1464  } else if (attr != toString(GNE_ATTR_PARENT)) {
1465  double acVal;
1466  std::istringstream buf(genericData->getParameter(attr, "0"));
1467  buf >> acVal;
1468  switch (compOp) {
1469  case '<':
1470  if (acVal < val) {
1471  result.push_back(genericData);
1472  }
1473  break;
1474  case '>':
1475  if (acVal > val) {
1476  result.push_back(genericData);
1477  }
1478  break;
1479  case '=':
1480  if (acVal == val) {
1481  result.push_back(genericData);
1482  }
1483  break;
1484  }
1485  } else {
1486  // string match
1487  std::string acVal = genericData->getAttributeForSelection(GNE_ATTR_PARENT);
1488  switch (compOp) {
1489  case '@':
1490  if (acVal.find(expr) != std::string::npos) {
1491  result.push_back(genericData);
1492  }
1493  break;
1494  case '!':
1495  if (acVal.find(expr) == std::string::npos) {
1496  result.push_back(genericData);
1497  }
1498  break;
1499  case '=':
1500  if (acVal == expr) {
1501  result.push_back(genericData);
1502  }
1503  break;
1504  case '^':
1505  if (acVal != expr) {
1506  result.push_back(genericData);
1507  }
1508  break;
1509  }
1510  }
1511  }
1512  return result;
1513 }
1514 
1515 
1516 FXVerticalFrame*
1518  return myContentFrame;
1519 }
1520 
1521 
1524  return myModificationMode;
1525 }
1526 
1527 
1530  return mySelectionInformation;
1531 }
1532 
1533 /****************************************************************************/
FXDEFMAP(GNESelectorFrame::ModificationMode) ModificationModeMap[]
@ NETWORK
Network mode (Edges, junctions, etc..)
@ DATA
Data mode (edgeData, LaneData etc..)
@ DEMAND
Demand mode (Routes, Vehicles etc..)
@ MID_GNE_SELECTORFRAME_SELECTSCALE
changes the visual scaling of selected items
Definition: GUIAppEnum.h:891
@ MID_GNE_SELECTORFRAME_CHILDREN
select/unselect children
Definition: GUIAppEnum.h:901
@ MID_CHOOSEN_SAVE
Save set.
Definition: GUIAppEnum.h:557
@ MID_CHOOSEN_INVERT
Deselect selected items.
Definition: GUIAppEnum.h:569
@ MID_CHOOSEN_DELETE
delete set
Definition: GUIAppEnum.h:561
@ MID_CHOOSEN_OPERATION
set type of selection
Definition: GUIAppEnum.h:551
@ MID_CHOOSEN_LOAD
Load set.
Definition: GUIAppEnum.h:555
@ MID_CHOOSEN_CLEAR
Clear set.
Definition: GUIAppEnum.h:559
@ MID_GNE_SELECT
select element
Definition: GUIAppEnum.h:813
@ MID_GNE_SELECTORFRAME_PARENTS
select/unselect parents
Definition: GUIAppEnum.h:899
#define GUIDesignSpinDial
Definition: GUIDesigns.h:417
#define GUIDesignButton
Definition: GUIDesigns.h:68
#define GUIDesignComboBox
Definition: GUIDesigns.h:267
#define GUIDesignComboBoxNCol
number of column of every combo box
Definition: GUIDesigns.h:285
#define GUIDesignAuxiliarHorizontalFrame
design for auxiliar (Without borders) horizontal frame used to pack another frames
Definition: GUIDesigns.h:343
#define GUIDesignLabelThickCenter
label with thick, text justify to left and extended with (used in selector frame)
Definition: GUIDesigns.h:238
#define GUIDesignRadioButton
Definition: GUIDesigns.h:179
#define GUIDesignLabelFrameInformation
label extended over frame without thick and with text justify to left, used to show information in fr...
Definition: GUIDesigns.h:244
@ GLO_EDGERELDATA
edge relation data
@ GLO_TAZRELDATA
TAZ relation data.
@ GLO_TRANSHIP
a container tranship
@ GLO_ROUTE
a route
@ GLO_JUNCTION
a junction
@ GLO_LANE
a lane
@ GLO_TAZ
Traffic Assignment Zones (TAZs)
@ GLO_CONTAINER
a container
@ GLO_EDGEDATA
edge data
@ GLO_CONNECTION
a connection
@ GLO_ADDITIONALELEMENT
reserved GLO type to pack all additionals elements
@ GLO_PERSONTRIP
a person trip
@ GLO_EDGE
an edge
@ GLO_VEHICLE
a vehicle
@ GLO_PERSON
a person
@ GLO_TRANSPORT
a container transport
@ GLO_POI
a poi
@ GLO_STOP
a stop
@ GLO_POLYGON
a polygon
@ GLO_CROSSING
a tl-logic
FXString gCurrentFolder
The folder used as last.
#define WRITE_DEBUG(msg)
Definition: MsgHandler.h:290
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:288
SumoXMLTag
Numbers representing SUMO-XML - element names.
@ SUMO_TAG_TAZ
a traffic assignment zone
@ SUMO_TAG_CONTAINERFLOW
@ SUMO_TAG_VEHICLE
description of a vehicle
@ GNE_TAG_FLOW_ROUTE
a flow definition using a route instead of a from-to edges route (used in NETEDIT)
@ GNE_TAG_FLOW_WITHROUTE
description of a vehicle with an embedded route (used in NETEDIT)
@ SUMO_TAG_FLOW
a flow definitio nusing a from-to edges instead of a route (used by router)
@ SUMO_TAG_CONTAINER
@ SUMO_TAG_JUNCTION
begin/end of the description of a junction
@ SUMO_TAG_ROUTE
begin/end of the description of a route
@ SUMO_TAG_MEANDATA_EDGE
an edge based mean data detector
@ SUMO_TAG_POLY
begin/end of the description of a polygon
@ SUMO_TAG_LANE
begin/end of the description of a single lane
@ GNE_TAG_VEHICLE_WITHROUTE
description of a vehicle with an embedded route (used in NETEDIT)
@ SUMO_TAG_PERSON
@ SUMO_TAG_PERSONFLOW
@ SUMO_TAG_TRIP
a single trip definition (used by router)
@ SUMO_TAG_EDGE
begin/end of the description of an edge
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
@ SUMO_ATTR_SPEED
@ 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_ID
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
FXGroupBoxModule (based on FXGroupBox)
void setText(const std::string &text)
set text
FXVerticalFrame * getCollapsableFrame()
get collapsable frame (used by all elements that will be collapsed if button is toogled)
const GNETagProperties & getTagProperty() const
get tagProperty associated with this Attribute Carrier
GNENet * getNet() const
get pointer to net
A road/street connecting two junctions (netedit-version)
Definition: GNEEdge.h:53
void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
Definition: GNEEdge.cpp:894
void hideElementSet()
hide element set
void showElementSet()
show element set
GNEViewNet * myViewNet
View Net.
Definition: GNEFrame.h:114
FXVerticalFrame * myContentFrame
Vertical frame that holds all widgets of frame.
Definition: GNEFrame.h:117
virtual void show()
show Frame
Definition: GNEFrame.cpp:108
virtual void hide()
hide Frame
Definition: GNEFrame.cpp:117
This lane is powered by an underlying GNEEdge and basically knows how to draw itself.
Definition: GNELane.h:46
GNEAttributeCarrier * retrieveAttributeCarrier(const GUIGlID id, bool hardFail=true) const
get a single attribute carrier based on a GLID
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
FXComboBox * myParentsComboBox
comboBox for parents
SelectionHierarchy(GNESelectorFrame *selectorFrameParent)
FOX-declaration.
FXButton * myUnselectParentsButton
unselect parents button
FXButton * mySelectParentsButton
select parents button
FXButton * myUnselectChildrenButton
unselect parents button
long onCmdParents(FXObject *obj, FXSelector, void *)
called when user press select/unselect parents button
long onCmdChildren(FXObject *obj, FXSelector, void *)
called when user press select/unselect children button
long onCmdSelectItem(FXObject *obj, FXSelector, void *)
called when user select an item in comboBox
FXComboBox * myChildrenComboBox
comboBox for children
const std::vector< std::pair< Selection, std::string > > myItems
FXButton * mySelectChildrenButton
select children button
void updateInformationLabel()
update information label
SelectionOperation(GNESelectorFrame *selectorFrameParent)
FOX-declaration.
long onCmdSave(FXObject *, FXSelector, void *)
Called when the user presses the Save-button.
bool processDataElementSelection(const bool onlyCount, const bool onlyUnselect, bool &ignoreLocking)
process data element selection
bool askContinueIfLock() const
ask if continue due locking
long onCmdDelete(FXObject *, FXSelector, void *)
Called when the user presses the delete-button.
long onCmdInvert(FXObject *, FXSelector, void *)
Called when the user presses the Invert-button.
long onCmdClear(FXObject *, FXSelector, void *)
Called when the user presses the Clear-button.
long onCmdLoad(FXObject *, FXSelector, void *)
Called when the user presses the Load-button.
bool processDemandElementSelection(const bool onlyCount, const bool onlyUnselect, bool &ignoreLocking)
process demand element selection
bool processNetworkElementSelection(const bool onlyCount, const bool onlyUnselect, bool &ignoreLocking)
FOX need this.
long onCmdScaleSelection(FXObject *, FXSelector, void *)
Called when the user changes visual scaling.
VisualScaling(GNESelectorFrame *selectorFrameParent)
FOX-declaration.
FXRealSpinner * mySelectionScaling
Spinner for selection scaling.
FXVerticalFrame * getContentFrame() const
get vertical frame that holds all widgets of frame
std::vector< GNEAttributeCarrier * > getMatches(const SumoXMLTag ACTag, const SumoXMLAttr ACAttr, const char compOp, const double val, const std::string &expr)
return ACs of the given type with matching attrs
void updateFrameAfterUndoRedo()
function called after undo/redo in the current frame
std::vector< GNEAttributeCarrier * > getGenericMatches(const std::vector< GNEGenericData * > &genericDatas, const std::string &attr, const char compOp, const double val, const std::string &expr)
return GenericDatas of the given type with matching attrs
ModificationMode * getModificationModeModule() const
get modification mode modul
GNESelectorFrame(FXHorizontalFrame *horizontalFrameParent, GNEViewNet *viewNet)
Constructor.
void show()
show Frame
GNESelectorFrame::SelectionOperation * mySelectionOperation
modul for selection operations
~GNESelectorFrame()
Destructor.
GNESelectorFrame::SelectionInformation * mySelectionInformation
modul for selection information
GNESelectorFrame::VisualScaling * myVisualScaling
modul for visual scaling
GNEElementSet * myDemandElementSet
moduls for select demand element set
GNESelectorFrame::Information * myInformation
information modul
GNESelectorFrame::SelectionHierarchy * mySelectionHierarchy
modul for selection hierarchy
GNEElementSet * myNetworkElementSet
moduls for select network element set
GNEElementSet * myDataElementSet
moduls for select data element set
GNESelectorFrame::ModificationMode * myModificationMode
modul for change modification mode
void clearCurrentSelection() const
clear current selection with possibility of undo/redo
void hide()
hide Frame
void handleIDs(const std::vector< GNEAttributeCarrier * > &ACs, const ModificationMode::Operation setop=ModificationMode::Operation::DEFAULT)
apply list of ids to the current selection according to Operation,
SelectionInformation * getSelectionInformation() const
getmodul for selection information
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...
GNENet * getNet() const
get the net object
const GNEViewNetHelper::EditModes & getEditModes() const
get edit modes
Definition: GNEViewNet.cpp:513
bool autoSelectNodes()
whether to autoselect nodes or to lanes
Definition: GNEViewNet.cpp:635
GNEUndoList * getUndoList() const
get the undoList object
static StringBijection< GUIGlObjectType > TypeNames
associates object types with strings
Definition: GUIGlObject.h:66
GUIGlObjectType getType() const
Returns the type of the object as coded in GUIGlObjectType.
GUIGlID getGlID() const
Returns the numerical id of the object.
static GUIGlObjectStorage gIDStorage
A single static instance of this class.
GUIGlObject * getObjectBlocking(GUIGlID id)
Returns the object from the container locking it.
static FXIcon * getIcon(const GUIIcon which)
returns a icon previously defined in the enum GUIIcon
static FXString getFilename2Write(FXWindow *parent, const FXString &header, const FXString &extension, FXIcon *icon, FXString &currentFolder)
Returns the file name to write.
Definition: MFXUtils.cpp:82
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:61
void close()
Closes the device and removes it from the dictionary.
static OutputDevice & getDevice(const std::string &name)
Returns the described OutputDevice.
C++ TraCI client API implementation.
Definition: GUI.h:31
const std::string & getString(const T key) const
bool isCurrentSupermodeDemand() const
@check if current supermode is Demand
bool isCurrentSupermodeData() const
@check if current supermode is Data
bool isCurrentSupermodeNetwork() const
@check if current supermode is Network