File indexing completed on 2024-04-14 03:47:44

0001 // SPDX-License-Identifier: LGPL-2.1-or-later
0002 //
0003 // SPDX-FileCopyrightText: 2006-2007 Torsten Rahn <tackat@kde.org>
0004 // SPDX-FileCopyrightText: 2007 Inge Wallin <ingwa@kde.org>
0005 //
0006 
0007 #include "FileManager.h"
0008 
0009 #include <QFileInfo>
0010 #include <QElapsedTimer>
0011 
0012 #include "FileLoader.h"
0013 #include "MarbleDebug.h"
0014 #include "MarbleModel.h"
0015 #include "GeoDataTreeModel.h"
0016 
0017 #include "GeoDataLatLonAltBox.h"
0018 #include "GeoDataStyle.h"
0019 
0020 
0021 using namespace Marble;
0022 
0023 namespace Marble
0024 {
0025 class FileManagerPrivate
0026 {
0027 public:
0028     FileManagerPrivate( GeoDataTreeModel *treeModel, const PluginManager *pluginManager, FileManager* parent ) :
0029         q( parent ),
0030         m_treeModel( treeModel ),
0031         m_pluginManager( pluginManager )
0032     {
0033     }
0034 
0035     ~FileManagerPrivate()
0036     {
0037         for ( FileLoader *loader: m_loaderList ) {
0038             if ( loader ) {
0039                 loader->wait();
0040             }
0041         }
0042     }
0043 
0044     void appendLoader( FileLoader *loader );
0045     void closeFile( const QString &key );
0046     void cleanupLoader( FileLoader *loader );
0047 
0048     FileManager *const q;
0049     GeoDataTreeModel *const m_treeModel;
0050     const PluginManager *const m_pluginManager;
0051 
0052     QList<FileLoader*> m_loaderList;
0053     QHash < QString, GeoDataDocument* > m_fileItemHash;
0054     GeoDataLatLonBox m_latLonBox;
0055     QElapsedTimer m_timer;
0056 };
0057 }
0058 
0059 FileManager::FileManager( GeoDataTreeModel *treeModel, const PluginManager *pluginManager, QObject *parent )
0060     : QObject( parent )
0061     , d( new FileManagerPrivate( treeModel, pluginManager, this ) )
0062 {
0063 }
0064 
0065 
0066 FileManager::~FileManager()
0067 {
0068     delete d;
0069 }
0070 
0071 void FileManager::addFile( const QString& filepath, const QString& property, const GeoDataStyle::Ptr &style, DocumentRole role, int renderOrder, bool recenter )
0072 {
0073     if( d->m_fileItemHash.contains( filepath ) ) {
0074             return;  // already loaded
0075     }
0076 
0077     for ( const FileLoader *loader: d->m_loaderList ) {
0078         if ( loader->path() == filepath )
0079             return;  // currently loading
0080     }
0081 
0082     mDebug() << "adding container:" << filepath;
0083     mDebug() << "Starting placemark loading timer";
0084     d->m_timer.start();
0085     FileLoader* loader = new FileLoader( this, d->m_pluginManager, recenter, filepath, property, style, role, renderOrder );
0086     d->appendLoader( loader );
0087 }
0088 
0089 void FileManager::addData( const QString &name, const QString &data, DocumentRole role )
0090 {
0091     FileLoader* loader = new FileLoader( this, d->m_pluginManager, data, name, role );
0092     d->appendLoader( loader );
0093 }
0094 
0095 void FileManagerPrivate::appendLoader( FileLoader *loader )
0096 {
0097     QObject::connect( loader, SIGNAL(loaderFinished(FileLoader*)),
0098              q, SLOT(cleanupLoader(FileLoader*)) );
0099 
0100     m_loaderList.append( loader );
0101     loader->start();
0102 }
0103 
0104 void FileManager::removeFile( const QString& key )
0105 {
0106     for ( FileLoader *loader: d->m_loaderList ) {
0107         if ( loader->path() == key ) {
0108             disconnect( loader, nullptr, this, nullptr );
0109             loader->wait();
0110             d->m_loaderList.removeAll( loader );
0111             delete loader->document();
0112             return;
0113         }
0114     }
0115 
0116     if( d->m_fileItemHash.contains( key ) ) {
0117         d->closeFile( key );
0118     }
0119 
0120     mDebug() << "could not identify " << key;
0121 }
0122 
0123 void FileManagerPrivate::closeFile( const QString& key )
0124 {
0125     mDebug() << "FileManager::closeFile " << key;
0126     if( m_fileItemHash.contains( key ) ) {
0127         GeoDataDocument *doc = m_fileItemHash.value( key );
0128         m_treeModel->removeDocument( doc );
0129         emit q->fileRemoved( key );
0130         delete doc;
0131         m_fileItemHash.remove( key );
0132     }
0133 }
0134 
0135 void FileManager::closeFile( const GeoDataDocument *document )
0136 {
0137     QHash < QString, GeoDataDocument* >::iterator itpoint = d->m_fileItemHash.begin();
0138     QHash < QString, GeoDataDocument* >::iterator const endpoint = d->m_fileItemHash.end();
0139     for (; itpoint != endpoint; ++itpoint ) {
0140         if( d->m_fileItemHash.value( itpoint.key() ) == document ) {
0141             d->closeFile( itpoint.key() );
0142             return;
0143         }
0144     }
0145 }
0146 
0147 int FileManager::size() const
0148 {
0149     return d->m_fileItemHash.size();
0150 }
0151 
0152 GeoDataDocument * FileManager::at( const QString &key )
0153 {
0154     if ( d->m_fileItemHash.contains( key ) ) {
0155         return d->m_fileItemHash.value( key );
0156     }
0157     return nullptr;
0158 }
0159 
0160 int FileManager::pendingFiles() const
0161 {
0162     return d->m_loaderList.size();
0163 }
0164 
0165 void FileManagerPrivate::cleanupLoader( FileLoader* loader )
0166 {
0167     GeoDataDocument *doc = loader->document();
0168     m_loaderList.removeAll( loader );
0169     if ( loader->isFinished() ) {
0170         if ( doc ) {
0171             if ( doc->name().isEmpty() && !doc->fileName().isEmpty() )
0172             {
0173                 QFileInfo file( doc->fileName() );
0174                 doc->setName( file.baseName() );
0175             }
0176             m_treeModel->addDocument( doc );
0177             m_fileItemHash.insert( loader->path(), doc );
0178             emit q->fileAdded( loader->path() );
0179             if( loader->recenter() ) {
0180                 m_latLonBox |= doc->latLonAltBox();
0181             }
0182         }
0183         if ( !loader->error().isEmpty() ) {
0184             qWarning() << "Failed to parse" << loader->path() << loader->error();
0185             emit q->fileError(loader->path(), loader->error());
0186         }
0187         delete loader;
0188     }
0189     if ( m_loaderList.isEmpty()  )
0190     {
0191         mDebug() << "Finished loading all placemarks " << m_timer.elapsed();
0192 
0193         if ( !m_latLonBox.isEmpty() ) {
0194             emit q->centeredDocument( m_latLonBox );
0195         }
0196         m_latLonBox.clear();
0197     }
0198 }
0199 
0200 #include "moc_FileManager.cpp"