File indexing completed on 2025-01-05 03:59:35

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