| 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 | |