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 19327 : GUISelectedStorage::SingleTypeSelections::SingleTypeSelections() {}
43 :
44 :
45 19327 : GUISelectedStorage::SingleTypeSelections::~SingleTypeSelections() {}
46 :
47 :
48 : bool
49 90725535 : GUISelectedStorage::SingleTypeSelections::isSelected(GUIGlID id) {
50 90725535 : 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 37108 : GUISelectedStorage::SingleTypeSelections::clear() {
68 : mySelected.clear();
69 37108 : }
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::set<GUIGlID>&
79 0 : GUISelectedStorage::SingleTypeSelections::getSelected() const {
80 0 : return mySelected;
81 : }
82 :
83 : /* -------------------------------------------------------------------------
84 : * for GUISelectedStorage
85 : * ----------------------------------------------------------------------- */
86 :
87 8084 : GUISelectedStorage::GUISelectedStorage() {}
88 :
89 :
90 8084 : GUISelectedStorage::~GUISelectedStorage() {}
91 :
92 :
93 : bool
94 90725535 : GUISelectedStorage::isSelected(GUIGlObjectType type, GUIGlID id) {
95 90725535 : switch (type) {
96 : case GLO_NETWORK:
97 : return false;
98 90725535 : default:
99 90725535 : return mySelections[type].isSelected(id);
100 : }
101 : }
102 :
103 : bool
104 37815334 : GUISelectedStorage::isSelected(const GUIGlObject* o) {
105 37815334 : if (o == nullptr) {
106 : return false;
107 : } else {
108 37815334 : 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::set<GUIGlID>&
164 0 : GUISelectedStorage::getSelected() const {
165 0 : return myAllSelected;
166 : }
167 :
168 :
169 : const std::set<GUIGlID>&
170 0 : GUISelectedStorage::getSelected(GUIGlObjectType type) {
171 0 : return mySelections[type].getSelected();
172 : }
173 :
174 :
175 : void
176 22107 : GUISelectedStorage::clear() {
177 59215 : for (std::map<GUIGlObjectType, SingleTypeSelections>::iterator it = mySelections.begin(); it != mySelections.end(); it++) {
178 37108 : it->second.clear();
179 : }
180 : myAllSelected.clear();
181 22107 : if (myUpdateTarget) {
182 0 : myUpdateTarget->selectionUpdated();
183 : }
184 22107 : }
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(const std::string& filename, std::string& msgOut, GUIGlObjectType type, int maxErrors) {
197 : std::set<GUIGlID> result;
198 0 : std::ostringstream msg;
199 0 : std::ifstream strm(filename.c_str());
200 : int numIgnored = 0;
201 : int numMissing = 0;
202 0 : if (!strm.good()) {
203 0 : msgOut = TLF("Could not open '%'.\n", filename);
204 0 : return result;
205 : }
206 0 : while (strm.good()) {
207 : std::string line;
208 0 : strm >> line;
209 0 : if (line.length() == 0) {
210 0 : continue;
211 : }
212 0 : if (StringUtils::startsWith(line, "node:")) {
213 0 : line = StringUtils::replace(line, "node:", "junction:");
214 : }
215 :
216 0 : GUIGlObject* object = GUIGlObjectStorage::gIDStorage.getObjectBlocking(line);
217 0 : if (object) {
218 0 : if (type != GLO_MAX && (object->getType() != type)) {
219 0 : numIgnored++;
220 0 : if (numIgnored + numMissing <= maxErrors) {
221 0 : msg << TLF("Ignoring item '%' because of invalid type %\n", line, toString(object->getType()));
222 : }
223 : } else {
224 0 : result.insert(object->getGlID());
225 : }
226 : } else {
227 0 : numMissing++;
228 0 : if (numIgnored + numMissing <= maxErrors) {
229 0 : msg << TLF("Item '%' not found\n", line);
230 : }
231 0 : continue;
232 : }
233 : }
234 0 : strm.close();
235 0 : if (numIgnored + numMissing > maxErrors) {
236 0 : msg << "...\n" << TLF("% objects ignored, % objects not found\n", numIgnored, numMissing);
237 : }
238 0 : msgOut = msg.str();
239 0 : return result;
240 0 : }
241 :
242 :
243 : std::string
244 0 : GUISelectedStorage::load(const std::string& filename, GUIGlObjectType type) {
245 : std::string errors;
246 0 : const std::set<GUIGlID> ids = loadIDs(filename, errors, type);
247 0 : for (std::set<GUIGlID>::const_iterator it = ids.begin(); it != ids.end(); it++) {
248 0 : select(*it, false);
249 : }
250 0 : if (myUpdateTarget) {
251 0 : myUpdateTarget->selectionUpdated();
252 : }
253 0 : return errors;
254 : }
255 :
256 :
257 : void
258 0 : GUISelectedStorage::save(GUIGlObjectType type, const std::string& filename) {
259 0 : mySelections[type].save(filename);
260 0 : }
261 :
262 :
263 : void
264 0 : GUISelectedStorage::save(const std::string& filename) const {
265 0 : save(filename, myAllSelected);
266 0 : }
267 :
268 :
269 : void
270 0 : GUISelectedStorage::add2Update(UpdateTarget* updateTarget) {
271 0 : myUpdateTarget = updateTarget;
272 0 : }
273 :
274 :
275 : void
276 0 : GUISelectedStorage::remove2Update() {
277 0 : myUpdateTarget = nullptr;
278 0 : }
279 :
280 :
281 : void
282 0 : GUISelectedStorage::save(const std::string& filename, const std::set<GUIGlID>& ids) {
283 0 : OutputDevice& dev = OutputDevice::getDevice(filename);
284 0 : for (std::set<GUIGlID>::const_iterator i = ids.begin(); i != ids.end(); ++i) {
285 0 : GUIGlObject* object = GUIGlObjectStorage::gIDStorage.getObjectBlocking(*i);
286 0 : if (object != nullptr) {
287 : std::string name = object->getFullName();
288 0 : dev << name << "\n";
289 0 : GUIGlObjectStorage::gIDStorage.unblockObject(*i);
290 : }
291 : }
292 0 : dev.close();
293 0 : }
294 :
295 :
296 : /****************************************************************************/
|