Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
GNEAttributesEditorRow.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2001-2025 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// Row used for edit attributes in GNEAttributesEditorType
19/****************************************************************************/
20
26#include <netedit/GNENet.h>
28#include <netedit/GNEViewNet.h>
36
38
39// ===========================================================================
40// FOX callback mapping
41// ===========================================================================
42
54
55// Object implementation
56FXIMPLEMENT(GNEAttributesEditorRow, FXHorizontalFrame, GNEAttributeRowMap, ARRAYNUMBER(GNEAttributeRowMap))
57
58// ===========================================================================
59// method definitions
60// ===========================================================================
61
63 FXHorizontalFrame(attributeTable->getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame),
64 myAttributeTable(attributeTable) {
65 // get static tooltip menu
66 const auto tooltipMenu = attributeTable->getFrameParent()->getViewNet()->getViewParent()->getGNEAppWindows()->getStaticTooltipMenu();
67 // Create left label
68 myAttributeLabel = new MFXLabelTooltip(this, tooltipMenu, "Label", nullptr, GUIDesignLabelThickedFixed(100));
69 myAttributeLabel->hide();
70 // create lef boolean checkBox for enable/disable attributes
71 myAttributeToggleEnableCheckButton = new FXCheckButton(this, "Enable/Disable attribute checkBox", this,
73 myAttributeToggleEnableCheckButton->hide();
74 // create left button parent
75 myAttributeButton = new MFXButtonTooltip(this, tooltipMenu, "button", nullptr, this,
77 // create right text field for string attributes
78 myValueTextField = new MFXTextFieldIcon(this, tooltipMenu, GUIIcon::EMPTY, this, MID_GNE_ATTRIBUTESEDITORROW_SETATTRIBUTE, GUIDesignTextField);
79 myValueTextField->hide();
80 // create right combo box for discrete attributes
81 myValueComboBox = new MFXComboBoxIcon(this, tooltipMenu, true, GUIDesignComboBoxVisibleItems, this,
83 myValueComboBox->hide();
84 // Create right check button
85 myValueCheckButton = new FXCheckButton(this, "check button", this, MID_GNE_ATTRIBUTESEDITORROW_SETATTRIBUTE, GUIDesignCheckButton);
86 myValueCheckButton->hide();
87 // create right move lane up button
88 myValueLaneUpButton = new MFXButtonTooltip(this, tooltipMenu, "", GUIIconSubSys::getIcon(GUIIcon::ARROW_UP), this,
90 myValueLaneUpButton->hide();
91 // set tip texts
92 myValueLaneUpButton->setTipText(TL("Move element up one lane"));
93 myValueLaneUpButton->setHelpText(TL("Move element up one lane"));
94 // create right move lane down button
95 myValueLaneDownButton = new MFXButtonTooltip(this, tooltipMenu, "", GUIIconSubSys::getIcon(GUIIcon::ARROW_DOWN), this,
97 myValueLaneDownButton->hide();
98 // set tip texts
99 myValueLaneDownButton->setTipText(TL("Move element down one lane"));
100 myValueLaneDownButton->setHelpText(TL("Move element down one lane"));
101 // start hidden
102 hide();
103}
104
105
106bool
107GNEAttributesEditorRow::showAttributeRow(GNEAttributesEditorType* attributeTable, const GNEAttributeProperties* attrProperty, const bool forceDisable) {
108 // update parent table
109 myAttributeTable = attributeTable;
110 if (myAttributeTable->myEditedACs.empty()) {
111 return false;
112 } else {
114 }
115 myAttrProperty = attrProperty;
116 const auto attribute = myAttrProperty->getAttr();
117 const auto tagPropertyParent = attrProperty->getTagPropertyParent();
118 const auto firstEditedAC = myAttributeTable->myEditedACs.front();
119 // check if we're editing multiple ACs
120 const auto multipleEditedACs = (myAttributeTable->myEditedACs.size() > 1);
121 // declare flag for show attribute enabled
122 const bool attributeEnabled = isAttributeEnabled(attrProperty);
123 // check if this attribute is computed
124 const bool computedAttribute = multipleEditedACs ? false : firstEditedAC->isAttributeComputed(attribute);
125 // get string value depending if attribute is enabled
126 const std::string value = getAttributeValue(attributeEnabled);
127 // get parent if we're editing single vTypes
128 GNEAttributeCarrier* ACParent = nullptr;
129 if (!multipleEditedACs && attrProperty->isVType()) {
131 // parent can be either type or distribution
132 if (attribute == SUMO_ATTR_TYPE) {
133 ACParent = ACs->retrieveDemandElement(SUMO_TAG_VTYPE, firstEditedAC->getAttribute(SUMO_ATTR_TYPE), false);
134 }
135 if (ACParent == nullptr) {
136 ACParent = ACs->retrieveDemandElement(SUMO_TAG_VTYPE_DISTRIBUTION, firstEditedAC->getAttribute(SUMO_ATTR_TYPE), false);
137 }
138 }
139 // hide editing for unique attributes in case of multi-selection
140 if (multipleEditedACs && attrProperty->isUnique()) {
141 return hideAttributeRow();
142 }
143 // front element has their own button, and doesn't use the UndoList
144 if (attribute == GNE_ATTR_FRONTELEMENT) {
145 return hideAttributeRow();
146 }
147 // if we have a disabled flow attribute, don't show row
148 if (attrProperty->isFlow() && !attributeEnabled) {
149 return hideAttributeRow();
150 }
151 // expected and joins depend of triggered
152 if (tagPropertyParent->isVehicleStop() && !attributeEnabled) {
153 if (attribute == SUMO_ATTR_EXPECTED) {
154 return hideAttributeRow();
155 } else if (attribute == SUMO_ATTR_EXPECTED_CONTAINERS) {
156 return hideAttributeRow();
157 } else if (attribute == SUMO_ATTR_JOIN) {
158 return hideAttributeRow();
159 }
160 }
161 // don't show stop offset exception if stopOffset is zero
162 if ((attribute == GNE_ATTR_STOPOEXCEPTION) && !attributeEnabled) {
163 return hideAttributeRow();
164 }
165 // show elements depending of attribute properties
166 if (attrProperty->isActivatable()) {
167 showAttributeToggleEnable(attrProperty, attributeEnabled);
168 } else if (attrProperty->isFileOpen() || attrProperty->isFileSave()) {
169 showAttributeFile(attrProperty, attributeEnabled);
170 } else if (attribute == GNE_ATTR_PARENT) {
171 showAttributeReparent(attributeEnabled);
172 } else if ((attribute == SUMO_ATTR_TYPE) && tagPropertyParent->hasTypeParent()) {
173 showAttributeInspectParent(attrProperty, attributeEnabled);
174 } else if (attrProperty->isVClass() && (attribute != SUMO_ATTR_DISALLOW)) {
175 showAttributeVClass(attrProperty, attributeEnabled);
176 } else if (attribute == SUMO_ATTR_COLOR) {
177 showAttributeColor(attrProperty, attributeEnabled);
178 } else if (attribute == GNE_ATTR_PARAMETERS) {
180 } else {
181 showAttributeLabel(attrProperty);
182 }
183 // continue depending of type of attribute
184 if (attrProperty->isBool()) {
185 showValueCheckButton(value, attributeEnabled, computedAttribute);
186 } else if (attrProperty->isDiscrete() || attrProperty->isVType()) {
187 showValueComboBox(attrProperty, value, attributeEnabled, computedAttribute);
188 } else {
189 showValueString(value, attributeEnabled, computedAttribute);
190 }
191 // check if show move lane buttons
192 if (!multipleEditedACs && !tagPropertyParent->isNetworkElement() && (attribute == SUMO_ATTR_LANE)) {
193 showMoveLaneButtons(value);
194 myValueLaneUpButton->show();
195 myValueLaneDownButton->show();
196 } else {
197 myValueLaneUpButton->hide();
198 myValueLaneDownButton->hide();
199 }
200 // enable depending of supermode
201 enableElements(attrProperty, forceDisable);
202 // Show row
203 show();
204 return true;
205}
206
207
208bool
210 hide();
211 return false;
212}
213
214
215void
217 // disable all elements
219 myAttributeButton->disable();
222 myValueCheckButton->disable();
223 myValueLaneUpButton->disable();
224 myValueLaneDownButton->disable();
225}
226
227
232
233
234std::string
236 if (myValueCheckButton->shown()) {
237 return (myValueCheckButton->getCheck() == TRUE) ? "true" : "false";
238 } else if (myValueComboBox->shown()) {
239 return myValueComboBox->getText().text();
240 } else if (myValueTextField->shown()) {
241 return myValueTextField->getText().text();
242 } else {
243 return "";
244 }
245}
246
247
248bool
250 if (myValueCheckButton->shown()) {
251 return true;
252 } else if (myValueComboBox->shown()) {
254 (myValueComboBox->getBackColor() != GUIDesignBackgroundColorRed);
255 } else if (myValueTextField->shown()) {
258 } else {
259 return true;
260 }
261}
262
263
264bool
266 return shown();
267}
268
269
271GNEAttributesEditorRow::fillSumoBaseObject(CommonXMLStructure::SumoBaseObject* baseObject, const bool insertDefaultValues) const {
272 const auto attribute = myAttrProperty->getAttr();
273 // check if this is the default value
274 const bool usingDefaultValue = isValueValid() && (myAttrProperty->getDefaultStringValue() == getCurrentValue());
275 // first check if insert default values
276 if (!insertDefaultValues && usingDefaultValue) {
277 return SUMO_ATTR_NOTHING;
278 }
279 // now check if attribute is activatable AND is enabled
280 if (myAttrProperty->isActivatable() && (myAttributeToggleEnableCheckButton->getCheck() == FALSE)) {
281 return SUMO_ATTR_NOTHING;
282 }
283 // continue depending of type
284 if (myAttrProperty->isBool()) {
285 baseObject->addBoolAttribute(attribute, myValueCheckButton->getCheck() == TRUE);
286 } else if (myAttrProperty->isDiscrete()) {
288 (myValueComboBox->getBackColor() == GUIDesignBackgroundColorRed)) {
289 return attribute;
290 } else {
291 baseObject->addStringAttribute(attribute, myValueComboBox->getText().text());
292 }
294 (myValueTextField->getBackColor() == GUIDesignBackgroundColorRed)) {
295 return attribute;
296 } else if (myAttrProperty->isInt()) {
297 // int value
298 if (GNEAttributeCarrier::canParse<int>(myValueTextField->getText().text())) {
299 const auto intValue = GNEAttributeCarrier::parse<int>(myValueTextField->getText().text());
300 if (myAttrProperty->isPositive() && (intValue < 0)) {
301 return attribute;
302 } else {
303 baseObject->addIntAttribute(attribute, intValue);
304 }
306 baseObject->addIntAttribute(attribute, myAttrProperty->getDefaultIntValue());
307 } else if (myAttrProperty->hasDefaultValue() && myValueTextField->getText().empty()) {
308 baseObject->addIntAttribute(attribute, myAttrProperty->getDefaultIntValue());
309 } else {
310 return attribute;
311 }
312 } else if (myAttrProperty->isFloat()) {
313 // double value
314 if (myAttrProperty->isList()) {
315 if (GNEAttributeCarrier::canParse<std::vector<double> >(myValueTextField->getText().text())) {
316 const auto doubleListValue = GNEAttributeCarrier::parse<std::vector<double> >(myValueTextField->getText().text());
317 // check every double
318 for (const auto doubleValue : doubleListValue) {
319 if (myAttrProperty->isPositive() && (doubleValue < 0)) {
320 return attribute;
321 } else if (myAttrProperty->isFloat() && ((doubleValue < 0) || (doubleValue > 1))) {
322 return attribute;
323 }
324 }
325 baseObject->addDoubleListAttribute(attribute, doubleListValue);
326 } else {
327 return attribute;
328 }
329 } else if (GNEAttributeCarrier::canParse<double>(myValueTextField->getText().text())) {
330 const auto doubleValue = GNEAttributeCarrier::parse<double>(myValueTextField->getText().text());
331 // check using default value for certain default values (for example, length = -1)
332 if (!usingDefaultValue && myAttrProperty->isPositive() && (doubleValue < 0)) {
333 return attribute;
334 } else if (!usingDefaultValue && myAttrProperty->isProbability() && ((doubleValue < 0) || (doubleValue > 1))) {
335 return attribute;
336 } else {
337 baseObject->addDoubleAttribute(attribute, doubleValue);
338 }
341 } else if (myAttrProperty->hasDefaultValue() && myValueTextField->getText().empty()) {
343 } else {
344 return attribute;
345 }
346 } else if (myAttrProperty->isSUMOTime()) {
347 // time value
348 if (GNEAttributeCarrier::canParse<SUMOTime>(myValueTextField->getText().text())) {
349 const auto timeValue = GNEAttributeCarrier::parse<SUMOTime>(myValueTextField->getText().text());
350 if (timeValue < 0) {
351 return attribute;
352 } else {
353 baseObject->addTimeAttribute(attribute, timeValue);
354 }
356 baseObject->addTimeAttribute(attribute, myAttrProperty->getDefaultTimeValue());
357 } else if (myAttrProperty->hasDefaultValue() && myValueTextField->getText().empty()) {
358 baseObject->addTimeAttribute(attribute, myAttrProperty->getDefaultTimeValue());
359 } else {
360 return attribute;
361 }
362 } else if (myAttrProperty->isPosition()) {
363 // position value
364 if (myAttrProperty->isList()) {
365 if (GNEAttributeCarrier::canParse<PositionVector>(myValueTextField->getText().text())) {
366 baseObject->addPositionVectorAttribute(attribute, GNEAttributeCarrier::parse<PositionVector>(myValueTextField->getText().text()));
367 } else {
368 return attribute;
369 }
370 } else if (GNEAttributeCarrier::canParse<Position>(myValueTextField->getText().text())) {
371 baseObject->addPositionAttribute(attribute, GNEAttributeCarrier::parse<Position>(myValueTextField->getText().text()));
374 } else if (myAttrProperty->hasDefaultValue() && myValueTextField->getText().empty()) {
376 } else {
377 return attribute;
378 }
379 } else if (myAttrProperty->isColor()) {
380 // color value
381 if (GNEAttributeCarrier::canParse<RGBColor>(myValueTextField->getText().text())) {
382 baseObject->addColorAttribute(attribute, GNEAttributeCarrier::parse<RGBColor>(myValueTextField->getText().text()));
384 baseObject->addColorAttribute(attribute, myAttrProperty->getDefaultColorValue());
385 } else if (myAttrProperty->hasDefaultValue() && myValueTextField->getText().empty()) {
386 baseObject->addColorAttribute(attribute, myAttrProperty->getDefaultColorValue());
387 } else {
388 return attribute;
389 }
390 } else if (myAttrProperty->isList()) {
391 baseObject->addStringListAttribute(attribute, GNEAttributeCarrier::parse<std::vector<std::string> >(myValueTextField->getText().text()));
392 } else if (attribute == GNE_ATTR_PARAMETERS) {
393 baseObject->addParameters(myValueTextField->getText().text());
394 } else {
395 baseObject->addStringAttribute(attribute, myValueTextField->getText().text());
396 }
397 // all ok, then return nothing
398 return SUMO_ATTR_NOTHING;
399}
400
401
402long
403GNEAttributesEditorRow::onCmdOpenColorDialog(FXObject*, FXSelector, void*) {
406 // If previous attribute wasn't correct, set black as default color
407 if (GNEAttributeCarrier::canParse<RGBColor>(myValueTextField->getText().text())) {
408 color = GNEAttributeCarrier::parse<RGBColor>(myValueTextField->getText().text());
409 } else if (myAttrProperty->hasDefaultValue()) {
411 }
412 // declare colorDialog
413 const auto colorDialog = new GNEColorDialog(GNEApp, color);
414 // continue depending of result
415 if (colorDialog->getResult() == GNEDialog::Result::ACCEPT) {
416 myValueTextField->setText(toString(colorDialog->getColor()).c_str(), TRUE);
417 }
418 return 1;
419}
420
421
422long
425 // declare allowVClassesDialog
426 const auto allowVClassesDialog = new GNEVClassesDialog(GNEApp, myAttrProperty->getAttr(), myValueTextField->getText().text());
427 // continue depending of result
428 if (allowVClassesDialog->getResult() == GNEDialog::Result::ACCEPT) {
429 myValueTextField->setText(allowVClassesDialog->getModifiedVClasses().c_str(), TRUE);
430 }
431 return 1;
432}
433
434
435long
436GNEAttributesEditorRow::onCmdOpenFileDialog(FXObject*, FXSelector, void*) {
437 // open dialog
443 // update text field
444 if (fileDialog.getResult() == GNEDialog::Result::ACCEPT) {
445 myValueTextField->setText(fileDialog.getFilename().c_str(), TRUE);
446 }
447 return 1;
448}
449
450
451long
452GNEAttributesEditorRow::onCmdReparent(FXObject*, FXSelector, void*) {
454 return 1;
455}
456
457
458long
459GNEAttributesEditorRow::onCmdInspectParent(FXObject*, FXSelector, void*) {
461 return 1;
462}
463
464
465long
466GNEAttributesEditorRow::onCmdMoveLaneUp(FXObject*, FXSelector, void*) {
468 return 1;
469}
470
471
472long
473GNEAttributesEditorRow::onCmdMoveLaneDown(FXObject*, FXSelector, void*) {
475 return 1;
476}
477
478
479long
480GNEAttributesEditorRow::onCmdSetAttribute(FXObject* obj, FXSelector, void*) {
481 if (myAttributeTable->myEditedACs.empty()) {
482 return 0;
483 }
484 const auto& editedAC = myAttributeTable->myEditedACs.front();
485 const auto attribute = myAttrProperty->getAttr();
486 // continue depending of clicked object
487 if (obj == myValueCheckButton) {
488 // Set true o false depending of the checkBox
489 if (myValueCheckButton->getCheck()) {
490 myValueCheckButton->setText("true");
491 } else {
492 myValueCheckButton->setText("false");
493 }
494 myAttributeTable->setAttribute(attribute, myValueCheckButton->getText().text());
495 } else if (obj == myValueComboBox) {
496 const std::string newValue = myValueComboBox->getText().text();
497 // check if the new comboBox value is valid
498 if (editedAC->isValid(attribute, newValue)) {
501 myValueComboBox->killFocus();
502 myAttributeTable->setAttribute(attribute, newValue);
503 } else {
504 // edit colors
506 if (newValue.empty()) {
508 }
509 }
510 } else if (obj == myValueTextField) {
511 // first check if set default value
513 // update text field without notify
515 }
516 // if we're editing an angle, check if filter between [0,360]
517 if ((attribute == SUMO_ATTR_ANGLE) && GNEAttributeCarrier::canParse<double>(myValueTextField->getText().text())) {
518 // filter anglea and update text field without notify
519 const double angle = fmod(GNEAttributeCarrier::parse<double>(myValueTextField->getText().text()), 360);
520 myValueTextField->setText(toString(angle).c_str(), FALSE);
521 }
522 // if we're editing a position or a shape, strip whitespace after comma
523 if ((attribute == SUMO_ATTR_POSITION) || (attribute == SUMO_ATTR_SHAPE)) {
524 std::string shape(myValueTextField->getText().text());
525 while (shape.find(", ") != std::string::npos) {
526 shape = StringUtils::replace(shape, ", ", ",");
527 }
528 myValueTextField->setText(toString(shape).c_str(), FALSE);
529 }
530 // if we're editing a int, strip decimal value
531 if (myAttrProperty->isInt() && GNEAttributeCarrier::canParse<double>(myValueTextField->getText().text())) {
532 double doubleValue = GNEAttributeCarrier::parse<double>(myValueTextField->getText().text());
533 if ((doubleValue - (int)doubleValue) == 0) {
534 myValueTextField->setText(toString((int)doubleValue).c_str(), FALSE);
535 }
536 }
537 // after apply all filters, obtain value
538 const std::string newValue = myValueTextField->getText().text();
539 // check if the new textField value is valid
540 if (editedAC->isValid(attribute, newValue)) {
544 if (myAttributeTable->isEditorTypeEditor() || newValue.empty() || (attribute != SUMO_ATTR_ID)) {
545 myAttributeTable->setAttribute(attribute, newValue);
546 }
547 } else {
548 // edit colors
550 if (newValue.empty()) {
552 }
553 }
554 }
555 return 1;
556}
557
558
559long
564
565
567 myAttributeTable(nullptr) {
568}
569
570
571const std::string
573 const auto attribute = myAttrProperty->getAttr();
574 // if we're in creator mode, generate ID
577 const auto parentTag = myAttrProperty->getTagPropertyParent()->getTag();
579 return ACs->generateEdgeID();
581 return ACs->generateAdditionalID(parentTag);
583 return ACs->generateDemandElementID(parentTag);
585 return ACs->generateMeanDataID(parentTag);
586 } else if (parentTag == SUMO_TAG_TYPE) {
587 return ACs->generateEdgeTypeID();
588 } else if (parentTag == SUMO_TAG_DATASET) {
589 return ACs->generateDataSetID();
590 }
591 }
592 if (enabled) {
593 // Declare a set of occurring values and insert attribute's values of item (note: We use a set to avoid repeated values)
594 std::set<std::string> values;
595 // iterate over edited attributes and insert every value in set
596 for (const auto& editedAC : myAttributeTable->myEditedACs) {
597 if (editedAC->hasAttribute(attribute)) {
598 values.insert(editedAC->getAttribute(attribute));
599 }
600 }
601 // merge all values in a single string
602 std::ostringstream oss;
603 for (auto it = values.begin(); it != values.end(); it++) {
604 if (it != values.begin()) {
605 oss << " ";
606 }
607 oss << *it;
608 }
609 // obtain value to be shown in row
610 return oss.str();
611 } else {
612 return myAttributeTable->myEditedACs.front()->getAlternativeValueForDisabledAttributes(attribute);
613 }
614}
615
616
617void
619 myAttributeToggleEnableCheckButton->setText(attrProperty->getAttrStr().c_str());
620 myAttributeToggleEnableCheckButton->setCheck(value);
623 // hide other elements
624 myAttributeLabel->hide();
625 myAttributeButton->hide();
626}
627
628
629void
631 // update attribute button
632 myAttributeButton->setText(TL("Reparent"));
633 myAttributeButton->setHelpText(TL("Change parent of this element"));
634 myAttributeButton->setTipText(myAttributeButton->getHelpText());
635 myAttributeButton->setIcon(nullptr);
637 if (enabled) {
638 myAttributeButton->enable();
639 } else {
640 myAttributeButton->disable();
641 }
642 myAttributeButton->show();
643 // hide other elements
644 myAttributeLabel->hide();
646}
647
648
649void
651 // update attribute button
652 myAttributeButton->setText(attrProperty->getAttrStr().c_str());
653 myAttributeButton->setHelpText(TLF("Inspect % parent", attrProperty->getAttrStr()).c_str());
654 myAttributeButton->setTipText(myAttributeButton->getHelpText());
657 if (enabled) {
658 myAttributeButton->enable();
659 } else {
660 myAttributeButton->disable();
661 }
662 myAttributeButton->show();
663 // hide other elements
664 myAttributeLabel->hide();
666}
667
668
669void
671 // update attribute button
672 myAttributeButton->setText(attrProperty->getAttrStr().c_str());
673 myAttributeButton->setHelpText(TL("Open dialog for editing vClasses"));
674 myAttributeButton->setTipText(myAttributeButton->getHelpText());
675 myAttributeButton->setIcon(nullptr);
677 if (enabled) {
678 myAttributeButton->enable();
679 } else {
680 myAttributeButton->disable();
681 }
682 myAttributeButton->show();
683 // hide other elements
684 myAttributeLabel->hide();
686}
687
688
689void
691 // update attribute button
692 myAttributeButton->setText(attrProperty->getAttrStr().c_str());
693 myAttributeButton->setHelpText(TL("Open dialog for editing color"));
694 myAttributeButton->setTipText(myAttributeButton->getHelpText());
697 if (enabled) {
698 myAttributeButton->enable();
699 } else {
700 myAttributeButton->disable();
701 }
702 myAttributeButton->show();
703 // hide other elements
704 myAttributeLabel->hide();
706}
707
708
709void
711 // update attribute button
712 myAttributeButton->setText(attrProperty->getAttrStr().c_str());
713 if (attrProperty->isFileOpen()) {
714 myAttributeButton->setHelpText(TL("Open dialog to select an existent file"));
715 } else {
716 myAttributeButton->setHelpText(TL("Open dialog to select or create an existent file"));
717 }
718 myAttributeButton->setTipText(myAttributeButton->getHelpText());
721 if (enabled) {
722 myAttributeButton->enable();
723 } else {
724 myAttributeButton->disable();
725 }
726 myAttributeButton->show();
727 // hide other elements
728 myAttributeLabel->hide();
730}
731
732
733void
735 myAttributeLabel->setText(attrProperty->getAttrStr().c_str());
736 myAttributeLabel->setTipText(attrProperty->getDefinition().c_str());
737 myAttributeLabel->show();
738 // hide other elements
740 myAttributeButton->hide();
741}
742
743
744void
750
751
752void
754 const bool enabled, const bool computed) {
755 // first we need to check if all boolean values are equal
756 bool allValuesEqual = true;
757 // declare boolean vector
758 std::vector<bool> booleanVector;
759 // check if value can be parsed to a boolean vector
760 if (GNEAttributeCarrier::canParse<std::vector<bool> >(value)) {
761 booleanVector = GNEAttributeCarrier::parse<std::vector<bool> >(value);
762 }
763 // iterate over booleans comparing all element with the first
764 for (const auto booleanValue : booleanVector) {
765 if (booleanValue != booleanVector.front()) {
766 allValuesEqual = false;
767 }
768 }
769 // use checkbox or textfield depending if all booleans are equal
770 if (allValuesEqual) {
771 if (enabled) {
772 myValueCheckButton->enable();
773 } else {
774 myValueCheckButton->disable();
775 }
776 // set check button
777 if ((booleanVector.size() > 0) && booleanVector.front()) {
778 myValueCheckButton->setCheck(true);
779 myValueCheckButton->setText("true");
780 } else {
781 myValueCheckButton->setCheck(false);
782 myValueCheckButton->setText("false");
783 }
784 // show check button
785 myValueCheckButton->show();
786 // hide other value elements
787 myValueTextField->hide();
788 myValueComboBox->hide();
789 myValueLaneUpButton->hide();
790 myValueLaneDownButton->hide();
791 } else {
792 // show value as string
793 showValueString(value, enabled, computed);
794 }
795}
796
797
798void
799GNEAttributesEditorRow::showValueComboBox(const GNEAttributeProperties* attrProperty, const std::string& value,
800 const bool enabled, const bool computed) {
801 // first we need to check if all boolean values are equal
802 bool allValuesEqual = true;
803 // declare boolean vector
804 std::vector<std::string> stringVector = GNEAttributeCarrier::parse<std::vector<std::string> >(value);
805 // iterate over string comparing all element with the first
806 for (const auto& stringValue : stringVector) {
807 if (stringValue != stringVector.front()) {
808 allValuesEqual = false;
809 }
810 }
811 // use checkbox or textfield depending if all booleans are equal
812 if (allValuesEqual) {
813 // clear and enable comboBox
817 if (enabled) {
819 } else {
821 }
822 // fill depeding of ACAttr
823 if (attrProperty->getAttr() == SUMO_ATTR_VCLASS) {
824 // add all vClasses with their icons
825 for (const auto& vClassStr : SumoVehicleClassStrings.getStrings()) {
827 }
828 } else if (attrProperty->isVType()) {
829 // get ACs
831 // fill comboBox with all vTypes and vType distributions sorted by ID
832 std::map<std::string, GNEDemandElement*> sortedTypes;
833 for (const auto& type : ACs->getDemandElements().at(SUMO_TAG_VTYPE)) {
834 sortedTypes[type.second->getID()] = type.second;
835 }
836 for (const auto& sortedType : sortedTypes) {
837 myValueComboBox->appendIconItem(sortedType.first.c_str(), sortedType.second->getACIcon());
838 }
839 sortedTypes.clear();
840 for (const auto& typeDistribution : ACs->getDemandElements().at(SUMO_TAG_VTYPE_DISTRIBUTION)) {
841 sortedTypes[typeDistribution.second->getID()] = typeDistribution.second;
842 }
843 for (const auto& sortedType : sortedTypes) {
844 myValueComboBox->appendIconItem(sortedType.first.c_str(), sortedType.second->getACIcon());
845 }
846 } else if (attrProperty->getAttr() == SUMO_ATTR_ICON) {
847 // add all POIIcons with their icons
848 for (const auto& POIIcon : SUMOXMLDefinitions::POIIcons.getValues()) {
850 }
851 } else if ((attrProperty->getAttr() == SUMO_ATTR_RIGHT_OF_WAY) && (myAttributeTable->myEditedACs.size() == 1) &&
852 (attrProperty->getTagPropertyParent()->getTag() == SUMO_TAG_JUNCTION)) {
853 // special case for junction types
854 if (myAttributeTable->myEditedACs.front()->getAttribute(SUMO_ATTR_TYPE) == "priority") {
857 } else if (myAttributeTable->myEditedACs.front()->getAttribute(SUMO_ATTR_TYPE) == "traffic_light") {
861 } else {
863 }
864 } else {
865 // fill comboBox with discrete values
866 for (const auto& discreteValue : attrProperty->getDiscreteValues()) {
867 myValueComboBox->appendIconItem(discreteValue.c_str(), nullptr);
868 }
869 }
870 // set current value (or disable)
871 const auto index = myValueComboBox->findItem(value.c_str());
872 if (index < 0) {
873 if (myValueComboBox->getNumItems() > 0) {
875 } else {
877 }
878 } else {
880 }
881 // show comboBox button
882 myValueComboBox->show();
883 // hide other value elements
884 myValueTextField->hide();
885 myValueCheckButton->hide();
886 myValueLaneUpButton->hide();
887 myValueLaneDownButton->hide();
888 } else {
889 // show value as string
890 showValueString(value, enabled, computed);
891 }
892}
893
894
895void
896GNEAttributesEditorRow::showValueString(const std::string& value, const bool enabled, const bool computed) {
897 // clear and enable comboBox
898 myValueTextField->setText(value.c_str());
899 if (computed) {
901 } else {
903 }
904 if (enabled) {
906 } else {
908 }
909 // show list of values
910 myValueTextField->show();
911 // hide other value elements
912 myValueCheckButton->hide();
913 myValueComboBox->hide();
914}
915
916
917void
919 // retrieve lane
920 const auto lane = myAttributeTable->myFrameParent->getViewNet()->getNet()->getAttributeCarriers()->retrieveLane(laneID, false);
921 // check lane
922 if (lane) {
923 // check if disable move up
924 if ((lane->getIndex() + 1) >= (int)lane->getParentEdge()->getChildLanes().size()) {
925 myValueLaneUpButton->disable();
926 } else {
927 myValueLaneUpButton->enable();
928 }
929 // check if disable move down
930 if ((lane->getIndex() - 1) < 0) {
931 myValueLaneDownButton->disable();
932 } else {
933 myValueLaneDownButton->enable();
934 }
935 } else {
936 // if lane doesn't exist, disable both
937 myValueLaneUpButton->disable();
938 myValueLaneDownButton->disable();
939 }
940}
941
942
943void
944GNEAttributesEditorRow::enableElements(const GNEAttributeProperties* attrProperty, const bool forceDisable) {
945 const auto& editModes = myAttributeTable->myFrameParent->getViewNet()->getEditModes();
946 const auto tagProperty = attrProperty->getTagPropertyParent();
947 // by default we assume that elements are disabled
948 bool enableElements = false;
949 if (forceDisable) {
950 enableElements = false;
951 } else if (editModes.isCurrentSupermodeNetwork()) {
952 if (tagProperty->isNetworkElement() || tagProperty->isAdditionalElement()) {
953 enableElements = true;
954 } else if ((tagProperty->getTag() == SUMO_TAG_TAZSOURCE) || (tagProperty->getTag() == SUMO_TAG_TAZSINK)) {
955 enableElements = true;
956 }
957 } else if (editModes.isCurrentSupermodeDemand() && tagProperty->isDemandElement()) {
958 enableElements = true;
959 } else if (editModes.isCurrentSupermodeData() && (tagProperty->isDataElement() || tagProperty->isMeanData())) {
960 enableElements = true;
961 }
962 if (!enableElements) {
964 myAttributeButton->disable();
967 myValueCheckButton->disable();
968 myValueLaneUpButton->disable();
969 myValueLaneDownButton->disable();
970 }
971}
972
973
974bool
976 if (attrProperty->isAlwaysEnabled()) {
977 return true;
978 } else {
979 for (const auto& AC : myAttributeTable->myEditedACs) {
980 if (AC->isAttributeEnabled(attrProperty->getAttr())) {
981 return true;
982 }
983 }
984 return false;
985 }
986}
987
988/****************************************************************************/
FXDEFMAP(GNEAttributesEditorRow) GNEAttributeRowMap[]
@ MID_GNE_ATTRIBUTESEDITORROW_MOVELANEUP
move lane up
@ MID_GNE_ATTRIBUTESEDITORROW_OPENDIALOG_FILE
open file dialog in attributes editor row
@ MID_GNE_ATTRIBUTESEDITORROW_SETATTRIBUTE
set attribute (string, bool, etc.) in attributes editor row
@ MID_GNE_ATTRIBUTESEDITORROW_OPENDIALOG_COLOR
open color dialog in attributes editor row
@ MID_GNE_ATTRIBUTESEDITORROW_REPARENT
reparent
@ MID_GNE_ATTRIBUTESEDITORROW_TOGGLEENABLEATTRIBUTE
toogle enable attribute in attributes editor row
@ MID_GNE_ATTRIBUTESEDITORROW_OPENDIALOG_ALLOW
open allow dialog in attributes editor row
@ MID_GNE_ATTRIBUTESEDITORROW_MOVELANEDOWN
move lane down
@ MID_GNE_ATTRIBUTESEDITORROW_INSPECTPARENT
inspect parent
#define GUIDesignButtonAttribute
button extended over over column with thick and raise frame
Definition GUIDesigns.h:106
#define GUIDesignTextColorRed
red color (for invalid text)
Definition GUIDesigns.h:44
#define GUIDesignButtonIcon
button only with icon
Definition GUIDesigns.h:109
#define GUIDesignComboBoxAttribute
Combo box static (cannot be edited) extended over the matrix column.
Definition GUIDesigns.h:304
#define GUIDesignTextField
Definition GUIDesigns.h:74
#define GUIDesignAuxiliarHorizontalFrame
design for auxiliar (Without borders) horizontal frame used to pack another frames
Definition GUIDesigns.h:430
#define GUIDesignBackgroundColorRed
red background color (for invalid text)
Definition GUIDesigns.h:50
#define GUIDesignTextColorBlue
blue color (for default text)
Definition GUIDesigns.h:41
#define GUIDesignComboBoxVisibleItems
Definition GUIDesigns.h:64
#define GUIDesignTextColorBlack
black color (for correct text)
Definition GUIDesigns.h:38
#define GUIDesignBackgroundColorWhite
white background color (for valid text)
Definition GUIDesigns.h:47
#define GUIDesignCheckButton
checkButton placed in left position
Definition GUIDesigns.h:194
#define GUIDesignCheckButtonAttribute
checkButton without thick extended over the frame used for attributes
Definition GUIDesigns.h:203
#define GUIDesignLabelThickedFixed(width)
label thicked, icon before text, text centered and custom width
Definition GUIDesigns.h:254
@ OPEN
open icons
#define TL(string)
Definition MsgHandler.h:304
#define TLF(string,...)
Definition MsgHandler.h:306
SUMOVehicleClass getVehicleClassID(const std::string &name)
Returns the class id of the abstract class given by its name.
StringBijection< SUMOVehicleClass > SumoVehicleClassStrings(sumoVehicleClassStringInitializer, SVC_CUSTOM2, false)
POIIcon
POI icons.
@ SUMO_TAG_VTYPE
description of a vehicle/person/container type
@ SUMO_TAG_TAZSINK
a sink within a district (connection road)
@ SUMO_TAG_JUNCTION
begin/end of the description of a junction
@ SUMO_TAG_VTYPE_DISTRIBUTION
distribution of a vehicle type
@ SUMO_TAG_DATASET
@ SUMO_TAG_TYPE
type (edge)
@ SUMO_TAG_TAZSOURCE
a source within a district (connection road)
@ SUMO_TAG_EDGE
begin/end of the description of an edge
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
@ SUMO_ATTR_DISALLOW
@ SUMO_ATTR_ICON
icon
@ SUMO_ATTR_LANE
@ GNE_ATTR_PARENT
parent of an additional element
@ GNE_ATTR_PARAMETERS
parameters "key1=value1|key2=value2|...|keyN=valueN"
@ SUMO_ATTR_EXPECTED
@ GNE_ATTR_STOPOEXCEPTION
stop exceptions (virtual, used by edge and lanes)
@ SUMO_ATTR_SHAPE
edge: the shape in xml-definition
@ SUMO_ATTR_ANGLE
@ SUMO_ATTR_JOIN
@ SUMO_ATTR_VCLASS
@ GNE_ATTR_FRONTELEMENT
@ SUMO_ATTR_EXPECTED_CONTAINERS
@ SUMO_ATTR_TYPE
@ SUMO_ATTR_COLOR
A color information.
@ SUMO_ATTR_ID
@ SUMO_ATTR_RIGHT_OF_WAY
How to compute right of way.
@ SUMO_ATTR_POSITION
@ SUMO_ATTR_NOTHING
invalid attribute, must be the last one
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:46
void addDoubleListAttribute(const SumoXMLAttr attr, const std::vector< double > &value)
add double list attribute into current SumoBaseObject node
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)
add string attribute into current SumoBaseObject node
void addColorAttribute(const SumoXMLAttr attr, const RGBColor &value)
add color attribute into current SumoBaseObject node
void addParameters(const std::string &value)
add parameters into current SumoBaseObject node (format: key=value1|key2=value2|.....
static T parse(const std::string &string)
parses a value of type T from string (used for basic types: int, double, bool, etc....
static bool canParse(const std::string &string)
true if a value of type T can be parsed from string
bool isVClass() const
return true if attribute is a VehicleClass
bool isProbability() const
return true if attribute is a probability
const std::string & getDefaultStringValue() const
get default value in string format
bool isColor() const
return true if attribute is a color
bool isBool() const
return true if attribute is boolean
const std::string & getAttrStr() const
get XML Attribute in string format (can be updated using alternative name)
bool isPosition() const
return true if attribute is a position
const std::vector< std::string > & getFilenameExtensions() const
get filename extensions in string format used in open dialogs
SUMOTime getDefaultTimeValue() const
get default time value
bool isList() const
return true if attribute is a list
double getDefaultDoubleValue() const
get default double value
bool isInt() const
return true if attribute is an integer
bool isDiscrete() const
return true if attribute is discrete
bool isFileOpen() const
return true if attribute is a filename open
int getDefaultIntValue() const
get default int value
const std::string & getDefinition() const
get default value
bool isVType() const
return true if attribute is a VType or vTypeDistribution
bool isUnique() const
return true if attribute is unique
bool isFloat() const
return true if attribute is a float
const RGBColor & getDefaultColorValue() const
get default bool value
const GNETagProperties * getTagPropertyParent() const
get reference to tagProperty parent
bool isSUMOTime() const
return true if attribute is a SUMOTime
bool hasDefaultValue() const
return true if attribute owns a default value
bool isFileSave() const
return true if attribute is a filename save
bool isFlow() const
return true if attribute is part of a flow definition
bool isActivatable() const
return true if attribute is activatable
bool isPositive() const
return true if attribute is positive
const std::vector< std::string > & getDiscreteValues() const
get discrete values
const Position & getDefaultPositionValue() const
get default position value
bool isAlwaysEnabled() const
return true if attribute is always enabled
SumoXMLAttr getAttr() const
get XML Attribute
bool isAttributeRowShown() const
check if current attribute row is shown
void enableElements(const GNEAttributeProperties *attrProperty, const bool forceDisable)
check if enable or disable all elements depending of current supermode or forceDisable
MFXButtonTooltip * myValueLaneUpButton
Button for move lane up.
void showValueComboBox(const GNEAttributeProperties *attrProperty, const std::string &value, const bool enabled, const bool computed)
show value for combo Box
FXCheckButton * myAttributeToggleEnableCheckButton
pointer to attribute menu check
MFXButtonTooltip * myAttributeButton
pointer to button that can be used for files, color, parent, vclass or inspect
long onCmdInspectParent(FXObject *, FXSelector, void *)
called when user press "inspect parent"
MFXButtonTooltip * myValueLaneDownButton
Button for move lane down.
const std::string getAttributeValue(const bool enabled) const
get value from edited ACs
long onCmdOpenColorDialog(FXObject *sender, FXSelector, void *arg)
called when user press "edit color" dialog
void showAttributeColor(const GNEAttributeProperties *attrProperty, const bool enabled)
show attribute button color
bool isAttributeEnabled(const GNEAttributeProperties *attrProperty) const
check if the given attribute is enabled
void showAttributeVClass(const GNEAttributeProperties *attrProperty, const bool enabled)
show attribute button vClass
MFXLabelTooltip * myAttributeLabel
pointer to attribute label
MFXComboBoxIcon * myValueComboBox
pointer to combo box for select choices
SumoXMLAttr fillSumoBaseObject(CommonXMLStructure::SumoBaseObject *baseObject, const bool insertDefaultValues) const
fill sumo Base object
bool isValueValid() const
check if current attribute row is valid
bool hideAttributeRow()
hide attribute row (always return false)
void showAttributeLabel(const GNEAttributeProperties *attrProperty)
show attribute label
GNEAttributesEditorType * myAttributeTable
pointer to attribute table parent
long onCmdToggleEnableAttribute(FXObject *, FXSelector, void *)
called when user press the checkBox for toogle enable/disable attribute
std::string getCurrentValue() const
get current value in string format
const GNEAttributeProperties * getAttrProperty() const
get attribute property
GNEAttributesEditorRow()
default constructor (needed for FOX)
long onCmdMoveLaneDown(FXObject *, FXSelector, void *)
called when user press "move lane down"
long onCmdMoveLaneUp(FXObject *, FXSelector, void *)
called when user press "move lane up"
void showMoveLaneButtons(const std::string &laneID)
show move lane buttons
void showAttributeToggleEnable(const GNEAttributeProperties *attrProperty, const bool value)
show attribute toogle enable
FXCheckButton * myValueCheckButton
pointer to menu check
void showAttributeInspectParent(const GNEAttributeProperties *attrProperty, const bool enabled)
show attribute button inspect parent
const GNEAttributeProperties * myAttrProperty
edited attribute property
void showValueCheckButton(const std::string &value, const bool enabled, const bool computed)
show value for check button
MFXTextFieldIcon * myValueTextField
pointer to text field for modify values
void hideAllAttributeElements()
hide all attribute elements
long onCmdSetAttribute(FXObject *obj, FXSelector, void *)
set new string/bool attribute
bool showAttributeRow(GNEAttributesEditorType *attributeTable, const GNEAttributeProperties *attrProperty, const bool forceDisable)
return true if attribute row was successfully show
void showAttributeFile(const GNEAttributeProperties *attrProperty, const bool enabled)
show attribute button file
long onCmdOpenFileDialog(FXObject *, FXSelector, void *)
called when user press "open file" dialog
void showAttributeReparent(const bool enabled)
show attribute button reparent
long onCmdOpenVClassDialog(FXObject *, FXSelector, void *)
called when user press "open allow" dialog
void showValueString(const std::string &value, const bool enabled, const bool computed)
show value for strings
long onCmdReparent(FXObject *, FXSelector, void *)
called when user press reparent button
GNEFrame * getFrameParent() const
pointer to GNEFrame parent
bool isEditorTypeEditor() const
check if this is an attribute editor of type "editor"
GNEFrame * myFrameParent
pointer to GNEFrame parent
std::vector< GNEAttributeCarrier * > myEditedACs
current edited ACs
void setAttribute(SumoXMLAttr attr, const std::string &value)
set attribute in the current ACs (Callend from row)
void inspectParent()
inspect parent (Callend from row)
const EditorType myEditorType
variable use for packing editorType type options
void enableReparent()
void enable reparent
void toggleEnableAttribute(SumoXMLAttr attr, const bool value)
set attribute in the current ACs (Callend from row)
GNEViewNet * getViewNet() const
get view net
Definition GNEFrame.cpp:145
FXVerticalFrame * getCollapsableFrame()
get collapsable frame (used by all elements that will be collapsed if button is toggled)
GNELane * retrieveLane(const std::string &id, bool hardFail=true, bool checkVolatileChange=false) const
get lane by id
GNENetHelper::AttributeCarriers * getAttributeCarriers() const
get all attribute carriers used in this net
Definition GNENet.cpp:174
bool isMeanData() const
return true if tag correspond to a mean data element
GUIIcon getGUIIcon() const
get GUI icon associated to this tag property
SumoXMLTag getTag() const
get Tag vinculated with this attribute Property
bool isDemandElement() const
return true if tag correspond to a demand element
bool isAdditionalElement() const
return true if tag correspond to an additional element (note: this include TAZ, shapes and wires)
GNENet * getNet() const
get the net object
const GNEViewNetHelper::EditModes & getEditModes() const
get edit modes
GNEViewParent * getViewParent() const
get the net object
GNEApplicationWindow * getGNEAppWindows() const
get GNE Application Windows
static FXIcon * getIcon(const GUIIcon which)
returns a icon previously defined in the enum GUIIcon
long setCurrentItem(const FXint index, FXbool notify=FALSE)
Set the current item (index is zero-based)
FXint findItem(const FXString &text) const
find item
FXint getNumItems() const
Return the number of items in the list.
void setBackColor(FXColor clr)
Set window background color.
FXString getText() const
Get the text.
void setTextColor(FXColor clr)
Change text color.
virtual void clearItems()
Remove all items from the list.
void disable()
Disable combo box.
FXColor getTextColor() const
Return text color.
FXint appendIconItem(const FXString &text, FXIcon *icon=nullptr, FXColor bgColor=FXRGB(255, 255, 255), void *ptr=nullptr)
append icon item in the last position
void enable()
Enable combo box.
virtual void disable()
Disable text field.
virtual void killFocus()
Remove the focus from this window.
virtual void enable()
Enable text field.
FXColor getTextColor() const
Return text color.
FXString getText() const
Get the text for this label.
void setTextColor(FXColor clr)
Change text color.
void setText(const FXString &text, FXbool notify=FALSE)
Change the text and move cursor to end.
static FXIcon * getPOIIcon(POIIcon iconType)
returns icon associated to the given POI image
Definition POIIcons.cpp:30
static const RGBColor BLACK
Definition RGBColor.h:196
static StringBijection< POIIcon > POIIcons
POI icon values.
static StringBijection< RightOfWay > RightOfWayValues
righ of way algorithms
std::vector< T > getValues() const
get all keys
static std::string replace(std::string str, const std::string &what, const std::string &by)
Replaces all occurrences of the second string by the third string within the first string.
static FXIcon * getVClassIcon(const SUMOVehicleClass vc)
returns icon associated to the given vClass