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.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>
32 #include <utils/xml/NamespaceIDs.h>
33 
34 #include "GNESelectorFrame.h"
35 #include "GNEElementSet.h"
36 
37 
38 // ===========================================================================
39 // FOX callback mapping
40 // ===========================================================================
41 FXDEFMAP(GNESelectorFrame::ModificationMode) ModificationModeMap[] = {
43 };
44 
47 };
48 
49 FXDEFMAP(GNESelectorFrame::SelectionOperation) SelectionOperationMap[] = {
56 };
57 
58 FXDEFMAP(GNESelectorFrame::SelectionHierarchy) SelectionHierarchyMap[] = {
62 };
63 
64 // Object implementation
65 FXIMPLEMENT(GNESelectorFrame::ModificationMode, MFXGroupBoxModule, ModificationModeMap, ARRAYNUMBER(ModificationModeMap))
66 FXIMPLEMENT(GNESelectorFrame::VisualScaling, MFXGroupBoxModule, VisualScalingMap, ARRAYNUMBER(VisualScalingMap))
67 FXIMPLEMENT(GNESelectorFrame::SelectionOperation, MFXGroupBoxModule, SelectionOperationMap, ARRAYNUMBER(SelectionOperationMap))
68 FXIMPLEMENT(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 
89 void
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 
141 void
142 GNESelectorFrame::SelectionInformation::updateInformationLabel(const std::string& element, int number) {
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 
178 long
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 
234 long
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 
273 void
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  mySelectorFrameParent->myViewNet->updateViewNet();
321  }
322 }
323 
324 
325 long
326 GNESelectorFrame::SelectionOperation::onCmdLoad(FXObject*, FXSelector, void*) {
327  // get the new file name
328  FXFileDialog opendialog(getCollapsableFrame(), TL("Open List of Selected Items"));
329  opendialog.setIcon(GUIIconSubSys::getIcon(GUIIcon::OPEN));
330  opendialog.setSelectMode(SELECTFILE_EXISTING);
331  opendialog.setPatternList("Selection files (*.txt)\nAll files (*)");
332  if (gCurrentFolder.length() != 0) {
333  opendialog.setDirectory(gCurrentFolder);
334  }
335  if (opendialog.execute()) {
336  gCurrentFolder = opendialog.getDirectory();
337  loadFromFile(opendialog.getFilename().text());
338  }
339  return 1;
340 }
341 
342 
343 long
344 GNESelectorFrame::SelectionOperation::onCmdSave(FXObject*, FXSelector, void*) {
345  FXString file = MFXUtils::getFilename2Write(this,
346  TL("Save List of selected Items"), ".txt",
348  if (file == "") {
349  return 1;
350  }
351  try {
352  OutputDevice& dev = OutputDevice::getDevice(file.text());
353  // get selected attribute carriers
354  const auto selectedACs = mySelectorFrameParent->myViewNet->getNet()->getAttributeCarriers()->getSelectedAttributeCarriers(false);
355  for (const auto& selectedAC : selectedACs) {
356  GUIGlObject* object = dynamic_cast<GUIGlObject*>(selectedAC);
357  if (object) {
358  dev << GUIGlObject::TypeNames.getString(object->getType()) << ":" << selectedAC->getID() << "\n";
359  }
360  }
361  dev.close();
362  } catch (IOError& e) {
363  // write warning if netedit is running in testing mode
364  WRITE_DEBUG("Opening FXMessageBox 'error storing selection'");
365  // open message box error
366  FXMessageBox::error(getCollapsableFrame(), MBOX_OK, "Storing Selection failed", "%s", e.what());
367  // write warning if netedit is running in testing mode
368  WRITE_DEBUG("Closed FXMessageBox 'error storing selection' with 'OK'");
369  }
370  return 1;
371 }
372 
373 
374 long
376  bool ignoreLocking = false;
377  // only continue if there is element for selecting
378  if ((mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeNetwork() && processNetworkElementSelection(true, false, ignoreLocking)) ||
379  (mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeDemand() && processDemandElementSelection(true, false, ignoreLocking)) ||
380  (mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeData() && processDataElementSelection(true, false, ignoreLocking))) {
381  // for invert selection, first clean current selection and next select elements of set "unselectedElements"
382  mySelectorFrameParent->myViewNet->getUndoList()->begin(GUIIcon::MODESELECT, TL("invert selection"));
383  // invert selection of elements depending of current supermode
384  if (mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeNetwork()) {
385  processNetworkElementSelection(false, true, ignoreLocking);
386  } else if (mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeDemand()) {
387  processDemandElementSelection(false, true, ignoreLocking);
388  } else if (mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeData()) {
389  processDataElementSelection(false, true, ignoreLocking);
390  }
391  // finish selection operation
392  mySelectorFrameParent->myViewNet->getUndoList()->end();
393  }
394  return 1;
395 }
396 
397 long
399  // acts like the 'del' hotkey
400  mySelectorFrameParent->getViewNet()->hotkeyDel();
401  return 1;
402 }
403 
404 
405 long
407  bool ignoreLocking = false;
408  // only continue if there is element for selecting
409  if ((mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeNetwork() && processNetworkElementSelection(true, false, ignoreLocking)) ||
410  (mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeDemand() && processDemandElementSelection(true, false, ignoreLocking)) ||
411  (mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeData() && processDataElementSelection(true, false, ignoreLocking))) {
412  // for invert selection, first clean current selection and next select elements of set "unselectedElements"
413  mySelectorFrameParent->myViewNet->getUndoList()->begin(GUIIcon::MODESELECT, TL("invert selection"));
414  // invert selection of elements depending of current supermode
415  if (mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeNetwork()) {
416  // invert network elements
417  processNetworkElementSelection(false, false, ignoreLocking);
418  } else if (mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeDemand()) {
419  // invert demand elements
420  processDemandElementSelection(false, false, ignoreLocking);
421  } else if (mySelectorFrameParent->myViewNet->getEditModes().isCurrentSupermodeData()) {
422  // invert data elements
423  processDataElementSelection(false, false, ignoreLocking);
424  }
425  // finish selection operation
426  mySelectorFrameParent->myViewNet->getUndoList()->end();
427  }
428  return 1;
429 }
430 
431 
432 long
434  // begin undoList operation
435  mySelectorFrameParent->getViewNet()->getUndoList()->begin(Supermode::NETWORK, GUIIcon::SIMPLIFYNETWORK, TL("reduce network"));
436  // invert and clear
437  onCmdInvert(0, 0, 0);
438  onCmdDelete(0, 0, 0);
439  // end undoList operation
440  mySelectorFrameParent->getViewNet()->getUndoList()->end();
441  return 1;
442 }
443 
444 
445 bool
446 GNESelectorFrame::SelectionOperation::processNetworkElementSelection(const bool onlyCount, const bool onlyUnselect, bool& ignoreLocking) {
447  // obtan locks (only for improve code legibly)
448  const auto& locks = mySelectorFrameParent->getViewNet()->getLockManager();
449  // get attribute carriers (only for improve code legibly)
450  const auto& ACs = mySelectorFrameParent->myViewNet->getNet()->getAttributeCarriers();
451  // obtain undoList (only for improve code legibly)
452  GNEUndoList* undoList = mySelectorFrameParent->myViewNet->getUndoList();
453  // iterate over junctions
454  for (const auto& junction : ACs->getJunctions()) {
455  // check if junction selection is locked
456  if (ignoreLocking || !locks.isObjectLocked(GLO_JUNCTION, false)) {
457  if (onlyCount) {
458  return true;
459  } else if (onlyUnselect || junction.second.second->isAttributeCarrierSelected()) {
460  junction.second.second->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
461  } else {
462  junction.second.second->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
463  }
464  } else if (onlyCount) {
465  ignoreLocking = askContinueIfLock();
466  return true;
467  }
468  // due we iterate over all junctions, only it's necessary iterate over incoming edges
469  for (const auto& incomingEdge : junction.second.second->getGNEIncomingEdges()) {
470  // special case for clear
471  if (onlyUnselect) {
472  // check if edge selection is locked
473  if (ignoreLocking || !locks.isObjectLocked(GLO_EDGE, false)) {
474  if (onlyCount) {
475  return true;
476  } else {
477  incomingEdge->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
478  }
479  } else if (onlyCount) {
480  ignoreLocking = askContinueIfLock();
481  return true;
482  }
483  // check if lane selection is locked
484  if (ignoreLocking || !locks.isObjectLocked(GLO_LANE, false)) {
485  for (const auto& lane : incomingEdge->getLanes()) {
486  if (onlyCount) {
487  return true;
488  } else {
489  lane->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
490  }
491  }
492  } else if (onlyCount) {
493  ignoreLocking = askContinueIfLock();
494  return true;
495  }
496  } else if (mySelectorFrameParent->myViewNet->checkSelectEdges()) {
497  // check if edge selection is locked
498  if (ignoreLocking || !locks.isObjectLocked(GLO_EDGE, false)) {
499  if (onlyCount) {
500  return true;
501  } else if (onlyUnselect || incomingEdge->isAttributeCarrierSelected()) {
502  incomingEdge->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
503  } else {
504  incomingEdge->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
505  }
506  } else if (onlyCount) {
507  ignoreLocking = askContinueIfLock();
508  return true;
509  }
510  } else {
511  // check if lane selection is locked
512  if (ignoreLocking || !locks.isObjectLocked(GLO_LANE, false)) {
513  for (const auto& lane : incomingEdge->getLanes()) {
514  if (onlyCount) {
515  return true;
516  } else if (onlyUnselect || lane->isAttributeCarrierSelected()) {
517  lane->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
518  } else {
519  lane->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
520  }
521  }
522  } else if (onlyCount) {
523  ignoreLocking = askContinueIfLock();
524  return true;
525  }
526  }
527  // check if connection selection is locked
528  if (ignoreLocking || !locks.isObjectLocked(GLO_CONNECTION, false)) {
529  for (const auto& connection : incomingEdge->getGNEConnections()) {
530  if (onlyCount) {
531  return true;
532  } else if (onlyUnselect || connection->isAttributeCarrierSelected()) {
533  connection->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
534  } else {
535  connection->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
536  }
537  }
538  } else if (onlyCount) {
539  ignoreLocking = askContinueIfLock();
540  return true;
541  }
542  }
543  // check if crossing selection is locked
544  if (ignoreLocking || !locks.isObjectLocked(GLO_CROSSING, false)) {
545  for (const auto& crossing : junction.second.second->getGNECrossings()) {
546  if (onlyCount) {
547  return true;
548  } else if (onlyUnselect || crossing->isAttributeCarrierSelected()) {
549  crossing->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
550  } else {
551  crossing->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
552  }
553  }
554  } else if (onlyCount) {
555  ignoreLocking = askContinueIfLock();
556  return true;
557  }
558  // check if walkingArea selection is locked
559  if (ignoreLocking || !locks.isObjectLocked(GLO_WALKINGAREA, false)) {
560  for (const auto& walkingArea : junction.second.second->getGNEWalkingAreas()) {
561  if (onlyCount) {
562  return true;
563  } else if (onlyUnselect || walkingArea->isAttributeCarrierSelected()) {
564  walkingArea->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
565  } else {
566  walkingArea->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
567  }
568  }
569  } else if (onlyCount) {
570  ignoreLocking = askContinueIfLock();
571  return true;
572  }
573  }
574  // check if additionals selection is locked
575  if (ignoreLocking || !locks.isObjectLocked(GLO_ADDITIONALELEMENT, false)) {
576  for (const auto& additionalTag : ACs->getAdditionals()) {
577  // first check if additional is selectable
579  for (const auto& additional : additionalTag.second) {
580  if (onlyCount) {
581  return true;
582  } else if (onlyUnselect || additional.second->isAttributeCarrierSelected()) {
583  additional.second->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
584  } else {
585  additional.second->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
586  }
587  }
588  }
589  }
590  } else if (onlyCount) {
591  ignoreLocking = askContinueIfLock();
592  return true;
593  }
594  // check if wires selection is locked
595  if (ignoreLocking || !locks.isObjectLocked(GLO_WIRE, false)) {
596  for (const auto& wireTag : ACs->getAdditionals()) {
597  // first check if wire is selectable
599  for (const auto& wire : wireTag.second) {
600  if (onlyCount) {
601  return true;
602  } else if (onlyUnselect || wire.second->isAttributeCarrierSelected()) {
603  wire.second->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
604  } else {
605  wire.second->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
606  }
607  }
608  }
609  }
610  } else if (onlyCount) {
611  ignoreLocking = askContinueIfLock();
612  return true;
613  }
614  // invert TAZs
615  if (ignoreLocking || !locks.isObjectLocked(GLO_TAZ, false)) {
616  for (const auto& TAZ : ACs->getAdditionals().at(SUMO_TAG_TAZ)) {
617  if (onlyCount) {
618  return true;
619  } else if (onlyUnselect || TAZ.second->isAttributeCarrierSelected()) {
620  TAZ.second->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
621  } else {
622  TAZ.second->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
623  }
624  }
625  for (const auto& TAZSource : ACs->getAdditionals().at(SUMO_TAG_TAZSOURCE)) {
626  if (onlyCount) {
627  return true;
628  } else if (onlyUnselect || TAZSource.second->isAttributeCarrierSelected()) {
629  TAZSource.second->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
630  } else {
631  TAZSource.second->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
632  }
633  }
634  for (const auto& TAZSink : ACs->getAdditionals().at(SUMO_TAG_TAZSINK)) {
635  if (onlyCount) {
636  return true;
637  } else if (onlyUnselect || TAZSink.second->isAttributeCarrierSelected()) {
638  TAZSink.second->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
639  } else {
640  TAZSink.second->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
641  }
642  }
643  } else if (onlyCount) {
644  ignoreLocking = askContinueIfLock();
645  return true;
646  }
647  // invert polygons
648  if (ignoreLocking || !locks.isObjectLocked(GLO_POLYGON, false)) {
649  for (const auto& polygon : ACs->getAdditionals().at(SUMO_TAG_POLY)) {
650  if (onlyCount) {
651  return true;
652  } else if (onlyUnselect || polygon.second->isAttributeCarrierSelected()) {
653  polygon.second->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
654  } else {
655  polygon.second->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
656  }
657  }
658  } else if (onlyCount) {
659  ignoreLocking = askContinueIfLock();
660  return true;
661  }
662  // invert POIs and POILanes
663  if (ignoreLocking || !locks.isObjectLocked(GLO_POI, false)) {
664  for (const auto& POI : ACs->getAdditionals().at(SUMO_TAG_POI)) {
665  if (onlyCount) {
666  return true;
667  } else if (onlyUnselect || POI.second->isAttributeCarrierSelected()) {
668  POI.second->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
669  } else {
670  POI.second->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
671  }
672  }
673  for (const auto& POILane : ACs->getAdditionals().at(GNE_TAG_POILANE)) {
674  if (onlyCount) {
675  return true;
676  } else if (onlyUnselect || POILane.second->isAttributeCarrierSelected()) {
677  POILane.second->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
678  } else {
679  POILane.second->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
680  }
681  }
682  for (const auto& POIGeo : ACs->getAdditionals().at(GNE_TAG_POIGEO)) {
683  if (onlyCount) {
684  return true;
685  } else if (onlyUnselect || POIGeo.second->isAttributeCarrierSelected()) {
686  POIGeo.second->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
687  } else {
688  POIGeo.second->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
689  }
690  }
691  } else if (onlyCount) {
692  ignoreLocking = askContinueIfLock();
693  return true;
694  }
695  // inver JuPedSim elements
696  if (ignoreLocking || !locks.isObjectLocked(GLO_JPS_WALKABLEAREA, false)) {
697  for (const auto& walkableArea : ACs->getAdditionals().at(GNE_TAG_JPS_WALKABLEAREA)) {
698  if (onlyCount) {
699  return true;
700  } else if (onlyUnselect || walkableArea.second->isAttributeCarrierSelected()) {
701  walkableArea.second->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
702  } else {
703  walkableArea.second->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
704  }
705  }
706  } else if (onlyCount) {
707  ignoreLocking = askContinueIfLock();
708  return true;
709  }
710  if (ignoreLocking || !locks.isObjectLocked(GLO_JPS_OBSTACLE, false)) {
711  for (const auto& obstacle : ACs->getAdditionals().at(GNE_TAG_JPS_OBSTACLE)) {
712  if (onlyCount) {
713  return true;
714  } else if (onlyUnselect || obstacle.second->isAttributeCarrierSelected()) {
715  obstacle.second->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
716  } else {
717  obstacle.second->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
718  }
719  }
720  } else if (onlyCount) {
721  ignoreLocking = askContinueIfLock();
722  return true;
723  }
724  return false;
725 }
726 
727 
728 bool
729 GNESelectorFrame::SelectionOperation::processDemandElementSelection(const bool onlyCount, const bool onlyUnselect, bool& ignoreLocking) {
730  // obtan locks (only for improve code legibly)
731  const auto& locks = mySelectorFrameParent->getViewNet()->getLockManager();
732  // obtain undoList (only for improve code legibly)
733  GNEUndoList* undoList = mySelectorFrameParent->myViewNet->getUndoList();
734  // get demand elements
735  const auto& demandElements = mySelectorFrameParent->myViewNet->getNet()->getAttributeCarriers()->getDemandElements();
736  // invert routes
737  if (ignoreLocking || !locks.isObjectLocked(GLO_ROUTE, false)) {
738  for (const auto& route : demandElements.at(SUMO_TAG_ROUTE)) {
739  if (onlyCount) {
740  return true;
741  } else if (onlyUnselect || route.second->isAttributeCarrierSelected()) {
742  route.second->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
743  } else {
744  route.second->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
745  }
746  }
747  // iterate over all embedded routes
748  for (const auto& vehicle : demandElements.at(GNE_TAG_VEHICLE_WITHROUTE)) {
749  if (onlyCount) {
750  return true;
751  } else if (onlyUnselect || vehicle.second->getChildDemandElements().front()->isAttributeCarrierSelected()) {
752  vehicle.second->getChildDemandElements().front()->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
753  } else {
754  vehicle.second->getChildDemandElements().front()->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
755  }
756  }
757  for (const auto& routeFlow : demandElements.at(GNE_TAG_FLOW_WITHROUTE)) {
758  if (onlyCount) {
759  return true;
760  } else if (onlyUnselect || routeFlow.second->getChildDemandElements().front()->isAttributeCarrierSelected()) {
761  routeFlow.second->getChildDemandElements().front()->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
762  } else {
763  routeFlow.second->getChildDemandElements().front()->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
764  }
765  }
766  } else if (onlyCount) {
767  ignoreLocking = askContinueIfLock();
768  return true;
769  }
770  // invert vehicles
771  if (ignoreLocking || !locks.isObjectLocked(GLO_VEHICLE, false)) {
772  for (const auto& vehicleTag : NamespaceIDs::vehicles) {
773  for (const auto& vehicle : demandElements.at(vehicleTag)) {
774  if (onlyCount) {
775  return true;
776  } else if (onlyUnselect || vehicle.second->isAttributeCarrierSelected()) {
777  vehicle.second->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
778  } else {
779  vehicle.second->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
780  }
781  }
782  }
783  } else if (onlyCount) {
784  ignoreLocking = askContinueIfLock();
785  return true;
786  }
787  // invert persons
788  if (ignoreLocking || !locks.isObjectLocked(GLO_PERSON, false)) {
789  for (const auto& personTag : NamespaceIDs::persons) {
790  for (const auto& person : demandElements.at(personTag)) {
791  if (onlyCount) {
792  return true;
793  } else if (onlyUnselect || person.second->isAttributeCarrierSelected()) {
794  person.second->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
795  } else {
796  person.second->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
797  }
798  }
799  }
800  } else if (onlyCount) {
801  ignoreLocking = askContinueIfLock();
802  return true;
803  }
804  // invert person trip
805  if (ignoreLocking || !locks.isObjectLocked(GLO_PERSON, false)) {
806  for (const auto& personTag : NamespaceIDs::persons) {
807  for (const auto& person : demandElements.at(personTag)) {
808  for (const auto& personPlan : person.second->getChildDemandElements()) {
809  if (personPlan->getTagProperty().isPersonTrip()) {
810  if (onlyCount) {
811  return true;
812  } else if (onlyUnselect || personPlan->isAttributeCarrierSelected()) {
813  personPlan->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
814  } else {
815  personPlan->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
816  }
817  }
818  }
819  }
820  }
821  } else if (onlyCount) {
822  ignoreLocking = askContinueIfLock();
823  return true;
824  }
825  // invert ride
826  if (ignoreLocking || !locks.isObjectLocked(GLO_PERSON, false)) {
827  for (const auto& personTag : NamespaceIDs::persons) {
828  for (const auto& person : demandElements.at(personTag)) {
829  for (const auto& personPlan : person.second->getChildDemandElements()) {
830  if (personPlan->getTagProperty().isPlanRide()) {
831  if (onlyCount) {
832  return true;
833  } else if (onlyUnselect || personPlan->isAttributeCarrierSelected()) {
834  personPlan->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
835  } else {
836  personPlan->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
837  }
838  }
839  }
840  }
841  }
842  } else if (onlyCount) {
843  ignoreLocking = askContinueIfLock();
844  return true;
845  }
846  // invert walks
847  if (ignoreLocking || !locks.isObjectLocked(GLO_PERSON, false)) {
848  for (const auto& personTag : NamespaceIDs::persons) {
849  for (const auto& person : demandElements.at(personTag)) {
850  for (const auto& personPlan : person.second->getChildDemandElements()) {
851  if (personPlan->getTagProperty().isPlanWalk()) {
852  if (onlyCount) {
853  return true;
854  } else if (onlyUnselect || personPlan->isAttributeCarrierSelected()) {
855  personPlan->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
856  } else {
857  personPlan->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
858  }
859  }
860  }
861  }
862  }
863  } else if (onlyCount) {
864  ignoreLocking = askContinueIfLock();
865  return true;
866  }
867  // invert containers
868  if (ignoreLocking || !locks.isObjectLocked(GLO_CONTAINER, false)) {
869  for (const auto& containerTag : NamespaceIDs::containers) {
870  for (const auto& container : demandElements.at(containerTag)) {
871  if (onlyCount) {
872  return true;
873  } else if (onlyUnselect || container.second->isAttributeCarrierSelected()) {
874  container.second->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
875  } else {
876  container.second->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
877  }
878  }
879  }
880  } else if (onlyCount) {
881  ignoreLocking = askContinueIfLock();
882  return true;
883  }
884  // invert transport
885  if (ignoreLocking || !locks.isObjectLocked(GLO_CONTAINER, false)) {
886  for (const auto& containerTag : NamespaceIDs::containers) {
887  for (const auto& container : demandElements.at(containerTag)) {
888  for (const auto& containerPlan : container.second->getChildDemandElements()) {
889  if (containerPlan->getTagProperty().isPlanTransport()) {
890  if (onlyCount) {
891  return true;
892  } else if (onlyUnselect || containerPlan->isAttributeCarrierSelected()) {
893  containerPlan->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
894  } else {
895  containerPlan->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
896  }
897  }
898  }
899  }
900  }
901  } else if (onlyCount) {
902  ignoreLocking = askContinueIfLock();
903  return true;
904  }
905  // invert tranships
906  if (ignoreLocking || !locks.isObjectLocked(GLO_CONTAINER, false)) {
907  for (const auto& containerTag : NamespaceIDs::containers) {
908  for (const auto& container : demandElements.at(containerTag)) {
909  for (const auto& containerPlan : container.second->getChildDemandElements()) {
910  if (containerPlan->getTagProperty().isPlanTranship()) {
911  if (onlyCount) {
912  return true;
913  } else if (onlyUnselect || containerPlan->isAttributeCarrierSelected()) {
914  containerPlan->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
915  } else {
916  containerPlan->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
917  }
918  }
919  }
920  }
921  }
922  } else if (onlyCount) {
923  ignoreLocking = askContinueIfLock();
924  return true;
925  }
926  // invert stops and waypoints
927  if (ignoreLocking || !locks.isObjectLocked(GLO_STOP, false)) {
928  for (const auto& demandElementTag : demandElements) {
929  for (const auto& demandElement : demandElementTag.second) {
930  if (demandElement.second->getTagProperty().isVehicleStop() ||
931  demandElement.second->getTagProperty().isVehicleWaypoint() ||
932  demandElement.second->getTagProperty().isPlanStop()) {
933  if (onlyCount) {
934  return true;
935  } else if (onlyUnselect || demandElement.second->isAttributeCarrierSelected()) {
936  demandElement.second->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
937  } else {
938  demandElement.second->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
939  }
940  }
941  }
942  }
943  } else if (onlyCount) {
944  ignoreLocking = askContinueIfLock();
945  return true;
946  }
947  return false;
948 }
949 
950 
951 bool
952 GNESelectorFrame::SelectionOperation::processDataElementSelection(const bool onlyCount, const bool onlyUnselect, bool& ignoreLocking) {
953  // get locks (only for improve code legibly)
954  const auto& locks = mySelectorFrameParent->getViewNet()->getLockManager();
955  // get undoRedo (only for improve code legibly)
956  const auto undoList = mySelectorFrameParent->myViewNet->getUndoList();
957  // get ACs (only for improve code legibly)
958  const auto& ACs = mySelectorFrameParent->myViewNet->getNet()->getAttributeCarriers();
959  // invert generic datas
960  for (const auto& genericDataTag : ACs->getGenericDatas()) {
961  for (const auto& genericData : genericDataTag.second) {
962  if (onlyCount && locks.isObjectLocked(genericData.second->getType(), false)) {
963  ignoreLocking = askContinueIfLock();
964  return true;
965  } else if ((ignoreLocking || (!locks.isObjectLocked(GLO_EDGEDATA, false) && genericData.second->getType() == GLO_EDGEDATA)) ||
966  (ignoreLocking || (!locks.isObjectLocked(GLO_EDGERELDATA, false) && genericData.second->getType() == GLO_EDGERELDATA)) ||
967  (ignoreLocking || (!locks.isObjectLocked(GLO_TAZRELDATA, false) && genericData.second->getType() == GLO_TAZRELDATA))) {
968  if (onlyCount) {
969  return true;
970  } else if (onlyUnselect || genericData.second->isAttributeCarrierSelected()) {
971  genericData.second->setAttribute(GNE_ATTR_SELECTED, "false", undoList);
972  } else {
973  genericData.second->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
974  }
975  }
976  }
977  }
978  return false;
979 }
980 
981 
982 bool
984  WRITE_DEBUG("Opening FXMessageBox 'confirm selection operation'");
985  // open question box
986  const FXuint answer = FXMessageBox::question(mySelectorFrameParent->getViewNet()->getApp(),
987  MBOX_YES_NO, "Confirm selection operation", "There are locked elements in the current selection.\nApply operation to locked elements?");
988  if (answer != 1) { //1:yes, 2:no, 4:esc
989  // write warning if netedit is running in testing mode
990  if (answer == 2) {
991  WRITE_DEBUG("Closed FXMessageBox 'confirm selection operation' with 'No'");
992  } else if (answer == 4) {
993  WRITE_DEBUG("Closed FXMessageBox 'confirm selection operation' with 'ESC'");
994  }
995  return false;
996  } else {
997  // write warning if netedit is running in testing mode
998  WRITE_DEBUG("Closed FXMessageBox 'confirm selection operation' with 'Yes'");
999  return true;
1000  }
1001 }
1002 
1003 // ---------------------------------------------------------------------------
1004 // ModificationMode::SelectionHierarchy - methods
1005 // ---------------------------------------------------------------------------
1006 
1008  MFXGroupBoxModule(selectorFrameParent, TL("Hierarchy operations")),
1009  mySelectorFrameParent(selectorFrameParent),
1010  myCurrentSelectedParent(Selection::ALL),
1011  myCurrentSelectedChild(Selection::ALL) {
1012  // create label for parents
1013  new FXLabel(getCollapsableFrame(), TL("Select parents"), nullptr, GUIDesignLabelThick(JUSTIFY_NORMAL));
1014  // Create MFXComboBoxIcon for parent comboBox
1017  // create parent buttons
1018  FXHorizontalFrame* parentButtons = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame);
1019  // Create "select" Button
1021  // Create "unselect" Button
1023  // create label for parents
1024  new FXLabel(getCollapsableFrame(), TL("Select children"), nullptr, GUIDesignLabelThick(JUSTIFY_NORMAL));
1025  // Create MFXComboBoxIcon for parent comboBox
1028  // create children buttons
1029  FXHorizontalFrame* childrenButtons = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame);
1030  // Create "select" Button
1032  // Create "unselect" Button
1034  // fill comboBoxes
1035  for (const auto& item : myItems) {
1036  myParentsComboBox->appendIconItem(item.second.c_str());
1037  myChildrenComboBox->appendIconItem(item.second.c_str());
1038  }
1039 }
1040 
1041 
1043 
1044 
1045 long
1047  if (obj == myParentsComboBox) {
1048  for (const auto& item : myItems) {
1049  if (item.second == myParentsComboBox->getText().text()) {
1050  // enable buttons
1051  mySelectParentsButton->enable();
1052  myUnselectParentsButton->enable();
1053  // change text color
1054  myParentsComboBox->setTextColor(FXRGB(0, 0, 0));
1055  // set current selected parent
1056  myCurrentSelectedParent = item.first;
1057  return 1;
1058  }
1059  }
1060  // item not found
1061  myCurrentSelectedParent = Selection::NOTHING;
1062  // disable buttons
1063  mySelectParentsButton->disable();
1064  myUnselectParentsButton->disable();
1065  myParentsComboBox->setTextColor(FXRGB(255, 0, 0));
1066  return 1;
1067  } else if (obj == myChildrenComboBox) {
1068  for (const auto& item : myItems) {
1069  if (item.second == myChildrenComboBox->getText().text()) {
1070  // enable buttons
1071  mySelectChildrenButton->enable();
1072  myUnselectChildrenButton->enable();
1073  // change text color
1074  myChildrenComboBox->setTextColor(FXRGB(0, 0, 0));
1075  // set current selected parent
1076  myCurrentSelectedChild = item.first;
1077  return 1;
1078  }
1079  }
1080  // item not found
1081  myCurrentSelectedChild = Selection::NOTHING;
1082  // disable buttons
1083  mySelectChildrenButton->disable();
1084  myUnselectChildrenButton->disable();
1085  myChildrenComboBox->setTextColor(FXRGB(255, 0, 0));
1086  return 1;
1087  }
1088  return 0;
1089 }
1090 
1091 
1092 long
1093 GNESelectorFrame::SelectionHierarchy::onCmdParents(FXObject* obj, FXSelector, void*) {
1094  // get selected elements
1095  const auto selectedACs = mySelectorFrameParent->getViewNet()->getNet()->getAttributeCarriers()->getSelectedAttributeCarriers(true);
1096  // check if there is selected ACs
1097  if ((selectedACs.size() > 0) && (myCurrentSelectedParent != Selection::NOTHING)) {
1098  // vector of hierarchical elements to select
1099  std::vector<GNEHierarchicalElement*> HEToSelect;
1100  for (const auto& selectedAC : selectedACs) {
1101  // get hierarchical element
1102  const auto HE = selectedAC->getHierarchicalElement();
1103  // junctions
1104  if ((myCurrentSelectedParent == Selection::ALL) || (myCurrentSelectedParent == Selection::JUNCTION)) {
1105  HEToSelect.insert(HEToSelect.end(), HE->getParentJunctions().begin(), HE->getParentJunctions().end());
1106  }
1107  // edges
1108  if ((myCurrentSelectedParent == Selection::ALL) || (myCurrentSelectedParent == Selection::EDGE)) {
1109  if (selectedAC->getTagProperty().getTag() == SUMO_TAG_LANE) {
1110  // special case for lanes
1111  HEToSelect.push_back(dynamic_cast<GNELane*>(selectedAC)->getParentEdge());
1112  } else {
1113  HEToSelect.insert(HEToSelect.end(), HE->getParentEdges().begin(), HE->getParentEdges().end());
1114  }
1115  }
1116  // lanes
1117  if ((myCurrentSelectedParent == Selection::ALL) || (myCurrentSelectedParent == Selection::LANE)) {
1118  HEToSelect.insert(HEToSelect.end(), HE->getParentLanes().begin(), HE->getParentLanes().end());
1119  }
1120  // additional
1121  if ((myCurrentSelectedParent == Selection::ALL) || (myCurrentSelectedParent == Selection::ADDITIONAL)) {
1122  HEToSelect.insert(HEToSelect.end(), HE->getParentAdditionals().begin(), HE->getParentAdditionals().end());
1123  }
1124  // wire
1125  if ((myCurrentSelectedParent == Selection::ALL) || (myCurrentSelectedParent == Selection::WIRE)) {
1126  HEToSelect.insert(HEToSelect.end(), HE->getParentAdditionals().begin(), HE->getParentAdditionals().end());
1127  }
1128  // demand
1129  if ((myCurrentSelectedParent == Selection::ALL) || (myCurrentSelectedParent == Selection::DEMAND)) {
1130  HEToSelect.insert(HEToSelect.end(), HE->getParentDemandElements().begin(), HE->getParentDemandElements().end());
1131  }
1132  // data
1133  if ((myCurrentSelectedParent == Selection::ALL) || (myCurrentSelectedParent == Selection::DATA)) {
1134  HEToSelect.insert(HEToSelect.end(), HE->getParentGenericDatas().begin(), HE->getParentGenericDatas().end());
1135  }
1136  }
1137  // select HE
1138  if (HEToSelect.size() > 0) {
1139  if (HEToSelect.size() > 1) {
1140  mySelectorFrameParent->getViewNet()->getUndoList()->begin(GUIIcon::SELECT, TL("select parents"));
1141  }
1142  for (const auto& HE : HEToSelect) {
1143  if (obj == mySelectParentsButton) {
1144  HE->setAttribute(GNE_ATTR_SELECTED, "true", mySelectorFrameParent->getViewNet()->getUndoList());
1145  } else {
1146  HE->setAttribute(GNE_ATTR_SELECTED, "false", mySelectorFrameParent->getViewNet()->getUndoList());
1147  }
1148  }
1149  if (HEToSelect.size() > 1) {
1150  mySelectorFrameParent->getViewNet()->getUndoList()->end();
1151  }
1152  }
1153  // update information label
1154  mySelectorFrameParent->mySelectionInformation->updateInformationLabel();
1155  // update viewNet
1156  mySelectorFrameParent->getViewNet()->update();
1157  }
1158  return 1;
1159 }
1160 
1161 
1162 long
1163 GNESelectorFrame::SelectionHierarchy::onCmdChildren(FXObject* obj, FXSelector, void*) {
1164  // get selected elements
1165  const auto selectedACs = mySelectorFrameParent->getViewNet()->getNet()->getAttributeCarriers()->getSelectedAttributeCarriers(true);
1166  // check if there is selected ACs
1167  if ((selectedACs.size() > 0) && (myCurrentSelectedChild != Selection::NOTHING)) {
1168  // vector of hierarchical elements to select
1169  std::vector<GNEHierarchicalElement*> HEToSelect;
1170  for (const auto& selectedAC : selectedACs) {
1171  // get hierarchical element
1172  const auto HE = selectedAC->getHierarchicalElement();
1173  // junctions
1174  if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::JUNCTION)) {
1175  if (selectedAC->getTagProperty().getTag() == SUMO_TAG_JUNCTION) {
1176  // special case for junction
1177  const auto junction = dynamic_cast<GNEJunction*>(selectedAC);
1178  // insert edges
1179  HEToSelect.insert(HEToSelect.end(), junction->getGNEIncomingEdges().begin(), junction->getGNEIncomingEdges().end());
1180  HEToSelect.insert(HEToSelect.end(), junction->getGNEOutgoingEdges().begin(), junction->getGNEOutgoingEdges().end());
1181  } else {
1182  HEToSelect.insert(HEToSelect.end(), HE->getChildJunctions().begin(), HE->getChildJunctions().end());
1183  }
1184  }
1185  // edges
1186  if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::EDGE)) {
1187  if (selectedAC->getTagProperty().getTag() == SUMO_TAG_EDGE) {
1188  // special case for edges
1189  const auto edge = dynamic_cast<GNEEdge*>(selectedAC);
1190  // insert lanes
1191  HEToSelect.insert(HEToSelect.end(), edge->getLanes().begin(), edge->getLanes().end());
1192  } else {
1193  HEToSelect.insert(HEToSelect.end(), HE->getChildEdges().begin(), HE->getChildEdges().end());
1194  }
1195  }
1196  // connections
1197  if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::CONNECTION)) {
1198  if (selectedAC->getTagProperty().getTag() == SUMO_TAG_EDGE) {
1199  // case for edges
1200  const auto edge = dynamic_cast<GNEEdge*>(selectedAC);
1201  // insert connections
1202  HEToSelect.insert(HEToSelect.end(), edge->getGNEConnections().begin(), edge->getGNEConnections().end());
1203  } else if (selectedAC->getTagProperty().getTag() == SUMO_TAG_LANE) {
1204  // case for lanes
1205  const auto lane = dynamic_cast<GNELane*>(selectedAC);
1206  // insert connections
1207  for (const auto& connection : lane->getParentEdge()->getGNEConnections()) {
1208  if (connection->getAttribute(SUMO_ATTR_FROM_LANE) == lane->getAttribute(SUMO_ATTR_INDEX)) {
1209  HEToSelect.push_back(connection);
1210  }
1211  }
1212  } else if (selectedAC->getTagProperty().getTag() == SUMO_TAG_JUNCTION) {
1213  // case for junction
1214  const auto junction = dynamic_cast<GNEJunction*>(selectedAC);
1215  // get connections
1216  const auto connections = junction->getGNEConnections();
1217  // insert connections
1218  HEToSelect.insert(HEToSelect.end(), connections.begin(), connections.end());
1219  }
1220  }
1221  // crossings
1222  if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::CROSSING)) {
1223  if (selectedAC->getTagProperty().getTag() == SUMO_TAG_JUNCTION) {
1224  // case for junction
1225  const auto junction = dynamic_cast<GNEJunction*>(selectedAC);
1226  // insert crossings
1227  HEToSelect.insert(HEToSelect.end(), junction->getGNECrossings().begin(), junction->getGNECrossings().end());
1228  }
1229  }
1230  // lanes
1231  if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::LANE)) {
1232  HEToSelect.insert(HEToSelect.end(), HE->getChildLanes().begin(), HE->getChildLanes().end());
1233  }
1234  // additional
1235  if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::ADDITIONAL)) {
1236  // avoid insert symbols
1237  for (const auto& additionalChild : HE->getChildAdditionals()) {
1238  if (!additionalChild->getTagProperty().isWireElement() && !additionalChild->getTagProperty().isSymbol()) {
1239  HEToSelect.push_back(additionalChild);
1240  }
1241  }
1242  }
1243  // wire
1244  if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::WIRE)) {
1245  // avoid insert symbols
1246  for (const auto& wireChild : HE->getChildAdditionals()) {
1247  if (wireChild->getTagProperty().isWireElement() && !wireChild->getTagProperty().isSymbol()) {
1248  HEToSelect.push_back(wireChild);
1249  }
1250  }
1251  }
1252  // demand
1253  if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::DEMAND)) {
1254  HEToSelect.insert(HEToSelect.end(), HE->getChildDemandElements().begin(), HE->getChildDemandElements().end());
1255  }
1256  // data
1257  if ((myCurrentSelectedChild == Selection::ALL) || (myCurrentSelectedChild == Selection::DATA)) {
1258  HEToSelect.insert(HEToSelect.end(), HE->getChildGenericDatas().begin(), HE->getChildGenericDatas().end());
1259  }
1260  }
1261  // select HE
1262  if (HEToSelect.size() > 0) {
1263  if (HEToSelect.size() > 1) {
1264  mySelectorFrameParent->getViewNet()->getUndoList()->begin(GUIIcon::SELECT, TL("select children"));
1265  }
1266  for (const auto& HE : HEToSelect) {
1267  if (obj == mySelectChildrenButton) {
1268  HE->setAttribute(GNE_ATTR_SELECTED, "true", mySelectorFrameParent->getViewNet()->getUndoList());
1269  } else {
1270  HE->setAttribute(GNE_ATTR_SELECTED, "false", mySelectorFrameParent->getViewNet()->getUndoList());
1271  }
1272  }
1273  if (HEToSelect.size() > 1) {
1274  mySelectorFrameParent->getViewNet()->getUndoList()->end();
1275  }
1276  }
1277  // update information label
1278  mySelectorFrameParent->mySelectionInformation->updateInformationLabel();
1279  // update viewNet
1280  mySelectorFrameParent->getViewNet()->update();
1281  }
1282  return 1;
1283 }
1284 
1285 // ---------------------------------------------------------------------------
1286 // GNECrossingFrame::Legend - methods
1287 // ---------------------------------------------------------------------------
1288 
1290  MFXGroupBoxModule(selectorFrameParent, TL("Information")) {
1291  // Create Selection Hint
1292  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);
1293 }
1294 
1295 
1297 
1298 // ---------------------------------------------------------------------------
1299 // GNESelectorFrame - methods
1300 // ---------------------------------------------------------------------------
1301 
1303  GNEFrame(viewParent, viewNet, TL("Selection")) {
1304  // create selection information
1306  // create Modification Mode modul
1308  // create ElementSet modul
1312  // create VisualScaling modul
1313  myVisualScaling = new VisualScaling(this);
1314  // create SelectionOperation modul
1316  // create SelectionHierarchy modul
1318  // create Information modul
1319  myInformation = new Information(this);
1320 }
1321 
1322 
1324 
1325 
1326 void
1328  // refresh element set
1330  // only show network element set
1335  // only show demand element set
1339  } else if (myViewNet->getEditModes().isCurrentSupermodeData()) {
1340  // only show data element set
1344  }
1345  // update information label
1347  // Show frame
1348  GNEFrame::show();
1349 }
1350 
1351 
1352 void
1354  // hide frame
1355  GNEFrame::hide();
1356 }
1357 
1358 
1359 void
1361  // update information label
1363 }
1364 
1365 
1366 void
1368  mySelectionOperation->onCmdClear(nullptr, 0, nullptr);
1369 }
1370 
1371 
1372 bool
1374  // get front AC
1375  auto AC = viewObjects.getAttributeCarrierFront();
1376  // check AC
1377  if (AC == nullptr) {
1378  return false;
1379  }
1380  // check locking
1381  if (myViewNet->getLockManager().isObjectLocked(AC->getGUIGlObject()->getType(), AC->isAttributeCarrierSelected())) {
1382  return false;
1383  }
1384  // check modes
1385  if ((AC->getTagProperty().isNetworkElement() || AC->getTagProperty().isAdditionalElement()) &&
1387  return false;
1388  }
1389  if (AC->getTagProperty().isDemandElement() && !myViewNet->getEditModes().isCurrentSupermodeDemand()) {
1390  return false;
1391  }
1392  if (AC->getTagProperty().isDataElement() && !myViewNet->getEditModes().isCurrentSupermodeData()) {
1393  return false;
1394  }
1395  // filter GLObjects by layer
1396  auto filteredGLObjects = GNEViewNetHelper::filterElementsByLayer(viewObjects.getGLObjects());
1397  // check if we have to open dialog
1398  if (filteredGLObjects.size() > 1) {
1399  myViewNet->openSelectDialogAtCursor(filteredGLObjects);
1400  } else {
1401  // toggle selection
1402  if (AC->isAttributeCarrierSelected()) {
1403  AC->unselectAttributeCarrier();
1404  } else {
1405  AC->selectAttributeCarrier();
1406  }
1407  // update information label
1409  }
1410  return true;
1411 }
1412 
1413 
1414 void
1415 GNESelectorFrame::handleIDs(const std::vector<GNEAttributeCarrier*>& ACs, const ModificationMode::Operation setop) {
1416  // declare set operation
1418  // declare two sets of attribute carriers, one for select and another for unselect
1419  std::set<std::pair<std::string, GNEAttributeCarrier*> > ACsToSelect, ACsToUnselect;
1420  // in restrict AND replace mode all current selected attribute carriers will be unselected
1421  if ((setOperation == ModificationMode::Operation::REPLACE) || (setOperation == ModificationMode::Operation::RESTRICT)) {
1422  // obtain selected ACs depending of current supermode
1423  std::vector<GNEAttributeCarrier*> selectedACs = myViewNet->getNet()->getAttributeCarriers()->getSelectedAttributeCarriers(false);
1424  // add id into ACs to unselect
1425  for (const auto& selectedAC : selectedACs) {
1426  ACsToUnselect.insert(std::make_pair(selectedAC->getID(), selectedAC));
1427  }
1428  }
1429  // handle ids
1430  for (const auto& AC : ACs) {
1431  // iterate over AttributeCarriers an place it in ACsToSelect or ACsToUnselect
1432  switch (setOperation) {
1434  ACsToUnselect.insert(std::make_pair(AC->getID(), AC));
1435  break;
1437  if (ACsToUnselect.find(std::make_pair(AC->getID(), AC)) != ACsToUnselect.end()) {
1438  ACsToSelect.insert(std::make_pair(AC->getID(), AC));
1439  }
1440  break;
1441  default:
1442  ACsToSelect.insert(std::make_pair(AC->getID(), AC));
1443  break;
1444  }
1445  }
1446  // select junctions and their connections if Auto select junctions is enabled (note: only for "add mode")
1448  std::set<GNEEdge*> edgesToSelect;
1449  // iterate over ACsToSelect and extract edges
1450  for (const auto& AC : ACsToSelect) {
1451  if (AC.second->getTagProperty().getTag() == SUMO_TAG_EDGE) {
1452  edgesToSelect.insert(myViewNet->getNet()->getAttributeCarriers()->retrieveEdge(AC.second->getID()));
1453  }
1454  }
1455  // iterate over extracted edges
1456  for (const auto& edgeToSelect : edgesToSelect) {
1457  // select junction source and all connections, crossings and walkingAreas
1458  ACsToSelect.insert(std::make_pair(edgeToSelect->getFromJunction()->getID(), edgeToSelect->getFromJunction()));
1459  for (const auto& connectionToSelect : edgeToSelect->getFromJunction()->getGNEConnections()) {
1460  ACsToSelect.insert(std::make_pair(connectionToSelect->getID(), connectionToSelect));
1461  }
1462  for (const auto& fromCrossingToSelect : edgeToSelect->getFromJunction()->getGNECrossings()) {
1463  ACsToSelect.insert(std::make_pair(fromCrossingToSelect->getID(), fromCrossingToSelect));
1464  }
1465  for (const auto& fromWalkingAreaToSelect : edgeToSelect->getFromJunction()->getGNEWalkingAreas()) {
1466  ACsToSelect.insert(std::make_pair(fromWalkingAreaToSelect->getID(), fromWalkingAreaToSelect));
1467  }
1468  // select junction destination and all connections, crossings and walkingAreas
1469  ACsToSelect.insert(std::make_pair(edgeToSelect->getToJunction()->getID(), edgeToSelect->getToJunction()));
1470  for (const auto& connectionToSelect : edgeToSelect->getToJunction()->getGNEConnections()) {
1471  ACsToSelect.insert(std::make_pair(connectionToSelect->getID(), connectionToSelect));
1472  }
1473  for (const auto& toCrossingToSelect : edgeToSelect->getToJunction()->getGNECrossings()) {
1474  ACsToSelect.insert(std::make_pair(toCrossingToSelect->getID(), toCrossingToSelect));
1475  }
1476  for (const auto& toWalkingAreaToSelect : edgeToSelect->getToJunction()->getGNEWalkingAreas()) {
1477  ACsToSelect.insert(std::make_pair(toWalkingAreaToSelect->getID(), toWalkingAreaToSelect));
1478  }
1479  }
1480  }
1481  // only continue if there is ACs to select or unselect
1482  if ((ACsToSelect.size() + ACsToUnselect.size()) > 0) {
1483  // first unselect AC of ACsToUnselect and then selects AC of ACsToSelect
1484  myViewNet->getUndoList()->begin(GUIIcon::MODESELECT, TL("selection"));
1485  for (const auto& ACToUnselect : ACsToUnselect) {
1486  if (ACToUnselect.second->getTagProperty().isSelectable()) {
1487  ACToUnselect.second->setAttribute(GNE_ATTR_SELECTED, "false", myViewNet->getUndoList());
1488  }
1489  }
1490  for (const auto& ACToSelect : ACsToSelect) {
1491  if (ACToSelect.second->getTagProperty().isSelectable()) {
1492  ACToSelect.second->setAttribute(GNE_ATTR_SELECTED, "true", myViewNet->getUndoList());
1493  }
1494  }
1495  // finish operation
1496  myViewNet->getUndoList()->end();
1497  }
1498 }
1499 
1500 
1501 std::vector<GNEAttributeCarrier*>
1502 GNESelectorFrame::getMatches(const SumoXMLTag ACTag, const SumoXMLAttr ACAttr, const char compOp, const double val, const std::string& expr) {
1503  std::vector<GNEAttributeCarrier*> result;
1504  // first retrieve all ACs using ACTag
1505  const auto allACbyTag = myViewNet->getNet()->getAttributeCarriers()->retrieveAttributeCarriers(ACTag);
1506  // get Tag value
1507  const auto& tagValue = GNEAttributeCarrier::getTagProperty(ACTag);
1508  // iterate over all ACs
1509  for (const auto& AC : allACbyTag) {
1510  if (expr == "" && compOp == '@') {
1511  result.push_back(AC);
1512  } else if (tagValue.hasAttribute(ACAttr) && tagValue.getAttributeProperties(ACAttr).isNumerical()) {
1513  double acVal;
1514  std::istringstream buf(AC->getAttribute(ACAttr));
1515  buf >> acVal;
1516  switch (compOp) {
1517  case '<':
1518  if (acVal < val) {
1519  result.push_back(AC);
1520  }
1521  break;
1522  case '>':
1523  if (acVal > val) {
1524  result.push_back(AC);
1525  }
1526  break;
1527  case '=':
1528  if (acVal == val) {
1529  result.push_back(AC);
1530  }
1531  break;
1532  }
1533  } else {
1534  // string match
1535  std::string acVal = AC->getAttributeForSelection(ACAttr);
1536  switch (compOp) {
1537  case '@':
1538  if (acVal.find(expr) != std::string::npos) {
1539  result.push_back(AC);
1540  }
1541  break;
1542  case '!':
1543  if (acVal.find(expr) == std::string::npos) {
1544  result.push_back(AC);
1545  }
1546  break;
1547  case '=':
1548  if (acVal == expr) {
1549  result.push_back(AC);
1550  }
1551  break;
1552  case '^':
1553  if (acVal != expr) {
1554  result.push_back(AC);
1555  }
1556  break;
1557  }
1558  }
1559  }
1560  return result;
1561 }
1562 
1563 
1564 std::vector<GNEAttributeCarrier*>
1565 GNESelectorFrame::getGenericMatches(const std::vector<GNEGenericData*>& genericDatas, const std::string& attr, const char compOp, const double val, const std::string& expr) {
1566  std::vector<GNEAttributeCarrier*> result;
1567  // iterate over generic datas
1568  for (const auto& genericData : genericDatas) {
1569  if (expr == "" && compOp == '@') {
1570  result.push_back(genericData);
1571  } else if (attr != toString(GNE_ATTR_PARENT)) {
1572  double acVal;
1573  std::istringstream buf(genericData->getParameter(attr, "0"));
1574  buf >> acVal;
1575  switch (compOp) {
1576  case '<':
1577  if (acVal < val) {
1578  result.push_back(genericData);
1579  }
1580  break;
1581  case '>':
1582  if (acVal > val) {
1583  result.push_back(genericData);
1584  }
1585  break;
1586  case '=':
1587  if (acVal == val) {
1588  result.push_back(genericData);
1589  }
1590  break;
1591  }
1592  } else {
1593  // string match
1594  std::string acVal = genericData->getAttributeForSelection(GNE_ATTR_PARENT);
1595  switch (compOp) {
1596  case '@':
1597  if (acVal.find(expr) != std::string::npos) {
1598  result.push_back(genericData);
1599  }
1600  break;
1601  case '!':
1602  if (acVal.find(expr) == std::string::npos) {
1603  result.push_back(genericData);
1604  }
1605  break;
1606  case '=':
1607  if (acVal == expr) {
1608  result.push_back(genericData);
1609  }
1610  break;
1611  case '^':
1612  if (acVal != expr) {
1613  result.push_back(genericData);
1614  }
1615  break;
1616  }
1617  }
1618  }
1619  return result;
1620 }
1621 
1622 
1623 FXVerticalFrame*
1625  return myContentFrame;
1626 }
1627 
1628 
1631  return myModificationMode;
1632 }
1633 
1634 
1637  return mySelectionOperation;
1638 }
1639 
1640 
1643  return mySelectionInformation;
1644 }
1645 
1646 /****************************************************************************/
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:1046
@ MID_GNE_SELECTORFRAME_CHILDREN
select/unselect children
Definition: GUIAppEnum.h:1060
@ MID_CHOOSEN_SAVE
Save set.
Definition: GUIAppEnum.h:599
@ MID_CHOOSEN_INVERT
Deselect selected items.
Definition: GUIAppEnum.h:611
@ MID_CHOOSEN_DELETE
delete set
Definition: GUIAppEnum.h:603
@ MID_CHOOSEN_OPERATION
set type of selection
Definition: GUIAppEnum.h:593
@ MID_CHOOSEN_LOAD
Load set.
Definition: GUIAppEnum.h:597
@ MID_CHOOSEN_REDUCE
simplify network reduction
Definition: GUIAppEnum.h:615
@ MID_CHOOSEN_CLEAR
Clear set.
Definition: GUIAppEnum.h:601
@ MID_GNE_SELECT
select element
Definition: GUIAppEnum.h:948
@ MID_GNE_SELECTORFRAME_PARENTS
select/unselect parents
Definition: GUIAppEnum.h:1058
#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
@ GLO_EDGERELDATA
edge relation data
@ GLO_TAZRELDATA
TAZ relation data.
@ GLO_WALKINGAREA
a walkingArea
@ GLO_JPS_WALKABLEAREA
walkable area
@ GLO_ROUTE
a route
@ GLO_WIRE
reserved GLO type for packing all wire elements
@ GLO_JUNCTION
a junction
@ GLO_LANE
a lane
@ GLO_TAZ
Traffic Assignment Zones (TAZs)
@ GLO_CONTAINER
a container
@ GLO_JPS_OBSTACLE
obstacles
@ GLO_EDGEDATA
edge data
@ GLO_CONNECTION
a connection
@ GLO_ADDITIONALELEMENT
reserved GLO type for packing all additionals elements
@ GLO_EDGE
an edge
@ GLO_VEHICLE
a vehicle
@ GLO_PERSON
a person
@ GLO_POI
poi (over view, geo and lane)
@ GLO_STOP
a stop
@ GLO_POLYGON
polygon
@ GLO_CROSSING
a tl-logic
FXString gCurrentFolder
The folder used as last.
@ OPEN
open icons
@ SIMPLIFYNETWORK
@ SAVE
save icons
#define WRITE_DEBUG(msg)
Definition: MsgHandler.h:306
#define WRITE_ERRORF(...)
Definition: MsgHandler.h:305
#define TL(string)
Definition: MsgHandler.h:315
SumoXMLTag
Numbers representing SUMO-XML - element names.
@ SUMO_TAG_TAZ
a traffic assignment zone
@ SUMO_TAG_TAZSINK
a sink within a district (connection road)
@ GNE_TAG_EDGEREL_SINGLE
@ SUMO_TAG_POI
begin/end of the description of a Point of interest
@ SUMO_TAG_VEHICLE
description of a vehicle
@ GNE_TAG_POIGEO
Point of interest over view with GEO attributes.
@ GNE_TAG_FLOW_WITHROUTE
description of a vehicle with an embedded route
@ SUMO_TAG_JUNCTION
begin/end of the description of a junction
@ SUMO_TAG_ROUTE
begin/end of the description of a route
@ SUMO_TAG_POLY
begin/end of the description of a polygon
@ SUMO_TAG_LANE
begin/end of the description of a single lane
@ GNE_TAG_VEHICLE_WITHROUTE
description of a vehicle with an embedded route
@ GNE_TAG_POILANE
Point of interest over Lane.
@ GNE_TAG_JPS_OBSTACLE
polygon used for draw juPedSim obstacles
@ SUMO_TAG_TAZSOURCE
a source within a district (connection road)
@ GNE_TAG_JPS_WALKABLEAREA
polygon used for draw juPedSim walkable areas
@ 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)
virtual GUIGlObject * getGUIGlObject()=0
const GNETagProperties & getTagProperty() const
get tagProperty associated with this Attribute Carrier
bool isTemplate() const
check if this AC is template
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
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:121
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 processDataElementSelection(const bool onlyCount, const bool onlyUnselect, bool &ignoreLocking)
process data element selection
bool askContinueIfLock() const
ask if continue due locking
long onCmdDelete(FXObject *, FXSelector, void *)
Called when the user presses the delete-button.
long onCmdReduce(FXObject *, FXSelector, void *)
Called when the user presses the Reduce-button.
long onCmdInvert(FXObject *, FXSelector, void *)
Called when the user presses the Invert-button.
long onCmdClear(FXObject *, FXSelector, void *)
Called when the user presses the Clear-button.
long onCmdLoad(FXObject *, FXSelector, void *)
Called when the user presses the Load-button.
void loadFromFile(const std::string &file) const
load from file
bool processDemandElementSelection(const bool onlyCount, const bool onlyUnselect, bool &ignoreLocking)
process demand element selection
bool processNetworkElementSelection(const bool onlyCount, const bool onlyUnselect, bool &ignoreLocking)
FOX need this.
long onCmdScaleSelection(FXObject *, FXSelector, void *)
Called when the user changes visual scaling.
VisualScaling(GNESelectorFrame *selectorFrameParent)
FOX-declaration.
FXRealSpinner * mySelectionScaling
Spinner for selection scaling.
FXVerticalFrame * getContentFrame() const
get vertical frame that holds all widgets of frame
std::vector< GNEAttributeCarrier * > getMatches(const SumoXMLTag ACTag, const SumoXMLAttr ACAttr, const char compOp, const double val, const std::string &expr)
return ACs of the given type with matching attrs
void updateFrameAfterUndoRedo()
function called after undo/redo in the current frame
ModificationMode * getModificationModeModul() const
get modification mode modul
std::vector< GNEAttributeCarrier * > getGenericMatches(const std::vector< GNEGenericData * > &genericDatas, const std::string &attr, const char compOp, const double val, const std::string &expr)
return GenericDatas of the given type with matching attrs
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 isAdditionalPureElement() const
return true if tag correspond to a pure additional element
bool isWireElement() const
return true if tag correspond to a Wire element
bool isDemandElement() const
return true if tag correspond to a demand element
void end()
End undo command sub-group. If the sub-group is still empty, it will be deleted; otherwise,...
void begin(GUIIcon icon, const std::string &description)
Begin undo command sub-group with current supermode. This begins a new group of commands that are tre...
bool isObjectLocked(GUIGlObjectType objectType, const bool selected) const
check if given GLObject is locked for inspect, select, delete and move
class used to group all variables related with objects under cursor after a click over view
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
Definition: GNEViewNet.cpp:703
void openSelectDialogAtCursor(const std::vector< GUIGlObject * > &GLObjects)
open select dialog at cursor
Definition: GNEViewNet.cpp:660
bool autoSelectNodes()
whether to autoselect nodes or to lanes
Definition: GNEViewNet.cpp:853
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.
Definition: GNEViewParent.h:88
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
Definition: GUIDesigns.cpp:128
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
Definition: GUIDesigns.cpp:138
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.
Definition: GUIGlObject.h:156
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 const std::vector< SumoXMLTag > vehicles
vehicles namespace
Definition: NamespaceIDs.h:59
static const std::vector< SumoXMLTag > persons
persons namespace
Definition: NamespaceIDs.h:62
static const std::vector< SumoXMLTag > containers
containers namespace
Definition: NamespaceIDs.h:65
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, bool usePrefix=true)
Returns the described OutputDevice.
C++ TraCI client API implementation.
Definition: POI.h:34
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