[Plugin Manager] New tab for all plugins. New class QgsPluginItemDelegate

This commit is contained in:
Borys Jurgiel 2013-09-15 11:24:01 +00:00
parent b49df73e18
commit c093ab91b0
9 changed files with 207 additions and 42 deletions

View File

@ -143,12 +143,12 @@ class QgsPluginInstaller(QObject):
for key in plugins.all():
if plugins.all()[key]["status"] == "new":
status = self.tr("There is a new plugin available")
tabIndex = 3 # tab 3 contains new plugins
tabIndex = 4 # PLUGMAN_TAB_NEW
# then check for updates (and eventually overwrite status)
for key in plugins.all():
if plugins.all()[key]["status"] == "upgradeable":
status = self.tr("There is a plugin update available")
tabIndex = 2 # tab 2 contains upgradeable plugins
tabIndex = 3 # PLUGMAN_TAB_UPGRADEABLE
# finally set the notify label
if status:
self.statusLabel.setText(u' <a href="%d">%s</a> ' % (tabIndex,status) )

View File

@ -152,6 +152,7 @@ SET(QGIS_APP_SRCS
pluginmanager/qgspluginmanager_texts.cpp
pluginmanager/qgsapppluginmanagerinterface.cpp
pluginmanager/qgspluginsortfilterproxymodel.cpp
pluginmanager/qgspluginitemdelegate.cpp
qgsnewspatialitelayerdialog.cpp
)
@ -286,6 +287,7 @@ SET (QGIS_APP_MOC_HDRS
pluginmanager/qgspluginmanager.h
pluginmanager/qgsapppluginmanagerinterface.h
pluginmanager/qgspluginsortfilterproxymodel.h
pluginmanager/qgspluginitemdelegate.h
qgsnewspatialitelayerdialog.h
)

View File

@ -0,0 +1,102 @@
/***************************************************************************
qgspluginitemdelegate.cpp - a QItemDelegate subclass for plugin manager
-------------------
begin : Fri Sep 13 2013, Brighton HF
copyright : (C) 2013 Borys Jurgiel
email : info@borysjurgiel.pl
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgspluginitemdelegate.h"
#include <QPainter>
#include <QFont>
#include <QStyleOptionViewItem>
#include <QModelIndex>
#include <QApplication>
#include "qgspluginsortfilterproxymodel.h"
QgsPluginItemDelegate::QgsPluginItemDelegate( QObject * parent ) : QStyledItemDelegate( parent ) {}
QSize QgsPluginItemDelegate::sizeHint( const QStyleOptionViewItem & option, const QModelIndex & index ) const
{
Q_UNUSED( option );
Q_UNUSED( index );
return QSize( 20, 20 );
}
void QgsPluginItemDelegate::paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const
{
painter->save();
painter->setRenderHint( QPainter::SmoothPixmapTransform );
QStyle *style = QApplication::style();
// Draw the background
style->drawPrimitive( QStyle::PE_PanelItemViewItem, &option, painter, NULL );
// Draw the checkbox
if ( index.flags() & Qt::ItemIsUserCheckable )
{
QStyleOptionButton checkBoxStyle;
checkBoxStyle.rect = option.rect;
if ( index.data( Qt::CheckStateRole ).toBool() )
{
checkBoxStyle.state = QStyle::State_On|QStyle::State_Enabled;
}
else
{
checkBoxStyle.state = QStyle::State_Off|QStyle::State_Enabled;
}
style->drawControl( QStyle::CE_CheckBox, &checkBoxStyle, painter );
}
// Draw the icon
QPixmap iconPixmap = index.data( Qt::DecorationRole ).value<QPixmap>();
if ( !iconPixmap.isNull() )
{
int iconSize = option.rect.height();
painter->drawPixmap( option.rect.left() + 24 , option.rect.top(), iconSize, iconSize, iconPixmap );
}
// Draw the text
if ( option.state & QStyle::State_Selected )
{
painter->setPen( option.palette.highlightedText().color() );
}
else
{
painter->setPen( option.palette.text().color() );
}
if ( ! index.data( PLUGIN_ERROR_ROLE ).toString().isEmpty() )
{
painter->setPen( Qt::red );
}
if ( ! index.data( PLUGIN_ERROR_ROLE ).toString().isEmpty()
|| index.data( PLUGIN_STATUS_ROLE ).toString() == QString( "upgradeable" )
|| index.data( PLUGIN_STATUS_ROLE ).toString() == QString( "new" ) )
{
QFont font = painter->font();
font.setBold( true );
painter->setFont( font );
}
painter->drawText( option.rect.left() + 48 , option.rect.bottom() - 3 , index.data( Qt::DisplayRole ).toString() );
painter->restore();
}

View File

@ -0,0 +1,34 @@
/***************************************************************************
qgspluginitemdelegate.h - a QItemDelegate subclass for plugin manager
-------------------
begin : Fri Sep 13 2013, Brighton HF
copyright : (C) 2013 Borys Jurgiel
email : info@borysjurgiel.pl
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSPLUGINITEMDELEGATE_H
#define QGSPLUGINITEMDELEGATE_H
#include <QStyledItemDelegate>
/**
* A custom model/view delegate that can eithe display checkbox or empty space for proprer text alignment
*/
class QgsPluginItemDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
QgsPluginItemDelegate( QObject * parent = 0 );
QSize sizeHint( const QStyleOptionViewItem & theOption, const QModelIndex & theIndex ) const;
void paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const;
};
#endif //QGSPLUGINITEMDELEGATE_H

View File

@ -39,6 +39,7 @@
#include "qgspluginmanager.h"
#include "qgisplugin.h"
#include "qgslogger.h"
#include "qgspluginitemdelegate.h"
// Do we need this?
// #define TESTLIB
@ -87,6 +88,7 @@ QgsPluginManager::QgsPluginManager( QWidget * parent, bool pluginsAreEnabled, Qt
mModelProxy->setDynamicSortFilter( true );
mModelProxy->sort( 0, Qt::AscendingOrder );
vwPlugins->setModel( mModelProxy );
vwPlugins->setItemDelegate( new QgsPluginItemDelegate( vwPlugins ) );
vwPlugins->setFocus();
// Preset widgets
@ -493,29 +495,15 @@ void QgsPluginManager::reloadModelData()
if ( QFileInfo( iconPath ).isFile() )
{
mypDetailItem->setIcon( QPixmap( iconPath ) );
mypDetailItem->setData( QPixmap( iconPath ), Qt::DecorationRole );
}
else
{
mypDetailItem->setIcon( QPixmap( QgsApplication::defaultThemePath() + "/plugin.png" ) );
mypDetailItem->setData( QPixmap( QgsApplication::defaultThemePath() + "/plugin.png" ), Qt::DecorationRole );
}
mypDetailItem->setEditable( false );
// set item display style
if ( ! it->value( "error" ).isEmpty() )
{
QBrush brush = mypDetailItem->foreground();
brush.setColor( Qt::red );
mypDetailItem->setForeground( brush );
}
if ( ! it->value( "error" ).isEmpty() || it->value( "status" ) == "upgradeable" || it->value( "status" ) == "new" )
{
QFont font = mypDetailItem->font();
font.setBold( true );
mypDetailItem->setFont( font );
}
// Set checkable if the plugin is installed and not disabled due to incompatibility.
// Broken plugins are checkable to to allow disabling them
mypDetailItem->setCheckable( it->value( "installed" ) == "true" && it->value( "error" ) != "incompatible" );
@ -552,6 +540,7 @@ void QgsPluginManager::reloadModelData()
if ( hasReinstallablePlugins() ) mModelPlugins->appendRow( createSpacerItem( tr( "Reinstallable", "category: plugins that are installed and available" ) , "installedZ" ) );
if ( hasUpgradeablePlugins() ) mModelPlugins->appendRow( createSpacerItem( tr( "Upgradeable", "category: plugins that are installed and there is a newer version available" ), "upgradeableZ" ) );
if ( hasNewerPlugins() ) mModelPlugins->appendRow( createSpacerItem( tr( "Downgradeable", "category: plugins that are installed and there is an OLDER version available" ), "newerZ" ) );
if ( hasAvailablePlugins() ) mModelPlugins->appendRow( createSpacerItem( tr( "Installable", "category: plugins that are available for installation" ), "not installedZ" ) );
}
updateTabTitle();
@ -559,10 +548,10 @@ void QgsPluginManager::reloadModelData()
buttonUpgradeAll->setEnabled( hasUpgradeablePlugins() );
// Disable tabs that are empty because of no suitable plugins in the model.
mOptionsListWidget->item( 1 )->setHidden( ! hasAvailablePlugins() );
mOptionsListWidget->item( 2 )->setHidden( ! hasUpgradeablePlugins() );
mOptionsListWidget->item( 3 )->setHidden( ! hasNewPlugins() );
mOptionsListWidget->item( 4 )->setHidden( ! hasInvalidPlugins() );
mOptionsListWidget->item( PLUGMAN_TAB_NOT_INSTALLED )->setHidden( ! hasAvailablePlugins() );
mOptionsListWidget->item( PLUGMAN_TAB_UPGRADEABLE )->setHidden( ! hasUpgradeablePlugins() );
mOptionsListWidget->item( PLUGMAN_TAB_NEW )->setHidden( ! hasNewPlugins() );
mOptionsListWidget->item( PLUGMAN_TAB_INVALID )->setHidden( ! hasInvalidPlugins() );
}
@ -973,27 +962,32 @@ void QgsPluginManager::setCurrentTab( int idx )
QString tabTitle;
switch ( idx )
{
case 0:
case PLUGMAN_TAB_ALL:
// all (statuses ends with Z are for spacers to always sort properly)
acceptedStatuses << "installed" << "not installed" << "orphan" << "newer" << "upgradeable" << "not installedZ" << "installedZ" << "upgradeableZ" << "orphanZ" << "newerZZ" << "" ;
tabTitle = "all_plugins";
break;
case PLUGMAN_TAB_INSTALLED:
// installed (statuses ends with Z are for spacers to always sort properly)
acceptedStatuses << "installed" << "orphan" << "newer" << "upgradeable" << "installedZ" << "upgradeableZ" << "orphanZ" << "newerZZ" << "" ;
tabTitle = "installed_plugins";
break;
case 1:
case PLUGMAN_TAB_NOT_INSTALLED:
// not installed (get more)
acceptedStatuses << "not installed" << "new" ;
tabTitle = "get_more_plugins";
tabTitle = "not_installed_plugins";
break;
case 2:
case PLUGMAN_TAB_UPGRADEABLE:
// upgradeable
acceptedStatuses << "upgradeable" ;
tabTitle = "upgradeable_plugins";
break;
case 3:
case PLUGMAN_TAB_NEW:
// new
acceptedStatuses << "new" ;
tabTitle = "new_plugins";
break;
case 4:
case PLUGMAN_TAB_INVALID:
// invalid
acceptedStatuses << "invalid" ;
tabTitle = "invalid_plugins";

View File

@ -30,6 +30,13 @@
#include "qgspythonutils.h"
#include "qgspluginsortfilterproxymodel.h"
const int PLUGMAN_TAB_ALL = 0;
const int PLUGMAN_TAB_INSTALLED = 1;
const int PLUGMAN_TAB_NOT_INSTALLED = 2;
const int PLUGMAN_TAB_UPGRADEABLE = 3;
const int PLUGMAN_TAB_NEW = 4;
const int PLUGMAN_TAB_INVALID = 5;
/*!
* \brief Plugin manager for browsing, (un)installing and (un)loading plugins
@author Gary Sherman

View File

@ -8,22 +8,39 @@ void QgsPluginManager::initTabDescriptions()
if ( !mTabDescriptions.isEmpty() )
return;
mTabDescriptions.insert( "installed_plugins", tr( "<h3>Installed Plugins</h3>\
mTabDescriptions.insert( "all_plugins", tr( "<h3>All Plugins</h3>\
\
<p>\
On the left you see the list of <b>installed plugins</b> on your system. Both python and cpp \
plugins are listed. Some plugins come with your QGIS installation while most of\
them are made available via the plugin repositories.\
On the left you see the list of all plugins available for your QGIS, both installed and available for download. \
Some plugins come with your QGIS installation while most of them are made available via the plugin repositories.\
</p>\
\
<p>\
You can temporarily enable or disable a plugin.\
To <i>enable</i> or <i>disable</i> a plugin,\
click its checkbox or doubleclick its name...\
To <i>enable</i> or <i>disable</i> a plugin, click its checkbox or doubleclick its name...\
</p>\
\
<p>\
Plugins showing in <span style='color:red'>red</span> are not loaded because there is a problem. Consult the \
'Invalid' tab to see more details, or to reinstall or uninstall this plugin.\
Plugins showing in <span style='color:red'>red</span> are not loaded because there is a problem. They are also listed \
on the 'Invalid' tab. Click on the plugin name to see more details, or to reinstall or uninstall this plugin.\
</p>\
" ) );
mTabDescriptions.insert( "installed_plugins", tr( "<h3>Installed Plugins</h3>\
\
<p>\
Here you only see plugins <b>installed on your QGIS</b>.\
</p>\
<p>\
Click on the name to see details. \
</p>\
<p>\
Click the checkbox or doubleclick the name to <i>activate</i> or <i>deactivate</i> the plugin.\
</p>\
<p>\
You can change the sorting via the context menu (right click).\
</p>\
" ) );
@ -40,7 +57,7 @@ plugins are available in the repositories.\
mTabDescriptions.insert( "get_more_plugins", tr( "<h3>Get more plugins</h3>\
mTabDescriptions.insert( "not_installed_plugins", tr( "<h3>Not installed plugins</h3>\
\
<p>\
Here you see the list of all plugins available in the repositories, but which are <b>not yet installed</b>.\

View File

@ -32,7 +32,7 @@ bool QgsPluginSortFilterProxyModel::filterAcceptsRow( int sourceRow, const QMode
{
// it's a status spacer.
// TODO: the condition below is only suitable for status spacers
return ( filterByStatus( inx ) && mAcceptedStatuses.count() > 1 && sourceModel()->data( inx, SPACER_ROLE ).toString() == mAcceptedSpacers );
return ( filterByStatus( inx ) && mAcceptedStatuses.count() > 2 && sourceModel()->data( inx, SPACER_ROLE ).toString() == mAcceptedSpacers );
}
return ( filterByStatus( inx ) && sourceModel()->data( inx, filterRole() ).toString().contains( filterRegExp() ) );

View File

@ -104,6 +104,15 @@
<property name="wordWrap">
<bool>true</bool>
</property>
<item>
<property name="text">
<string>All</string>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/propertyicons/plugins.svg</normaloff>:/images/themes/default/propertyicons/plugins.svg</iconset>
</property>
</item>
<item>
<property name="text">
<string>Installed</string>
@ -121,14 +130,14 @@
</item>
<item>
<property name="text">
<string>Get more</string>
<string>Not installed</string>
</property>
<property name="toolTip">
<string>Not installed plugins available for download</string>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/propertyicons/plugins.svg</normaloff>:/images/themes/default/propertyicons/plugins.svg</iconset>
<normaloff>:/images/themes/default/propertyicons/plugin.svg</normaloff>:/images/themes/default/propertyicons/plugin.svg</iconset>
</property>
<property name="flags">
<set>ItemIsSelectable|ItemIsEnabled</set>
@ -556,8 +565,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>547</width>
<height>748</height>
<width>352</width>
<height>758</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_10">