File indexing completed on 2023-12-03 07:45:56
0001 /* 0002 This file is part of the KDE project 0003 SPDX-FileCopyrightText: 2006 David Faure <faure@kde.org> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #ifndef KDIRMODEL_H 0009 #define KDIRMODEL_H 0010 0011 #include "kiowidgets_export.h" 0012 #include <QAbstractItemModel> 0013 #include <kfileitem.h> 0014 0015 #include <memory> 0016 0017 class KDirLister; 0018 class KDirModelPrivate; 0019 class JobUrlCache; 0020 0021 /** 0022 * @class KDirModel kdirmodel.h <KDirModel> 0023 * 0024 * @short A model for a KIO-based directory tree. 0025 * 0026 * KDirModel implements the QAbstractItemModel interface (for use with Qt's model/view widgets) 0027 * around the directory listing for one directory or a tree of directories. 0028 * 0029 * Note that there are some cases when using QPersistentModelIndexes from this model will not give 0030 * expected results. QPersistentIndexes will remain valid and updated if its siblings are added or 0031 * removed. However, if the QPersistentIndex or one of its ancestors is moved, the QPersistentIndex will become 0032 * invalid. For example, if a file or directory is renamed after storing a QPersistentModelIndex for it, 0033 * the index (along with any stored children) will become invalid even though it is still in the model. The reason 0034 * for this is that moves of files and directories are treated as separate insert and remove actions. 0035 * 0036 * @see KDirSortFilterProxyModel 0037 * 0038 * @author David Faure 0039 * Based on work by Hamish Rodda and Pascal Letourneau 0040 */ 0041 class KIOWIDGETS_EXPORT KDirModel : public QAbstractItemModel 0042 { 0043 Q_OBJECT 0044 0045 public: 0046 /** 0047 * @param parent parent qobject 0048 */ 0049 explicit KDirModel(QObject *parent = nullptr); 0050 ~KDirModel() override; 0051 0052 /** 0053 * Flags for the openUrl() method 0054 * @see OpenUrlFlags 0055 * @since 5.69 0056 */ 0057 enum OpenUrlFlag { 0058 NoFlags = 0x0, ///< No additional flags specified. 0059 Reload = 0x1, ///< Indicates whether to use the cache or to reread 0060 ///< the directory from the disk. 0061 ///< Use only when opening a dir not yet listed by our dirLister() 0062 ///< without using the cache. Otherwise use dirLister()->updateDirectory(). 0063 ShowRoot = 0x2, ///< Display a root node for the URL being opened. 0064 }; 0065 /** 0066 * Stores a combination of #OpenUrlFlag values. 0067 */ 0068 Q_DECLARE_FLAGS(OpenUrlFlags, OpenUrlFlag) 0069 Q_FLAG(OpenUrlFlags) 0070 0071 /** 0072 * Display the contents of @p url in the model. 0073 * Apart from the support for the ShowRoot flag, this is equivalent to dirLister()->openUrl(url, flags) 0074 * @param url the URL of the directory whose contents should be listed. 0075 * Unless ShowRoot is set, the item for this directory will NOT be shown, the model starts at its children. 0076 * @param flags see OpenUrlFlag 0077 * @since 5.69 0078 */ 0079 Q_INVOKABLE void openUrl(const QUrl &url, OpenUrlFlags flags = NoFlags); 0080 0081 /** 0082 * Set the directory lister to use by this model, instead of the default KDirLister created internally. 0083 * The model takes ownership. 0084 */ 0085 void setDirLister(KDirLister *dirLister); 0086 0087 /** 0088 * Return the directory lister used by this model. 0089 */ 0090 KDirLister *dirLister() const; 0091 0092 /** 0093 * Return the fileitem for a given index. This is O(1), i.e. fast. 0094 */ 0095 KFileItem itemForIndex(const QModelIndex &index) const; 0096 0097 #if KIOWIDGETS_ENABLE_DEPRECATED_SINCE(4, 0) 0098 /** 0099 * Return the index for a given kfileitem. This can be slow. 0100 * @deprecated Since 4.0, use the method that takes a KFileItem by value 0101 */ 0102 KIOWIDGETS_DEPRECATED_VERSION(4, 0, "Use KDirModel::indexForItem(const KFileItem &)") 0103 QModelIndex indexForItem(const KFileItem *) const; 0104 #endif 0105 0106 /** 0107 * Return the index for a given kfileitem. This can be slow. 0108 */ 0109 Q_INVOKABLE QModelIndex indexForItem(const KFileItem &) const; 0110 0111 /** 0112 * Return the index for a given url. This can be slow. 0113 */ 0114 Q_INVOKABLE QModelIndex indexForUrl(const QUrl &url) const; 0115 0116 /** 0117 * @short Lists subdirectories using fetchMore() as needed until the given @p url exists in the model. 0118 * 0119 * When the model is used by a treeview, call KDirLister::openUrl with the base url of the tree, 0120 * then the treeview will take care of calling fetchMore() when the user opens directories. 0121 * However if you want the tree to show a given URL (i.e. open the tree recursively until that URL), 0122 * call expandToUrl(). 0123 * Note that this is asynchronous; the necessary listing of subdirectories will take time so 0124 * the model will not immediately have this url available. 0125 * The model emits the signal expand() when an index has become available; this can be connected 0126 * to the treeview in order to let it open that index. 0127 * @param url the url of a subdirectory of the directory model (or a file in a subdirectory) 0128 */ 0129 Q_INVOKABLE void expandToUrl(const QUrl &url); 0130 0131 /** 0132 * Notify the model that the item at this index has changed. 0133 * For instance because KMimeTypeResolver called determineMimeType on it. 0134 * This makes the model emit its dataChanged signal at this index, so that views repaint. 0135 * Note that for most things (renaming, changing size etc.), KDirLister's signals tell the model already. 0136 */ 0137 Q_INVOKABLE void itemChanged(const QModelIndex &index); 0138 0139 /** 0140 * Forget all previews (optimization for turning previews off). 0141 * The items will again have their default appearance (not controlled by the model). 0142 * @since 5.28 0143 */ 0144 Q_INVOKABLE void clearAllPreviews(); 0145 0146 /** 0147 * Useful "default" columns. Views can use a proxy to have more control over this. 0148 */ 0149 enum ModelColumns { 0150 Name = 0, 0151 Size, 0152 ModifiedTime, 0153 Permissions, 0154 Owner, 0155 Group, 0156 Type, 0157 ColumnCount, 0158 }; 0159 0160 /// Possible return value for data(ChildCountRole), meaning the item isn't a directory, 0161 /// or we haven't calculated its child count yet 0162 enum { ChildCountUnknown = -1 }; 0163 0164 enum AdditionalRoles { 0165 // Note: use printf "0x%08X\n" $(($RANDOM*$RANDOM)) 0166 // to define additional roles. 0167 FileItemRole = 0x07A263FF, ///< returns the KFileItem for a given index. roleName is "fileItem". 0168 ChildCountRole = 0x2C4D0A40, ///< returns the number of items in a directory, or ChildCountUnknown. roleName is "childCount". 0169 HasJobRole = 0x01E555A5, ///< returns whether or not there is a job on an item (file/directory). roleName is "hasJob". 0170 }; 0171 0172 /** 0173 * @see DropsAllowed 0174 */ 0175 enum DropsAllowedFlag { 0176 NoDrops = 0, 0177 DropOnDirectory = 1, ///< allow drops on any directory 0178 DropOnAnyFile = 2, ///< allow drops on any file 0179 DropOnLocalExecutable = 4, ///< allow drops on local executables, shell scripts and desktop files. Can be used with DropOnDirectory. 0180 }; 0181 /** 0182 * Stores a combination of #DropsAllowedFlag values. 0183 */ 0184 Q_DECLARE_FLAGS(DropsAllowed, DropsAllowedFlag) 0185 Q_FLAG(DropsAllowed) 0186 0187 /// Set whether dropping onto items should be allowed, and for which kind of item 0188 /// Drops are disabled by default. 0189 Q_INVOKABLE void setDropsAllowed(DropsAllowed dropsAllowed); 0190 0191 /// Reimplemented from QAbstractItemModel. Returns true for empty directories. 0192 bool canFetchMore(const QModelIndex &parent) const override; 0193 /// Reimplemented from QAbstractItemModel. Returns ColumnCount. 0194 int columnCount(const QModelIndex &parent = QModelIndex()) const override; 0195 /// Reimplemented from QAbstractItemModel. 0196 QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; 0197 /// Reimplemented from QAbstractItemModel. Not implemented yet. 0198 bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override; 0199 /// Reimplemented from QAbstractItemModel. Lists the subdirectory. 0200 void fetchMore(const QModelIndex &parent) override; 0201 /// Reimplemented from QAbstractItemModel. 0202 Qt::ItemFlags flags(const QModelIndex &index) const override; 0203 /// Reimplemented from QAbstractItemModel. Returns true for directories. 0204 bool hasChildren(const QModelIndex &parent = QModelIndex()) const override; 0205 /// Reimplemented from QAbstractItemModel. Returns the column titles. 0206 QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; 0207 /// Reimplemented from QAbstractItemModel. O(1) 0208 QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; 0209 /// Reimplemented from QAbstractItemModel. 0210 QMimeData *mimeData(const QModelIndexList &indexes) const override; 0211 /// Reimplemented from QAbstractItemModel. 0212 QStringList mimeTypes() const override; 0213 /// Reimplemented from QAbstractItemModel. 0214 QModelIndex parent(const QModelIndex &index) const override; 0215 /// Reimplemented from QAbstractItemModel. 0216 QModelIndex sibling(int row, int column, const QModelIndex &index) const override; 0217 /// Reimplemented from QAbstractItemModel. 0218 int rowCount(const QModelIndex &parent = QModelIndex()) const override; 0219 /// Reimplemented from QAbstractItemModel. 0220 /// Call this to set a new icon, e.g. a preview 0221 bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; 0222 /// Reimplemented from QAbstractItemModel. Not implemented. @see KDirSortFilterProxyModel 0223 void sort(int column, Qt::SortOrder order = Qt::AscendingOrder) override; 0224 /// Reimplemented from QAbstractItemModel. 0225 /// @see AdditionalRoles 0226 QHash<int, QByteArray> roleNames() const override; 0227 0228 /** 0229 * Remove urls from the list if an ancestor is present on the list. This can 0230 * be used to delete only the ancestor url and skip a potential error of a non-existent url. 0231 * 0232 * For example, for a list of "/home/foo/a", "/home/foo/a/a.txt", "/home/foo/a/a/a.txt", "/home/foo/a/b/b.txt", 0233 * "home/foo/b/b.txt", this method will return the list "/home/foo/a", "/home/foo/b/b.txt". 0234 * 0235 * @return the list @p urls without parented urls inside. 0236 * @since 4.2 0237 */ 0238 static QList<QUrl> simplifiedUrlList(const QList<QUrl> &urls); 0239 0240 /** 0241 * This emits the needSequenceIcon signal, requesting another sequence icon 0242 * 0243 * If there is a KFilePreviewGenerator attached to this model, that generator will care 0244 * about creating another preview. 0245 * 0246 * @param index Index of the item that should get another icon 0247 * @param sequenceIndex Index in the sequence. If it is zero, the standard icon will be assigned. 0248 * For higher indices, arbitrary different meaningful icons will be generated. 0249 * @since 4.3 0250 */ 0251 void requestSequenceIcon(const QModelIndex &index, int sequenceIndex); 0252 0253 /** 0254 * Enable/Disable the displaying of an animated overlay that is shown for any destination 0255 * urls (in the view). When enabled, the animations (if any) will be drawn automatically. 0256 * 0257 * Only the files/folders that are visible and have jobs associated with them 0258 * will display the animation. 0259 * You would likely not want this enabled if you perform some kind of custom painting 0260 * that takes up a whole item, and will just make this(and what you paint) look funky. 0261 * 0262 * Default is disabled. 0263 * 0264 * Note: KFileItemDelegate needs to have it's method called with the same 0265 * value, when you make the call to this method. 0266 * 0267 * @since 4.5 0268 */ 0269 void setJobTransfersVisible(bool show); 0270 0271 /** 0272 * Returns whether or not displaying job transfers has been enabled. 0273 * @since 4.5 0274 */ 0275 bool jobTransfersVisible() const; 0276 0277 Qt::DropActions supportedDropActions() const override; 0278 0279 Q_SIGNALS: 0280 /** 0281 * Emitted for each subdirectory that is a parent of a url passed to expandToUrl 0282 * This allows to asynchronously open a tree view down to a given directory. 0283 * Also emitted for the final file, if expandToUrl is called with a file 0284 * (for instance so that it can be selected). 0285 */ 0286 void expand(const QModelIndex &index); 0287 /** 0288 * Emitted when another icon sequence index is requested 0289 * @param index Index of the item that should get another icon 0290 * @param sequenceIndex Index in the sequence. If it is zero, the standard icon should be assigned. 0291 * For higher indices, arbitrary different meaningful icons should be generated. 0292 * This is usually slowly counted up while the user hovers the icon. 0293 * If no meaningful alternative icons can be generated, this should be ignored. 0294 * @since 4.3 0295 */ 0296 void needSequenceIcon(const QModelIndex &index, int sequenceIndex); 0297 0298 private: 0299 // Make those private, they shouldn't be called by applications 0300 bool insertRows(int, int, const QModelIndex & = QModelIndex()) override; 0301 bool insertColumns(int, int, const QModelIndex & = QModelIndex()) override; 0302 bool removeRows(int, int, const QModelIndex & = QModelIndex()) override; 0303 bool removeColumns(int, int, const QModelIndex & = QModelIndex()) override; 0304 0305 private: 0306 friend class KDirModelPrivate; 0307 std::unique_ptr<KDirModelPrivate> const d; 0308 }; 0309 0310 Q_DECLARE_OPERATORS_FOR_FLAGS(KDirModel::DropsAllowed) 0311 Q_DECLARE_OPERATORS_FOR_FLAGS(KDirModel::OpenUrlFlags) 0312 0313 #endif /* KDIRMODEL_H */