File indexing completed on 2024-04-28 05:45:11

0001 /*
0002  * SPDX-FileCopyrightText: 2012 Peter Penz <peter.penz19@gmail.com>
0003  *
0004  * SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #ifndef KSTANDARDITEMLISTWIDGET_H
0008 #define KSTANDARDITEMLISTWIDGET_H
0009 
0010 #include "dolphin_export.h"
0011 #include "kitemviews/kitemlistwidget.h"
0012 
0013 #include <QPixmap>
0014 #include <QPointF>
0015 #include <QStaticText>
0016 
0017 class KItemListRoleEditor;
0018 class KItemListStyleOption;
0019 class KItemListView;
0020 
0021 class DOLPHIN_EXPORT KStandardItemListWidgetInformant : public KItemListWidgetInformant
0022 {
0023 public:
0024     KStandardItemListWidgetInformant();
0025     ~KStandardItemListWidgetInformant() override;
0026 
0027     void calculateItemSizeHints(QVector<std::pair<qreal /* height */, bool /* isElided */>> &logicalHeightHints,
0028                                 qreal &logicalWidthHint,
0029                                 const KItemListView *view) const override;
0030 
0031     qreal preferredRoleColumnWidth(const QByteArray &role, int index, const KItemListView *view) const override;
0032 
0033 protected:
0034     /**
0035      * @return The value of the "text" role. The default implementation returns
0036      *         view->model()->data(index)["text"]. If a derived class can
0037      *         prevent the (possibly expensive) construction of the
0038      *         QHash<QByteArray, QVariant> returned by KItemModelBase::data(int),
0039      *         it can reimplement this function.
0040      */
0041     virtual QString itemText(int index, const KItemListView *view) const;
0042 
0043     /**
0044      * @return The value of the "isLink" role. The default implementation returns false.
0045      *         The derived class should reimplement this function, when information about
0046      *         links is available and in usage.
0047      */
0048     virtual bool itemIsLink(int index, const KItemListView *view) const;
0049 
0050     /**
0051      * @return String representation of the role \a role. The representation of
0052      *         a role might depend on other roles, so the values of all roles
0053      *         are passed as parameter.
0054      */
0055     virtual QString roleText(const QByteArray &role, const QHash<QByteArray, QVariant> &values) const;
0056 
0057     /**
0058     * @return A font based on baseFont which is customized for symlinks.
0059     */
0060     virtual QFont customizedFontForLinks(const QFont &baseFont) const;
0061 
0062     void calculateIconsLayoutItemSizeHints(QVector<std::pair<qreal, bool>> &logicalHeightHints, qreal &logicalWidthHint, const KItemListView *view) const;
0063     void calculateCompactLayoutItemSizeHints(QVector<std::pair<qreal, bool>> &logicalHeightHints, qreal &logicalWidthHint, const KItemListView *view) const;
0064     void calculateDetailsLayoutItemSizeHints(QVector<std::pair<qreal, bool>> &logicalHeightHints, qreal &logicalWidthHint, const KItemListView *view) const;
0065 
0066     friend class KStandardItemListWidget; // Accesses roleText()
0067 };
0068 
0069 /**
0070  * @brief ItemList widget implementation for KStandardItemListView and KStandardItemModel.
0071  */
0072 class DOLPHIN_EXPORT KStandardItemListWidget : public KItemListWidget
0073 {
0074     Q_OBJECT
0075 
0076 public:
0077     enum Layout { IconsLayout, CompactLayout, DetailsLayout };
0078 
0079     KStandardItemListWidget(KItemListWidgetInformant *informant, QGraphicsItem *parent);
0080     ~KStandardItemListWidget() override;
0081 
0082     void setLayout(Layout layout);
0083 
0084     void setHighlightEntireRow(bool highlightEntireRow);
0085     bool highlightEntireRow() const;
0086 
0087     void setSupportsItemExpanding(bool supportsItemExpanding);
0088     bool supportsItemExpanding() const;
0089 
0090     void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override;
0091 
0092     QRectF iconRect() const override;
0093     QRectF textRect() const override;
0094     QRectF textFocusRect() const override;
0095     QRectF selectionRect() const override;
0096     QRectF expansionToggleRect() const override;
0097     QRectF selectionToggleRect() const override;
0098     QPixmap createDragPixmap(const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override;
0099 
0100     static KItemListWidgetInformant *createInformant();
0101 
0102 protected:
0103     /**
0104      * Invalidates the cache which results in calling KStandardItemListWidget::refreshCache() as
0105      * soon as the item need to gets repainted.
0106      */
0107     void invalidateCache();
0108 
0109     /**
0110      * Invalidates the icon cache which results in calling KStandardItemListWidget::refreshCache() as
0111      * soon as the item needs to get repainted.
0112      */
0113     void invalidateIconCache();
0114 
0115     /**
0116      * Is called if the cache got invalidated by KStandardItemListWidget::invalidateCache().
0117      * The default implementation is empty.
0118      */
0119     virtual void refreshCache();
0120 
0121     /**
0122      * @return True if the give role should be right aligned when showing it inside a column.
0123      *         Per default false is returned.
0124      */
0125     virtual bool isRoleRightAligned(const QByteArray &role) const;
0126 
0127     /**
0128      * @return True if the item should be visually marked as hidden item. Per default
0129      *         false is returned.
0130      */
0131     virtual bool isHidden() const;
0132 
0133     /**
0134      * @return A font based on baseFont which is customized according to the data shown in the widget.
0135      */
0136     virtual QFont customizedFont(const QFont &baseFont) const;
0137 
0138     virtual QPalette::ColorRole normalTextColorRole() const;
0139 
0140     void setTextColor(const QColor &color);
0141     QColor textColor(const QWidget &widget) const;
0142 
0143     void setOverlay(const QPixmap &overlay);
0144     QPixmap overlay() const;
0145 
0146     /**
0147      * @see KStandardItemListWidgetInformant::roleText().
0148      */
0149     QString roleText(const QByteArray &role, const QHash<QByteArray, QVariant> &values) const;
0150 
0151     /**
0152      * Fixes:
0153      * Select the text without MIME-type extension
0154      * This is file-item-specific and should be moved
0155      * into KFileItemListWidget.
0156      *
0157      * Inherited classes can define, if the MIME-type extension
0158      * should be selected or not.
0159      *
0160      * @return Selection length (with or without MIME-type extension)
0161      */
0162     virtual int selectionLength(const QString &text) const;
0163 
0164     void dataChanged(const QHash<QByteArray, QVariant> &current, const QSet<QByteArray> &roles = QSet<QByteArray>()) override;
0165     void visibleRolesChanged(const QList<QByteArray> &current, const QList<QByteArray> &previous) override;
0166     void columnWidthChanged(const QByteArray &role, qreal current, qreal previous) override;
0167     void sidePaddingChanged(qreal width) override;
0168     void styleOptionChanged(const KItemListStyleOption &current, const KItemListStyleOption &previous) override;
0169     void hoveredChanged(bool hovered) override;
0170     void selectedChanged(bool selected) override;
0171     void siblingsInformationChanged(const QBitArray &current, const QBitArray &previous) override;
0172     void editedRoleChanged(const QByteArray &current, const QByteArray &previous) override;
0173     void iconSizeChanged(int current, int previous) override;
0174     void resizeEvent(QGraphicsSceneResizeEvent *event) override;
0175     void showEvent(QShowEvent *event) override;
0176     void hideEvent(QHideEvent *event) override;
0177     bool event(QEvent *event) override;
0178 
0179     struct TextInfo {
0180         QPointF pos;
0181         QStaticText staticText;
0182     };
0183     void updateAdditionalInfoTextColor();
0184 
0185 public Q_SLOTS:
0186     void finishRoleEditing();
0187 
0188 private Q_SLOTS:
0189     void slotCutItemsChanged();
0190     void slotRoleEditingCanceled(const QByteArray &role, const QVariant &value);
0191     void slotRoleEditingFinished(const QByteArray &role, const QVariant &value);
0192 
0193 private:
0194     void triggerCacheRefreshing();
0195     void updateExpansionArea();
0196     void updatePixmapCache();
0197 
0198     void updateTextsCache();
0199     void updateIconsLayoutTextCache();
0200     void updateCompactLayoutTextCache();
0201     void updateDetailsLayoutTextCache();
0202 
0203     void drawPixmap(QPainter *painter, const QPixmap &pixmap);
0204     void drawSiblingsInformation(QPainter *painter);
0205 
0206     QRectF roleEditingRect(const QByteArray &role) const;
0207 
0208     QString elideRightKeepExtension(const QString &text, int elidingWidth) const;
0209 
0210     /**
0211      * Escapes text for display purposes.
0212      *
0213      * Replaces '\n' with Unicode line break (U+21B5).
0214      */
0215     QString escapeString(const QString &text) const;
0216 
0217     /**
0218      * Closes the role editor and returns the focus back
0219      * to the KItemListContainer.
0220      */
0221     void closeRoleEditor();
0222 
0223     QPixmap pixmapForIcon(const QString &name, const QStringList &overlays, int size, QIcon::Mode mode) const;
0224 
0225     /**
0226      * @return Preferred size of the rating-image based on the given
0227      *         style-option. The height of the font is taken as
0228      *         reference.
0229      */
0230     static QSizeF preferredRatingSize(const KItemListStyleOption &option);
0231 
0232     /**
0233      * @return Horizontal padding in pixels that is added to the required width of
0234      *         a column to display the content.
0235      */
0236     static qreal columnPadding(const KItemListStyleOption &option);
0237 
0238 protected:
0239     QHash<QByteArray, TextInfo *> m_textInfo; // PlacesItemListWidget needs to access this
0240 
0241 private:
0242     bool m_isCut;
0243     bool m_isHidden;
0244     QFont m_customizedFont;
0245     QFontMetrics m_customizedFontMetrics;
0246     bool m_isExpandable;
0247     bool m_highlightEntireRow;
0248     bool m_supportsItemExpanding;
0249 
0250     bool m_dirtyLayout;
0251     bool m_dirtyContent;
0252     QSet<QByteArray> m_dirtyContentRoles;
0253 
0254     Layout m_layout;
0255     QPointF m_pixmapPos;
0256     QPixmap m_pixmap;
0257     QSize m_scaledPixmapSize; //Size of the pixmap in device independent pixels
0258 
0259     qreal m_columnWidthSum;
0260     QRectF m_iconRect; // Cache for KItemListWidget::iconRect()
0261     QPixmap m_hoverPixmap; // Cache for modified m_pixmap when hovering the item
0262 
0263     QRectF m_textRect;
0264 
0265     QList<QByteArray> m_sortedVisibleRoles;
0266 
0267     QRectF m_expansionArea;
0268 
0269     QColor m_customTextColor;
0270     QColor m_additionalInfoTextColor;
0271 
0272     QPixmap m_overlay;
0273     QPixmap m_rating;
0274 
0275     KItemListRoleEditor *m_roleEditor;
0276     KItemListRoleEditor *m_oldRoleEditor;
0277 
0278     friend class KStandardItemListWidgetInformant; // Accesses private static methods to be able to
0279                                                    // share a common layout calculation
0280 };
0281 
0282 #endif