Path: blob/main/src/netedit/dialogs/GNEVClassesDialog.cpp
193735 views
/****************************************************************************/1// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo2// Copyright (C) 2001-2026 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 GNEVClassesDialog.cpp14/// @author Pablo Alvarez Lopez15/// @date April 201616///17// Dialog for edit allow VClass attribute18/****************************************************************************/1920#include <netedit/GNEApplicationWindow.h>21#include <utils/common/MsgHandler.h>22#include <utils/common/StringTokenizer.h>23#include <utils/gui/div/GUIDesigns.h>2425#include "GNEVClassesDialog.h"2627// ===========================================================================28// FOX callback mapping29// ===========================================================================3031FXDEFMAP(GNEVClassesDialog::VClassRow) VClassRowMap[] = {32FXMAPFUNC(SEL_COMMAND, MID_GNE_ALLOWVCLASSES_TOGGLE, GNEVClassesDialog::VClassRow::onCmdToggleVClass),33};3435FXDEFMAP(GNEVClassesDialog) GNEVClassesDialogMap[] = {36FXMAPFUNC(SEL_COMMAND, MID_GNE_ALLOWVCLASSES_SELECTALL, GNEVClassesDialog::onCmdSelectAll),37FXMAPFUNC(SEL_COMMAND, MID_GNE_ALLOWVCLASSES_UNSELECTALL, GNEVClassesDialog::onCmdUnselectAll),38FXMAPFUNC(SEL_COMMAND, MID_GNE_ALLOWVCLASSES_ONLY_ROAD, GNEVClassesDialog::onCmdSelectOnlyRoad),39FXMAPFUNC(SEL_COMMAND, MID_GNE_ALLOWVCLASSES_ONLY_RAIL, GNEVClassesDialog::onCmdSelectOnlyRail),40};4142// Object implementation43FXIMPLEMENT(GNEVClassesDialog::VClassRow, FXHorizontalFrame, VClassRowMap, ARRAYNUMBER(VClassRowMap))44FXIMPLEMENT(GNEVClassesDialog, GNEDialog, GNEVClassesDialogMap, ARRAYNUMBER(GNEVClassesDialogMap))4546// ===========================================================================47// member method definitions48// ===========================================================================4950// ---------------------------------------------------------------------------51// GNEVClassesDialog::VClassRow - methods52// ---------------------------------------------------------------------------5354GNEVClassesDialog::VClassRow::VClassRow(FXVerticalFrame* contentsFrame, SUMOVehicleClass vClass,55GUIIcon vClassIcon, const std::string& description) :56FXHorizontalFrame(contentsFrame, GUIDesignAuxiliarHorizontalFrame),57myVClassString(getVehicleClassNames(vClass)) {58// add frame for vehicle icons59FXLabel* labelVehicleIcon = new FXLabel(this, "", GUIIconSubSys::getIcon(vClassIcon), GUIDesignLabelIcon64x32Thicked);60labelVehicleIcon->setBackColor(FXRGBA(255, 255, 255, 255));61// create frame for information and button62FXVerticalFrame* buttonAndInformationFrame = new FXVerticalFrame(this, GUIDesignAuxiliarHorizontalFrame);63FXHorizontalFrame* buttonAndStatusFrame = new FXHorizontalFrame(buttonAndInformationFrame, GUIDesignAuxiliarHorizontalFrame);64// create button for enable/disable vehicle class65myVClassButton = GUIDesigns::buildFXButton(buttonAndStatusFrame, "", "", "", GUIIconSubSys::getIcon(GUIIcon::EMPTY),66this, MID_GNE_ALLOWVCLASSES_TOGGLE, GUIDesignButtonIcon);67// create label for vehicle class name68new FXLabel(buttonAndStatusFrame, myVClassString.c_str(), nullptr, GUIDesignLabelThick(JUSTIFY_LEFT));69// create label for description of vehicle70new FXLabel(buttonAndInformationFrame, description.c_str(), nullptr, GUIDesignLabelThick(JUSTIFY_LEFT));71}727374GNEVClassesDialog::VClassRow::~VClassRow() {7576}777879const std::string&80GNEVClassesDialog::VClassRow::getVClassString() const {81return myVClassString;82}838485void86GNEVClassesDialog::VClassRow::setVClassButtonStatus(const bool enabled) {87if (enabled) {88myVClassButton->setIcon(GUIIconSubSys::getIcon(GUIIcon::ACCEPT));89} else {90myVClassButton->setIcon(GUIIconSubSys::getIcon(GUIIcon::CANCEL));91}92}939495bool96GNEVClassesDialog::VClassRow::isVClassButtonEnabled() const {97return (myVClassButton->getIcon() == GUIIconSubSys::getIcon(GUIIcon::ACCEPT));98}99100101long102GNEVClassesDialog::VClassRow::onCmdToggleVClass(FXObject*, FXSelector, void*) {103if (myVClassButton->getIcon() == GUIIconSubSys::getIcon(GUIIcon::ACCEPT)) {104setVClassButtonStatus(false);105} else {106setVClassButtonStatus(true);107}108return 1;109}110111// ---------------------------------------------------------------------------112// GNEVClassesDialog - methods113// ---------------------------------------------------------------------------114115GNEVClassesDialog::GNEVClassesDialog(GNEApplicationWindow* applicationWindow, SumoXMLAttr attr,116const std::string originalVClasses) :117GNEDialog(applicationWindow, TLF("Edit vClasses of attribute '%'", toString(attr)), GUIIcon::GREENVEHICLE,118DialogType::VCLASS, GNEDialog::Buttons::ACCEPT_CANCEL_RESET, OpenType::MODAL, ResizeMode::STATIC),119myOriginalVClasses(originalVClasses),120myEditedVClasses(originalVClasses) {121// build dialog122builder();123}124125126GNEVClassesDialog::GNEVClassesDialog(GNEApplicationWindow* applicationWindow, GNEDialog* parentDialog,127SumoXMLAttr attr, const std::string originalVClasses) :128GNEDialog(applicationWindow, parentDialog, TLF("Edit vClasses of attribute '%'", toString(attr)), GUIIcon::GREENVEHICLE,129DialogType::VCLASS, GNEDialog::Buttons::ACCEPT_CANCEL_RESET, OpenType::MODAL, ResizeMode::STATIC),130myOriginalVClasses(originalVClasses),131myEditedVClasses(originalVClasses) {132// build dialog133builder();134}135136137GNEVClassesDialog::~GNEVClassesDialog() {138}139140141void142GNEVClassesDialog::runInternalTest(const InternalTestStep::DialogArgument* dialogArgument) {143if (dialogArgument->getCustomAction() == "allVehicles") {144onCmdSelectAll(nullptr, 0, nullptr);145} else if (dialogArgument->getCustomAction() == "disallowAll") {146onCmdUnselectAll(nullptr, 0, nullptr);147} else if (dialogArgument->getCustomAction() == "onlyRoadVehicles") {148onCmdSelectOnlyRoad(nullptr, 0, nullptr);149} else if (dialogArgument->getCustomAction() == "onlyRailVehicles") {150onCmdSelectOnlyRail(nullptr, 0, nullptr);151} else if (SumoVehicleClassStrings.hasString(dialogArgument->getCustomAction())) {152myVClassMap[getVehicleClassID(dialogArgument->getCustomAction())]->onCmdToggleVClass(nullptr, 0, nullptr);153} else {154WRITE_ERROR("Invalid dialog argument " + dialogArgument->getCustomAction() + " used in GNEVClassesDialog::runInternalTest");155}156}157158159std::string160GNEVClassesDialog::getModifiedVClasses() const {161return myEditedVClasses;162}163164165long166GNEVClassesDialog::onCmdSelectAll(FXObject*, FXSelector, void*) {167// change all icons to accept168for (const auto& vClass : myVClassMap) {169vClass.second->setVClassButtonStatus(true);170}171return 1;172}173174175long176GNEVClassesDialog::onCmdUnselectAll(FXObject*, FXSelector, void*) {177// change all icons to cancel178for (const auto& vClass : myVClassMap) {179vClass.second->setVClassButtonStatus(false);180}181return 1;182}183184185long186GNEVClassesDialog::onCmdSelectOnlyRoad(FXObject*, FXSelector, void*) {187// change all non-road icons to disallow, and allow for the rest188for (const auto& vClass : myVClassMap) {189if ((vClass.first & (SVC_PEDESTRIAN | SVC_NON_ROAD)) == 0) {190vClass.second->setVClassButtonStatus(true);191} else {192vClass.second->setVClassButtonStatus(false);193}194}195return 1;196}197198199long200GNEVClassesDialog::onCmdSelectOnlyRail(FXObject*, FXSelector, void*) {201// change all non-road icons to disallow, and allow for the rest202for (const auto& vClass : myVClassMap) {203if ((vClass.first & SVC_RAIL_CLASSES) != 0) {204vClass.second->setVClassButtonStatus(true);205} else {206vClass.second->setVClassButtonStatus(false);207}208}209return 1;210}211212213long214GNEVClassesDialog::onCmdAccept(FXObject*, FXSelector, void*) {215bool allSelected = true;216// clear allow and disallow VClasses217std::vector<std::string> allowedVehicles;218for (const auto& vClass : myVClassMap) {219// check if vehicle is allowed depending on the Icon220if (vClass.second->isVClassButtonEnabled()) {221allowedVehicles.push_back(vClass.second->getVClassString());222} else {223allSelected = false;224}225}226if (allSelected) {227myEditedVClasses = "all";228} else {229myEditedVClasses = joinToString(allowedVehicles, " ");230}231// Stop Modal if we have a different classes from original232if (myEditedVClasses != myOriginalVClasses) {233return closeDialogAccepting();234} else {235return closeDialogCanceling();236}237}238239240long241GNEVClassesDialog::onCmdCancel(FXObject*, FXSelector, void*) {242// reset vClasses243myEditedVClasses = myOriginalVClasses;244// cancel245return closeDialogCanceling();246}247248249long250GNEVClassesDialog::onCmdReset(FXObject*, FXSelector, void*) {251// reset vClasses252myEditedVClasses = myOriginalVClasses;253// continue depending of allow254if (myEditedVClasses == "all") {255// iterate over myVClassMap and set all icons as true256for (const auto& vClass : myVClassMap) {257vClass.second->setVClassButtonStatus(true);258}259} else {260// declare string vector for saving all vclasses261const std::vector<std::string>& allowStringVector = StringTokenizer(myEditedVClasses).getVector();262const std::set<std::string> allowSet(allowStringVector.begin(), allowStringVector.end());263// iterate over myVClassMap and set icons264for (const auto& vClass : myVClassMap) {265if (allowSet.count(getVehicleClassNames(vClass.first)) > 0) {266vClass.second->setVClassButtonStatus(true);267} else {268vClass.second->setVClassButtonStatus(false);269}270}271}272return 1;273}274275276void277GNEVClassesDialog::builder() {278// label for selection options279new FXLabel(getContentFrame(), TL("Selection options"), nullptr, GUIDesignLabel(JUSTIFY_NORMAL));280// horizontal frame uniform for options281FXHorizontalFrame* optionsFrame = new FXHorizontalFrame(getContentFrame(), GUIDesignAuxiliarHorizontalFrameUniform);282// allow all283GUIDesigns::buildFXButton(optionsFrame, "", "", "", GUIIconSubSys::getIcon(GUIIcon::OK), this, MID_GNE_ALLOWVCLASSES_SELECTALL, GUIDesignButtonIcon);284new FXLabel(optionsFrame, TL("Allow all vehicles"), nullptr, GUIDesignLabelThick(JUSTIFY_LEFT));285// only road286GUIDesigns::buildFXButton(optionsFrame, "", "", "", GUIIconSubSys::getIcon(GUIIcon::OK), this, MID_GNE_ALLOWVCLASSES_ONLY_ROAD, GUIDesignButtonIcon);287new FXLabel(optionsFrame, TL("Allow only road vehicles"), nullptr, GUIDesignLabelThick(JUSTIFY_LEFT));288// only rail289GUIDesigns::buildFXButton(optionsFrame, "", "", "", GUIIconSubSys::getIcon(GUIIcon::OK), this, MID_GNE_ALLOWVCLASSES_ONLY_RAIL, GUIDesignButtonIcon);290new FXLabel(optionsFrame, TL("Allow only rail vehicles"), nullptr, GUIDesignLabelThick(JUSTIFY_LEFT));291// disallow all292GUIDesigns::buildFXButton(optionsFrame, "", "", "", GUIIconSubSys::getIcon(GUIIcon::CANCEL), this, MID_GNE_ALLOWVCLASSES_UNSELECTALL, GUIDesignButtonIcon);293new FXLabel(optionsFrame, TL("Disallow all vehicles"), nullptr, GUIDesignLabelThick(JUSTIFY_LEFT));294// label for select vClasses295new FXLabel(getContentFrame(), TL("Select vClasses"), nullptr, GUIDesignLabel(JUSTIFY_NORMAL));296// Create frame for vehicles's columns297FXHorizontalFrame* myVehiclesFrame = new FXHorizontalFrame(getContentFrame(), GUIDesignContentsFrame);298// create left frame and fill it299FXVerticalFrame* vehiclesLeftFrame = new FXVerticalFrame(myVehiclesFrame, GUIDesignAuxiliarFrame);300myVClassMap[SVC_PASSENGER] = new VClassRow(vehiclesLeftFrame, SVC_PASSENGER, GUIIcon::VCLASS_PASSENGER, TL("Default vehicle class"));301myVClassMap[SVC_PRIVATE] = new VClassRow(vehiclesLeftFrame, SVC_PRIVATE, GUIIcon::VCLASS_PRIVATE, TL("A passenger car assigned for private use"));302myVClassMap[SVC_TAXI] = new VClassRow(vehiclesLeftFrame, SVC_TAXI, GUIIcon::VCLASS_TAXI, TL("Vehicle for hire with a driver"));303myVClassMap[SVC_BUS] = new VClassRow(vehiclesLeftFrame, SVC_BUS, GUIIcon::VCLASS_BUS, TL("Urban line traffic"));304myVClassMap[SVC_COACH] = new VClassRow(vehiclesLeftFrame, SVC_COACH, GUIIcon::VCLASS_COACH, TL("Overland transport"));305myVClassMap[SVC_DELIVERY] = new VClassRow(vehiclesLeftFrame, SVC_DELIVERY, GUIIcon::VCLASS_DELIVERY, TL("Vehicles specialized in delivering goods"));306myVClassMap[SVC_TRUCK] = new VClassRow(vehiclesLeftFrame, SVC_TRUCK, GUIIcon::VCLASS_TRUCK, TL("Vehicle designed to transport cargo"));307myVClassMap[SVC_TRAILER] = new VClassRow(vehiclesLeftFrame, SVC_TRAILER, GUIIcon::VCLASS_TRAILER, TL("Truck with trailer"));308myVClassMap[SVC_EMERGENCY] = new VClassRow(vehiclesLeftFrame, SVC_EMERGENCY, GUIIcon::VCLASS_EMERGENCY, TL("Vehicle designated to respond to an emergency"));309myVClassMap[SVC_MOTORCYCLE] = new VClassRow(vehiclesLeftFrame, SVC_MOTORCYCLE, GUIIcon::VCLASS_MOTORCYCLE, TL("Two- or three-wheeled motor vehicle"));310myVClassMap[SVC_MOPED] = new VClassRow(vehiclesLeftFrame, SVC_MOPED, GUIIcon::VCLASS_MOPED, TL("Motorcycle not allowed in motorways"));311// create center frame and fill it312FXVerticalFrame* vehiclesCenterFrame = new FXVerticalFrame(myVehiclesFrame, GUIDesignAuxiliarFrame);313myVClassMap[SVC_BICYCLE] = new VClassRow(vehiclesCenterFrame, SVC_BICYCLE, GUIIcon::VCLASS_BICYCLE, TL("Human-powered, pedal-driven vehicle"));314myVClassMap[SVC_SCOOTER] = new VClassRow(vehiclesCenterFrame, SVC_SCOOTER, GUIIcon::VCLASS_SCOOTER, TL("An electric scooter or a kick scooter"));315myVClassMap[SVC_PEDESTRIAN] = new VClassRow(vehiclesCenterFrame, SVC_PEDESTRIAN, GUIIcon::VCLASS_PEDESTRIAN, TL("Person traveling on foot"));316myVClassMap[SVC_WHEELCHAIR] = new VClassRow(vehiclesCenterFrame, SVC_WHEELCHAIR, GUIIcon::VCLASS_WHEELCHAIR, TL("A mobility impaired person"));317myVClassMap[SVC_TRAM] = new VClassRow(vehiclesCenterFrame, SVC_TRAM, GUIIcon::VCLASS_TRAM, TL("Rail vehicle which runs on tracks"));318myVClassMap[SVC_RAIL_ELECTRIC] = new VClassRow(vehiclesCenterFrame, SVC_RAIL_ELECTRIC, GUIIcon::VCLASS_RAIL_ELECTRIC, TL("Rail electric vehicle"));319myVClassMap[SVC_RAIL_FAST] = new VClassRow(vehiclesCenterFrame, SVC_RAIL_FAST, GUIIcon::VCLASS_RAIL_FAST, TL("High-speed rail vehicle"));320myVClassMap[SVC_RAIL_URBAN] = new VClassRow(vehiclesCenterFrame, SVC_RAIL_URBAN, GUIIcon::VCLASS_RAIL_URBAN, TL("Heavier than tram"));321myVClassMap[SVC_RAIL] = new VClassRow(vehiclesCenterFrame, SVC_RAIL, GUIIcon::VCLASS_RAIL, TL("Heavy rail vehicle"));322myVClassMap[SVC_CABLE_CAR] = new VClassRow(vehiclesCenterFrame, SVC_CABLE_CAR, GUIIcon::VCLASS_CABLE_CAR, TL("A conveyance suspended on a cable"));323myVClassMap[SVC_SUBWAY] = new VClassRow(vehiclesCenterFrame, SVC_SUBWAY, GUIIcon::VCLASS_SUBWAY, TL("A railway that mostly runs underground"));324// create right frame and fill it (8 vehicles)325FXVerticalFrame* vehiclesRightFrame = new FXVerticalFrame(myVehiclesFrame, GUIDesignAuxiliarFrame);326myVClassMap[SVC_E_VEHICLE] = new VClassRow(vehiclesRightFrame, SVC_E_VEHICLE, GUIIcon::VCLASS_EVEHICLE, TL("Future electric mobility vehicles"));327myVClassMap[SVC_ARMY] = new VClassRow(vehiclesRightFrame, SVC_ARMY, GUIIcon::VCLASS_ARMY, TL("Vehicle designed for military forces"));328myVClassMap[SVC_SHIP] = new VClassRow(vehiclesRightFrame, SVC_SHIP, GUIIcon::VCLASS_SHIP, TL("Basic class for navigating waterway"));329myVClassMap[SVC_AUTHORITY] = new VClassRow(vehiclesRightFrame, SVC_AUTHORITY, GUIIcon::VCLASS_AUTHORITY, TL("Vehicle of a governmental security agency"));330myVClassMap[SVC_VIP] = new VClassRow(vehiclesRightFrame, SVC_VIP, GUIIcon::VCLASS_VIP, TL("A civilian security armored car used by VIPs"));331myVClassMap[SVC_HOV] = new VClassRow(vehiclesRightFrame, SVC_HOV, GUIIcon::VCLASS_HOV, TL("High-Occupancy Vehicle (two or more passengers)"));332myVClassMap[SVC_CONTAINER] = new VClassRow(vehiclesRightFrame, SVC_CONTAINER, GUIIcon::VCLASS_CONTAINER, TL("A transport container"));333myVClassMap[SVC_AIRCRAFT] = new VClassRow(vehiclesRightFrame, SVC_AIRCRAFT, GUIIcon::VCLASS_AIRCRAFT, TL("An airplane"));334myVClassMap[SVC_DRONE] = new VClassRow(vehiclesRightFrame, SVC_DRONE, GUIIcon::VCLASS_DRONE, TL("A small unmanned robot"));335myVClassMap[SVC_CUSTOM1] = new VClassRow(vehiclesRightFrame, SVC_CUSTOM1, GUIIcon::VCLASS_CUSTOM1, TL("Reserved for user-defined semantics"));336myVClassMap[SVC_CUSTOM2] = new VClassRow(vehiclesRightFrame, SVC_CUSTOM2, GUIIcon::VCLASS_CUSTOM2, TL("Reserved for user-defined semantics"));337// reset dialog338onCmdReset(nullptr, 0, nullptr);339// open modal dialog340openDialog();341}342343/****************************************************************************/344345346