1/* This file is part of the KDE libraries
2 Copyright (C) 2006,2007 Andreas Hartmetz (ahartmetz@gmail.com)
3 Copyright (C) 2008 Urs Wolfer (uwolfer @ kde.org)
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
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 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21
22#ifndef KEXTENDABLEITEMDELEGATE_H
23#define KEXTENDABLEITEMDELEGATE_H
24
25#include <QtGui/QStyledItemDelegate>
26
27#include <kdeui_export.h>
28
29/**
30 * This delegate makes it possible to display an arbitrary QWidget ("extender") that spans all columns below a line of items.
31 * The extender will logically belong to a column in the row above it.
32 *
33 * It is your responsibility to devise a way to trigger extension and contraction of items, by calling
34 * extendItem() and contractItem(). You can e.g. reimplement itemActivated() and similar functions.
35 *
36 * @warning extendItem() reparents the provided widget @a extender to the
37 * viewport of the itemview it belongs to. The @a extender is destroyed when
38 * you call contractItem() for the associated index. If you fail to do that
39 * and the associated item gets deleted you're in trouble. It remains as a
40 * visible artefact in your treeview. Additionally when closing your
41 * application you get an assertion failure from KExtendableItemDelegate. Make
42 * sure that you always call contractItem for indices before you delete them.
43 *
44 * @author Andreas Hartmetz <ahartmetz@gmail.com>
45 *
46 * @since 4.1
47 */
48
49class QAbstractItemView;
50
51class KDEUI_EXPORT KExtendableItemDelegate : public QStyledItemDelegate {
52 Q_OBJECT
53
54public:
55 enum auxDataRoles {ShowExtensionIndicatorRole = Qt::UserRole + 200};
56
57 /**
58 * Create a new KExtendableItemDelegate that belongs to @p parent. In contrast to generic
59 * QAbstractItemDelegates, an instance of this class can only ever be the delegate for one
60 * instance of af QAbstractItemView subclass.
61 */
62 KExtendableItemDelegate(QAbstractItemView *parent);
63 virtual ~KExtendableItemDelegate();
64
65 /**
66 * Re-implemented for internal reasons. API not affected.
67 */
68 virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
69
70 /**
71 * Re-implemented for internal reasons. API not affected.
72 */
73 virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
74
75 /**
76 * Insert the @p extender for item at @p index into the view.
77 * If you need a parent for the extender at construction time, use the itemview's viewport().
78 * The delegate takes ownership of the extender; the extender will also be reparented and
79 * resized to the viewport.
80 */
81 void extendItem(QWidget *extender, const QModelIndex &index);
82
83 /**
84 * Remove the extender of item at @p index from the view. The extender widget
85 * will be deleted.
86 */
87 void contractItem(const QModelIndex &index);
88
89 /**
90 * Close all extenders and delete all extender widgets.
91 */
92 void contractAll();
93
94 /**
95 * Return whether there is an extender that belongs to @p index.
96 */
97 bool isExtended(const QModelIndex &index) const;
98
99 /**
100 * Reimplement this function to adjust the internal geometry of the extender.
101 * The external geometry of the extender will be set by the delegate.
102 */
103 virtual void updateExtenderGeometry(QWidget *extender, const QStyleOptionViewItem &option, const QModelIndex &index) const;
104
105Q_SIGNALS:
106 /**
107 * This signal indicates that the item at @p index was extended with @p extender.
108 */
109 void extenderCreated(QWidget *extender, const QModelIndex &index);
110
111 /**
112 * This signal indicates that the @p extender belonging to @p index has emitted the destroyed() signal.
113 */
114 void extenderDestroyed(QWidget *extender, const QModelIndex &index);
115
116protected:
117 /**
118 * Reimplement this function to fine-tune the position of the extender. @p option.rect will be a rectangle
119 * that is as wide as the viewport and as high as the usual item height plus the extender size hint's height.
120 * Its upper left corner will be at the upper left corner of the usual item.
121 * You can place the returned rectangle of this function anywhere inside that area.
122 */
123 QRect extenderRect(QWidget *extender, const QStyleOptionViewItem &option, const QModelIndex &index) const;
124
125 /**
126 * The pixmap that is displayed to extend an item. @p pixmap must have the same size as the pixmap in setContractPixmap.
127 */
128 void setExtendPixmap(const QPixmap &pixmap);
129
130 /**
131 * The pixmap that is displayed to contract an item. @p pixmap must have the same size as the pixmap in setExtendPixmap.
132 */
133 void setContractPixmap(const QPixmap &pixmap);
134
135 /**
136 * Return the pixmap that is displayed to extend an item.
137 */
138 QPixmap extendPixmap();
139
140 /**
141 * Return the pixmap that is displayed to contract an item.
142 */
143 QPixmap contractPixmap();
144
145
146private:
147 class Private;
148 Private *const d;
149
150 Q_PRIVATE_SLOT(d, void _k_extenderDestructionHandler(QObject *destroyed))
151 Q_PRIVATE_SLOT(d, void _k_verticalScroll())
152};
153#endif // KEXTENDABLEITEMDELEGATE_H
154