Marble

FileManager.cpp
1// SPDX-License-Identifier: LGPL-2.1-or-later
2//
3// SPDX-FileCopyrightText: 2006-2007 Torsten Rahn <tackat@kde.org>
4// SPDX-FileCopyrightText: 2007 Inge Wallin <ingwa@kde.org>
5//
6
7#include "FileManager.h"
8
9#include <QElapsedTimer>
10#include <QFileInfo>
11
12#include "FileLoader.h"
13#include "GeoDataTreeModel.h"
14#include "MarbleDebug.h"
15#include "MarbleModel.h"
16
17#include "GeoDataLatLonAltBox.h"
18#include "GeoDataStyle.h"
19
20using namespace Marble;
21
22namespace Marble
23{
24class FileManagerPrivate
25{
26public:
27 FileManagerPrivate(GeoDataTreeModel *treeModel, const PluginManager *pluginManager, FileManager *parent)
28 : q(parent)
29 , m_treeModel(treeModel)
30 , m_pluginManager(pluginManager)
31 {
32 }
33
34 ~FileManagerPrivate()
35 {
36 for (FileLoader *loader : std::as_const(m_loaderList)) {
37 if (loader) {
38 loader->wait();
39 }
40 }
41 }
42
43 void appendLoader(FileLoader *loader);
44 void closeFile(const QString &key);
45 void cleanupLoader(FileLoader *loader);
46
47 FileManager *const q;
48 GeoDataTreeModel *const m_treeModel;
49 const PluginManager *const m_pluginManager;
50
51 QList<FileLoader *> m_loaderList;
52 QHash<QString, GeoDataDocument *> m_fileItemHash;
53 GeoDataLatLonBox m_latLonBox;
54 QElapsedTimer m_timer;
55};
56}
57
60 , d(new FileManagerPrivate(treeModel, pluginManager, this))
61{
62}
63
65{
66 delete d;
67}
68
69void FileManager::addFile(const QString &filepath, const QString &property, const GeoDataStyle::Ptr &style, DocumentRole role, int renderOrder, bool recenter)
70{
71 if (d->m_fileItemHash.contains(filepath)) {
72 return; // already loaded
73 }
74
75 for (const FileLoader *loader : std::as_const(d->m_loaderList)) {
76 if (loader->path() == filepath)
77 return; // currently loading
78 }
79
80 mDebug() << "adding container:" << filepath;
81 mDebug() << "Starting placemark loading timer";
82 d->m_timer.start();
83 auto loader = new FileLoader(this, d->m_pluginManager, recenter, filepath, property, style, role, renderOrder);
84 d->appendLoader(loader);
85}
86
87void FileManager::addData(const QString &name, const QString &data, DocumentRole role)
88{
89 auto loader = new FileLoader(this, d->m_pluginManager, data, name, role);
90 d->appendLoader(loader);
91}
92
93void FileManagerPrivate::appendLoader(FileLoader *loader)
94{
95 QObject::connect(loader, SIGNAL(loaderFinished(FileLoader *)), q, SLOT(cleanupLoader(FileLoader *)));
96
97 m_loaderList.append(loader);
98 loader->start();
99}
100
102{
103 for (FileLoader *loader : std::as_const(d->m_loaderList)) {
104 if (loader->path() == key) {
105 disconnect(loader, nullptr, this, nullptr);
106 loader->wait();
107 d->m_loaderList.removeAll(loader);
108 delete loader->document();
109 return;
110 }
111 }
112
113 if (d->m_fileItemHash.contains(key)) {
114 d->closeFile(key);
115 }
116
117 mDebug() << "could not identify " << key;
118}
119
120void FileManagerPrivate::closeFile(const QString &key)
121{
122 mDebug() << "FileManager::closeFile " << key;
123 if (m_fileItemHash.contains(key)) {
124 GeoDataDocument *doc = m_fileItemHash.value(key);
125 m_treeModel->removeDocument(doc);
126 Q_EMIT q->fileRemoved(key);
127 delete doc;
128 m_fileItemHash.remove(key);
129 }
130}
131
132void FileManager::closeFile(const GeoDataDocument *document)
133{
134 QHash<QString, GeoDataDocument *>::iterator itpoint = d->m_fileItemHash.begin();
135 QHash<QString, GeoDataDocument *>::iterator const endpoint = d->m_fileItemHash.end();
136 for (; itpoint != endpoint; ++itpoint) {
137 if (d->m_fileItemHash.value(itpoint.key()) == document) {
138 d->closeFile(itpoint.key());
139 return;
140 }
141 }
142}
143
144int FileManager::size() const
145{
146 return d->m_fileItemHash.size();
147}
148
149GeoDataDocument *FileManager::at(const QString &key)
150{
151 if (d->m_fileItemHash.contains(key)) {
152 return d->m_fileItemHash.value(key);
153 }
154 return nullptr;
155}
156
158{
159 return d->m_loaderList.size();
160}
161
162void FileManagerPrivate::cleanupLoader(FileLoader *loader)
163{
164 GeoDataDocument *doc = loader->document();
165 m_loaderList.removeAll(loader);
166 if (loader->isFinished()) {
167 if (doc) {
168 if (doc->name().isEmpty() && !doc->fileName().isEmpty()) {
169 QFileInfo file(doc->fileName());
170 doc->setName(file.baseName());
171 }
172 m_treeModel->addDocument(doc);
173 m_fileItemHash.insert(loader->path(), doc);
174 Q_EMIT q->fileAdded(loader->path());
175 if (loader->recenter()) {
176 m_latLonBox |= doc->latLonAltBox();
177 }
178 }
179 if (!loader->error().isEmpty()) {
180 qWarning() << "Failed to parse" << loader->path() << loader->error();
181 Q_EMIT q->fileError(loader->path(), loader->error());
182 }
183 delete loader;
184 }
185 if (m_loaderList.isEmpty()) {
186 mDebug() << "Finished loading all placemarks " << m_timer.elapsed();
187
188 if (!m_latLonBox.isEmpty()) {
189 Q_EMIT q->centeredDocument(m_latLonBox);
190 }
191 m_latLonBox.clear();
192 }
193}
194
195#include "moc_FileManager.cpp"
This file contains the headers for MarbleModel.
int pendingFiles() const
Returns the number of files being opened at the moment.
void addFile(const QString &fileName, const QString &property, const GeoDataStyle::Ptr &style, DocumentRole role, int renderOrder=0, bool recenter=false)
Loads a new file into the manager.
FileManager(GeoDataTreeModel *treeModel, const PluginManager *pluginManager, QObject *parent=nullptr)
Creates a new file manager.
void removeFile(const QString &fileName)
removes an existing file from the manager
void addData(const QString &name, const QString &data, DocumentRole role)
add Data containing KML code as string
~FileManager() override
Destroys the file manager.
GeoDataLatLonAltBox latLonAltBox() const
A convenience function that returns the LatLonAltBox of all placemarks in this container.
A container for Features, Styles and in the future Schemas.
QString fileName() const
The filename of the document.
QString name() const
The name of the feature.
void setName(const QString &value)
Set a new name for this feature.
The representation of GeoData in a model This class represents all available data given by kml-data f...
The class that handles Marble's plugins.
Binds a QML item to a specific geodetic location in screen coordinates.
void append(QList< T > &&value)
qsizetype removeAll(const AT &t)
QObject(QObject *parent)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
bool disconnect(const QMetaObject::Connection &connection)
QObject * parent() const const
QVariant property(const char *name) const const
iterator begin()
bool isEmpty() const const
bool isFinished() const const
void start(Priority priority)
bool wait(QDeadlineTimer deadline)
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Jan 24 2025 11:52:08 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.