1 | /* |
2 | This file is part of the KDE project |
3 | SPDX-FileCopyrightText: 2006-2007, 2008 Fredrik Höglund <fredrik@kde.org> |
4 | |
5 | SPDX-License-Identifier: LGPL-2.0-or-later |
6 | */ |
7 | |
8 | #ifndef KFILEITEMDELEGATE_H |
9 | #define KFILEITEMDELEGATE_H |
10 | |
11 | #include "kiowidgets_export.h" |
12 | #include <KFileItem> |
13 | #include <QAbstractItemDelegate> |
14 | #include <QTextOption> |
15 | |
16 | #include <memory> |
17 | |
18 | class QAbstractItemModel; |
19 | class QAbstractItemView; |
20 | class QHelpEvent; |
21 | class QModelIndex; |
22 | class QPainter; |
23 | |
24 | /*! |
25 | * \class KFileItemDelegate |
26 | * \inmodule KIOWidgets |
27 | * |
28 | * \brief KFileItemDelegate is intended to be used to provide a KDE file system |
29 | * view, when using one of the standard item views in Qt with KDirModel. |
30 | * |
31 | * While primarily intended to be used with KDirModel, it uses |
32 | * Qt::DecorationRole and Qt::DisplayRole for the icons and text labels, |
33 | * just like QItemDelegate, and can thus be used with any standard model. |
34 | * |
35 | * When used with KDirModel however, KFileItemDelegate can change the way |
36 | * the display and/or decoration roles are drawn, based on properties |
37 | * of the file items. For example, if the file item is a symbolic link, |
38 | * it will use an italic font to draw the file name. |
39 | * |
40 | * KFileItemDelegate also supports showing additional information about |
41 | * the file items below the icon labels. |
42 | * |
43 | * Which information should be shown, if any, is controlled by the |
44 | * information property, which is a list that can be set by calling |
45 | * setShowInformation(), and read by calling showInformation(). |
46 | * By default this list is empty. |
47 | * |
48 | * To use KFileItemDelegate, instantiate an object from the delegate, |
49 | * and call setItemDelegate() in one of the standard item views in Qt: |
50 | * |
51 | * \code |
52 | * QListView *listview = new QListView(this); |
53 | * KFileItemDelegate *delegate = new KFileItemDelegate(this); |
54 | * listview->setItemDelegate(delegate); |
55 | * \endcode |
56 | */ |
57 | class KIOWIDGETS_EXPORT KFileItemDelegate : public QAbstractItemDelegate |
58 | { |
59 | Q_OBJECT |
60 | |
61 | /*! |
62 | * \property KFileItemDelegate::information |
63 | * |
64 | * This property holds which additional information (if any) should be shown below |
65 | * items in icon views. |
66 | */ |
67 | Q_PROPERTY(InformationList information READ showInformation WRITE setShowInformation) |
68 | |
69 | /*! |
70 | * \property KFileItemDelegate::shadowColor |
71 | * |
72 | * This property holds the color used for the text shadow. |
73 | * |
74 | * The alpha value in the color determines the opacity of the shadow. |
75 | * Shadows are only rendered when the alpha value is non-zero. |
76 | * The default value for this property is Qt::transparent. |
77 | */ |
78 | Q_PROPERTY(QColor shadowColor READ shadowColor WRITE setShadowColor) |
79 | |
80 | /*! |
81 | * \property KFileItemDelegate::shadowOffset |
82 | * |
83 | * This property holds the horizontal and vertical offset for the text shadow. |
84 | * The default value for this property is (1, 1). |
85 | */ |
86 | Q_PROPERTY(QPointF shadowOffset READ shadowOffset WRITE setShadowOffset) |
87 | |
88 | /*! |
89 | * \property KFileItemDelegate::shadowBlur |
90 | * |
91 | * This property holds the blur radius for the text shadow. |
92 | * The default value for this property is 2. |
93 | */ |
94 | Q_PROPERTY(qreal shadowBlur READ shadowBlur WRITE setShadowBlur) |
95 | |
96 | /*! |
97 | * \property KFileItemDelegate::maximumSize |
98 | * |
99 | * This property holds the maximum size that can be returned |
100 | * by KFileItemDelegate::sizeHint(). If the maximum size is empty, |
101 | * it will be ignored. |
102 | */ |
103 | Q_PROPERTY(QSize maximumSize READ maximumSize WRITE setMaximumSize) |
104 | |
105 | /*! |
106 | * \property KFileItemDelegate::showToolTipWhenElided |
107 | * |
108 | * This property determines whether a tooltip will be shown by the delegate |
109 | * if the display role is elided. This tooltip will contain the full display |
110 | * role information. The tooltip will only be shown if the Qt::ToolTipRole differs |
111 | * from Qt::DisplayRole, or if they match, showToolTipWhenElided flag is set and |
112 | * the display role information is elided. |
113 | */ |
114 | Q_PROPERTY(bool showToolTipWhenElided READ showToolTipWhenElided WRITE setShowToolTipWhenElided) |
115 | |
116 | /*! |
117 | * \property KFileItemDelegate::jobTransfersVisible |
118 | * |
119 | * This property determines if there are KIO jobs on a destination URL visible, then |
120 | * they will have a small animation overlay displayed on them. |
121 | */ |
122 | Q_PROPERTY(bool jobTransfersVisible READ jobTransfersVisible WRITE setJobTransfersVisible) |
123 | |
124 | public: |
125 | /*! |
126 | * This enum defines the additional information that can be displayed below item |
127 | * labels in icon views. |
128 | * |
129 | * The information will only be shown for indexes for which the model provides |
130 | * a valid value for KDirModel::FileItemRole, and only when there's sufficient vertical |
131 | * space to display at least one line of the information, along with the display label. |
132 | * |
133 | * For the number of items to be shown for folders, the model must provide a valid |
134 | * value for KDirMode::ChildCountRole, in addition to KDirModel::FileItemRole. |
135 | * |
136 | * Note that KFileItemDelegate will not call KFileItem::determineMimeType() if |
137 | * KFileItem::isMimeTypeKnown() returns false, so if you want to display MIME types |
138 | * you should call KFileItem::determineMimeType() yourself, to ensure that MIME |
139 | * types are resolved. If the MIME type isn't known, "Unknown" will be displayed until |
140 | * the MIME type has been successfully resolved. |
141 | * |
142 | * \value NoInformation No additional information will be shown for items. |
143 | * \value Size The file size for files, and the number of items for folders. |
144 | * \value Permissions A UNIX permissions string, e.g. -rwxr-xr-x. |
145 | * \value OctalPermissions The permissions as an octal value, e.g. 0644. |
146 | * \value Owner The user name of the file owner, e.g. root |
147 | * \value OwnerAndGroup The user and group that owns the file, e.g. root:root |
148 | * \value CreationTime The date and time the file/folder was created. |
149 | * \value ModificationTime The date and time the file/folder was last modified. |
150 | * \value AccessTime The date and time the file/folder was last accessed. |
151 | * \value MimeType The MIME type for the item, e.g. text/html. |
152 | * \value FriendlyMimeType The descriptive name for the MIME type, e.g. HTML Document. |
153 | * \value[since 4.5] LinkDest The destination of a symbolic link. |
154 | * \value[since 4.5] LocalPathOrUrl The local path to the file or the URL in case it is not a local file. |
155 | * \value[since 4.6] Comment A simple comment that can be displayed to the user as is. |
156 | * |
157 | * \sa setShowInformation() |
158 | * \sa showInformation() |
159 | * \sa information |
160 | */ |
161 | enum Information { |
162 | NoInformation, |
163 | Size, |
164 | Permissions, |
165 | OctalPermissions, |
166 | Owner, |
167 | OwnerAndGroup, |
168 | CreationTime, |
169 | ModificationTime, |
170 | AccessTime, |
171 | MimeType, |
172 | FriendlyMimeType, |
173 | LinkDest, |
174 | LocalPathOrUrl, |
175 | , |
176 | }; |
177 | Q_ENUM(Information) |
178 | |
179 | /*! |
180 | * \typedef KFileItemDelegate::InformationList |
181 | */ |
182 | typedef QList<Information> InformationList; |
183 | |
184 | /*! |
185 | * Constructs a new KFileItemDelegate. |
186 | * |
187 | * \a parent The parent object for the delegate. |
188 | */ |
189 | explicit KFileItemDelegate(QObject *parent = nullptr); |
190 | |
191 | /*! |
192 | * Destroys the item delegate. |
193 | */ |
194 | ~KFileItemDelegate() override; |
195 | |
196 | /*! |
197 | * Returns the nominal size for the item referred to by \a index, given the |
198 | * provided options. |
199 | * |
200 | * If the model provides a valid Qt::FontRole and/or Qt::TextAlignmentRole for the item, |
201 | * those will be used instead of the ones specified in the style options. |
202 | * |
203 | * This function is reimplemented from QAbstractItemDelegate. |
204 | * |
205 | * \a option The style options that should be used when painting the item. |
206 | * |
207 | * \a index The index to the item for which to return the size hint. |
208 | */ |
209 | QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override; |
210 | |
211 | /*! |
212 | * Paints the item indicated by \a index, using \a painter. |
213 | * |
214 | * The item will be drawn in the rectangle specified by option.rect. |
215 | * The correct size for that rectangle can be obtained by calling |
216 | * sizeHint(). |
217 | * |
218 | * This function will use the following data values if the model provides |
219 | * them for the item, in place of the values in \a option: |
220 | * |
221 | * \list |
222 | * \li Qt::FontRole The font that should be used for the display role. |
223 | * \li Qt::TextAlignmentRole The alignment of the display role. |
224 | * \li Qt::ForegroundRole The text color for the display role. |
225 | * \li Qt::BackgroundRole The background color for the item. |
226 | * \endlist |
227 | * |
228 | * This function is reimplemented from QAbstractItemDelegate. |
229 | * |
230 | * \a painter The painter with which to draw the item. |
231 | * |
232 | * \a option The style options that should be used when painting the item. |
233 | * |
234 | * \a index The index to the item that should be painted. |
235 | */ |
236 | void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; |
237 | |
238 | QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override; |
239 | |
240 | bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) override; |
241 | |
242 | void setEditorData(QWidget *editor, const QModelIndex &index) const override; |
243 | |
244 | void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override; |
245 | |
246 | void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override; |
247 | |
248 | /*! |
249 | * Sets the list of information lines that are shown below the icon label in list views. |
250 | * |
251 | * You will typically construct the list like this: |
252 | * \code |
253 | * KFileItemDelegate::InformationList list; |
254 | * list << KFileItemDelegate::FriendlyMimeType << KFileItemDelegate::Size; |
255 | * delegate->setShowInformation(list); |
256 | * \endcode |
257 | * |
258 | * The information lines will be displayed in the list order. |
259 | * The delegate will first draw the item label, and then as many information |
260 | * lines as will fit in the available space. |
261 | * |
262 | * \a list A list of information items that should be shown |
263 | */ |
264 | void setShowInformation(const InformationList &list); |
265 | |
266 | /*! |
267 | * Sets a single information line that is shown below the icon label in list views. |
268 | * |
269 | * This is a convenience function for when you only want to show a single line |
270 | * of information. |
271 | * |
272 | * \a information The information that should be shown |
273 | */ |
274 | void setShowInformation(Information information); |
275 | |
276 | /*! |
277 | * Returns the file item information that should be shown below item labels in list views. |
278 | */ |
279 | InformationList showInformation() const; |
280 | |
281 | /*! |
282 | * Sets the color used for drawing the text shadow. |
283 | * |
284 | * To enable text shadows, set the shadow color to a non-transparent color. |
285 | * To disable text shadows, set the color to Qt::transparent. |
286 | * |
287 | * \sa shadowColor() |
288 | */ |
289 | void setShadowColor(const QColor &color); |
290 | |
291 | /*! |
292 | * Returns the color used for the text shadow. |
293 | * |
294 | * \sa setShadowColor() |
295 | */ |
296 | QColor shadowColor() const; |
297 | |
298 | /*! |
299 | * Sets the horizontal and vertical offset for the text shadow. |
300 | * |
301 | * \sa shadowOffset() |
302 | */ |
303 | void setShadowOffset(const QPointF &offset); |
304 | |
305 | /*! |
306 | * Returns the offset used for the text shadow. |
307 | * |
308 | * \sa setShadowOffset() |
309 | */ |
310 | QPointF shadowOffset() const; |
311 | |
312 | /*! |
313 | * Sets the blur radius for the text shadow. |
314 | * |
315 | * \sa shadowBlur() |
316 | */ |
317 | void setShadowBlur(qreal radius); |
318 | |
319 | /*! |
320 | * Returns the blur radius for the text shadow. |
321 | * |
322 | * \sa setShadowBlur() |
323 | */ |
324 | qreal shadowBlur() const; |
325 | |
326 | /*! |
327 | * Sets the maximum size for KFileItemDelegate::sizeHint(). |
328 | * |
329 | * \sa maximumSize() |
330 | */ |
331 | void setMaximumSize(const QSize &size); |
332 | |
333 | /*! |
334 | * Returns the maximum size for KFileItemDelegate::sizeHint(). |
335 | * |
336 | * \sa setMaximumSize() |
337 | */ |
338 | QSize maximumSize() const; |
339 | |
340 | /*! |
341 | * Sets whether a tooltip should be shown if the display role is |
342 | * elided containing the full display role information. |
343 | * |
344 | * \note The tooltip will only be shown if the Qt::ToolTipRole differs |
345 | * from Qt::DisplayRole, or if they match, showToolTipWhenElided |
346 | * flag is set and the display role information is elided. |
347 | * \sa showToolTipWhenElided() |
348 | */ |
349 | void setShowToolTipWhenElided(bool showToolTip); |
350 | |
351 | /*! |
352 | * Returns whether a tooltip should be shown if the display role |
353 | * is elided containing the full display role information. |
354 | * |
355 | * \note The tooltip will only be shown if the Qt::ToolTipRole differs |
356 | * from Qt::DisplayRole, or if they match, showToolTipWhenElided |
357 | * flag is set and the display role information is elided. |
358 | * \sa setShowToolTipWhenElided() |
359 | */ |
360 | bool showToolTipWhenElided() const; |
361 | |
362 | /*! |
363 | * Returns the rectangle of the icon that is aligned inside the decoration |
364 | * rectangle. |
365 | */ |
366 | QRect iconRect(const QStyleOptionViewItem &option, const QModelIndex &index) const; |
367 | |
368 | /*! |
369 | * When the contents text needs to be wrapped, \a wrapMode strategy |
370 | * will be followed. |
371 | * |
372 | */ |
373 | void setWrapMode(QTextOption::WrapMode wrapMode); |
374 | |
375 | /*! |
376 | * Returns the wrapping strategy followed to show text when it needs |
377 | * wrapping. |
378 | * |
379 | */ |
380 | QTextOption::WrapMode wrapMode() const; |
381 | |
382 | /*! |
383 | * Enable/Disable the displaying of an animated overlay that is shown for any destination |
384 | * urls (in the view). When enabled, the animations (if any) will be drawn automatically. |
385 | * |
386 | * Only the files/folders that are visible and have jobs associated with them |
387 | * will display the animation. |
388 | * You would likely not want this enabled if you perform some kind of custom painting |
389 | * that takes up a whole item, and will just make this(and what you paint) look funky. |
390 | * |
391 | * Default is disabled. |
392 | * |
393 | * Note: The model (KDirModel) needs to have it's method called with the same |
394 | * value, when you make the call to this method. |
395 | */ |
396 | void setJobTransfersVisible(bool jobTransfersVisible); |
397 | |
398 | /*! |
399 | * Returns whether or not the displaying of job transfers is enabled. |
400 | * \sa setJobTransfersVisible() |
401 | */ |
402 | bool jobTransfersVisible() const; |
403 | |
404 | bool eventFilter(QObject *object, QEvent *event) override; |
405 | |
406 | /*! |
407 | * Returns the rectangle where selectionEmblem is being drawn |
408 | * |
409 | * \since 6.14 |
410 | */ |
411 | QRect selectionEmblemRect() const; |
412 | |
413 | /*! |
414 | * Set the rectangle where selectionEmblem should be drawn in. |
415 | * |
416 | * \since 6.14 |
417 | */ |
418 | void setSelectionEmblemRect(QRect rect, int iconSize); |
419 | |
420 | /*! |
421 | * \since 6.14 |
422 | */ |
423 | KFileItem fileItem(const QModelIndex &index) const; |
424 | |
425 | public Q_SLOTS: |
426 | bool helpEvent(QHelpEvent *event, QAbstractItemView *view, const QStyleOptionViewItem &option, const QModelIndex &index) override; |
427 | |
428 | /*! |
429 | * Returns the shape of the item as a region. |
430 | * |
431 | * The returned region can be used for precise hit testing of the item. |
432 | */ |
433 | QRegion shape(const QStyleOptionViewItem &option, const QModelIndex &index); |
434 | |
435 | private: |
436 | class Private; |
437 | std::unique_ptr<Private> const d; /// \internal |
438 | Q_DISABLE_COPY(KFileItemDelegate) |
439 | |
440 | void drawSelectionEmblem(QStyleOptionViewItem option, QPainter *painter, const QModelIndex &index) const; |
441 | }; |
442 | |
443 | #endif // KFILEITEMDELEGATE_H |
444 | |