1
/****************************************************************************
2
* Copyright (C) 2009-2014 by Savoir-Faire Linux *
3
* Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> *
5
* This library is free software; you can redistribute it and/or *
6
* modify it under the terms of the GNU Lesser General Public *
7
* License as published by the Free Software Foundation; either *
8
* version 2.1 of the License, or (at your option) any later version. *
10
* This library is distributed in the hope that it will be useful, *
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
13
* Lesser General Public License for more details. *
15
* You should have received a copy of the GNU General Public License *
16
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
17
***************************************************************************/
18
#include "categorizeddelegate.h"
21
#include <QtGui/QTreeView>
22
#include <QtGui/QPainter>
23
#include <QtGui/QApplication>
24
#include <QtCore/QDebug>
27
static const int TOP_MARGIN = 20;
28
static const int BOTTOM_MARGIN = 7 ;
32
CategorizedDelegate::CategorizedDelegate(QTreeView* widget)
33
: QStyledItemDelegate(widget)
34
, m_LeftMargin(7),m_RightMargin(7),m_pChildDelegate(nullptr),m_pChildChildDelegate(nullptr)
39
CategorizedDelegate::~CategorizedDelegate()
41
if ( m_pChildDelegate ) delete m_pChildDelegate ;
42
if ( m_pChildChildDelegate ) delete m_pChildChildDelegate;
45
///Report category height
46
QSize CategorizedDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const {
47
//Only do it for categories and objects deeper than 1 level, use precalculated values for others
48
if (index.parent().isValid() && !index.parent().parent().isValid() && m_pChildDelegate) {
49
return m_pChildDelegate->sizeHint(option,index);
51
if (index.parent().parent().isValid() && m_pChildChildDelegate) {
52
return m_pChildChildDelegate->sizeHint(option,index);
54
if (!index.parent().isValid()) {
55
//This allow deleted contacts and filtered out categories not to be displayed
56
const bool hasChildren = index.child(0,0).isValid();
60
//If the category has children, then return the real size
61
static const int metric = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameVMargin)*2;
62
QSize sh = QStyledItemDelegate::sizeHint(option, index);
63
sh.rheight() += BOTTOM_MARGIN + (index.row()==0?metric:TOP_MARGIN);
64
sh.rwidth() += m_LeftMargin;
67
return QStyledItemDelegate::sizeHint(option,index);
70
///Draw the category (and the first child)
71
void CategorizedDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
73
Q_ASSERT(index.isValid());
75
if (!option.rect.height())
77
if (!index.parent().isValid()) {
78
QStyleOptionViewItem opt(option);
79
const QRegion cl = painter->clipRegion();
80
painter->setClipRect(opt.rect);
81
drawSimpleCategory(index, 0, opt, painter);
82
painter->setClipRegion(cl);
86
painter->setClipRect(option.rect);
88
if (m_pChildDelegate && !index.parent().parent().isValid())
89
m_pChildDelegate->paint(painter,option,index);
90
else if (m_pChildChildDelegate && index.parent().parent().isValid())
91
m_pChildChildDelegate->paint(painter,option,index);
94
///Set the delagate that are categorized
95
void CategorizedDelegate::setChildDelegate(QStyledItemDelegate* childDelegate)
97
m_pChildDelegate = childDelegate;
100
///Set the categorized delegate own children
101
void CategorizedDelegate::setChildChildDelegate(QStyledItemDelegate* childDelegate)
103
m_pChildChildDelegate = childDelegate;
106
void CategorizedDelegate::drawSimpleCategory(const QModelIndex &index, int sortRole, const QStyleOption &option, QPainter *painter) const
109
//Some theme have internal glow (such as Oxygen)
110
static const int metric = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameVMargin)*2;
112
const QString category = index.model()->data(index, Qt::DisplayRole).toString();
113
painter->setClipping(false);
114
static QPen pen(QApplication::palette().color(QPalette::Disabled,QPalette::Text));
116
painter->setPen(pen);
117
painter->setOpacity(0.3);
118
const int topMargin2 = index.row()==0?metric:TOP_MARGIN;
119
painter->drawLine(0,option.rect.y()+(topMargin2),option.rect.x()+option.rect.width()+option.rect.x(),option.rect.y()+(topMargin2));
120
painter->setOpacity(1);
121
painter->drawText(QRect(metric?1.5*metric:4,option.rect.y()+1+(topMargin2),option.rect.width(),option.rect.height()-1),Qt::AlignLeft | Qt::AlignTop,category);