Skip to content
Permalink
Browse files
Created a custom view delegate for displaying in lists like the plugi…
…n manager and the grass toolbox.

The delegate allows displaying a title (in bold) and a description underneath it (in normal font), without needing to resort to using tables & columns. The delegate currently works in two modes:
1) Direct rendering of item onto a painter
2) Renderng the item via a qgsdetaileditemwidget (disabled for not as its experimental)
THe qgsdetailed item data class is a new qvariant type that can be used to pass title, description etc between the model and the view.


git-svn-id: http://svn.osgeo.org/qgis/trunk@8463 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
timlinux committed May 19, 2008
1 parent 172c20e commit 9b3f088
Show file tree
Hide file tree
Showing 6 changed files with 381 additions and 0 deletions.
@@ -0,0 +1,46 @@
/***************************************************************************
qgsdetailedlistdata.cpp - A data represenation for a rich QItemData subclass
-------------------
begin : Sat May 17 2008
copyright : (C) 2008 Tim Sutton
email : tim@linfiniti.com
***************************************************************************/

/***************************************************************************
* *
* 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. *
* *
***************************************************************************/
/* $Id:$ */

#include "qgsdetaileditemdata.h"
QgsDetailedItemData::QgsDetailedItemData()
{
}

QgsDetailedItemData::~QgsDetailedItemData()
{
}

void QgsDetailedItemData::setTitle(QString theTitle)
{
mTitle=theTitle;
}

void QgsDetailedItemData::setDetail(QString theDetail)
{
mDetail=theDetail;
}

QString QgsDetailedItemData::title()
{
return mTitle;
}

QString QgsDetailedItemData::detail()
{
return mDetail;
}
@@ -0,0 +1,47 @@
/***************************************************************************
qgsdetaileditemdata.h - A data represenation for a rich QItemData subclass
-------------------
begin : Sat May 17 2008
copyright : (C) 2008 Tim Sutton
email : tim@linfiniti.com
***************************************************************************/

/***************************************************************************
* *
* 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. *
* *
***************************************************************************/
/* $Id:$ */
#ifndef QGSDETAILEDITEMDATA_H
#define QGSDETAILEDITEMDATA_H


#include <QMetaType>
#include <QString>

/** This class is the data only representation of a
* QgsDetailedItemWidget, designed to be used in custom views.
*/
class QgsDetailedItemData
{
public:
QgsDetailedItemData();
~QgsDetailedItemData();
void setTitle(QString theTitle);
void setDetail(QString theDetail);
QString title();
QString detail();
private:
QString mTitle;
QString mDetail;
QString mLibraryName;
bool mCheckBoxEnabled;
};

// Make QVariant aware of this data type (see qtdocs star
// rating delegate example for more details)
Q_DECLARE_METATYPE(QgsDetailedItemData)
#endif //QGSDETAILEDITEMDATA_H
@@ -0,0 +1,167 @@
/***************************************************************************
qgsdetailedlistwidget.cpp - A rich QItemDelegate subclass
-------------------
begin : Sat May 17 2008
copyright : (C) 2008 Tim Sutton
email : tim@linfiniti.com
***************************************************************************/

/***************************************************************************
* *
* 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. *
* *
***************************************************************************/
/* $Id:$ */

#include "qgsdetaileditemdelegate.h"
#include "qgsdetaileditemwidget.h"
#include "qgsdetaileditemdata.h"
#include <QPainter>
#include <QFont>
#include <QFontMetrics>
#include <QStyleOptionViewItem>
#include <QModelIndex>
#include <QCheckBox>
#include <QLinearGradient>
QgsDetailedItemDelegate::QgsDetailedItemDelegate(QObject * parent) :
QAbstractItemDelegate(parent),
mpWidget(new QgsDetailedItemWidget()),
mpCheckBox(new QCheckBox())

{
mpCheckBox->resize(16,16);
}

QgsDetailedItemDelegate::~QgsDetailedItemDelegate()
{
delete mpCheckBox;
delete mpWidget;
}

void QgsDetailedItemDelegate::paint(QPainter * thepPainter,
const QStyleOptionViewItem & theOption,
const QModelIndex & theIndex) const
{
if (qVariantCanConvert<QgsDetailedItemData>(theIndex.data(Qt::UserRole)))
{
QgsDetailedItemData myData =
qVariantValue<QgsDetailedItemData>(theIndex.data(Qt::UserRole));
bool myCheckState = theIndex.model()->data(theIndex, Qt::CheckStateRole).toBool();
mpWidget->setChecked(myCheckState);
mpWidget->setData(myData);
mpWidget->resize(theOption.rect.width(),mpWidget->height());
mpWidget->setAutoFillBackground(false);
mpWidget->show();
mpWidget->repaint();

if (theOption.state & QStyle::State_Selected)
{
QColor myColor1 = theOption.palette.highlight();
QColor myColor2 = myColor1;
myColor2 = myColor2.lighter();
QLinearGradient myGradient(QPointF(0,theOption.rect.y()),
QPointF(0,theOption.rect.y() + mpWidget->height()));
myGradient.setColorAt(0, myColor1);
myGradient.setColorAt(0.1, myColor2);
myGradient.setColorAt(0.5, myColor1);
myGradient.setColorAt(0.9, myColor2);
myGradient.setColorAt(1, myColor2);
thepPainter->fillRect(theOption.rect, QBrush(myGradient));
}
QPixmap myPixmap(mpWidget->size());
mpWidget->render(&myPixmap);
thepPainter->drawPixmap(theOption.rect.x(),
theOption.rect.y(),
myPixmap);
}
else
{
// After painting we need to restore the painter to its original state
thepPainter->save();
//
// Get the strings and check box properties
//
QString myString = theIndex.model()->data(theIndex, Qt::DisplayRole).toString();
QString myDetailString = theIndex.model()->data(theIndex, Qt::UserRole).toString();
bool myCheckState = theIndex.model()->data(theIndex, Qt::CheckStateRole).toBool();
mpCheckBox->setChecked(myCheckState);
QPixmap myPixmap(mpCheckBox->size());
mpCheckBox->render(&myPixmap); //we will draw this onto the widget further down

//
// Calculate the widget height and other metrics
//
QFont myFont = theOption.font;
QFont myBoldFont = myFont;
myBoldFont.setBold(true);
myBoldFont.setPointSize(myFont.pointSize() + 3);
QFontMetrics myMetrics(myBoldFont);
int myVerticalSpacer = 3; //spacing between title and description
int myHorizontalSpacer = 5; //spacing between checkbox / icon and description
int myTextStartX = theOption.rect.x() + myPixmap.width() + myHorizontalSpacer;
int myHeight = myMetrics.height() + myVerticalSpacer;

//
// Draw the item background with a gradient if its highlighted
//
if (theOption.state & QStyle::State_Selected)
{
QColor myColor1 = theOption.palette.highlight();
QColor myColor2 = myColor1;
myColor2 = myColor2.lighter();
int myHeight = myMetrics.height() + myVerticalSpacer;
QLinearGradient myGradient(QPointF(0,theOption.rect.y()),
QPointF(0,theOption.rect.y() + myHeight*2));
myGradient.setColorAt(0, myColor1);
myGradient.setColorAt(0.1, myColor2);
myGradient.setColorAt(0.5, myColor1);
myGradient.setColorAt(0.9, myColor2);
myGradient.setColorAt(1, myColor2);
thepPainter->fillRect(theOption.rect, QBrush(myGradient));
}

//
// Draw the checkbox
//
thepPainter->drawPixmap(theOption.rect.x(),
theOption.rect.y() + mpCheckBox->height(),
myPixmap);

//
// Draw the title and description
//
thepPainter->setFont(myBoldFont);
thepPainter->drawText( myTextStartX ,theOption.rect.y() + myHeight, myString);
thepPainter->setFont(myFont); //return to original font set by client
thepPainter->drawText( myTextStartX,
theOption.rect.y() + (myHeight *2) - myVerticalSpacer,
myDetailString);
thepPainter->restore();
}
}

QSize QgsDetailedItemDelegate::sizeHint(
const QStyleOptionViewItem & theOption,
const QModelIndex & theIndex ) const
{
if (qVariantCanConvert<QgsDetailedItemData>(theIndex.data(Qt::UserRole)))
{
return QSize(378,mpWidget->height());
}
else // fall back to hand calculated & hand drawn item
{
QFont myFont = theOption.font;
QFont myBoldFont = myFont;
myBoldFont.setBold(true);
myBoldFont.setPointSize(myFont.pointSize() + 3);
QFontMetrics myMetrics(myBoldFont);
int myVerticalSpacer = 3; //spacing between title and description
int myHorizontalSpacer = 5; //spacing between checkbox / icon and description
int myHeight = myMetrics.height() + myVerticalSpacer;
return QSize(50,
myHeight *2 + myVerticalSpacer);
}
}
@@ -0,0 +1,44 @@
/***************************************************************************
qgsdetaileditemdelegate.h - A rich QItemDelegate subclass
-------------------
begin : Sat May 17 2008
copyright : (C) 2008 Tim Sutton
email : tim@linfiniti.com
***************************************************************************/

/***************************************************************************
* *
* 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. *
* *
***************************************************************************/
/* $Id:$ */
#ifndef QGSDETAILEDITEMDELEGATE_H
#define QGSDETAILEDITEMDELEGATE_H

#include <QAbstractItemDelegate>
#include <QString>

class QCheckBox;
class QgsDetailedItemWidget;

class QgsDetailedItemDelegate :
public QAbstractItemDelegate
{
Q_OBJECT;
public:
QgsDetailedItemDelegate(QObject * parent = 0);
~QgsDetailedItemDelegate();
void paint(QPainter * thePainter,
const QStyleOptionViewItem & theOption,
const QModelIndex & theIndex) const;
QSize sizeHint( const QStyleOptionViewItem & theOption,
const QModelIndex & theIndex ) const;
private:
QgsDetailedItemWidget * mpWidget;
QCheckBox * mpCheckBox;
};

#endif //QGSDETAILEDITEMDELEGATE_H
@@ -0,0 +1,40 @@
/***************************************************************************
qgsdetailedlistwidget.cpp - A rich QItemWidget subclass
-------------------
begin : Sat May 17 2008
copyright : (C) 2008 Tim Sutton
email : tim@linfiniti.com
***************************************************************************/

/***************************************************************************
* *
* 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. *
* *
***************************************************************************/
/* $Id:$ */

#include "qgsdetaileditemwidget.h"
QgsDetailedItemWidget::QgsDetailedItemWidget(QWidget * parent) :
QWidget(parent)

{
setupUi(this);
}

QgsDetailedItemWidget::~QgsDetailedItemWidget()
{
}

void QgsDetailedItemWidget::setData(QgsDetailedItemData theData)
{
lblTitle->setText(theData.title());
tbDetail->setText(theData.detail());
}

void QgsDetailedItemWidget::setChecked(bool theFlag)
{
cbx->setChecked(theFlag);
}
@@ -0,0 +1,37 @@
/***************************************************************************
qgsdetaileditemwidget.h - A rich QItemWidget subclass
-------------------
begin : Sat May 17 2008
copyright : (C) 2008 Tim Sutton
email : tim@linfiniti.com
***************************************************************************/

/***************************************************************************
* *
* 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. *
* *
***************************************************************************/
/* $Id:$ */
#ifndef QGSDETAILEDITEMWIDGET_H
#define QGSDETAILEDITEMWIDGET_H

#include <ui_qgsdetaileditemwidgetbase.h>
#include <qgsdetaileditemdata.h>

class QgsDetailedItemWidget :
public QWidget, private Ui::QgsDetailedItemWidgetBase
{
Q_OBJECT;
public:
QgsDetailedItemWidget(QWidget * parent = 0);
~QgsDetailedItemWidget();
void setData(QgsDetailedItemData theData);
void setChecked(bool theFlag);
private:
QgsDetailedItemData mData;
};

#endif //QGSDETAILEDITEMWIDGET_H

0 comments on commit 9b3f088

Please sign in to comment.