SUMO - Simulation of Urban MObility
GNESelectorFrame.cpp
Go to the documentation of this file.
1 /****************************************************************************/
7 // The Widget for modifying selections of network-elements
8 // (some elements adapted from GUIDialog_GLChosenEditor)
9 /****************************************************************************/
10 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
11 // Copyright (C) 2001-2017 DLR (http://www.dlr.de/) and contributors
12 /****************************************************************************/
13 //
14 // This file is part of SUMO.
15 // SUMO is free software: you can redistribute it and/or modify
16 // it under the terms of the GNU General Public License as published by
17 // the Free Software Foundation, either version 3 of the License, or
18 // (at your option) any later version.
19 //
20 /****************************************************************************/
21 
22 
23 // ===========================================================================
24 // included modules
25 // ===========================================================================
26 #ifdef _MSC_VER
27 #include <windows_config.h>
28 #else
29 #include <config.h>
30 #endif
31 
32 #include <iostream>
42 
43 #include "GNESelectorFrame.h"
44 #include "GNEViewNet.h"
45 #include "GNEViewParent.h"
46 #include "GNENet.h"
47 #include "GNEJunction.h"
48 #include "GNEEdge.h"
49 #include "GNELane.h"
50 #include "GNEUndoList.h"
51 #include "GNEChange_Selection.h"
52 #include "GNEAttributeCarrier.h"
53 
54 
55 // ===========================================================================
56 // FOX callback mapping
57 // ===========================================================================
58 FXDEFMAP(GNESelectorFrame) GNESelectorFrameMap[] = {
60  FXMAPFUNC(SEL_COMMAND, MID_CHOOSEN_ELEMENTS, GNESelectorFrame::onCmdSubset),
61  FXMAPFUNC(SEL_COMMAND, MID_CHOOSEN_LOAD, GNESelectorFrame::onCmdLoad),
62  FXMAPFUNC(SEL_COMMAND, MID_CHOOSEN_SAVE, GNESelectorFrame::onCmdSave),
63  FXMAPFUNC(SEL_COMMAND, MID_CHOOSEN_INVERT, GNESelectorFrame::onCmdInvert),
64  FXMAPFUNC(SEL_COMMAND, MID_CHOOSEN_CLEAR, GNESelectorFrame::onCmdClear),
65  FXMAPFUNC(SEL_COMMAND, MID_GNE_SELMB_TAG, GNESelectorFrame::onCmdSelMBTag),
68  FXMAPFUNC(SEL_COMMAND, MID_HELP, GNESelectorFrame::onCmdHelp),
70 };
71 
72 // Object implementation
73 FXIMPLEMENT(GNESelectorFrame, FXVerticalFrame, GNESelectorFrameMap, ARRAYNUMBER(GNESelectorFrameMap))
74 
75 // ===========================================================================
76 // method definitions
77 // ===========================================================================
78 GNESelectorFrame::GNESelectorFrame(FXHorizontalFrame* horizontalFrameParent, GNEViewNet* viewNet):
79  GNEFrame(horizontalFrameParent, viewNet, getStats().c_str()),
80  mySetOperation(SET_ADD),
81  myCurrentTag(SUMO_TAG_NOTHING),
82  myCurrentAttribute(SUMO_ATTR_NOTHING),
83  ALL_VCLASS_NAMES_MATCH_STRING("all " + joinToString(SumoVehicleClassStrings.getStrings(), " ")) {
84  // selection modification mode
85  FXGroupBox* selBox = new FXGroupBox(myContentFrame, "Modification Mode", GUIDesignGroupBoxFrame);
86  // Create all options buttons
87  myAddRadioButton = new FXRadioButton(selBox, "add\t\tSelected objects are added to the previous selection",
89  myRemoveRadioButton = new FXRadioButton(selBox, "remove\t\tSelected objects are removed from the previous selection",
91  myKeepRadioButton = new FXRadioButton(selBox, "keep\t\tRestrict previous selection by the current selection",
93  myReplaceRadioButton = new FXRadioButton(selBox, "replace\t\tReplace previous selection by the current selection",
95  myAddRadioButton->setCheck(true);
96  // Create groupBox for selection by expression matching (match box)
97  FXGroupBox* elementBox = new FXGroupBox(myContentFrame, "type of element", GUIDesignGroupBoxFrame);
98  // Create MatchTagBox for tags and fill it
99  mySetComboBox = new FXComboBox(elementBox, GUIDesignComboBoxNCol, this, MID_CHOOSEN_ELEMENTS, GUIDesignComboBox);
100  mySetComboBox->appendItem("Net Element");
101  mySetComboBox->appendItem("Additional");
102  mySetComboBox->setNumVisible(mySetComboBox->getNumItems());
103  // Create groupBox fro selection by expression matching (match box)
104  FXGroupBox* matchBox = new FXGroupBox(myContentFrame, "Match Attribute", GUIDesignGroupBoxFrame);
105  // Create MatchTagBox for tags
106  myMatchTagComboBox = new FXComboBox(matchBox, GUIDesignComboBoxNCol, this, MID_GNE_SELMB_TAG, GUIDesignComboBox);
107  // Create listBox for Attributes
108  myMatchAttrComboBox = new FXComboBox(matchBox, GUIDesignComboBoxNCol, this, MID_GME_SELMB_ATTRIBUTE, GUIDesignComboBox);
109  // Create TextField for Match string
110  myMatchString = new FXTextField(matchBox, GUIDesignTextFieldNCol, this, MID_GNE_SELMB_STRING, GUIDesignTextField);
111  // Fill list of sub-items
112  onCmdSubset(0, 0, 0);
113  // Set speed of edge as default attribute
114  myCurrentTag = SUMO_TAG_EDGE;
115  myMatchAttrComboBox->setCurrentItem(3);
116  myCurrentAttribute = SUMO_ATTR_SPEED;
117  // Set default value for Match string
118  myMatchString->setText(">10.0");
119  // Create help button
120  new FXButton(matchBox, "Help", 0, this, MID_HELP, GUIDesignButtonRectangular);
121  // Create Groupbox for visual scalings
122  FXGroupBox* selSizeBox = new FXGroupBox(myContentFrame, "Visual Scaling", GUIDesignGroupBoxFrame);
123  // Create spin button and configure it
124  mySelectionScaling = new FXRealSpinDial(selSizeBox, 7, this, MID_GNE_SELECT_SCALE, GUIDesignSpinDial);
125  mySelectionScaling->setNumberFormat(1);
126  mySelectionScaling->setIncrements(0.1, .5, 1);
127  mySelectionScaling->setRange(1, 100);
128  mySelectionScaling->setValue(1);
129  mySelectionScaling->setHelpText("Enlarge selected objects");
130  // Create groupbox for additional buttons
131  FXGroupBox* additionalButtons = new FXGroupBox(myContentFrame, "Operations for selections", GUIDesignGroupBoxFrame);
132  // Create "Clear List" Button
133  new FXButton(additionalButtons, "Clear\t\t", 0, this, MID_CHOOSEN_CLEAR, GUIDesignButton);
134  // Create "Invert" Button
135  new FXButton(additionalButtons, "Invert\t\t", 0, this, MID_CHOOSEN_INVERT, GUIDesignButton);
136  // Create "Save" Button
137  new FXButton(additionalButtons, "Save\t\tSave ids of currently selected objects to a file.", 0, this, MID_CHOOSEN_SAVE, GUIDesignButton);
138  // Create "Load" Button
139  new FXButton(additionalButtons, "Load\t\tLoad ids from a file according to the current modfication mode.", 0, this, MID_CHOOSEN_LOAD, GUIDesignButton);
140  // Create groupbox for information about selections
141  FXGroupBox* selectionHintGroupBox = new FXGroupBox(myContentFrame, "Information", GUIDesignGroupBoxFrame);
142  // Create Selection Hint
143  new FXLabel(selectionHintGroupBox, " - Hold <SHIFT> for \n rectangle selection.\n - Press <DEL> to\n delete selected items.", 0, GUIDesignLabelLeft);
144 }
145 
146 
149 }
150 
151 
152 long
153 GNESelectorFrame::onCmdSelectOperation(FXObject* obj, FXSelector, void*) {
154  if (obj == myAddRadioButton) {
156  myAddRadioButton->setCheck(true);
157  myRemoveRadioButton->setCheck(false);
158  myKeepRadioButton->setCheck(false);
159  myReplaceRadioButton->setCheck(false);
160  return 1;
161  } else if (obj == myRemoveRadioButton) {
163  myAddRadioButton->setCheck(false);
164  myRemoveRadioButton->setCheck(true);
165  myKeepRadioButton->setCheck(false);
166  myReplaceRadioButton->setCheck(false);
167  return 1;
168  } else if (obj == myKeepRadioButton) {
170  myAddRadioButton->setCheck(false);
171  myRemoveRadioButton->setCheck(false);
172  myKeepRadioButton->setCheck(true);
173  myReplaceRadioButton->setCheck(false);
174  return 1;
175  } else if (obj == myReplaceRadioButton) {
177  myAddRadioButton->setCheck(false);
178  myRemoveRadioButton->setCheck(false);
179  myKeepRadioButton->setCheck(false);
180  myReplaceRadioButton->setCheck(true);
181  return 1;
182  } else {
183  return 0;
184  }
185 }
186 
187 
188 long
189 GNESelectorFrame::onCmdSubset(FXObject*, FXSelector, void*) {
190  if ((mySetComboBox->getText() == "Net Element") || (mySetComboBox->getText() == "Additional")) {
191  mySetComboBox->setTextColor(FXRGB(0, 0, 0));
192  myMatchTagComboBox->enable();
193  myMatchAttrComboBox->enable();
194  myMatchString->enable();
195  // Clear items of myMatchTagComboBox
196  myMatchTagComboBox->clearItems();
197  // Set items depending of current items
198  const bool netElements = mySetComboBox->getText() == "Net Element";
199  const std::vector<SumoXMLTag>& tags = GNEAttributeCarrier::allowedTags(netElements);
200  for (std::vector<SumoXMLTag>::const_iterator it = tags.begin(); it != tags.end(); it++) {
201  myMatchTagComboBox->appendItem(toString(*it).c_str());
202  }
203  myMatchTagComboBox->setCurrentItem(0); // edges
204  myMatchTagComboBox->setNumVisible(myMatchTagComboBox->getNumItems());
205  // Fill attributes with the current element type
206  onCmdSelMBTag(0, 0, 0);
207  return 1;
208  } else {
209  mySetComboBox->setTextColor(FXRGB(255, 0, 0));
210  myMatchTagComboBox->disable();
211  myMatchAttrComboBox->disable();
212  myMatchString->disable();
213  return 1;
214  }
215 }
216 
217 
218 long
219 GNESelectorFrame::onCmdLoad(FXObject*, FXSelector, void*) {
220  // get the new file name
221  FXFileDialog opendialog(this, "Open List of Selected Items");
222  opendialog.setIcon(GUIIconSubSys::getIcon(ICON_EMPTY));
223  opendialog.setSelectMode(SELECTFILE_EXISTING);
224  opendialog.setPatternList("Selection files (*.txt)\nAll files (*)");
225  if (gCurrentFolder.length() != 0) {
226  opendialog.setDirectory(gCurrentFolder);
227  }
228  if (opendialog.execute()) {
229  gCurrentFolder = opendialog.getDirectory();
230  std::string file = opendialog.getFilename().text();
231  // @todo maybe rewrite so that mySetOperation also applies to loaded items?
232  std::string errors;
233  std::set<GUIGlID> ids = gSelected.loadIDs(file, errors);
234  handleIDs(std::vector<GUIGlID>(ids.begin(), ids.end()), false);
235  if (errors != "") {
236  // write warning if netedit is running in testing mode
237  if (myViewNet->isTestingModeEnabled() == true) {
238  WRITE_WARNING("Opening FXMessageBox of type 'error'");
239  }
240  // open message box error
241  FXMessageBox::error(this, MBOX_OK, "Errors while loading Selection", "%s", errors.c_str());
242  // write warning if netedit is running in testing mode
243  if (myViewNet->isTestingModeEnabled() == true) {
244  WRITE_WARNING("Closed FXMessageBox of type 'error' with 'OK'");
245  }
246  }
247  }
248  myViewNet->update();
249  return 1;
250 }
251 
252 
253 long
254 GNESelectorFrame::onCmdSave(FXObject*, FXSelector, void*) {
255  FXString file = MFXUtils::getFilename2Write(
256  this, "Save List of selected Items", ".txt", GUIIconSubSys::getIcon(ICON_EMPTY), gCurrentFolder);
257  if (file == "") {
258  return 1;
259  }
260  try {
261  gSelected.save(file.text());
262  } catch (IOError& e) {
263  // write warning if netedit is running in testing mode
264  if (myViewNet->isTestingModeEnabled() == true) {
265  WRITE_WARNING("Opening FXMessageBox of type 'error'");
266  }
267  // open message box error
268  FXMessageBox::error(this, MBOX_OK, "Storing Selection failed", "%s", e.what());
269  // write warning if netedit is running in testing mode
270  if (myViewNet->isTestingModeEnabled() == true) {
271  WRITE_WARNING("Closed FXMessageBox of type 'error' with 'OK'");
272  }
273  }
274  return 1;
275 }
276 
277 
278 long
279 GNESelectorFrame::onCmdClear(FXObject*, FXSelector, void*) {
280  myViewNet->getUndoList()->add(new GNEChange_Selection(myViewNet->getNet(), std::set<GUIGlID>(), gSelected.getSelected(), true), true);
281  myViewNet->update();
282  return 1;
283 }
284 
285 
286 long
287 GNESelectorFrame::onCmdInvert(FXObject*, FXSelector, void*) {
288  std::set<GUIGlID> ids = myViewNet->getNet()->getGlIDs(GLO_JUNCTION);
289  for (std::set<GUIGlID>::const_iterator it = ids.begin(); it != ids.end(); it++) {
291  }
292  ids = myViewNet->getNet()->getGlIDs((myViewNet->selectEdges() == true) ? GLO_EDGE : GLO_LANE);
293  for (std::set<GUIGlID>::const_iterator it = ids.begin(); it != ids.end(); it++) {
295  }
297  for (std::set<GUIGlID>::const_iterator it = ids.begin(); it != ids.end(); it++) {
299  }
301  for (std::set<GUIGlID>::const_iterator it = ids.begin(); it != ids.end(); it++) {
303  }
304  myViewNet->update();
305  return 1;
306 }
307 
308 
309 long
310 GNESelectorFrame::onCmdSelMBTag(FXObject*, FXSelector, void*) {
311  const bool netElements = mySetComboBox->getText() == "Net Element";
313  const std::vector<SumoXMLTag>& tags = GNEAttributeCarrier::allowedTags(netElements);
314  for (std::vector<SumoXMLTag>::const_iterator i = tags.begin(); (i != tags.end()) && (myCurrentTag == SUMO_TAG_NOTHING); i++) {
315  if (toString(*i) == myMatchTagComboBox->getText().text()) {
316  myCurrentTag = *i;
317  }
318  }
319  // check that typed by user value is correct
321  // set color and enable items
322  myMatchTagComboBox->setTextColor(FXRGB(0, 0, 0));
323  myMatchAttrComboBox->enable();
324  myMatchString->enable();
325  myMatchAttrComboBox->clearItems();
326  const std::vector<std::pair <SumoXMLAttr, std::string> >& attrs = GNEAttributeCarrier::allowedAttributes(myCurrentTag);
327  for (std::vector<std::pair <SumoXMLAttr, std::string> >::const_iterator it = attrs.begin(); it != attrs.end(); it++) {
328  myMatchAttrComboBox->appendItem(toString(it->first).c_str());
329  }
330  // @ToDo: Here can be placed a butto to set the default value
331  myMatchAttrComboBox->setNumVisible(myMatchAttrComboBox->getNumItems());
332  } else {
333  // change color to red and disable items
334  myMatchTagComboBox->setTextColor(FXRGB(255, 0, 0));
335  myMatchAttrComboBox->disable();
336  myMatchString->disable();
337  }
338  update();
339  return 1;
340 }
341 
342 
343 long
344 GNESelectorFrame::onCmdSelMBAttribute(FXObject*, FXSelector, void*) {
345  const std::vector<std::pair <SumoXMLAttr, std::string> >& attrs = GNEAttributeCarrier::allowedAttributes(myCurrentTag);
347  for (std::vector<std::pair <SumoXMLAttr, std::string> >::const_iterator i = attrs.begin(); (i != attrs.end()) && (myCurrentAttribute == SUMO_ATTR_NOTHING); i++) {
348  if (toString(i->first) == myMatchAttrComboBox->getText().text()) {
349  myCurrentAttribute = i->first;
350  }
351  }
353  myMatchAttrComboBox->setTextColor(FXRGB(0, 0, 0));
354  myMatchString->enable();
355  } else {
356  myMatchAttrComboBox->setTextColor(FXRGB(255, 0, 0));
357  myMatchString->disable();
358  }
359  return 1;
360 }
361 
362 
363 long
364 GNESelectorFrame::onCmdSelMBString(FXObject*, FXSelector, void*) {
365  std::string expr(myMatchString->getText().text());
366  bool valid = true;
367  if (expr == "") {
368  // the empty expression matches all objects
369  handleIDs(getMatches(myCurrentTag, myCurrentAttribute, '@', 0, expr), false);
371  // The expression must have the form
372  // <val matches if attr < val
373  // >val matches if attr > val
374  // =val matches if attr = val
375  // val matches if attr = val
376  char compOp = expr[0];
377  if (compOp == '<' || compOp == '>' || compOp == '=') {
378  expr = expr.substr(1);
379  } else {
380  compOp = '=';
381  }
382  try {
383  handleIDs(getMatches(myCurrentTag, myCurrentAttribute, compOp, GNEAttributeCarrier::parse<double>(expr.c_str()), expr), false);
384  } catch (EmptyData&) {
385  valid = false;
386  } catch (NumberFormatException&) {
387  valid = false;
388  }
389  } else {
390  // The expression must have the form
391  // =str: matches if <str> is an exact match
392  // !str: matches if <str> is not a substring
393  // ^str: matches if <str> is not an exact match
394  // str: matches if <str> is a substring (sends compOp '@')
395  // Alternatively, if the expression is empty it matches all objects
396  char compOp = expr[0];
397  if (compOp == '=' || compOp == '!' || compOp == '^') {
398  expr = expr.substr(1);
399  } else {
400  compOp = '@';
401  }
402  handleIDs(getMatches(myCurrentTag, myCurrentAttribute, compOp, 0, expr), false);
403  }
404  if (valid) {
405  myMatchString->setTextColor(FXRGB(0, 0, 0));
406  myMatchString->killFocus();
407  } else {
408  myMatchString->setTextColor(FXRGB(255, 0, 0));
409  }
410  return 1;
411 }
412 
413 
414 long
415 GNESelectorFrame::onCmdHelp(FXObject*, FXSelector, void*) {
416  FXDialogBox* helpDialog = new FXDialogBox(this, "Match Attribute Help", GUIDesignDialogBox);
417  std::ostringstream help;
418  help
419  << "The 'Match Attribute' controls allow to specify a set of objects which are then applied to the current selection "
420  << "according to the current 'Modification Mode'.\n"
421  << "1. Select an object type from the first input box\n"
422  << "2. Select an attribute from the second input box\n"
423  << "3. Enter a 'match expression' in the third input box and press <return>\n"
424  << "\n"
425  << "The empty expression matches all objects\n"
426  << "For numerical attributes the match expression must consist of a comparison operator ('<', '>', '=') and a number.\n"
427  << "An object matches if the comparison between its attribute and the given number by the given operator evaluates to 'true'\n"
428  << "\n"
429  << "For string attributes the match expression must consist of a comparison operator ('', '=', '!', '^') and a string.\n"
430  << " '' (no operator) matches if string is a substring of that object'ts attribute.\n"
431  << " '=' matches if string is an exact match.\n"
432  << " '!' matches if string is not a substring.\n"
433  << " '^' matches if string is not an exact match.\n"
434  << "\n"
435  << "Examples:\n"
436  << "junction; id; 'foo' -> match all junctions that have 'foo' in their id\n"
437  << "junction; type; '=priority' -> match all junctions of type 'priority', but not of type 'priority_stop'\n"
438  << "edge; speed; '>10' -> match all edges with a speed above 10\n";
439  new FXLabel(helpDialog, help.str().c_str(), 0, GUIDesignLabelLeft);
440  // "OK"
441  new FXButton(helpDialog, "OK\t\tSave modifications", GUIIconSubSys::getIcon(ICON_ACCEPT), helpDialog, FXDialogBox::ID_ACCEPT, GUIDesignButtonOK);
442  helpDialog->create();
443  helpDialog->show();
444  return 1;
445 }
446 
447 
448 long
449 GNESelectorFrame::onCmdScaleSelection(FXObject*, FXSelector, void*) {
451  myViewNet->update();
452  return 1;
453 }
454 
455 
456 void
458  // selection may have changed due to deletions
459  gSelected.add2Update(this);
461  // Show frame
462  GNEFrame::show();
463 }
464 
465 
466 void
468  // selection may have changed due to deletions
470  // hide frame
471  GNEFrame::hide();
472 }
473 
474 
475 std::string
477  return "Selection:\n" +
478  toString(gSelected.getSelected(GLO_JUNCTION).size()) + " Junctions\n" +
479  toString(gSelected.getSelected(GLO_EDGE).size()) + " Edges\n" +
480  toString(gSelected.getSelected(GLO_LANE).size()) + " Lanes\n" +
481  toString(gSelected.getSelected(GLO_CONNECTION).size()) + " Connections\n" +
482  toString(gSelected.getSelected(GLO_ADDITIONAL).size()) + " Additionals\n" +
483  toString(gSelected.getSelected(GLO_CROSSING).size()) + " Crossings";
484 }
485 
486 
487 void
489  myFrameHeaderLabel->setText(getStats().c_str());
490  update();
491 }
492 
493 
494 void
495 GNESelectorFrame::handleIDs(std::vector<GUIGlID> ids, bool selectEdgesEnabled, SetOperation setop) {
496  const SetOperation setOperation = (setop == SET_DEFAULT ? (SetOperation)mySetOperation : setop);
497  std::set<GUIGlID> previousSelection;
498  myViewNet->getUndoList()->p_begin("change selection");
499  if (setOperation == SET_REPLACE) {
500  myViewNet->getUndoList()->add(new GNEChange_Selection(myViewNet->getNet(), std::set<GUIGlID>(), gSelected.getSelected(), true), true);
501  } else if (setOperation == SET_RESTRICT) {
502  previousSelection = gSelected.getSelected(); // have to make a copy
503  myViewNet->getUndoList()->add(new GNEChange_Selection(myViewNet->getNet(), std::set<GUIGlID>(), gSelected.getSelected(), true), true);
504  }
505  // handle ids
506  GUIGlObject* object;
507  GUIGlObjectType type;
508  std::set<GUIGlID> idsSet(ids.begin(), ids.end());
509  std::set<GUIGlID> selected;
510  std::set<GUIGlID> deselected;
511  if (myViewNet->autoSelectNodes()) {
512  for (std::vector<GUIGlID>::const_iterator it = ids.begin(); it != ids.end(); it++) {
513  GUIGlID id = *it;
514  if (id > 0) { // net object?
516  if ((object->getType() == GLO_LANE) && (selectEdgesEnabled == true)) {
517  const GNEEdge& edge = (static_cast<GNELane*>(object))->getParentEdge();
518  idsSet.insert(edge.getGNEJunctionSource()->getGlID());
519  idsSet.insert(edge.getGNEJunctionDestiny()->getGlID());
520  }
522  }
523  }
524  }
525  for (std::set<GUIGlID>::const_iterator it = idsSet.begin(); it != idsSet.end(); it++) {
526  GUIGlID id = *it;
527  if (id > 0) { // net object?
529  if (object == 0) {
530  // in debug mode we would like to know about this.
531  // It might be caused by a corrupted gl-name stack.
532  // However, most cases of uninitizliaed values would go hidden since 0 is assumed to be the net object anyway
533  assert(false);
534  continue;
535  }
536  type = object->getType();
538  if ((type == GLO_LANE) && (selectEdgesEnabled == true)) {
539  // @note edge may be selected/deselected multiple times but this shouldn't
540  // hurt unless we add SET_TOGGLE
541  id = (static_cast<GNELane*>(object))->getParentEdge().getGlID();
542  }
543  // doing the switch outside the loop requires functional techniques. this was deemed to ugly
544  switch (setOperation) {
547  selected.insert(id);
548  break;
550  deselected.insert(id);
551  break;
553  if (previousSelection.count(id)) {
554  selected.insert(id);
555  }
556  break;
557  default:
558  break;
559  }
560  }
561  }
562  myViewNet->getUndoList()->add(new GNEChange_Selection(myViewNet->getNet(), selected, deselected, true), true);
564  myViewNet->update();
565 }
566 
567 
568 std::vector<GUIGlID>
569 GNESelectorFrame::getMatches(SumoXMLTag tag, SumoXMLAttr attr, char compOp, double val, const std::string& expr) {
570  GUIGlObject* object;
572  std::vector<GUIGlID> result;
573  const std::set<GUIGlID> allIDs = myViewNet->getNet()->getGlIDs();
574  const bool numerical = GNEAttributeCarrier::isNumerical(tag, attr);
575  for (std::set<GUIGlID>::const_iterator it = allIDs.begin(); it != allIDs.end(); it++) {
576  GUIGlID id = *it;
578  if (!object) {
579  throw ProcessError("Unkown object passed to GNESelectorFrame::getMatches (id=" + toString(id) + ").");
580  }
581  ac = dynamic_cast<GNEAttributeCarrier*>(object);
582  if (ac && ac->getTag() == tag) { // not all objects need to be attribute carriers
583  if (expr == "") {
584  result.push_back(id);
585  } else if (numerical) {
586  double acVal;
587  std::istringstream buf(ac->getAttribute(attr));
588  buf >> acVal;
589  switch (compOp) {
590  case '<':
591  if (acVal < val) {
592  result.push_back(id);
593  }
594  break;
595  case '>':
596  if (acVal > val) {
597  result.push_back(id);
598  }
599  break;
600  case '=':
601  if (acVal == val) {
602  result.push_back(id);
603  }
604  break;
605  }
606  } else {
607  // string match
608  std::string acVal = ac->getAttribute(attr);
609  if ((attr == SUMO_ATTR_ALLOW || attr == SUMO_ATTR_DISALLOW) && acVal == "all") {
611  }
612  switch (compOp) {
613  case '@':
614  if (acVal.find(expr) != std::string::npos) {
615  result.push_back(id);
616  }
617  break;
618  case '!':
619  if (acVal.find(expr) == std::string::npos) {
620  result.push_back(id);
621  }
622  break;
623  case '=':
624  if (acVal == expr) {
625  result.push_back(id);
626  }
627  break;
628  case '^':
629  if (acVal != expr) {
630  result.push_back(id);
631  }
632  break;
633  }
634  }
635  }
637  }
638  return result;
639 }
640 
641 /****************************************************************************/
FXRadioButton * myReplaceRadioButton
replace radio button
a tl-logic
SumoXMLTag
Numbers representing SUMO-XML - element names.
const std::set< GUIGlID > & getSelected() const
Returns the set of ids of all selected objects.
bool selectEdges()
whether inspection, selection and inversion should apply to edges or to lanes
Definition: GNEViewNet.cpp:363
void selectionUpdated()
called if currently registered for updates for changes of global selection
#define GUIDesignComboBoxNCol
number of column of every combo box
Definition: GUIDesigns.h:197
Deselect selected items.
Definition: GUIAppEnum.h:357
long onCmdSelMBString(FXObject *, FXSelector, void *)
Called when the user enters a new selection expression.
FXComboBox * myMatchAttrComboBox
attributes of the match box
GUIGlObjectType
SetOperation
FOX-declaration.
FXDEFMAP(GNESelectorFrame) GNESelectorFrameMap[]
long onCmdSave(FXObject *, FXSelector, void *)
Called when the user presses the Save-button.
void toggleSelection(GUIGlID id)
Toggles selection of an object.
std::vector< GUIGlID > getMatches(SumoXMLTag tag, SumoXMLAttr attr, char compOp, double val, const std::string &expr)
return objects of the given type with matching attrs
std::set< GUIGlID > getGlIDs(GUIGlObjectType type=GLO_MAX)
Definition: GNENet.cpp:897
a connection
void show()
show Frame
SumoXMLAttr myCurrentAttribute
current SumoXMLTag Attribute
FXTextField * myMatchString
string of the match
FXRealSpinDial * mySelectionScaling
selection scaling
Clear set.
Definition: GUIAppEnum.h:351
SumoXMLTag myCurrentTag
current SumoXMLTag tag
void remove2Update()
Removes the dialog to be updated.
This lane is powered by an underlying GNEEdge and basically knows how to draw itself.
Definition: GNELane.h:54
void p_begin(const std::string &description)
Begin undo command sub-group. This begins a new group of commands that are treated as a single comman...
Definition: GNEUndoList.cpp:82
long onCmdLoad(FXObject *, FXSelector, void *)
Called when the user presses the Load-button.
FXString gCurrentFolder
The folder used as last.
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
void handleIDs(std::vector< GUIGlID > ids, bool selectEdgesEnabled, SetOperation setop=SET_DEFAULT)
apply list of ids to the current selection according to SetOperation,
virtual std::string getAttribute(SumoXMLAttr key) const =0
static FXString getFilename2Write(FXWindow *parent, const FXString &header, const FXString &extension, FXIcon *icon, FXString &currentFolder)
Returns the file name to write.
Definition: MFXUtils.cpp:91
static const std::vector< std::pair< SumoXMLAttr, std::string > > & allowedAttributes(SumoXMLTag tag)
get all editable attributes for tag and their default values.
long onCmdHelp(FXObject *, FXSelector, void *)
Called when the user clicks the help button.
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
bool isTestingModeEnabled() const
check if netedit is running in testing mode
Definition: GNEViewNet.cpp:405
#define GUIDesignComboBox
Definition: GUIDesigns.h:187
help button
Definition: GUIAppEnum.h:404
GNEViewNet * myViewNet
the window to inform when the tls is modfied
Definition: GNEFrame.h:95
std::set< GUIGlID > loadIDs(const std::string &filename, std::string &msgOut, GUIGlObjectType type=GLO_MAX, int maxErrors=16)
Loads a selection list (optionally with restricted type) and returns the ids of all active objects...
~GNESelectorFrame()
Destructor.
long onCmdScaleSelection(FXObject *, FXSelector, void *)
Called when the user changes visual scaling.
GNEUndoList * getUndoList() const
get the undoList object
long onCmdClear(FXObject *, FXSelector, void *)
Called when the user presses the Clear-button.
GUIGlObjectType getType() const
Returns the type of the object as coded in GUIGlObjectType.
#define GUIDesignTextField
Definition: GUIDesigns.h:41
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:56
SetOperation mySetOperation
how to modify selection
void p_end()
End undo command sub-group. If the sub-group is still empty, it will be deleted; otherwise, the sub-group will be added as a new command into parent group. A matching begin() must have been called previously.
Definition: GNEUndoList.cpp:89
FXLabel * myFrameHeaderLabel
the label for the frame&#39;s header
Definition: GNEFrame.h:101
long onCmdSelMBAttribute(FXObject *, FXSelector, void *)
Called when the user selectes a tag in the match box.
static GUIGlObjectStorage gIDStorage
A single static instance of this class.
GNEJunction * getGNEJunctionDestiny() const
returns the destination-junction
Definition: GNEEdge.cpp:165
invalid attribute
static const std::vector< SumoXMLTag > & allowedTags(bool net)
get all editable for tag (net or additional).
bool autoSelectNodes()
whether to autoselect nodes or to lanes
Definition: GNEViewNet.cpp:381
Save set.
Definition: GUIAppEnum.h:349
StringBijection< SUMOVehicleClass > SumoVehicleClassStrings(sumoVehicleClassStringInitializer, SVC_CUSTOM2, false)
const std::string ALL_VCLASS_NAMES_MATCH_STRING
the string that should be matched against if attr &#39;allowed&#39; or &#39;disallowed&#39; are set to "all" ...
GNEJunction * getGNEJunctionSource() const
returns the source-junction
Definition: GNEEdge.cpp:159
FXRadioButton * myKeepRadioButton
keep button
#define GUIDesignButtonRectangular
little button rectangular (46x23) used in frames (For example, in "help" buttons) ...
Definition: GUIDesigns.h:63
long onCmdSelectOperation(FXObject *, FXSelector, void *)
begin/end of the description of an edge
void setSelectionScaling(double selectionScale)
set selection scaling
Definition: GNEViewNet.cpp:387
A road/street connecting two junctions (netedit-version)
Definition: GNEEdge.h:57
unsigned int GUIGlID
Definition: GUIGlObject.h:50
#define GUIDesignTextFieldNCol
Num of column of text field.
Definition: GUIDesigns.h:50
compound additional
set subset of elements
Definition: GUIAppEnum.h:345
#define GUIDesignButton
Definition: GUIDesigns.h:57
long onCmdSubset(FXObject *, FXSelector, void *)
Called when the user change the type of element to search (netElement or Additional) ...
virtual void show()
show Frame
Definition: GNEFrame.cpp:98
#define GUIDesignDialogBox
Definition: GUIDesigns.h:393
FXRadioButton * myRemoveRadioButton
remove radio button
void add2Update(UpdateTarget *updateTarget)
Adds a dialog to be updated.
#define GUIDesignGroupBoxFrame
Group box design extended over frame.
Definition: GUIDesigns.h:219
FXComboBox * myMatchTagComboBox
tag of the match box
long onCmdInvert(FXObject *, FXSelector, void *)
Called when the user presses the Invert-button.
an edge
FXdouble getValue() const
Return current value.
virtual void hide()
hide Frame
Definition: GNEFrame.cpp:107
GNENet * getNet() const
get the net object
GUIGlID getGlID() const
Returns the numerical id of the object.
#define GUIDesignButtonOK
Definition: GUIDesigns.h:98
selector match box messages
Definition: GUIAppEnum.h:457
#define GUIDesignSpinDial
Definition: GUIDesigns.h:301
set type of selection
Definition: GUIAppEnum.h:343
void unblockObject(GUIGlID id)
Marks an object as unblocked.
std::string getStats() const
get stats
void hide()
hide Frame
#define GUIDesignLabelLeft
Definition: GUIDesigns.h:144
Load set.
Definition: GUIAppEnum.h:347
static bool isNumerical(SumoXMLTag tag, SumoXMLAttr attr)
whether an attribute is numerical (int or float)
FXRadioButton * myAddRadioButton
add radio button
Spinner control.
GUIGlObject * getObjectBlocking(GUIGlID id)
Returns the object from the container locking it.
#define GUIDesignRadioButton
Definition: GUIDesigns.h:134
long onCmdSelMBTag(FXObject *, FXSelector, void *)
Called when the user selectes a tag in the match box.
FXComboBox * mySetComboBox
tag of the sets of elements
GUISelectedStorage gSelected
A global holder of selected objects.
static FXIcon * getIcon(GUIIcon which)
returns a icon previously defined in the enum GUIIcon
std::string joinToString(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=gPrecision)
Definition: ToString.h:228
void save(GUIGlObjectType type, const std::string &filename)
Saves a selection list.
changes the visual scaling of selected items
Definition: GUIAppEnum.h:674
a junction
SumoXMLTag getTag() const
get XML Tag assigned to this object