Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2001-2024 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 : /****************************************************************************/
14 : /// @file GUISelectedStorage.h
15 : /// @author Daniel Krajzewicz
16 : /// @author Jakob Erdmann
17 : /// @author Michael Behrisch
18 : /// @date Jun 2004
19 : ///
20 : // Storage for "selected" objects
21 : /****************************************************************************/
22 : #pragma once
23 : #include <config.h>
24 :
25 : #include <unordered_set>
26 : #include <string>
27 : #include <map>
28 : #include <fstream>
29 : #include <utils/foxtools/fxheader.h>
30 : #include <utils/common/UtilExceptions.h>
31 : #include <utils/gui/globjects/GUIGlObject.h>
32 :
33 :
34 : // ===========================================================================
35 : // class declarations
36 : // ===========================================================================
37 : class OutputDevice;
38 :
39 :
40 : // ===========================================================================
41 : // class definitions
42 : // ===========================================================================
43 : /**
44 : * @class GUISelectedStorage
45 : * @brief Storage for "selected" objects
46 : *
47 : * Object selection is done by storing the "gl-ids" of selectable objects
48 : * (GUIGlObjects) within internal containers of this class. Each id is stored
49 : * twice - in a global container and within one of the type-aware containers.
50 : *
51 : * This class allows adding and removing objects (their ids) from the lists
52 : * of selected objects, saving the lists into a file, and obtaining the lists
53 : * of selected objects (both all and type-aware).
54 : *
55 : * Most of the adding/removing methods do not require a GUIGlObjectType as
56 : * parameter, but an integer. This is done to perform the action on objects with
57 : * a yet unknown type - in this case, the type is obtained internally.
58 : *
59 : * Besides this, the class forces an active view of selected items
60 : * to refresh its contents if an item is added/removed. For this, an
61 : * FXWindow has to make itself visible to GUISelectedStorage.
62 : *
63 : * @see GUIGlObject
64 : * @see GUIGlObjectType
65 : * @see GUIDialog_GLChosenEditor
66 : */
67 : class GUISelectedStorage {
68 :
69 : public:
70 : /// @class update target
71 0 : class UpdateTarget {
72 :
73 : public:
74 : /// @brief virtual destructor
75 0 : virtual ~UpdateTarget() {};
76 :
77 : /// @brief called when selection is updated
78 : virtual void selectionUpdated() = 0;
79 : };
80 :
81 : public:
82 : /// @brief Constructor
83 : GUISelectedStorage();
84 :
85 : /// @brief Destructor
86 : ~GUISelectedStorage();
87 :
88 : /** @brief Returns the information whether the object with the given type and id is selected
89 : *
90 : * If the type is ==-1, it is determined, first. If it could not be obtained,
91 : * or if the type is not covered by any selection container, a ProcessError is thrown.
92 : *
93 : * Otherwise, the container holding objects of the determined type is
94 : * asked whether the given id is stored using SingleTypeSelections::isSelected().
95 : *
96 : * @param[in] type The type of the object (GUIGlObjectType or -1)
97 : * @param[in] id The id of the object
98 : * @return Whether the object is selected
99 : * @exception ProcessError If the object is not known or the type is not covered by a sub-container
100 : * @see GUIGlObject
101 : * @see GUIGlObjectType
102 : * @see SingleTypeSelections::isSelected
103 : */
104 : bool isSelected(GUIGlObjectType type, GUIGlID id);
105 :
106 : bool isSelected(const GUIGlObject* o);
107 :
108 : /** @brief Adds the object with the given id
109 : *
110 : * The id of the object is added to the sub-container that is
111 : * responsible for objects of the determined type using SingleTypeSelections::select
112 : * and to the global list of chosen items if it is not already there.
113 : *
114 : * The optionally listening window is informed about the change.
115 : *
116 : * @param[in] id The id of the object
117 : * @exception ProcessError If the object is not known or the type is not covered by a sub-container
118 : * @see GUIGlObject
119 : * @see GUIGlObjectType
120 : * @see SingleTypeSelections::select
121 : * @see GUIDialog_GLChosenEditor
122 : */
123 : void select(GUIGlID id, bool update = true);
124 :
125 : /** @brief Deselects the object with the given id
126 : *
127 : * The id of the object is removed from the sub-container that is
128 : * responsible for objects of the determined type using SingleTypeSelections::deselect
129 : * and from the global list of chosen items if it is there.
130 : *
131 : * The optionally listening UpdateTarget is informed about the change.
132 : *
133 : * @param[in] id The id of the object
134 : * @exception ProcessError If the object is not known or the type is not covered by a sub-container
135 : * @see GUIGlObject
136 : * @see GUIGlObjectType
137 : * @see SingleTypeSelections::deselect
138 : * @see GUIDialog_GLChosenEditor
139 : */
140 : void deselect(GUIGlID id);
141 :
142 : /** @brief Toggles selection of an object
143 : *
144 : * If the object can not be obtained a ProcessError is thrown.
145 : *
146 : * Otherwise, it is determined whether the object is already selected or not.
147 : * If so, it is deselected by calling "deselect", otherwise it is selected
148 : * via "select".
149 : *
150 : * @param[in] id The id of the object
151 : * @exception ProcessError If the object is not known or the type is not covered by a sub-container
152 : * @see GUIGlObject
153 : * @see deselect
154 : * @see select
155 : */
156 : void toggleSelection(GUIGlID id);
157 :
158 : /// @brief Returns the set of ids of all selected objects
159 : const std::unordered_set<GUIGlID>& getSelected() const;
160 :
161 : /** @brief Returns the set of ids of all selected objects' of a certain type
162 : *
163 : * @param[in] type The type of the object
164 : * @return A set containing the ids of all selected objects of the given type
165 : * @see SingleTypeSelections::getSelected
166 : */
167 : const std::unordered_set<GUIGlID>& getSelected(GUIGlObjectType type);
168 :
169 : /** @brief Clears the list of selected objects
170 : *
171 : * Clears the global container and all sub-containers via SingleTypeSelections::clear.
172 : *
173 : * The optionally listening UpdateTarget is informed about the change.
174 : */
175 : void clear();
176 :
177 : /// @brief inform the update target of earlier changes
178 : void notifyChanged();
179 :
180 : /** @brief Loads a selection list (optionally with restricted type)
181 : *
182 : * @param[in] filename The name of the file to load the list of selected objects from
183 : * @param[in] type The type of the objects to load if changed from default
184 : * @return error messages if errors occurred or the empty string
185 : */
186 : std::string load(const std::string& filename, GUIGlObjectType type = GLO_MAX, std::ostream* dynamicNotFound = nullptr);
187 : std::string load(std::istream& strm, GUIGlObjectType type = GLO_MAX, std::ostream* dynamicNotFound = nullptr);
188 :
189 : /** @brief Loads a selection list (optionally with restricted type) and
190 : * returns the ids of all active objects
191 : *
192 : * @param[in] filename The name of the file to load the list of selected objects from
193 : * @param[out] msg Any error messages while loading or the empty string
194 : * @param[in] type The type of the objects to load if changed from default
195 : * @param[in] maxErrors The maximum Number of errors to return
196 : * @return the set of loaded ids
197 : */
198 : std::set<GUIGlID> loadIDs(std::istream& strm, std::string& msgOut, GUIGlObjectType type = GLO_MAX, std::ostream* dynamicNotFound = nullptr, int maxErrors = 16);
199 :
200 : /** @brief Saves a selection list
201 : *
202 : * @param[in] type The type of the objects to save
203 : * @param[in] filename The name of the file to save the list of selected objects into
204 : */
205 : void save(GUIGlObjectType type, const std::string& filename);
206 :
207 : /** @brief Saves the combined selection of all types
208 : *
209 : * @param[in] filename The name of the file to save the list of selected objects into
210 : */
211 : void save(const std::string& filename) const;
212 :
213 : /** @brief Adds a dialog to be updated
214 : * @param[in] updateTarget the callback for selection changes
215 : */
216 : void add2Update(UpdateTarget* updateTarget);
217 :
218 : /// @brief @brief Removes the dialog to be updated
219 : void remove2Update();
220 :
221 : /**
222 : * @class SingleTypeSelections
223 : * @brief A container for ids of selected objects of a certain type.
224 : */
225 : class SingleTypeSelections {
226 :
227 : public:
228 : /// @brief Constructor
229 : SingleTypeSelections();
230 :
231 : /// @brief Destructor
232 : ~SingleTypeSelections();
233 :
234 : /** @brief Returns the information whether the object with the given id is qithin the selection
235 : * @param[in] id The id of the object
236 : * @return Whether the object is selected
237 : */
238 : bool isSelected(GUIGlID id);
239 :
240 : /** @brief Adds the object with the given id to the list of selected objects
241 : * @param[in] id The id of the object
242 : */
243 : void select(GUIGlID id);
244 :
245 : /** @brief Deselects the object with the given id from the list of selected objects
246 : * @param[in] id The id of the object
247 : */
248 : void deselect(GUIGlID id);
249 :
250 : /// @brief Clears the list of selected objects
251 : void clear();
252 :
253 : /** @brief Saves the list of selected objects to a file named as given
254 : * @param[in] filename The name of the file to save the list into
255 : */
256 : void save(const std::string& filename);
257 :
258 : /** @brief Returns the list of selected ids
259 : * @return A list containing the ids of all selected objects
260 : */
261 : const std::unordered_set<GUIGlID>& getSelected() const;
262 :
263 : private:
264 : /// @brief The list of selected ids
265 : std::unordered_set<GUIGlID> mySelected;
266 : };
267 :
268 : /// @brief set SingleTypeSelections as friend class
269 : friend class SingleTypeSelections;
270 :
271 :
272 : private:
273 : /// @brief map with the selections
274 : std::map<GUIGlObjectType, SingleTypeSelections> mySelections;
275 :
276 : /// @brief List of selected objects
277 : std::unordered_set<GUIGlID> myAllSelected;
278 :
279 : /// @brief The dialog to be updated
280 : UpdateTarget* myUpdateTarget;
281 :
282 : /// @brief saves items from the given set
283 : static void save(const std::string& filename, const std::unordered_set<GUIGlID>& ids);
284 : };
|