1 | /* This file is part of the KDE project |
2 | Copyright (C) 2006 David Faure <faure@kde.org> |
3 | |
4 | This library is free software; you can redistribute it and/or |
5 | modify it under the terms of the GNU Library General Public |
6 | License as published by the Free Software Foundation; either |
7 | version 2 of the License, or (at your option) any later version. |
8 | |
9 | This library is distributed in the hope that it will be useful, |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | Library General Public License for more details. |
13 | |
14 | You should have received a copy of the GNU Library General Public License |
15 | along with this library; see the file COPYING.LIB. If not, write to |
16 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
17 | Boston, MA 02110-1301, USA. |
18 | */ |
19 | #ifndef KDIRMODEL_H |
20 | #define KDIRMODEL_H |
21 | |
22 | #include <QtCore/QAbstractItemModel> |
23 | #include <kio/kio_export.h> |
24 | #include <kfileitem.h> |
25 | |
26 | class KDirLister; |
27 | class KDirModelPrivate; |
28 | class JobUrlCache; |
29 | |
30 | /** |
31 | * @short A model for a KIO-based directory tree. |
32 | * |
33 | * KDirModel implements the QAbstractItemModel interface (for use with Qt's model/view widgets) |
34 | * around the directory listing for one directory or a tree of directories. |
35 | * |
36 | * Note that there are some cases when using QPersistentModelIndexes from this model will not give |
37 | * expected results. QPersistentIndexes will remain valid and updated if its siblings are added or |
38 | * removed. However, if the QPersistentIndex or one of its ancestors is moved, the QPersistentIndex will become |
39 | * invalid. For example, if a file or directory is renamed after storing a QPersistentModelIndex for it, |
40 | * the index (along with any stored children) will become invalid even though it is still in the model. The reason |
41 | * for this is that moves of files and directories are treated as separate insert and remove actions. |
42 | * |
43 | * @see KDirSortFilterProxyModel |
44 | * |
45 | * @author David Faure |
46 | * Based on work by Hamish Rodda and Pascal Letourneau |
47 | */ |
48 | class KIO_EXPORT KDirModel : public QAbstractItemModel |
49 | { |
50 | Q_OBJECT |
51 | |
52 | public: |
53 | /** |
54 | * @param parent parent qobject |
55 | */ |
56 | explicit KDirModel( QObject* parent = 0 ); |
57 | ~KDirModel(); |
58 | |
59 | /** |
60 | * Set the directory lister to use by this model, instead of the default KDirLister created internally. |
61 | * The model takes ownership. |
62 | */ |
63 | void setDirLister( KDirLister* dirLister ); |
64 | |
65 | /** |
66 | * Return the directory lister used by this model. |
67 | */ |
68 | KDirLister* dirLister() const; |
69 | |
70 | /** |
71 | * Return the fileitem for a given index. This is O(1), i.e. fast. |
72 | */ |
73 | KFileItem itemForIndex( const QModelIndex& index ) const; |
74 | |
75 | /** |
76 | * Return the index for a given kfileitem. This can be slow. |
77 | * @deprecated use the method that takes a KFileItem by value |
78 | */ |
79 | #ifndef KDE_NO_DEPRECATED |
80 | KDE_DEPRECATED QModelIndex indexForItem( const KFileItem* ) const; |
81 | #endif |
82 | |
83 | /** |
84 | * Return the index for a given kfileitem. This can be slow. |
85 | */ |
86 | QModelIndex indexForItem( const KFileItem& ) const; |
87 | |
88 | /** |
89 | * Return the index for a given url. This can be slow. |
90 | */ |
91 | QModelIndex indexForUrl(const KUrl& url) const; |
92 | |
93 | /** |
94 | * @short Lists subdirectories using fetchMore() as needed until the given @p url exists in the model. |
95 | * |
96 | * When the model is used by a treeview, call KDirLister::openUrl with the base url of the tree, |
97 | * then the treeview will take care of calling fetchMore() when the user opens directories. |
98 | * However if you want the tree to show a given URL (i.e. open the tree recursively until that URL), |
99 | * call expandToUrl(). |
100 | * Note that this is asynchronous; the necessary listing of subdirectories will take time so |
101 | * the model will not immediately have this url available. |
102 | * The model emits the signal expand() when an index has become available; this can be connected |
103 | * to the treeview in order to let it open that index. |
104 | * @param url the url of a subdirectory of the directory model (or a file in a subdirectory) |
105 | */ |
106 | void expandToUrl(const KUrl& url); |
107 | |
108 | /** |
109 | * Notify the model that the item at this index has changed. |
110 | * For instance because KMimeTypeResolver called determineMimeType on it. |
111 | * This makes the model emit its dataChanged signal at this index, so that views repaint. |
112 | * Note that for most things (renaming, changing size etc.), KDirLister's signals tell the model already. |
113 | */ |
114 | void itemChanged( const QModelIndex& index ); |
115 | |
116 | /*** |
117 | * Useful "default" columns. Views can use a proxy to have more control over this. |
118 | */ |
119 | enum ModelColumns { |
120 | Name = 0, |
121 | Size, |
122 | ModifiedTime, |
123 | Permissions, |
124 | Owner, |
125 | Group, |
126 | Type, |
127 | ColumnCount |
128 | }; |
129 | |
130 | /// Possible return value for data(ChildCountRole), meaning the item isn't a directory, |
131 | /// or we haven't calculated its child count yet |
132 | enum { ChildCountUnknown = -1 }; |
133 | |
134 | enum AdditionalRoles { |
135 | // Note: use printf "0x%08X\n" $(($RANDOM*$RANDOM)) |
136 | // to define additional roles. |
137 | FileItemRole = 0x07A263FF, ///< returns the KFileItem for a given index |
138 | ChildCountRole = 0x2C4D0A40, ///< returns the number of items in a directory, or ChildCountUnknown |
139 | HasJobRole = 0x01E555A5 ///< returns whether or not there is a job on an item (file/directory) |
140 | }; |
141 | |
142 | enum DropsAllowedFlag { |
143 | NoDrops = 0, |
144 | DropOnDirectory = 1, ///< allow drops on any directory |
145 | DropOnAnyFile = 2, ///< allow drops on any file |
146 | DropOnLocalExecutable = 4 ///< allow drops on local executables, shell scripts and desktop files. Can be used with DropOnDirectory. |
147 | }; |
148 | Q_DECLARE_FLAGS(DropsAllowed, DropsAllowedFlag) |
149 | |
150 | /// Set whether dropping onto items should be allowed, and for which kind of item |
151 | /// Drops are disabled by default. |
152 | void setDropsAllowed(DropsAllowed dropsAllowed); |
153 | |
154 | /// Reimplemented from QAbstractItemModel. Returns true for empty directories. |
155 | virtual bool canFetchMore ( const QModelIndex & parent ) const; |
156 | /// Reimplemented from QAbstractItemModel. Returns ColumnCount. |
157 | virtual int columnCount ( const QModelIndex & parent = QModelIndex() ) const; |
158 | /// Reimplemented from QAbstractItemModel. |
159 | virtual QVariant data ( const QModelIndex & index, int role = Qt::DisplayRole ) const; |
160 | /// Reimplemented from QAbstractItemModel. Not implemented yet. |
161 | virtual bool dropMimeData ( const QMimeData * data, Qt::DropAction action, int row, int column, const QModelIndex & parent ); |
162 | /// Reimplemented from QAbstractItemModel. Lists the subdirectory. |
163 | virtual void fetchMore ( const QModelIndex & parent ); |
164 | /// Reimplemented from QAbstractItemModel. |
165 | virtual Qt::ItemFlags flags ( const QModelIndex & index ) const; |
166 | /// Reimplemented from QAbstractItemModel. Returns true for directories. |
167 | virtual bool hasChildren ( const QModelIndex & parent = QModelIndex() ) const; |
168 | /// Reimplemented from QAbstractItemModel. Returns the column titles. |
169 | virtual QVariant ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const; |
170 | /// Reimplemented from QAbstractItemModel. O(1) |
171 | virtual QModelIndex index ( int row, int column, const QModelIndex & parent = QModelIndex() ) const; |
172 | /// Reimplemented from QAbstractItemModel. |
173 | virtual QMimeData * mimeData ( const QModelIndexList & indexes ) const; |
174 | /// Reimplemented from QAbstractItemModel. |
175 | virtual QStringList mimeTypes () const; |
176 | /// Reimplemented from QAbstractItemModel. |
177 | virtual QModelIndex parent ( const QModelIndex & index ) const; |
178 | /// Reimplemented from QAbstractItemModel. |
179 | virtual int rowCount ( const QModelIndex & parent = QModelIndex() ) const; |
180 | /// Reimplemented from QAbstractItemModel. |
181 | /// Call this to set a new icon, e.g. a preview |
182 | virtual bool setData ( const QModelIndex & index, const QVariant & value, int role = Qt::EditRole ); |
183 | /// Reimplemented from QAbstractItemModel. Not implemented. @see KDirSortFilterProxyModel |
184 | virtual void sort ( int column, Qt::SortOrder order = Qt::AscendingOrder ); |
185 | |
186 | |
187 | /** |
188 | * Remove urls from the list if an ancestor is present on the list. This can |
189 | * be used to delete only the ancestor url and skip a potential error of a non-existent url. |
190 | * |
191 | * 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", |
192 | * "home/foo/b/b.txt", this method will return the list "/home/foo/a", "/home/foo/b/b.txt". |
193 | * |
194 | * @return the list @p urls without parented urls inside. |
195 | * @since 4.2 |
196 | */ |
197 | static KUrl::List simplifiedUrlList( const KUrl::List & urls ); |
198 | |
199 | /** |
200 | * This emits the needSequenceIcon signal, requesting another sequence icon |
201 | * |
202 | * If there is a KFilePreviewGenerator attached to this model, that generator will care |
203 | * about creating another preview. |
204 | * |
205 | * @param index Index of the item that should get another icon |
206 | * @param sequenceIndex Index in the sequence. If it is zero, the standard icon will be assigned. |
207 | * For higher indices, arbitrary different meaningful icons will be generated. |
208 | * @since 4.3 |
209 | */ |
210 | void requestSequenceIcon(const QModelIndex& index, int sequenceIndex); |
211 | |
212 | /** |
213 | * Enable/Disable the displaying of an animated overlay that is shown for any destination |
214 | * urls (in the view). When enabled, the animations (if any) will be drawn automatically. |
215 | * |
216 | * Only the files/folders that are visible and have jobs associated with them |
217 | * will display the animation. |
218 | * You would likely not want this enabled if you perform some kind of custom painting |
219 | * that takes up a whole item, and will just make this(and what you paint) look funky. |
220 | * |
221 | * Default is disabled. |
222 | * |
223 | * Note: KFileItemDelegate needs to have it's method called with the same |
224 | * value, when you make the call to this method. |
225 | * |
226 | * @since 4.5 |
227 | */ |
228 | void setJobTransfersVisible(bool value); |
229 | |
230 | /** |
231 | * Returns whether or not displaying job transfers has been enabled. |
232 | * @since 4.5 |
233 | */ |
234 | bool jobTransfersVisible() const; |
235 | |
236 | Q_SIGNALS: |
237 | /** |
238 | * Emitted for each subdirectory that is a parent of a url passed to expandToUrl |
239 | * This allows to asynchronously open a tree view down to a given directory. |
240 | * Also emitted for the final file, if expandToUrl is called with a file |
241 | * (for instance so that it can be selected). |
242 | */ |
243 | void expand(const QModelIndex& index); |
244 | /** |
245 | * Emitted when another icon sequence index is requested |
246 | * @param index Index of the item that should get another icon |
247 | * @param sequenceIndex Index in the sequence. If it is zero, the standard icon should be assigned. |
248 | * For higher indices, arbitrary different meaningful icons should be generated. |
249 | * This is usually slowly counted up while the user hovers the icon. |
250 | * If no meaningful alternative icons can be generated, this should be ignored. |
251 | * @since 4.3 |
252 | */ |
253 | void needSequenceIcon(const QModelIndex& index, int sequenceIndex); |
254 | |
255 | private: |
256 | // Make those private, they shouldn't be called by applications |
257 | virtual bool insertRows(int , int, const QModelIndex & = QModelIndex()); |
258 | virtual bool insertColumns(int, int, const QModelIndex & = QModelIndex()); |
259 | virtual bool removeRows(int, int, const QModelIndex & = QModelIndex()); |
260 | virtual bool removeColumns(int, int, const QModelIndex & = QModelIndex()); |
261 | |
262 | private: |
263 | friend class KDirModelPrivate; |
264 | KDirModelPrivate *const d; |
265 | |
266 | Q_PRIVATE_SLOT( d, void _k_slotNewItems(const KUrl&, const KFileItemList&) ) |
267 | Q_PRIVATE_SLOT( d, void _k_slotDeleteItems(const KFileItemList&) ) |
268 | Q_PRIVATE_SLOT( d, void _k_slotRefreshItems(const QList<QPair<KFileItem, KFileItem> >&) ) |
269 | Q_PRIVATE_SLOT( d, void _k_slotClear() ) |
270 | Q_PRIVATE_SLOT( d, void _k_slotRedirection(const KUrl&, const KUrl&) ) |
271 | Q_PRIVATE_SLOT( d, void _k_slotJobUrlsChanged(const QStringList&)) |
272 | }; |
273 | |
274 | Q_DECLARE_OPERATORS_FOR_FLAGS(KDirModel::DropsAllowed) |
275 | |
276 | #endif /* KDIRMODEL_H */ |
277 | |