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"