void QgsPluginManager::clearAll() { // clear all selection checkboxes for ( int row = 0; row < mModelPlugins->rowCount(); row++ ) { QStandardItem *mypItem = mModelPlugins->item( row, 0 ); QgsDetailedItemData myData = qVariantValue<QgsDetailedItemData>( mypItem->data( PLUGIN_DATA_ROLE ) ); myData.setChecked( false ); QVariant myVariant = qVariantFromValue( myData ); mypItem->setData( myVariant, PLUGIN_DATA_ROLE ); } }
void QgsPluginManager::unload() { QSettings settings; QgsDebugMsg( "Checking for plugins to unload" ); for ( int row = 0; row < mModelPlugins->rowCount(); row++ ) { // FPV - I want to use index. You can do evrething with item. QModelIndex myIndex = mModelPlugins->index( row, 0 ); QgsDetailedItemData myData = qVariantValue<QgsDetailedItemData>( mModelPlugins->data( myIndex, PLUGIN_DATA_ROLE ) ); if ( !myData.isChecked() ) { // iThe plugin name without version string in its data PLUGIN_LIB [ts] myIndex = mModelPlugins->index( row, 0 ); // its off -- see if it is loaded and if so, unload it QgsPluginRegistry *pRegistry = QgsPluginRegistry::instance(); // is loaded? QString baseName = mModelPlugins->data( myIndex, PLUGIN_BASE_NAME_ROLE ).toString(); if ( ! pRegistry->isLoaded( baseName ) ) continue; if ( pRegistry->isPythonPlugin( baseName ) ) { if ( mPythonUtils && mPythonUtils->isEnabled() ) { if ( mPythonUtils->canUninstallPlugin( baseName ) ) { mPythonUtils->unloadPlugin( baseName ); //disable it to the qsettings file settings.setValue( "/PythonPlugins/" + baseName, false ); } } } else // C++ plugin { QgisPlugin *plugin = pRegistry->plugin( baseName ); if ( plugin ) { plugin->unload(); } //disable it to the qsettings file [ts] settings.setValue( "/Plugins/" + baseName, false ); } // remove the plugin from the registry pRegistry->removePlugin( baseName ); } } QgsPluginRegistry::instance()->dump(); }
void QgsDetailedItemDelegate::paint( QPainter * thepPainter, const QStyleOptionViewItem & theOption, const QModelIndex & theIndex ) const { // After painting we need to restore the painter to its original state thepPainter->save(); if ( theIndex.data( Qt::UserRole ).canConvert<QgsDetailedItemData>() ) { QgsDetailedItemData myData = theIndex.data( Qt::UserRole ).value<QgsDetailedItemData>(); if ( myData.isRenderedAsWidget() ) { paintAsWidget( thepPainter, theOption, myData ); } else //render by manually painting { paintManually( thepPainter, theOption, myData ); } } //can convert item data thepPainter->restore(); }
void QgsPluginManager::on_vwPlugins_clicked( const QModelIndex &theIndex ) { if ( theIndex.column() == 0 ) { // // If the model has been filtered, the index row in the proxy wont match // the index row in the underlying model so we need to jump through this // little hoop to get the correct item // QModelIndex realIndex = mModelProxy->mapToSource( theIndex ); QStandardItem* mypItem = mModelPlugins->itemFromIndex( realIndex ); QgsDetailedItemData myData = qVariantValue<QgsDetailedItemData>( mypItem->data( PLUGIN_DATA_ROLE ) ); if ( myData.isEnabled() ) { myData.setChecked( ! myData.isChecked() ); } QVariant myVariant = qVariantFromValue( myData ); mypItem->setData( myVariant, PLUGIN_DATA_ROLE ); } }
std::vector < QgsPluginItem > QgsPluginManager::getSelectedPlugins() { std::vector < QgsPluginItem > pis; // FPV - I want to use item here. You can do everything with index if you want. for ( int row = 0; row < mModelPlugins->rowCount(); row++ ) { QgsDetailedItemData myData = qVariantValue<QgsDetailedItemData>( mModelPlugins->item( row, 0 )->data( PLUGIN_DATA_ROLE ) ); if ( myData.isChecked() ) { //QString baseName = mModelPlugins->item( row, 0 )->data( PLUGIN_BASE_NAME_ROLE ).toString(); QString pluginName = mModelPlugins->item( row, 0 )->data( Qt::DisplayRole ).toString(); bool pythonic = false; QString library = mModelPlugins->item( row, 0 )->data( PLUGIN_LIBRARY_ROLE ).toString(); if ( library.left( 7 ) == "python:" ) { library = library.mid( 7 ); pythonic = true; } else // C++ plugin { QString dir = mModelPlugins->item( row, 0 )->data( PLUGIN_DIRECTORY_ROLE ).toString(); //library = lblPluginDir->text() + QDir::separator() + library; library = dir + QDir::separator() + library; } // Ctor params for plugin item: //QgsPluginItem(QString name=0, // QString description=0, // QString fullPath=0, // QString type=0, // bool python=false); pis.push_back( QgsPluginItem( pluginName, library, 0, pythonic ) ); } } return pis; }
int QgsDetailedItemDelegate::height( const QStyleOptionViewItem & theOption, const QgsDetailedItemData theData ) const { QFontMetrics myTitleMetrics( titleFont( theOption ) ); QFontMetrics myDetailMetrics( detailFont( theOption ) ); //we don't word wrap the title so its easy to measure int myHeight = myTitleMetrics.height() + verticalSpacing(); //the detail needs to be measured though QStringList myList = wordWrap( theData.detail(), myDetailMetrics, theOption.rect.width() - ( mpCheckBox->width() + horizontalSpacing() ) ); myHeight += ( myList.count() + 1 ) * ( myDetailMetrics.height() - verticalSpacing() ); return myHeight; }
void QgsDetailedItemWidget::setData( QgsDetailedItemData theData ) { lblTitle->setText( theData.title() ); lblDetail->setText( theData.detail() ); lblCategory->setText( theData.category() ); cbx->setVisible( theData.isCheckable() ); cbx->setChecked( theData.isChecked() ); lblIcon->setPixmap( theData.icon() ); }
QSize QgsDetailedItemDelegate::sizeHint( const QStyleOptionViewItem & theOption, const QModelIndex & theIndex ) const { if ( theIndex.data( Qt::UserRole ).canConvert<QgsDetailedItemData>() ) { QgsDetailedItemData myData = theIndex.data( Qt::UserRole ).value<QgsDetailedItemData>(); if ( myData.isRenderedAsWidget() ) { return QSize( 378, mpWidget->height() ); } else // fall back to hand calculated & hand drawn item { //for some reason itmes are non selectable if using rect.width() on osx and win return QSize( 50, height( theOption, myData ) ); //return QSize(theOption.rect.width(), myHeight + myVerticalSpacer); } } else //cant convert to qgsdetaileditemdata { return QSize( 50, 50 ); //fallback } }
int QgsDetailedItemDelegate::height( const QStyleOptionViewItem &option, const QgsDetailedItemData &data ) const { QFontMetrics myTitleMetrics( titleFont( option ) ); QFontMetrics myDetailMetrics( detailFont( option ) ); QFontMetrics myCategoryMetrics( categoryFont( option ) ); //we don't word wrap the title so its easy to measure int myHeight = myTitleMetrics.height() + verticalSpacing(); //the detail needs to be measured though QStringList myList = wordWrap( data.detail(), myDetailMetrics, option.rect.width() - ( mpCheckBox->width() + horizontalSpacing() ) ); myHeight += ( myList.count() + 1 ) * ( myDetailMetrics.height() - verticalSpacing() ); //we don't word wrap the category so its easy to measure myHeight += myCategoryMetrics.height() + verticalSpacing(); #if 0 // if category should be wrapped use this code myList = wordWrap( data.category(), myCategoryMetrics, option.rect.width() - ( mpCheckBox->width() + horizontalSpacing() ) ); myHeight += ( myList.count() + 1 ) * ( myCategoryMetrics.height() - verticalSpacing() ); #endif return myHeight; }
void QgsDetailedItemDelegate::paintAsWidget( QPainter *thepPainter, const QStyleOptionViewItem &theOption, const QgsDetailedItemData &theData ) const { mpWidget->setChecked( theData.isChecked() ); mpWidget->setData( theData ); mpWidget->resize( theOption.rect.width(), mpWidget->height() ); mpWidget->setAutoFillBackground( true ); //mpWidget->setAttribute(Qt::WA_OpaquePaintEvent); mpWidget->repaint(); if ( theOption.state & QStyle::State_Selected ) { drawHighlight( theOption, thepPainter, height( theOption, theData ) ); } QPixmap myPixmap = QPixmap::grabWidget( mpWidget ); thepPainter->drawPixmap( theOption.rect.x(), theOption.rect.y(), myPixmap ); }//render as widget
void QgsGrassTools::addModules( QTreeWidgetItem *parent, QDomElement &element, QTreeWidget *modulesTreeWidget, QStandardItemModel * modulesListModel, bool direct ) { QDomNode n = element.firstChild(); QTreeWidgetItem *item; QTreeWidgetItem *lastItem = 0; while ( !n.isNull() ) { QDomElement e = n.toElement(); if ( !e.isNull() ) { // QgsDebugMsg(QString("tag = %1").arg(e.tagName())); if ( e.tagName() != "section" && e.tagName() != "grass" ) { QgsDebugMsg( QString( "Unknown tag: %1" ).arg( e.tagName() ) ); continue; } // Check GRASS version QString version_min = e.attribute( "version_min" ); QString version_max = e.attribute( "version_max" ); if ( !QgsGrassModuleOption::checkVersion( e.attribute( "version_min" ), e.attribute( "version_max" ) ) ) { n = n.nextSibling(); continue; } if ( parent ) { item = new QTreeWidgetItem( parent, lastItem ); } else { item = new QTreeWidgetItem( modulesTreeWidget, lastItem ); } if ( e.tagName() == "section" ) { QString label = QApplication::translate( "grasslabel", e.attribute( "label" ).toUtf8() ); QgsDebugMsg( QString( "label = %1" ).arg( label ) ); item->setText( 0, label ); item->setExpanded( false ); addModules( item, e, modulesTreeWidget, modulesListModel, direct ); lastItem = item; } else if ( e.tagName() == "grass" ) { // GRASS module QString name = e.attribute( "name" ); QgsDebugMsg( QString( "name = %1" ).arg( name ) ); QString path = QgsApplication::pkgDataPath() + "/grass/modules/" + name; QgsGrassModule::Description description = QgsGrassModule::description( path ); if ( !direct || description.direct ) { QString label = description.label; QPixmap pixmap = QgsGrassModule::pixmap( path, 32 ); item->setText( 0, name + " - " + label ); item->setIcon( 0, QIcon( pixmap ) ); item->setText( 1, name ); lastItem = item; // Add this item to our list model QStandardItem * mypDetailItem = new QStandardItem( name + "\n" + label ); mypDetailItem->setData( name, Qt::UserRole + 1 ); //for calling runModule later QString mySearchText = name + " - " + label; mypDetailItem->setData( mySearchText, Qt::UserRole + 2 ); //for filtering later mypDetailItem->setData( pixmap, Qt::DecorationRole ); mypDetailItem->setCheckable( false ); mypDetailItem->setEditable( false ); // setData in the delegate with a variantised QgsDetailedItemData QgsDetailedItemData myData; myData.setTitle( name ); myData.setDetail( label ); myData.setIcon( pixmap ); myData.setCheckable( false ); myData.setRenderAsWidget( false ); QVariant myVariant = qVariantFromValue( myData ); mypDetailItem->setData( myVariant, Qt::UserRole ); modulesListModel->appendRow( mypDetailItem ); } else { delete item; } } } n = n.nextSibling(); } }
void QgsDetailedItemDelegate::paintManually( QPainter *thepPainter, const QStyleOptionViewItem &theOption, const QgsDetailedItemData &theData ) const { // // Get the strings and check box properties // //bool myCheckState = theIndex.model()->data(theIndex, Qt::CheckStateRole).toBool(); mpCheckBox->setChecked( theData.isChecked() ); mpCheckBox->setEnabled( theData.isEnabled() ); QPixmap myCbxPixmap( mpCheckBox->size() ); mpCheckBox->render( &myCbxPixmap ); //we will draw this onto the widget further down // // Calculate the widget height and other metrics // QFontMetrics myTitleMetrics( titleFont( theOption ) ); QFontMetrics myDetailMetrics( detailFont( theOption ) ); int myTextStartX = theOption.rect.x() + horizontalSpacing(); int myTextStartY = theOption.rect.y() + verticalSpacing(); int myHeight = myTitleMetrics.height() + verticalSpacing(); // // Draw the item background with a gradient if its highlighted // if ( theOption.state & QStyle::State_Selected ) { drawHighlight( theOption, thepPainter, height( theOption, theData ) ); thepPainter->setPen( theOption.palette.highlightedText().color() ); } else { thepPainter->setPen( theOption.palette.text().color() ); } // // Draw the checkbox // if ( theData.isCheckable() ) { thepPainter->drawPixmap( theOption.rect.x(), theOption.rect.y() + mpCheckBox->height(), myCbxPixmap ); myTextStartX = theOption.rect.x() + myCbxPixmap.width() + horizontalSpacing(); } // // Draw the decoration (pixmap) // bool myIconFlag = false; QPixmap myDecoPixmap = theData.icon(); if ( !myDecoPixmap.isNull() ) { myIconFlag = true; int iconWidth = 32, iconHeight = 32; if ( myDecoPixmap.width() <= iconWidth && myDecoPixmap.height() <= iconHeight ) { // the pixmap has reasonable size int offsetX = 0, offsetY = 0; if ( myDecoPixmap.width() < iconWidth ) offsetX = ( iconWidth - myDecoPixmap.width() ) / 2; if ( myDecoPixmap.height() < iconHeight ) offsetY = ( iconHeight - myDecoPixmap.height() ) / 2; thepPainter->drawPixmap( myTextStartX + offsetX, myTextStartY + offsetY, myDecoPixmap ); } else { // shrink the pixmap, it's too big thepPainter->drawPixmap( myTextStartX, myTextStartY, iconWidth, iconHeight, myDecoPixmap ); } myTextStartX += iconWidth + horizontalSpacing(); } // // Draw the title // myTextStartY += myHeight / 2; thepPainter->setFont( titleFont( theOption ) ); thepPainter->drawText( myTextStartX, myTextStartY, theData.title() ); // // Draw the description with word wrapping if needed // thepPainter->setFont( detailFont( theOption ) ); //return to original font set by client if ( myIconFlag ) { myTextStartY += verticalSpacing(); } else { myTextStartY += myDetailMetrics.height() + verticalSpacing(); } QStringList myList = wordWrap( theData.detail(), myDetailMetrics, theOption.rect.width() - myTextStartX ); QStringListIterator myLineWrapIterator( myList ); while ( myLineWrapIterator.hasNext() ) { QString myLine = myLineWrapIterator.next(); thepPainter->drawText( myTextStartX, myTextStartY, myLine ); myTextStartY += myDetailMetrics.height() - verticalSpacing(); } // // Draw the category. Not sure if we need word wrapping for it. // thepPainter->setFont( categoryFont( theOption ) ); //return to original font set by client thepPainter->drawText( myTextStartX, myTextStartY, theData.category() ); // // Draw the category with word wrapping if needed // /* myTextStartY += verticalSpacing(); if ( myIconFlag ) { myTextStartY += verticalSpacing(); } else { myTextStartY += myCategoryMetrics.height() + verticalSpacing(); } myList = wordWrap( theData.category(), myCategoryMetrics, theOption.rect.width() - myTextStartX ); QStringListIterator myLineWrapIter( myList ); while ( myLineWrapIter.hasNext() ) { QString myLine = myLineWrapIter.next(); thepPainter->drawText( myTextStartX, myTextStartY, myLine ); myTextStartY += myCategoryMetrics.height() - verticalSpacing(); } */ } //render by manual painting
void QgsGrassTools::addModules( QTreeWidgetItem *parent, QDomElement &element ) { QDomNode n = element.firstChild(); QTreeWidgetItem *item; QTreeWidgetItem *lastItem = 0; while ( !n.isNull() ) { QDomElement e = n.toElement(); if ( !e.isNull() ) { // QgsDebugMsg(QString("tag = %1").arg(e.tagName())); if ( e.tagName() == "section" && e.tagName() == "grass" ) { QgsDebugMsg( QString( "Unknown tag: %1" ).arg( e.tagName() ) ); continue; } if ( parent ) { item = new QTreeWidgetItem( parent, lastItem ); } else { item = new QTreeWidgetItem( mModulesTree, lastItem ); } if ( e.tagName() == "section" ) { QString label = e.attribute( "label" ); QgsDebugMsg( QString( "label = %1" ).arg( label ) ); item->setText( 0, label ); item->setExpanded( false ); addModules( item, e ); lastItem = item; } else if ( e.tagName() == "grass" ) { // GRASS module QString name = e.attribute( "name" ); QgsDebugMsg( QString( "name = %1" ).arg( name ) ); QString path = QgsApplication::pkgDataPath() + "/grass/modules/" + name; QString label = QgsGrassModule::label( path ); QPixmap pixmap = QgsGrassModule::pixmap( path, 25 ); item->setText( 0, name + " - " + label ); item->setIcon( 0, QIcon( pixmap ) ); item->setText( 1, name ); lastItem = item; // // Experimental work by Tim - add this item to our list model // QStandardItem * mypDetailItem = new QStandardItem( name ); mypDetailItem->setData( name, Qt::UserRole + 1 ); //for calling runModule later QString mySearchText = name + " - " + label; mypDetailItem->setData( mySearchText, Qt::UserRole + 2 ); //for filtering later mypDetailItem->setData( pixmap, Qt::DecorationRole ); mypDetailItem->setCheckable( false ); mypDetailItem->setEditable( false ); // setData in the delegate with a variantised QgsDetailedItemData QgsDetailedItemData myData; myData.setTitle( name ); myData.setDetail( label ); myData.setIcon( pixmap ); myData.setCheckable( false ); myData.setRenderAsWidget( true ); QVariant myVariant = qVariantFromValue( myData ); mypDetailItem->setData( myVariant, Qt::UserRole ); mModelTools->appendRow( mypDetailItem ); // // End of experimental work by Tim // } } n = n.nextSibling(); } }
void QgsPluginManager::getPluginDescriptions() { QString sharedLibExtension; #ifdef WIN32 sharedLibExtension = "*.dll"; #else sharedLibExtension = "*.so*"; #endif // check all libs in the current ans user plugins directories, and get name and descriptions QSettings settings; QStringList myPathList( lblPluginDir->text() ); QString myPaths = settings.value( "plugins/searchPathsForPlugins", "" ).toString(); if ( !myPaths.isEmpty() ) { myPathList.append( myPaths.split( "|" ) ); } for ( int j = 0; j < myPathList.size(); ++j ) { QString myPluginDir = myPathList.at( j ); QDir pluginDir( myPluginDir, sharedLibExtension, QDir::Name | QDir::IgnoreCase, QDir::Files | QDir::NoSymLinks ); if ( pluginDir.count() == 0 ) { QMessageBox::information( this, tr( "No Plugins" ), tr( "No QGIS plugins found in %1" ).arg( myPluginDir ) ); return; } QgsDebugMsg( "PLUGIN MANAGER:" ); for ( uint i = 0; i < pluginDir.count(); i++ ) { QString lib = QString( "%1/%2" ).arg( myPluginDir ).arg( pluginDir[i] ); #ifdef TESTLIB // This doesn't work on WIN32 and causes problems with plugins // on OS X (the code doesn't cause a problem but including dlfcn.h // renders plugins unloadable) #if !defined(WIN32) && !defined(Q_OS_MACX) // test code to help debug loading problems // This doesn't work on WIN32 and causes problems with plugins // on OS X (the code doesn't cause a problem but including dlfcn.h // renders plugins unloadable) //void *handle = dlopen((const char *) lib, RTLD_LAZY); void *handle = dlopen( lib.toLocal8Bit().data(), RTLD_LAZY | RTLD_GLOBAL ); if ( !handle ) { QgsDebugMsg( "Error in dlopen: " ); QgsDebugMsg( dlerror() ); } else { QgsDebugMsg( "dlopen suceeded for " + lib ); dlclose( handle ); } #endif //#ifndef WIN32 && Q_OS_MACX #endif //#ifdef TESTLIB QgsDebugMsg( "Examining: " + lib ); QLibrary *myLib = new QLibrary( lib ); bool loaded = myLib->load(); if ( !loaded ) { QgsDebugMsg( QString( "Failed to load: %1 (%2)" ).arg( myLib->fileName() ).arg( myLib->errorString() ) ); delete myLib; continue; } QgsDebugMsg( "Loaded library: " + myLib->fileName() ); // Don't bother with libraries that are providers //if(!myLib->resolve("isProvider")) //MH: Replaced to allow for plugins that are linked to providers //type is only used in non-provider plugins if ( !myLib->resolve( "type" ) ) { delete myLib; continue; } // resolve the metadata from plugin name_t *pName = ( name_t * ) cast_to_fptr( myLib->resolve( "name" ) ); description_t *pDesc = ( description_t * ) cast_to_fptr( myLib->resolve( "description" ) ); category_t *pCat = ( category_t * ) cast_to_fptr( myLib->resolve( "category" ) ); version_t *pVersion = ( version_t * ) cast_to_fptr( myLib->resolve( "version" ) ); icon_t* pIcon = ( icon_t * ) cast_to_fptr( myLib->resolve( "icon" ) ); // show the values (or lack of) for each function if ( pName ) { QgsDebugMsg( "Plugin name: " + pName() ); } else { QgsDebugMsg( "Plugin name not returned when queried" ); } if ( pDesc ) { QgsDebugMsg( "Plugin description: " + pDesc() ); } else { QgsDebugMsg( "Plugin description not returned when queried" ); } if ( pCat ) { QgsDebugMsg( "Plugin category: " + pCat() ); } else { QgsDebugMsg( "Plugin category not returned when queried" ); } if ( pVersion ) { QgsDebugMsg( "Plugin version: " + pVersion() ); } else { QgsDebugMsg( "Plugin version not returned when queried" ); } if ( pIcon ) { QgsDebugMsg( "Plugin icon: " + pIcon() ); } if ( !pName || !pDesc || !pVersion ) { QgsDebugMsg( "Failed to get name, description, or type for " + myLib->fileName() ); delete myLib; continue; } QString pluginName = pName(); QString pluginDesc = pDesc(); // if no category defined - use default value QString pluginCat = ( pCat ? pCat() : tr( "Plugins" ) ); QString pluginVersion = pVersion(); QString pluginIconFileName = ( pIcon ? pIcon() : QString() ); QString baseName = QFileInfo( lib ).baseName(); QString myLibraryName = pluginDir[i]; // filtering will be done on the display role so give it name and desription // user wont see this text since we are using a custome delegate QStandardItem * mypDetailItem = new QStandardItem( pluginName + " - " + pluginDesc ); mypDetailItem->setData( myLibraryName, PLUGIN_LIBRARY_ROLE ); mypDetailItem->setData( myPluginDir, PLUGIN_DIRECTORY_ROLE ); mypDetailItem->setData( baseName, PLUGIN_BASE_NAME_ROLE ); //for matching in registry later QgsDetailedItemData myData; myData.setTitle( pluginName ); myData.setDetail( pluginDesc ); myData.setCategory( tr( "Installed in %1 menu/toolbar" ).arg( pluginCat ) ); myData.setRenderAsWidget( false ); myData.setCheckable( true ); myData.setChecked( false ); //start unchecked - we will check it later if needed if ( pluginIconFileName.isEmpty() ) myData.setIcon( QPixmap( QgsApplication::defaultThemePath() + "/plugin.png" ) ); else myData.setIcon( QPixmap( pluginIconFileName ) ); QgsDebugMsg( "Getting an instance of the QgsPluginRegistry" ); // check to see if the plugin is loaded and set the checkbox accordingly QgsPluginRegistry *pRegistry = QgsPluginRegistry::instance(); // get the library using the plugin description if ( !pRegistry->isLoaded( baseName ) ) { QgsDebugMsg( "Couldn't find plugin in the registry" ); } else { QgsDebugMsg( "Found plugin in the registry" ); // TODO: this check shouldn't be necessary, plugin base names must be unique if ( pRegistry->library( baseName ) == myLib->fileName() ) { // set the checkbox myData.setChecked( true ); } } QVariant myVariant = qVariantFromValue( myData ); mypDetailItem->setData( myVariant, PLUGIN_DATA_ROLE ); // Add items to model mModelPlugins->appendRow( mypDetailItem ); delete myLib; } } }
void QgsPluginManager::getPythonPluginDescriptions() { if ( !mPythonUtils || !mPythonUtils->isEnabled() ) return; // look for plugins systemwide QStringList pluginList = mPythonUtils->pluginList(); for ( int i = 0; i < pluginList.size(); i++ ) { QString packageName = pluginList[i]; // import plugin's package - skip loading it if an error occured if ( !mPythonUtils->loadPlugin( packageName ) ) continue; // get information from the plugin QString pluginName = mPythonUtils->getPluginMetadata( packageName, "name" ); QString description = mPythonUtils->getPluginMetadata( packageName, "description" ); QString category = mPythonUtils->getPluginMetadata( packageName, "category" ); QString version = mPythonUtils->getPluginMetadata( packageName, "version" ); QString iconName = mPythonUtils->getPluginMetadata( packageName, "icon" ); if ( pluginName == "__error__" || description == "__error__" || version == "__error__" ) continue; // if there is no category in Python plugin assume default 'Plugins' category if ( category == "__error__" ) { category = tr( "Plugins" ); } bool isCompatible = QgsPluginRegistry::instance()->isPythonPluginCompatible( packageName ); QString compatibleString; // empty by default if ( !isCompatible ) compatibleString = " " + tr( "[ incompatible ]" ); // filtering will be done on the display role so give it name and desription // user wont see this text since we are using a custome delegate QStandardItem * mypDetailItem = new QStandardItem( pluginName + " - " + description ); QString myLibraryName = "python:" + packageName; mypDetailItem->setData( myLibraryName, PLUGIN_LIBRARY_ROLE ); //for loading libs later mypDetailItem->setData( packageName, PLUGIN_BASE_NAME_ROLE ); //for matching in registry later mypDetailItem->setCheckable( false ); mypDetailItem->setEditable( false ); mypDetailItem->setEnabled( isCompatible ); // setData in the delegate with a variantised QgsDetailedItemData QgsDetailedItemData myData; myData.setTitle( pluginName + " (" + version + ")" + compatibleString ); myData.setEnabled( isCompatible ); myData.setDetail( description ); myData.setCategory( tr( "Installed in %1 menu/toolbar" ).arg( category ) ); //myData.setIcon(pixmap); //todo use a python logo here myData.setCheckable( true ); myData.setRenderAsWidget( false ); myData.setChecked( false ); //start off assuming false if ( iconName == "__error__" ) myData.setIcon( QPixmap( QgsApplication::defaultThemePath() + "/plugin.png" ) ); else { bool relative = QFileInfo( iconName ).isRelative(); if ( relative ) { QString pluginDir; mPythonUtils->evalString( QString( "qgis.utils.pluginDirectory('%1')" ).arg( packageName ), pluginDir ); iconName = pluginDir + "/" + iconName; } myData.setIcon( QPixmap( iconName ) ); } // check to see if the plugin is loaded and set the checkbox accordingly QgsPluginRegistry *pRegistry = QgsPluginRegistry::instance(); if ( pRegistry->isLoaded( packageName ) && pRegistry->isPythonPlugin( packageName ) ) { QgsDebugMsg( "Found plugin in the registry" ); // set the checkbox myData.setChecked( true ); } else { QgsDebugMsg( "Couldn't find plugin in the registry: " + packageName ); } QVariant myVariant = qVariantFromValue( myData ); mypDetailItem->setData( myVariant, PLUGIN_DATA_ROLE ); // Add item to model mModelPlugins->appendRow( mypDetailItem ); } }