Skip to content

Commit

Permalink
introduced new plugin metadata entry "category". Show hint based on
Browse files Browse the repository at this point in the history
category in Plugin Manager and update all core plugins respectively
  • Loading branch information
alexbruy committed Dec 20, 2011
1 parent 8eecfc3 commit 9f8f86d
Show file tree
Hide file tree
Showing 41 changed files with 386 additions and 79 deletions.
2 changes: 2 additions & 0 deletions python/plugins/GdalTools/__init__.py
Expand Up @@ -21,6 +21,8 @@ def name():
return "GdalTools"
def description():
return "Integrate gdal tools into qgis"
def category():
return "Raster"
def version():
return "Version 1.2.29"
def qgisMinimumVersion():
Expand Down
23 changes: 13 additions & 10 deletions python/plugins/fTools/__init__.py
Expand Up @@ -29,23 +29,26 @@
#---------------------------------------------------------------------

def name():
return "fTools"
return "fTools"

def description():
return "Tools for vector data analysis and management"
return "Tools for vector data analysis and management"

def category():
return "Vector"

def version():
return "0.6.1"
return "0.6.1"

def qgisMinimumVersion():
return "1.4"
return "1.4"

def icon():
return "icons/logo_small.png"
return "icons/logo_small.png"

def authorName():
return "Carson J. Q. Farmer"
return "Carson J. Q. Farmer"

def classFactory( iface ):
from fTools import fToolsPlugin
return fToolsPlugin( iface )
from fTools import fToolsPlugin
return fToolsPlugin( iface )
18 changes: 10 additions & 8 deletions python/plugins/mapserver_export/__init__.py
Expand Up @@ -19,19 +19,21 @@
This script initializes the plugin, making it known to QGIS.
"""

def name():
return "MapServer Export"
def name():
return "MapServer Export"
def description():
return "Export a saved QGIS project file to a MapServer map file"
def version():
return "Version 0.4.3"
def qgisMinimumVersion():
def category():
return "Plugins"
def version():
return "Version 0.4.3"
def qgisMinimumVersion():
return "1.0"
def icon():
return "mapserver_export.png"
def authorName():
return "Gary E. Sherman"
def classFactory(iface):
def classFactory(iface):
# load MapServerExport class from file mapserverexport.py
from mapserverexport import MapServerExport
return MapServerExport(iface)
from mapserverexport import MapServerExport
return MapServerExport(iface)
11 changes: 10 additions & 1 deletion python/plugins/osm/__init__.py
Expand Up @@ -33,6 +33,15 @@ def description():
return "Viewer and editor for OpenStreetMap data"


def category():
"""Function returns category of this plugin.
@return category of this plugin.
"""

return "Plugins"


def version():
"""Function returns version of this plugin.
Expand Down Expand Up @@ -64,5 +73,5 @@ def classFactory(iface):

from OsmPlugin import OsmPlugin
# return object of our plugin with reference to QGIS interface as the only argument
return OsmPlugin(iface)
return OsmPlugin(iface)

3 changes: 3 additions & 0 deletions python/plugins/plugin_installer/__init__.py
Expand Up @@ -20,6 +20,9 @@ def version():
def description():
return "Downloads and installs QGIS python plugins"

def category():
return "Plugins"

def qgisMinimumVersion():
return "1.0"

Expand Down
5 changes: 5 additions & 0 deletions src/app/qgspluginitem.cpp
Expand Up @@ -32,6 +32,11 @@ QString QgsPluginItem::description()
return m_description;
}

QString QgsPluginItem::category()
{
return m_category;
}

QString QgsPluginItem::fullPath()
{
return m_fullPath;
Expand Down
2 changes: 2 additions & 0 deletions src/app/qgspluginitem.h
Expand Up @@ -28,13 +28,15 @@ class QgsPluginItem
QgsPluginItem( QString name = 0, QString fullPath = 0, QString type = 0, bool python = false );
QString name();
QString description();
QString category();
QString fullPath();
QString type();
bool isPython();
~QgsPluginItem();
private:
QString m_name;
QString m_description;
QString m_category;
QString m_fullPath;
//! Plugin type (either ui or maplayer)
QString m_type;
Expand Down
20 changes: 20 additions & 0 deletions src/app/qgspluginmanager.cpp
Expand Up @@ -171,12 +171,19 @@ void QgsPluginManager::getPythonPluginDescriptions()
// 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 )
Expand All @@ -196,6 +203,7 @@ void QgsPluginManager::getPythonPluginDescriptions()
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 );
Expand Down Expand Up @@ -308,6 +316,7 @@ void QgsPluginManager::getPluginDescriptions()
// 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" ) );

Expand All @@ -328,6 +337,14 @@ void QgsPluginManager::getPluginDescriptions()
{
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() );
Expand All @@ -350,6 +367,8 @@ void QgsPluginManager::getPluginDescriptions()

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();
Expand All @@ -363,6 +382,7 @@ void QgsPluginManager::getPluginDescriptions()
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
Expand Down
10 changes: 7 additions & 3 deletions src/app/qgspluginregistry.cpp
Expand Up @@ -36,6 +36,7 @@
typedef QgisPlugin *create_ui( QgisInterface * qI );
typedef QString name_t();
typedef QString description_t();
typedef QString category_t();
typedef int type_t();


Expand Down Expand Up @@ -455,12 +456,13 @@ bool QgsPluginRegistry::checkCppPlugin( QString pluginFullPath )

name_t * myName = ( name_t * ) cast_to_fptr( myLib.resolve( "name" ) );
description_t * myDescription = ( description_t * ) cast_to_fptr( myLib.resolve( "description" ) );
category_t * myCategory = ( category_t * ) cast_to_fptr( myLib.resolve( "category" ) );
version_t * myVersion = ( version_t * ) cast_to_fptr( myLib.resolve( "version" ) );

if ( myName && myDescription && myVersion )
if ( myName && myDescription && myVersion && myCategory )
return true;

QgsDebugMsg( "Failed to get name, description, or type for " + myLib.fileName() );
QgsDebugMsg( "Failed to get name, description, category or type for " + myLib.fileName() );
return false;
}

Expand All @@ -471,7 +473,7 @@ bool QgsPluginRegistry::checkPythonPlugin( QString packageName )
if ( !mPythonUtils->loadPlugin( packageName ) )
return false;

QString pluginName, description, version;
QString pluginName, description, category, version;

// get information from the plugin
// if there are some problems, don't continue with metadata retreival
Expand All @@ -481,6 +483,8 @@ bool QgsPluginRegistry::checkPythonPlugin( QString packageName )
description = mPythonUtils->getPluginMetadata( packageName, "description" );
if ( description != "__error__" )
version = mPythonUtils->getPluginMetadata( packageName, "version" );
// for Python plugins category still optional, by default used "Plugins" category
//category = mPythonUtils->getPluginMetadata( packageName, "category" );
}

if ( pluginName == "__error__" || description == "__error__" || version == "__error__" )
Expand Down
13 changes: 13 additions & 0 deletions src/gui/qgsdetaileditemdata.cpp
Expand Up @@ -36,18 +36,26 @@ void QgsDetailedItemData::setDetail( const QString theDetail )
mDetail = theDetail;
}

void QgsDetailedItemData::setCategory( const QString theCategory )
{
mCategory = theCategory;
}

void QgsDetailedItemData::setIcon( const QPixmap theIcon )
{
mPixmap = theIcon;
}

void QgsDetailedItemData::setCheckable( const bool theFlag )
{
mCheckableFlag = theFlag;
}

void QgsDetailedItemData::setChecked( const bool theFlag )
{
mCheckedFlag = theFlag;
}

void QgsDetailedItemData::setRenderAsWidget( const bool theFlag )
{
mRenderAsWidgetFlag = theFlag;
Expand All @@ -63,6 +71,11 @@ QString QgsDetailedItemData::detail() const
return mDetail;
}

QString QgsDetailedItemData::category() const
{
return mCategory;
}

QPixmap QgsDetailedItemData::icon() const
{
return mPixmap;
Expand Down
3 changes: 3 additions & 0 deletions src/gui/qgsdetaileditemdata.h
Expand Up @@ -33,6 +33,7 @@ class GUI_EXPORT QgsDetailedItemData
~QgsDetailedItemData();
void setTitle( const QString theTitle );
void setDetail( const QString theDetail );
void setCategory( const QString theCategory );
void setIcon( const QPixmap theIcon );
void setCheckable( const bool theFlag );
void setChecked( const bool theFlag );
Expand All @@ -47,6 +48,7 @@ class GUI_EXPORT QgsDetailedItemData

QString title() const;
QString detail() const;
QString category() const;
QPixmap icon() const;
bool isCheckable() const;
bool isChecked() const;
Expand All @@ -56,6 +58,7 @@ class GUI_EXPORT QgsDetailedItemData
private:
QString mTitle;
QString mDetail;
QString mCategory;
QString mLibraryName;
QPixmap mPixmap;
bool mCheckableFlag;
Expand Down
50 changes: 50 additions & 0 deletions src/gui/qgsdetaileditemdelegate.cpp
Expand Up @@ -111,6 +111,7 @@ void QgsDetailedItemDelegate::paintManually( QPainter * thepPainter,

QFontMetrics myTitleMetrics( titleFont( theOption ) );
QFontMetrics myDetailMetrics( detailFont( theOption ) );
QFontMetrics myCategoryMetrics( categoryFont( theOption ) );
int myTextStartX = theOption.rect.x() + horizontalSpacing();
int myTextStartY = theOption.rect.y() + verticalSpacing();
int myHeight = myTitleMetrics.height() + verticalSpacing();
Expand Down Expand Up @@ -200,6 +201,40 @@ void QgsDetailedItemDelegate::paintManually( QPainter * thepPainter,
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


Expand Down Expand Up @@ -246,13 +281,21 @@ int QgsDetailedItemDelegate::height( const QStyleOptionViewItem & theOption,
{
QFontMetrics myTitleMetrics( titleFont( theOption ) );
QFontMetrics myDetailMetrics( detailFont( theOption ) );
QFontMetrics myCategoryMetrics( categoryFont( 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() );
//we don't word wrap the category so its easy to measure
myHeight += myCategoryMetrics.height() + verticalSpacing();
// if category should be wrapped use this code
//~ myList = wordWrap( theData.category(),
//~ myCategoryMetrics,
//~ theOption.rect.width() - ( mpCheckBox->width() + horizontalSpacing() ) );
//~ myHeight += ( myList.count() + 1 ) * ( myCategoryMetrics.height() - verticalSpacing() );
return myHeight;
}

Expand All @@ -263,6 +306,13 @@ QFont QgsDetailedItemDelegate::detailFont( const QStyleOptionViewItem &theOption
return myFont;
}

QFont QgsDetailedItemDelegate::categoryFont( const QStyleOptionViewItem &theOption ) const
{
QFont myFont = theOption.font;
myFont.setBold( true );
return myFont;
}

QFont QgsDetailedItemDelegate::titleFont( const QStyleOptionViewItem &theOption ) const
{
QFont myTitleFont = detailFont( theOption );
Expand Down

0 comments on commit 9f8f86d

Please sign in to comment.