Path: blob/main/src/utils/gui/div/GUISelectedStorage.cpp
169684 views
/****************************************************************************/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.cpp14/// @author Daniel Krajzewicz15/// @author Jakob Erdmann16/// @author Michael Behrisch17/// @date Jun 200418///19// Storage for "selected" objects20/****************************************************************************/21#include <config.h>2223#include <algorithm>24#include <utils/gui/globjects/GUIGlObject.h>25#include <utils/gui/globjects/GUIGlObjectStorage.h>26#include <utils/iodevices/OutputDevice.h>27#include <utils/common/ToString.h>2829#include "GUISelectedStorage.h"30#include "GUIDialog_GLChosenEditor.h"313233// ===========================================================================34// member method definitions35// ===========================================================================3637/* -------------------------------------------------------------------------38* for GUISelectedStorage::SingleTypeSelections39* ----------------------------------------------------------------------- */4041GUISelectedStorage::SingleTypeSelections::SingleTypeSelections() {}424344GUISelectedStorage::SingleTypeSelections::~SingleTypeSelections() {}454647bool48GUISelectedStorage::SingleTypeSelections::isSelected(GUIGlID id) {49return mySelected.count(id) > 0;50}515253void54GUISelectedStorage::SingleTypeSelections::select(GUIGlID id) {55mySelected.insert(id);56}575859void60GUISelectedStorage::SingleTypeSelections::deselect(GUIGlID id) {61mySelected.erase(id);62}636465void66GUISelectedStorage::SingleTypeSelections::clear() {67mySelected.clear();68}697071void72GUISelectedStorage::SingleTypeSelections::save(const std::string& filename) {73GUISelectedStorage::save(filename, mySelected);74}757677const std::unordered_set<GUIGlID>&78GUISelectedStorage::SingleTypeSelections::getSelected() const {79return mySelected;80}8182/* -------------------------------------------------------------------------83* for GUISelectedStorage84* ----------------------------------------------------------------------- */8586GUISelectedStorage::GUISelectedStorage() {}878889GUISelectedStorage::~GUISelectedStorage() {}909192bool93GUISelectedStorage::isSelected(GUIGlObjectType type, GUIGlID id) {94switch (type) {95case GLO_NETWORK:96return false;97default:98return mySelections[type].isSelected(id);99}100}101102bool103GUISelectedStorage::isSelected(const GUIGlObject* o) {104if (o == nullptr) {105return false;106} else {107return isSelected(o->getType(), o->getGlID());108}109}110111void112GUISelectedStorage::select(GUIGlID id, bool update) {113GUIGlObject* object = GUIGlObjectStorage::gIDStorage.getObjectBlocking(id);114if (!object) {115throw ProcessError("Unknown object in GUISelectedStorage::select (id=" + toString(id) + ").");116}117GUIGlObjectType type = object->getType();118GUIGlObjectStorage::gIDStorage.unblockObject(id);119120mySelections[type].select(id);121myAllSelected.insert(id);122if (update && myUpdateTarget) {123myUpdateTarget->selectionUpdated();124}125}126127128void129GUISelectedStorage::deselect(GUIGlID id) {130GUIGlObject* object = GUIGlObjectStorage::gIDStorage.getObjectBlocking(id);131if (!object) {132throw ProcessError("Unknown object in GUISelectedStorage::deselect (id=" + toString(id) + ").");133}134GUIGlObjectType type = object->getType();135GUIGlObjectStorage::gIDStorage.unblockObject(id);136137mySelections[type].deselect(id);138myAllSelected.erase(id);139if (myUpdateTarget) {140myUpdateTarget->selectionUpdated();141}142}143144145void146GUISelectedStorage::deselect(GUIGlObjectType type, GUIGlID id) {147mySelections[type].deselect(id);148myAllSelected.erase(id);149}150151152void153GUISelectedStorage::toggleSelection(GUIGlID id) {154GUIGlObject* object = GUIGlObjectStorage::gIDStorage.getObjectBlocking(id);155if (!object) {156throw ProcessError("Unknown object in GUISelectedStorage::toggleSelection (id=" + toString(id) + ").");157}158159bool selected = isSelected(object->getType(), id);160if (!selected) {161select(id);162} else {163deselect(id);164}165GUIGlObjectStorage::gIDStorage.unblockObject(id);166}167168169const std::unordered_set<GUIGlID>&170GUISelectedStorage::getSelected() const {171return myAllSelected;172}173174175const std::unordered_set<GUIGlID>&176GUISelectedStorage::getSelected(GUIGlObjectType type) {177return mySelections[type].getSelected();178}179180181void182GUISelectedStorage::clear() {183for (auto& selection : mySelections) {184selection.second.clear();185}186myAllSelected.clear();187if (myUpdateTarget) {188myUpdateTarget->selectionUpdated();189}190}191192193void194GUISelectedStorage::notifyChanged() {195if (myUpdateTarget) {196myUpdateTarget->selectionUpdated();197}198}199200201std::set<GUIGlID>202GUISelectedStorage::loadIDs(std::istream& strm, std::string& msgOut, GUIGlObjectType type, std::ostream* dynamicNotFound, int maxErrors) {203std::set<GUIGlID> result;204std::ostringstream msg;205int numIgnored = 0;206int numMissing = 0;207while (strm.good()) {208std::string line;209strm >> line;210if (line.length() == 0) {211continue;212}213if (StringUtils::startsWith(line, "node:")) {214line = StringUtils::replace(line, "node:", "junction:");215}216217GUIGlObject* object = GUIGlObjectStorage::gIDStorage.getObjectBlocking(line);218if (object) {219if (type != GLO_MAX && (object->getType() != type)) {220numIgnored++;221if (numIgnored + numMissing <= maxErrors) {222msg << TLF("Ignoring item '%' because of invalid type %\n", line, toString(object->getType()));223}224} else {225result.insert(object->getGlID());226}227} else {228numMissing++;229if (dynamicNotFound != nullptr && (230StringUtils::startsWith(line, "vehicle:") ||231StringUtils::startsWith(line, "person:") ||232StringUtils::startsWith(line, "container:"))) {233(*dynamicNotFound) << line << "\n";234} else {235if (numIgnored + numMissing <= maxErrors) {236msg << TLF("Item '%' not found\n", line);237}238}239continue;240}241}242if (numIgnored + numMissing > maxErrors) {243msg << "...\n" << TLF("% objects ignored, % objects not found\n", numIgnored, numMissing);244}245msgOut = msg.str();246return result;247}248249250std::string251GUISelectedStorage::load(const std::string& filename, GUIGlObjectType type, std::ostream* dynamicNotFound) {252std::ifstream strm(filename.c_str());253if (!strm.good()) {254return TLF("Could not open '%'.\n", filename);255}256std::string errors = load(strm, type, dynamicNotFound);257strm.close();258return errors;259}260261262std::string263GUISelectedStorage::load(std::istream& strm, GUIGlObjectType type, std::ostream* dynamicNotFound) {264std::string errors;265const std::set<GUIGlID> ids = loadIDs(strm, errors, type, dynamicNotFound);266for (const auto glID : ids) {267select(glID, false);268}269if (myUpdateTarget) {270myUpdateTarget->selectionUpdated();271}272return errors;273}274275276void277GUISelectedStorage::save(GUIGlObjectType type, const std::string& filename) {278mySelections[type].save(filename);279}280281282void283GUISelectedStorage::save(const std::string& filename) const {284save(filename, myAllSelected);285}286287288void289GUISelectedStorage::add2Update(UpdateTarget* updateTarget) {290myUpdateTarget = updateTarget;291}292293294void295GUISelectedStorage::remove2Update() {296myUpdateTarget = nullptr;297}298299300void301GUISelectedStorage::save(const std::string& filename, const std::unordered_set<GUIGlID>& ids) {302OutputDevice& dev = OutputDevice::getDevice(filename);303for (const auto glID : ids) {304GUIGlObject* object = GUIGlObjectStorage::gIDStorage.getObjectBlocking(glID);305if (object != nullptr) {306std::string name = object->getFullName();307dev << name << "\n";308GUIGlObjectStorage::gIDStorage.unblockObject(glID);309}310}311dev.close();312}313314315/****************************************************************************/316317318