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