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 18500 : GUISelectedStorage::SingleTypeSelections::SingleTypeSelections() {} 43 : 44 : 45 18500 : GUISelectedStorage::SingleTypeSelections::~SingleTypeSelections() {} 46 : 47 : 48 : bool 49 75357621 : GUISelectedStorage::SingleTypeSelections::isSelected(GUIGlID id) { 50 75357621 : return mySelected.count(id) > 0; 51 : } 52 : 53 : 54 : void 55 8 : GUISelectedStorage::SingleTypeSelections::select(GUIGlID id) { 56 : mySelected.insert(id); 57 8 : } 58 : 59 : 60 : void 61 0 : GUISelectedStorage::SingleTypeSelections::deselect(GUIGlID id) { 62 : mySelected.erase(id); 63 0 : } 64 : 65 : 66 : void 67 35461 : GUISelectedStorage::SingleTypeSelections::clear() { 68 : mySelected.clear(); 69 35461 : } 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 7793 : GUISelectedStorage::GUISelectedStorage() {} 88 : 89 : 90 7793 : GUISelectedStorage::~GUISelectedStorage() {} 91 : 92 : 93 : bool 94 75357621 : GUISelectedStorage::isSelected(GUIGlObjectType type, GUIGlID id) { 95 75357621 : switch (type) { 96 : case GLO_NETWORK: 97 : return false; 98 75357621 : default: 99 75357621 : return mySelections[type].isSelected(id); 100 : } 101 : } 102 : 103 : bool 104 33028509 : GUISelectedStorage::isSelected(const GUIGlObject* o) { 105 33028509 : if (o == nullptr) { 106 : return false; 107 : } else { 108 33028509 : return isSelected(o->getType(), o->getGlID()); 109 : } 110 : } 111 : 112 : void 113 8 : GUISelectedStorage::select(GUIGlID id, bool update) { 114 8 : GUIGlObject* object = GUIGlObjectStorage::gIDStorage.getObjectBlocking(id); 115 8 : if (!object) { 116 0 : throw ProcessError(TLF("Unknown object in GUISelectedStorage::select (id=%).", toString(id))); 117 : } 118 8 : GUIGlObjectType type = object->getType(); 119 8 : GUIGlObjectStorage::gIDStorage.unblockObject(id); 120 : 121 8 : mySelections[type].select(id); 122 : myAllSelected.insert(id); 123 8 : if (update && myUpdateTarget) { 124 0 : myUpdateTarget->selectionUpdated(); 125 : } 126 8 : } 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(TLF("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 8 : GUISelectedStorage::toggleSelection(GUIGlID id) { 148 8 : GUIGlObject* object = GUIGlObjectStorage::gIDStorage.getObjectBlocking(id); 149 8 : if (!object) { 150 0 : throw ProcessError(TLF("Unknown object in GUISelectedStorage::toggleSelection (id=%).", toString(id))); 151 : } 152 : 153 8 : bool selected = isSelected(object->getType(), id); 154 8 : if (!selected) { 155 8 : select(id); 156 : } else { 157 0 : deselect(id); 158 : } 159 8 : GUIGlObjectStorage::gIDStorage.unblockObject(id); 160 8 : } 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 21292 : GUISelectedStorage::clear() { 177 56753 : for (std::map<GUIGlObjectType, SingleTypeSelections>::iterator it = mySelections.begin(); it != mySelections.end(); it++) { 178 35461 : it->second.clear(); 179 : } 180 : myAllSelected.clear(); 181 21292 : if (myUpdateTarget) { 182 0 : myUpdateTarget->selectionUpdated(); 183 : } 184 21292 : } 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 = "Could not open '" + filename + "'.\n"; 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 << "Ignoring item '" << line << "' because of invalid type " << toString(object->getType()) << "\n"; 222 : } 223 : } else { 224 0 : result.insert(object->getGlID()); 225 : } 226 : } else { 227 0 : numMissing++; 228 0 : if (numIgnored + numMissing <= maxErrors) { 229 0 : msg << "Item '" + line + "' not found\n"; 230 : } 231 0 : continue; 232 : } 233 : } 234 0 : strm.close(); 235 0 : if (numIgnored + numMissing > maxErrors) { 236 0 : msg << "...\n" << numIgnored << " objects ignored, " << numMissing << " objects not found\n"; 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 : /****************************************************************************/