📄 qgpluginmanager.cpp
字号:
/*! \fn QRESULT QPluginManager::queryInterface(const QString& feature, Type** iface) const Sets \a iface to point to the interface providing \a feature. \sa featureList(), library()*/#include <qptrlist.h>QGPluginManager::QGPluginManager( const QUuid& id, const QStringList& paths, const QString &suffix, bool cs ) : interfaceId( id ), plugDict( 17, cs ), casesens( cs ), autounload( TRUE ){ // Every QLibrary object is destroyed on destruction of the manager libDict.setAutoDelete( TRUE ); for ( QStringList::ConstIterator it = paths.begin(); it != paths.end(); ++it ) { QString path = *it; addLibraryPath( path + suffix ); }}QGPluginManager::~QGPluginManager(){ if ( !autounload ) { QDictIterator<QLibrary> it( libDict ); while ( it.current() ) { QLibrary *lib = it.current(); ++it; lib->setAutoUnload( FALSE ); } }}void QGPluginManager::addLibraryPath( const QString& path ){ if ( !enabled() || !QDir( path ).exists( ".", TRUE ) ) return;#if defined(Q_OS_WIN32) QString filter = "*.dll";#elif defined(Q_OS_MACX) QString filter = "*.dylib; *.so";#elif defined(Q_OS_HPUX) QString filter = "*.sl";#elif defined(Q_OS_UNIX) QString filter = "*.so";#endif QStringList plugins = QDir(path).entryList( filter ); for ( QStringList::Iterator p = plugins.begin(); p != plugins.end(); ++p ) { QString lib = QDir::cleanDirPath( path + "/" + *p ); if ( libList.contains( lib ) ) continue; libList.append( lib ); }}const QLibrary* QGPluginManager::library( const QString& feature ) const{ if ( !enabled() || feature.isEmpty() ) return 0; // We already have a QLibrary object for this feature QLibrary *library = 0; if ( ( library = plugDict[feature] ) ) return library; // Find the filename that matches the feature request best QMap<int, QStringList> map; QStringList::ConstIterator it = libList.begin(); int best = 0; int worst = 15; while ( it != libList.end() ) { if ( (*it).isEmpty() || libDict[*it] ) { ++it; continue; } QString basename = QFileInfo(*it).baseName(); int s = similarity( feature, basename ); if ( s < worst ) worst = s; if ( s > best ) best = s; map[s].append( basename + QChar(0xfffd) + *it ); ++it; } if ( map.isEmpty() ) return 0; // no libraries to add // Start with the best match to get the library object QGPluginManager *that = (QGPluginManager*)this; for ( int s = best; s >= worst; --s ) { QStringList group = map[s]; group.sort(); // sort according to the base name QStringList::ConstIterator git = group.begin(); while ( git != group.end() ) { QString lib = (*git).mid( (*git).find( QChar(0xfffd) ) + 1 ); QString basename = (*git).left( (*git).find( QChar(0xfffd) ) ); ++git; QStringList sameBasename; while( git != group.end() && basename == (*git).left( (*git).find( QChar(0xfffd) ) ) ) { sameBasename << (*git).mid( (*git).find( QChar(0xfffd) ) + 1 ); ++git; } if ( sameBasename.isEmpty() ) { that->addLibrary( new QComLibrary( lib ) ); } else { QPtrList<QComLibrary> same; same.setAutoDelete( TRUE ); for ( QStringList::ConstIterator bit = sameBasename.begin(); bit != sameBasename.end(); ++bit ) same.append( new QComLibrary( *bit ) ); QComLibrary* bestMatch = 0; for ( QComLibrary* candidate = same.first(); candidate; candidate = same.next() ) if ( candidate->qtVersion() && candidate->qtVersion() <= QT_VERSION && ( !bestMatch || candidate->qtVersion() > bestMatch->qtVersion() ) ) bestMatch = candidate; if ( bestMatch ) { same.find( bestMatch ); that->addLibrary( same.take() ); } } if ( ( library = that->plugDict[feature] ) ) return library; } } return 0;}QStringList QGPluginManager::featureList() const{ QStringList features; if ( !enabled() ) return features; QGPluginManager *that = (QGPluginManager*)this; QStringList theLibs = libList; QStringList phase2Libs; QStringList phase2Deny; /* In order to get the feature list we need to add all interesting libraries. If there are libraries with the same base name, we prioritze the one that fits our Qt version number and ignore the others */ QStringList::Iterator it; for ( it = theLibs.begin(); it != theLibs.end(); ++it ) { if ( (*it).isEmpty() || libDict[*it] ) continue; QComLibrary* library = new QComLibrary( *it ); if ( library->qtVersion() == QT_VERSION ) { that->addLibrary( library ); phase2Deny << QFileInfo( *it ).baseName(); } else { delete library; phase2Libs << *it; } } for ( it = phase2Libs.begin(); it != phase2Libs.end(); ++it ) if ( !phase2Deny.contains( QFileInfo( *it ).baseName() ) ) that->addLibrary( new QComLibrary( *it ) ); for ( QDictIterator<QLibrary> pit( plugDict ); pit.current(); ++pit ) features << pit.currentKey(); return features;}bool QGPluginManager::addLibrary( QLibrary* lib ){ if ( !enabled() || !lib ) return FALSE; QComLibrary* plugin = (QComLibrary*)lib; bool useful = FALSE; QUnknownInterface* iFace = 0; plugin->queryInterface( interfaceId, &iFace ); if ( iFace ) { QFeatureListInterface *fliFace = 0; QComponentInformationInterface *cpiFace = 0; iFace->queryInterface( IID_QFeatureList, (QUnknownInterface**)&fliFace ); if ( !fliFace ) plugin->queryInterface( IID_QFeatureList, (QUnknownInterface**)&fliFace ); if ( !fliFace ) { iFace->queryInterface( IID_QComponentInformation, (QUnknownInterface**)&cpiFace ); if ( !cpiFace ) plugin->queryInterface( IID_QComponentInformation, (QUnknownInterface**)&cpiFace ); } QStringList fl; if ( fliFace ) // Map all found features to the library fl = fliFace->featureList(); else if ( cpiFace ) fl << cpiFace->name(); for ( QStringList::Iterator f = fl.begin(); f != fl.end(); ++f ) { QLibrary *old = plugDict[*f]; if ( !old ) { useful = TRUE; plugDict.replace( *f, plugin ); } else { // we have old *and* plugin, which one to pick? QComLibrary* first = (QComLibrary*)old; QComLibrary* second = (QComLibrary*)plugin; bool takeFirst = TRUE; if ( first->qtVersion() != QT_VERSION ) { if ( second->qtVersion() == QT_VERSION ) takeFirst = FALSE; else if ( second->qtVersion() < QT_VERSION && first->qtVersion() > QT_VERSION ) takeFirst = FALSE; } if ( !takeFirst ) { useful = TRUE; plugDict.replace( *f, plugin ); qWarning("%s: Discarding feature %s in %s!", (const char*) QFile::encodeName( plugin->library()), (*f).latin1(), (const char*) QFile::encodeName( old->library() ) ); } else { qWarning("%s: Feature %s already defined in %s!", (const char*) QFile::encodeName( old->library() ), (*f).latin1(), (const char*) QFile::encodeName( plugin->library() ) ); } } } if ( fliFace ) fliFace->release(); if ( cpiFace ) cpiFace->release(); iFace->release(); } if ( useful ) { libDict.replace( plugin->library(), plugin ); if ( !libList.contains( plugin->library() ) ) libList.append( plugin->library() ); return TRUE; } delete plugin; return FALSE;}bool QGPluginManager::enabled() const{#ifdef QT_SHARED return TRUE;#else return FALSE;#endif}QRESULT QGPluginManager::queryUnknownInterface(const QString& feature, QUnknownInterface** iface) const{ QComLibrary* plugin = 0; plugin = (QComLibrary*)library( feature ); return plugin ? plugin->queryInterface( interfaceId, (QUnknownInterface**)iface ) : QE_NOINTERFACE;}#endif //QT_NO_COMPONENT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -