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.cpp
15 : /// @author Daniel Krajzewicz
16 : /// @author Jakob Erdmann
17 : /// @author Michael Behrisch
18 : /// @date Jun 2004
19 : ///
20 : // Storage for "selected" objects
21 : /****************************************************************************/
22 : #include <config.h>
23 :
24 : #include <algorithm>
25 : #include <utils/gui/globjects/GUIGlObject.h>
26 : #include <utils/gui/globjects/GUIGlObjectStorage.h>
27 : #include <utils/iodevices/OutputDevice.h>
28 : #include <utils/common/ToString.h>
29 :
30 : #include "GUISelectedStorage.h"
31 : #include "GUIDialog_GLChosenEditor.h"
32 :
33 :
34 : // ===========================================================================
35 : // member method definitions
36 : // ===========================================================================
37 :
38 : /* -------------------------------------------------------------------------
39 : * for GUISelectedStorage::SingleTypeSelections
40 : * ----------------------------------------------------------------------- */
41 :
42 19585 : GUISelectedStorage::SingleTypeSelections::SingleTypeSelections() {}
43 :
44 :
45 19583 : GUISelectedStorage::SingleTypeSelections::~SingleTypeSelections() {}
46 :
47 :
48 : bool
49 89165184 : GUISelectedStorage::SingleTypeSelections::isSelected(GUIGlID id) {
50 89165184 : return mySelected.count(id) > 0;
51 : }
52 :
53 :
54 : void
55 0 : GUISelectedStorage::SingleTypeSelections::select(GUIGlID id) {
56 : mySelected.insert(id);
57 0 : }
58 :
59 :
60 : void
61 0 : GUISelectedStorage::SingleTypeSelections::deselect(GUIGlID id) {
62 : mySelected.erase(id);
63 0 : }
64 :
65 :
66 : void
67 37555 : GUISelectedStorage::SingleTypeSelections::clear() {
68 : mySelected.clear();
69 37555 : }
70 :
71 :
72 : void
73 0 : GUISelectedStorage::SingleTypeSelections::save(const std::string& filename) {
74 0 : GUISelectedStorage::save(filename, mySelected);
75 0 : }
76 :
77 :
78 : const std::unordered_set<GUIGlID>&
79 0 : GUISelectedStorage::SingleTypeSelections::getSelected() const {
80 0 : return mySelected;
81 : }
82 :
83 : /* -------------------------------------------------------------------------
84 : * for GUISelectedStorage
85 : * ----------------------------------------------------------------------- */
86 :
87 8154 : GUISelectedStorage::GUISelectedStorage() {}
88 :
89 :
90 8154 : GUISelectedStorage::~GUISelectedStorage() {}
91 :
92 :
93 : bool
94 89165184 : GUISelectedStorage::isSelected(GUIGlObjectType type, GUIGlID id) {
95 89165184 : switch (type) {
96 : case GLO_NETWORK:
97 : return false;
98 89165184 : default:
99 89165184 : return mySelections[type].isSelected(id);
100 : }
101 : }
102 :
103 : bool
104 35657533 : GUISelectedStorage::isSelected(const GUIGlObject* o) {
105 35657533 : if (o == nullptr) {
106 : return false;
107 : } else {
108 35657533 : return isSelected(o->getType(), o->getGlID());
109 : }
110 : }
111 :
112 : void
113 0 : GUISelectedStorage::select(GUIGlID id, bool update) {
114 0 : GUIGlObject* object = GUIGlObjectStorage::gIDStorage.getObjectBlocking(id);
115 0 : if (!object) {
116 0 : throw ProcessError("Unknown object in GUISelectedStorage::select (id=" + toString(id) + ").");
117 : }
118 0 : GUIGlObjectType type = object->getType();
119 0 : GUIGlObjectStorage::gIDStorage.unblockObject(id);
120 :
121 0 : mySelections[type].select(id);
122 : myAllSelected.insert(id);
123 0 : if (update && myUpdateTarget) {
124 0 : myUpdateTarget->selectionUpdated();
125 : }
126 0 : }
127 :
128 :
129 : void
130 0 : GUISelectedStorage::deselect(GUIGlID id) {
131 0 : GUIGlObject* object = GUIGlObjectStorage::gIDStorage.getObjectBlocking(id);
132 0 : if (!object) {
133 0 : throw ProcessError("Unknown object in GUISelectedStorage::deselect (id=" + toString(id) + ").");
134 : }
135 0 : GUIGlObjectType type = object->getType();
136 0 : GUIGlObjectStorage::gIDStorage.unblockObject(id);
137 :
138 0 : mySelections[type].deselect(id);
139 : myAllSelected.erase(id);
140 0 : if (myUpdateTarget) {
141 0 : myUpdateTarget->selectionUpdated();
142 : }
143 0 : }
144 :
145 :
146 : void
147 0 : GUISelectedStorage::toggleSelection(GUIGlID id) {
148 0 : GUIGlObject* object = GUIGlObjectStorage::gIDStorage.getObjectBlocking(id);
149 0 : if (!object) {
150 0 : throw ProcessError("Unknown object in GUISelectedStorage::toggleSelection (id=" + toString(id) + ").");
151 : }
152 :
153 0 : bool selected = isSelected(object->getType(), id);
154 0 : if (!selected) {
155 0 : select(id);
156 : } else {
157 0 : deselect(id);
158 : }
159 0 : GUIGlObjectStorage::gIDStorage.unblockObject(id);
160 0 : }
161 :
162 :
163 : const std::unordered_set<GUIGlID>&
164 0 : GUISelectedStorage::getSelected() const {
165 0 : return myAllSelected;
166 : }
167 :
168 :
169 : const std::unordered_set<GUIGlID>&
170 0 : GUISelectedStorage::getSelected(GUIGlObjectType type) {
171 0 : return mySelections[type].getSelected();
172 : }
173 :
174 :
175 : void
176 22280 : GUISelectedStorage::clear() {
177 59835 : for (auto& selection : mySelections) {
178 37555 : selection.second.clear();
179 : }
180 : myAllSelected.clear();
181 22280 : if (myUpdateTarget) {
182 0 : myUpdateTarget->selectionUpdated();
183 : }
184 22280 : }
185 :
186 :
187 : void
188 0 : GUISelectedStorage::notifyChanged() {
189 0 : if (myUpdateTarget) {
190 0 : myUpdateTarget->selectionUpdated();
191 : }
192 0 : }
193 :
194 :
195 : std::set<GUIGlID>
196 0 : GUISelectedStorage::loadIDs(std::istream& strm, std::string& msgOut, GUIGlObjectType type, std::ostream* dynamicNotFound, int maxErrors) {
197 : std::set<GUIGlID> result;
198 0 : std::ostringstream msg;
199 : int numIgnored = 0;
200 : int numMissing = 0;
201 0 : while (strm.good()) {
202 : std::string line;
203 0 : strm >> line;
204 0 : if (line.length() == 0) {
205 0 : continue;
206 : }
207 0 : if (StringUtils::startsWith(line, "node:")) {
208 0 : line = StringUtils::replace(line, "node:", "junction:");
209 : }
210 :
211 0 : GUIGlObject* object = GUIGlObjectStorage::gIDStorage.getObjectBlocking(line);
212 0 : if (object) {
213 0 : if (type != GLO_MAX && (object->getType() != type)) {
214 0 : numIgnored++;
215 0 : if (numIgnored + numMissing <= maxErrors) {
216 0 : msg << TLF("Ignoring item '%' because of invalid type %\n", line, toString(object->getType()));
217 : }
218 : } else {
219 0 : result.insert(object->getGlID());
220 : }
221 : } else {
222 0 : numMissing++;
223 0 : if (dynamicNotFound != nullptr && (
224 0 : StringUtils::startsWith(line, "vehicle:") ||
225 0 : StringUtils::startsWith(line, "person:") ||
226 0 : StringUtils::startsWith(line, "container:"))) {
227 0 : (*dynamicNotFound) << line << "\n";
228 : } else {
229 0 : if (numIgnored + numMissing <= maxErrors) {
230 0 : msg << TLF("Item '%' not found\n", line);
231 : }
232 : }
233 0 : continue;
234 : }
235 : }
236 0 : if (numIgnored + numMissing > maxErrors) {
237 0 : msg << "...\n" << TLF("% objects ignored, % objects not found\n", numIgnored, numMissing);
238 : }
239 0 : msgOut = msg.str();
240 0 : return result;
241 0 : }
242 :
243 :
244 : std::string
245 0 : GUISelectedStorage::load(const std::string& filename, GUIGlObjectType type, std::ostream* dynamicNotFound) {
246 0 : std::ifstream strm(filename.c_str());
247 0 : if (!strm.good()) {
248 0 : return TLF("Could not open '%'.\n", filename);
249 : }
250 0 : std::string errors = load(strm, type, dynamicNotFound);
251 0 : strm.close();
252 0 : return errors;
253 0 : }
254 :
255 :
256 : std::string
257 0 : GUISelectedStorage::load(std::istream& strm, GUIGlObjectType type, std::ostream* dynamicNotFound) {
258 : std::string errors;
259 0 : const std::set<GUIGlID> ids = loadIDs(strm, errors, type, dynamicNotFound);
260 0 : for (const auto glID : ids) {
261 0 : select(glID, false);
262 : }
263 0 : if (myUpdateTarget) {
264 0 : myUpdateTarget->selectionUpdated();
265 : }
266 0 : return errors;
267 : }
268 :
269 :
270 : void
271 0 : GUISelectedStorage::save(GUIGlObjectType type, const std::string& filename) {
272 0 : mySelections[type].save(filename);
273 0 : }
274 :
275 :
276 : void
277 0 : GUISelectedStorage::save(const std::string& filename) const {
278 0 : save(filename, myAllSelected);
279 0 : }
280 :
281 :
282 : void
283 0 : GUISelectedStorage::add2Update(UpdateTarget* updateTarget) {
284 0 : myUpdateTarget = updateTarget;
285 0 : }
286 :
287 :
288 : void
289 0 : GUISelectedStorage::remove2Update() {
290 0 : myUpdateTarget = nullptr;
291 0 : }
292 :
293 :
294 : void
295 0 : GUISelectedStorage::save(const std::string& filename, const std::unordered_set<GUIGlID>& ids) {
296 0 : OutputDevice& dev = OutputDevice::getDevice(filename);
297 0 : for (const auto glID : ids) {
298 0 : GUIGlObject* object = GUIGlObjectStorage::gIDStorage.getObjectBlocking(glID);
299 0 : if (object != nullptr) {
300 : std::string name = object->getFullName();
301 0 : dev << name << "\n";
302 0 : GUIGlObjectStorage::gIDStorage.unblockObject(glID);
303 : }
304 : }
305 0 : dev.close();
306 0 : }
307 :
308 :
309 : /****************************************************************************/
|