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*) {
405 // If previous attribute wasn't correct, set black as default color
406 if (GNEAttributeCarrier::canParse<RGBColor>(myValueTextField->getText().text())) {
407 color = GNEAttributeCarrier::parse<RGBColor>(myValueTextField->getText().text());
408 } else if (myAttrProperty->hasDefaultValue()) {
410 }
411 // declare colorDialog
412 const auto colorDialog = new GNEColorDialog(myAttributeTable->getFrameParent()->getViewNet()->getViewParent()->getGNEAppWindows(), color);
413 // continue depending of result
414 if (colorDialog->getResult() == GNEDialog::Result::ACCEPT) {
415 myValueTextField->setText(toString(colorDialog->getColor()).c_str(), TRUE);
416 }
417 return 1;
418}
419
420
421long
423 // declare allowVClassesDialog
424 const auto allowVClassesDialog = new GNEVClassesDialog(myAttributeTable->getFrameParent()->getViewNet()->getViewParent()->getGNEAppWindows(),
426 // continue depending of result
427 if (allowVClassesDialog->getResult() == GNEDialog::Result::ACCEPT) {
428 myValueTextField->setText(allowVClassesDialog->getModifiedVClasses().c_str(), TRUE);
429 }
430 return 1;
431}
432
433
434long
435GNEAttributesEditorRow::onCmdOpenFileDialog(FXObject*, FXSelector, void*) {
436 // open dialog
442 // update text field
443 if (fileDialog.getResult() == GNEDialog::Result::ACCEPT) {
444 myValueTextField->setText(fileDialog.getFilename().c_str(), TRUE);
445 }
446 return 1;
447}
448
449
450long
451GNEAttributesEditorRow::onCmdReparent(FXObject*, FXSelector, void*) {
453 return 1;
454}
455
456
457long
458GNEAttributesEditorRow::onCmdInspectParent(FXObject*, FXSelector, void*) {
460 return 1;
461}
462
463
464long
465GNEAttributesEditorRow::onCmdMoveLaneUp(FXObject*, FXSelector, void*) {
467 return 1;
468}
469
470
471long
472GNEAttributesEditorRow::onCmdMoveLaneDown(FXObject*, FXSelector, void*) {
474 return 1;
475}
476
477
478long
479GNEAttributesEditorRow::onCmdSetAttribute(FXObject* obj, FXSelector, void*) {
480 if (myAttributeTable->myEditedACs.empty()) {
481 return 0;
482 }
483 const auto& editedAC = myAttributeTable->myEditedACs.front();
484 const auto attribute = myAttrProperty->getAttr();
485 // continue depending of clicked object
486 if (obj == myValueCheckButton) {
487 // Set true o false depending of the checkBox
488 if (myValueCheckButton->getCheck()) {
489 myValueCheckButton->setText("true");
490 } else {
491 myValueCheckButton->setText("false");
492 }
493 myAttributeTable->setAttribute(attribute, myValueCheckButton->getText().text());
494 } else if (obj == myValueComboBox) {
495 const std::string newValue = myValueComboBox->getText().text();
496 // check if the new comboBox value is valid
497 if (editedAC->isValid(attribute, newValue)) {
500 myValueComboBox->killFocus();
501 myAttributeTable->setAttribute(attribute, newValue);
502 } else {
503 // edit colors
505 if (newValue.empty()) {
507 }
508 }
509 } else if (obj == myValueTextField) {
510 // first check if set default value
512 // update text field without notify
514 }
515 // if we're editing an angle, check if filter between [0,360]
516 if ((attribute == SUMO_ATTR_ANGLE) && GNEAttributeCarrier::canParse<double>(myValueTextField->getText().text())) {
517 // filter anglea and update text field without notify
518 const double angle = fmod(GNEAttributeCarrier::parse<double>(myValueTextField->getText().text()), 360);
519 myValueTextField->setText(toString(angle).c_str(), FALSE);
520 }
521 // if we're editing a position or a shape, strip whitespace after comma
522 if ((attribute == SUMO_ATTR_POSITION) || (attribute == SUMO_ATTR_SHAPE)) {
523 std::string shape(myValueTextField->getText().text());
524 while (shape.find(", ") != std::string::npos) {
525 shape = StringUtils::replace(shape, ", ", ",");
526 }
527 myValueTextField->setText(toString(shape).c_str(), FALSE);
528 }
529 // if we're editing a int, strip decimal value
530 if (myAttrProperty->isInt() && GNEAttributeCarrier::canParse<double>(myValueTextField->getText().text())) {
531 double doubleValue = GNEAttributeCarrier::parse<double>(myValueTextField->getText().text());
532 if ((doubleValue - (int)doubleValue) == 0) {
533 myValueTextField->setText(toString((int)doubleValue).c_str(), FALSE);
534 }
535 }
536 // after apply all filters, obtain value
537 const std::string newValue = myValueTextField->getText().text();
538 // check if the new textField value is valid
539 if (editedAC->isValid(attribute, newValue)) {
543 if (myAttributeTable->isEditorTypeEditor() || newValue.empty() || (attribute != SUMO_ATTR_ID)) {
544 myAttributeTable->setAttribute(attribute, newValue);
545 }
546 } else {
547 // edit colors
549 if (newValue.empty()) {
551 }
552 }
553 }
554 return 1;
555}
556
557
558long
563
564
566 myAttributeTable(nullptr) {
567}
568
569
570const std::string
572 const auto attribute = myAttrProperty->getAttr();
573 // if we're in creator mode, generate ID
576 const auto parentTag = myAttrProperty->getTagPropertyParent()->getTag();
578 return ACs->generateEdgeID();
580 return ACs->generateAdditionalID(parentTag);
582 return ACs->generateDemandElementID(parentTag);
584 return ACs->generateMeanDataID(parentTag);
585 } else if (parentTag == SUMO_TAG_TYPE) {
586 return ACs->generateEdgeTypeID();
587 } else if (parentTag == SUMO_TAG_DATASET) {
588 return ACs->generateDataSetID();
589 }
590 }
591 if (enabled) {
592 // Declare a set of occurring values and insert attribute's values of item (note: We use a set to avoid repeated values)
593 std::set<std::string> values;
594 // iterate over edited attributes and insert every value in set
595 for (const auto& editedAC : myAttributeTable->myEditedACs) {
596 if (editedAC->hasAttribute(attribute)) {
597 values.insert(editedAC->getAttribute(attribute));
598 }
599 }
600 // merge all values in a single string
601 std::ostringstream oss;
602 for (auto it = values.begin(); it != values.end(); it++) {
603 if (it != values.begin()) {
604 oss << " ";
605 }
606 oss << *it;
607 }
608 // obtain value to be shown in row
609 return oss.str();
610 } else {
611 return myAttributeTable->myEditedACs.front()->getAlternativeValueForDisabledAttributes(attribute);
612 }
613}
614
615
616void
618 myAttributeToggleEnableCheckButton->setText(attrProperty->getAttrStr().c_str());
619 myAttributeToggleEnableCheckButton->setCheck(value);
622 // hide other elements
623 myAttributeLabel->hide();
624 myAttributeButton->hide();
625}
626
627
628void
630 // update attribute button
631 myAttributeButton->setText(TL("Reparent"));
632 myAttributeButton->setHelpText(TL("Change parent of this element"));
633 myAttributeButton->setTipText(myAttributeButton->getHelpText());
634 myAttributeButton->setIcon(nullptr);
636 if (enabled) {
637 myAttributeButton->enable();
638 } else {
639 myAttributeButton->disable();
640 }
641 myAttributeButton->show();
642 // hide other elements
643 myAttributeLabel->hide();
645}
646
647
648void
650 // update attribute button
651 myAttributeButton->setText(attrProperty->getAttrStr().c_str());
652 myAttributeButton->setHelpText(TLF("Inspect % parent", attrProperty->getAttrStr()).c_str());
653 myAttributeButton->setTipText(myAttributeButton->getHelpText());
656 if (enabled) {
657 myAttributeButton->enable();
658 } else {
659 myAttributeButton->disable();
660 }
661 myAttributeButton->show();
662 // hide other elements
663 myAttributeLabel->hide();
665}
666
667
668void
670 // update attribute button
671 myAttributeButton->setText(attrProperty->getAttrStr().c_str());
672 myAttributeButton->setHelpText(TL("Open dialog for editing vClasses"));
673 myAttributeButton->setTipText(myAttributeButton->getHelpText());
674 myAttributeButton->setIcon(nullptr);
676 if (enabled) {
677 myAttributeButton->enable();
678 } else {
679 myAttributeButton->disable();
680 }
681 myAttributeButton->show();
682 // hide other elements
683 myAttributeLabel->hide();
685}
686
687
688void
690 // update attribute button
691 myAttributeButton->setText(attrProperty->getAttrStr().c_str());
692 myAttributeButton->setHelpText(TL("Open dialog for editing color"));
693 myAttributeButton->setTipText(myAttributeButton->getHelpText());
696 if (enabled) {
697 myAttributeButton->enable();
698 } else {
699 myAttributeButton->disable();
700 }
701 myAttributeButton->show();
702 // hide other elements
703 myAttributeLabel->hide();
705}
706
707
708void
710 // update attribute button
711 myAttributeButton->setText(attrProperty->getAttrStr().c_str());
712 if (attrProperty->isFileOpen()) {
713 myAttributeButton->setHelpText(TL("Open dialog to select an existent file"));
714 } else {
715 myAttributeButton->setHelpText(TL("Open dialog to select or create an existent file"));
716 }
717 myAttributeButton->setTipText(myAttributeButton->getHelpText());
720 if (enabled) {
721 myAttributeButton->enable();
722 } else {
723 myAttributeButton->disable();
724 }
725 myAttributeButton->show();
726 // hide other elements
727 myAttributeLabel->hide();
729}
730
731
732void
734 myAttributeLabel->setText(attrProperty->getAttrStr().c_str());
735 myAttributeLabel->setTipText(attrProperty->getDefinition().c_str());
736 myAttributeLabel->show();
737 // hide other elements
739 myAttributeButton->hide();
740}
741
742
743void
749
750
751void
753 const bool enabled, const bool computed) {
754 // first we need to check if all boolean values are equal
755 bool allValuesEqual = true;
756 // declare boolean vector
757 std::vector<bool> booleanVector;
758 // check if value can be parsed to a boolean vector
759 if (GNEAttributeCarrier::canParse<std::vector<bool> >(value)) {
760 booleanVector = GNEAttributeCarrier::parse<std::vector<bool> >(value);
761 }
762 // iterate over booleans comparing all element with the first
763 for (const auto& booleanValue : booleanVector) {
764 if (booleanValue != booleanVector.front()) {
765 allValuesEqual = false;
766 }
767 }
768 // use checkbox or textfield depending if all booleans are equal
769 if (allValuesEqual) {
770 if (enabled) {
771 myValueCheckButton->enable();
772 } else {
773 myValueCheckButton->disable();
774 }
775 // set check button
776 if ((booleanVector.size() > 0) && booleanVector.front()) {
777 myValueCheckButton->setCheck(true);
778 myValueCheckButton->setText("true");
779 } else {
780 myValueCheckButton->setCheck(false);
781 myValueCheckButton->setText("false");
782 }
783 // show check button
784 myValueCheckButton->show();
785 // hide other value elements
786 myValueTextField->hide();
787 myValueComboBox->hide();
788 myValueLaneUpButton->hide();
789 myValueLaneDownButton->hide();
790 } else {
791 // show value as string
792 showValueString(value, enabled, computed);
793 }
794}
795
796
797void
798GNEAttributesEditorRow::showValueComboBox(const GNEAttributeProperties* attrProperty, const std::string& value,
799 const bool enabled, const bool computed) {
800 // first we need to check if all boolean values are equal
801 bool allValuesEqual = true;
802 // declare boolean vector
803 std::vector<std::string> stringVector = GNEAttributeCarrier::parse<std::vector<std::string> >(value);
804 // iterate over string comparing all element with the first
805 for (const auto& stringValue : stringVector) {
806 if (stringValue != stringVector.front()) {
807 allValuesEqual = false;
808 }
809 }
810 // use checkbox or textfield depending if all booleans are equal
811 if (allValuesEqual) {
812 // clear and enable comboBox
816 if (enabled) {
818 } else {
820 }
821 // fill depeding of ACAttr
822 if (attrProperty->getAttr() == SUMO_ATTR_VCLASS) {
823 // add all vClasses with their icons
824 for (const auto& vClassStr : SumoVehicleClassStrings.getStrings()) {
826 }
827 } else if (attrProperty->isVType()) {
828 // get ACs
830 // fill comboBox with all vTypes and vType distributions sorted by ID
831 std::map<std::string, GNEDemandElement*> sortedTypes;
832 for (const auto& type : ACs->getDemandElements().at(SUMO_TAG_VTYPE)) {
833 sortedTypes[type.second->getID()] = type.second;
834 }
835 for (const auto& sortedType : sortedTypes) {
836 myValueComboBox->appendIconItem(sortedType.first.c_str(), sortedType.second->getACIcon());
837 }
838 sortedTypes.clear();
839 for (const auto& typeDistribution : ACs->getDemandElements().at(SUMO_TAG_VTYPE_DISTRIBUTION)) {
840 sortedTypes[typeDistribution.second->getID()] = typeDistribution.second;
841 }
842 for (const auto& sortedType : sortedTypes) {
843 myValueComboBox->appendIconItem(sortedType.first.c_str(), sortedType.second->getACIcon());
844 }
845 } else if (attrProperty->getAttr() == SUMO_ATTR_ICON) {
846 // add all POIIcons with their icons
847 for (const auto& POIIcon : SUMOXMLDefinitions::POIIcons.getValues()) {
849 }
850 } else if ((attrProperty->getAttr() == SUMO_ATTR_RIGHT_OF_WAY) && (myAttributeTable->myEditedACs.size() == 1) &&
851 (attrProperty->getTagPropertyParent()->getTag() == SUMO_TAG_JUNCTION)) {
852 // special case for junction types
853 if (myAttributeTable->myEditedACs.front()->getAttribute(SUMO_ATTR_TYPE) == "priority") {
856 } else if (myAttributeTable->myEditedACs.front()->getAttribute(SUMO_ATTR_TYPE) == "traffic_light") {
860 } else {
862 }
863 } else {
864 // fill comboBox with discrete values
865 for (const auto& discreteValue : attrProperty->getDiscreteValues()) {
866 myValueComboBox->appendIconItem(discreteValue.c_str(), nullptr);
867 }
868 }
869 // set current value (or disable)
870 const auto index = myValueComboBox->findItem(value.c_str());
871 if (index < 0) {
872 if (myValueComboBox->getNumItems() > 0) {
874 } else {
876 }
877 } else {
879 }
880 // show comboBox button
881 myValueComboBox->show();
882 // hide other value elements
883 myValueTextField->hide();
884 myValueCheckButton->hide();
885 myValueLaneUpButton->hide();
886 myValueLaneDownButton->hide();
887 } else {
888 // show value as string
889 showValueString(value, enabled, computed);
890 }
891}
892
893
894void
895GNEAttributesEditorRow::showValueString(const std::string& value, const bool enabled, const bool computed) {
896 // clear and enable comboBox
897 myValueTextField->setText(value.c_str());
898 if (computed) {
900 } else {
902 }
903 if (enabled) {
905 } else {
907 }
908 // show list of values
909 myValueTextField->show();
910 // hide other value elements
911 myValueCheckButton->hide();
912 myValueComboBox->hide();
913}
914
915
916void
918 // retrieve lane
919 const auto lane = myAttributeTable->myFrameParent->getViewNet()->getNet()->getAttributeCarriers()->retrieveLane(laneID, false);
920 // check lane
921 if (lane) {
922 // check if disable move up
923 if ((lane->getIndex() + 1) >= (int)lane->getParentEdge()->getChildLanes().size()) {
924 myValueLaneUpButton->disable();
925 } else {
926 myValueLaneUpButton->enable();
927 }
928 // check if disable move down
929 if ((lane->getIndex() - 1) < 0) {
930 myValueLaneDownButton->disable();
931 } else {
932 myValueLaneDownButton->enable();
933 }
934 } else {
935 // if lane doesn't exist, disable both
936 myValueLaneUpButton->disable();
937 myValueLaneDownButton->disable();
938 }
939}
940
941
942void
943GNEAttributesEditorRow::enableElements(const GNEAttributeProperties* attrProperty, const bool forceDisable) {
944 const auto& editModes = myAttributeTable->myFrameParent->getViewNet()->getEditModes();
945 const auto tagProperty = attrProperty->getTagPropertyParent();
946 // by default we assume that elements are disabled
947 bool enableElements = false;
948 if (forceDisable) {
949 enableElements = false;
950 } else if (editModes.isCurrentSupermodeNetwork()) {
951 if (tagProperty->isNetworkElement() || tagProperty->isAdditionalElement()) {
952 enableElements = true;
953 } else if ((tagProperty->getTag() == SUMO_TAG_TAZSOURCE) || (tagProperty->getTag() == SUMO_TAG_TAZSINK)) {
954 enableElements = true;
955 }
956 } else if (editModes.isCurrentSupermodeDemand() && tagProperty->isDemandElement()) {
957 enableElements = true;
958 } else if (editModes.isCurrentSupermodeData() && (tagProperty->isDataElement() || tagProperty->isMeanData())) {
959 enableElements = true;
960 }
961 if (!enableElements) {
963 myAttributeButton->disable();
966 myValueCheckButton->disable();
967 myValueLaneUpButton->disable();
968 myValueLaneDownButton->disable();
969 }
970}
971
972
973bool
975 if (attrProperty->isAlwaysEnabled()) {
976 return true;
977 } else {
978 for (const auto& AC : myAttributeTable->myEditedACs) {
979 if (AC->isAttributeEnabled(attrProperty->getAttr())) {
980 return true;
981 }
982 }
983 return false;
984 }
985}
986
987/****************************************************************************/
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:152
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:144
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.
FXVerticalFrame * getCollapsableFrame()
get collapsable frame (used by all elements that will be collapsed if button is toggled)
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