File indexing completed on 2024-04-21 03:49:50
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 "MarbleDebug.h" 0011 #include "PluginManager.h" 0012 #include "ParseRunnerPlugin.h" 0013 #include "RunnerTask.h" 0014 0015 #include <QFileInfo> 0016 #include <QList> 0017 #include <QThreadPool> 0018 #include <QTimer> 0019 #include <QMutex> 0020 0021 namespace Marble 0022 { 0023 0024 class MarbleModel; 0025 0026 class Q_DECL_HIDDEN ParsingRunnerManager::Private 0027 { 0028 public: 0029 Private( ParsingRunnerManager *parent, const PluginManager *pluginManager ); 0030 0031 ~Private(); 0032 0033 void cleanupParsingTask(); 0034 void addParsingResult(GeoDataDocument *document, const QString &error); 0035 0036 ParsingRunnerManager *const q; 0037 const PluginManager *const m_pluginManager; 0038 QMutex m_parsingTasksMutex; 0039 int m_parsingTasks; 0040 GeoDataDocument *m_fileResult; 0041 }; 0042 0043 ParsingRunnerManager::Private::Private( ParsingRunnerManager *parent, const PluginManager *pluginManager ) : 0044 q( parent ), 0045 m_pluginManager( pluginManager ), 0046 m_parsingTasks(0), 0047 m_fileResult( nullptr ) 0048 { 0049 qRegisterMetaType<GeoDataDocument*>( "GeoDataDocument*" ); 0050 } 0051 0052 ParsingRunnerManager::Private::~Private() 0053 { 0054 // nothing to do 0055 } 0056 0057 void ParsingRunnerManager::Private::cleanupParsingTask() 0058 { 0059 QMutexLocker locker(&m_parsingTasksMutex); 0060 m_parsingTasks = qMax(0, m_parsingTasks-1); 0061 if (m_parsingTasks == 0) { 0062 emit q->parsingFinished(); 0063 } 0064 } 0065 0066 ParsingRunnerManager::ParsingRunnerManager( const PluginManager *pluginManager, QObject *parent ) : 0067 QObject( parent ), 0068 d( new Private( this, pluginManager ) ) 0069 { 0070 if ( QThreadPool::globalInstance()->maxThreadCount() < 4 ) { 0071 QThreadPool::globalInstance()->setMaxThreadCount( 4 ); 0072 } 0073 } 0074 0075 ParsingRunnerManager::~ParsingRunnerManager() 0076 { 0077 delete d; 0078 } 0079 0080 void ParsingRunnerManager::parseFile( const QString &fileName, DocumentRole role ) 0081 { 0082 QList<const ParseRunnerPlugin*> plugins = d->m_pluginManager->parsingRunnerPlugins(); 0083 const QFileInfo fileInfo( fileName ); 0084 const QString suffix = fileInfo.suffix().toLower(); 0085 const QString completeSuffix = fileInfo.completeSuffix().toLower(); 0086 0087 d->m_parsingTasks = 0; 0088 for( const ParseRunnerPlugin *plugin: plugins ) { 0089 QStringList const extensions = plugin->fileExtensions(); 0090 if ( extensions.isEmpty() || extensions.contains( suffix ) || extensions.contains( completeSuffix ) ) { 0091 ParsingTask *task = new ParsingTask( plugin->newRunner(), this, fileName, role ); 0092 connect( task, SIGNAL(finished()), this, SLOT(cleanupParsingTask()) ); 0093 mDebug() << "parse task " << plugin->nameId() << " " << (quintptr)task; 0094 ++d->m_parsingTasks; 0095 QThreadPool::globalInstance()->start( task ); 0096 } 0097 } 0098 0099 if (d->m_parsingTasks == 0) { 0100 emit parsingFinished(); 0101 } 0102 } 0103 0104 GeoDataDocument *ParsingRunnerManager::openFile( const QString &fileName, DocumentRole role, int timeout ) 0105 { 0106 d->m_fileResult = nullptr; 0107 QEventLoop localEventLoop; 0108 QTimer watchdog; 0109 watchdog.setSingleShot(true); 0110 connect( &watchdog, SIGNAL(timeout()), 0111 &localEventLoop, SLOT(quit())); 0112 connect(this, SIGNAL(parsingFinished()), 0113 &localEventLoop, SLOT(quit()), Qt::QueuedConnection ); 0114 0115 watchdog.start( timeout ); 0116 parseFile( fileName, role); 0117 localEventLoop.exec(); 0118 return d->m_fileResult; 0119 } 0120 0121 void ParsingRunnerManager::Private::addParsingResult(GeoDataDocument *document, const QString &error) 0122 { 0123 if ( document || !error.isEmpty() ) { 0124 if (document) { 0125 m_fileResult = document; 0126 } 0127 emit q->parsingFinished( document, error ); 0128 } 0129 } 0130 0131 } 0132 0133 #include "moc_ParsingRunnerManager.cpp"