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-2020 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
18 // Auxiliar class for GNEFrame Moduls (only for attributes edition)
19 /****************************************************************************/
20 #include <config.h>
21 
22 #include <netedit/GNENet.h>
23 #include <netedit/GNEUndoList.h>
24 #include <netedit/GNEViewNet.h>
33 
34 #include "GNEFrame.h"
36 
37 
38 // ===========================================================================
39 // FOX callback mapping
40 // ===========================================================================
41 
46 };
47 
50 };
51 
55 };
56 
61 };
62 
65 };
66 
70 };
71 
74 };
75 
79 };
80 
85 };
86 
90 };
91 
92 // Object implementation
93 FXIMPLEMENT(GNEFrameAttributesModuls::AttributesCreatorRow, FXHorizontalFrame, RowCreatorMap, ARRAYNUMBER(RowCreatorMap))
94 FXIMPLEMENT(GNEFrameAttributesModuls::AttributesCreator, FXGroupBox, AttributesCreatorMap, ARRAYNUMBER(AttributesCreatorMap))
95 FXIMPLEMENT(GNEFrameAttributesModuls::AttributesCreatorFlow, FXGroupBox, AttributesCreatorFlowMap, ARRAYNUMBER(AttributesCreatorFlowMap))
96 FXIMPLEMENT(GNEFrameAttributesModuls::AttributesEditorRow, FXHorizontalFrame, AttributesEditorRowMap, ARRAYNUMBER(AttributesEditorRowMap))
97 FXIMPLEMENT(GNEFrameAttributesModuls::AttributesEditor, FXGroupBox, AttributesEditorMap, ARRAYNUMBER(AttributesEditorMap))
98 FXIMPLEMENT(GNEFrameAttributesModuls::AttributesEditorFlow, FXGroupBox, AttributesEditorFlowMap, ARRAYNUMBER(AttributesEditorFlowMap))
99 FXIMPLEMENT(GNEFrameAttributesModuls::AttributesEditorExtended, FXGroupBox, AttributesEditorExtendedMap, ARRAYNUMBER(AttributesEditorExtendedMap))
100 FXIMPLEMENT(GNEFrameAttributesModuls::ParametersEditorCreator, FXGroupBox, ParametersEditorCreatorMap, ARRAYNUMBER(ParametersEditorCreatorMap))
101 FXIMPLEMENT(GNEFrameAttributesModuls::DrawingShape, FXGroupBox, DrawingShapeMap, ARRAYNUMBER(DrawingShapeMap))
102 FXIMPLEMENT(GNEFrameAttributesModuls::NeteditAttributes, FXGroupBox, NeteditAttributesMap, ARRAYNUMBER(NeteditAttributesMap))
103 
104 
105 // ===========================================================================
106 // method definitions
107 // ===========================================================================
108 
109 // ---------------------------------------------------------------------------
110 // GNEFrameAttributesModuls::AttributesCreatorRow - methods
111 // ---------------------------------------------------------------------------
112 
114  FXHorizontalFrame(AttributesCreatorParent, GUIDesignAuxiliarHorizontalFrame),
115  myAttributesCreatorParent(AttributesCreatorParent),
116  myAttrProperties(attrProperties) {
117  // Create left visual elements
118  myAttributeLabel = new FXLabel(this, "name", nullptr, GUIDesignLabelAttribute);
119  myAttributeLabel->hide();
120  myAttributeCheckButton = new FXCheckButton(this, "name", this, MID_GNE_SET_ATTRIBUTE_BOOL, GUIDesignCheckButtonAttribute);
121  myAttributeCheckButton->hide();
122  myAttributeColorButton = new FXButton(this, "ColorButton", nullptr, this, MID_GNE_SET_ATTRIBUTE_DIALOG, GUIDesignButtonAttribute);
123  myAttributeColorButton->hide();
124  // Create right visual elements
125  myValueTextField = new FXTextField(this, GUIDesignTextFieldNCol, this, MID_GNE_SET_ATTRIBUTE, GUIDesignTextField);
126  myValueTextField->hide();
127  myValueCheckButton = new FXCheckButton(this, "Disabled", this, MID_GNE_SET_ATTRIBUTE, GUIDesignCheckButton);
128  myValueCheckButton->hide();
129  // by default attribute check button is true (except for until)
130  if ((attrProperties.getTagPropertyParent().isStop() || attrProperties.getTagPropertyParent().isPersonStop()) && (attrProperties.getAttr() == SUMO_ATTR_UNTIL)) {
131  myAttributeCheckButton->setCheck(FALSE);
132  } else {
133  myAttributeCheckButton->setCheck(TRUE);
134  }
135  // only create if parent was created
136  if (getParent()->id()) {
137  // create AttributesCreatorRow
138  FXHorizontalFrame::create();
139  // reset invalid value
140  myInvalidValue = "";
141  // special case for attribute ID
142  if (attrProperties.getAttr() == SUMO_ATTR_ID) {
143  // show check button and disable it
144  myAttributeCheckButton->setText(myAttrProperties.getAttrStr().c_str());
145  myAttributeCheckButton->setCheck(false);
146  myAttributeCheckButton->show();
147  // show text field and disable it
148  myValueTextField->setTextColor(FXRGB(0, 0, 0));
149  myValueTextField->disable();
150  // generate ID
151  myValueTextField->setText(generateID().c_str());
152  // show textField
153  myValueTextField->show();
154  } else {
155  // show label, button for edit colors or radio button
156  if (myAttrProperties.isColor()) {
157  myAttributeColorButton->setTextColor(FXRGB(0, 0, 0));
158  myAttributeColorButton->setText(myAttrProperties.getAttrStr().c_str());
159  myAttributeColorButton->show();
160  } else if (myAttrProperties.isActivatable()) {
161  myAttributeCheckButton->setText(myAttrProperties.getAttrStr().c_str());
162  myAttributeCheckButton->show();
163  // special case for attributes "Parking", "until" and "duration" (by default disabled)
164  if ((myAttrProperties.getTagPropertyParent().isStop() || myAttrProperties.getTagPropertyParent().isPersonStop()) &&
165  (myAttrProperties.getAttr() == SUMO_ATTR_UNTIL || myAttrProperties.getAttr() == SUMO_ATTR_EXTENSION ||
166  myAttrProperties.getAttr() == SUMO_ATTR_PARKING)) {
167  myAttributeCheckButton->setCheck(FALSE);
168  } else {
169  myAttributeCheckButton->setCheck(TRUE);
170  }
171  } else {
172  myAttributeLabel->setText(myAttrProperties.getAttrStr().c_str());
173  myAttributeLabel->show();
174  }
175  if (myAttrProperties.isBool()) {
176  if (GNEAttributeCarrier::parse<bool>(attrProperties.getDefaultValue())) {
177  myValueCheckButton->setCheck(true);
178  myValueCheckButton->setText("true");
179  } else {
180  myValueCheckButton->setCheck(false);
181  myValueCheckButton->setText("false");
182  }
183  myValueCheckButton->show();
184  // if it's associated to a label button and is disabled, then disable myValueCheckButton
185  if (myAttributeCheckButton->shown() && (myAttributeCheckButton->getCheck() == FALSE)) {
186  myValueCheckButton->disable();
187  }
188  } else {
189  myValueTextField->setTextColor(FXRGB(0, 0, 0));
190  myValueTextField->setText(attrProperties.getDefaultValue().c_str());
191  myValueTextField->show();
192  // if it's associated to a label button and is disabled, then disable myValueTextField
193  if (myAttributeCheckButton->shown() && (myAttributeCheckButton->getCheck() == FALSE)) {
194  myValueTextField->disable();
195  }
196  }
197  }
198  // show AttributesCreatorRow
199  show();
200  }
201 }
202 
203 
204 void
206  // only destroy if parent was created
207  if (getParent()->id()) {
208  FXHorizontalFrame::destroy();
209  }
210 }
211 
212 
215  return myAttrProperties;
216 }
217 
218 
219 std::string
221  if (myAttrProperties.isBool()) {
222  return (myValueCheckButton->getCheck() == 1) ? "1" : "0";
223  } else {
224  return myValueTextField->getText().text();
225  }
226 }
227 
228 
229 bool
231  if (shown()) {
232  return myAttributeCheckButton->getCheck() == TRUE;
233  } else {
234  return false;
235  }
236 }
237 
238 
239 void
241  if (shown()) {
242  // set radio button
243  myAttributeCheckButton->setCheck(value);
244  // enable or disable input fields
245  if (value) {
246  if (myAttrProperties.isBool()) {
247  myValueCheckButton->enable();
248  } else {
249  myValueTextField->enable();
250  }
251  } else {
252  if (myAttrProperties.isBool()) {
253  myValueCheckButton->disable();
254  } else {
255  myValueTextField->disable();
256  }
257  }
258  }
259 }
260 
261 
262 void
264  if (myAttrProperties.isBool()) {
265  return myValueCheckButton->enable();
266  } else {
267  return myValueTextField->enable();
268  }
269 }
270 
271 
272 void
274  if (myAttrProperties.isBool()) {
275  return myValueCheckButton->disable();
276  } else {
277  return myValueTextField->disable();
278  }
279 }
280 
281 
282 bool
284  if (!shown()) {
285  return false;
286  } else if (myAttrProperties.isBool()) {
287  return myValueCheckButton->isEnabled();
288  } else {
289  return myValueTextField->isEnabled();
290  }
291 }
292 
293 
294 void
296  // currently only row with ID attribute must be updated
297  if (myAttrProperties.getAttr() == SUMO_ATTR_ID) {
298  myValueTextField->setText(generateID().c_str());
299  }
300 }
301 
302 
303 const std::string&
305  return myInvalidValue;
306 }
307 
308 
311  return myAttributesCreatorParent;
312 }
313 
314 
315 long
317  // We assume that current value is valid
318  myInvalidValue = "";
319  // Check if format of current value of myTextField is correct
320  if (obj == myValueCheckButton) {
321  if (myValueCheckButton->getCheck()) {
322  myValueCheckButton->setText("true");
323  } else {
324  myValueCheckButton->setText("false");
325  }
326  } else if (myAttrProperties.isComplex()) {
327  // check complex attribute
328  myInvalidValue = checkComplexAttribute(myValueTextField->getText().text());
329  } else if (myAttrProperties.isInt()) {
330  // first filter int attributes
331  if (GNEAttributeCarrier::canParse<double>(myValueTextField->getText().text())) {
332  // obtain parsed attribute
333  double parsedDouble = GNEAttributeCarrier::parse<double>(myValueTextField->getText().text());
334  // check if parsed double doesn't have decimal part (or is 0)
335  if ((parsedDouble - (int)parsedDouble) == 0) {
336  myValueTextField->setText(toString((int)parsedDouble).c_str(), FALSE);
337  // Check if int value must be positive
338  if (myAttrProperties.isPositive() && (parsedDouble < 0)) {
339  myInvalidValue = "'" + myAttrProperties.getAttrStr() + "' cannot be negative";
340  }
341  } else {
342  myInvalidValue = "'" + myAttrProperties.getAttrStr() + "' doesn't have a valid 'int' format";
343  }
344  } else {
345  myInvalidValue = "'" + myAttrProperties.getAttrStr() + "' doesn't have a valid 'int' format";
346  }
347 
348  } else if (myAttrProperties.getAttr() == SUMO_ATTR_ANGLE) {
349  if (GNEAttributeCarrier::canParse<double>(myValueTextField->getText().text())) {
350  // filter angle
351  double angle = GNEAttributeCarrier::parse<double>(myValueTextField->getText().text());
352  // filter if angle isn't between [0,360]
353  if ((angle < 0) || (angle > 360)) {
354  // apply modul
355  angle = fmod(angle, 360);
356  }
357  // update Textfield
358  myValueTextField->setText(toString(angle).c_str(), FALSE);
359  } else {
360  myInvalidValue = "'" + myAttrProperties.getAttrStr() + "' doesn't have a valid 'float' format between [0, 360]";
361  }
362  } else if (myAttrProperties.isSUMOTime()) {
363  // time attributes work as positive doubles
364  if (!GNEAttributeCarrier::canParse<SUMOTime>(myValueTextField->getText().text())) {
365  myInvalidValue = "'" + myAttrProperties.getAttrStr() + "' doesn't have a valid SUMOTime format";
366  }
367  } else if (myAttrProperties.isFloat()) {
368  if (GNEAttributeCarrier::canParse<double>(myValueTextField->getText().text())) {
369  // convert string to double
370  double doubleValue = GNEAttributeCarrier::parse<double>(myValueTextField->getText().text());
371  // Check if double value must be positive
372  if (myAttrProperties.isPositive() && (doubleValue < 0)) {
373  myInvalidValue = "'" + myAttrProperties.getAttrStr() + "' cannot be negative";
374  // check if double value is a probability
375  } else if (myAttrProperties.isProbability() && ((doubleValue < 0) || doubleValue > 1)) {
376  myInvalidValue = "'" + myAttrProperties.getAttrStr() + "' takes only values between 0 and 1";
377  } else if (myAttrProperties.hasAttrRange() && ((doubleValue < myAttrProperties.getMinimumRange()) || doubleValue > myAttrProperties.getMaximumRange())) {
378  myInvalidValue = "'" + myAttrProperties.getAttrStr() + "' takes only values between " + toString(myAttrProperties.getMinimumRange()) + " and " + toString(myAttrProperties.getMaximumRange());
379  } else if ((myAttributesCreatorParent->getCurrentTagProperties().getTag() == SUMO_TAG_E2DETECTOR) && (myAttrProperties.getAttr() == SUMO_ATTR_LENGTH) && (doubleValue == 0)) {
380  myInvalidValue = "E2 length cannot be 0";
381  }
382  } else {
383  myInvalidValue = "'" + myAttrProperties.getAttrStr() + "' doesn't have a valid 'float' format";
384  }
385  } else if (myAttrProperties.isColor()) {
386  // check if filename format is valid
387  if (GNEAttributeCarrier::canParse<RGBColor>(myValueTextField->getText().text()) == false) {
388  myInvalidValue = "'" + myAttrProperties.getAttrStr() + "' doesn't have a valid 'RBGColor' format";
389  }
390  } else if (myAttrProperties.isFilename()) {
391  const std::string file = myValueTextField->getText().text();
392  // check if filename format is valid
393  if (SUMOXMLDefinitions::isValidFilename(file) == false) {
394  myInvalidValue = "input contains invalid characters for a filename";
395  } else if (myAttrProperties.getAttr() == SUMO_ATTR_IMGFILE) {
396  if (!file.empty()) {
397  // only load value if file exist and can be loaded
398  if (GUITexturesHelper::getTextureID(file) == -1) {
399  myInvalidValue = "doesn't exist image '" + file + "'";
400  }
401  }
402  }
403  } else if (myAttrProperties.getAttr() == SUMO_ATTR_NAME) {
404  const std::string name = myValueTextField->getText().text();
405  // check if name format is valid
406  if (SUMOXMLDefinitions::isValidAttribute(name) == false) {
407  myInvalidValue = "input contains invalid characters";
408  }
409  } else if (myAttrProperties.getAttr() == SUMO_ATTR_VTYPES) {
410  const std::string types = myValueTextField->getText().text();
411  // if list of VTypes isn't empty, check that all characters are valid
412  if (!types.empty() && !SUMOXMLDefinitions::isValidListOfTypeID(types)) {
413  myInvalidValue = "list of IDs contains invalid characters";
414  }
415  } else if (myAttrProperties.getAttr() == SUMO_ATTR_INDEX) {
416  // special case for stop indx
417  const std::string index = myValueTextField->getText().text();
418  if ((index != "fit") && (index != "end") && !GNEAttributeCarrier::canParse<int>(index)) {
419  myInvalidValue = "index isn't either 'fit' or 'end' or a valid positive int";
420  } else if (GNEAttributeCarrier::canParse<int>(index) && (GNEAttributeCarrier::parse<int>(index) < 0)) {
421  myInvalidValue = "index cannot be negative";
422  }
423  } else if ((myAttrProperties.getAttr() == SUMO_ATTR_EXPECTED) || (myAttrProperties.getAttr() == SUMO_ATTR_EXPECTED_CONTAINERS)) {
424  // check if attribute can be parsed in a list of Ids
425  std::vector<std::string> vehicleIDs = GNEAttributeCarrier::parse<std::vector<std::string> >(myValueTextField->getText().text());
426  // check every ID
427  for (const auto& i : vehicleIDs) {
429  myInvalidValue = "invalid id used in " + myAttrProperties.getAttrStr();
430  }
431  }
432  } else if (myAttrProperties.getAttr() == SUMO_ATTR_TRIP_ID) {
433  if (!SUMOXMLDefinitions::isValidVehicleID(myValueTextField->getText().text())) {
434  myInvalidValue = "invalid id used in " + myAttrProperties.getAttrStr();
435  }
436  } else if (myAttrProperties.getAttr() == SUMO_ATTR_ID) {
437  // check ID depending of tag
438  if (myAttrProperties.getTagPropertyParent().isNetworkElement() && !SUMOXMLDefinitions::isValidNetID(myValueTextField->getText().text())) {
439  myInvalidValue = "invalid id used in " + myAttrProperties.getAttrStr();
440  } else if (myAttrProperties.getTagPropertyParent().isDetector() && !SUMOXMLDefinitions::isValidDetectorID(myValueTextField->getText().text())) {
441  myInvalidValue = "invalid id used in " + myAttrProperties.getAttrStr();
442  } else if (myAttrProperties.getTagPropertyParent().isAdditionalElement() && !SUMOXMLDefinitions::isValidNetID(myValueTextField->getText().text())) {
443  myInvalidValue = "invalid id used in " + myAttrProperties.getAttrStr();
444  } else if (myAttrProperties.getTagPropertyParent().isShape() && !SUMOXMLDefinitions::isValidTypeID(myValueTextField->getText().text())) {
445  myInvalidValue = "invalid id used in " + myAttrProperties.getAttrStr();
446  } else if (myAttrProperties.getTagPropertyParent().isDemandElement() && !SUMOXMLDefinitions::isValidVehicleID(myValueTextField->getText().text())) {
447  myInvalidValue = "invalid id used in " + myAttrProperties.getAttrStr();
448  }
449  } else if ((myAttrProperties.getAttr() == SUMO_ATTR_FREQUENCY) && myAttrProperties.getTagPropertyParent().isDetector()) {
450  if (!myValueTextField->getText().empty()) {
451  if (!GNEAttributeCarrier::canParse<double>(myValueTextField->getText().text())) {
452  myInvalidValue = "'" + myAttrProperties.getAttrStr() + "' doesn't have a valid 'float' or empty format";
453  } else if (GNEAttributeCarrier::parse<double>(myValueTextField->getText().text()) < 0) {
454  myInvalidValue = "'" + myAttrProperties.getAttrStr() + "' cannot be negative";
455  }
456  }
457  }
458  // change color of text field depending of myCurrentValueValid
459  if (myInvalidValue.size() == 0) {
460  myValueTextField->setTextColor(FXRGB(0, 0, 0));
461  myValueTextField->killFocus();
462  } else {
463  // IF value of TextField isn't valid, change their color to Red
464  myValueTextField->setTextColor(FXRGB(255, 0, 0));
465  }
466  // Update aditional frame
467  update();
468  return 1;
469 }
470 
471 
472 long
474  if (myAttributeCheckButton->getCheck()) {
475  // enable input values
476  myValueCheckButton->enable();
477  myValueTextField->enable();
478  // refresh row
479  refreshRow();
480  } else {
481  // disable input values
482  myValueCheckButton->disable();
483  myValueTextField->disable();
484  }
485  return 0;
486 }
487 
488 
489 long
491  // create FXColorDialog
492  FXColorDialog colordialog(this, tr("Color Dialog"));
493  colordialog.setTarget(this);
494  // If previous attribute wasn't correct, set black as default color
495  if (GNEAttributeCarrier::canParse<RGBColor>(myValueTextField->getText().text())) {
496  colordialog.setRGBA(MFXUtils::getFXColor(RGBColor::parseColor(myValueTextField->getText().text())));
497  } else {
498  colordialog.setRGBA(MFXUtils::getFXColor(RGBColor::parseColor(myAttrProperties.getDefaultValue())));
499  }
500  // execute dialog to get a new color
501  if (colordialog.execute()) {
502  myValueTextField->setText(toString(MFXUtils::getRGBColor(colordialog.getRGBA())).c_str());
503  onCmdSetAttribute(nullptr, 0, nullptr);
504  }
505  return 0;
506 }
507 
508 
509 std::string
511  // declare values needed to check if given complex parameters are valid
512  std::string errorMessage;
513  DepartDefinition dd;
522  SVCPermissions mode;
523  int valueInt;
524  double valueDouble;
525  SUMOTime valueSUMOTime;
526  // check complex attribute
527  switch (myAttrProperties.getAttr()) {
528  case SUMO_ATTR_DEPART:
529  case SUMO_ATTR_BEGIN:
530  SUMOVehicleParameter::parseDepart(value, myAttrProperties.getAttrStr(), "", valueSUMOTime, dd, errorMessage);
531  break;
533  SUMOVehicleParameter::parseDepartLane(value, myAttrProperties.getAttrStr(), "", valueInt, dld, errorMessage);
534  break;
535  case SUMO_ATTR_DEPARTPOS:
536  SUMOVehicleParameter::parseDepartPos(value, myAttrProperties.getAttrStr(), "", valueDouble, dpd, errorMessage);
537  break;
539  SUMOVehicleParameter::parseDepartSpeed(value, myAttrProperties.getAttrStr(), "", valueDouble, dsd, errorMessage);
540  break;
542  SUMOVehicleParameter::parseArrivalLane(value, myAttrProperties.getAttrStr(), "", valueInt, ald, errorMessage);
543  break;
545  SUMOVehicleParameter::parseArrivalPos(value, myAttrProperties.getAttrStr(), "", valueDouble, apd, errorMessage);
546  break;
548  SUMOVehicleParameter::parseArrivalSpeed(value, myAttrProperties.getAttrStr(), "", valueDouble, asd, errorMessage);
549  break;
551  SUMOVehicleParameter::parseDepartPosLat(value, myAttrProperties.getAttrStr(), "", valueDouble, dpld, errorMessage);
552  break;
554  SUMOVehicleParameter::parseArrivalPosLat(value, myAttrProperties.getAttrStr(), "", valueDouble, apld, errorMessage);
555  break;
556  case SUMO_ATTR_MODES:
557  SUMOVehicleParameter::parsePersonModes(value, myAttrProperties.getAttrStr(), "", mode, errorMessage);
558  break;
559  default:
560  throw ProcessError("Invalid complex attribute");
561  }
562  // return error message (Will be empty if value is valid)
563  return errorMessage;
564 }
565 
566 
567 std::string
569  if (myAttrProperties.getTagPropertyParent().isShape()) {
570  return myAttributesCreatorParent->getFrameParent()->getViewNet()->getNet()->generateShapeID(myAttrProperties.getTagPropertyParent().getTag());
571  } else if (myAttrProperties.getTagPropertyParent().isAdditionalElement()) {
572  return myAttributesCreatorParent->getFrameParent()->getViewNet()->getNet()->generateAdditionalID(myAttrProperties.getTagPropertyParent().getTag());
573  } else if (myAttrProperties.getTagPropertyParent().isDemandElement()) {
574  return myAttributesCreatorParent->getFrameParent()->getViewNet()->getNet()->generateDemandElementID(myAttrProperties.getTagPropertyParent().getTag());
575  } else {
576  return "";
577  }
578 }
579 
580 
581 bool
583  return (myAttributesCreatorParent->getFrameParent()->getViewNet()->getNet()->retrieveAdditional(
584  myAttrProperties.getTagPropertyParent().getTag(),
585  myValueTextField->getText().text(), false) == nullptr);
586 }
587 
588 // ---------------------------------------------------------------------------
589 // GNEFrameAttributesModuls::AttributesCreator - methods
590 // ---------------------------------------------------------------------------
591 
593  FXGroupBox(frameParent->myContentFrame, "Internal attributes", GUIDesignGroupBoxFrame),
594  myFrameParent(frameParent) {
595  // resize myAttributesCreatorRows
597  // create myAttributesCreatorFlow
599  // create help button
600  myHelpButton = new FXButton(this, "Help", nullptr, this, MID_HELP, GUIDesignButtonRectangular);
601 }
602 
603 
605 
606 
607 void
608 GNEFrameAttributesModuls::AttributesCreator::showAttributesCreatorModul(const GNETagProperties& tagProperties, const std::vector<SumoXMLAttr>& hiddenAttributes) {
609  // set current tag Properties
610  myTagProperties = tagProperties;
611  // first destroy all rows
612  for (int i = 0; i < (int)myAttributesCreatorRows.size(); i++) {
613  // destroy and delete all rows
614  if (myAttributesCreatorRows.at(i) != nullptr) {
615  myAttributesCreatorRows.at(i)->destroy();
616  delete myAttributesCreatorRows.at(i);
617  myAttributesCreatorRows.at(i) = nullptr;
618  }
619  }
620  // now declare a flag to show Flow editor
621  bool showFlowEditor = false;
622  // iterate over tag attributes and create AttributesCreatorRows for every attribute
623  for (const auto& i : myTagProperties) {
624  // declare falg to check conditions for show attribute
625  bool showAttribute = true;
626  // check that only non-unique attributes (except ID) are created (And depending of includeExtendedAttributes)
627  if (i.isUnique() && (i.getAttr() != SUMO_ATTR_ID)) {
628  showAttribute = false;
629  }
630  // check if attribute must stay hidden
631  if (std::find(hiddenAttributes.begin(), hiddenAttributes.end(), i.getAttr()) != hiddenAttributes.end()) {
632  showAttribute = false;
633  }
634  // check if attribute is a flow definitionattribute
635  if (i.isFlowDefinition()) {
636  showAttribute = false;
637  showFlowEditor = true;
638  }
639  // check special case for vaporizer IDs
640  if ((i.getAttr() == SUMO_ATTR_ID) && (i.getTagPropertyParent().getTag() == SUMO_TAG_VAPORIZER)) {
641  showAttribute = false;
642  }
643  // check special case for VType IDs in vehicle Frame
644  if ((i.getAttr() == SUMO_ATTR_TYPE) && (myFrameParent->getViewNet()->getEditModes().isCurrentSupermodeDemand()) &&
645  (myFrameParent->getViewNet()->getEditModes().demandEditMode == DemandEditMode::DEMAND_VEHICLE)) {
646  showAttribute = false;
647  }
648  // show attribute depending of showAttribute flag
649  if (showAttribute) {
650  myAttributesCreatorRows.at(i.getPositionListed()) = new AttributesCreatorRow(this, i);
651  }
652  }
653  // reparent help button (to place it at bottom)
654  myHelpButton->reparent(this);
655  // recalc
656  recalc();
657  // check if flow editor has to be shown
658  if (showFlowEditor) {
659  myAttributesCreatorFlow->showAttributesCreatorFlowModul(tagProperties.hasAttribute(SUMO_ATTR_PERSONSPERHOUR));
660  } else {
661  myAttributesCreatorFlow->hideAttributesCreatorFlowModul();
662  }
663  // show
664  show();
665 }
666 
667 
668 void
670  // hide attributes creator flow
671  myAttributesCreatorFlow->hideAttributesCreatorFlowModul();
672  // hide modul
673  hide();
674 }
675 
676 
677 GNEFrame*
679  return myFrameParent;
680 }
681 
682 
683 std::map<SumoXMLAttr, std::string>
685  std::map<SumoXMLAttr, std::string> values;
686  // get standard parameters
687  for (int i = 0; i < (int)myAttributesCreatorRows.size(); i++) {
688  if (myAttributesCreatorRows.at(i) && myAttributesCreatorRows.at(i)->getAttrProperties().getAttr() != SUMO_ATTR_NOTHING) {
689  // flag for row enabled
690  bool rowEnabled = myAttributesCreatorRows.at(i)->isAttributesCreatorRowEnabled();
691  // flag for default attributes
692  bool hasDefaultStaticValue = !myAttributesCreatorRows.at(i)->getAttrProperties().hasStaticDefaultValue() || (myAttributesCreatorRows.at(i)->getAttrProperties().getDefaultValue() != myAttributesCreatorRows.at(i)->getValue());
693  // flag for enablitables attributes
694  bool isFlowDefinitionAttribute = myAttributesCreatorRows.at(i)->getAttrProperties().isFlowDefinition();
695  // flag for optional attributes
696  bool isActivatableAttribute = myAttributesCreatorRows.at(i)->getAttrProperties().isActivatable() && myAttributesCreatorRows.at(i)->getAttributeCheckButtonCheck();
697  // check if flags configuration allow to include values
698  if (rowEnabled && (includeAll || hasDefaultStaticValue || isFlowDefinitionAttribute || isActivatableAttribute)) {
699  values[myAttributesCreatorRows.at(i)->getAttrProperties().getAttr()] = myAttributesCreatorRows.at(i)->getValue();
700  }
701  }
702  }
703  // add extra flow attributes (only will updated if myAttributesCreatorFlow is shown)
704  myAttributesCreatorFlow->setFlowParameters(values);
705  // return values
706  return values;
707 }
708 
709 
712  return myTagProperties;
713 }
714 
715 
716 void
718  std::string errorMessage;
719  // iterate over standar parameters
720  for (const auto& i : myTagProperties) {
721  if (errorMessage.empty() && myAttributesCreatorRows.at(i.getPositionListed())) {
722  // Return string with the error if at least one of the parameter isn't valid
723  std::string attributeValue = myAttributesCreatorRows.at(i.getPositionListed())->isAttributeValid();
724  if (attributeValue.size() != 0) {
725  errorMessage = attributeValue;
726  }
727  }
728  }
729  // show warning box if input parameters aren't invalid
730  if (extra.size() == 0) {
731  errorMessage = "Invalid input parameter of " + myTagProperties.getTagStr() + ": " + errorMessage;
732  } else {
733  errorMessage = "Invalid input parameter of " + myTagProperties.getTagStr() + ": " + extra;
734  }
735 
736  // set message in status bar
737  myFrameParent->myViewNet->setStatusBarText(errorMessage);
738  // Write Warning in console if we're in testing mode
739  WRITE_DEBUG(errorMessage);
740 }
741 
742 
743 bool
745  // iterate over standar parameters
746  for (auto i : myTagProperties) {
747  // Return false if error message of attriuve isn't empty
748  if (myAttributesCreatorRows.at(i.getPositionListed()) && myAttributesCreatorRows.at(i.getPositionListed())->isAttributeValid().size() != 0) {
749  return false;
750  }
751  }
752  return true;
753 }
754 
755 
756 void
758  // currently only row with attribute ID must be refresh
759  if (myTagProperties.hasAttribute(SUMO_ATTR_ID) && (myTagProperties.getTag() != SUMO_TAG_VAPORIZER)) {
760  myAttributesCreatorRows[myTagProperties.getAttributeProperties(SUMO_ATTR_ID).getPositionListed()]->refreshRow();
761  }
762 }
763 
764 long
766  // open Help attributes dialog
767  myFrameParent->openHelpAttributesDialog(myTagProperties);
768  return 1;
769 }
770 
771 // ---------------------------------------------------------------------------
772 // GNEFrameAttributesModuls::AttributesCreatorFlow - methods
773 // ---------------------------------------------------------------------------
774 
776  FXGroupBox(attributesCreatorParent->getFrameParent()->myContentFrame, "Flow attributes", GUIDesignGroupBoxFrame),
777  myAttributesCreatorParent(attributesCreatorParent),
778  myFlowParameters(VEHPARS_END_SET | VEHPARS_NUMBER_SET) {
779  // declare auxiliar horizontal frame
780  FXHorizontalFrame* auxiliarHorizontalFrame = nullptr;
781  // create elements for end attribute
782  auxiliarHorizontalFrame = new FXHorizontalFrame(this, GUIDesignAuxiliarHorizontalFrame);
783  myAttributeEndRadioButton = new FXRadioButton(auxiliarHorizontalFrame, toString(SUMO_ATTR_END).c_str(), this, MID_GNE_SET_ATTRIBUTE_BUTTON, GUIDesignRadioButtonAttribute);
784  myValueEndTextField = new FXTextField(auxiliarHorizontalFrame, GUIDesignTextFieldNCol, this, MID_GNE_SET_ATTRIBUTE, GUIDesignTextField);
785  // create elements for number attribute
786  auxiliarHorizontalFrame = new FXHorizontalFrame(this, GUIDesignAuxiliarHorizontalFrame);
787  myAttributeNumberRadioButton = new FXRadioButton(auxiliarHorizontalFrame, toString(SUMO_ATTR_NUMBER).c_str(), this, MID_GNE_SET_ATTRIBUTE_BUTTON, GUIDesignRadioButtonAttribute);
788  myValueNumberTextField = new FXTextField(auxiliarHorizontalFrame, GUIDesignTextFieldNCol, this, MID_GNE_SET_ATTRIBUTE, GUIDesignTextField);
789  // create elements for vehsPerHour attribute
790  auxiliarHorizontalFrame = new FXHorizontalFrame(this, GUIDesignAuxiliarHorizontalFrame);
792  myValueVehsPerHourTextField = new FXTextField(auxiliarHorizontalFrame, GUIDesignTextFieldNCol, this, MID_GNE_SET_ATTRIBUTE, GUIDesignTextField);
793  // create elements for period attribute
794  auxiliarHorizontalFrame = new FXHorizontalFrame(this, GUIDesignAuxiliarHorizontalFrame);
795  myAttributePeriodRadioButton = new FXRadioButton(auxiliarHorizontalFrame, toString(SUMO_ATTR_PERIOD).c_str(), this, MID_GNE_SET_ATTRIBUTE_BUTTON, GUIDesignRadioButtonAttribute);
796  myValuePeriodTextField = new FXTextField(auxiliarHorizontalFrame, GUIDesignTextFieldNCol, this, MID_GNE_SET_ATTRIBUTE, GUIDesignTextField);
797  // create elements for Probability attribute
798  auxiliarHorizontalFrame = new FXHorizontalFrame(this, GUIDesignAuxiliarHorizontalFrame);
799  myAttributeProbabilityRadioButton = new FXRadioButton(auxiliarHorizontalFrame, toString(SUMO_ATTR_PROB).c_str(), this, MID_GNE_SET_ATTRIBUTE_BUTTON, GUIDesignRadioButtonAttribute);
800  myValueProbabilityTextField = new FXTextField(auxiliarHorizontalFrame, GUIDesignTextFieldNCol, this, MID_GNE_SET_ATTRIBUTE, GUIDesignTextField);
801  // set default values
802  myValueEndTextField->setText("3600");
803  myValueNumberTextField->setText("1800");
804  myValueVehsPerHourTextField->setText("1800");
805  myValuePeriodTextField->setText("2");
806  myValueProbabilityTextField->setText("0.5");
807  // refresh attributes
809 }
810 
811 
813 
814 
815 void
817  if (persons) {
818  myAttributeVehsPerHourRadioButton->setText(toString(SUMO_ATTR_PERSONSPERHOUR).c_str());
819  } else {
820  myAttributeVehsPerHourRadioButton->setText(toString(SUMO_ATTR_VEHSPERHOUR).c_str());
821  }
822  // show
823  show();
824 }
825 
826 
827 void
829  hide();
830 }
831 
832 
833 void
835  if (myFlowParameters & VEHPARS_END_SET) {
836  myAttributeEndRadioButton->setCheck(TRUE);
837  myValueEndTextField->enable();
838  } else {
839  myAttributeEndRadioButton->setCheck(FALSE);
840  myValueEndTextField->disable();
841  }
842  if (myFlowParameters & VEHPARS_NUMBER_SET) {
843  myAttributeNumberRadioButton->setCheck(TRUE);
844  myValueNumberTextField->enable();
845  } else {
846  myAttributeNumberRadioButton->setCheck(FALSE);
847  myValueNumberTextField->disable();
848  }
849  if (myFlowParameters & VEHPARS_VPH_SET) {
850  myAttributeVehsPerHourRadioButton->setCheck(TRUE);
851  myValueVehsPerHourTextField->enable();
852  } else {
853  myAttributeVehsPerHourRadioButton->setCheck(FALSE);
854  myValueVehsPerHourTextField->disable();
855  }
856  if (myFlowParameters & VEHPARS_PERIOD_SET) {
857  myAttributePeriodRadioButton->setCheck(TRUE);
858  myValuePeriodTextField->enable();
859  } else {
860  myAttributePeriodRadioButton->setCheck(FALSE);
861  myValuePeriodTextField->disable();
862  }
863  if (myFlowParameters & VEHPARS_PROB_SET) {
864  myAttributeProbabilityRadioButton->setCheck(TRUE);
865  myValueProbabilityTextField->enable();
866  } else {
867  myAttributeProbabilityRadioButton->setCheck(FALSE);
868  myValueProbabilityTextField->disable();
869  }
870 }
871 
872 
873 void
874 GNEFrameAttributesModuls::AttributesCreatorFlow::setFlowParameters(std::map<SumoXMLAttr, std::string>& parameters) {
875  if (myFlowParameters & VEHPARS_END_SET) {
876  parameters[SUMO_ATTR_END] = myValueEndTextField->getText().text();
877  }
878  if (myFlowParameters & VEHPARS_NUMBER_SET) {
879  parameters[SUMO_ATTR_NUMBER] = myValueNumberTextField->getText().text();
880  }
881  if (myFlowParameters & VEHPARS_VPH_SET) {
882  if (myAttributeVehsPerHourRadioButton->getText().text() == toString(SUMO_ATTR_VEHSPERHOUR)) {
883  parameters[SUMO_ATTR_VEHSPERHOUR] = myValueVehsPerHourTextField->getText().text();
884  } else {
885  parameters[SUMO_ATTR_PERSONSPERHOUR] = myValueVehsPerHourTextField->getText().text();
886  }
887  }
888  if (myFlowParameters & VEHPARS_PERIOD_SET) {
889  parameters[SUMO_ATTR_PERIOD] = myValuePeriodTextField->getText().text();
890  }
891  if (myFlowParameters & VEHPARS_PROB_SET) {
892  parameters[SUMO_ATTR_PROB] = myValueProbabilityTextField->getText().text();
893  }
894 }
895 
896 
897 void
899  std::string errorMessage;
900  /*
901  // iterate over standar parameters
902  for (const auto& i : myTagProperties) {
903  if (errorMessage.empty() && myAttributesCreatorRows.at(i.getPositionListed())) {
904  // Return string with the error if at least one of the parameter isn't valid
905  std::string attributeValue = myAttributesCreatorRows.at(i.getPositionListed())->isAttributeValid();
906  if (attributeValue.size() != 0) {
907  errorMessage = attributeValue;
908  }
909  }
910  }
911  // show warning box if input parameters aren't invalid
912  if (extra.size() == 0) {
913  errorMessage = "Invalid input parameter of " + myTagProperties.getTagStr() + ": " + errorMessage;
914  } else {
915  errorMessage = "Invalid input parameter of " + myTagProperties.getTagStr() + ": " + extra;
916  }
917  */
918  // set message in status bar
919  myAttributesCreatorParent->getFrameParent()->myViewNet->setStatusBarText(errorMessage);
920  // Write Warning in console if we're in testing mode
921  WRITE_DEBUG(errorMessage);
922 }
923 
924 
925 bool
927  // check every flow attribute
928  if (myFlowParameters & VEHPARS_END_SET) {
929  if (GNEAttributeCarrier::canParse<double>(myValueEndTextField->getText().text())) {
930  if (GNEAttributeCarrier::parse<double>(myValueEndTextField->getText().text()) < 0) {
931  return false;
932  }
933  } else {
934  return false;
935  }
936  }
937  if (myFlowParameters & VEHPARS_NUMBER_SET) {
938  if (GNEAttributeCarrier::canParse<double>(myValueNumberTextField->getText().text())) {
939  if (GNEAttributeCarrier::parse<double>(myValueNumberTextField->getText().text()) < 0) {
940  return false;
941  }
942  } else {
943  return false;
944  }
945  }
946  if (myFlowParameters & VEHPARS_VPH_SET) {
947  if (GNEAttributeCarrier::canParse<double>(myValueVehsPerHourTextField->getText().text())) {
948  if (GNEAttributeCarrier::parse<double>(myValueVehsPerHourTextField->getText().text()) < 0) {
949  return false;
950  }
951  } else {
952  return false;
953  }
954  }
955  if (myFlowParameters & VEHPARS_PERIOD_SET) {
956  if (GNEAttributeCarrier::canParse<double>(myValuePeriodTextField->getText().text())) {
957  if (GNEAttributeCarrier::parse<double>(myValuePeriodTextField->getText().text()) < 0) {
958  return false;
959  }
960  } else {
961  return false;
962  }
963  }
964  if (myFlowParameters & VEHPARS_PROB_SET) {
965  if (GNEAttributeCarrier::canParse<double>(myValueProbabilityTextField->getText().text())) {
966  if (GNEAttributeCarrier::parse<double>(myValueProbabilityTextField->getText().text()) < 0) {
967  return false;
968  }
969  } else {
970  return false;
971  }
972  }
973  return true;
974 }
975 
976 
977 long
979  // obtain clicked textfield
980  FXTextField* textField = nullptr;
981  // check what text field was pressed
982  if (obj == myValueEndTextField) {
983  textField = myValueEndTextField;
984  } else if (obj == myValueNumberTextField) {
985  textField = myValueNumberTextField;
986  } else if (obj == myValueVehsPerHourTextField) {
987  textField = myValueVehsPerHourTextField;
988  } else if (obj == myValuePeriodTextField) {
989  textField = myValuePeriodTextField;
990  } else if (obj == myValueProbabilityTextField) {
991  textField = myValueProbabilityTextField;
992  } else {
993  throw ProcessError("Invalid text field");
994  }
995  // check if value is valid
996  if (GNEAttributeCarrier::canParse<double>(textField->getText().text()) && (GNEAttributeCarrier::parse<double>(textField->getText().text()) >= 0)) {
997  textField->setTextColor(FXRGB(0, 0, 0));
998  } else {
999  textField->setTextColor(FXRGB(255, 0, 0));
1000  }
1001  textField->killFocus();
1002  return 1;
1003 }
1004 
1005 
1006 long
1008  // check what check button was pressed
1009  if (obj == myAttributeEndRadioButton) {
1011  } else if (obj == myAttributeNumberRadioButton) {
1013  } else if (obj == myAttributeVehsPerHourRadioButton) {
1014  if (myAttributeVehsPerHourRadioButton->getText().text() == toString(SUMO_ATTR_VEHSPERHOUR)) {
1016  } else {
1018  }
1019  } else if (obj == myAttributePeriodRadioButton) {
1021  } else if (obj == myAttributeProbabilityRadioButton) {
1023  } else {
1024  throw ProcessError("Invalid Radio Button");
1025  }
1026  // refresh attributes
1027  refreshAttributesCreatorFlow();
1028  return 1;
1029 }
1030 
1031 // ---------------------------------------------------------------------------
1032 // GNEFrameAttributesModuls::AttributesEditorRow - methods
1033 // ---------------------------------------------------------------------------
1034 
1035 GNEFrameAttributesModuls::AttributesEditorRow::AttributesEditorRow(GNEFrameAttributesModuls::AttributesEditor* attributeEditorParent, const GNEAttributeProperties& ACAttr, const std::string& value, bool attributeEnabled) :
1036  FXHorizontalFrame(attributeEditorParent, GUIDesignAuxiliarHorizontalFrame),
1037  myAttributesEditorParent(attributeEditorParent),
1038  myACAttr(ACAttr),
1039  myMultiple(GNEAttributeCarrier::parse<std::vector<std::string>>(value).size() > 1) {
1040  // Create and hide label
1041  myAttributeLabel = new FXLabel(this, "attributeLabel", nullptr, GUIDesignLabelAttribute);
1042  myAttributeLabel->hide();
1043  // Create and hide check button
1044  myAttributeCheckButton = new FXCheckButton(this, "attributeCheckButton", this, MID_GNE_SET_ATTRIBUTE_BOOL, GUIDesignCheckButtonAttribute);
1045  myAttributeCheckButton->hide();
1046  // Create and hide ButtonCombinableChoices
1047  myAttributeButtonCombinableChoices = new FXButton(this, "attributeButtonCombinableChoices", nullptr, this, MID_GNE_SET_ATTRIBUTE_DIALOG, GUIDesignButtonAttribute);
1049  // create and hidde color editor
1050  myAttributeColorButton = new FXButton(this, "attributeColorButton", nullptr, this, MID_GNE_SET_ATTRIBUTE_DIALOG, GUIDesignButtonAttribute);
1051  myAttributeColorButton->hide();
1052  // Create and hide textField for string attributes
1054  myValueTextField->hide();
1055  // Create and hide ComboBox
1057  myValueComboBoxChoices->hide();
1058  // Create and hide checkButton
1059  myValueCheckButton = new FXCheckButton(this, "", this, MID_GNE_SET_ATTRIBUTE, GUIDesignCheckButton);
1060  myValueCheckButton->hide();
1061  // only create if parent was created
1062  if (getParent()->id()) {
1063  // create AttributesEditorRow
1064  FXHorizontalFrame::create();
1065  // start enabling all elements, depending if attribute is enabled
1066  if (attributeEnabled == false) {
1067  myValueTextField->disable();
1068  myValueComboBoxChoices->disable();
1069  myValueCheckButton->disable();
1070  } else {
1071  myValueTextField->enable();
1072  myValueComboBoxChoices->enable();
1073  myValueCheckButton->enable();
1074  }
1075  // if Tag correspond to an network element but we're in demand mode (or vice versa), disable all elements
1076  if (myACAttr.getAttr() != SUMO_ATTR_NOTHING) {
1079  myAttributeColorButton->enable();
1080  myAttributeCheckButton->enable();
1081  } else {
1082  myAttributeColorButton->disable();
1083  myAttributeCheckButton->disable();
1084  myValueTextField->disable();
1085  myValueComboBoxChoices->disable();
1086  myValueCheckButton->disable();
1088  }
1089  }
1090  // set left column
1091  if (myACAttr.isColor()) {
1092  // show color button
1093  myAttributeColorButton->setTextColor(FXRGB(0, 0, 0));
1094  myAttributeColorButton->setText(myACAttr.getAttrStr().c_str());
1095  myAttributeColorButton->show();
1096  } else if (myACAttr.isActivatable()) {
1097  // show checkbox button
1098  myAttributeCheckButton->setTextColor(FXRGB(0, 0, 0));
1099  myAttributeCheckButton->setText(myACAttr.getAttrStr().c_str());
1100  myAttributeCheckButton->show();
1101  // check or uncheck depending of attributeEnabled
1102  if (attributeEnabled) {
1103  myAttributeCheckButton->setCheck(TRUE);
1104  } else {
1105  myAttributeCheckButton->setCheck(FALSE);
1106  }
1107  } else {
1108  // Show attribute Label
1109  myAttributeLabel->setText(myACAttr.getAttrStr().c_str());
1110  myAttributeLabel->show();
1111  }
1112  // Set field depending of the type of value
1113  if (myACAttr.isBool()) {
1114  // first we need to check if all boolean values are equal
1115  bool allBooleanValuesEqual = true;
1116  // declare boolean vector
1117  std::vector<bool> booleanVector;
1118  // check if value can be parsed to a boolean vector
1119  if (GNEAttributeCarrier::canParse<std::vector<bool> >(value)) {
1120  booleanVector = GNEAttributeCarrier::parse<std::vector<bool> >(value);
1121  }
1122  // iterate over pased booleans comparing all element with the first
1123  for (const auto i : booleanVector) {
1124  if (i != booleanVector.front()) {
1125  allBooleanValuesEqual = false;
1126  }
1127  }
1128  // use checkbox or textfield depending if all booleans are equal
1129  if (allBooleanValuesEqual) {
1130  // set check button
1131  if ((booleanVector.size() > 0) && booleanVector.front()) {
1132  myValueCheckButton->setCheck(true);
1133  myValueCheckButton->setText("true");
1134  } else {
1135  myValueCheckButton->setCheck(false);
1136  myValueCheckButton->setText("false");
1137  }
1138  // show check button
1139  myValueCheckButton->show();
1140  } else {
1141  // show list of bools (0 1)
1142  myValueTextField->setText(value.c_str());
1143  myValueTextField->setTextColor(FXRGB(0, 0, 0));
1144  myValueTextField->show();
1145  }
1146  } else if (myACAttr.isDiscrete()) {
1147  // Check if are VClasses
1148  if ((myACAttr.getDiscreteValues().size() > 0) && myACAttr.isVClasses()) {
1149  // hide label
1150  myAttributeLabel->hide();
1151  // Show button combinable choices
1154  // Show string with the values
1155  myValueTextField->setText(value.c_str());
1156  myValueTextField->setTextColor(FXRGB(0, 0, 0));
1157  myValueTextField->show();
1158  } else if (!myMultiple) {
1159  // fill comboBox
1160  myValueComboBoxChoices->clearItems();
1161  for (const auto& it : myACAttr.getDiscreteValues()) {
1162  myValueComboBoxChoices->appendItem(it.c_str());
1163  }
1164  // show combo box with values
1165  myValueComboBoxChoices->setNumVisible((int)myACAttr.getDiscreteValues().size());
1166  myValueComboBoxChoices->setCurrentItem(myValueComboBoxChoices->findItem(value.c_str()));
1167  myValueComboBoxChoices->setTextColor(FXRGB(0, 0, 0));
1168  myValueComboBoxChoices->show();
1169  } else {
1170  // represent combinable choices in multiple selections always with a textfield instead with a comboBox
1171  myValueTextField->setText(value.c_str());
1172  myValueTextField->setTextColor(FXRGB(0, 0, 0));
1173  myValueTextField->show();
1174  }
1175  } else {
1176  // In any other case (String, list, etc.), show value as String
1177  myValueTextField->setText(value.c_str());
1178  myValueTextField->setTextColor(FXRGB(0, 0, 0));
1179  myValueTextField->show();
1180  }
1181  // Show AttributesEditorRow
1182  show();
1183  }
1184 }
1185 
1186 
1187 void
1189  // only destroy if parent was created
1190  if (getParent()->id()) {
1191  FXHorizontalFrame::destroy();
1192  }
1193 }
1194 
1195 
1196 void
1197 GNEFrameAttributesModuls::AttributesEditorRow::refreshAttributesEditorRow(const std::string& value, bool forceRefresh, bool attributeEnabled) {
1198  // start enabling all elements, depending if attribute is enabled
1199  if (attributeEnabled == false) {
1200  myValueTextField->disable();
1201  myValueComboBoxChoices->disable();
1202  myValueCheckButton->disable();
1203  } else {
1204  myValueTextField->enable();
1205  myValueComboBoxChoices->enable();
1206  myValueCheckButton->enable();
1207  }
1208  // if Tag correspond to an network element but we're in demand mode (or vice versa), disable all elements
1209  if (myACAttr.getAttr() != SUMO_ATTR_NOTHING) {
1210  if (isSupermodeValid(myAttributesEditorParent->getFrameParent()->myViewNet, myACAttr)) {
1211  myAttributeButtonCombinableChoices->enable();
1212  myAttributeColorButton->enable();
1213  myAttributeCheckButton->enable();
1214  } else {
1215  myAttributeColorButton->disable();
1216  myAttributeCheckButton->disable();
1217  myValueTextField->disable();
1218  myValueComboBoxChoices->disable();
1219  myValueCheckButton->disable();
1220  myAttributeButtonCombinableChoices->disable();
1221  }
1222  }
1223  // set check buton
1224  if (myAttributeCheckButton->shown()) {
1225  myAttributeCheckButton->setCheck(attributeEnabled);
1226  }
1227  if (myValueTextField->shown()) {
1228  // set last valid value and restore color if onlyValid is disabled
1229  if (myValueTextField->getTextColor() == FXRGB(0, 0, 0) || forceRefresh) {
1230  myValueTextField->setText(value.c_str());
1231  myValueTextField->setTextColor(FXRGB(0, 0, 0));
1232  }
1233  } else if (myValueComboBoxChoices->shown()) {
1234  // fill comboBox again
1235  myValueComboBoxChoices->clearItems();
1236  for (const auto& it : myACAttr.getDiscreteValues()) {
1237  myValueComboBoxChoices->appendItem(it.c_str());
1238  }
1239  // show combo box with values
1240  myValueComboBoxChoices->setNumVisible((int)myACAttr.getDiscreteValues().size());
1241  myValueComboBoxChoices->setCurrentItem(myValueComboBoxChoices->findItem(value.c_str()));
1242  myValueComboBoxChoices->setTextColor(FXRGB(0, 0, 0));
1243  myValueComboBoxChoices->show();
1244  } else if (myValueCheckButton->shown()) {
1245  if (GNEAttributeCarrier::canParse<bool>(value)) {
1246  myValueCheckButton->setCheck(GNEAttributeCarrier::parse<bool>(value));
1247  } else {
1248  myValueCheckButton->setCheck(false);
1249  }
1250  }
1251 }
1252 
1253 
1254 bool
1256  return ((myValueTextField->getTextColor() == FXRGB(0, 0, 0)) && (myValueComboBoxChoices->getTextColor() == FXRGB(0, 0, 0)));
1257 }
1258 
1259 
1260 long
1262  if (obj == myAttributeColorButton) {
1263  // create FXColorDialog
1264  FXColorDialog colordialog(this, tr("Color Dialog"));
1265  colordialog.setTarget(this);
1266  // If previous attribute wasn't correct, set black as default color
1267  if (GNEAttributeCarrier::canParse<RGBColor>(myValueTextField->getText().text())) {
1268  colordialog.setRGBA(MFXUtils::getFXColor(RGBColor::parseColor(myValueTextField->getText().text())));
1269  } else if (!myACAttr.getDefaultValue().empty()) {
1270  colordialog.setRGBA(MFXUtils::getFXColor(RGBColor::parseColor(myACAttr.getDefaultValue())));
1271  } else {
1272  colordialog.setRGBA(MFXUtils::getFXColor(RGBColor::BLACK));
1273  }
1274  // execute dialog to get a new color
1275  if (colordialog.execute()) {
1276  std::string newValue = toString(MFXUtils::getRGBColor(colordialog.getRGBA()));
1277  myValueTextField->setText(newValue.c_str());
1278  if (myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers().front()->isValid(myACAttr.getAttr(), newValue)) {
1279  // if its valid for the first AC than its valid for all (of the same type)
1280  if (myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers().size() > 1) {
1281  myAttributesEditorParent->getFrameParent()->myViewNet->getUndoList()->p_begin("Change multiple attributes");
1282  }
1283  // Set new value of attribute in all selected ACs
1284  for (const auto& it_ac : myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers()) {
1285  it_ac->setAttribute(myACAttr.getAttr(), newValue, myAttributesEditorParent->getFrameParent()->myViewNet->getUndoList());
1286  }
1287  // If previously value was incorrect, change font color to black
1288  myValueTextField->setTextColor(FXRGB(0, 0, 0));
1289  myValueTextField->killFocus();
1290  }
1291  }
1292  return 0;
1293  } else if (obj == myAttributeButtonCombinableChoices) {
1294  // if its valid for the first AC than its valid for all (of the same type)
1295  if (myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers().size() > 1) {
1296  myAttributesEditorParent->getFrameParent()->myViewNet->getUndoList()->p_begin("Change multiple attributes");
1297  }
1298  // open GNEAllowDisallow
1299  GNEAllowDisallow(myAttributesEditorParent->getFrameParent()->myViewNet, myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers().front()).execute();
1300  std::string allowed = myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers().front()->getAttribute(SUMO_ATTR_ALLOW);
1301  // Set new value of attribute in all selected ACs
1302  for (const auto& it_ac : myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers()) {
1303  it_ac->setAttribute(SUMO_ATTR_ALLOW, allowed, myAttributesEditorParent->getFrameParent()->myViewNet->getUndoList());
1304  }
1305  // finish change multiple attributes
1306  if (myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers().size() > 1) {
1307  myAttributesEditorParent->getFrameParent()->myViewNet->getUndoList()->p_end();
1308  }
1309  // update frame parent after attribute sucesfully set
1310  myAttributesEditorParent->getFrameParent()->attributeUpdated();
1311  return 1;
1312  } else {
1313  throw ProcessError("Invalid call to onCmdOpenAttributeDialog");
1314  }
1315 }
1316 
1317 
1318 long
1320  // Declare changed value
1321  std::string newVal;
1322  // First, obtain the string value of the new attribute depending of their type
1323  if (myACAttr.isBool()) {
1324  // first check if we're editing boolean as a list of string or as a checkbox
1325  if (myValueCheckButton->shown()) {
1326  // Set true o false depending of the checkBox
1327  if (myValueCheckButton->getCheck()) {
1328  myValueCheckButton->setText("true");
1329  newVal = "true";
1330  } else {
1331  myValueCheckButton->setText("false");
1332  newVal = "false";
1333  }
1334  } else {
1335  // obtain boolean value of myValueTextField (because we're inspecting multiple attribute carriers with different values)
1336  newVal = myValueTextField->getText().text();
1337  }
1338  } else if (myACAttr.isDiscrete()) {
1339  // Check if are VClasses
1340  if ((myACAttr.getDiscreteValues().size() > 0) && myACAttr.isVClasses()) {
1341  // Get value obtained using AttributesEditor
1342  newVal = myValueTextField->getText().text();
1343  } else if (!myMultiple) {
1344  // Get value of ComboBox
1345  newVal = myValueComboBoxChoices->getText().text();
1346  } else {
1347  // due this is a multiple selection, obtain value of myValueTextField instead of comboBox
1348  newVal = myValueTextField->getText().text();
1349  }
1350  } else {
1351  // Check if default value of attribute must be set
1352  if (myValueTextField->getText().empty() && myACAttr.hasStaticDefaultValue()) {
1353  newVal = myACAttr.getDefaultValue();
1354  myValueTextField->setText(newVal.c_str());
1355  } else if (myACAttr.isInt() && GNEAttributeCarrier::canParse<double>(myValueTextField->getText().text())) {
1356  // filter int attributes
1357  double doubleValue = GNEAttributeCarrier::parse<double>(myValueTextField->getText().text());
1358  // check if myValueTextField has to be updated
1359  if ((doubleValue - (int)doubleValue) == 0) {
1360  newVal = toString((int)doubleValue);
1361  myValueTextField->setText(newVal.c_str(), FALSE);
1362  }
1363  } else if ((myACAttr.getAttr() == SUMO_ATTR_ANGLE) && GNEAttributeCarrier::canParse<double>(myValueTextField->getText().text())) {
1364  // filter angle
1365  double angle = GNEAttributeCarrier::parse<double>(myValueTextField->getText().text());
1366  // filter if angle isn't between [0,360]
1367  if ((angle < 0) || (angle > 360)) {
1368  // apply modul
1369  angle = fmod(angle, 360);
1370  }
1371  // set newVal
1372  newVal = toString(angle);
1373  // update Textfield
1374  myValueTextField->setText(newVal.c_str(), FALSE);
1375  } else {
1376  // obtain value of myValueTextField
1377  newVal = myValueTextField->getText().text();
1378  }
1379  }
1380  // we need a extra check for Position and Shape Values, due #2658
1381  if ((myACAttr.getAttr() == SUMO_ATTR_POSITION) || (myACAttr.getAttr() == SUMO_ATTR_SHAPE)) {
1382  newVal = stripWhitespaceAfterComma(newVal);
1383  }
1384  // Check if attribute must be changed
1385  if ((myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers().size() > 0) && myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers().front()->isValid(myACAttr.getAttr(), newVal)) {
1386  // if its valid for the first AC than its valid for all (of the same type)
1387  if (myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers().size() > 1) {
1388  myAttributesEditorParent->getFrameParent()->myViewNet->getUndoList()->p_begin("Change multiple attributes");
1389  } else if (myACAttr.getAttr() == SUMO_ATTR_ID) {
1390  // IDs attribute has to be encapsulated
1391  myAttributesEditorParent->getFrameParent()->myViewNet->getUndoList()->p_begin("change " + myACAttr.getTagPropertyParent().getTagStr() + " attribute");
1392  }
1393  // Set new value of attribute in all selected ACs
1394  for (const auto& it_ac : myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers()) {
1395  it_ac->setAttribute(myACAttr.getAttr(), newVal, myAttributesEditorParent->getFrameParent()->myViewNet->getUndoList());
1396  }
1397  // finish change multiple attributes or ID Attributes
1398  if (myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers().size() > 1) {
1399  myAttributesEditorParent->getFrameParent()->myViewNet->getUndoList()->p_end();
1400  } else if (myACAttr.getAttr() == SUMO_ATTR_ID) {
1401  myAttributesEditorParent->getFrameParent()->myViewNet->getUndoList()->p_end();
1402  }
1403  // If previously value was incorrect, change font color to black
1404  if (myACAttr.isVClasses()) {
1405  myValueTextField->setTextColor(FXRGB(0, 0, 0));
1406  myValueTextField->killFocus();
1407  // in this case, we need to refresh the other values (For example, allow/Disallow objects)
1408  myAttributesEditorParent->refreshAttributeEditor(false, false);
1409  } else if (myACAttr.isDiscrete()) {
1410  myValueComboBoxChoices->setTextColor(FXRGB(0, 0, 0));
1411  myValueComboBoxChoices->killFocus();
1412  } else if (myValueTextField != nullptr) {
1413  myValueTextField->setTextColor(FXRGB(0, 0, 0));
1414  myValueTextField->killFocus();
1415  }
1416  // update frame parent after attribute sucesfully set
1417  myAttributesEditorParent->getFrameParent()->attributeUpdated();
1418  } else {
1419  // If value of TextField isn't valid, change color to Red depending of type
1420  if (myACAttr.isVClasses()) {
1421  myValueTextField->setTextColor(FXRGB(255, 0, 0));
1422  myValueTextField->killFocus();
1423  } else if (myACAttr.isDiscrete()) {
1424  myValueComboBoxChoices->setTextColor(FXRGB(255, 0, 0));
1425  myValueComboBoxChoices->killFocus();
1426  } else if (myValueTextField != nullptr) {
1427  myValueTextField->setTextColor(FXRGB(255, 0, 0));
1428  }
1429  // Write Warning in console if we're in testing mode
1430  WRITE_DEBUG("Value '" + newVal + "' for attribute " + myACAttr.getAttrStr() + " of " + myACAttr.getTagPropertyParent().getTagStr() + " isn't valid");
1431  }
1432  return 1;
1433 }
1434 
1435 
1436 long
1438  // obtain undoList (To improve code legibly)
1439  GNEUndoList* undoList = myAttributesEditorParent->getFrameParent()->myViewNet->getUndoList();
1440  // check if we have to enable or disable
1441  if (myAttributeCheckButton->getCheck()) {
1442  // enable input values
1443  myValueCheckButton->enable();
1444  myValueTextField->enable();
1445  // enable attribute
1446  undoList->p_begin("enable attribute '" + myACAttr.getAttrStr() + "'");
1447  myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers().front()->enableAttribute(myACAttr.getAttr(), undoList);
1448  undoList->p_end();
1449  } else {
1450  // disable input values
1451  myValueCheckButton->disable();
1452  myValueTextField->disable();
1453  // disable attribute
1454  undoList->p_begin("disable attribute '" + myACAttr.getAttrStr() + "'");
1455  myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers().front()->disableAttribute(myACAttr.getAttr(), undoList);
1456  undoList->p_end();
1457  }
1458  return 0;
1459 }
1460 
1461 
1463  myMultiple(false) {
1464 }
1465 
1466 
1467 std::string
1469  std::string result(stringValue);
1470  while (result.find(", ") != std::string::npos) {
1471  result = StringUtils::replace(result, ", ", ",");
1472  }
1473  return result;
1474 }
1475 
1476 // ---------------------------------------------------------------------------
1477 // GNEFrameAttributesModuls::AttributesEditor - methods
1478 // ---------------------------------------------------------------------------
1479 
1481  FXGroupBox(FrameParent->myContentFrame, "Internal attributes", GUIDesignGroupBoxFrame),
1482  myFrameParent(FrameParent),
1483  myIncludeExtended(true) {
1484  // resize myAttributesEditorRows
1486  // create myAttributesFlowEditor
1488  // leave it hidden
1490  // Create help button
1491  myHelpButton = new FXButton(this, "Help", nullptr, this, MID_HELP, GUIDesignButtonRectangular);
1492 }
1493 
1494 
1495 void
1496 GNEFrameAttributesModuls::AttributesEditor::showAttributeEditorModul(bool includeExtended, bool forceAttributeEnabled) {
1497  myIncludeExtended = includeExtended;
1498  // first remove all rows
1499  for (int i = 0; i < (int)myAttributesEditorRows.size(); i++) {
1500  // destroy and delete all rows
1501  if (myAttributesEditorRows.at(i) != nullptr) {
1502  myAttributesEditorRows.at(i)->destroy();
1503  delete myAttributesEditorRows.at(i);
1504  myAttributesEditorRows.at(i) = nullptr;
1505  }
1506  }
1507  // declare flag to check if flow editor has to be shown
1508  bool showFlowEditor = false;
1509  if (myFrameParent->getViewNet()->getInspectedAttributeCarriers().size() > 0) {
1510  // Iterate over attributes
1511  for (const auto& tagProperty : myFrameParent->getViewNet()->getInspectedAttributeCarriers().front()->getTagProperty()) {
1512  // declare flag to show/hidde atribute
1513  bool editAttribute = true;
1514  // disable editing for unique attributes in case of multi-selection
1515  if ((myFrameParent->getViewNet()->getInspectedAttributeCarriers().size() > 1) && tagProperty.isUnique()) {
1516  editAttribute = false;
1517  }
1518  // disable editing of extended attributes if includeExtended isn't enabled
1519  if (tagProperty.isExtended() && !includeExtended) {
1520  editAttribute = false;
1521  }
1522  // disable editing of flow definition attributes, but enable flow editor
1523  if (tagProperty.isFlowDefinition()) {
1524  editAttribute = false;
1525  showFlowEditor = true;
1526  }
1527  // continue if attribute is editable
1528  if (editAttribute) {
1529  // Declare a set of occuring values and insert attribute's values of item (note: We use a set to avoid repeated values)
1530  std::set<std::string> occuringValues;
1531  // iterate over edited attributes
1532  for (const auto& it_ac : myFrameParent->getViewNet()->getInspectedAttributeCarriers()) {
1533  occuringValues.insert(it_ac->getAttribute(tagProperty.getAttr()));
1534  }
1535  // get current value
1536  std::ostringstream oss;
1537  for (auto values = occuringValues.begin(); values != occuringValues.end(); values++) {
1538  if (values != occuringValues.begin()) {
1539  oss << " ";
1540  }
1541  oss << *values;
1542  }
1543  // obtain value to be shown in row
1544  std::string value = oss.str();
1545  // declare a flag for enabled attributes
1546  bool attributeEnabled = myFrameParent->getViewNet()->getInspectedAttributeCarriers().front()->isAttributeEnabled(tagProperty.getAttr());
1547  // overwritte value if attribute is disabled (used by LinkIndex)
1548  if (attributeEnabled == false) {
1549  value = myFrameParent->getViewNet()->getInspectedAttributeCarriers().front()->getAlternativeValueForDisabledAttributes(tagProperty.getAttr());
1550  }
1551  // extra check for Triggered and container Triggered
1552  if (myFrameParent->getViewNet()->getInspectedAttributeCarriers().front()->getTagProperty().isStop() ||
1553  myFrameParent->getViewNet()->getInspectedAttributeCarriers().front()->getTagProperty().isPersonStop()) {
1554  if ((tagProperty.getAttr() == SUMO_ATTR_EXPECTED) && (myFrameParent->getViewNet()->getInspectedAttributeCarriers().front()->isAttributeEnabled(SUMO_ATTR_TRIGGERED) == false)) {
1555  attributeEnabled = false;
1556  } else if ((tagProperty.getAttr() == SUMO_ATTR_EXPECTED_CONTAINERS) && (myFrameParent->getViewNet()->getInspectedAttributeCarriers().front()->isAttributeEnabled(SUMO_ATTR_CONTAINER_TRIGGERED) == false)) {
1557  attributeEnabled = false;
1558  }
1559  }
1560  // if forceEnablellAttribute is enable, force attributeEnabled (except for ID)
1561  if (forceAttributeEnabled && (tagProperty.getAttr() != SUMO_ATTR_ID)) {
1562  attributeEnabled = true;
1563  }
1564  // create attribute editor row
1565  myAttributesEditorRows[tagProperty.getPositionListed()] = new AttributesEditorRow(this, tagProperty, value, attributeEnabled);
1566  }
1567  }
1568  // check if Flow editor has to be shown
1569  if (showFlowEditor) {
1570  myAttributesEditorFlow->showAttributeEditorFlowModul();
1571  } else {
1572  myAttributesEditorFlow->hideAttributesEditorFlowModul();
1573  }
1574  // show AttributesEditor
1575  show();
1576  } else {
1577  myAttributesEditorFlow->hideAttributesEditorFlowModul();
1578  }
1579  // reparent help button (to place it at bottom)
1580  myHelpButton->reparent(this);
1581 }
1582 
1583 
1584 void
1586  // hide AttributesEditorFlowModul
1587  myAttributesEditorFlow->hideAttributesEditorFlowModul();
1588  // hide also AttributesEditor
1589  hide();
1590 }
1591 
1592 
1593 void
1594 GNEFrameAttributesModuls::AttributesEditor::refreshAttributeEditor(bool forceRefreshShape, bool forceRefreshPosition) {
1595  // first check if there is inspected attribute carriers
1596  if (myFrameParent->getViewNet()->getInspectedAttributeCarriers().size() > 0) {
1597  // Iterate over inspected attribute carriers
1598  for (const auto& tagProperty : myFrameParent->getViewNet()->getInspectedAttributeCarriers().front()->getTagProperty()) {
1599  // declare flag to show/hidde atribute
1600  bool editAttribute = true;
1601  // disable editing for unique attributes in case of multi-selection
1602  if ((myFrameParent->getViewNet()->getInspectedAttributeCarriers().size() > 1) && tagProperty.isUnique()) {
1603  editAttribute = false;
1604  }
1605  // disable editing of extended attributes if includeExtended isn't enabled
1606  if (tagProperty.isExtended() && !myIncludeExtended) {
1607  editAttribute = false;
1608  }
1609  // disable editing of flow definition attributes, but enable flow editor
1610  if (tagProperty.isFlowDefinition()) {
1611  editAttribute = false;
1612  }
1613  // continue if attribute is editable
1614  if (editAttribute) {
1615  // Declare a set of occuring values and insert attribute's values of item (note: We use a set to avoid repeated values)
1616  std::set<std::string> occuringValues;
1617  // iterate over edited attributes
1618  for (const auto& it_ac : myFrameParent->getViewNet()->getInspectedAttributeCarriers()) {
1619  occuringValues.insert(it_ac->getAttribute(tagProperty.getAttr()));
1620  }
1621  // get current value
1622  std::ostringstream oss;
1623  for (auto values = occuringValues.begin(); values != occuringValues.end(); values++) {
1624  if (values != occuringValues.begin()) {
1625  oss << " ";
1626  }
1627  oss << *values;
1628  }
1629  // obtain value to be shown in row
1630  std::string value = oss.str();
1631  // declare a flag for enabled attributes
1632  bool attributeEnabled = myFrameParent->getViewNet()->getInspectedAttributeCarriers().front()->isAttributeEnabled(tagProperty.getAttr());
1633  // overwritte value if attribute is disabled (used by LinkIndex)
1634  if (attributeEnabled == false) {
1635  value = myFrameParent->getViewNet()->getInspectedAttributeCarriers().front()->getAlternativeValueForDisabledAttributes(tagProperty.getAttr());
1636  }
1637  // extra check for Triggered and container Triggered
1638  if (myFrameParent->getViewNet()->getInspectedAttributeCarriers().front()->getTagProperty().isStop() ||
1639  myFrameParent->getViewNet()->getInspectedAttributeCarriers().front()->getTagProperty().isPersonStop()) {
1640  if ((tagProperty.getAttr() == SUMO_ATTR_EXPECTED) && (myFrameParent->getViewNet()->getInspectedAttributeCarriers().front()->isAttributeEnabled(SUMO_ATTR_TRIGGERED) == false)) {
1641  attributeEnabled = false;
1642  } else if ((tagProperty.getAttr() == SUMO_ATTR_EXPECTED_CONTAINERS) && (myFrameParent->getViewNet()->getInspectedAttributeCarriers().front()->isAttributeEnabled(SUMO_ATTR_CONTAINER_TRIGGERED) == false)) {
1643  attributeEnabled = false;
1644  }
1645  }
1646  /*
1647  // if forceEnablellAttribute is enable, force attributeEnabled (except for ID)
1648  if (myForceAttributeEnabled && (tagProperty.getAttr() != SUMO_ATTR_ID)) {
1649  attributeEnabled = true;
1650  }
1651  */
1652  // Check if Position or Shape refresh has to be forced
1653  if ((tagProperty.getAttr() == SUMO_ATTR_SHAPE) && forceRefreshShape) {
1654  myAttributesEditorRows[tagProperty.getPositionListed()]->refreshAttributesEditorRow(value, true, attributeEnabled);
1655  } else if ((tagProperty.getAttr() == SUMO_ATTR_POSITION) && forceRefreshPosition) {
1656  // Refresh attributes maintain invalid values
1657  myAttributesEditorRows[tagProperty.getPositionListed()]->refreshAttributesEditorRow(value, true, attributeEnabled);
1658  } else {
1659  // Refresh attributes maintain invalid values
1660  myAttributesEditorRows[tagProperty.getPositionListed()]->refreshAttributesEditorRow(value, false, attributeEnabled);
1661  }
1662  }
1663  }
1664  // check if flow editor has to be update
1665  if (myAttributesEditorFlow->isAttributesEditorFlowModulShown()) {
1666  myAttributesEditorFlow->refreshAttributeEditorFlow();
1667  }
1668  }
1669 }
1670 
1671 
1672 GNEFrame*
1674  return myFrameParent;
1675 }
1676 
1677 
1678 long
1680  // open Help attributes dialog if there is inspected ACs
1681  if (myFrameParent->getViewNet()->getInspectedAttributeCarriers().size() > 0) {
1682  // open Help attributes dialog
1683  myFrameParent->openHelpAttributesDialog(myFrameParent->getViewNet()->getInspectedAttributeCarriers().front()->getTagProperty());
1684  }
1685  return 1;
1686 }
1687 
1688 // ---------------------------------------------------------------------------
1689 // GNEFrameAttributesModuls::AttributesEditorFlow - methods
1690 // ---------------------------------------------------------------------------
1691 
1693  FXGroupBox(attributesEditorParent->getFrameParent()->myContentFrame, "Flow attributes", GUIDesignGroupBoxFrame),
1694  myAttributesEditorParent(attributesEditorParent) {
1695  // declare auxiliar horizontal frame
1696  FXHorizontalFrame* auxiliarHorizontalFrame = nullptr;
1697  // create elements for end attribute
1698  auxiliarHorizontalFrame = new FXHorizontalFrame(this, GUIDesignAuxiliarHorizontalFrame);
1699  myAttributeEndRadioButton = new FXRadioButton(auxiliarHorizontalFrame, toString(SUMO_ATTR_END).c_str(), this, MID_GNE_SET_ATTRIBUTE_BUTTON, GUIDesignRadioButtonAttribute);
1700  myValueEndTextField = new FXTextField(auxiliarHorizontalFrame, GUIDesignTextFieldNCol, this, MID_GNE_SET_ATTRIBUTE, GUIDesignTextField);
1701  // create elements for number attribute
1702  auxiliarHorizontalFrame = new FXHorizontalFrame(this, GUIDesignAuxiliarHorizontalFrame);
1703  myAttributeNumberRadioButton = new FXRadioButton(auxiliarHorizontalFrame, toString(SUMO_ATTR_NUMBER).c_str(), this, MID_GNE_SET_ATTRIBUTE_BUTTON, GUIDesignRadioButtonAttribute);
1704  myValueNumberTextField = new FXTextField(auxiliarHorizontalFrame, GUIDesignTextFieldNCol, this, MID_GNE_SET_ATTRIBUTE, GUIDesignTextField);
1705  // create elements for vehsPerHour attribute
1706  auxiliarHorizontalFrame = new FXHorizontalFrame(this, GUIDesignAuxiliarHorizontalFrame);
1708  myValueVehsPerHourTextField = new FXTextField(auxiliarHorizontalFrame, GUIDesignTextFieldNCol, this, MID_GNE_SET_ATTRIBUTE, GUIDesignTextField);
1709  // create elements for period attribute
1710  auxiliarHorizontalFrame = new FXHorizontalFrame(this, GUIDesignAuxiliarHorizontalFrame);
1711  myAttributePeriodRadioButton = new FXRadioButton(auxiliarHorizontalFrame, toString(SUMO_ATTR_PERIOD).c_str(), this, MID_GNE_SET_ATTRIBUTE_BUTTON, GUIDesignRadioButtonAttribute);
1712  myValuePeriodTextField = new FXTextField(auxiliarHorizontalFrame, GUIDesignTextFieldNCol, this, MID_GNE_SET_ATTRIBUTE, GUIDesignTextField);
1713  // create elements for Probability attribute
1714  auxiliarHorizontalFrame = new FXHorizontalFrame(this, GUIDesignAuxiliarHorizontalFrame);
1715  myAttributeProbabilityRadioButton = new FXRadioButton(auxiliarHorizontalFrame, toString(SUMO_ATTR_PROB).c_str(), this, MID_GNE_SET_ATTRIBUTE_BUTTON, GUIDesignRadioButtonAttribute);
1716  myValueProbabilityTextField = new FXTextField(auxiliarHorizontalFrame, GUIDesignTextFieldNCol, this, MID_GNE_SET_ATTRIBUTE, GUIDesignTextField);
1717 }
1718 
1719 
1720 void
1722  if (myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers().size() > 0) {
1723  // refresh attributeEditorFlowModul
1724  refreshAttributeEditorFlow();
1725  // show flow
1726  show();
1727  } else {
1728  hide();
1729  }
1730 }
1731 
1732 
1733 void
1735  // simply hide modul
1736  hide();
1737 }
1738 
1739 
1740 bool
1742  return shown();
1743 }
1744 
1745 
1746 void
1748  if (myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers().size() > 0) {
1749  // simply refresh every flow attribute
1750  refreshEnd();
1751  refreshNumber();
1752  refreshVehsPerHour();
1753  refreshPeriod();
1754  refreshProbability();
1755  }
1756 }
1757 
1758 
1759 long
1761  // obtain undoList (To improve code legibly)
1762  GNEUndoList* undoList = myAttributesEditorParent->getFrameParent()->myViewNet->getUndoList();
1764  std::string value;
1765  // check what check button was pressed
1766  if (obj == myValueEndTextField) {
1767  attr = SUMO_ATTR_END;
1768  value = myValueEndTextField->getText().text();
1769  } else if (obj == myValueNumberTextField) {
1770  attr = SUMO_ATTR_NUMBER;
1771  value = myValueNumberTextField->getText().text();
1772  } else if (obj == myValueVehsPerHourTextField) {
1773  // check attribute
1774  if (myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers().front()->getTagProperty().hasAttribute(SUMO_ATTR_VEHSPERHOUR)) {
1775  attr = SUMO_ATTR_VEHSPERHOUR;
1776  } else {
1777  attr = SUMO_ATTR_PERSONSPERHOUR;
1778  }
1779  value = myValueVehsPerHourTextField->getText().text();
1780  } else if (obj == myValuePeriodTextField) {
1781  attr = SUMO_ATTR_PERIOD;
1782  value = myValuePeriodTextField->getText().text();
1783  } else if (obj == myValueProbabilityTextField) {
1784  attr = SUMO_ATTR_PROB;
1785  value = myValueProbabilityTextField->getText().text();
1786  } else {
1787  throw ProcessError("Invalid text field");
1788  }
1789  // write debug (for Netedit tests)
1790  WRITE_DEBUG("Selected checkBox for attribute '" + toString(attr) + "'");
1791  // check if we're editing multiple attributes
1792  if (myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers().size() > 1) {
1793  undoList->p_begin("Change multiple " + toString(attr) + " attributes");
1794  }
1795  // enable attribute with undo/redo
1796  for (const auto& i : myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers()) {
1797  i->setAttribute(attr, value, undoList);
1798  }
1799  // check if we're editing multiple attributes
1800  if (myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers().size() > 1) {
1801  undoList->p_end();
1802  }
1803  // refresh Attributes edito parent
1804  refreshAttributeEditorFlow();
1805  return 1;
1806 }
1807 
1808 
1809 long
1811  // obtain undoList (To improve code legibly)
1812  GNEUndoList* undoList = myAttributesEditorParent->getFrameParent()->myViewNet->getUndoList();
1814  // check what check button was pressed
1815  if (obj == myAttributeEndRadioButton) {
1816  attr = SUMO_ATTR_END;
1817  } else if (obj == myAttributeNumberRadioButton) {
1818  attr = SUMO_ATTR_NUMBER;
1819  } else if (obj == myAttributeVehsPerHourRadioButton) {
1820  attr = SUMO_ATTR_VEHSPERHOUR;
1821  } else if (obj == myAttributePeriodRadioButton) {
1822  attr = SUMO_ATTR_PERIOD;
1823  } else if (obj == myAttributeProbabilityRadioButton) {
1824  attr = SUMO_ATTR_PROB;
1825  } else {
1826  throw ProcessError("Invalid Radio Button");
1827  }
1828  // write debug (for Netedit tests)
1829  WRITE_DEBUG("Selected checkBox for attribute '" + toString(attr) + "'");
1830  // begin undo list
1831  if (myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers().size() > 1) {
1832  undoList->p_begin("enable multiple " + toString(attr) + " attributes");
1833  } else {
1834  undoList->p_begin("enable attribute '" + toString(attr) + "'");
1835  }
1836  // enable attribute with undo/redo
1837  for (const auto& i : myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers()) {
1838  i->enableAttribute(attr, undoList);
1839  }
1840  // end undoList
1841  undoList->p_end();
1842  // refresh Attributes edito parent
1843  refreshAttributeEditorFlow();
1844  return 1;
1845 }
1846 
1847 
1848 void
1850  // first we need to check if all attributes are enabled or disabled
1851  int allAttributesEnabledOrDisabled = 0;
1852  for (const auto& i : myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers()) {
1853  allAttributesEnabledOrDisabled += i->isAttributeEnabled(SUMO_ATTR_END);
1854  }
1855  if (allAttributesEnabledOrDisabled == (int)myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers().size()) {
1856  // Declare a set of occuring values and insert attribute's values of item
1857  std::set<std::string> occuringValues;
1858  for (const auto& values : myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers()) {
1859  occuringValues.insert(values->getAttribute(SUMO_ATTR_END));
1860  }
1861  // get current value
1862  std::ostringstream endValue;
1863  for (auto it_val = occuringValues.begin(); it_val != occuringValues.end(); it_val++) {
1864  if (it_val != occuringValues.begin()) {
1865  endValue << " ";
1866  }
1867  endValue << *it_val;
1868  }
1869  // set radio button and text field
1870  myValueEndTextField->enable();
1871  myValueEndTextField->setText(endValue.str().c_str());
1872  myAttributeEndRadioButton->setCheck(TRUE);
1873  } else {
1874  // disable radio button and text field
1875  myValueEndTextField->disable();
1876  // check if we set an special value in textField
1877  if ((allAttributesEnabledOrDisabled > 0) && (myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers().size() > 1)) {
1878  myValueEndTextField->setText("Different flow attributes");
1879  } else if (myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers().size() == 1) {
1880  myValueEndTextField->setText(myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers().front()->getAlternativeValueForDisabledAttributes(SUMO_ATTR_END).c_str());
1881  } else {
1882  myValueEndTextField->setText("");
1883  }
1884  myAttributeEndRadioButton->setCheck(FALSE);
1885  }
1886 }
1887 
1888 
1889 void
1891  // first we need to check if all attributes are enabled or disabled
1892  int allAttributesEnabledOrDisabled = 0;
1893  for (const auto& i : myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers()) {
1894  allAttributesEnabledOrDisabled += i->isAttributeEnabled(SUMO_ATTR_NUMBER);
1895  }
1896  if (allAttributesEnabledOrDisabled == (int)myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers().size()) {
1897  // Declare a set of occuring values and insert attribute's values of item
1898  std::set<std::string> occuringValues;
1899  for (const auto& values : myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers()) {
1900  occuringValues.insert(values->getAttribute(SUMO_ATTR_NUMBER));
1901  }
1902  // get current value
1903  std::ostringstream numberValues;
1904  for (auto it_val = occuringValues.begin(); it_val != occuringValues.end(); it_val++) {
1905  if (it_val != occuringValues.begin()) {
1906  numberValues << " ";
1907  }
1908  numberValues << *it_val;
1909  }
1910  // set radio button and text field
1911  myValueNumberTextField->enable();
1912  myValueNumberTextField->setText(numberValues.str().c_str());
1913  myAttributeNumberRadioButton->setCheck(TRUE);
1914  } else {
1915  // disable radio button
1916  myValueNumberTextField->disable();
1917  // check if we set an special value in textField
1918  if ((allAttributesEnabledOrDisabled > 0) && (myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers().size() > 1)) {
1919  myValueNumberTextField->setText("Different flow attributes");
1920  } else if (myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers().size() == 1) {
1921  myValueNumberTextField->setText(myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers().front()->getAlternativeValueForDisabledAttributes(SUMO_ATTR_NUMBER).c_str());
1922  } else {
1923  myValueNumberTextField->setText("");
1924  }
1925  myAttributeNumberRadioButton->setCheck(FALSE);
1926  }
1927 }
1928 
1929 
1930 void
1932  // declare attribute
1934  // first change attribute
1935  if (myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers().front()->getTagProperty().hasAttribute(SUMO_ATTR_PERSONSPERHOUR)) {
1936  attr = SUMO_ATTR_PERSONSPERHOUR;
1937  }
1938  // update radio button
1939  myAttributeVehsPerHourRadioButton->setText(toString(attr).c_str());
1940  // we need to check if all attributes are enabled or disabled
1941  int allAttributesEnabledOrDisabled = 0;
1942  for (const auto& i : myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers()) {
1943  allAttributesEnabledOrDisabled += i->isAttributeEnabled(attr);
1944  }
1945  if (allAttributesEnabledOrDisabled == (int)myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers().size()) {
1946  // Declare a set of occuring values and insert attribute's values of item
1947  std::set<std::string> occuringValues;
1948  for (const auto& values : myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers()) {
1949  occuringValues.insert(values->getAttribute(attr));
1950  }
1951  // get current value
1952  std::ostringstream vehsPerHourValues;
1953  for (auto it_val = occuringValues.begin(); it_val != occuringValues.end(); it_val++) {
1954  if (it_val != occuringValues.begin()) {
1955  vehsPerHourValues << " ";
1956  }
1957  vehsPerHourValues << *it_val;
1958  }
1959  // set radio button and text field
1960  myValueVehsPerHourTextField->enable();
1961  myValueVehsPerHourTextField->setText(vehsPerHourValues.str().c_str());
1962  myAttributeVehsPerHourRadioButton->setCheck(TRUE);
1963  } else {
1964  // disable radio button
1965  myValueVehsPerHourTextField->disable();
1966  // check if we set an special value in textField
1967  if ((allAttributesEnabledOrDisabled > 0) && (myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers().size() > 1)) {
1968  myValueVehsPerHourTextField->setText("Different flow attributes");
1969  } else if (myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers().size() == 1) {
1970  myValueVehsPerHourTextField->setText(myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers().front()->getAlternativeValueForDisabledAttributes(attr).c_str());
1971  } else {
1972  myValueVehsPerHourTextField->setText("");
1973  }
1974  myAttributeVehsPerHourRadioButton->setCheck(FALSE);
1975  }
1976 }
1977 
1978 
1979 void
1981  // first we need to check if all attributes are enabled or disabled
1982  int allAttributesEnabledOrDisabled = 0;
1983  for (const auto& i : myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers()) {
1984  allAttributesEnabledOrDisabled += i->isAttributeEnabled(SUMO_ATTR_PERIOD);
1985  }
1986  if (allAttributesEnabledOrDisabled == (int)myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers().size()) {
1987  // Declare a set of occuring values and insert attribute's values of item
1988  std::set<std::string> occuringValues;
1989  for (const auto& values : myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers()) {
1990  occuringValues.insert(values->getAttribute(SUMO_ATTR_PERIOD));
1991  }
1992  // get current value
1993  std::ostringstream periodValues;
1994  for (auto it_val = occuringValues.begin(); it_val != occuringValues.end(); it_val++) {
1995  if (it_val != occuringValues.begin()) {
1996  periodValues << " ";
1997  }
1998  periodValues << *it_val;
1999  }
2000  // set radio button and text field
2001  myValuePeriodTextField->enable();
2002  myValuePeriodTextField->setText(periodValues.str().c_str());
2003  myAttributePeriodRadioButton->setCheck(TRUE);
2004  } else {
2005  // disable radio button and text field
2006  myValuePeriodTextField->disable();
2007  // check if we set an special value in textField
2008  if ((allAttributesEnabledOrDisabled > 0) && (myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers().size() > 1)) {
2009  myValuePeriodTextField->setText("Different flow attributes");
2010  } else if (myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers().size() == 1) {
2011  myValuePeriodTextField->setText(myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers().front()->getAlternativeValueForDisabledAttributes(SUMO_ATTR_PERIOD).c_str());
2012  } else {
2013  myValuePeriodTextField->setText("");
2014  }
2015  myAttributePeriodRadioButton->setCheck(FALSE);
2016  }
2017 }
2018 
2019 
2020 void
2022  // first we need to check if all attributes are enabled or disabled
2023  int allAttributesEnabledOrDisabled = 0;
2024  for (const auto& i : myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers()) {
2025  allAttributesEnabledOrDisabled += i->isAttributeEnabled(SUMO_ATTR_PROB);
2026  }
2027  if (allAttributesEnabledOrDisabled == (int)myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers().size()) {
2028  // Declare a set of occuring values and insert attribute's values of item
2029  std::set<std::string> occuringValues;
2030  for (const auto& values : myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers()) {
2031  occuringValues.insert(values->getAttribute(SUMO_ATTR_PROB));
2032  }
2033  // get current value
2034  std::ostringstream probabilityValues;
2035  for (auto it_val = occuringValues.begin(); it_val != occuringValues.end(); it_val++) {
2036  if (it_val != occuringValues.begin()) {
2037  probabilityValues << " ";
2038  }
2039  probabilityValues << *it_val;
2040  }
2041  // set radio button and text field
2042  myValueProbabilityTextField->enable();
2043  myValueProbabilityTextField->setText(probabilityValues.str().c_str());
2044  myAttributeProbabilityRadioButton->enable();
2045  myAttributeProbabilityRadioButton->setCheck(TRUE);
2046  } else {
2047  // disable radio button and text field
2048  myValueProbabilityTextField->disable();
2049  // check if we set an special value in textField
2050  if ((allAttributesEnabledOrDisabled > 0) && (myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers().size() > 1)) {
2051  myValueProbabilityTextField->setText("Different flow attributes");
2052  } else if (myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers().size() == 1) {
2053  myValueProbabilityTextField->setText(myAttributesEditorParent->getFrameParent()->getViewNet()->getInspectedAttributeCarriers().front()->getAlternativeValueForDisabledAttributes(SUMO_ATTR_PROB).c_str());
2054  } else {
2055  myValueProbabilityTextField->setText("");
2056  }
2057  myAttributeProbabilityRadioButton->setCheck(FALSE);
2058  }
2059 }
2060 
2061 // ---------------------------------------------------------------------------
2062 // GNEFrameAttributesModuls::AttributesEditorExtended- methods
2063 // ---------------------------------------------------------------------------
2064 
2066  FXGroupBox(frameParent->myContentFrame, "Extended attributes", GUIDesignGroupBoxFrame),
2067  myFrameParent(frameParent) {
2068  // Create open dialog button
2069  new FXButton(this, "Open attributes editor", nullptr, this, MID_GNE_SET_ATTRIBUTE_DIALOG, GUIDesignButton);
2070 }
2071 
2072 
2074 
2075 
2076 void
2078  show();
2079 }
2080 
2081 
2082 void
2084  hide();
2085 }
2086 
2087 
2088 long
2090  // open AttributesCreator extended dialog
2091  myFrameParent->attributesEditorExtendedDialogOpened();
2092  return 1;
2093 }
2094 
2095 // ---------------------------------------------------------------------------
2096 // GNEFrameAttributesModuls::ParametersEditorCreator - methods
2097 // ---------------------------------------------------------------------------
2098 
2100  FXGroupBox(frameParent->myContentFrame, "Parameters", GUIDesignGroupBoxFrame),
2101  myFrameParent(frameParent),
2102  myAttrType(Parameterised::ParameterisedAttrType::STRING) {
2103  // create textfield and buttons
2105  myButtonEditParameters = new FXButton(this, "Edit parameters", nullptr, this, MID_GNE_OPEN_PARAMETERS_DIALOG, GUIDesignButton);
2106 }
2107 
2108 
2110 
2111 
2112 void
2114  // refresh ParametersEditorCreator
2115  refreshParametersEditorCreator();
2116  // show groupbox
2117  show();
2118 }
2119 
2120 
2121 void
2123  // hide groupbox
2124  hide();
2125 }
2126 
2127 
2128 void
2130  myTextFieldParameters->setText(getParametersStr().c_str());
2131  myTextFieldParameters->setTextColor(FXRGB(0, 0, 0));
2132 }
2133 
2134 
2135 const std::map<std::string, std::string>&
2137  return myParameters;
2138 }
2139 
2140 
2141 std::string
2143  std::string result;
2144  // Generate an string using the following structure: "key1=value1|key2=value2|...
2145  for (const auto& i : myParameters) {
2146  result += i.first + "=" + i.second + "|";
2147  }
2148  // remove the last "|"
2149  if (!result.empty()) {
2150  result.pop_back();
2151  }
2152  return result;
2153 }
2154 
2155 
2156 std::vector<std::pair<std::string, std::string> >
2158  std::vector<std::pair<std::string, std::string> > result;
2159  // Generate a vector string using the following structure: "<key1,value1>, <key2, value2>,...
2160  for (const auto& parameter : myParameters) {
2161  result.push_back(std::make_pair(parameter.first, parameter.second));
2162  }
2163  return result;
2164 }
2165 
2166 
2167 void
2168 GNEFrameAttributesModuls::ParametersEditorCreator::setParameters(const std::vector<std::pair<std::string, std::string> >& parameters) {
2169  // declare result string
2170  std::string result;
2171  // Generate an string using the following structure: "key1=value1|key2=value2|...
2172  for (const auto& i : parameters) {
2173  result += i.first + "=" + i.second + "|";
2174  }
2175  // remove the last "|"
2176  if (!result.empty()) {
2177  result.pop_back();
2178  }
2179  // set result in textField (and call onCmdEditParameters)
2180  myTextFieldParameters->setText(result.c_str(), TRUE);
2181 }
2182 
2183 
2184 GNEFrame*
2186  return myFrameParent;
2187 }
2188 
2189 
2192  return myAttrType;
2193 }
2194 
2195 
2196 long
2198  // write debug information
2199  WRITE_DEBUG("Open single parameters dialog");
2200  if (GNESingleParametersDialog(this).execute()) {
2201  // write debug information
2202  WRITE_DEBUG("Close single parameters dialog");
2203  // Refresh parameter EditorCreator
2204  refreshParametersEditorCreator();
2205  } else {
2206  // write debug information
2207  WRITE_DEBUG("Cancel single parameters dialog");
2208  }
2209  return 1;
2210 }
2211 
2212 
2213 long
2215  // clear current existent parameters
2216  myParameters.clear();
2217  // check if current given string is valid
2218  if (Parameterised::areParametersValid(myTextFieldParameters->getText().text(), true, myAttrType)) {
2219  // parsed parameters ok, then set text field black and continue
2220  myTextFieldParameters->setTextColor(FXRGB(0, 0, 0));
2221  myTextFieldParameters->killFocus();
2222  // obtain parameters "key=value"
2223  std::vector<std::string> parameters = StringTokenizer(myTextFieldParameters->getText().text(), "|", true).getVector();
2224  // iterate over parameters
2225  for (const auto& parameter : parameters) {
2226  // obtain key, value
2227  std::vector<std::string> keyParam = StringTokenizer(parameter, "=", true).getVector();
2228  // save it in myParameters
2229  myParameters[keyParam.front()] = keyParam.back();
2230  }
2231  // overwritte myTextFieldParameters (to remove duplicated parameters
2232  myTextFieldParameters->setText(getParametersStr().c_str(), FALSE);
2233  } else {
2234  myTextFieldParameters->setTextColor(FXRGB(255, 0, 0));
2235  }
2236  return 1;
2237 }
2238 
2239 // ---------------------------------------------------------------------------
2240 // GNEFrameAttributesModuls::DrawingShape - methods
2241 // ---------------------------------------------------------------------------
2242 
2244  FXGroupBox(frameParent->myContentFrame, "Drawing", GUIDesignGroupBoxFrame),
2245  myFrameParent(frameParent),
2246  myDeleteLastCreatedPoint(false) {
2247  // create start and stop buttons
2248  myStartDrawingButton = new FXButton(this, "Start drawing", 0, this, MID_GNE_STARTDRAWING, GUIDesignButton);
2249  myStopDrawingButton = new FXButton(this, "Stop drawing", 0, this, MID_GNE_STOPDRAWING, GUIDesignButton);
2250  myAbortDrawingButton = new FXButton(this, "Abort drawing", 0, this, MID_GNE_ABORTDRAWING, GUIDesignButton);
2251  // create information label
2252  std::ostringstream information;
2253  information
2254  << "- 'Start drawing' or ENTER\n"
2255  << " draws shape boundary.\n"
2256  << "- 'Stop drawing' or ENTER\n"
2257  << " creates shape.\n"
2258  << "- 'Shift + Click'removes\n"
2259  << " last created point.\n"
2260  << "- 'Abort drawing' or ESC\n"
2261  << " removes drawed shape.";
2262  myInformationLabel = new FXLabel(this, information.str().c_str(), 0, GUIDesignLabelFrameInformation);
2263  // disable stop and abort functions as init
2264  myStopDrawingButton->disable();
2265  myAbortDrawingButton->disable();
2266 }
2267 
2268 
2270 
2271 
2273  // abort current drawing before show
2274  abortDrawing();
2275  // show FXGroupBox
2276  FXGroupBox::show();
2277 }
2278 
2279 
2281  // abort current drawing before hide
2282  abortDrawing();
2283  // show FXGroupBox
2284  FXGroupBox::hide();
2285 }
2286 
2287 
2288 void
2290  // Only start drawing if DrawingShape modul is shown
2291  if (shown()) {
2292  // change buttons
2293  myStartDrawingButton->disable();
2294  myStopDrawingButton->enable();
2295  myAbortDrawingButton->enable();
2296  }
2297 }
2298 
2299 
2300 void
2302  // try to build shape
2303  if (myFrameParent->shapeDrawed()) {
2304  // clear created points
2305  myTemporalShapeShape.clear();
2306  myFrameParent->myViewNet->updateViewNet();
2307  // change buttons
2308  myStartDrawingButton->enable();
2309  myStopDrawingButton->disable();
2310  myAbortDrawingButton->disable();
2311  } else {
2312  // abort drawing if shape cannot be created
2313  abortDrawing();
2314  }
2315 }
2316 
2317 
2318 void
2320  // clear created points
2321  myTemporalShapeShape.clear();
2322  myFrameParent->myViewNet->updateViewNet();
2323  // change buttons
2324  myStartDrawingButton->enable();
2325  myStopDrawingButton->disable();
2326  myAbortDrawingButton->disable();
2327 }
2328 
2329 
2330 void
2332  if (myStopDrawingButton->isEnabled()) {
2333  myTemporalShapeShape.push_back(P);
2334  } else {
2335  throw ProcessError("A new point cannot be added if drawing wasn't started");
2336  }
2337 }
2338 
2339 
2340 void
2342 
2343 }
2344 
2345 
2346 const PositionVector&
2348  return myTemporalShapeShape;
2349 }
2350 
2351 
2352 bool
2354  return myStopDrawingButton->isEnabled();
2355 }
2356 
2357 
2358 void
2360  myDeleteLastCreatedPoint = value;
2361 }
2362 
2363 
2364 bool
2366  return myDeleteLastCreatedPoint;
2367 }
2368 
2369 
2370 long
2372  startDrawing();
2373  return 0;
2374 }
2375 
2376 
2377 long
2379  stopDrawing();
2380  return 0;
2381 }
2382 
2383 
2384 long
2386  abortDrawing();
2387  return 0;
2388 }
2389 
2390 // ---------------------------------------------------------------------------
2391 // GNEFrameAttributesModuls::NeteditAttributes- methods
2392 // ---------------------------------------------------------------------------
2393 
2395  FXGroupBox(frameParent->myContentFrame, "Netedit attributes", GUIDesignGroupBoxFrame),
2396  myFrameParent(frameParent),
2397  myCurrentLengthValid(true),
2398  myActualAdditionalReferencePoint(GNE_ADDITIONALREFERENCEPOINT_LEFT) {
2399  // Create FXListBox for the reference points and fill it
2401  myReferencePointMatchBox->appendItem("reference left");
2402  myReferencePointMatchBox->appendItem("reference right");
2403  myReferencePointMatchBox->appendItem("reference center");
2404  // Create Frame for Length Label and textField
2405  myLengthFrame = new FXHorizontalFrame(this, GUIDesignAuxiliarHorizontalFrame);
2408  myLengthTextField->setText("10");
2409  // Create Frame for block movement label and checkBox (By default disabled)
2410  myBlockMovementFrame = new FXHorizontalFrame(this, GUIDesignAuxiliarHorizontalFrame);
2411  new FXLabel(myBlockMovementFrame, "block move", 0, GUIDesignLabelAttribute);
2413  myBlockMovementCheckButton->setCheck(false);
2414  // Create Frame for block shape label and checkBox (By default disabled)
2415  myBlockShapeFrame = new FXHorizontalFrame(this, GUIDesignAuxiliarHorizontalFrame);
2416  new FXLabel(myBlockShapeFrame, "block shape", 0, GUIDesignLabelAttribute);
2418  // Create Frame for block close polygon and checkBox (By default disabled)
2419  myCloseShapeFrame = new FXHorizontalFrame(this, GUIDesignAuxiliarHorizontalFrame);
2420  new FXLabel(myCloseShapeFrame, "Close shape", 0, GUIDesignLabelAttribute);
2422  myBlockShapeCheckButton->setCheck(false);
2423  // Create Frame for center element after creation (By default enabled)
2425  new FXLabel(myCenterViewAfterCreationFrame, "Center view", 0, GUIDesignLabelAttribute);
2427  myCenterViewAfterCreationButton->setCheck(true);
2428  // Create help button
2429  helpReferencePoint = new FXButton(this, "Help", 0, this, MID_HELP, GUIDesignButtonRectangular);
2430  // Set visible items
2431  myReferencePointMatchBox->setNumVisible((int)myReferencePointMatchBox->getNumItems());
2432 }
2433 
2434 
2436 
2437 
2438 void
2440  // we assume that frame will not be show
2441  bool showFrame = false;
2442  // check if length text field has to be showed
2443  if (tagProperty.canMaskStartEndPos()) {
2444  myLengthFrame->show();
2445  myReferencePointMatchBox->show();
2446  showFrame = true;
2447  } else {
2448  myLengthFrame->hide();
2449  myReferencePointMatchBox->hide();
2450  }
2451  // check if block movement check button has to be show
2452  if (tagProperty.canBlockMovement()) {
2453  myBlockMovementFrame->show();
2454  showFrame = true;
2455  } else {
2456  myBlockMovementFrame->hide();
2457  }
2458  // check if block shape check button has to be show
2459  if (tagProperty.canBlockShape()) {
2460  myBlockShapeFrame->show();
2461  showFrame = true;
2462  } else {
2463  myBlockShapeFrame->hide();
2464  }
2465  // check if close shape check button has to be show
2466  if (tagProperty.canCloseShape()) {
2467  myCloseShapeFrame->show();
2468  showFrame = true;
2469  } else {
2470  myCloseShapeFrame->hide();
2471  }
2472  // check if center camera after creation check button has to be show
2473  if (tagProperty.canCenterCameraAfterCreation()) {
2474  myCenterViewAfterCreationFrame->show();
2475  showFrame = true;
2476  } else {
2477  myCenterViewAfterCreationFrame->hide();
2478  }
2479  // if at least one element is show, show modul
2480  if (showFrame) {
2481  recalc();
2482  show();
2483  } else {
2484  hide();
2485  }
2486 }
2487 
2488 
2489 void
2491  hide();
2492 }
2493 
2494 
2495 bool
2496 GNEFrameAttributesModuls::NeteditAttributes::getNeteditAttributesAndValues(std::map<SumoXMLAttr, std::string>& valuesMap, const GNELane* lane) const {
2497  // check if we need to obtain a start and end position over an edge
2498  if (myReferencePointMatchBox->shown()) {
2499  // we need a valid lane to calculate position over lane
2500  if (lane == nullptr) {
2501  return false;
2502  } else if (myCurrentLengthValid) {
2503  // Obtain position of the mouse over lane (limited over grid)
2504  double mousePositionOverLane = lane->getLaneShape().nearest_offset_to_point2D(myFrameParent->myViewNet->snapToActiveGrid(myFrameParent->myViewNet->getPositionInformation())) / lane->getLengthGeometryFactor();
2505  // check if current reference point is valid
2506  if (myActualAdditionalReferencePoint == GNE_ADDITIONALREFERENCEPOINT_INVALID) {
2507  std::string errorMessage = "Current selected reference point isn't valid";
2508  myFrameParent->myViewNet->setStatusBarText(errorMessage);
2509  // Write Warning in console if we're in testing mode
2510  WRITE_DEBUG(errorMessage);
2511  return false;
2512  } else {
2513  // obtain length
2514  double length = GNEAttributeCarrier::parse<double>(myLengthTextField->getText().text());
2515  // set start and end position
2516  valuesMap[SUMO_ATTR_STARTPOS] = toString(setStartPosition(mousePositionOverLane, length));
2517  valuesMap[SUMO_ATTR_ENDPOS] = toString(setEndPosition(mousePositionOverLane, length));
2518  }
2519  } else {
2520  return false;
2521  }
2522  }
2523  // Save block value if element can be blocked
2524  if (myBlockMovementCheckButton->shown()) {
2525  if (myBlockMovementCheckButton->getCheck() == 1) {
2526  valuesMap[GNE_ATTR_BLOCK_MOVEMENT] = "1";
2527  } else {
2528  valuesMap[GNE_ATTR_BLOCK_MOVEMENT] = "0";
2529  }
2530  }
2531  // Save block shape value if shape's element can be blocked
2532  if (myBlockShapeCheckButton->shown()) {
2533  if (myBlockShapeCheckButton->getCheck() == 1) {
2534  valuesMap[GNE_ATTR_BLOCK_SHAPE] = "1";
2535  } else {
2536  valuesMap[GNE_ATTR_BLOCK_SHAPE] = "0";
2537  }
2538  }
2539  // Save close shape value if shape's element can be closed
2540  if (myCloseShapeCheckButton->shown()) {
2541  if (myCloseShapeCheckButton->getCheck() == 1) {
2542  valuesMap[GNE_ATTR_CLOSE_SHAPE] = "1";
2543  } else {
2544  valuesMap[GNE_ATTR_CLOSE_SHAPE] = "0";
2545  }
2546  }
2547  // check center element after creation
2548  if (myCenterViewAfterCreationButton->shown() && (myCenterViewAfterCreationButton->getCheck() == 1)) {
2549  valuesMap[GNE_ATTR_CENTER_AFTER_CREATION] = "1";
2550  }
2551  // all ok, then return true to continue creating element
2552  return true;
2553 }
2554 
2555 
2556 long
2558  if (obj == myBlockMovementCheckButton) {
2559  if (myBlockMovementCheckButton->getCheck()) {
2560  myBlockMovementCheckButton->setText("true");
2561  } else {
2562  myBlockMovementCheckButton->setText("false");
2563  }
2564  } else if (obj == myBlockShapeCheckButton) {
2565  if (myBlockShapeCheckButton->getCheck()) {
2566  myBlockShapeCheckButton->setText("true");
2567  } else {
2568  myBlockShapeCheckButton->setText("false");
2569  }
2570  } else if (obj == myCloseShapeCheckButton) {
2571  if (myCloseShapeCheckButton->getCheck()) {
2572  myCloseShapeCheckButton->setText("true");
2573  } else {
2574  myCloseShapeCheckButton->setText("false");
2575  }
2576  } else if (obj == myCenterViewAfterCreationButton) {
2577  if (myCenterViewAfterCreationButton->getCheck()) {
2578  myCenterViewAfterCreationButton->setText("true");
2579  } else {
2580  myCenterViewAfterCreationButton->setText("false");
2581  }
2582  } else if (obj == myLengthTextField) {
2583  // change color of text field depending of the input length
2584  if (GNEAttributeCarrier::canParse<double>(myLengthTextField->getText().text()) &&
2585  GNEAttributeCarrier::parse<double>(myLengthTextField->getText().text()) > 0) {
2586  myLengthTextField->setTextColor(FXRGB(0, 0, 0));
2587  myLengthTextField->killFocus();
2588  myCurrentLengthValid = true;
2589  } else {
2590  myLengthTextField->setTextColor(FXRGB(255, 0, 0));
2591  myCurrentLengthValid = false;
2592  }
2593  // Update aditional frame
2594  update();
2595  } else if (obj == myReferencePointMatchBox) {
2596  // Cast actual reference point type
2597  if (myReferencePointMatchBox->getText() == "reference left") {
2598  myReferencePointMatchBox->setTextColor(FXRGB(0, 0, 0));
2599  myActualAdditionalReferencePoint = GNE_ADDITIONALREFERENCEPOINT_LEFT;
2600  myLengthTextField->enable();
2601  } else if (myReferencePointMatchBox->getText() == "reference right") {
2602  myReferencePointMatchBox->setTextColor(FXRGB(0, 0, 0));
2603  myActualAdditionalReferencePoint = GNE_ADDITIONALREFERENCEPOINT_RIGHT;
2604  myLengthTextField->enable();
2605  } else if (myReferencePointMatchBox->getText() == "reference center") {
2606  myLengthTextField->enable();
2607  myReferencePointMatchBox->setTextColor(FXRGB(0, 0, 0));
2608  myActualAdditionalReferencePoint = GNE_ADDITIONALREFERENCEPOINT_CENTER;
2609  myLengthTextField->enable();
2610  } else {
2611  myReferencePointMatchBox->setTextColor(FXRGB(255, 0, 0));
2612  myActualAdditionalReferencePoint = GNE_ADDITIONALREFERENCEPOINT_INVALID;
2613  myLengthTextField->disable();
2614  }
2615  }
2616 
2617  return 1;
2618 }
2619 
2620 
2621 long
2623  // Create dialog box
2624  FXDialogBox* additionalNeteditAttributesHelpDialog = new FXDialogBox(this, "Netedit Parameters Help", GUIDesignDialogBox);
2625  additionalNeteditAttributesHelpDialog->setIcon(GUIIconSubSys::getIcon(GUIIcon::MODEADDITIONAL));
2626  // set help text
2627  std::ostringstream help;
2628  help
2629  << "- Referece point: Mark the initial position of the additional element.\n"
2630  << " Example: If you want to create a busStop with a length of 30 in the point 100 of the lane:\n"
2631  << " - Reference Left will create it with startPos = 70 and endPos = 100.\n"
2632  << " - Reference Right will create it with startPos = 100 and endPos = 130.\n"
2633  << " - Reference Center will create it with startPos = 85 and endPos = 115.\n"
2634  << "\n"
2635  << "- Block movement: if is enabled, the created additional element will be blocked. i.e. cannot be moved with\n"
2636  << " the mouse. This option can be modified inspecting element.\n"
2637  << "- Center view: if is enabled, view will be center over created element.";
2638  // Create label with the help text
2639  new FXLabel(additionalNeteditAttributesHelpDialog, help.str().c_str(), 0, GUIDesignLabelFrameInformation);
2640  // Create horizontal separator
2641  new FXHorizontalSeparator(additionalNeteditAttributesHelpDialog, GUIDesignHorizontalSeparator);
2642  // Create frame for OK Button
2643  FXHorizontalFrame* myHorizontalFrameOKButton = new FXHorizontalFrame(additionalNeteditAttributesHelpDialog, GUIDesignAuxiliarHorizontalFrame);
2644  // Create Button Close (And two more horizontal frames to center it)
2645  new FXHorizontalFrame(myHorizontalFrameOKButton, GUIDesignAuxiliarHorizontalFrame);
2646  new FXButton(myHorizontalFrameOKButton, "OK\t\tclose", GUIIconSubSys::getIcon(GUIIcon::ACCEPT), additionalNeteditAttributesHelpDialog, FXDialogBox::ID_ACCEPT, GUIDesignButtonOK);
2647  new FXHorizontalFrame(myHorizontalFrameOKButton, GUIDesignAuxiliarHorizontalFrame);
2648  // Write Warning in console if we're in testing mode
2649  WRITE_DEBUG("Opening NeteditAttributes help dialog");
2650  // create Dialog
2651  additionalNeteditAttributesHelpDialog->create();
2652  // show in the given position
2653  additionalNeteditAttributesHelpDialog->show(PLACEMENT_CURSOR);
2654  // refresh APP
2655  getApp()->refresh();
2656  // open as modal dialog (will block all windows until stop() or stopModal() is called)
2657  getApp()->runModalFor(additionalNeteditAttributesHelpDialog);
2658  // Write Warning in console if we're in testing mode
2659  WRITE_DEBUG("Closing NeteditAttributes help dialog");
2660  return 1;
2661  /**********
2662  help from PolygonFrame
2663  << "- Block movement: If enabled, the created polygon element will be blocked. i.e. cannot be moved with\n"
2664  << " the mouse. This option can be modified inspecting element.\n"
2665  << "\n"
2666  << "- Block shape: If enabled, the shape of created polygon element will be blocked. i.e. their geometry points\n"
2667  << " cannot be edited be moved with the mouse. This option can be modified inspecting element.\n"
2668  << "\n"
2669  << "- Close shape: If enabled, the created polygon element will be closed. i.e. the last created geometry point\n"
2670  << " will be connected with the first geometry point automatically. This option can be modified inspecting element.";
2671 
2672  ****************/
2673 }
2674 
2675 
2676 double
2677 GNEFrameAttributesModuls::NeteditAttributes::setStartPosition(double positionOfTheMouseOverLane, double lengthOfAdditional) const {
2678  switch (myActualAdditionalReferencePoint) {
2679  case GNE_ADDITIONALREFERENCEPOINT_LEFT:
2680  return positionOfTheMouseOverLane;
2681  case GNE_ADDITIONALREFERENCEPOINT_RIGHT:
2682  return positionOfTheMouseOverLane - lengthOfAdditional;
2683  case GNE_ADDITIONALREFERENCEPOINT_CENTER:
2684  return positionOfTheMouseOverLane - lengthOfAdditional / 2;
2685  default:
2686  throw InvalidArgument("Reference Point invalid");
2687  }
2688 }
2689 
2690 
2691 double
2692 GNEFrameAttributesModuls::NeteditAttributes::setEndPosition(double positionOfTheMouseOverLane, double lengthOfAdditional) const {
2693  switch (myActualAdditionalReferencePoint) {
2694  case GNE_ADDITIONALREFERENCEPOINT_LEFT:
2695  return positionOfTheMouseOverLane + lengthOfAdditional;
2696  case GNE_ADDITIONALREFERENCEPOINT_RIGHT:
2697  return positionOfTheMouseOverLane;
2698  case GNE_ADDITIONALREFERENCEPOINT_CENTER:
2699  return positionOfTheMouseOverLane + lengthOfAdditional / 2;
2700  default:
2701  throw InvalidArgument("Reference Point invalid");
2702  }
2703 }
2704 
2705 
2706 bool
2708  if (viewNet->getEditModes().isCurrentSupermodeNetwork() && (
2709  AC->getTagProperty().isNetworkElement() ||
2711  AC->getTagProperty().isShape() ||
2712  AC->getTagProperty().isTAZElement())) {
2713  return true;
2714  } else if (viewNet->getEditModes().isCurrentSupermodeDemand() &&
2715  AC->getTagProperty().isDemandElement()) {
2716  return true;
2717  } else if (viewNet->getEditModes().isCurrentSupermodeData() &&
2718  AC->getTagProperty().isDataElement()) {
2719  return true;
2720  } else {
2721  return false;
2722  }
2723 }
2724 
2725 
2726 bool
2730  return (viewNet->getEditModes().isCurrentSupermodeNetwork());
2731  } else if (ACAttr.getTagPropertyParent().isDemandElement()) {
2732  return (viewNet->getEditModes().isCurrentSupermodeDemand());
2733  } else if (ACAttr.getTagPropertyParent().isDataElement()) {
2734  return (viewNet->getEditModes().isCurrentSupermodeData());
2735  } else {
2736  return false;
2737  }
2738 }
2739 
2740 /****************************************************************************/
FXDEFMAP(GNEFrameAttributesModuls::AttributesCreatorRow) RowCreatorMap[]
@ DEMAND_VEHICLE
Mode for editing vehicles.
@ MID_GNE_SET_ATTRIBUTE
attribute edited
Definition: GUIAppEnum.h:717
@ MID_GNE_OPEN_PARAMETERS_DIALOG
open parameters dialog
Definition: GUIAppEnum.h:751
@ MID_GNE_SET_ATTRIBUTE_BUTTON
attribute selected using button (radio button or checkbox)
Definition: GUIAppEnum.h:753
@ MID_GNE_SET_ATTRIBUTE_DIALOG
attribute edited trought dialog
Definition: GUIAppEnum.h:749
@ MID_GNE_STARTDRAWING
start drawing polygon
Definition: GUIAppEnum.h:777
@ MID_HELP
help button
Definition: GUIAppEnum.h:578
@ MID_GNE_ABORTDRAWING
abort drawing polygon
Definition: GUIAppEnum.h:781
@ MID_GNE_STOPDRAWING
stop drawing polygon
Definition: GUIAppEnum.h:779
@ MID_GNE_SET_ATTRIBUTE_BOOL
bool attribute edited
Definition: GUIAppEnum.h:747
#define GUIDesignButtonAttribute
button extended over over column with thick and raise frame
Definition: GUIDesigns.h:65
#define GUIDesignButton
Definition: GUIDesigns.h:62
#define GUIDesignComboBoxAttribute
Combo box static (cannot be edited) extended over the matrix column.
Definition: GUIDesigns.h:246
#define GUIDesignComboBox
Definition: GUIDesigns.h:237
#define GUIDesignComboBoxNCol
number of column of every combo box
Definition: GUIDesigns.h:255
#define GUIDesignTextField
Definition: GUIDesigns.h:36
#define GUIDesignAuxiliarHorizontalFrame
design for auxiliar (Without borders) horizontal frame used to pack another frames
Definition: GUIDesigns.h:313
#define GUIDesignLabelAttribute
label extended over the matrix column with thick frame
Definition: GUIDesigns.h:199
#define GUIDesignDialogBox
Definition: GUIDesigns.h:494
#define GUIDesignButtonRectangular
little button rectangula used in frames (For example, in "help" buttons)
Definition: GUIDesigns.h:68
#define GUIDesignTextFieldNCol
Num of column of text field.
Definition: GUIDesigns.h:54
#define GUIDesignGroupBoxFrame
Group box design extended over frame.
Definition: GUIDesigns.h:278
#define GUIDesignButtonOK
Definition: GUIDesigns.h:115
#define GUIDesignRadioButtonAttribute
design for radio button with fixed height
Definition: GUIDesigns.h:167
#define GUIDesignCheckButton
checkButton placed in left position
Definition: GUIDesigns.h:133
#define GUIDesignHorizontalSeparator
Definition: GUIDesigns.h:362
#define GUIDesignCheckButtonAttribute
checkButton without thick extended over the frame used for attributes
Definition: GUIDesigns.h:139
#define GUIDesignLabelFrameInformation
label extended over frame without thick and with text justify to left, used to show information in fr...
Definition: GUIDesigns.h:223
@ MODEADDITIONAL
#define WRITE_DEBUG(msg)
Definition: MsgHandler.h:286
long long int SUMOTime
Definition: SUMOTime.h:31
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
const int VEHPARS_PROB_SET
const int VEHPARS_VPH_SET
const int VEHPARS_END_SET
DepartLaneDefinition
Possible ways to choose a lane on depart.
ArrivalSpeedDefinition
Possible ways to choose the arrival speed.
DepartPosLatDefinition
DepartPosDefinition
Possible ways to choose the departure position.
ArrivalLaneDefinition
Possible ways to choose the arrival lane.
DepartSpeedDefinition
Possible ways to choose the departure speed.
const int VEHPARS_NUMBER_SET
ArrivalPosDefinition
Possible ways to choose the arrival position.
const int VEHPARS_PERIOD_SET
ArrivalPosLatDefinition
Possible ways to choose the departure position.
DepartDefinition
Possible ways to depart.
@ SUMO_TAG_E2DETECTOR
an e2 detector
@ SUMO_TAG_VAPORIZER
vaporizer of vehicles
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
@ SUMO_ATTR_CONTAINER_TRIGGERED
@ SUMO_ATTR_STARTPOS
@ SUMO_ATTR_PARKING
@ SUMO_ATTR_EXTENSION
@ SUMO_ATTR_NUMBER
@ SUMO_ATTR_ALLOW
@ SUMO_ATTR_ARRIVALSPEED
@ SUMO_ATTR_ARRIVALLANE
@ SUMO_ATTR_DEPART
@ GNE_ATTR_CENTER_AFTER_CREATION
flag to center camera after element creation
@ SUMO_ATTR_VEHSPERHOUR
@ SUMO_ATTR_DEPARTPOS_LAT
@ GNE_ATTR_BLOCK_MOVEMENT
block movement of a graphic element
@ SUMO_ATTR_ENDPOS
@ SUMO_ATTR_ARRIVALPOS
@ SUMO_ATTR_BEGIN
weights: time range begin
@ SUMO_ATTR_EXPECTED
@ SUMO_ATTR_MODES
@ GNE_ATTR_CLOSE_SHAPE
Close shape of a polygon (Used by GNEPolys)
@ SUMO_ATTR_VTYPES
@ SUMO_ATTR_SHAPE
edge: the shape in xml-definition
@ SUMO_ATTR_DEPARTPOS
@ SUMO_ATTR_INDEX
@ SUMO_ATTR_NAME
@ SUMO_ATTR_PERIOD
@ SUMO_ATTR_FREQUENCY
@ SUMO_ATTR_DEPARTSPEED
@ SUMO_ATTR_ANGLE
@ SUMO_ATTR_TRIP_ID
@ SUMO_ATTR_END
weights: time range end
@ SUMO_ATTR_DEPARTLANE
@ SUMO_ATTR_PROB
@ GNE_ATTR_BLOCK_SHAPE
block shape of a graphic element (Used mainly in GNEShapes)
@ SUMO_ATTR_EXPECTED_CONTAINERS
@ SUMO_ATTR_TYPE
@ SUMO_ATTR_LENGTH
@ SUMO_ATTR_ID
@ SUMO_ATTR_UNTIL
@ SUMO_ATTR_ARRIVALPOS_LAT
@ SUMO_ATTR_IMGFILE
@ SUMO_ATTR_TRIGGERED
@ SUMO_ATTR_POSITION
@ SUMO_ATTR_NOTHING
invalid attribute
@ SUMO_ATTR_PERSONSPERHOUR
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:44
Dialog for edit rerouters.
GNEViewNet * myViewNet
FOX need this.
const GNETagProperties & getTagProperty() const
get Tag Property assigned to this object
static bool canParse(const std::string &string)
true if a value of type T can be parsed from string
static const size_t MAXNUMBEROFATTRIBUTES
max number of attributes allowed for every tag
bool isColor() const
return true if atribute is a color
bool isBool() const
return true if atribute is boolean
const std::string & getAttrStr() const
get XML Attribute
bool isDiscrete() const
return true if atribute is discrete
bool isVClasses() const
return true if atribute is a list of VClasses
bool isActivatable() const
return true if atribute is activatable
const std::vector< std::string > & getDiscreteValues() const
get discrete values
SumoXMLAttr getAttr() const
get XML Attribute
const GNETagProperties & getTagPropertyParent() const
get reference to tagProperty parent
FXTextField * myValueVehsPerHourTextField
textField for 'VehsPerHour' attribute
void showWarningMessage(std::string extra="") const
show warning message with information about non-valid attributes
FXRadioButton * myAttributeEndRadioButton
Radio button for 'end' attribute.
FXTextField * myValuePeriodTextField
textField for 'period' attribute
AttributesCreatorFlow(AttributesCreator *attributesCreatorParent)
FOX-declaration.
FXTextField * myValueEndTextField
textField for 'end' attribute
long onCmdSelectFlowRadioButton(FXObject *, FXSelector, void *)
called when user press a radio button
void setFlowParameters(std::map< SumoXMLAttr, std::string > &parameters)
set parameters
FXRadioButton * myAttributeNumberRadioButton
Radio button for 'number' attribute.
FXRadioButton * myAttributePeriodRadioButton
Radio button for 'period' attribute.
void refreshAttributesCreatorFlow()
refresh AttributesCreatorFlow
long onCmdSetFlowAttribute(FXObject *, FXSelector, void *)
FXTextField * myValueNumberTextField
textField for 'number' attribute
void showAttributesCreatorFlowModul(const bool persons)
show AttributesCreatorFlow modul
FXRadioButton * myAttributeProbabilityRadioButton
Radio button for 'probability' attribute.
FXTextField * myValueProbabilityTextField
textField for 'probability' attribute
FXRadioButton * myAttributeVehsPerHourRadioButton
Radio button for 'VehsPerHour' attribute.
bool areValuesValid() const
check if parameters of attributes are valid
long onCmdHelp(FXObject *, FXSelector, void *)
GNEFrame * getFrameParent() const
return frame parent
void refreshRows()
refresh rows (called after creating an element)
void showAttributesCreatorModul(const GNETagProperties &tagProperties, const std::vector< SumoXMLAttr > &hiddenAttributes)
show AttributesCreator modul
std::map< SumoXMLAttr, std::string > getAttributesAndValues(bool includeAll) const
get attributes and their values
std::vector< AttributesCreatorRow * > myAttributesCreatorRows
vector with the AttributesCreatorRow
AttributesCreatorFlow * myAttributesCreatorFlow
pointer to myAttributesCreatorFlow
bool areValuesValid() const
check if parameters of attributes are valid
void showWarningMessage(std::string extra="") const
show warning message with information about non-valid attributes
AttributesCreator(GNEFrame *frameParent)
constructor
GNETagProperties getCurrentTagProperties() const
get current edited Tag Properties
AttributesCreator * getAttributesCreatorParent() const
get AttributesCreator parent
long onCmdSelectCheckButton(FXObject *, FXSelector, void *)
called when user press a check button
bool isAttributesCreatorRowEnabled() const
check if row is enabled
long onCmdSelectColorButton(FXObject *, FXSelector, void *)
called when user press the "Color" button
bool isValidID() const
check if current ID placed in myValueTextField is valid
void setAttributeCheckButtonCheck(bool value)
enable or disable label checkbox button for optional attributes
const std::string & isAttributeValid() const
returns a empty string if current value is valid, a string with information about invalid value in ot...
const GNEAttributeProperties & getAttrProperties() const
return Attr
long onCmdSetAttribute(FXObject *, FXSelector, void *)
std::string checkComplexAttribute(const std::string &value)
check if given complex attribute is valid
void destroy()
destroy AttributesCreatorRow (but don't delete)
bool getAttributeCheckButtonCheck() const
return status of label checkbox button
AttributesEditorExtended(GNEFrame *frameParent)
FOX-declaration.
void showAttributesEditorExtendedModul()
show AttributesEditorExtended modul
FXTextField * myValueEndTextField
textField for 'end' attribute
FXTextField * myValuePeriodTextField
textField for 'period' attribute
long onCmdSetFlowAttribute(FXObject *, FXSelector, void *)
FXRadioButton * myAttributeVehsPerHourRadioButton
Radio button for 'VehsPerHour' attribute.
long onCmdSelectFlowRadioButton(FXObject *, FXSelector, void *)
called when user press a radio button
FXTextField * myValueVehsPerHourTextField
textField for 'VehsPerHour' attribute
FXRadioButton * myAttributeNumberRadioButton
Radio button for 'number' attribute.
void refreshVehsPerHour()
refresh parameter VehsPerHour
void refreshProbability()
refresh parameter Probability
void refreshAttributeEditorFlow()
refresh attribute EditorFlow (only the valid values will be refresh)
AttributesEditorFlow(AttributesEditor *attributesEditorParent)
FOX-declaration.
FXRadioButton * myAttributeEndRadioButton
Radio button for 'end' attribute.
bool isAttributesEditorFlowModulShown() const
check if attribute editor flow modul is shown
FXTextField * myValueProbabilityTextField
textField for 'probability' attribute
FXTextField * myValueNumberTextField
textField for 'number' attribute
FXRadioButton * myAttributePeriodRadioButton
Radio button for 'period' attribute.
void showAttributeEditorFlowModul()
show attributes editor Flow Modul
FXRadioButton * myAttributeProbabilityRadioButton
Radio button for 'probability' attribute.
AttributesEditorFlow * myAttributesEditorFlow
pointer to attributesEditorFlow
void showAttributeEditorModul(bool includeExtended, bool forceAttributeEnabled)
show attributes of multiple ACs
std::vector< AttributesEditorRow * > myAttributesEditorRows
list of Attribute editor rows
long onCmdAttributesEditorHelp(FXObject *, FXSelector, void *)
void refreshAttributeEditor(bool forceRefreshShape, bool forceRefreshPosition)
refresh attribute editor (only the valid values will be refresh)
GNEFrame * getFrameParent() const
pointer to GNEFrame parent
AttributesEditor(GNEFrame *inspectorFrameParent)
FOX-declaration.
bool isAttributesEditorRowValid() const
check if current attribute of TextField/ComboBox is valid
FXCheckButton * myValueCheckButton
pointer to menu check
FXLabel * myAttributeLabel
pointer to attribute label
FXButton * myAttributeColorButton
Button for open color editor.
void destroy()
destroy AttributesCreatorRow (but don't delete)
FXTextField * myValueTextField
textField to modify the value of string attributes
long onCmdOpenAttributeDialog(FXObject *, FXSelector, void *)
open model dialog for more comfortable attribute editing
void refreshAttributesEditorRow(const std::string &value, bool forceRefresh, bool attributeEnabled)
refresh current row
long onCmdSelectCheckButton(FXObject *, FXSelector, void *)
called when user press a check button
std::string stripWhitespaceAfterComma(const std::string &stringValue)
removed invalid spaces of Positions and shapes
const GNEAttributeProperties myACAttr
current AC Attribute
FXButton * myAttributeButtonCombinableChoices
pointer to buttonCombinableChoices
long onCmdSetAttribute(FXObject *, FXSelector, void *)
try to set new attribute value
AttributesEditor * myAttributesEditorParent
pointer to AttributesEditor parent
FXComboBox * myValueComboBoxChoices
pointer to combo box choices
const bool myMultiple
flag to check if input element contains multiple values
FXCheckButton * myAttributeCheckButton
pointer to attribute menu check
const PositionVector & getTemporalShape() const
get Temporal shape
void addNewPoint(const Position &P)
add new point to temporal shape
FXButton * myStartDrawingButton
button for start drawing
bool getDeleteLastCreatedPoint()
get flag delete last created point
FXLabel * myInformationLabel
Label with information.
void setDeleteLastCreatedPoint(bool value)
enable or disable delete last created point
void stopDrawing()
stop drawing and check if shape can be created
long onCmdAbortDrawing(FXObject *, FXSelector, void *)
Called when the user press abort drawing button.
bool isDrawing() const
return true if currently a shape is drawed
DrawingShape(GNEFrame *frameParent)
FOX-declaration.
FXButton * myAbortDrawingButton
button for abort drawing
long onCmdStopDrawing(FXObject *, FXSelector, void *)
Called when the user press stop drawing button.
long onCmdStartDrawing(FXObject *, FXSelector, void *)
FXButton * myStopDrawingButton
button for stop drawing
void showNeteditAttributesModul(const GNETagProperties &tagValue)
show Netedit attributes modul
FXCheckButton * myBlockShapeCheckButton
checkBox for block shape
FXTextField * myLengthTextField
textField for length
FXHorizontalFrame * myBlockShapeFrame
horizontal frame for block shape
FXCheckButton * myCenterViewAfterCreationButton
checkbox to enable/disable center element after creation
long onCmdSetNeteditAttribute(FXObject *, FXSelector, void *)
FXHorizontalFrame * myCenterViewAfterCreationFrame
horizontal frame for center view after creation frame
double setEndPosition(double positionOfTheMouseOverLane, double lengthOfAdditional) const
obtain the End position values of StoppingPlaces and E2 detector over the lane
FXHorizontalFrame * myBlockMovementFrame
horizontal frame for block movement
NeteditAttributes(GNEFrame *frameParent)
FOX-declaration.
FXCheckButton * myBlockMovementCheckButton
checkBox for block movement
FXHorizontalFrame * myLengthFrame
horizontal frame for length
FXComboBox * myReferencePointMatchBox
match box with the list of reference points
double setStartPosition(double positionOfTheMouseOverLane, double lengthOfAdditional) const
obtain the Start position values of StoppingPlaces and E2 detector over the lane
bool getNeteditAttributesAndValues(std::map< SumoXMLAttr, std::string > &valuesMap, const GNELane *lane) const
fill valuesMap with netedit attributes
void hideNeteditAttributesModul()
hide Netedit attributes modul
FXHorizontalFrame * myCloseShapeFrame
horizontal frame for close polygon
FXButton * helpReferencePoint
Button for help about the reference point.
FXCheckButton * myCloseShapeCheckButton
checkbox to enable/disable close polygon
long onCmdHelp(FXObject *, FXSelector, void *)
Called when user press the help button.
long onCmdSetParameters(FXObject *, FXSelector, void *)
Called when user udpate the parameter text field.
std::string getParametersStr() const
get parameters as string
FXButton * myButtonEditParameters
button for edit parameters using specific dialog
void setParameters(const std::vector< std::pair< std::string, std::string > > &parameters)
set parameters
const std::map< std::string, std::string > & getParametersMap() const
get parameters as map
void showParametersEditorCreator()
show netedit attributes EditorCreator
void hideParametersEditorCreator()
hide netedit attributes EditorCreator
Parameterised::ParameterisedAttrType getAttrType() const
get current parameter type
ParametersEditorCreator(GNEFrame *frameParent)
FOX-declaration.
FXTextField * myTextFieldParameters
text field for write parameters
std::vector< std::pair< std::string, std::string > > getParameters() const
get parameters as vector of strings
GNEFrame * getFrameParent() const
pointer to frame parent
static bool isSupermodeValid(const GNEViewNet *viewNet, const GNEAttributeCarrier *AC)
return true if AC can be edited in the current supermode
GNEViewNet * myViewNet
View Net.
Definition: GNEFrame.h:113
This lane is powered by an underlying GNEEdge and basically knows how to draw itself.
Definition: GNELane.h:45
const PositionVector & getLaneShape() const
Definition: GNELane.cpp:117
double getLengthGeometryFactor() const
get length geometry factor
Definition: GNELane.cpp:1615
static void setFlowParameters(const SumoXMLAttr attribute, int &parameters)
configure flow parameters
Dialog for edit parameters.
bool isShape() const
return true if tag correspond to a shape
bool canBlockMovement() const
return true if tag correspond to an element that can block their movement
bool isTAZElement() const
return true if tag correspond to a TAZ element
bool isNetworkElement() const
return true if tag correspond to a network element
bool isDataElement() const
return true if tag correspond to a data element
bool canBlockShape() const
return true if tag correspond to an element that can block their shape
bool canMaskStartEndPos() const
return true if tag correspond to an element that can mask the attributes "start" and "end" position a...
bool canCenterCameraAfterCreation() const
return true if tag correspond to an element that center camera after creation
bool canCloseShape() const
return true if tag correspond to an element that can close their shape
bool isDemandElement() const
return true if tag correspond to a demand element
bool isAdditionalElement() const
return true if tag correspond to an additional element
bool hasAttribute(SumoXMLAttr attr) const
check if current TagProperties owns the attribute "attr"
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:71
void p_end()
End undo command sub-group. If the sub-group is still empty, it will be deleted; otherwise,...
Definition: GNEUndoList.cpp:78
const GNEViewNetHelper::EditModes & getEditModes() const
get edit modes
Definition: GNEViewNet.cpp:467
GNEUndoList * getUndoList() const
get the undoList object
static FXIcon * getIcon(const GUIIcon which)
returns a icon previously defined in the enum GUIIcon
static int getTextureID(const std::string &filename, const bool mirrorX=false)
return texture id for the given filename (initialize on first use)
static FXColor getFXColor(const RGBColor &col)
converts FXColor to RGBColor
Definition: MFXUtils.cpp:112
static RGBColor getRGBColor(FXColor col)
converts FXColor to RGBColor
Definition: MFXUtils.cpp:106
An upper class for objects with additional parameters.
Definition: Parameterised.h:39
ParameterisedAttrType
@brie enum for Parameterised type
Definition: Parameterised.h:43
static bool areParametersValid(const std::string &value, bool report=false, ParameterisedAttrType attrType=ParameterisedAttrType::STRING, const std::string kvsep="=", const std::string sep="|")
check if given string can be parsed to a parameters map "key1=value1|key2=value2|....
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:36
A list of positions.
double nearest_offset_to_point2D(const Position &p, bool perpendicular=true) const
return the nearest offest to point 2D
static RGBColor parseColor(std::string coldef)
Parses a color information.
Definition: RGBColor.cpp:168
static const RGBColor BLACK
Definition: RGBColor.h:188
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.
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.
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.
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.
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.
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.
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.
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.
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 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.
static bool isValidTypeID(const std::string &value)
whether the given string is a valid id for an edge or vehicle type
static bool isValidVehicleID(const std::string &value)
whether the given string is a valid id for a vehicle or flow
static bool isValidFilename(const std::string &value)
whether the given string is a valid attribute for a filename (for example, a name)
static bool isValidDetectorID(const std::string &value)
whether the given string is a valid id for an detector
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't allowed)
static bool isValidNetID(const std::string &value)
whether the given string is a valid id for a network element
static bool isValidAttribute(const std::string &value)
whether the given string is a valid attribute for a certain key (for example, a name)
std::vector< std::string > getVector()
return vector of strings
static std::string replace(std::string str, const char *what, const char *by)
bool isCurrentSupermodeDemand() const
@check if current supermode is Demand
bool isCurrentSupermodeData() const
@check if current supermode is Data
bool isCurrentSupermodeNetwork() const
@check if current supermode is Network