File indexing completed on 2024-12-01 09:54:11
0001 /* 0002 This file is part of the KDE libraries 0003 SPDX-FileCopyrightText: 2006, 2007 Andreas Hartmetz <ahartmetz@gmail.com> 0004 SPDX-FileCopyrightText: 2008 Urs Wolfer <uwolfer@kde.org> 0005 0006 SPDX-License-Identifier: LGPL-2.0-or-later 0007 */ 0008 0009 #ifndef KEXTENDABLEITEMDELEGATE_H 0010 #define KEXTENDABLEITEMDELEGATE_H 0011 0012 #include <QStyledItemDelegate> 0013 #include <memory> 0014 0015 #include <kitemviews_export.h> 0016 0017 class QAbstractItemView; 0018 0019 /** 0020 * @class KExtendableItemDelegate kextendableitemdelegate.h KExtendableItemDelegate 0021 * 0022 * This delegate makes it possible to display an arbitrary QWidget ("extender") that spans all columns below a line of items. 0023 * The extender will logically belong to a column in the row above it. 0024 * 0025 * It is your responsibility to devise a way to trigger extension and contraction of items, by calling 0026 * extendItem() and contractItem(). You can e.g. reimplement itemActivated() and similar functions. 0027 * 0028 * @warning extendItem() reparents the provided widget @a extender to the 0029 * viewport of the itemview it belongs to. The @a extender is destroyed when 0030 * you call contractItem() for the associated index. If you fail to do that 0031 * and the associated item gets deleted you're in trouble. It remains as a 0032 * visible artefact in your treeview. Additionally when closing your 0033 * application you get an assertion failure from KExtendableItemDelegate. Make 0034 * sure that you always call contractItem for indices before you delete them. 0035 * 0036 * @author Andreas Hartmetz <ahartmetz@gmail.com> 0037 * 0038 * @since 4.1 0039 */ 0040 class KITEMVIEWS_EXPORT KExtendableItemDelegate : public QStyledItemDelegate 0041 { 0042 Q_OBJECT 0043 0044 public: 0045 enum auxDataRoles { 0046 ShowExtensionIndicatorRole = Qt::UserRole + 200, 0047 }; 0048 0049 /** 0050 * Create a new KExtendableItemDelegate that belongs to @p parent. In contrast to generic 0051 * QAbstractItemDelegates, an instance of this class can only ever be the delegate for one 0052 * instance of af QAbstractItemView subclass. 0053 */ 0054 KExtendableItemDelegate(QAbstractItemView *parent); 0055 ~KExtendableItemDelegate() override; 0056 0057 /** 0058 * Re-implemented for internal reasons. API not affected. 0059 */ 0060 QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override; 0061 0062 /** 0063 * Re-implemented for internal reasons. API not affected. 0064 */ 0065 void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; 0066 0067 /** 0068 * Insert the @p extender for item at @p index into the view. 0069 * If you need a parent for the extender at construction time, use the itemview's viewport(). 0070 * The delegate takes ownership of the extender; the extender will also be reparented and 0071 * resized to the viewport. 0072 */ 0073 void extendItem(QWidget *extender, const QModelIndex &index); 0074 0075 /** 0076 * Remove the extender of item at @p index from the view. The extender widget 0077 * will be deleted. 0078 */ 0079 void contractItem(const QModelIndex &index); 0080 0081 /** 0082 * Close all extenders and delete all extender widgets. 0083 */ 0084 void contractAll(); 0085 0086 /** 0087 * Return whether there is an extender that belongs to @p index. 0088 */ 0089 bool isExtended(const QModelIndex &index) const; 0090 0091 /** 0092 * Reimplement this function to adjust the internal geometry of the extender. 0093 * The external geometry of the extender will be set by the delegate. 0094 */ 0095 virtual void updateExtenderGeometry(QWidget *extender, const QStyleOptionViewItem &option, const QModelIndex &index) const; 0096 0097 Q_SIGNALS: 0098 /** 0099 * This signal indicates that the item at @p index was extended with @p extender. 0100 */ 0101 void extenderCreated(QWidget *extender, const QModelIndex &index); 0102 0103 /** 0104 * This signal indicates that the @p extender belonging to @p index has emitted the destroyed() signal. 0105 */ 0106 void extenderDestroyed(QWidget *extender, const QModelIndex &index); 0107 0108 protected: 0109 /** 0110 * Reimplement this function to fine-tune the position of the extender. @p option.rect will be a rectangle 0111 * that is as wide as the viewport and as high as the usual item height plus the extender size hint's height. 0112 * Its upper left corner will be at the upper left corner of the usual item. 0113 * You can place the returned rectangle of this function anywhere inside that area. 0114 */ 0115 QRect extenderRect(QWidget *extender, const QStyleOptionViewItem &option, const QModelIndex &index) const; 0116 0117 /** 0118 * The pixmap that is displayed to extend an item. @p pixmap must have the same size as the pixmap in setContractPixmap. 0119 */ 0120 void setExtendPixmap(const QPixmap &pixmap); 0121 0122 /** 0123 * The pixmap that is displayed to contract an item. @p pixmap must have the same size as the pixmap in setExtendPixmap. 0124 */ 0125 void setContractPixmap(const QPixmap &pixmap); 0126 0127 /** 0128 * Return the pixmap that is displayed to extend an item. 0129 */ 0130 QPixmap extendPixmap(); 0131 0132 /** 0133 * Return the pixmap that is displayed to contract an item. 0134 */ 0135 QPixmap contractPixmap(); 0136 0137 private: 0138 friend class KExtendableItemDelegatePrivate; 0139 std::unique_ptr<class KExtendableItemDelegatePrivate> const d; 0140 0141 Q_PRIVATE_SLOT(d, void _k_extenderDestructionHandler(QObject *destroyed)) 0142 Q_PRIVATE_SLOT(d, void _k_verticalScroll()) 0143 }; 0144 #endif // KEXTENDABLEITEMDELEGATE_H