/****************************************************************************/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 GUISelectedStorage.h14/// @author Daniel Krajzewicz15/// @author Jakob Erdmann16/// @author Michael Behrisch17/// @date Jun 200418///19// Storage for "selected" objects20/****************************************************************************/21#pragma once22#include <config.h>2324#include <unordered_set>25#include <string>26#include <map>27#include <fstream>28#include <utils/foxtools/fxheader.h>29#include <utils/common/UtilExceptions.h>30#include <utils/gui/globjects/GUIGlObject.h>313233// ===========================================================================34// class declarations35// ===========================================================================36class OutputDevice;373839// ===========================================================================40// class definitions41// ===========================================================================42/**43* @class GUISelectedStorage44* @brief Storage for "selected" objects45*46* Object selection is done by storing the "gl-ids" of selectable objects47* (GUIGlObjects) within internal containers of this class. Each id is stored48* twice - in a global container and within one of the type-aware containers.49*50* This class allows adding and removing objects (their ids) from the lists51* of selected objects, saving the lists into a file, and obtaining the lists52* of selected objects (both all and type-aware).53*54* Most of the adding/removing methods do not require a GUIGlObjectType as55* parameter, but an integer. This is done to perform the action on objects with56* a yet unknown type - in this case, the type is obtained internally.57*58* Besides this, the class forces an active view of selected items59* to refresh its contents if an item is added/removed. For this, an60* FXWindow has to make itself visible to GUISelectedStorage.61*62* @see GUIGlObject63* @see GUIGlObjectType64* @see GUIDialog_GLChosenEditor65*/66class GUISelectedStorage {6768public:69/// @class update target70class UpdateTarget {7172public:73/// @brief virtual destructor74virtual ~UpdateTarget() {};7576/// @brief called when selection is updated77virtual void selectionUpdated() = 0;78};7980public:81/// @brief Constructor82GUISelectedStorage();8384/// @brief Destructor85~GUISelectedStorage();8687/** @brief Returns the information whether the object with the given type and id is selected88*89* If the type is ==-1, it is determined, first. If it could not be obtained,90* or if the type is not covered by any selection container, a ProcessError is thrown.91*92* Otherwise, the container holding objects of the determined type is93* asked whether the given id is stored using SingleTypeSelections::isSelected().94*95* @param[in] type The type of the object (GUIGlObjectType or -1)96* @param[in] id The id of the object97* @return Whether the object is selected98* @exception ProcessError If the object is not known or the type is not covered by a sub-container99* @see GUIGlObject100* @see GUIGlObjectType101* @see SingleTypeSelections::isSelected102*/103bool isSelected(GUIGlObjectType type, GUIGlID id);104105bool isSelected(const GUIGlObject* o);106107/** @brief Adds the object with the given id108*109* The id of the object is added to the sub-container that is110* responsible for objects of the determined type using SingleTypeSelections::select111* and to the global list of chosen items if it is not already there.112*113* The optionally listening window is informed about the change.114*115* @param[in] id The id of the object116* @exception ProcessError If the object is not known or the type is not covered by a sub-container117* @see GUIGlObject118* @see GUIGlObjectType119* @see SingleTypeSelections::select120* @see GUIDialog_GLChosenEditor121*/122void select(GUIGlID id, bool update = true);123124/** @brief Deselects the object with the given id125*126* The id of the object is removed from the sub-container that is127* responsible for objects of the determined type using SingleTypeSelections::deselect128* and from the global list of chosen items if it is there.129*130* The optionally listening UpdateTarget is informed about the change.131*132* @param[in] id The id of the object133* @exception ProcessError If the object is not known or the type is not covered by a sub-container134* @see GUIGlObject135* @see GUIGlObjectType136* @see SingleTypeSelections::deselect137* @see GUIDialog_GLChosenEditor138*/139void deselect(GUIGlID id);140141void deselect(GUIGlObjectType type, GUIGlID id);142143/** @brief Toggles selection of an object144*145* If the object can not be obtained a ProcessError is thrown.146*147* Otherwise, it is determined whether the object is already selected or not.148* If so, it is deselected by calling "deselect", otherwise it is selected149* via "select".150*151* @param[in] id The id of the object152* @exception ProcessError If the object is not known or the type is not covered by a sub-container153* @see GUIGlObject154* @see deselect155* @see select156*/157void toggleSelection(GUIGlID id);158159/// @brief Returns the set of ids of all selected objects160const std::unordered_set<GUIGlID>& getSelected() const;161162/** @brief Returns the set of ids of all selected objects' of a certain type163*164* @param[in] type The type of the object165* @return A set containing the ids of all selected objects of the given type166* @see SingleTypeSelections::getSelected167*/168const std::unordered_set<GUIGlID>& getSelected(GUIGlObjectType type);169170/** @brief Clears the list of selected objects171*172* Clears the global container and all sub-containers via SingleTypeSelections::clear.173*174* The optionally listening UpdateTarget is informed about the change.175*/176void clear();177178/// @brief inform the update target of earlier changes179void notifyChanged();180181/** @brief Loads a selection list (optionally with restricted type)182*183* @param[in] filename The name of the file to load the list of selected objects from184* @param[in] type The type of the objects to load if changed from default185* @return error messages if errors occurred or the empty string186*/187std::string load(const std::string& filename, GUIGlObjectType type = GLO_MAX, std::ostream* dynamicNotFound = nullptr);188std::string load(std::istream& strm, GUIGlObjectType type = GLO_MAX, std::ostream* dynamicNotFound = nullptr);189190/** @brief Loads a selection list (optionally with restricted type) and191* returns the ids of all active objects192*193* @param[in] filename The name of the file to load the list of selected objects from194* @param[out] msg Any error messages while loading or the empty string195* @param[in] type The type of the objects to load if changed from default196* @param[in] maxErrors The maximum Number of errors to return197* @return the set of loaded ids198*/199std::set<GUIGlID> loadIDs(std::istream& strm, std::string& msgOut, GUIGlObjectType type = GLO_MAX, std::ostream* dynamicNotFound = nullptr, int maxErrors = 16);200201/** @brief Saves a selection list202*203* @param[in] type The type of the objects to save204* @param[in] filename The name of the file to save the list of selected objects into205*/206void save(GUIGlObjectType type, const std::string& filename);207208/** @brief Saves the combined selection of all types209*210* @param[in] filename The name of the file to save the list of selected objects into211*/212void save(const std::string& filename) const;213214/** @brief Adds a dialog to be updated215* @param[in] updateTarget the callback for selection changes216*/217void add2Update(UpdateTarget* updateTarget);218219/// @brief @brief Removes the dialog to be updated220void remove2Update();221222/**223* @class SingleTypeSelections224* @brief A container for ids of selected objects of a certain type.225*/226class SingleTypeSelections {227228public:229/// @brief Constructor230SingleTypeSelections();231232/// @brief Destructor233~SingleTypeSelections();234235/** @brief Returns the information whether the object with the given id is qithin the selection236* @param[in] id The id of the object237* @return Whether the object is selected238*/239bool isSelected(GUIGlID id);240241/** @brief Adds the object with the given id to the list of selected objects242* @param[in] id The id of the object243*/244void select(GUIGlID id);245246/** @brief Deselects the object with the given id from the list of selected objects247* @param[in] id The id of the object248*/249void deselect(GUIGlID id);250251/// @brief Clears the list of selected objects252void clear();253254/** @brief Saves the list of selected objects to a file named as given255* @param[in] filename The name of the file to save the list into256*/257void save(const std::string& filename);258259/** @brief Returns the list of selected ids260* @return A list containing the ids of all selected objects261*/262const std::unordered_set<GUIGlID>& getSelected() const;263264private:265/// @brief The list of selected ids266std::unordered_set<GUIGlID> mySelected;267};268269/// @brief set SingleTypeSelections as friend class270friend class SingleTypeSelections;271272273private:274/// @brief map with the selections275std::map<GUIGlObjectType, SingleTypeSelections> mySelections;276277/// @brief List of selected objects278std::unordered_set<GUIGlID> myAllSelected;279280/// @brief The dialog to be updated281UpdateTarget* myUpdateTarget;282283/// @brief saves items from the given set284static void save(const std::string& filename, const std::unordered_set<GUIGlID>& ids);285};286287288