Skip to content

Commit

Permalink
Created a custom view delegate for displaying in lists like the plugi…
Browse files Browse the repository at this point in the history
…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/qgis@8463 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
timlinux committed May 19, 2008
1 parent dd368da commit eedc26b
Show file tree
Hide file tree
Showing 6 changed files with 381 additions and 0 deletions.
46 changes: 46 additions & 0 deletions src/gui/qgsdetaileditemdata.cpp
@@ -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;
}
47 changes: 47 additions & 0 deletions src/gui/qgsdetaileditemdata.h
@@ -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
167 changes: 167 additions & 0 deletions src/gui/qgsdetaileditemdelegate.cpp
@@ -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);
}
}
44 changes: 44 additions & 0 deletions src/gui/qgsdetaileditemdelegate.h
@@ -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
40 changes: 40 additions & 0 deletions src/gui/qgsdetaileditemwidget.cpp
@@ -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);
}
37 changes: 37 additions & 0 deletions src/gui/qgsdetaileditemwidget.h
@@ -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 eedc26b

Please sign in to comment.