Eclipse SUMO - Simulation of Urban MObility
GNEFrameAttributesModuls.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
15 // Auxiliar class for GNEFrame Moduls (only for attributes edition)
16 /****************************************************************************/
17 
18 // ===========================================================================
19 // included modules
20 // ===========================================================================
21 
22 #include <config.h>
23 
24 #include <netedit/GNENet.h>
25 #include <netedit/GNEUndoList.h>
26 #include <netedit/GNEViewNet.h>
35 
36 #include "GNEFrame.h"
38 
39 
40 // ===========================================================================
41 // FOX callback mapping
42 // ===========================================================================
43 
49 };
50 
51 FXDEFMAP(GNEFrameAttributesModuls::AttributesCreator) AttributesCreatorMap[] = {
53 };
54 
55 FXDEFMAP(GNEFrameAttributesModuls::AttributesEditorRow) AttributesEditorRowMap[] = {
60 };
61 
64 };
65 
66 FXDEFMAP(GNEFrameAttributesModuls::AttributesEditorExtended) AttributesEditorExtendedMap[] = {
68 };
69 
70 FXDEFMAP(GNEFrameAttributesModuls::GenericParametersEditor) GenericParametersEditorMap[] = {
73 };
74 
79 };
80 
81 FXDEFMAP(GNEFrameAttributesModuls::NeteditAttributes) NeteditAttributesMap[] = {
84 };
85 
86 // Object implementation
87 FXIMPLEMENT(GNEFrameAttributesModuls::AttributesCreatorRow, FXHorizontalFrame, RowCreatorMap, ARRAYNUMBER(RowCreatorMap))
88 FXIMPLEMENT(GNEFrameAttributesModuls::AttributesCreator, FXGroupBox, AttributesCreatorMap, ARRAYNUMBER(AttributesCreatorMap))
89 FXIMPLEMENT(GNEFrameAttributesModuls::AttributesEditorRow, FXHorizontalFrame, AttributesEditorRowMap, ARRAYNUMBER(AttributesEditorRowMap))
90 FXIMPLEMENT(GNEFrameAttributesModuls::AttributesEditor, FXGroupBox, AttributesEditorMap, ARRAYNUMBER(AttributesEditorMap))
91 FXIMPLEMENT(GNEFrameAttributesModuls::AttributesEditorExtended, FXGroupBox, AttributesEditorExtendedMap, ARRAYNUMBER(AttributesEditorExtendedMap))
92 FXIMPLEMENT(GNEFrameAttributesModuls::GenericParametersEditor, FXGroupBox, GenericParametersEditorMap, ARRAYNUMBER(GenericParametersEditorMap))
93 FXIMPLEMENT(GNEFrameAttributesModuls::DrawingShape, FXGroupBox, DrawingShapeMap, ARRAYNUMBER(DrawingShapeMap))
94 FXIMPLEMENT(GNEFrameAttributesModuls::NeteditAttributes, FXGroupBox, NeteditAttributesMap, ARRAYNUMBER(NeteditAttributesMap))
95 
96 
97 // ===========================================================================
98 // method definitions
99 // ===========================================================================
100 
101 // ---------------------------------------------------------------------------
102 // GNEFrameAttributesModuls::AttributesCreatorRow - methods
103 // ---------------------------------------------------------------------------
104 
105 GNEFrameAttributesModuls::AttributesCreatorRow::AttributesCreatorRow(AttributesCreator* AttributesCreatorParent, const GNEAttributeCarrier::AttributeProperties& attrProperties) :
106  FXHorizontalFrame(AttributesCreatorParent, GUIDesignAuxiliarHorizontalFrame),
107  myAttributesCreatorParent(AttributesCreatorParent),
108  myAttrProperties(attrProperties) {
109  // Create left visual elements
110  myAttributeLabel = new FXLabel(this, "name", nullptr, GUIDesignLabelAttribute);
111  myAttributeLabel->hide();
112  myAttributeRadioButton = new FXRadioButton(this, "name", this, MID_GNE_SET_ATTRIBUTE_RADIOBUTTON, GUIDesignRadioButtonAttribute);
113  myAttributeRadioButton->hide();
114  myAttributeCheckButton = new FXCheckButton(this, "name", this, MID_GNE_SET_ATTRIBUTE_BOOL, GUIDesignCheckButtonAttribute);
115  myAttributeCheckButton->hide();
116  myAttributeColorButton = new FXButton(this, "ColorButton", nullptr, this, MID_GNE_SET_ATTRIBUTE_DIALOG, GUIDesignButtonAttribute);
117  myAttributeColorButton->hide();
118  // Create right visual elements
119  myValueTextFieldInt = new FXTextField(this, GUIDesignTextFieldNCol, this, MID_GNE_SET_ATTRIBUTE, GUIDesignTextFieldInt);
120  myValueTextFieldInt->hide();
121  myValueTextFieldReal = new FXTextField(this, GUIDesignTextFieldNCol, this, MID_GNE_SET_ATTRIBUTE, GUIDesignTextFieldReal);
122  myValueTextFieldReal->hide();
123  myValueTextFieldStrings = new FXTextField(this, GUIDesignTextFieldNCol, this, MID_GNE_SET_ATTRIBUTE, GUIDesignTextField);
124  myValueTextFieldStrings->hide();
125  myValueCheckButton = new FXCheckButton(this, "Disabled", this, MID_GNE_SET_ATTRIBUTE, GUIDesignCheckButton);
126  myValueCheckButton->hide();
127  // by default attribute check button is true (except for until)
128  if ((attrProperties.getTagPropertyParent().isStop() || attrProperties.getTagPropertyParent().isPersonStop()) && (attrProperties.getAttr() == SUMO_ATTR_UNTIL)) {
129  myAttributeCheckButton->setCheck(FALSE);
130  } else {
131  myAttributeCheckButton->setCheck(TRUE);
132  }
133  // only create if parent was created
134  if (getParent()->id()) {
135  // create AttributesCreatorRow
136  FXHorizontalFrame::create();
137  // reset invalid value
138  myInvalidValue = "";
139  // show label, button for edit colors or radio button
140  if (myAttrProperties.isColor()) {
141  myAttributeColorButton->setTextColor(FXRGB(0, 0, 0));
142  myAttributeColorButton->setText(myAttrProperties.getAttrStr().c_str());
143  myAttributeColorButton->show();
144  } else if (myAttrProperties.isEnablitable()) {
145  myAttributeRadioButton->setTextColor(FXRGB(0, 0, 0));
146  myAttributeRadioButton->setText(myAttrProperties.getAttrStr().c_str());
147  myAttributeRadioButton->show();
148  } else if (myAttrProperties.isOptional()) {
149  myAttributeCheckButton->setText(myAttrProperties.getAttrStr().c_str());
150  myAttributeCheckButton->show();
151  } else {
152  myAttributeLabel->setText(myAttrProperties.getAttrStr().c_str());
153  myAttributeLabel->show();
154  }
155  if (myAttrProperties.isInt()) {
156  myValueTextFieldInt->setTextColor(FXRGB(0, 0, 0));
157  myValueTextFieldInt->setText(attrProperties.getDefaultValue().c_str());
158  myValueTextFieldInt->show();
159  // if it's associated to a radio button and is disabled, then disabled myValueTextFieldInt
160  if (myAttributeRadioButton->shown() && (myAttributeRadioButton->getCheck() == FALSE)) {
161  myValueTextFieldInt->disable();
162  }
163  // if it's associated to a label button and is disabled, then disabled myValueTextFieldInt
164  if (myAttributeCheckButton->shown() && (myAttributeCheckButton->getCheck() == FALSE)) {
165  myValueTextFieldInt->disable();
166  }
167  } else if (myAttrProperties.isFloat() || myAttrProperties.isSUMOTime()) {
168  myValueTextFieldReal->setTextColor(FXRGB(0, 0, 0));
169  myValueTextFieldReal->setText(attrProperties.getDefaultValue().c_str());
170  myValueTextFieldReal->show();
171  // if it's associated to a radio button and is disabled, then disable myValueTextFieldReal
172  if (myAttributeRadioButton->shown() && (myAttributeRadioButton->getCheck() == FALSE)) {
173  myValueTextFieldReal->disable();
174  }
175  // if it's associated to a label button and is disabled, then disable myValueTextFieldReal
176  if (myAttributeCheckButton->shown() && (myAttributeCheckButton->getCheck() == FALSE)) {
177  myValueTextFieldReal->disable();
178  }
179  } else if (myAttrProperties.isBool()) {
180  if (GNEAttributeCarrier::parse<bool>(attrProperties.getDefaultValue())) {
181  myValueCheckButton->setCheck(true);
182  myValueCheckButton->setText("true");
183  } else {
184  myValueCheckButton->setCheck(false);
185  myValueCheckButton->setText("false");
186  }
187  myValueCheckButton->show();
188  // if it's associated to a radio button and is disabled, then disable myValueCheckButton
189  if (myAttributeRadioButton->shown() && (myAttributeRadioButton->getCheck() == FALSE)) {
190  myValueCheckButton->disable();
191  }
192  // if it's associated to a label button and is disabled, then disable myValueCheckButton
193  if (myAttributeCheckButton->shown() && (myAttributeCheckButton->getCheck() == FALSE)) {
194  myValueCheckButton->disable();
195  }
196  } else {
197  myValueTextFieldStrings->setTextColor(FXRGB(0, 0, 0));
198  myValueTextFieldStrings->setText(attrProperties.getDefaultValue().c_str());
199  myValueTextFieldStrings->show();
200  // if it's associated to a radio button and is disabled, then disable myValueTextFieldStrings
201  if (myAttributeRadioButton->shown() && (myAttributeRadioButton->getCheck() == FALSE)) {
202  myValueTextFieldStrings->disable();
203  }
204  // if it's associated to a label button and is disabled, then disable myValueTextFieldStrings
205  if (myAttributeCheckButton->shown() && (myAttributeCheckButton->getCheck() == FALSE)) {
206  myValueTextFieldStrings->disable();
207  }
208  }
209  // show AttributesCreatorRow
210  show();
211  }
212 }
213 
214 
215 void
217  // only destroy if parent was created
218  if (getParent()->id()) {
219  FXHorizontalFrame::destroy();
220  }
221 }
222 
223 
226  return myAttrProperties;
227 }
228 
229 
230 std::string
232  if (myAttrProperties.isBool()) {
233  return (myValueCheckButton->getCheck() == 1) ? "1" : "0";
234  } else if (myAttrProperties.isInt()) {
235  return myValueTextFieldInt->getText().text();
237  return myValueTextFieldReal->getText().text();
238  } else {
239  return myValueTextFieldStrings->getText().text();
240  }
241 }
242 
243 
244 bool
246  if (shown()) {
247  return myAttributeRadioButton->getCheck() == TRUE;
248  } else {
249  return false;
250  }
251 }
252 
253 
254 void
256  if (shown()) {
257  // set radio button
258  myAttributeRadioButton->setCheck(value);
259  // enable or disable input fields
260  if (value) {
261  if (myAttrProperties.isBool()) {
262  myValueCheckButton->enable();
263  } else if (myAttrProperties.isInt()) {
264  myValueTextFieldInt->enable();
266  myValueTextFieldReal->enable();
267  } else {
268  myValueTextFieldStrings->enable();
269  }
270  } else {
271  if (myAttrProperties.isBool()) {
272  myValueCheckButton->disable();
273  } else if (myAttrProperties.isInt()) {
274  myValueTextFieldInt->disable();
276  myValueTextFieldReal->disable();
277  } else {
278  myValueTextFieldStrings->disable();
279  }
280  }
281  }
282 }
283 
284 
285 bool
287  if (shown()) {
288  return myAttributeCheckButton->getCheck() == TRUE;
289  } else {
290  return false;
291  }
292 }
293 
294 
295 void
297  if (shown()) {
298  // set radio button
299  myAttributeCheckButton->setCheck(value);
300  // enable or disable input fields
301  if (value) {
302  if (myAttrProperties.isBool()) {
303  myValueCheckButton->enable();
304  } else if (myAttrProperties.isInt()) {
305  myValueTextFieldInt->enable();
307  myValueTextFieldReal->enable();
308  } else {
309  myValueTextFieldStrings->enable();
310  }
311  } else {
312  if (myAttrProperties.isBool()) {
313  myValueCheckButton->disable();
314  } else if (myAttrProperties.isInt()) {
315  myValueTextFieldInt->disable();
317  myValueTextFieldReal->disable();
318  } else {
319  myValueTextFieldStrings->disable();
320  }
321  }
322  }
323 }
324 
325 
326 void
328  if (myAttrProperties.isBool()) {
329  return myValueCheckButton->enable();
330  } else if (myAttrProperties.isInt()) {
331  return myValueTextFieldInt->enable();
333  return myValueTextFieldReal->enable();
334  } else {
335  return myValueTextFieldStrings->enable();
336  }
337 }
338 
339 
340 void
342  if (myAttrProperties.isBool()) {
343  return myValueCheckButton->disable();
344  } else if (myAttrProperties.isInt()) {
345  return myValueTextFieldInt->disable();
347  return myValueTextFieldReal->disable();
348  } else {
349  return myValueTextFieldStrings->disable();
350  }
351 }
352 
353 
354 bool
356  if (!shown()) {
357  return false;
358  } else if (myAttrProperties.isBool()) {
359  return myValueCheckButton->isEnabled();
360  } else if (myAttrProperties.isInt()) {
361  return myValueTextFieldInt->isEnabled();
363  return myValueTextFieldReal->isEnabled();
364  } else {
365  return myValueTextFieldStrings->isEnabled();
366  }
367 }
368 
369 
370 const std::string&
372  return myInvalidValue;
373 }
374 
375 
379 }
380 
381 
382 long
384  // We assume that current value is valid
385  myInvalidValue = "";
386  // Check if format of current value of myTextField is correct
387  if (obj == myValueCheckButton) {
388  if (myValueCheckButton->getCheck()) {
389  myValueCheckButton->setText("true");
390  } else {
391  myValueCheckButton->setText("false");
392  }
393  // update disjoint attribute
395  } else if (myAttrProperties.isComplex()) {
396  // check complex attribute
398  } else if (myAttrProperties.isInt()) {
399  if (GNEAttributeCarrier::canParse<int>(myValueTextFieldInt->getText().text())) {
400  // convert string to int
401  int intValue = GNEAttributeCarrier::parse<int>(myValueTextFieldInt->getText().text());
402  // Check if int value must be positive
403  if (myAttrProperties.isPositive() && (intValue < 0)) {
404  myInvalidValue = "'" + myAttrProperties.getAttrStr() + "' cannot be negative";
405  }
406  } else {
407  myInvalidValue = "'" + myAttrProperties.getAttrStr() + "' doesn't have a valid 'int' format";
408  }
409  } else if (myAttrProperties.isSUMOTime()) {
410  // time attributes work as positive doubles
411  if (!GNEAttributeCarrier::canParse<SUMOTime>(myValueTextFieldReal->getText().text())) {
412  myInvalidValue = "'" + myAttrProperties.getAttrStr() + "' doesn't have a valid SUMOTime format";
413  }
414  } else if (myAttrProperties.isFloat()) {
415  if (GNEAttributeCarrier::canParse<double>(myValueTextFieldReal->getText().text())) {
416  // convert string to double
417  double doubleValue = GNEAttributeCarrier::parse<double>(myValueTextFieldReal->getText().text());
418  // Check if double value must be positive
419  if (myAttrProperties.isPositive() && (doubleValue < 0)) {
420  myInvalidValue = "'" + myAttrProperties.getAttrStr() + "' cannot be negative";
421  // check if double value is a probability
422  } else if (myAttrProperties.isProbability() && ((doubleValue < 0) || doubleValue > 1)) {
423  myInvalidValue = "'" + myAttrProperties.getAttrStr() + "' takes only values between 0 and 1";
424  } else if (myAttrProperties.hasAttrRange() && ((doubleValue < myAttrProperties.getMinimumRange()) || doubleValue > myAttrProperties.getMaximumRange())) {
425  myInvalidValue = "'" + myAttrProperties.getAttrStr() + "' takes only values between " + toString(myAttrProperties.getMinimumRange()) + " and " + toString(myAttrProperties.getMaximumRange());
427  myInvalidValue = "E2 length cannot be 0";
428  }
429  } else {
430  myInvalidValue = "'" + myAttrProperties.getAttrStr() + "' doesn't have a valid 'float' format";
431  }
432  } else if (myAttrProperties.isColor()) {
433  // check if filename format is valid
434  if (GNEAttributeCarrier::canParse<RGBColor>(myValueTextFieldStrings->getText().text()) == false) {
435  myInvalidValue = "'" + myAttrProperties.getAttrStr() + "' doesn't have a valid 'RBGColor' format";
436  }
437  } else if (myAttrProperties.isFilename()) {
438  std::string file = myValueTextFieldStrings->getText().text();
439  // check if filename format is valid
440  if (SUMOXMLDefinitions::isValidFilename(file) == false) {
441  myInvalidValue = "input contains invalid characters for a filename";
442  } else if (myAttrProperties.getAttr() == SUMO_ATTR_IMGFILE) {
443  if (!file.empty()) {
444  // only load value if file exist and can be loaded
445  if (GUITexturesHelper::getTextureID(file) == -1) {
446  myInvalidValue = "doesn't exist image '" + file + "'";
447  }
448  }
449  }
450  } else if (myAttrProperties.getAttr() == SUMO_ATTR_NAME) {
451  std::string name = myValueTextFieldStrings->getText().text();
452  // check if name format is valid
453  if (SUMOXMLDefinitions::isValidAttribute(name) == false) {
454  myInvalidValue = "input contains invalid characters";
455  }
456  } else if (myAttrProperties.getAttr() == SUMO_ATTR_VTYPES) {
457  std::string name = myValueTextFieldStrings->getText().text();
458  // if list of VTypes isn't empty, check that all characters are valid
459  if (!name.empty() && !SUMOXMLDefinitions::isValidListOfTypeID(name)) {
460  myInvalidValue = "list of IDs contains invalid characters";
461  }
462  } else if (myAttrProperties.getAttr() == SUMO_ATTR_INDEX) {
463  // special case for stop indx
464  std::string index = myValueTextFieldStrings->getText().text();
465  if ((index != "fit") && (index != "end") && !GNEAttributeCarrier::canParse<int>(index)) {
466  myInvalidValue = "index isn't either 'fit' or 'end' or a valid positive int";
467  } else if (GNEAttributeCarrier::canParse<int>(index) && (GNEAttributeCarrier::parse<int>(index) < 0)) {
468  myInvalidValue = "index cannot be negative";
469  }
471  // check if attribute can be parsed in a list of Ids
472  std::vector<std::string> vehicleIDs = GNEAttributeCarrier::parse<std::vector<std::string> >(myValueTextFieldStrings->getText().text());
473  // check every ID
474  for (const auto &i : vehicleIDs) {
476  myInvalidValue = "invalid id used in " + myAttrProperties.getAttrStr();
477  }
478  }
479  } else if (myAttrProperties.getAttr() == SUMO_ATTR_ACTTYPE) {
480  if (myValueTextFieldStrings->getText().text() != "waiting") {
481  myInvalidValue = "invalid " + myAttrProperties.getAttrStr();
482  }
483  } else if (myAttrProperties.getAttr() == SUMO_ATTR_TRIP_ID) {
485  myInvalidValue = "invalid id used in " + myAttrProperties.getAttrStr();
486  }
487  }
488  // change color of text field depending of myCurrentValueValid
489  if (myInvalidValue.size() == 0) {
490  myValueTextFieldInt->setTextColor(FXRGB(0, 0, 0));
491  myValueTextFieldInt->killFocus();
492  myValueTextFieldReal->setTextColor(FXRGB(0, 0, 0));
493  myValueTextFieldReal->killFocus();
494  myValueTextFieldStrings->setTextColor(FXRGB(0, 0, 0));
495  myValueTextFieldStrings->killFocus();
496  } else {
497  // IF value of TextField isn't valid, change their color to Red
498  myValueTextFieldInt->setTextColor(FXRGB(255, 0, 0));
499  myValueTextFieldReal->setTextColor(FXRGB(255, 0, 0));
500  myValueTextFieldStrings->setTextColor(FXRGB(255, 0, 0));
501  }
502  // Update aditional frame
503  update();
504  return 1;
505 }
506 
507 
508 long
510  if (myAttributeCheckButton->getCheck()) {
511  // enable input values
512  myValueCheckButton->enable();
513  myValueTextFieldInt->enable();
514  myValueTextFieldReal->enable();
515  myValueTextFieldStrings->enable();
516  } else {
517  // disable input values
518  myValueCheckButton->disable();
519  myValueTextFieldInt->disable();
520  myValueTextFieldReal->disable();
521  myValueTextFieldStrings->disable();
522  }
523  return 0;
524 }
525 
526 
527 long
529  // create FXColorDialog
530  FXColorDialog colordialog(this, tr("Color Dialog"));
531  colordialog.setTarget(this);
532  // If previous attribute wasn't correct, set black as default color
533  if (GNEAttributeCarrier::canParse<RGBColor>(myValueTextFieldStrings->getText().text())) {
534  colordialog.setRGBA(MFXUtils::getFXColor(RGBColor::parseColor(myValueTextFieldStrings->getText().text())));
535  } else {
537  }
538  // execute dialog to get a new color
539  if (colordialog.execute()) {
540  myValueTextFieldStrings->setText(toString(MFXUtils::getRGBColor(colordialog.getRGBA())).c_str());
541  onCmdSetAttribute(nullptr, 0, nullptr);
542  }
543  return 0;
544 }
545 
546 long
548  // write debug (for Netedit tests)
549  WRITE_DEBUG("Selected radio button for attribute '" + myAttrProperties.getAttrStr() + "'");
550  // update disjoint attributes in AC Attributes parent
552  return 0;
553 }
554 
555 
556 std::string
558  // declare values needed to check if given complex parameters are valid
559  std::string errorMessage;
560  DepartDefinition dd;
569  SVCPermissions mode;
570  int valueInt;
571  double valueDouble;
572  SUMOTime valueSUMOTime;
573  // check complex attribute
574  switch (myAttrProperties.getAttr()) {
575  case SUMO_ATTR_DEPART:
576  case SUMO_ATTR_BEGIN:
577  SUMOVehicleParameter::parseDepart(value, myAttrProperties.getAttrStr(), "", valueSUMOTime, dd, errorMessage);
578  break;
580  SUMOVehicleParameter::parseDepartLane(value, myAttrProperties.getAttrStr(), "", valueInt, dld, errorMessage);
581  break;
582  case SUMO_ATTR_DEPARTPOS:
583  SUMOVehicleParameter::parseDepartPos(value, myAttrProperties.getAttrStr(), "", valueDouble, dpd, errorMessage);
584  break;
586  SUMOVehicleParameter::parseDepartSpeed(value, myAttrProperties.getAttrStr(), "", valueDouble, dsd, errorMessage);
587  break;
589  SUMOVehicleParameter::parseArrivalLane(value, myAttrProperties.getAttrStr(), "", valueInt, ald, errorMessage);
590  break;
592  SUMOVehicleParameter::parseArrivalPos(value, myAttrProperties.getAttrStr(), "", valueDouble, apd, errorMessage);
593  break;
595  SUMOVehicleParameter::parseArrivalSpeed(value, myAttrProperties.getAttrStr(), "", valueDouble, asd, errorMessage);
596  break;
598  SUMOVehicleParameter::parseDepartPosLat(value, myAttrProperties.getAttrStr(), "", valueDouble, dpld, errorMessage);
599  break;
601  SUMOVehicleParameter::parseArrivalPosLat(value, myAttrProperties.getAttrStr(), "", valueDouble, apld, errorMessage);
602  break;
603  case SUMO_ATTR_MODES:
604  SUMOVehicleParameter::parsePersonModes(value, myAttrProperties.getAttrStr(), "", mode, errorMessage);
605  break;
606  default:
607  throw ProcessError("Invalid complex attribute");
608  }
609  // return error message (Will be empty if value is valid)
610  return errorMessage;
611 }
612 
613 // ---------------------------------------------------------------------------
614 // GNEFrameAttributesModuls::AttributesCreator - methods
615 // ---------------------------------------------------------------------------
616 
618  FXGroupBox(frameParent->myContentFrame, "Internal attributes", GUIDesignGroupBoxFrame),
619  myFrameParent(frameParent) {
620  // resize myAttributesCreatorRows
622  // create help button
623  myHelpButton = new FXButton(this, "Help", nullptr, this, MID_HELP, GUIDesignButtonRectangular);
624 }
625 
626 
628 
629 
630 void
632  // get current tag Properties
633  myTagProperties = tagProperties;
634  // destroy all rows
635  for (int i = 0; i < (int)myAttributesCreatorRows.size(); i++) {
636  // destroy and delete all rows
637  if (myAttributesCreatorRows.at(i) != nullptr) {
638  myAttributesCreatorRows.at(i)->destroy();
639  delete myAttributesCreatorRows.at(i);
640  myAttributesCreatorRows.at(i) = nullptr;
641  }
642  }
643  // iterate over tag attributes and create a AttributesCreatorRow
644  for (const auto& i : myTagProperties) {
645  // make sure that only non-unique attributes are created (And depending of includeExtendedAttributes)
646  if (!i.isUnique()) {
647  myAttributesCreatorRows.at(i.getPositionListed()) = new AttributesCreatorRow(this, i);
648  }
649  }
650  // update disjoint attributes
651  updateDisjointAttributes(nullptr);
652  // reparent help button (to place it at bottom)
653  myHelpButton->reparent(this);
654  // recalc
655  recalc();
656  // show
657  show();
658 }
659 
660 
661 void
663  hide();
664 }
665 
666 
667 std::map<SumoXMLAttr, std::string>
669  std::map<SumoXMLAttr, std::string> values;
670  // get standard parameters
671  for (int i = 0; i < (int)myAttributesCreatorRows.size(); i++) {
672  if (myAttributesCreatorRows.at(i) && myAttributesCreatorRows.at(i)->getAttrProperties().getAttr() != SUMO_ATTR_NOTHING) {
673  // flag for row enabled
674  bool rowEnabled = myAttributesCreatorRows.at(i)->isAttributesCreatorRowEnabled();
675  // flag for default attributes
676  bool hasDefaultStaticValue = !myAttributesCreatorRows.at(i)->getAttrProperties().hasStaticDefaultValue() || (myAttributesCreatorRows.at(i)->getAttrProperties().getDefaultValue() != myAttributesCreatorRows.at(i)->getValue());
677  // flag for enablitables attributes
678  bool isEnablitableAttribute = myAttributesCreatorRows.at(i)->getAttrProperties().isEnablitable();
679  // flag for optional attributes
680  bool isOptionalAttribute = myAttributesCreatorRows.at(i)->getAttrProperties().isOptional() && myAttributesCreatorRows.at(i)->getAttributeCheckButtonCheck();
681  // check if flags configuration allow to include values
682  if (rowEnabled && (includeAll || hasDefaultStaticValue || isEnablitableAttribute || isOptionalAttribute)) {
683  values[myAttributesCreatorRows.at(i)->getAttrProperties().getAttr()] = myAttributesCreatorRows.at(i)->getValue();
684  }
685  }
686  }
687  return values;
688 }
689 
690 
693  return myTagProperties;
694 }
695 
696 
697 void
699  std::string errorMessage;
700  // iterate over standar parameters
701  for (const auto& i : myTagProperties) {
702  if (errorMessage.empty() && myAttributesCreatorRows.at(i.getPositionListed())) {
703  // Return string with the error if at least one of the parameter isn't valid
704  std::string attributeValue = myAttributesCreatorRows.at(i.getPositionListed())->isAttributeValid();
705  if (attributeValue.size() != 0) {
706  errorMessage = attributeValue;
707  }
708  }
709  }
710  // show warning box if input parameters aren't invalid
711  if (extra.size() == 0) {
712  errorMessage = "Invalid input parameter of " + myTagProperties.getTagStr() + ": " + errorMessage;
713  } else {
714  errorMessage = "Invalid input parameter of " + myTagProperties.getTagStr() + ": " + extra;
715  }
716 
717  // set message in status bar
718  myFrameParent->myViewNet->setStatusBarText(errorMessage);
719  // Write Warning in console if we're in testing mode
720  WRITE_DEBUG(errorMessage);
721 }
722 
723 
724 bool
726  // iterate over standar parameters
727  for (auto i : myTagProperties) {
728  // Return false if error message of attriuve isn't empty
729  if (myAttributesCreatorRows.at(i.getPositionListed()) && myAttributesCreatorRows.at(i.getPositionListed())->isAttributeValid().size() != 0) {
730  return false;
731  }
732  }
733  return true;
734 }
735 
736 
737 void
739  // currently only Flows supports disjoint attributes
741  // obtain all rows (to improve code legibility)
747  if (row == nullptr) {
748  // by default routeFlows uses end and number
749  endRow->setAttributeRadioButtonCheck(true);
750  numberRow->setAttributeRadioButtonCheck(true);
751  vehsperhourRow->setAttributeRadioButtonCheck(false);
752  periodRow->setAttributeRadioButtonCheck(false);
753  probabilityRow->setAttributeRadioButtonCheck(false);
754  } else {
755  // check what row was clicked
756  switch (row->getAttrProperties().getAttr()) {
757  // end has more priority as number
758  case SUMO_ATTR_END:
759  endRow->setAttributeRadioButtonCheck(true);
760  // disable other combinations
761  vehsperhourRow->setAttributeRadioButtonCheck(false);
762  periodRow->setAttributeRadioButtonCheck(false);
763  probabilityRow->setAttributeRadioButtonCheck(false);
764  break;
765  case SUMO_ATTR_NUMBER:
766  numberRow->setAttributeRadioButtonCheck(true);
767  // disable number if begin and end are enabled because end has more priority as number
768  if (endRow->getAttributeRadioButtonCheck()) {
769  endRow->setAttributeRadioButtonCheck(false);
770  } else {
771  // disable other combinations
772  vehsperhourRow->setAttributeRadioButtonCheck(false);
773  periodRow->setAttributeRadioButtonCheck(false);
774  probabilityRow->setAttributeRadioButtonCheck(false);
775  }
776  break;
778  // disable number if begin and end are enabled because end has more priority as number
779  if (endRow->getAttributeRadioButtonCheck() && numberRow->getAttributeRadioButtonCheck()) {
780  numberRow->setAttributeRadioButtonCheck(false);
781  }
782  // disable other combinations
783  vehsperhourRow->setAttributeRadioButtonCheck(true);
784  periodRow->setAttributeRadioButtonCheck(false);
785  probabilityRow->setAttributeRadioButtonCheck(false);
786  break;
787  case SUMO_ATTR_PERIOD:
788  // disable number if begin and end are enabled because end has more priority as number
789  if (endRow->getAttributeRadioButtonCheck() && numberRow->getAttributeRadioButtonCheck()) {
790  numberRow->setAttributeRadioButtonCheck(false);
791  }
792  // disable other combinations
793  vehsperhourRow->setAttributeRadioButtonCheck(false);
794  periodRow->setAttributeRadioButtonCheck(true);
795  probabilityRow->setAttributeRadioButtonCheck(false);
796  break;
797  case SUMO_ATTR_PROB:
798  // disable number if begin and end are enabled because end has more priority as number
799  if (endRow->getAttributeRadioButtonCheck() && numberRow->getAttributeRadioButtonCheck()) {
800  numberRow->setAttributeRadioButtonCheck(false);
801  }
802  // disable other combinations
803  vehsperhourRow->setAttributeRadioButtonCheck(false);
804  periodRow->setAttributeRadioButtonCheck(false);
805  probabilityRow->setAttributeRadioButtonCheck(true);
806  break;
807  default:
808  break;
809  }
810  }
812  // check if expected has to be enabled or disabled
815  } else {
817  }
818  // check if expected contaienrs has to be enabled or disabled
821  } else {
823  }
824  }
825 }
826 
827 
828 long
830  // open Help attributes dialog
832  return 1;
833 }
834 
835 // ---------------------------------------------------------------------------
836 // GNEFrameAttributesModuls::AttributesEditorRow - methods
837 // ---------------------------------------------------------------------------
838 
840  FXHorizontalFrame(attributeEditorParent, GUIDesignAuxiliarHorizontalFrame),
841  myAttributesEditorParent(attributeEditorParent),
842  myACAttr(ACAttr),
843  myMultiple(GNEAttributeCarrier::parse<std::vector<std::string>>(value).size() > 1) {
844  // Create and hide label
845  myAttributeLabel = new FXLabel(this, "attributeLabel", nullptr, GUIDesignLabelAttribute);
846  myAttributeLabel->hide();
847  // Create and hide radio button
848  myAttributeRadioButton = new FXRadioButton(this, "attributeRadioButton", this, MID_GNE_SET_ATTRIBUTE_RADIOBUTTON, GUIDesignRadioButtonAttribute);
849  myAttributeRadioButton->hide();
850  // Create and hide check button
851  myAttributeCheckButton = new FXCheckButton(this, "attributeCheckButton", this, MID_GNE_SET_ATTRIBUTE_BOOL, GUIDesignCheckButtonAttribute);
852  myAttributeCheckButton->hide();
853  // Create and hide ButtonCombinableChoices
854  myAttributeButtonCombinableChoices = new FXButton(this, "attributeButtonCombinableChoices", nullptr, this, MID_GNE_SET_ATTRIBUTE_DIALOG, GUIDesignButtonAttribute);
856  // create and hidde color editor
857  myAttributeColorButton = new FXButton(this, "attributeColorButton", nullptr, this, MID_GNE_SET_ATTRIBUTE_DIALOG, GUIDesignButtonAttribute);
858  myAttributeColorButton->hide();
859  // Create and hide textField for int attributes
861  myValueTextFieldInt->hide();
862  // Create and hide textField for real/time attributes
864  myValueTextFieldReal->hide();
865  // Create and hide textField for string attributes
867  myValueTextFieldStrings->hide();
868  // Create and hide ComboBox
870  myValueComboBoxChoices->hide();
871  // Create and hide checkButton
872  myValueCheckButton = new FXCheckButton(this, "", this, MID_GNE_SET_ATTRIBUTE, GUIDesignCheckButton);
873  myValueCheckButton->hide();
874  // only create if parent was created
875  if (getParent()->id()) {
876  // create AttributesEditorRow
877  FXHorizontalFrame::create();
878  // start enabling all elements, depending if attribute is editable and enabled
879  if (myACAttr.isNonEditable() || !attributeEnabled) {
880  myValueTextFieldInt->disable();
881  myValueTextFieldReal->disable();
882  myValueTextFieldStrings->disable();
883  myValueComboBoxChoices->disable();
884  myValueCheckButton->disable();
886  myAttributeColorButton->disable();
887  myAttributeCheckButton->disable();
888  } else {
889  myValueTextFieldInt->enable();
890  myValueTextFieldReal->enable();
891  myValueTextFieldStrings->enable();
892  myValueComboBoxChoices->enable();
893  myValueCheckButton->enable();
895  myAttributeColorButton->enable();
896  myAttributeCheckButton->enable();
897  }
898  // set left column
899  if (myACAttr.isColor()) {
900  myAttributeColorButton->setTextColor(FXRGB(0, 0, 0));
901  myAttributeColorButton->setText(myACAttr.getAttrStr().c_str());
902  myAttributeColorButton->show();
903  } else if (myACAttr.isOptional()) {
904  myAttributeCheckButton->setTextColor(FXRGB(0, 0, 0));
905  myAttributeCheckButton->setText(myACAttr.getAttrStr().c_str());
906  myAttributeCheckButton->setCheck(FALSE);
907  myAttributeCheckButton->show();
908  } else if (myACAttr.isEnablitable()) {
909  myAttributeRadioButton->setTextColor(FXRGB(0, 0, 0));
910  myAttributeRadioButton->setText(myACAttr.getAttrStr().c_str());
911  myAttributeRadioButton->show();
912  // enable or disable depending if is editable
913  if (myACAttr.isNonEditable()) {
914  myAttributeRadioButton->disable();
915  } else {
916  myAttributeRadioButton->enable();
917  }
918  // check if radio button has to be check
919  if (attributeEnabled) {
920  myAttributeRadioButton->setCheck(TRUE);
921  } else {
922  myAttributeRadioButton->setCheck(FALSE);
923  }
924  } else {
925  // Show attribute Label
926  myAttributeLabel->setText(myACAttr.getAttrStr().c_str());
927  myAttributeLabel->show();
928  }
929  // Set field depending of the type of value
930  if (myACAttr.isBool()) {
931  // first we need to check if all boolean values are equal
932  bool allBooleanValuesEqual = true;
933  // declare boolean vector
934  std::vector<bool> booleanVector;
935  // check if value can be parsed to a boolean vector
936  if (GNEAttributeCarrier::canParse<std::vector<bool> >(value)) {
937  booleanVector = GNEAttributeCarrier::parse<std::vector<bool> >(value);
938  }
939  // iterate over pased booleans comparing all element with the first
940  for (const auto& i : booleanVector) {
941  if (i != booleanVector.front()) {
942  allBooleanValuesEqual = false;
943  }
944  }
945  // use checkbox or textfield depending if all booleans are equal
946  if (allBooleanValuesEqual) {
947  // set check button
948  if ((booleanVector.size() > 0) && booleanVector.front()) {
949  myValueCheckButton->setCheck(true);
950  myValueCheckButton->setText("true");
951  } else {
952  myValueCheckButton->setCheck(false);
953  myValueCheckButton->setText("false");
954  }
955  // show check button
956  myValueCheckButton->show();
957  } else {
958  // show list of bools (0 1)
959  myValueTextFieldStrings->setText(value.c_str());
960  myValueTextFieldStrings->setTextColor(FXRGB(0, 0, 0));
961  myValueTextFieldStrings->show();
962  // enable or disable depending if attribute is editable and is enabled (used by disjoint attributes)
963  if (myACAttr.isNonEditable() || !attributeEnabled) {
964  myValueTextFieldStrings->disable();
965  }
966  }
967  } else if (myACAttr.isDiscrete()) {
968  // Check if are combinable choices
969  if ((myACAttr.getDiscreteValues().size() > 0) && myACAttr.isCombinable()) {
970  // hide label
971  myAttributeLabel->hide();
972  // Show button combinable choices
975  // Show string with the values
976  myValueTextFieldStrings->setText(value.c_str());
977  myValueTextFieldStrings->setTextColor(FXRGB(0, 0, 0));
978  myValueTextFieldStrings->show();
979  } else if (!myMultiple) {
980  // fill comboBox
981  myValueComboBoxChoices->clearItems();
982  for (const auto& it : myACAttr.getDiscreteValues()) {
983  myValueComboBoxChoices->appendItem(it.c_str());
984  }
985  // show combo box with values
986  myValueComboBoxChoices->setNumVisible((int)myACAttr.getDiscreteValues().size());
987  myValueComboBoxChoices->setCurrentItem(myValueComboBoxChoices->findItem(value.c_str()));
988  myValueComboBoxChoices->setTextColor(FXRGB(0, 0, 0));
989  myValueComboBoxChoices->show();
990  } else {
991  // represent combinable choices in multiple selections always with a textfield instead with a comboBox
992  myValueTextFieldStrings->setText(value.c_str());
993  myValueTextFieldStrings->setTextColor(FXRGB(0, 0, 0));
994  myValueTextFieldStrings->show();
995  }
996  } else if (myACAttr.isFloat() || myACAttr.isSUMOTime()) {
997  // show TextField for real/time values
998  myValueTextFieldReal->setText(value.c_str());
999  myValueTextFieldReal->setTextColor(FXRGB(0, 0, 0));
1000  myValueTextFieldReal->show();
1001  } else if (myACAttr.isInt()) {
1002  // Show textField for int attributes
1003  myValueTextFieldInt->setText(value.c_str());
1004  myValueTextFieldInt->setTextColor(FXRGB(0, 0, 0));
1005  myValueTextFieldInt->show();
1006  // we need an extra check for connection attribute "TLIndex", because it cannot be edited if junction's connection doesn' have a TLS
1007  if ((myACAttr.getTagPropertyParent().getTag() == SUMO_TAG_CONNECTION) && (myACAttr.getAttr() == SUMO_ATTR_TLLINKINDEX) && (value == "No TLS")) {
1008  myValueTextFieldInt->disable();
1009  }
1010  } else {
1011  // In any other case (String, list, etc.), show value as String
1012  myValueTextFieldStrings->setText(value.c_str());
1013  myValueTextFieldStrings->setTextColor(FXRGB(0, 0, 0));
1014  myValueTextFieldStrings->show();
1015  }
1016  // if Tag correspond to an network element but we're in demand mode (or vice versa), disable all elements
1019  myAttributeColorButton->disable();
1020  myAttributeRadioButton->disable();
1021  myAttributeCheckButton->disable();
1022  myValueTextFieldInt->disable();
1023  myValueTextFieldReal->disable();
1024  myValueTextFieldStrings->disable();
1025  myValueComboBoxChoices->disable();
1026  myValueCheckButton->disable();
1028  }
1029  // special case for Traffic Lights
1030  if ((myACAttr.getTagPropertyParent().getTag() == SUMO_TAG_JUNCTION) && (myACAttr.getAttr() == SUMO_ATTR_TLID) && value.empty()) {
1031  myValueTextFieldStrings->disable();
1032  }
1033  // special case for Default vehicle types (ID cannot be edited)
1034  if ((ACAttr.getTagPropertyParent().getTag() == SUMO_TAG_VTYPE) && (ACAttr.getAttr() == SUMO_ATTR_ID) &&
1035  ((value == DEFAULT_VTYPE_ID) || (value == DEFAULT_PEDTYPE_ID) || (value == DEFAULT_BIKETYPE_ID))) {
1036  myValueTextFieldStrings->disable();
1037  }
1038  // special case for stops over stopping places (value cannot be changed)
1039  if ((ACAttr.getTagPropertyParent().isStop() || ACAttr.getTagPropertyParent().isPersonStop()) &&
1040  ((ACAttr.getAttr() == SUMO_ATTR_BUS_STOP) || (ACAttr.getAttr() == SUMO_ATTR_CONTAINER_STOP) ||
1041  (ACAttr.getAttr() == SUMO_ATTR_CHARGING_STATION) || (ACAttr.getAttr() == SUMO_ATTR_PARKING_AREA))) {
1042  myValueTextFieldStrings->disable();
1043  }
1044  // Show AttributesEditorRow
1045  show();
1046  }
1047 }
1048 
1049 
1050 void
1052  // only destroy if parent was created
1053  if (getParent()->id()) {
1054  FXHorizontalFrame::destroy();
1055  }
1056 }
1057 
1058 
1059 void
1060 GNEFrameAttributesModuls::AttributesEditorRow::refreshAttributesEditorRow(const std::string& value, bool forceRefresh, bool disjointAttributeEnabled) {
1061  // start enabling all elements
1062  myValueTextFieldInt->enable();
1063  myValueTextFieldReal->enable();
1064  myValueTextFieldStrings->enable();
1065  myValueComboBoxChoices->enable();
1066  myValueCheckButton->enable();
1068  myAttributeColorButton->enable();
1069  myAttributeRadioButton->enable();
1070  myAttributeCheckButton->enable();
1071  // set radio buton
1072  if (myAttributeRadioButton->shown()) {
1073  myAttributeRadioButton->setCheck(disjointAttributeEnabled);
1074  }
1075  // set check buton
1076  if (myAttributeCheckButton->shown()) {
1077  myAttributeCheckButton->setCheck(/*disjointAttributeEnabled*/ FALSE);
1078  }
1079  if (myValueTextFieldInt->shown()) {
1080  // set last valid value and restore color if onlyValid is disabled
1081  if (myValueTextFieldInt->getTextColor() == FXRGB(0, 0, 0) || forceRefresh) {
1082  myValueTextFieldInt->setText(value.c_str());
1083  myValueTextFieldInt->setTextColor(FXRGB(0, 0, 0));
1084  }
1085  // disable depending of disjointAttributeEnabled
1086  if (myACAttr.isNonEditable() || !disjointAttributeEnabled) {
1087  myValueTextFieldInt->disable();
1088  }
1089  } else if (myValueTextFieldReal->shown()) {
1090  // set last valid value and restore color if onlyValid is disabled
1091  if (myValueTextFieldReal->getTextColor() == FXRGB(0, 0, 0) || forceRefresh) {
1092  myValueTextFieldReal->setText(value.c_str());
1093  myValueTextFieldReal->setTextColor(FXRGB(0, 0, 0));
1094  }
1095  // disable depending of disjointAttributeEnabled
1096  if (myACAttr.isNonEditable() || !disjointAttributeEnabled) {
1097  myValueTextFieldReal->disable();
1098  }
1099  } else if (myValueTextFieldStrings->shown()) {
1100  // set last valid value and restore color if onlyValid is disabled
1101  if (myValueTextFieldStrings->getTextColor() == FXRGB(0, 0, 0) || forceRefresh) {
1102  myValueTextFieldStrings->setText(value.c_str());
1103  myValueTextFieldStrings->setTextColor(FXRGB(0, 0, 0));
1104  }
1105  // disable depending of disjointAttributeEnabled
1106  if (myACAttr.isNonEditable() || !disjointAttributeEnabled) {
1107  myValueTextFieldStrings->disable();
1108  }
1109  } else if (myValueComboBoxChoices->shown()) {
1110  // fill comboBox again
1111  myValueComboBoxChoices->clearItems();
1112  for (const auto& it : myACAttr.getDiscreteValues()) {
1113  myValueComboBoxChoices->appendItem(it.c_str());
1114  }
1115  // show combo box with values
1116  myValueComboBoxChoices->setNumVisible((int)myACAttr.getDiscreteValues().size());
1117  myValueComboBoxChoices->setCurrentItem(myValueComboBoxChoices->findItem(value.c_str()));
1118  myValueComboBoxChoices->setTextColor(FXRGB(0, 0, 0));
1119  myValueComboBoxChoices->show();
1120  // disable depending of disjointAttributeEnabled
1121  if (myACAttr.isNonEditable() || !disjointAttributeEnabled) {
1122  myValueComboBoxChoices->disable();
1123  }
1124  } else if (myValueCheckButton->shown()) {
1125  if (GNEAttributeCarrier::canParse<bool>(value)) {
1126  myValueCheckButton->setCheck(GNEAttributeCarrier::parse<bool>(value));
1127  } else {
1128  myValueCheckButton->setCheck(false);
1129  }
1130  // disable depending of disjointAttributeEnabled
1131  if (myACAttr.isNonEditable() || !disjointAttributeEnabled) {
1132  myValueCheckButton->disable();
1133  }
1134  }
1135  // if Tag correspond to an network element but we're in demand mode (or vice versa), disable all elements
1136  if (myACAttr.getAttr() != SUMO_ATTR_NOTHING) {
1139  myAttributeColorButton->disable();
1140  myAttributeRadioButton->disable();
1141  myAttributeCheckButton->disable();
1142  myValueTextFieldInt->disable();
1143  myValueTextFieldReal->disable();
1144  myValueTextFieldStrings->disable();
1145  myValueComboBoxChoices->disable();
1146  myValueCheckButton->disable();
1148  }
1149  // special case for Traffic Lights
1150  if ((myACAttr.getTagPropertyParent().getTag() == SUMO_TAG_JUNCTION) && (myACAttr.getAttr() == SUMO_ATTR_TLID) && value.empty()) {
1151  myValueTextFieldStrings->disable();
1152  }
1153  // special case for Default vehicle types (ID cannot be edited)
1155  ((value == DEFAULT_VTYPE_ID) || (value == DEFAULT_PEDTYPE_ID) || (value == DEFAULT_BIKETYPE_ID))) {
1156  myValueTextFieldStrings->disable();
1157  }
1158  // special case for stops over stopping places (value cannot be changed)
1162  myValueTextFieldStrings->disable();
1163  }
1164  }
1165 }
1166 
1167 
1168 bool
1170  return ((myValueTextFieldInt->getTextColor() == FXRGB(0, 0, 0)) && (myValueTextFieldReal->getTextColor() == FXRGB(0, 0, 0)) &&
1171  (myValueTextFieldStrings->getTextColor() == FXRGB(0, 0, 0)) && (myValueComboBoxChoices->getTextColor() == FXRGB(0, 0, 0)));
1172 }
1173 
1174 
1175 long
1177  if (obj == myAttributeColorButton) {
1178  // create FXColorDialog
1179  FXColorDialog colordialog(this, tr("Color Dialog"));
1180  colordialog.setTarget(this);
1181  // If previous attribute wasn't correct, set black as default color
1182  if (GNEAttributeCarrier::canParse<RGBColor>(myValueTextFieldStrings->getText().text())) {
1183  colordialog.setRGBA(MFXUtils::getFXColor(RGBColor::parseColor(myValueTextFieldStrings->getText().text())));
1184  } else if (!myACAttr.getDefaultValue().empty()) {
1186  } else {
1187  colordialog.setRGBA(MFXUtils::getFXColor(RGBColor::BLACK));
1188  }
1189  // execute dialog to get a new color
1190  if (colordialog.execute()) {
1191  std::string newValue = toString(MFXUtils::getRGBColor(colordialog.getRGBA()));
1192  myValueTextFieldStrings->setText(newValue.c_str());
1193  if (myAttributesEditorParent->getEditedACs().front()->isValid(myACAttr.getAttr(), newValue)) {
1194  // if its valid for the first AC than its valid for all (of the same type)
1195  if (myAttributesEditorParent->getEditedACs().size() > 1) {
1196  myAttributesEditorParent->getFrameParent()->myViewNet->getUndoList()->p_begin("Change multiple attributes");
1197  }
1198  // Set new value of attribute in all selected ACs
1199  for (const auto& it_ac : myAttributesEditorParent->getEditedACs()) {
1200  it_ac->setAttribute(myACAttr.getAttr(), newValue, myAttributesEditorParent->getFrameParent()->myViewNet->getUndoList());
1201  }
1202  // If previously value was incorrect, change font color to black
1203  myValueTextFieldStrings->setTextColor(FXRGB(0, 0, 0));
1204  myValueTextFieldStrings->killFocus();
1205  }
1206  }
1207  return 0;
1208  } else if (obj == myAttributeButtonCombinableChoices) {
1209  // if its valid for the first AC than its valid for all (of the same type)
1210  if (myAttributesEditorParent->getEditedACs().size() > 1) {
1211  myAttributesEditorParent->getFrameParent()->myViewNet->getUndoList()->p_begin("Change multiple attributes");
1212  }
1213  // open GNEDialog_AllowDisallow
1215  std::string allowed = myAttributesEditorParent->getEditedACs().front()->getAttribute(SUMO_ATTR_ALLOW);
1216  // Set new value of attribute in all selected ACs
1217  for (const auto& it_ac : myAttributesEditorParent->getEditedACs()) {
1218  it_ac->setAttribute(SUMO_ATTR_ALLOW, allowed, myAttributesEditorParent->getFrameParent()->myViewNet->getUndoList());
1219  }
1220  // finish change multiple attributes
1221  if (myAttributesEditorParent->getEditedACs().size() > 1) {
1223  }
1224  // update frame parent after attribute sucesfully set
1226  return 1;
1227  } else {
1228  throw ProcessError("Invalid call to onCmdOpenAttributeDialog");
1229  }
1230 }
1231 
1232 
1233 long
1235  // Declare changed value
1236  std::string newVal;
1237  // First, obtain the string value of the new attribute depending of their type
1238  if (myACAttr.isBool()) {
1239  // first check if we're editing boolean as a list of string or as a checkbox
1240  if (myValueCheckButton->shown()) {
1241  // Set true o false depending of the checkBox
1242  if (myValueCheckButton->getCheck()) {
1243  myValueCheckButton->setText("true");
1244  newVal = "true";
1245  } else {
1246  myValueCheckButton->setText("false");
1247  newVal = "false";
1248  }
1249  } else {
1250  // obtain boolean value of myValueTextFieldStrings (because we're inspecting multiple attribute carriers with different values)
1251  newVal = myValueTextFieldStrings->getText().text();
1252  }
1253  } else if (myACAttr.isDiscrete()) {
1254  // Check if are combinable choices (for example, Vehicle Types)
1255  if ((myACAttr.getDiscreteValues().size() > 0) &&
1256  myACAttr.isCombinable()) {
1257  // Get value obtained using AttributesEditor
1258  newVal = myValueTextFieldStrings->getText().text();
1259  } else if (!myMultiple) {
1260  // Get value of ComboBox
1261  newVal = myValueComboBoxChoices->getText().text();
1262  } else {
1263  // due this is a multiple selection, obtain value of myValueTextFieldStrings instead of comboBox
1264  newVal = myValueTextFieldStrings->getText().text();
1265  }
1266  } else if (myACAttr.isFloat() || myACAttr.isSUMOTime()) {
1267  // Check if default value of attribute must be set
1268  if (myValueTextFieldReal->getText().empty() && myACAttr.hasStaticDefaultValue()) {
1269  newVal = myACAttr.getDefaultValue();
1270  myValueTextFieldReal->setText(newVal.c_str());
1271  } else {
1272  // obtain value of myValueTextFieldReal
1273  newVal = myValueTextFieldReal->getText().text();
1274  }
1275  } else if (myACAttr.isInt()) {
1276  // Check if default value of attribute must be set
1277  if (myValueTextFieldInt->getText().empty() && myACAttr.hasStaticDefaultValue()) {
1278  newVal = myACAttr.getDefaultValue();
1279  myValueTextFieldInt->setText(newVal.c_str());
1280  } else {
1281  // obtain value of myValueTextFieldInt
1282  newVal = myValueTextFieldInt->getText().text();
1283  }
1284  } else {
1285  // Check if default value of attribute must be set
1286  if (myValueTextFieldStrings->getText().empty() && myACAttr.hasStaticDefaultValue()) {
1287  newVal = myACAttr.getDefaultValue();
1288  myValueTextFieldStrings->setText(newVal.c_str());
1289  } else {
1290  // obtain value of myValueTextFieldStrings
1291  newVal = myValueTextFieldStrings->getText().text();
1292  }
1293  }
1294 
1295  // we need a extra check for Position and Shape Values, due #2658
1297  newVal = stripWhitespaceAfterComma(newVal);
1298  }
1299 
1300  // Check if attribute must be changed
1301  if (myAttributesEditorParent->getEditedACs().front()->isValid(myACAttr.getAttr(), newVal)) {
1302  // if its valid for the first AC than its valid for all (of the same type)
1303  if (myAttributesEditorParent->getEditedACs().size() > 1) {
1304  myAttributesEditorParent->getFrameParent()->myViewNet->getUndoList()->p_begin("Change multiple attributes");
1305  } else if (myACAttr.getAttr() == SUMO_ATTR_ID) {
1306  // IDs attribute has to be encapsulated
1308  }
1309  // Set new value of attribute in all selected ACs
1310  for (const auto& it_ac : myAttributesEditorParent->getEditedACs()) {
1311  it_ac->setAttribute(myACAttr.getAttr(), newVal, myAttributesEditorParent->getFrameParent()->myViewNet->getUndoList());
1312  }
1313  // finish change multiple attributes or ID Attributes
1314  if (myAttributesEditorParent->getEditedACs().size() > 1) {
1316  } else if (myACAttr.getAttr() == SUMO_ATTR_ID) {
1318  }
1319  // If previously value was incorrect, change font color to black
1320  if (myACAttr.isCombinable()) {
1321  myValueTextFieldStrings->setTextColor(FXRGB(0, 0, 0));
1322  myValueTextFieldStrings->killFocus();
1323  // in this case, we need to refresh the other values (For example, allow/Disallow objects)
1325  } else if (myACAttr.isDiscrete()) {
1326  myValueComboBoxChoices->setTextColor(FXRGB(0, 0, 0));
1327  myValueComboBoxChoices->killFocus();
1328  } else if (myACAttr.isFloat() || myACAttr.isSUMOTime()) {
1329  myValueTextFieldReal->setTextColor(FXRGB(0, 0, 0));
1330  myValueTextFieldReal->killFocus();
1331  } else if (myACAttr.isInt() && myValueTextFieldStrings != nullptr) {
1332  myValueTextFieldInt->setTextColor(FXRGB(0, 0, 0));
1333  myValueTextFieldInt->killFocus();
1334  } else if (myValueTextFieldStrings != nullptr) {
1335  myValueTextFieldStrings->setTextColor(FXRGB(0, 0, 0));
1336  myValueTextFieldStrings->killFocus();
1337  }
1338  // update frame parent after attribute sucesfully set
1340  } else {
1341  // If value of TextField isn't valid, change color to Red depending of type
1342  if (myACAttr.isCombinable()) {
1343  myValueTextFieldStrings->setTextColor(FXRGB(255, 0, 0));
1344  myValueTextFieldStrings->killFocus();
1345  } else if (myACAttr.isDiscrete()) {
1346  myValueComboBoxChoices->setTextColor(FXRGB(255, 0, 0));
1347  myValueComboBoxChoices->killFocus();
1348  } else if (myACAttr.isFloat() || myACAttr.isSUMOTime()) {
1349  myValueTextFieldReal->setTextColor(FXRGB(255, 0, 0));
1350  } else if (myACAttr.isInt() && myValueTextFieldStrings != nullptr) {
1351  myValueTextFieldInt->setTextColor(FXRGB(255, 0, 0));
1352  } else if (myValueTextFieldStrings != nullptr) {
1353  myValueTextFieldStrings->setTextColor(FXRGB(255, 0, 0));
1354  }
1355  // Write Warning in console if we're in testing mode
1356  WRITE_DEBUG("Value '" + newVal + "' for attribute " + myACAttr.getAttrStr() + " of " + myACAttr.getTagPropertyParent().getTagStr() + " isn't valid");
1357  }
1358  return 1;
1359 }
1360 
1361 
1362 long
1364  if (myAttributeCheckButton->getCheck()) {
1365  // enable input values
1366  myValueCheckButton->enable();
1367  myValueTextFieldInt->enable();
1368  myValueTextFieldReal->enable();
1369  myValueTextFieldStrings->enable();
1370  } else {
1371  // disable input values
1372  myValueCheckButton->disable();
1373  myValueTextFieldInt->disable();
1374  myValueTextFieldReal->disable();
1375  myValueTextFieldStrings->disable();
1376  }
1377  return 0;
1378 }
1379 
1380 
1381 long
1383  // obtain undoList (To improve code legibly)
1385  // write debug (for Netedit tests)
1386  WRITE_DEBUG("Selected radio button for attribute '" + myACAttr.getAttrStr() + "'");
1387  // begin undoList
1388  undoList->p_begin("enable attribute '" + myACAttr.getAttrStr() + "'");
1389  // change disjoint attribute with undo/redo
1390  myAttributesEditorParent->getEditedACs().front()->enableAttribute(myACAttr.getAttr(), undoList);
1391  // begin undoList
1392  undoList->p_end();
1393  // refresh Attributes edito parent
1395  return 0;
1396 }
1397 
1398 
1400  myMultiple(false) {
1401 }
1402 
1403 
1404 std::string
1406  std::string result(stringValue);
1407  while (result.find(", ") != std::string::npos) {
1408  result = StringUtils::replace(result, ", ", ",");
1409  }
1410  return result;
1411 }
1412 
1413 // ---------------------------------------------------------------------------
1414 // GNEFrameAttributesModuls::AttributesEditor - methods
1415 // ---------------------------------------------------------------------------
1416 
1418  FXGroupBox(FrameParent->myContentFrame, "Internal attributes", GUIDesignGroupBoxFrame),
1419  myFrameParent(FrameParent),
1420  myIncludeExtended(true) {
1421  // resize myAttributesEditorRows
1423  // Create help button
1424  myHelpButton = new FXButton(this, "Help", nullptr, this, MID_HELP, GUIDesignButtonRectangular);
1425 }
1426 
1427 
1428 void
1429 GNEFrameAttributesModuls::AttributesEditor::showAttributeEditorModul(const std::vector<GNEAttributeCarrier*>& ACs, bool includeExtended) {
1430  myEditedACs = ACs;
1431  myIncludeExtended = includeExtended;
1432  // remove all rows
1433  for (int i = 0; i < (int)myAttributesEditorRows.size(); i++) {
1434  // destroy and delete all rows
1435  if (myAttributesEditorRows.at(i) != nullptr) {
1436  myAttributesEditorRows.at(i)->destroy();
1437  delete myAttributesEditorRows.at(i);
1438  myAttributesEditorRows.at(i) = nullptr;
1439  }
1440  }
1441  if (myEditedACs.size() > 0) {
1442  // Iterate over attributes
1443  for (const auto& i : myEditedACs.front()->getTagProperty()) {
1444  // disable editing for unique attributes in case of multi-selection
1445  if ((myEditedACs.size() > 1) && i.isUnique()) {
1446  continue;
1447  }
1448  // disable editing of extended attributes if includeExtended isn't enabled
1449  if (i.isExtended() && !includeExtended) {
1450  continue;
1451  }
1452  // Declare a set of occuring values and insert attribute's values of item (note: We use a set to avoid repeated values)
1453  std::set<std::string> occuringValues;
1454  for (const auto& it_ac : myEditedACs) {
1455  occuringValues.insert(it_ac->getAttribute(i.getAttr()));
1456  }
1457  // get current value
1458  std::ostringstream oss;
1459  for (auto it_val = occuringValues.begin(); it_val != occuringValues.end(); it_val++) {
1460  if (it_val != occuringValues.begin()) {
1461  oss << " ";
1462  }
1463  oss << *it_val;
1464  }
1465  std::string value = oss.str();
1466  if ((myEditedACs.front()->getTagProperty().getTag() == SUMO_TAG_CONNECTION) &&
1467  (i.getAttr() == SUMO_ATTR_TLLINKINDEX)
1468  && value == toString(NBConnection::InvalidTlIndex)) {
1469  // possibly the connections are newly created (allow assigning
1470  // tlIndex if the junction(s) have a traffic light
1471  for (const auto& it_ac : myEditedACs) {
1472  if (!it_ac->isValid(SUMO_ATTR_TLLINKINDEX, "0")) {
1473  value = "No TLS";
1474  break;
1475  }
1476  }
1477  }
1478  // show AttributesEditor
1479  show();
1480  // check if attribute is enabled
1481  bool attributeEnabled = i.isEnablitable() ? myEditedACs.front()->isAttributeEnabled(i.getAttr()) : true;
1482  // create attribute editor row
1483  myAttributesEditorRows[i.getPositionListed()] = new AttributesEditorRow(this, i, value, attributeEnabled);
1484  }
1485  }
1486  // reparent help button (to place it at bottom)
1487  myHelpButton->reparent(this);
1488 }
1489 
1490 
1491 void
1493  // clear myEditedACs
1494  myEditedACs.clear();
1495  // hide also AttributesEditor
1496  hide();
1497 }
1498 
1499 
1500 void
1501 GNEFrameAttributesModuls::AttributesEditor::refreshAttributeEditor(bool forceRefreshShape, bool forceRefreshPosition) {
1502  if (myEditedACs.size() > 0) {
1503  // Iterate over attributes
1504  for (const auto& i : myEditedACs.front()->getTagProperty()) {
1505  // disable editing for unique attributes in case of multi-selection
1506  if ((myEditedACs.size() > 1) && i.isUnique()) {
1507  continue;
1508  }
1509  // Declare a set of occuring values and insert attribute's values of item
1510  std::set<std::string> occuringValues;
1511  for (const auto& it_ac : myEditedACs) {
1512  occuringValues.insert(it_ac->getAttribute(i.getAttr()));
1513  }
1514  // get current value
1515  std::ostringstream oss;
1516  for (auto it_val = occuringValues.begin(); it_val != occuringValues.end(); it_val++) {
1517  if (it_val != occuringValues.begin()) {
1518  oss << " ";
1519  }
1520  oss << *it_val;
1521  }
1522  // check if attribute is enabled
1523  bool attributeEnabled = i.isEnablitable() ? myEditedACs.front()->isAttributeEnabled(i.getAttr()) : true;
1524  // Check if refresh of Position or Shape has to be forced
1525  if ((i.getAttr() == SUMO_ATTR_SHAPE) && forceRefreshShape) {
1526  myAttributesEditorRows[i.getPositionListed()]->refreshAttributesEditorRow(oss.str(), true, attributeEnabled);
1527  } else if ((i.getAttr() == SUMO_ATTR_POSITION) && forceRefreshPosition) {
1528  // Refresh attributes maintain invalid values
1529  myAttributesEditorRows[i.getPositionListed()]->refreshAttributesEditorRow(oss.str(), true, attributeEnabled);
1530  } else {
1531  // Refresh attributes maintain invalid values
1532  myAttributesEditorRows[i.getPositionListed()]->refreshAttributesEditorRow(oss.str(), false, attributeEnabled);
1533  }
1534  }
1535  }
1536 }
1537 
1538 
1539 GNEFrame*
1541  return myFrameParent;
1542 }
1543 
1544 
1545 const std::vector<GNEAttributeCarrier*>&
1547  return myEditedACs;
1548 }
1549 
1550 
1551 void
1553  // Only remove if there is inspected ACs
1554  if (myEditedACs.size() > 0) {
1555  // Try to find AC in myACs
1556  auto i = std::find(myEditedACs.begin(), myEditedACs.end(), AC);
1557  // if was found
1558  if (i != myEditedACs.end()) {
1559  // erase AC from inspected ACs
1560  myEditedACs.erase(i);
1561  // Write Warning in console if we're in testing mode
1562  WRITE_DEBUG("Removed inspected element from Inspected ACs. " + toString(myEditedACs.size()) + " ACs remains.");
1563  // Inspect multi selection again (To refresh Modul)
1565  }
1566  }
1567 }
1568 
1569 
1570 long
1572  // open Help attributes dialog if there is inspected ACs
1573  if (myEditedACs.size() > 0) {
1574  // open Help attributes dialog
1575  myFrameParent->openHelpAttributesDialog(myEditedACs.front()->getTagProperty());
1576  }
1577  return 1;
1578 }
1579 
1580 // ---------------------------------------------------------------------------
1581 // GNEFrameAttributesModuls::AttributesEditorExtended- methods
1582 // ---------------------------------------------------------------------------
1583 
1585  FXGroupBox(frameParent->myContentFrame, "Extended attributes", GUIDesignGroupBoxFrame),
1586  myFrameParent(frameParent) {
1587  // Create open dialog button
1588  new FXButton(this, "Open attributes editor", nullptr, this, MID_GNE_SET_ATTRIBUTE_DIALOG, GUIDesignButton);
1589 }
1590 
1591 
1593 
1594 
1595 void
1597  show();
1598 }
1599 
1600 
1601 void
1603  hide();
1604 }
1605 
1606 
1607 long
1609  // open AttributesCreator extended dialog
1611  return 1;
1612 }
1613 
1614 // ---------------------------------------------------------------------------
1615 // GNEFrameAttributesModuls::GenericParametersEditor - methods
1616 // ---------------------------------------------------------------------------
1617 
1619  FXGroupBox(inspectorFrameParent->myContentFrame, "Generic parameters", GUIDesignGroupBoxFrame),
1620  myFrameParent(inspectorFrameParent),
1621  myAC(nullptr),
1622  myGenericParameters(nullptr) {
1623  // create empty vector with generic parameters
1624  myGenericParameters = new std::vector<std::pair<std::string, std::string> >;
1625  // create textfield and buttons
1627  myEditGenericParameterButton = new FXButton(this, "Edit generic parameter", nullptr, this, MID_GNE_SET_ATTRIBUTE_DIALOG, GUIDesignButton);
1628 }
1629 
1630 
1632  delete myGenericParameters;
1633 }
1634 
1635 
1636 void
1638  if (AC != nullptr) {
1639  myAC = AC;
1640  myACs.clear();
1641  // obtain a copy of generic parameters of AC
1642  if (myAC) {
1644  }
1645  // refresh GenericParametersEditor
1647  // show groupbox
1648  show();
1649  }
1650 }
1651 
1652 
1653 void
1655  if (ACs.size() > 0) {
1656  myAC = nullptr;
1657  myACs = ACs;
1658  // check if generic parameters are different
1659  bool differentsGenericParameters = false;
1660  std::string genericParameter = myACs.front()->getAttribute(GNE_ATTR_GENERIC);
1661  for (auto i : myACs) {
1662  if (genericParameter != i->getAttribute(GNE_ATTR_GENERIC)) {
1663  differentsGenericParameters = true;
1664  }
1665  }
1666  // set generic Parameters editor
1667  if (differentsGenericParameters) {
1668  myGenericParameters->clear();
1669  } else {
1670  *myGenericParameters = myACs.front()->getGenericParameters();
1671  }
1672  // refresh GenericParametersEditor
1674  // show groupbox
1675  show();
1676  }
1677 }
1678 
1679 
1680 void
1682  myAC = nullptr;
1683  // hide groupbox
1684  hide();
1685 }
1686 
1687 
1688 void
1690  // update text field depending of AC
1691  if (myAC) {
1693  myTextFieldGenericParameter->setTextColor(FXRGB(0, 0, 0));
1694  // disable myTextFieldGenericParameter if Tag correspond to an network element but we're in demand mode (or vice versa), disable all elements
1697  myTextFieldGenericParameter->disable();
1698  myEditGenericParameterButton->disable();
1699  } else {
1700  myTextFieldGenericParameter->enable();
1701  myEditGenericParameterButton->enable();
1702  }
1703  } else if (myACs.size() > 0) {
1704  // check if generic parameters of all inspected ACs are different
1705  std::string genericParameter = myACs.front()->getAttribute(GNE_ATTR_GENERIC);
1706  for (auto i : myACs) {
1707  if (genericParameter != i->getAttribute(GNE_ATTR_GENERIC)) {
1708  genericParameter = "different generic attributes";
1709  }
1710  }
1711  myTextFieldGenericParameter->setText(genericParameter.c_str());
1712  myTextFieldGenericParameter->setTextColor(FXRGB(0, 0, 0));
1713  // disable myTextFieldGenericParameter if we're in demand mode and inspected AC isn't a demand element (or viceversa)
1714  if (((myFrameParent->myViewNet->getEditModes().currentSupermode == GNE_SUPERMODE_NETWORK) && myACs.front()->getTagProperty().isDemandElement()) ||
1715  ((myFrameParent->myViewNet->getEditModes().currentSupermode == GNE_SUPERMODE_DEMAND) && !myACs.front()->getTagProperty().isDemandElement())) {
1716  myTextFieldGenericParameter->disable();
1717  myEditGenericParameterButton->disable();
1718  } else {
1719  myTextFieldGenericParameter->enable();
1720  myEditGenericParameterButton->enable();
1721  }
1722  }
1723 }
1724 
1725 
1726 std::string
1728  std::string result;
1729  // Generate an string using the following structure: "key1=value1|key2=value2|...
1730  for (auto i = myGenericParameters->begin(); i != myGenericParameters->end(); i++) {
1731  result += i->first + "=" + i->second + "|";
1732  }
1733  // remove the last "|"
1734  if (!result.empty()) {
1735  result.pop_back();
1736  }
1737  return result;
1738 }
1739 
1740 
1741 long
1743  // write debug information
1744  WRITE_DEBUG("Open generic parameter dialog");
1745  // edit generic parameters using dialog
1747  // write debug information
1748  WRITE_DEBUG("Close generic parameter dialog");
1749  // set values edited in Parameter dialog in Edited AC
1750  if (myAC) {
1752  } else if (myACs.size() > 0) {
1753  myFrameParent->myViewNet->getUndoList()->p_begin("Change multiple generic attributes");
1754  for (auto i : myACs) {
1756  }
1758  // update frame parent after attribute sucesfully set
1760  }
1761  // Refresh parameter editor
1763  } else {
1764  // write debug information
1765  WRITE_DEBUG("Cancel generic parameter dialog");
1766  }
1767  return 1;
1768 }
1769 
1770 
1771 long
1773  // separate value in a vector of string using | as separator
1774  std::vector<std::string> parsedValues;
1775  StringTokenizer st(myTextFieldGenericParameter->getText().text(), "|", true);
1776  while (st.hasNext()) {
1777  parsedValues.push_back(st.next());
1778  }
1779  // first check if parsed generic parameters are valid
1780  for (auto i : parsedValues) {
1782  WRITE_WARNING("Invalid format of Generic Parameter (" + i + ")");
1783  myTextFieldGenericParameter->setTextColor(FXRGB(255, 0, 0));
1784  return 1;
1785  }
1786  }
1787  // now check if there is duplicated parameters
1788  std::sort(parsedValues.begin(), parsedValues.end());
1789  for (auto i = parsedValues.begin(); i != parsedValues.end(); i++) {
1790  if (((i + 1) != parsedValues.end())) {
1791  std::vector<std::string> firstKey, secondKey;
1792  StringTokenizer stKey1(*i, "=", true);
1793  StringTokenizer stKey2(*(i + 1), "=", true);
1794  //parse both keys
1795  while (stKey1.hasNext()) {
1796  firstKey.push_back(stKey1.next());
1797  }
1798  while (stKey2.hasNext()) {
1799  secondKey.push_back(stKey2.next());
1800  }
1801  // compare both keys and stop if are equal
1802  if ((firstKey.size() != 2) || (secondKey.size() != 2) || (firstKey.front() == secondKey.front())) {
1803  WRITE_WARNING("Generic Parameters wit the same key aren't allowed (" + (*i) + "," + * (i + 1) + ")");
1804  myTextFieldGenericParameter->setTextColor(FXRGB(255, 0, 0));
1805  return 1;
1806  }
1807  }
1808  }
1809  // parsed generic parameters ok, then set text field black and continue
1810  myTextFieldGenericParameter->setTextColor(FXRGB(0, 0, 0));
1811  myTextFieldGenericParameter->killFocus();
1812  // clear current existent generic parameters and set parsed generic parameters
1813  myGenericParameters->clear();
1814  for (auto i : parsedValues) {
1815  std::vector<std::string> parsedParameters;
1816  StringTokenizer stParam(i, "=", true);
1817  while (stParam.hasNext()) {
1818  parsedParameters.push_back(stParam.next());
1819  }
1820  // Check that parsed parameters are exactly two and contains valid chracters
1821  if (parsedParameters.size() == 2 && SUMOXMLDefinitions::isValidGenericParameterKey(parsedParameters.front()) && SUMOXMLDefinitions::isValidGenericParameterValue(parsedParameters.back())) {
1822  myGenericParameters->push_back(std::make_pair(parsedParameters.front(), parsedParameters.back()));
1823  }
1824  }
1825  // if we're editing generic attributes of an AttributeCarrier, set it
1826  if (myAC) {
1828  } else if (myACs.size() > 0) {
1829  myFrameParent->myViewNet->getUndoList()->p_begin("Change multiple generic attributes");
1830  for (auto i : myACs) {
1832  }
1834  // update frame parent after attribute sucesfully set
1836  }
1837  return 1;
1838 }
1839 
1840 // ---------------------------------------------------------------------------
1841 // GNEFrameAttributesModuls::DrawingShape - methods
1842 // ---------------------------------------------------------------------------
1843 
1845  FXGroupBox(frameParent->myContentFrame, "Drawing", GUIDesignGroupBoxFrame),
1846  myFrameParent(frameParent),
1847  myDeleteLastCreatedPoint(false) {
1848  // create start and stop buttons
1849  myStartDrawingButton = new FXButton(this, "Start drawing", 0, this, MID_GNE_STARTDRAWING, GUIDesignButton);
1850  myStopDrawingButton = new FXButton(this, "Stop drawing", 0, this, MID_GNE_STOPDRAWING, GUIDesignButton);
1851  myAbortDrawingButton = new FXButton(this, "Abort drawing", 0, this, MID_GNE_ABORTDRAWING, GUIDesignButton);
1852 
1853  // create information label
1854  std::ostringstream information;
1855  information
1856  << "- 'Start drawing' or ENTER\n"
1857  << " draws shape boundary.\n"
1858  << "- 'Stop drawing' or ENTER\n"
1859  << " creates shape.\n"
1860  << "- 'Shift + Click'\n"
1861  << " removes last created point.\n"
1862  << "- 'Abort drawing' or ESC\n"
1863  << " removes drawed shape.";
1864  myInformationLabel = new FXLabel(this, information.str().c_str(), 0, GUIDesignLabelFrameInformation);
1865  // disable stop and abort functions as init
1866  myStopDrawingButton->disable();
1867  myAbortDrawingButton->disable();
1868 }
1869 
1870 
1872 
1873 
1875  // abort current drawing before show
1876  abortDrawing();
1877  // show FXGroupBox
1878  FXGroupBox::show();
1879 }
1880 
1881 
1883  // abort current drawing before hide
1884  abortDrawing();
1885  // show FXGroupBox
1886  FXGroupBox::hide();
1887 }
1888 
1889 
1890 void
1892  // Only start drawing if DrawingShape modul is shown
1893  if (shown()) {
1894  // change buttons
1895  myStartDrawingButton->disable();
1896  myStopDrawingButton->enable();
1897  myAbortDrawingButton->enable();
1898  }
1899 }
1900 
1901 
1902 void
1904  // try to build shape
1905  if (myFrameParent->shapeDrawed()) {
1906  // clear created points
1907  myTemporalShapeShape.clear();
1909  // change buttons
1910  myStartDrawingButton->enable();
1911  myStopDrawingButton->disable();
1912  myAbortDrawingButton->disable();
1913  } else {
1914  // abort drawing if shape cannot be created
1915  abortDrawing();
1916  }
1917 }
1918 
1919 
1920 void
1922  // clear created points
1923  myTemporalShapeShape.clear();
1925  // change buttons
1926  myStartDrawingButton->enable();
1927  myStopDrawingButton->disable();
1928  myAbortDrawingButton->disable();
1929 }
1930 
1931 
1932 void
1934  if (myStopDrawingButton->isEnabled()) {
1935  myTemporalShapeShape.push_back(P);
1936  } else {
1937  throw ProcessError("A new point cannot be added if drawing wasn't started");
1938  }
1939 }
1940 
1941 
1942 void
1944 
1945 }
1946 
1947 
1948 const PositionVector&
1950  return myTemporalShapeShape;
1951 }
1952 
1953 
1954 bool
1956  return myStopDrawingButton->isEnabled();
1957 }
1958 
1959 
1960 void
1962  myDeleteLastCreatedPoint = value;
1963 }
1964 
1965 
1966 bool
1968  return myDeleteLastCreatedPoint;
1969 }
1970 
1971 
1972 long
1974  startDrawing();
1975  return 0;
1976 }
1977 
1978 
1979 long
1981  stopDrawing();
1982  return 0;
1983 }
1984 
1985 
1986 long
1988  abortDrawing();
1989  return 0;
1990 }
1991 
1992 // ---------------------------------------------------------------------------
1993 // GNEFrameAttributesModuls::NeteditAttributes- methods
1994 // ---------------------------------------------------------------------------
1995 
1997  FXGroupBox(frameParent->myContentFrame, "Netedit attributes", GUIDesignGroupBoxFrame),
1998  myFrameParent(frameParent),
1999  myCurrentLengthValid(true),
2000  myActualAdditionalReferencePoint(GNE_ADDITIONALREFERENCEPOINT_LEFT) {
2001  // Create FXListBox for the reference points and fill it
2003  myReferencePointMatchBox->appendItem("reference left");
2004  myReferencePointMatchBox->appendItem("reference right");
2005  myReferencePointMatchBox->appendItem("reference center");
2006  // Create Frame for Length Label and textField
2007  FXHorizontalFrame* lengthFrame = new FXHorizontalFrame(this, GUIDesignAuxiliarHorizontalFrame);
2008  myLengthLabel = new FXLabel(lengthFrame, toString(SUMO_ATTR_LENGTH).c_str(), 0, GUIDesignLabelAttribute);
2009  myLengthTextField = new FXTextField(lengthFrame, GUIDesignTextFieldNCol, this, MID_GNE_SET_ATTRIBUTE, GUIDesignTextField);
2010  myLengthTextField->setText("10");
2011  // Create Frame for block movement label and checkBox (By default disabled)
2012  FXHorizontalFrame* blockMovement = new FXHorizontalFrame(this, GUIDesignAuxiliarHorizontalFrame);
2013  myBlockMovementLabel = new FXLabel(blockMovement, "block move", 0, GUIDesignLabelAttribute);
2014  myBlockMovementCheckButton = new FXCheckButton(blockMovement, "false", this, MID_GNE_SET_ATTRIBUTE, GUIDesignCheckButton);
2015  myBlockMovementCheckButton->setCheck(false);
2016  // Create Frame for block shape label and checkBox (By default disabled)
2017  FXHorizontalFrame* blockShapeFrame = new FXHorizontalFrame(this, GUIDesignAuxiliarHorizontalFrame);
2018  myBlockShapeLabel = new FXLabel(blockShapeFrame, "block shape", 0, GUIDesignLabelAttribute);
2019  myBlockShapeCheckButton = new FXCheckButton(blockShapeFrame, "false", this, MID_GNE_SET_ATTRIBUTE, GUIDesignCheckButton);
2020  // Create Frame for block close polygon and checkBox (By default disabled)
2021  FXHorizontalFrame* closePolygonFrame = new FXHorizontalFrame(this, GUIDesignAuxiliarHorizontalFrame);
2022  myClosePolygonLabel = new FXLabel(closePolygonFrame, "Close shape", 0, GUIDesignLabelAttribute);
2023  myCloseShapeCheckButton = new FXCheckButton(closePolygonFrame, "false", this, MID_GNE_SET_ATTRIBUTE, GUIDesignCheckButton);
2024  myBlockShapeCheckButton->setCheck(false);
2025  // Create help button
2026  helpReferencePoint = new FXButton(this, "Help", 0, this, MID_HELP, GUIDesignButtonRectangular);
2027  // Set visible items
2028  myReferencePointMatchBox->setNumVisible((int)myReferencePointMatchBox->getNumItems());
2029 }
2030 
2031 
2033 
2034 
2035 void
2037  // we assume that frame will not be show
2038  bool showFrame = false;
2039  // check if lenght text field has to be showed
2040  if (tagProperty.canMaskStartEndPos()) {
2041  myLengthLabel->show();
2042  myLengthTextField->show();
2043  myReferencePointMatchBox->show();
2044  showFrame = true;
2045  } else {
2046  myLengthLabel->hide();
2047  myLengthTextField->hide();
2048  myReferencePointMatchBox->hide();
2049  }
2050  // check if block movement check button has to be show
2051  if (tagProperty.canBlockMovement()) {
2052  myBlockMovementLabel->show();
2054  showFrame = true;
2055  } else {
2056  myBlockMovementLabel->hide();
2058  }
2059  // check if block shape check button has to be show
2060  if (tagProperty.canBlockShape()) {
2061  myBlockShapeLabel->show();
2062  myBlockShapeCheckButton->show();
2063  showFrame = true;
2064  } else {
2065  myBlockShapeLabel->hide();
2066  myBlockShapeCheckButton->hide();
2067  }
2068  // check if close shape check button has to be show
2069  if (tagProperty.canCloseShape()) {
2070  myClosePolygonLabel->show();
2071  myCloseShapeCheckButton->show();
2072  showFrame = true;
2073  } else {
2074  myClosePolygonLabel->hide();
2075  myCloseShapeCheckButton->hide();
2076  }
2077  // if at least one element is show, show modul
2078  if (showFrame) {
2079  show();
2080  } else {
2081  hide();
2082  }
2083 }
2084 
2085 
2086 void
2088  hide();
2089 }
2090 
2091 
2092 bool
2093 GNEFrameAttributesModuls::NeteditAttributes::getNeteditAttributesAndValues(std::map<SumoXMLAttr, std::string>& valuesMap, const GNELane* lane) const {
2094  // check if we need to obtain a start and end position over an edge
2095  if (myReferencePointMatchBox->shown()) {
2096  // we need a valid lane to calculate position over lane
2097  if (lane == nullptr) {
2098  return false;
2099  } else if (myCurrentLengthValid) {
2100  // Obtain position of the mouse over lane (limited over grid)
2102  // check if current reference point is valid
2104  std::string errorMessage = "Current selected reference point isn't valid";
2105  myFrameParent->myViewNet->setStatusBarText(errorMessage);
2106  // Write Warning in console if we're in testing mode
2107  WRITE_DEBUG(errorMessage);
2108  return false;
2109  } else {
2110  // obtain lenght
2111  double lenght = GNEAttributeCarrier::parse<double>(myLengthTextField->getText().text());
2112  // set start and end position
2113  valuesMap[SUMO_ATTR_STARTPOS] = toString(setStartPosition(mousePositionOverLane, lenght));
2114  valuesMap[SUMO_ATTR_ENDPOS] = toString(setEndPosition(mousePositionOverLane, lenght));
2115  }
2116  } else {
2117  return false;
2118  }
2119  }
2120  // Save block value if element can be blocked
2121  if (myBlockMovementCheckButton->shown()) {
2122  if (myBlockMovementCheckButton->getCheck() == 1) {
2123  valuesMap[GNE_ATTR_BLOCK_MOVEMENT] = "1";
2124  } else {
2125  valuesMap[GNE_ATTR_BLOCK_MOVEMENT] = "0";
2126  }
2127  }
2128  // Save block shape value if shape's element can be blocked
2129  if (myBlockShapeCheckButton->shown()) {
2130  if (myBlockShapeCheckButton->getCheck() == 1) {
2131  valuesMap[GNE_ATTR_BLOCK_SHAPE] = "1";
2132  } else {
2133  valuesMap[GNE_ATTR_BLOCK_SHAPE] = "0";
2134  }
2135  }
2136  // Save close shape value if shape's element can be closed
2137  if (myCloseShapeCheckButton->shown()) {
2138  if (myCloseShapeCheckButton->getCheck() == 1) {
2139  valuesMap[GNE_ATTR_CLOSE_SHAPE] = "1";
2140  } else {
2141  valuesMap[GNE_ATTR_CLOSE_SHAPE] = "0";
2142  }
2143  }
2144  // all ok, then return true to continue creating element
2145  return true;
2146 }
2147 
2148 
2149 long
2151  if (obj == myBlockMovementCheckButton) {
2152  if (myBlockMovementCheckButton->getCheck()) {
2153  myBlockMovementCheckButton->setText("true");
2154  } else {
2155  myBlockMovementCheckButton->setText("false");
2156  }
2157  } else if (obj == myBlockShapeCheckButton) {
2158  if (myBlockShapeCheckButton->getCheck()) {
2159  myBlockShapeCheckButton->setText("true");
2160  } else {
2161  myBlockShapeCheckButton->setText("false");
2162  }
2163  } else if (obj == myCloseShapeCheckButton) {
2164  if (myCloseShapeCheckButton->getCheck()) {
2165  myCloseShapeCheckButton->setText("true");
2166  } else {
2167  myCloseShapeCheckButton->setText("false");
2168  }
2169  } else if (obj == myLengthTextField) {
2170  // change color of text field depending of the input length
2171  if (GNEAttributeCarrier::canParse<double>(myLengthTextField->getText().text()) &&
2172  GNEAttributeCarrier::parse<double>(myLengthTextField->getText().text()) > 0) {
2173  myLengthTextField->setTextColor(FXRGB(0, 0, 0));
2174  myLengthTextField->killFocus();
2175  myCurrentLengthValid = true;
2176  } else {
2177  myLengthTextField->setTextColor(FXRGB(255, 0, 0));
2178  myCurrentLengthValid = false;
2179  }
2180  // Update aditional frame
2181  update();
2182  } else if (obj == myReferencePointMatchBox) {
2183  // Cast actual reference point type
2184  if (myReferencePointMatchBox->getText() == "reference left") {
2185  myReferencePointMatchBox->setTextColor(FXRGB(0, 0, 0));
2187  myLengthTextField->enable();
2188  } else if (myReferencePointMatchBox->getText() == "reference right") {
2189  myReferencePointMatchBox->setTextColor(FXRGB(0, 0, 0));
2191  myLengthTextField->enable();
2192  } else if (myReferencePointMatchBox->getText() == "reference center") {
2193  myLengthTextField->enable();
2194  myReferencePointMatchBox->setTextColor(FXRGB(0, 0, 0));
2196  myLengthTextField->enable();
2197  } else {
2198  myReferencePointMatchBox->setTextColor(FXRGB(255, 0, 0));
2200  myLengthTextField->disable();
2201  }
2202  }
2203 
2204  return 1;
2205 }
2206 
2207 
2208 long
2210  // Create dialog box
2211  FXDialogBox* additionalNeteditAttributesHelpDialog = new FXDialogBox(this, "Netedit Parameters Help", GUIDesignDialogBox);
2212  additionalNeteditAttributesHelpDialog->setIcon(GUIIconSubSys::getIcon(ICON_MODEADDITIONAL));
2213  // set help text
2214  std::ostringstream help;
2215  help
2216  << "- Referece point: Mark the initial position of the additional element.\n"
2217  << " Example: If you want to create a busStop with a length of 30 in the point 100 of the lane:\n"
2218  << " - Reference Left will create it with startPos = 70 and endPos = 100.\n"
2219  << " - Reference Right will create it with startPos = 100 and endPos = 130.\n"
2220  << " - Reference Center will create it with startPos = 85 and endPos = 115.\n"
2221  << "\n"
2222  << "- Block movement: if is enabled, the created additional element will be blocked. i.e. cannot be moved with\n"
2223  << " the mouse. This option can be modified inspecting element.";
2224  // Create label with the help text
2225  new FXLabel(additionalNeteditAttributesHelpDialog, help.str().c_str(), 0, GUIDesignLabelFrameInformation);
2226  // Create horizontal separator
2227  new FXHorizontalSeparator(additionalNeteditAttributesHelpDialog, GUIDesignHorizontalSeparator);
2228  // Create frame for OK Button
2229  FXHorizontalFrame* myHorizontalFrameOKButton = new FXHorizontalFrame(additionalNeteditAttributesHelpDialog, GUIDesignAuxiliarHorizontalFrame);
2230  // Create Button Close (And two more horizontal frames to center it)
2231  new FXHorizontalFrame(myHorizontalFrameOKButton, GUIDesignAuxiliarHorizontalFrame);
2232  new FXButton(myHorizontalFrameOKButton, "OK\t\tclose", GUIIconSubSys::getIcon(ICON_ACCEPT), additionalNeteditAttributesHelpDialog, FXDialogBox::ID_ACCEPT, GUIDesignButtonOK);
2233  new FXHorizontalFrame(myHorizontalFrameOKButton, GUIDesignAuxiliarHorizontalFrame);
2234  // Write Warning in console if we're in testing mode
2235  WRITE_DEBUG("Opening NeteditAttributes help dialog");
2236  // create Dialog
2237  additionalNeteditAttributesHelpDialog->create();
2238  // show in the given position
2239  additionalNeteditAttributesHelpDialog->show(PLACEMENT_CURSOR);
2240  // refresh APP
2241  getApp()->refresh();
2242  // open as modal dialog (will block all windows until stop() or stopModal() is called)
2243  getApp()->runModalFor(additionalNeteditAttributesHelpDialog);
2244  // Write Warning in console if we're in testing mode
2245  WRITE_DEBUG("Closing NeteditAttributes help dialog");
2246  return 1;
2247  /**********
2248  help from PolygonFrame
2249  << "- Block movement: If enabled, the created polygon element will be blocked. i.e. cannot be moved with\n"
2250  << " the mouse. This option can be modified inspecting element.\n"
2251  << "\n"
2252  << "- Block shape: If enabled, the shape of created polygon element will be blocked. i.e. their geometry points\n"
2253  << " cannot be edited be moved with the mouse. This option can be modified inspecting element.\n"
2254  << "\n"
2255  << "- Close shape: If enabled, the created polygon element will be closed. i.e. the last created geometry point\n"
2256  << " will be connected with the first geometry point automatically. This option can be modified inspecting element.";
2257 
2258  ****************/
2259 }
2260 
2261 
2262 double
2263 GNEFrameAttributesModuls::NeteditAttributes::setStartPosition(double positionOfTheMouseOverLane, double lengthOfAdditional) const {
2266  return positionOfTheMouseOverLane;
2268  return positionOfTheMouseOverLane - lengthOfAdditional;
2270  return positionOfTheMouseOverLane - lengthOfAdditional / 2;
2271  default:
2272  throw InvalidArgument("Reference Point invalid");
2273  }
2274 }
2275 
2276 
2277 double
2278 GNEFrameAttributesModuls::NeteditAttributes::setEndPosition(double positionOfTheMouseOverLane, double lengthOfAdditional) const {
2281  return positionOfTheMouseOverLane + lengthOfAdditional;
2283  return positionOfTheMouseOverLane;
2285  return positionOfTheMouseOverLane + lengthOfAdditional / 2;
2286  default:
2287  throw InvalidArgument("Reference Point invalid");
2288  }
2289 }
2290 
2291 /****************************************************************************/
std::string getGenericParametersStr() const
get generic parameters as string
double setStartPosition(double positionOfTheMouseOverLane, double lengthOfAdditional) const
obtain the Start position values of StoppingPlaces and E2 detector over the lane
bool isPersonStop() const
return true if tag correspond to a person stop element
bool hasAttrRange() const
return true if Attr correspond to an element that only accept a range of values
bool getDeleteLastCreatedPoint()
get flag delete last created point
void destroy()
destroy AttributesCreatorRow (but don&#39;t delete)
const bool myMultiple
flag to check if input element contains multiple values
const std::string & getAttrStr() const
get XML Attribute
#define GUIDesignComboBoxNCol
number of column of every combo box
Definition: GUIDesigns.h:233
Position snapToActiveGrid(const Position &pos, bool snapXY=true) const
Returns a position that is mapped to the closest grid point if the grid is active.
static RGBColor parseColor(std::string coldef)
Parses a color information.
Definition: RGBColor.cpp:177
FXRadioButton * myAttributeRadioButton
Radio button for disjoint attributes.
#define GUIDesignCheckButtonAttribute
checkButton without thick extended over the frame used for attributes
Definition: GUIDesigns.h:134
long long int SUMOTime
Definition: SUMOTime.h:35
#define GUIDesignButtonAttribute
button extended over over column with thick and raise frame
Definition: GUIDesigns.h:69
description of a vehicle type
static bool parseArrivalPosLat(const std::string &val, const std::string &element, const std::string &id, double &pos, ArrivalPosLatDefinition &apd, std::string &error)
Validates a given arrivalPosLat value.
attribute selected using a radio button
Definition: GUIAppEnum.h:647
PositionVector shape
The shape of the netElement element.
Definition: GNENetElement.h:57
stop drawing polygon
Definition: GUIAppEnum.h:667
FXCheckButton * myBlockShapeCheckButton
checkBox for block shape
void destroy()
destroy AttributesCreatorRow (but don&#39;t delete)
long onCmdSelectCheckButton(FXObject *, FXSelector, void *)
called when user press a check button
std::string next()
returns the next substring when it exists. Otherwise the behaviour is undefined
static bool isValidAttribute(const std::string &value)
whether the given string is a valid attribute for a certain key (for example, a name) ...
static bool isValidListOfTypeID(const std::string &value)
whether the given string is a valid list of ids for an edge or vehicle type (empty aren&#39;t allowed) ...
AttributesCreator * myAttributesCreatorParent
pointer to AttributesCreator
begin/end of the description of a junction
PositionVector myTemporalShapeShape
current drawed shape
bool isStop() const
return true if tag correspond to a stop element
void update() const
Mark the entire GNEViewNet to be repainted later.
Definition: GNEViewNet.cpp:292
void showGenericParametersEditor(GNEAttributeCarrier *AC)
show netedit attributes editor (used for edit generic parameters of an existent AC) ...
a flow definitio nusing a from-to edges instead of a route (used by router)
block shape of a graphic element (Used mainly in GNEShapes)
const GNEAttributeCarrier::AttributeProperties myACAttr
current AC Attribute
FXCheckButton * myValueCheckButton
pointer to menu check
ArrivalLaneDefinition
Possible ways to choose the arrival lane.
const AttributeProperties & getAttributeProperties(SumoXMLAttr attr) const
get attribute (throw error if doesn&#39;t exist)
long onCmdSelectRadioButton(FXObject *, FXSelector, void *)
called when user press a radio button
FXLabel * myBlockShapeLabel
Label for block shape.
bool isDemandElement() const
return true if tag correspond to a demand element
a flow definition nusing a route instead of a from-to edges route (used in NETEDIT) ...
#define GUIDesignComboBoxAttribute
Combo box static (cannot be edited) extended over the matrix column.
Definition: GUIDesigns.h:227
bool isCombinable() const
return true if atribute is combinable with other Attribute
std::string checkComplexAttribute(const std::string &value)
check if given complex attribute is valid
void setAttributeRadioButtonCheck(bool value)
enable or disable radio button for disjoint attributes
connectio between two lanes
long onCmdSelectRadioButton(FXObject *, FXSelector, void *)
set new disjoint attribute
virtual void attributesEditorExtendedDialogOpened()
open AttributesCreator extended dialog (can be reimplemented in frame children)
Definition: GNEFrame.cpp:191
static RGBColor getRGBColor(FXColor col)
converts FXColor to RGBColor
Definition: MFXUtils.cpp:108
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
void showAttributesCreatorModul(const GNEAttributeCarrier::TagProperties &myTagProperties)
show AttributesCreator modul
struct with the attribute Properties
bool isFilename() const
return true if atribute is a filename
bool isPositive() const
return true if atribute is positive
long onCmdAbortDrawing(FXObject *, FXSelector, void *)
Called when the user press abort drawing button.
std::vector< AttributesCreatorRow * > myAttributesCreatorRows
vector with the AttributesCreatorRow
FXTextField * myValueTextFieldStrings
textField to modify the default value of string parameters
bool isComplex() const
return true if atribute is complex
const std::string & getTagStr() const
get Tag vinculated with this attribute Property in String Format (used to avoid multiple calls to toS...
Close shape of a polygon (Used by GNEPolys)
weights: time range begin
link,node: the traffic light id responsible for this link
long onCmdSetAttribute(FXObject *, FXSelector, void *)
try to set new attribute value
long onCmdStopDrawing(FXObject *, FXSelector, void *)
Called when the user press stop drawing button.
bool canMaskStartEndPos() const
return true if tag correspond to an element that can mask the attributes "start" and "end" position a...
GNEFrame * myFrameParent
pointer to frame parent
This lane is powered by an underlying GNEEdge and basically knows how to draw itself.
Definition: GNELane.h:46
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:73
void hideNeteditAttributesModul()
hide Netedit attributes modul
const std::string DEFAULT_BIKETYPE_ID
AttributesEditor * myAttributesEditorParent
pointer to AttributesEditor parent
static const RGBColor BLACK
Definition: RGBColor.h:198
FXCheckButton * myBlockMovementCheckButton
checkBox for block movement
FXButton * myEditGenericParameterButton
button for add generic parameter
long onCmdSelectColorButton(FXObject *, FXSelector, void *)
called when user press the "Color" button
bool hasNext()
returns the information whether further substrings exist
AdditionalReferencePoint myActualAdditionalReferencePoint
actual additional reference point selected in the match Box
DepartPosLatDefinition
ArrivalPosLatDefinition
Possible ways to choose the departure position.
std::map< SumoXMLAttr, std::string > getAttributesAndValues(bool includeAll) const
get attributes and their values
FXButton * myAbortDrawingButton
button for abort drawing
virtual void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)=0
const std::string DEFAULT_VTYPE_ID
FXButton * myStartDrawingButton
button for start drawing
virtual std::string getAttribute(SumoXMLAttr key) const =0
FXDEFMAP(GNEFrameAttributesModuls::AttributesCreatorRow) RowCreatorMap[]
static bool isValidGenericParameterKey(const std::string &value)
whether the given string is a valid key for a generic parameter
virtual std::vector< std::pair< std::string, std::string > > getGenericParameters() const =0
return generic parameters as vector of pairs format
bool hasStaticDefaultValue() const
return true if attribute owns a static default value
int getPositionListed() const
get position in list (used in frames for listing attributes with certain sort)
generic attribute
bool isProbability() const
return true if atribute is a probability
bool isNonEditable() const
return true if atribute isn&#39;t editable
FXButton * helpReferencePoint
Button for help about the reference point.
FXLabel * myClosePolygonLabel
Label for open/close polygon.
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:239
GNEFrame * myFrameParent
pointer to Frame Parent
bool areValuesValid() const
check if parameters of attributes are valid
bool isInt() const
return true if atribute is an integer
#define GUIDesignComboBox
Definition: GUIDesigns.h:221
GNEViewNet * myViewNet
View Net.
Definition: GNEFrame.h:120
FXTextField * myValueTextFieldReal
textField to modify the value of real/Time attributes
bool isColor() const
return true if atribute is a color
Dialog for edit generic parameters.
const PositionVector & getTemporalShape() const
get Temporal shape
void showNeteditAttributesModul(const GNEAttributeCarrier::TagProperties &tagValue)
show Netedit attributes modul
static const size_t MAXNUMBEROFATTRIBUTES
max number of attributes allowed for every tag
const GNEAttributeCarrier::AttributeProperties myAttrProperties
attribute properties
GNEFrame * myFrameParent
pointer to GNEFrame parent
GNEUndoList * getUndoList() const
get the undoList object
Definition: GNEViewNet.cpp:933
bool canBlockMovement() const
return true if tag correspond to an element that can block their movement
static const int InvalidTlIndex
Definition: NBConnection.h:120
std::vector< std::pair< std::string, std::string > > * myGenericParameters
pointer to current vector of generic parameters
GNEAttributeCarrier::TagProperties getCurrentTagProperties() const
get current edited Tag Properties
long onCmdHelp(FXObject *, FXSelector, void *)
FXTextField * myValueTextFieldStrings
textField to modify the value of string attributes
std::string stripWhitespaceAfterComma(const std::string &stringValue)
removed invalid spaces of Positions and shapes
static bool isValidGenericParameterValue(const std::string &value)
whether the given string is a valid value for a generic parameter
DepartLaneDefinition
Possible ways to choose a lane on depart.
#define GUIDesignHorizontalSeparator
Definition: GUIDesigns.h:337
GNEAttributeCarrier * myAC
edited Attribute Carrier
start drawing polygon
Definition: GUIAppEnum.h:665
#define GUIDesignTextField
Definition: GUIDesigns.h:34
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:48
double getMaximumRange() const
get maximum range
SumoXMLTag getTag() const
get Tag vinculated with this attribute Property
long onCmdSetGenericParameter(FXObject *, FXSelector, void *)
Called when user udpate the generic parameter text field.
long onCmdSetAttribute(FXObject *, FXSelector, void *)
void refreshAttributeEditor(bool forceRefreshShape, bool forceRefreshPosition)
refresh attribute editor (only the valid values will be refresh)
FXTextField * myValueTextFieldInt
textField to modify the default value of int/float/string parameters
help button
Definition: GUIAppEnum.h:536
const TagProperties & getTagPropertyParent() const
get reference to tagProperty parent
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:39
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:80
bool isBool() const
return true if atribute is boolean
#define GUIDesignCheckButton
checkButton placed in left position
Definition: GUIDesigns.h:131
#define GUIDesignAuxiliarHorizontalFrame
design for auxiliar (Without borders) horizontal frame used to pack another frames ...
Definition: GUIDesigns.h:289
FXCheckButton * myCloseShapeCheckButton
checkbox to enable/disable closing polygon
double getMinimumRange() const
get minimum range
A list of positions.
Supermode currentSupermode
the current supermode
static bool isGenericParametersValid(const std::string &value)
check if given string can be parsed to a map/list of generic parameters
bool isAttributesEditorRowValid() const
check if current attribute of TextField/ComboBox is valid
long onCmdAttributesEditorHelp(FXObject *, FXSelector, void *)
bool canCloseShape() const
return true if tag correspond to an element that can close their shape
SumoXMLAttr getAttr() const
get XML Attribute
static int getTextureID(const std::string &filename, const bool mirrorX=false)
return texture id for the given filename (initialize on first use)
block movement of a graphic element
std::vector< GNEAttributeCarrier * > myEditedACs
the multi-selection currently being inspected
long onCmdEditGenericParameter(FXObject *, FXSelector, void *)
invalid attribute
double getLengthGeometryFactor() const
get length geometry factor
Definition: GNELane.cpp:1355
double setEndPosition(double positionOfTheMouseOverLane, double lengthOfAdditional) const
obtain the End position values of StoppingPlaces and E2 detector over the lane
attribute edited trought dialog
Definition: GUIAppEnum.h:645
bool myCurrentLengthValid
Flag to check if current length is valid.
bool myIncludeExtended
flag used to mark if current edited ACs are bein edited including extended attribute ...
edge: the shape in xml-definition
FXCheckButton * myAttributeCheckButton
check button to enable/disable Label attribute
bool isEnablitable() const
return true if atribute is enablitable
void showAttributeEditorModul(const std::vector< GNEAttributeCarrier *> &ACs, bool includeExtended)
show attributes of multiple ACs
static bool parseArrivalLane(const std::string &val, const std::string &element, const std::string &id, int &lane, ArrivalLaneDefinition &ald, std::string &error)
Validates a given arrivalLane value.
GNEAttributeCarrier::TagProperties myTagProperties
current edited Tag Properties
const NetElementGeometry & getGeometry() const
#define WRITE_DEBUG(msg)
Definition: MsgHandler.h:246
virtual bool shapeDrawed()
build a shaped element using the drawed shape (can be reimplemented in frame children) ...
Definition: GNEFrame.cpp:178
AttributesCreator * getAttributesCreatorParent() const
get AttributesCreator parent
#define GUIDesignLabelFrameInformation
label extended over frame without thick and with text justify to left, used to show information in fr...
Definition: GUIDesigns.h:210
void hideGenericParametersEditor()
hide netedit attributes editor
FXButton * myAttributeButtonCombinableChoices
pointer to buttonCombinableChoices
abort drawing polygon
Definition: GUIAppEnum.h:669
Dialog for edit rerouters.
FXLabel * myInformationLabel
Label with information.
#define GUIDesignButtonRectangular
little button rectangular (46x23) used in frames (For example, in "help" buttons) ...
Definition: GUIDesigns.h:72
FXRadioButton * myAttributeRadioButton
Radio button for disjoint attributes.
long onCmdHelp(FXObject *, FXSelector, void *)
Called when user press the help button.
FXLabel * myAttributeLabel
pointer to attribute label
DepartSpeedDefinition
Possible ways to choose the departure speed.
const std::string & isAttributeValid() const
returns a empty string if current value is valid, a string with information about invalid value in ot...
bool getNeteditAttributesAndValues(std::map< SumoXMLAttr, std::string > &valuesMap, const GNELane *lane) const
fill valuesMap with netedit attributes
long onCmdOpenAttributeDialog(FXObject *, FXSelector, void *)
open model dialog for more comfortable attribute editing
#define GUIDesignTextFieldNCol
Num of column of text field.
Definition: GUIDesigns.h:58
static bool canParse(const std::string &string)
true if a value of type T can be parsed from string
static std::string replace(std::string str, const char *what, const char *by)
FXCheckButton * myAttributeCheckButton
pointer to attribute menu check
bool isDiscrete() const
return true if atribute is discrete
void addNewPoint(const Position &P)
add new point to temporal shape
#define GUIDesignButton
Definition: GUIDesigns.h:66
FXTextField * myTextFieldGenericParameter
text field for write generic parameter
long onCmdStartDrawing(FXObject *, FXSelector, void *)
FXCheckButton * myValueCheckButton
check button to enable/disable the value of boolean parameters
bool isFloat() const
return true if atribute is a float
#define GUIDesignDialogBox
Definition: GUIDesigns.h:449
FXTextField * myLengthTextField
textField for length
static bool parsePersonModes(const std::string &modes, const std::string &element, const std::string &id, SVCPermissions &modeSet, std::string &error)
Validates a given person modes value.
void removeEditedAC(GNEAttributeCarrier *AC)
remove edited ACs
std::vector< GNEAttributeCarrier * > myACs
list of edited ACs
GNEFrame * getFrameParent() const
pointer to GNEFrame parent
#define GUIDesignGroupBoxFrame
Group box design extended over frame.
Definition: GUIDesigns.h:255
const std::string DEFAULT_PEDTYPE_ID
bool isDrawing() const
return true if currently a shape is drawed
static bool parseDepartPos(const std::string &val, const std::string &element, const std::string &id, double &pos, DepartPosDefinition &dpd, std::string &error)
Validates a given departPos value.
struct with the attribute Properties
GNEFrame * myFrameParent
pointer to frame parent
const std::vector< std::string > & getDiscreteValues() const
get discrete values
FXTextField * myValueTextFieldReal
textField to modify the default value of real/times parameters
weights: time range end
Demanding mode (Routes, Vehicles etc..)
static bool parseDepartPosLat(const std::string &val, const std::string &element, const std::string &id, double &pos, DepartPosLatDefinition &dpd, std::string &error)
Validates a given departPosLat value.
static bool parseArrivalSpeed(const std::string &val, const std::string &element, const std::string &id, double &speed, ArrivalSpeedDefinition &asd, std::string &error)
Validates a given arrivalSpeed value.
bool isAttributesCreatorRowEnabled() const
check if row is enabled
void setDeleteLastCreatedPoint(bool value)
enable or disable delete last created point
FXLabel * myBlockMovementLabel
Label for block movement.
void refreshGenericParametersEditor()
refresh netedit attributes
FXComboBox * myValueComboBoxChoices
pointer to combo box choices
static bool parseArrivalPos(const std::string &val, const std::string &element, const std::string &id, double &pos, ArrivalPosDefinition &apd, std::string &error)
Validates a given arrivalPos value.
#define GUIDesignTextFieldInt
text field extended over Frame with thick frame and limited to Integers
Definition: GUIDesigns.h:37
static bool parseDepartSpeed(const std::string &val, const std::string &element, const std::string &id, double &speed, DepartSpeedDefinition &dsd, std::string &error)
Validates a given departSpeed value.
void showWarningMessage(std::string extra="") const
show warning message with information about non-valid attributes
void refreshAttributesEditorRow(const std::string &value, bool forceRefresh, bool disjointAttributeEnabled)
refresh current row
long onCmdSelectCheckButton(FXObject *, FXSelector, void *)
called when user press a check button
#define GUIDesignTextFieldReal
text field extended over Frame with thick frame and limited to doubles/floats
Definition: GUIDesigns.h:40
static FXColor getFXColor(const RGBColor &col)
converts FXColor to RGBColor
Definition: MFXUtils.cpp:114
bool isSUMOTime() const
return true if atribute is a SUMOTime
const GNEAttributeCarrier::AttributeProperties & getAttrProperties() const
return Attr
FXButton * myStopDrawingButton
button for stop drawing
attribute edited
Definition: GUIAppEnum.h:619
#define GUIDesignButtonOK
Definition: GUIDesigns.h:114
void setStatusBarText(const std::string &text)
set staturBar text
Definition: GNEViewNet.cpp:482
const std::string & getDefaultValue() const
get default value
FXComboBox * myReferencePointMatchBox
match box with the list of reference points
const TagProperties & getTagProperty() const
get Tag Property assigned to this object
ArrivalPosDefinition
Possible ways to choose the arrival position.
Position getPositionInformation() const
Returns the cursor&#39;s x/y position within the network.
link: the index of the link within the traffic light
void updateDisjointAttributes(AttributesCreatorRow *row)
update disjoint attributes
void openHelpAttributesDialog(const GNEAttributeCarrier::TagProperties &tagProperties) const
Open help attributes dialog.
Definition: GNEFrame.cpp:197
void stopDrawing()
stop drawing and check if shape can be created
void showAttributesEditorExtendedModul()
show AttributesEditorExtended modul
virtual void attributeUpdated()
function called after set a valid attribute in AttributeCreator/AttributeEditor/GenericParametersEdit...
Definition: GNEFrame.cpp:185
ArrivalSpeedDefinition
Possible ways to choose the arrival speed.
bool getAttributeRadioButtonCheck() const
return status of radio button
bool attribute edited
Definition: GUIAppEnum.h:643
const GNEViewNetHelper::EditModes & getEditModes() const
get edit modes
Definition: GNEViewNet.cpp:399
#define GUIDesignLabelAttribute
label extended over the matrix column with thick frame and height of 23
Definition: GUIDesigns.h:186
bool myDeleteLastCreatedPoint
flag to enable/disable delete point mode
bool canBlockShape() const
return true if tag correspond to an element that can block their shape
DepartPosDefinition
Possible ways to choose the departure position.
#define GUIDesignRadioButtonAttribute
design for radio button with fixed height
Definition: GUIDesigns.h:158
double nearest_offset_to_point2D(const Position &p, bool perpendicular=true) const
return the nearest offest to point 2D
Network mode (Edges, junctions, etc..)
long onCmdSetNeteditAttribute(FXObject *, FXSelector, void *)
const std::vector< GNEAttributeCarrier * > & getEditedACs() const
get current edited ACs
void setAttributeCheckButtonCheck(bool value)
enable or disable label checkbox button for optional attributes
bool getAttributeCheckButtonCheck() const
return status of label checkbox button
static bool isValidFilename(const std::string &value)
whether the given string is a valid attribute for a filename (for example, a name) ...
static FXIcon * getIcon(GUIIcon which)
returns a icon previously defined in the enum GUIIcon
static bool isValidVehicleID(const std::string &value)
whether the given string is a valid id for a vehicle or flow
DepartDefinition
Possible ways to depart.
static bool parseDepart(const std::string &val, const std::string &element, const std::string &id, SUMOTime &depart, DepartDefinition &dd, std::string &error)
Validates a given depart value.
std::vector< AttributesEditorRow * > myAttributesEditorRows
list of Attribute editor rows
FXTextField * myValueTextFieldInt
textField to modify the value of int attributes
GNEFrame * myFrameParent
pointer to inspector frame parent
FXButton * myAttributeColorButton
Button for open color editor.
std::string myInvalidValue
string which indicates the reason due current value is invalid
static bool parseDepartLane(const std::string &val, const std::string &element, const std::string &id, int &lane, DepartLaneDefinition &dld, std::string &error)
Validates a given departLane value.
bool isOptional() const
return true if atribute is optional