Path: blob/main/src/netedit/elements/GNEAttributeCarrier.cpp
169678 views
/****************************************************************************/1// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo2// Copyright (C) 2001-2025 German Aerospace Center (DLR) and others.3// This program and the accompanying materials are made available under the4// terms of the Eclipse Public License 2.0 which is available at5// https://www.eclipse.org/legal/epl-2.0/6// This Source Code may also be made available under the following Secondary7// Licenses when the conditions for such availability set forth in the Eclipse8// Public License 2.0 are satisfied: GNU General Public License, version 29// or later which is available at10// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html11// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later12/****************************************************************************/13/// @file GNEAttributeCarrier.cpp14/// @author Jakob Erdmann15/// @date Feb 201116///17// Abstract Base class for gui objects which carry attributes18/****************************************************************************/1920#include <netedit/GNENet.h>21#include <netedit/GNETagPropertiesDatabase.h>22#include <netedit/GNEUndoList.h>23#include <netedit/GNEViewNet.h>24#include <netedit/changes/GNEChange_Attribute.h>25#include <utils/common/StringTokenizer.h>26#include <utils/common/ToString.h>27#include <utils/emissions/PollutantsInterface.h>28#include <utils/geom/GeomConvHelper.h>29#include <utils/gui/div/GUIGlobalSelection.h>30#include <utils/gui/images/VClassIcons.h>31#include <utils/iodevices/OutputDevice.h>32#include <utils/options/OptionsCont.h>33#include <utils/shapes/PointOfInterest.h>3435#include "GNEAttributeCarrier.h"3637// ===========================================================================38// static members39// ===========================================================================4041const std::string GNEAttributeCarrier::FEATURE_LOADED = "loaded";42const std::string GNEAttributeCarrier::FEATURE_GUESSED = "guessed";43const std::string GNEAttributeCarrier::FEATURE_MODIFIED = "modified";44const std::string GNEAttributeCarrier::FEATURE_APPROVED = "approved";45const std::string GNEAttributeCarrier::LANE_START = TL("lane start");46const std::string GNEAttributeCarrier::LANE_END = TL("lane end");47const std::string GNEAttributeCarrier::TRUE_STR = toString(true);48const std::string GNEAttributeCarrier::FALSE_STR = toString(false);4950// ===========================================================================51// method definitions52// ===========================================================================5354GNEAttributeCarrier::GNEAttributeCarrier(const SumoXMLTag tag, GNENet* net, const std::string& filename, const bool isTemplate) :55myTagProperty(net->getTagPropertiesDatabase()->getTagProperty(tag, true)),56myNet(net),57myFilename(filename),58myIsTemplate(isTemplate) {59// check if add this AC to saving file handler60if (myFilename.size() > 0) {61// add filename to saving files handler62if (myTagProperty->isAdditionalElement()) {63net->getSavingFilesHandler()->addAdditionalFilename(this);64} else if (myTagProperty->isDemandElement()) {65net->getSavingFilesHandler()->addDemandFilename(this);66} else if (myTagProperty->isDataElement()) {67net->getSavingFilesHandler()->addDataFilename(this);68} else if (myTagProperty->isMeanData()) {69net->getSavingFilesHandler()->addMeanDataFilename(this);70}71} else {72// always avoid empty files73if (myTagProperty->isAdditionalElement() && (net->getSavingFilesHandler()->getAdditionalFilenames().size() > 0)) {74myFilename = net->getSavingFilesHandler()->getAdditionalFilenames().front();75} else if (myTagProperty->isDemandElement() && (net->getSavingFilesHandler()->getDemandFilenames().size() > 0)) {76myFilename = net->getSavingFilesHandler()->getDemandFilenames().front();77} else if (myTagProperty->isDataElement() && (net->getSavingFilesHandler()->getDataFilenames().size() > 0)) {78myFilename = net->getSavingFilesHandler()->getDataFilenames().front();79} else if (myTagProperty->isMeanData() && (net->getSavingFilesHandler()->getMeanDataFilenames().size() > 0)) {80myFilename = net->getSavingFilesHandler()->getMeanDataFilenames().front();81}82}83}848586GNEAttributeCarrier::~GNEAttributeCarrier() {}878889const std::string90GNEAttributeCarrier::getID() const {91return getAttribute(SUMO_ATTR_ID);92}939495GNENet*96GNEAttributeCarrier::getNet() const {97return myNet;98}99100101const std::string&102GNEAttributeCarrier::getFilename() const {103return myFilename;104}105106107void108GNEAttributeCarrier::changeDefaultFilename(const std::string& file) {109if (myFilename.empty()) {110myFilename = file;111}112}113114115void116GNEAttributeCarrier::selectAttributeCarrier() {117auto glObject = getGUIGlObject();118if (glObject && myTagProperty->isSelectable()) {119gSelected.select(glObject->getGlID());120mySelected = true;121}122}123124125void126GNEAttributeCarrier::unselectAttributeCarrier() {127auto glObject = getGUIGlObject();128if (glObject && myTagProperty->isSelectable()) {129gSelected.deselect(glObject->getGlID());130mySelected = false;131}132}133134135bool136GNEAttributeCarrier::isAttributeCarrierSelected() const {137return mySelected;138}139140141bool142GNEAttributeCarrier::drawUsingSelectColor() const {143// first check if element is selected144if (mySelected) {145// get flag for network element146const bool networkElement = myTagProperty->isNetworkElement() || myTagProperty->isAdditionalElement();147// check current supermode148if (networkElement && myNet->getViewNet()->getEditModes().isCurrentSupermodeNetwork()) {149return true;150} else if (myTagProperty->isDemandElement() && myNet->getViewNet()->getEditModes().isCurrentSupermodeDemand()) {151return true;152} else if (myTagProperty->isGenericData() && myNet->getViewNet()->getEditModes().isCurrentSupermodeData()) {153return true;154} else {155return false;156}157} else {158return false;159}160}161162void163GNEAttributeCarrier::markForDrawingFront() {164myNet->getViewNet()->getMarkFrontElements().markAC(this);165myDrawInFront = true;166}167168169void170GNEAttributeCarrier::unmarkForDrawingFront() {171myNet->getViewNet()->getMarkFrontElements().unmarkAC(this);172myDrawInFront = false;173}174175176bool177GNEAttributeCarrier::isMarkedForDrawingFront() const {178return myDrawInFront;179}180181182void183GNEAttributeCarrier::drawInLayer(double typeOrLayer, const double extraOffset) const {184if (myDrawInFront) {185glTranslated(0, 0, GLO_FRONTELEMENT + extraOffset);186} else {187glTranslated(0, 0, typeOrLayer + extraOffset);188}189}190191192void193GNEAttributeCarrier::setInGrid(bool value) {194myInGrid = value;195}196197198bool199GNEAttributeCarrier::inGrid() const {200return myInGrid;201}202203204bool205GNEAttributeCarrier::checkDrawInspectContour() const {206return myNet->getViewNet()->getInspectedElements().isACInspected(this);207}208209210bool211GNEAttributeCarrier::checkDrawFrontContour() const {212return myDrawInFront;213}214215216void217GNEAttributeCarrier::resetDefaultValues(const bool allowUndoRedo) {218if (allowUndoRedo) {219// reset within undo-redo220const auto undoList = myNet->getViewNet()->getUndoList();221undoList->begin(myTagProperty->getGUIIcon(), TLF("reset %", myTagProperty->getTagStr()));222for (const auto& attrProperty : myTagProperty->getAttributeProperties()) {223if (!attrProperty->isUnique() && attrProperty->hasDefaultValue()) {224setAttribute(attrProperty->getAttr(), attrProperty->getDefaultStringValue(), undoList);225if (attrProperty->isActivatable()) {226if (attrProperty->getDefaultActivated()) {227enableAttribute(attrProperty->getAttr(), undoList);228} else {229disableAttribute(attrProperty->getAttr(), undoList);230}231}232}233}234undoList->end();235} else {236// simply reset every237for (const auto& attrProperty : myTagProperty->getAttributeProperties()) {238if (attrProperty->hasDefaultValue()) {239setAttribute(attrProperty->getAttr(), attrProperty->getDefaultStringValue());240if (attrProperty->isActivatable()) {241toggleAttribute(attrProperty->getAttr(), attrProperty->getDefaultActivated());242}243}244}245}246}247248249void250GNEAttributeCarrier::enableAttribute(SumoXMLAttr /*key*/, GNEUndoList* /*undoList*/) {251throw ProcessError(TL("Nothing to enable, implement in Children"));252253}254255256void257GNEAttributeCarrier::disableAttribute(SumoXMLAttr /*key*/, GNEUndoList* /*undoList*/) {258throw ProcessError(TL("Nothing to disable, implement in Children"));259}260261262bool263GNEAttributeCarrier::isAttributeEnabled(SumoXMLAttr /*key*/) const {264// by default, all attributes are enabled265return true;266}267268269bool270GNEAttributeCarrier::isAttributeComputed(SumoXMLAttr /*key*/) const {271// by default, all attributes aren't computed272return false;273}274275276bool277GNEAttributeCarrier::hasAttribute(SumoXMLAttr key) const {278return myTagProperty->hasAttribute(key);279}280281// canParse functions282283template<> bool284GNEAttributeCarrier::canParse<int>(const std::string& string) {285if (string == "INVALID_INT") {286return true;287} else {288return StringUtils::isInt(string);289}290}291292293template<> bool294GNEAttributeCarrier::canParse<double>(const std::string& string) {295if (string == "INVALID_DOUBLE") {296return true;297} else {298return StringUtils::isDouble(string);299}300}301302303template<> bool304GNEAttributeCarrier::canParse<SUMOTime>(const std::string& string) {305return isTime(string);306}307308309template<> bool310GNEAttributeCarrier::canParse<bool>(const std::string& string) {311return StringUtils::isBool(string);312}313314315template<> bool316GNEAttributeCarrier::canParse<Position>(const std::string& string) {317bool ok = true;318GeomConvHelper::parseShapeReporting(string, "position", 0, ok, true, false);319return ok;320}321322323template<> bool324GNEAttributeCarrier::canParse<SUMOVehicleClass>(const std::string& string) {325return SumoVehicleClassStrings.hasString(string);326}327328329template<> bool330GNEAttributeCarrier::canParse<RGBColor>(const std::string& string) {331return RGBColor::isColor(string);332}333334335template<> bool336GNEAttributeCarrier::canParse<SumoXMLAttr>(const std::string& string) {337return SUMOXMLDefinitions::Attrs.hasString(string);338}339340341template<> bool342GNEAttributeCarrier::canParse<SUMOVehicleShape>(const std::string& string) {343if (string.empty()) {344return true;345} else {346return SumoVehicleShapeStrings.hasString(string);347}348}349350351template<> bool352GNEAttributeCarrier::canParse<PositionVector>(const std::string& string) {353bool ok = true;354GeomConvHelper::parseShapeReporting(string, "shape", 0, ok, true, false);355return ok;356}357358359template<> bool360GNEAttributeCarrier::canParse<std::vector<int> >(const std::string& string) {361if (string.empty()) {362return true;363}364const auto values = StringTokenizer(string).getVector();365for (const auto& value : values) {366if (!canParse<int>(value)) {367return false;368}369}370return true;371}372373374template<> bool375GNEAttributeCarrier::canParse<std::vector<double> >(const std::string& string) {376if (string.empty()) {377return true;378}379const auto values = StringTokenizer(string).getVector();380for (const auto& value : values) {381if (!canParse<double>(value)) {382return false;383}384}385return true;386}387388389template<> bool390GNEAttributeCarrier::canParse<std::vector<bool> >(const std::string& string) {391if (string.empty()) {392return true;393}394const auto values = StringTokenizer(string).getVector();395for (const auto& value : values) {396if (!canParse<bool>(value)) {397return false;398}399}400return true;401}402403404template<> bool405GNEAttributeCarrier::canParse<std::vector<SumoXMLAttr> >(const std::string& string) {406if (string.empty()) {407return true;408}409const auto values = StringTokenizer(string).getVector();410for (const auto& value : values) {411if (!canParse<SumoXMLAttr>(value)) {412return false;413}414}415return true;416}417418// parse functions419420template<> int421GNEAttributeCarrier::parse(const std::string& string) {422if (string == "INVALID_INT") {423return INVALID_INT;424} else {425return StringUtils::toInt(string);426}427}428429430template<> double431GNEAttributeCarrier::parse(const std::string& string) {432if (string == "INVALID_DOUBLE") {433return INVALID_DOUBLE;434} else {435return StringUtils::toDouble(string);436}437}438439440template<> SUMOTime441GNEAttributeCarrier::parse(const std::string& string) {442return string2time(string);443}444445446template<> bool447GNEAttributeCarrier::parse(const std::string& string) {448return StringUtils::toBool(string);449}450451452template<> SUMOVehicleClass453GNEAttributeCarrier::parse(const std::string& string) {454if (string.size() == 0) {455throw EmptyData();456} else if (!SumoVehicleClassStrings.hasString(string)) {457return SVC_IGNORING;458} else {459return SumoVehicleClassStrings.get(string);460}461}462463464template<> RGBColor465GNEAttributeCarrier::parse(const std::string& string) {466if (string.empty()) {467return RGBColor::INVISIBLE;468} else {469return RGBColor::parseColor(string);470}471}472473474template<> Position475GNEAttributeCarrier::parse(const std::string& string) {476// we handle empty strings as position invalids477if (string.size() == 0) {478return Position::INVALID;479} else {480bool ok = true;481PositionVector pos = GeomConvHelper::parseShapeReporting(string, "user-supplied position", 0, ok, false, false);482if (!ok || (pos.size() != 1)) {483throw NumberFormatException("(Position) " + string);484} else {485return pos[0];486}487}488}489490491template<> PositionVector492GNEAttributeCarrier::parse(const std::string& string) {493PositionVector posVector;494// empty string are allowed (It means empty position vector)495if (string.empty()) {496return posVector;497} else {498bool ok = true;499posVector = GeomConvHelper::parseShapeReporting(string, "user-supplied shape", 0, ok, false, true);500if (!ok) {501throw NumberFormatException("(Position List) " + string);502} else {503return posVector;504}505}506}507508509template<> SUMOVehicleShape510GNEAttributeCarrier::parse(const std::string& string) {511if (string.empty()) {512return SUMOVehicleShape::UNKNOWN;513} else {514return SumoVehicleShapeStrings.get(string);515}516}517518519template<> std::vector<std::string>520GNEAttributeCarrier::parse(const std::string& string) {521return StringTokenizer(string).getVector();522}523524525template<> std::set<std::string>526GNEAttributeCarrier::parse(const std::string& string) {527const auto vectorString = StringTokenizer(string).getVector();528std::set<std::string> solution;529for (const auto& stringValue : vectorString) {530solution.insert(stringValue);531}532return solution;533}534535536template<> std::vector<int>537GNEAttributeCarrier::parse(const std::string& string) {538const auto vectorInt = parse<std::vector<std::string> >(string);539std::vector<int> parsedIntValues;540for (const auto& intValue : vectorInt) {541parsedIntValues.push_back(parse<int>(intValue));542}543return parsedIntValues;544}545546547template<> std::vector<double>548GNEAttributeCarrier::parse(const std::string& string) {549const auto vectorDouble = parse<std::vector<std::string> >(string);550std::vector<double> parsedDoubleValues;551for (const auto& doubleValue : vectorDouble) {552parsedDoubleValues.push_back(parse<double>(doubleValue));553}554return parsedDoubleValues;555}556557558template<> std::vector<bool>559GNEAttributeCarrier::parse(const std::string& string) {560const auto vectorBool = parse<std::vector<std::string> >(string);561std::vector<bool> parsedBoolValues;562for (const auto& boolValue : vectorBool) {563parsedBoolValues.push_back(parse<bool>(boolValue));564}565return parsedBoolValues;566}567568569template<> std::vector<SumoXMLAttr>570GNEAttributeCarrier::parse(const std::string& value) {571// Declare string vector572const auto attributesStr = parse<std::vector<std::string> > (value);573std::vector<SumoXMLAttr> attributes;574// Iterate over lanes IDs, retrieve Lanes and add it into parsedLanes575for (const auto& attributeStr : attributesStr) {576if (SUMOXMLDefinitions::Attrs.hasString(attributeStr)) {577attributes.push_back(static_cast<SumoXMLAttr>(SUMOXMLDefinitions::Attrs.get(attributeStr)));578} else {579throw FormatException("Error parsing attributes. Attribute '" + attributeStr + "' doesn't exist");580}581}582return attributes;583}584585// can parse (network) functions586587template<> bool588GNEAttributeCarrier::canParse<std::vector<GNEEdge*> >(const GNENet* net, const std::string& value, const bool checkConsecutivity) {589// Declare string vector590const auto edgeIds = parse<std::vector<std::string> > (value);591std::vector<GNEEdge*> parsedEdges;592parsedEdges.reserve(edgeIds.size());593for (const auto& edgeID : edgeIds) {594const auto edge = net->getAttributeCarriers()->retrieveEdge(edgeID, false);595if (edge == nullptr) {596return false;597} else if (checkConsecutivity) {598if ((parsedEdges.size() > 0) && (parsedEdges.back()->getToJunction() != edge->getFromJunction())) {599return false;600}601parsedEdges.push_back(edge);602}603}604return true;605}606607608template<> bool609GNEAttributeCarrier::canParse<std::vector<GNELane*> >(const GNENet* net, const std::string& value, const bool checkConsecutivity) {610// Declare string vector611const auto laneIds = parse<std::vector<std::string> > (value);612std::vector<GNELane*> parsedLanes;613parsedLanes.reserve(laneIds.size());614// Iterate over lanes IDs, retrieve Lanes and add it into parsedLanes615for (const auto& laneID : laneIds) {616const auto lane = net->getAttributeCarriers()->retrieveLane(laneID, false);617if (lane == nullptr) {618return false;619} else if (checkConsecutivity) {620if ((parsedLanes.size() > 0) && (parsedLanes.back()->getParentEdge()->getToJunction() != lane->getParentEdge()->getFromJunction())) {621return false;622}623parsedLanes.push_back(lane);624}625}626return true;627}628629// parse (network) functions630631template<> std::vector<GNEEdge*>632GNEAttributeCarrier::parse(const GNENet* net, const std::string& value) {633// Declare string vector634const auto edgeIds = parse<std::vector<std::string> > (value);635std::vector<GNEEdge*> parsedEdges;636parsedEdges.reserve(edgeIds.size());637// Iterate over edges IDs, retrieve Edges and add it into parsedEdges638for (const auto& edgeID : edgeIds) {639parsedEdges.push_back(net->getAttributeCarriers()->retrieveEdge(edgeID));640}641return parsedEdges;642}643644645template<> std::vector<GNELane*>646GNEAttributeCarrier::parse(const GNENet* net, const std::string& value) {647// Declare string vector648const auto laneIds = parse<std::vector<std::string> > (value);649std::vector<GNELane*> parsedLanes;650parsedLanes.reserve(laneIds.size());651// Iterate over lanes IDs, retrieve Lanes and add it into parsedLanes652for (const auto& laneID : laneIds) {653parsedLanes.push_back(net->getAttributeCarriers()->retrieveLane(laneID));654}655return parsedLanes;656}657658// parse ID functions659660template<> std::string661GNEAttributeCarrier::parseIDs(const std::vector<GNEEdge*>& ACs) {662// obtain ID's of edges and return their join663std::vector<std::string> edgeIDs;664for (const auto& AC : ACs) {665edgeIDs.push_back(AC->getID());666}667return joinToString(edgeIDs, " ");668}669670671template<> std::string672GNEAttributeCarrier::parseIDs(const std::vector<GNELane*>& ACs) {673// obtain ID's of lanes and return their join674std::vector<std::string> laneIDs;675for (const auto& AC : ACs) {676laneIDs.push_back(AC->getID());677}678return joinToString(laneIDs, " ");679}680681void682GNEAttributeCarrier::setACParameters(const std::vector<std::pair<std::string, std::string> >& parameters) {683// declare result string684std::string paramsStr;685// Generate an string using the following structure: "key1=value1|key2=value2|...686for (const auto& parameter : parameters) {687paramsStr += parameter.first + "=" + parameter.second + "|";688}689// remove the last "|"690if (!paramsStr.empty()) {691paramsStr.pop_back();692}693// set parameters694setAttribute(GNE_ATTR_PARAMETERS, paramsStr);695}696697698void699GNEAttributeCarrier::setACParameters(const std::vector<std::pair<std::string, std::string> >& parameters, GNEUndoList* undoList) {700// declare parametersMap701Parameterised::Map parametersMap;702// Generate an string using the following structure: "key1=value1|key2=value2|...703for (const auto& parameter : parameters) {704parametersMap[parameter.first] = parameter.second;705}706// set setACParameters map707setACParameters(parametersMap, undoList);708}709710711void712GNEAttributeCarrier::setACParameters(const Parameterised::Map& parameters, GNEUndoList* undoList) {713// declare result string714std::string paramsStr;715// Generate an string using the following structure: "key1=value1|key2=value2|...716for (const auto& parameter : parameters) {717paramsStr += parameter.first + "=" + parameter.second + "|";718}719// remove the last "|"720if (!paramsStr.empty()) {721paramsStr.pop_back();722}723// set parameters724setAttribute(GNE_ATTR_PARAMETERS, paramsStr, undoList);725}726727728std::string729GNEAttributeCarrier::getAlternativeValueForDisabledAttributes(SumoXMLAttr key) const {730switch (key) {731// Crossings732case SUMO_ATTR_TLLINKINDEX:733case SUMO_ATTR_TLLINKINDEX2:734return "No TLS";735// connections736case SUMO_ATTR_DIR: {737// special case for connection directions738std::string direction = getAttribute(key);739if (direction == "s") {740return "Straight (s)";741} else if (direction == "t") {742return "Turn (t))";743} else if (direction == "l") {744return "Left (l)";745} else if (direction == "r") {746return "Right (r)";747} else if (direction == "L") {748return "Partially left (L)";749} else if (direction == "R") {750return "Partially right (R)";751} else if (direction == "invalid") {752return "No direction (Invalid))";753} else {754return "undefined";755}756}757case SUMO_ATTR_STATE: {758// special case for connection states759std::string state = getAttribute(key);760if (state == "-") {761return "Dead end (-)";762} else if (state == "=") {763return "equal (=)";764} else if (state == "m") {765return "Minor link (m)";766} else if (state == "M") {767return "Major link (M)";768} else if (state == "O") {769return "TLS controller off (O)";770} else if (state == "o") {771return "TLS yellow flashing (o)";772} else if (state == "y") {773return "TLS yellow minor link (y)";774} else if (state == "Y") {775return "TLS yellow major link (Y)";776} else if (state == "r") {777return "TLS red (r)";778} else if (state == "g") {779return "TLS green minor (g)";780} else if (state == "G") {781return "TLS green major (G)";782} else if (state == "Z") {783return "Zipper (Z)";784} else {785return "undefined";786}787}788default:789return getAttribute(key);790}791}792793794std::string795GNEAttributeCarrier::getAttributeForSelection(SumoXMLAttr key) const {796return getAttribute(key);797}798799800const std::string&801GNEAttributeCarrier::getTagStr() const {802return myTagProperty->getTagStr();803}804805806FXIcon*807GNEAttributeCarrier::getACIcon() const {808// special case for vClass icons809if (myTagProperty->vClassIcon()) {810return VClassIcons::getVClassIcon(SumoVehicleClassStrings.get(getAttribute(SUMO_ATTR_VCLASS)));811} else {812return GUIIconSubSys::getIcon(myTagProperty->getGUIIcon());813}814}815816817bool818GNEAttributeCarrier::isTemplate() const {819return myIsTemplate;820}821822823const GNETagProperties*824GNEAttributeCarrier::getTagProperty() const {825return myTagProperty;826}827828// ===========================================================================829// private830// ===========================================================================831832void833GNEAttributeCarrier::toggleAttribute(SumoXMLAttr /*key*/, const bool /*value*/) {834throw ProcessError(TL("Nothing to toggle, implement in Children"));835}836837838std::string839GNEAttributeCarrier::getCommonAttribute(const Parameterised* parameterised, SumoXMLAttr key) const {840switch (key) {841case GNE_ATTR_ADDITIONAL_FILE:842case GNE_ATTR_DEMAND_FILE:843case GNE_ATTR_DATA_FILE:844case GNE_ATTR_MEANDATA_FILE:845return myFilename;846case GNE_ATTR_CENTER_AFTER_CREATION:847return toString(myCenterAfterCreation);848case GNE_ATTR_SELECTED:849if (mySelected) {850return TRUE_STR;851} else {852return FALSE_STR;853}854case GNE_ATTR_FRONTELEMENT:855if (myDrawInFront) {856return TRUE_STR;857} else {858return FALSE_STR;859}860case GNE_ATTR_PARAMETERS:861return parameterised->getParametersStr();862default:863throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");864}865}866867868void869GNEAttributeCarrier::setCommonAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {870switch (key) {871case GNE_ATTR_ADDITIONAL_FILE:872GNEChange_Attribute::changeAttribute(this, key, value, undoList);873// update filenames of all additional childrens874for (auto additionalChild : getHierarchicalElement()->getChildAdditionals()) {875additionalChild->setAttribute(key, value, undoList);876}877break;878case GNE_ATTR_DEMAND_FILE:879GNEChange_Attribute::changeAttribute(this, key, value, undoList);880// update filenames of all demand childrens881for (auto demandChild : getHierarchicalElement()->getChildDemandElements()) {882demandChild->setAttribute(key, myFilename, undoList);883}884break;885case GNE_ATTR_DATA_FILE:886case GNE_ATTR_MEANDATA_FILE:887case GNE_ATTR_CENTER_AFTER_CREATION:888case GNE_ATTR_SELECTED:889case GNE_ATTR_PARAMETERS:890GNEChange_Attribute::changeAttribute(this, key, value, undoList);891break;892default:893throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");894}895}896897898bool899GNEAttributeCarrier::isCommonValid(SumoXMLAttr key, const std::string& value) const {900switch (key) {901case GNE_ATTR_ADDITIONAL_FILE:902case GNE_ATTR_DEMAND_FILE:903case GNE_ATTR_DATA_FILE:904case GNE_ATTR_MEANDATA_FILE:905return SUMOXMLDefinitions::isValidFilename(value);906case GNE_ATTR_CENTER_AFTER_CREATION:907case GNE_ATTR_SELECTED:908return canParse<bool>(value);909case GNE_ATTR_PARAMETERS:910return Parameterised::areParametersValid(value);911default:912throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");913}914}915916917void918GNEAttributeCarrier::setCommonAttribute(Parameterised* parameterised, SumoXMLAttr key, const std::string& value) {919switch (key) {920case GNE_ATTR_ADDITIONAL_FILE:921myFilename = value;922if (value.empty()) {923// try to avoid empty files924if (myNet->getSavingFilesHandler()->getAdditionalFilenames().size() > 0) {925myFilename = myNet->getSavingFilesHandler()->getAdditionalFilenames().front();926}927} else {928myNet->getSavingFilesHandler()->addAdditionalFilename(this);929}930break;931case GNE_ATTR_DEMAND_FILE:932myFilename = value;933if (value.empty()) {934// try to avoid empty files935if (myNet->getSavingFilesHandler()->getDemandFilenames().size() > 0) {936myFilename = myNet->getSavingFilesHandler()->getDemandFilenames().front();937}938} else {939myNet->getSavingFilesHandler()->addDemandFilename(this);940}941break;942case GNE_ATTR_DATA_FILE:943myFilename = value;944if (value.empty()) {945// try to avoid empty files946if (myNet->getSavingFilesHandler()->getDataFilenames().size() > 0) {947myFilename = myNet->getSavingFilesHandler()->getDataFilenames().front();948}949} else {950myNet->getSavingFilesHandler()->addDataFilename(this);951}952break;953case GNE_ATTR_MEANDATA_FILE:954myFilename = value;955if (value.empty()) {956// try to avoid empty files957if (myNet->getSavingFilesHandler()->getMeanDataFilenames().size() > 0) {958myFilename = myNet->getSavingFilesHandler()->getMeanDataFilenames().front();959}960} else {961myNet->getSavingFilesHandler()->addMeanDataFilename(this);962}963break;964case GNE_ATTR_CENTER_AFTER_CREATION:965myCenterAfterCreation = parse<bool>(value);966break;967case GNE_ATTR_SELECTED:968if (parse<bool>(value)) {969selectAttributeCarrier();970} else {971unselectAttributeCarrier();972}973break;974case GNE_ATTR_PARAMETERS:975parameterised->setParametersStr(value);976break;977default:978throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");979}980}981982/****************************************************************************/983984985