Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[Plugin Manager] New tab for all plugins. New class QgsPluginItemDele…
…gate
  • Loading branch information
borysiasty committed Sep 15, 2013
1 parent b49df73 commit c093ab9
Show file tree
Hide file tree
Showing 9 changed files with 207 additions and 42 deletions.
4 changes: 2 additions & 2 deletions python/pyplugin_installer/installer.py
Expand Up @@ -143,12 +143,12 @@ def checkingDone(self):
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) )
Expand Down
2 changes: 2 additions & 0 deletions src/app/CMakeLists.txt
Expand Up @@ -152,6 +152,7 @@ SET(QGIS_APP_SRCS
pluginmanager/qgspluginmanager_texts.cpp
pluginmanager/qgsapppluginmanagerinterface.cpp
pluginmanager/qgspluginsortfilterproxymodel.cpp
pluginmanager/qgspluginitemdelegate.cpp

qgsnewspatialitelayerdialog.cpp
)
Expand Down Expand Up @@ -286,6 +287,7 @@ SET (QGIS_APP_MOC_HDRS
pluginmanager/qgspluginmanager.h
pluginmanager/qgsapppluginmanagerinterface.h
pluginmanager/qgspluginsortfilterproxymodel.h
pluginmanager/qgspluginitemdelegate.h

qgsnewspatialitelayerdialog.h
)
Expand Down
102 changes: 102 additions & 0 deletions src/app/pluginmanager/qgspluginitemdelegate.cpp
@@ -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();
}



34 changes: 34 additions & 0 deletions src/app/pluginmanager/qgspluginitemdelegate.h
@@ -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
46 changes: 20 additions & 26 deletions src/app/pluginmanager/qgspluginmanager.cpp
Expand Up @@ -39,6 +39,7 @@
#include "qgspluginmanager.h"
#include "qgisplugin.h"
#include "qgslogger.h"
#include "qgspluginitemdelegate.h"

// Do we need this?
// #define TESTLIB
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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" );
Expand Down Expand Up @@ -552,17 +540,18 @@ 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();

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() );
}


Expand Down Expand Up @@ -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";
Expand Down
7 changes: 7 additions & 0 deletions src/app/pluginmanager/qgspluginmanager.h
Expand Up @@ -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
Expand Down
35 changes: 26 additions & 9 deletions src/app/pluginmanager/qgspluginmanager_texts.cpp
Expand Up @@ -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>\
" ) );

Expand All @@ -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>.\
Expand Down
2 changes: 1 addition & 1 deletion src/app/pluginmanager/qgspluginsortfilterproxymodel.cpp
Expand Up @@ -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() ) );
Expand Down

0 comments on commit c093ab9

Please sign in to comment.