File indexing completed on 2024-04-28 05:45:10
0001 /* 0002 * SPDX-FileCopyrightText: 2011 Peter Penz <peter.penz19@gmail.com> 0003 * 0004 * Based on the Itemviews NG project from Trolltech Labs 0005 * 0006 * SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #ifndef KITEMMODELBASE_H 0010 #define KITEMMODELBASE_H 0011 0012 #include "dolphin_export.h" 0013 #include "kitemviews/kitemrange.h" 0014 #include "kitemviews/kitemset.h" 0015 0016 #include <QHash> 0017 #include <QObject> 0018 #include <QUrl> 0019 #include <QVariant> 0020 0021 class QMimeData; 0022 0023 /** 0024 * @brief Base class for model implementations used by KItemListView and KItemListController. 0025 * 0026 * An item-model consists of a variable number of items. The number of items 0027 * is given by KItemModelBase::count(). The data of an item is accessed by a unique index 0028 * with KItemModelBase::data(). The indexes are integer-values counting from 0 to the 0029 * KItemModelBase::count() - 1. 0030 * 0031 * One item consists of a variable number of role/value-pairs. 0032 * 0033 * A model can optionally provide sorting- and grouping-capabilities. 0034 * 0035 * Also optionally it is possible to provide a tree of items by implementing the methods 0036 * setExpanded(), isExpanded(), isExpandable() and expandedParentsCount(). 0037 */ 0038 class DOLPHIN_EXPORT KItemModelBase : public QObject 0039 { 0040 Q_OBJECT 0041 0042 public: 0043 explicit KItemModelBase(QObject *parent = nullptr); 0044 explicit KItemModelBase(const QByteArray &sortRole, QObject *parent = nullptr); 0045 ~KItemModelBase() override; 0046 0047 /** @return The number of items. */ 0048 virtual int count() const = 0; 0049 0050 virtual QHash<QByteArray, QVariant> data(int index) const = 0; 0051 0052 /** 0053 * Sets the data for the item at \a index to the given \a values. Returns true 0054 * if the data was set on the item; returns false otherwise. 0055 * 0056 * The default implementation does not set the data, and will always return 0057 * false. 0058 */ 0059 virtual bool setData(int index, const QHash<QByteArray, QVariant> &values); 0060 0061 /** 0062 * Enables/disables the grouped sorting. The method KItemModelBase::onGroupedSortingChanged() will be 0063 * called so that model-implementations can react on the grouped-sorting change. Afterwards the 0064 * signal groupedSortingChanged() will be emitted. If the grouped sorting is enabled, the method 0065 * KItemModelBase::groups() must be implemented. 0066 */ 0067 void setGroupedSorting(bool grouped); 0068 bool groupedSorting() const; 0069 0070 /** 0071 * Sets the sort-role to \a role. The method KItemModelBase::onSortRoleChanged() will be 0072 * called so that model-implementations can react on the sort-role change. Afterwards the 0073 * signal sortRoleChanged() will be emitted. 0074 * The implementation should resort only if \a resortItems is true. 0075 */ 0076 void setSortRole(const QByteArray &role, bool resortItems = true); 0077 QByteArray sortRole() const; 0078 0079 /** 0080 * Sets the sort order to \a order. The method KItemModelBase::onSortOrderChanged() will be 0081 * called so that model-implementations can react on the sort order change. Afterwards the 0082 * signal sortOrderChanged() will be emitted. 0083 */ 0084 void setSortOrder(Qt::SortOrder order); 0085 Qt::SortOrder sortOrder() const; 0086 0087 /** 0088 * @return Translated description for the \p role. The description is e.g. used 0089 * for the header in KItemListView. 0090 */ 0091 virtual QString roleDescription(const QByteArray &role) const; 0092 0093 /** 0094 * @return List of group headers. Each list-item consists of the index of the item 0095 * that represents the first item of a group and a value represented 0096 * as QVariant. The value is shown by an instance of KItemListGroupHeader. 0097 * Per default an empty list is returned. 0098 */ 0099 virtual QList<QPair<int, QVariant>> groups() const; 0100 0101 /** 0102 * Expands the item with the index \a index if \a expanded is true. 0103 * If \a expanded is false the item will be collapsed. 0104 * 0105 * Per default no expanding of items is implemented. When implementing 0106 * this method it is mandatory to overwrite KItemModelBase::isExpandable() 0107 * and KItemListView::supportsExpandableItems() to return true. 0108 * 0109 * @return True if the operation has been successful. 0110 */ 0111 virtual bool setExpanded(int index, bool expanded); 0112 0113 /** 0114 * @return True if the item with the index \a index is expanded. 0115 * Per default no expanding of items is implemented. When implementing 0116 * this method it is mandatory to overwrite KItemModelBase::isExpandable() 0117 * and KItemListView::supportsExpandableItems() to return true. 0118 */ 0119 virtual bool isExpanded(int index) const; 0120 0121 /** 0122 * @return True if expanding and collapsing of the item with the index \a index 0123 * is supported. Per default false is returned. 0124 */ 0125 virtual bool isExpandable(int index) const; 0126 0127 /** 0128 * @return Number of expanded parent items for the item with the given index. 0129 * Per default 0 is returned. 0130 */ 0131 virtual int expandedParentsCount(int index) const; 0132 0133 /** 0134 * @return MIME-data for the items given by \a indexes. The default implementation 0135 * returns 0. The ownership of the returned instance is in the hand of the 0136 * caller of this method. The method must be implemented if dragging of 0137 * items should be possible. 0138 */ 0139 virtual QMimeData *createMimeData(const KItemSet &indexes) const; 0140 0141 /** 0142 * @return Reimplement this to return the index for the first item 0143 * beginning with string typed in through the keyboard, -1 if not found. 0144 * @param text the text which has been typed in through the keyboard 0145 * @param startFromIndex the index from which to start searching from 0146 */ 0147 virtual int indexForKeyboardSearch(const QString &text, int startFromIndex = 0) const; 0148 0149 /** 0150 * @return True, if the item with the index \a index basically supports dropping. 0151 * Per default false is returned. 0152 * 0153 * The information is used only to give a visual feedback during a drag operation 0154 * and not to decide whether a drop event gets emitted. It is it is still up to 0155 * the receiver of KItemListController::itemDropEvent() to decide how to handle 0156 * the drop event. 0157 */ 0158 // TODO: Should the MIME-data be passed too so that the model can do a more specific 0159 // decision whether it accepts the drop? 0160 virtual bool supportsDropping(int index) const; 0161 0162 /** 0163 * @return An internal mimetype to signal that an itemDropEvent() should be rejected by 0164 * the receiving model. 0165 * 0166 * This mimeType can be used in createMimeData() to notify that the 0167 * drop-onto-items events should be ignored, while the drop-between-items 0168 * ones should be still accepted. 0169 */ 0170 QString blacklistItemDropEventMimeType() const; 0171 0172 /** 0173 * @return URL of the item at the specified index 0174 */ 0175 virtual QUrl url(int index) const; 0176 0177 /** 0178 * @return True, if item at specified index is a directory 0179 */ 0180 virtual bool isDir(int index) const; 0181 0182 /** 0183 * @return Parent directory of the items that are shown 0184 */ 0185 virtual QUrl directory() const; 0186 Q_SIGNALS: 0187 /** 0188 * Is emitted if one or more items have been inserted. Each item-range consists 0189 * of: 0190 * - an index where items have been inserted 0191 * - the number of inserted items. 0192 * The index of each item-range represents the index of the model 0193 * before the items have been inserted. 0194 * 0195 * For the item-ranges it is assured that: 0196 * - They don't overlap 0197 * - The index of item-range n is smaller than the index of item-range n + 1. 0198 */ 0199 void itemsInserted(const KItemRangeList &itemRanges); 0200 0201 /** 0202 * Is emitted if one or more items have been removed. Each item-range consists 0203 * of: 0204 * - an index where items have been inserted 0205 * - the number of inserted items. 0206 * The index of each item-range represents the index of the model 0207 * before the items have been removed. 0208 * 0209 * For the item-ranges it is assured that: 0210 * - They don't overlap 0211 * - The index of item-range n is smaller than the index of item-range n + 1. 0212 */ 0213 void itemsRemoved(const KItemRangeList &itemRanges); 0214 0215 /** 0216 * Is emitted if one ore more items get moved. 0217 * @param itemRange Item-range that gets moved to a new position. 0218 * @param movedToIndexes New positions for each element of the item-range. 0219 * 0220 * For example if the model has 10 items and the items 0 and 1 get exchanged 0221 * with the items 5 and 6 then the parameters look like this: 0222 * - itemRange: has the index 0 and a count of 7. 0223 * - movedToIndexes: Contains the seven values 5, 6, 2, 3, 4, 0, 1 0224 * 0225 * This signal implies that the groups might have changed. Therefore, 0226 * gropusChanged() is not emitted if this signal is emitted. 0227 */ 0228 void itemsMoved(const KItemRange &itemRange, const QList<int> &movedToIndexes); 0229 0230 void itemsChanged(const KItemRangeList &itemRanges, const QSet<QByteArray> &roles); 0231 0232 /** 0233 * Is emitted if the groups have changed, even though the order of the 0234 * items has not been modified. 0235 */ 0236 void groupsChanged(); 0237 0238 void groupedSortingChanged(bool current); 0239 void sortRoleChanged(const QByteArray ¤t, const QByteArray &previous); 0240 void sortOrderChanged(Qt::SortOrder current, Qt::SortOrder previous); 0241 0242 protected: 0243 /** 0244 * Is invoked if the grouped sorting has been changed by KItemModelBase::setGroupedSorting(). Allows 0245 * to react on the changed grouped sorting before the signal groupedSortingChanged() will be emitted. 0246 */ 0247 virtual void onGroupedSortingChanged(bool current); 0248 0249 /** 0250 * Is invoked if the sort role has been changed by KItemModelBase::setSortRole(). Allows 0251 * to react on the changed sort role before the signal sortRoleChanged() will be emitted. 0252 * The implementation must assure that the items are sorted by the role given by \a current. 0253 * Usually the most efficient way is to emit a 0254 * itemsRemoved() signal for all items, reorder the items internally and to emit a 0255 * itemsInserted() signal afterwards. 0256 * The implementation should resort only if \a resortItems is true. 0257 */ 0258 virtual void onSortRoleChanged(const QByteArray ¤t, const QByteArray &previous, bool resortItems = true); 0259 0260 /** 0261 * Is invoked if the sort order has been changed by KItemModelBase::setSortOrder(). Allows 0262 * to react on the changed sort order before the signal sortOrderChanged() will be emitted. 0263 * The implementation must assure that the items are sorted by the order given by \a current. 0264 * Usually the most efficient way is to emit a 0265 * itemsRemoved() signal for all items, reorder the items internally and to emit a 0266 * itemsInserted() signal afterwards. 0267 */ 0268 virtual void onSortOrderChanged(Qt::SortOrder current, Qt::SortOrder previous); 0269 0270 private: 0271 bool m_groupedSorting; 0272 QByteArray m_sortRole; 0273 Qt::SortOrder m_sortOrder; 0274 }; 0275 0276 inline Qt::SortOrder KItemModelBase::sortOrder() const 0277 { 0278 return m_sortOrder; 0279 } 0280 0281 #endif