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

0001 // SPDX-License-Identifier: LGPL-2.1-or-later
0002 //
0003 // SPDX-FileCopyrightText: 2008 Henry de Valence <hdevalence@gmail.com>
0004 // SPDX-FileCopyrightText: 2010 Dennis Nienhüser <nienhueser@kde.org>
0005 // SPDX-FileCopyrightText: 2010-2013 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
0006 // SPDX-FileCopyrightText: 2011 Thibaut Gridel <tgridel@free.fr>
0007 
0008 #include "ParsingRunnerManager.h"
0009 
0010 #include <QFileInfo>
0011 #include <QList>
0012 #include <QThreadPool>
0013 #include <QTimer>
0014 #include <QMutex>
0015 
0016 #include "PluginManager.h"
0017 #include "ParseRunnerPlugin.h"
0018 #include "RunnerTask.h"
0019 
0020 #include "digikam_debug.h"
0021 
0022 namespace Marble
0023 {
0024 
0025 class MarbleModel;
0026 
0027 class Q_DECL_HIDDEN ParsingRunnerManager::Private
0028 {
0029 public:
0030     Private( ParsingRunnerManager *parent, const PluginManager *pluginManager );
0031 
0032     ~Private();
0033 
0034     void cleanupParsingTask();
0035     void addParsingResult(GeoDataDocument *document, const QString &error);
0036 
0037     ParsingRunnerManager *const q;
0038     const PluginManager *const m_pluginManager;
0039     QMutex m_parsingTasksMutex;
0040     int m_parsingTasks;
0041     GeoDataDocument *m_fileResult;
0042 };
0043 
0044 ParsingRunnerManager::Private::Private( ParsingRunnerManager *parent, const PluginManager *pluginManager ) :
0045     q( parent ),
0046     m_pluginManager( pluginManager ),
0047     m_parsingTasks(0),
0048     m_fileResult( nullptr )
0049 {
0050     qRegisterMetaType<GeoDataDocument*>( "GeoDataDocument*" );
0051 }
0052 
0053 ParsingRunnerManager::Private::~Private()
0054 {
0055     // nothing to do
0056 }
0057 
0058 void ParsingRunnerManager::Private::cleanupParsingTask()
0059 {
0060     QMutexLocker locker(&m_parsingTasksMutex);
0061     m_parsingTasks = qMax(0, m_parsingTasks-1);
0062     if (m_parsingTasks == 0) {
0063         Q_EMIT q->parsingFinished();
0064     }
0065 }
0066 
0067 ParsingRunnerManager::ParsingRunnerManager( const PluginManager *pluginManager, QObject *parent ) :
0068     QObject( parent ),
0069     d( new Private( this, pluginManager ) )
0070 {
0071     if ( QThreadPool::globalInstance()->maxThreadCount() < 4 ) {
0072         QThreadPool::globalInstance()->setMaxThreadCount( 4 );
0073     }
0074 }
0075 
0076 ParsingRunnerManager::~ParsingRunnerManager()
0077 {
0078     delete d;
0079 }
0080 
0081 void ParsingRunnerManager::parseFile( const QString &fileName, DocumentRole role )
0082 {
0083     QList<const ParseRunnerPlugin*> plugins = d->m_pluginManager->parsingRunnerPlugins();
0084     const QFileInfo fileInfo( fileName );
0085     const QString suffix = fileInfo.suffix().toLower();
0086     const QString completeSuffix = fileInfo.completeSuffix().toLower();
0087 
0088     d->m_parsingTasks = 0;
0089     for( const ParseRunnerPlugin *plugin: plugins ) {
0090         QStringList const extensions = plugin->fileExtensions();
0091         if ( extensions.isEmpty() || extensions.contains( suffix ) || extensions.contains( completeSuffix ) ) {
0092             ParsingTask *task = new ParsingTask( plugin->newRunner(), this, fileName, role );
0093             connect( task, SIGNAL(finished()), this, SLOT(cleanupParsingTask()) );
0094             qCDebug(DIGIKAM_MARBLE_LOG) << "parse task " << plugin->nameId() << " " << (quintptr)task;
0095             ++d->m_parsingTasks;
0096             QThreadPool::globalInstance()->start( task );
0097         }
0098     }
0099 
0100     if (d->m_parsingTasks == 0) {
0101         Q_EMIT parsingFinished();
0102     }
0103 }
0104 
0105 GeoDataDocument *ParsingRunnerManager::openFile( const QString &fileName, DocumentRole role, int timeout )
0106 {
0107     d->m_fileResult = nullptr;
0108     QEventLoop localEventLoop;
0109     QTimer watchdog;
0110     watchdog.setSingleShot(true);
0111     connect( &watchdog, SIGNAL(timeout()),
0112              &localEventLoop, SLOT(quit()));
0113     connect(this, SIGNAL(parsingFinished()),
0114             &localEventLoop, SLOT(quit()), Qt::QueuedConnection );
0115 
0116     watchdog.start( timeout );
0117     parseFile( fileName, role);
0118     localEventLoop.exec();
0119     return d->m_fileResult;
0120 }
0121 
0122 void ParsingRunnerManager::Private::addParsingResult(GeoDataDocument *document, const QString &error)
0123 {
0124     if ( document || !error.isEmpty() ) {
0125         if (document) {
0126             m_fileResult = document;
0127         }
0128         Q_EMIT q->parsingFinished( document, error );
0129     }
0130 }
0131 
0132 }
0133 
0134 #include "moc_ParsingRunnerManager.cpp"