File indexing completed on 2024-05-12 05:47:30

0001 /*
0002  * SPDX-FileCopyrightText: 2011 Peter Penz <peter.penz19@gmail.com>
0003  *
0004  * SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #ifndef KITEMLISTHEADERWIDGET_H
0008 #define KITEMLISTHEADERWIDGET_H
0009 
0010 #include "dolphin_export.h"
0011 
0012 #include <QGraphicsWidget>
0013 #include <QHash>
0014 #include <QList>
0015 
0016 class KItemModelBase;
0017 
0018 /**
0019  * @brief Widget the implements the header for KItemListView showing the currently used roles.
0020  *
0021  * The widget is an internal API, the user of KItemListView may only access the
0022  * class KItemListHeader.
0023  */
0024 class DOLPHIN_EXPORT KItemListHeaderWidget : public QGraphicsWidget
0025 {
0026     Q_OBJECT
0027 
0028 public:
0029     explicit KItemListHeaderWidget(QGraphicsWidget *parent = nullptr);
0030     ~KItemListHeaderWidget() override;
0031 
0032     void setModel(KItemModelBase *model);
0033     KItemModelBase *model() const;
0034 
0035     void setAutomaticColumnResizing(bool automatic);
0036     bool automaticColumnResizing() const;
0037 
0038     void setColumns(const QList<QByteArray> &roles);
0039     QList<QByteArray> columns() const;
0040 
0041     void setColumnWidth(const QByteArray &role, qreal width);
0042     qreal columnWidth(const QByteArray &role) const;
0043 
0044     /**
0045      * Sets the column-width that is required to show the role unclipped.
0046      */
0047     void setPreferredColumnWidth(const QByteArray &role, qreal width);
0048     qreal preferredColumnWidth(const QByteArray &role) const;
0049 
0050     void setOffset(qreal offset);
0051     qreal offset() const;
0052 
0053     void setSidePadding(qreal width);
0054     qreal sidePadding() const;
0055 
0056     qreal minimumColumnWidth() const;
0057 
0058     void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override;
0059 
0060 Q_SIGNALS:
0061     /**
0062      * Is emitted if the width of a visible role has been adjusted by the user with the mouse
0063      * (no signal is emitted if KItemListHeader::setVisibleRoleWidth() is invoked).
0064      */
0065     void columnWidthChanged(const QByteArray &role, qreal currentWidth, qreal previousWidth);
0066 
0067     void sidePaddingChanged(qreal width);
0068 
0069     /**
0070      * Is emitted if the user has released the mouse button after adjusting the
0071      * width of a visible role.
0072      */
0073     void columnWidthChangeFinished(const QByteArray &role, qreal currentWidth);
0074 
0075     /**
0076      * Is emitted if the position of the column has been changed.
0077      */
0078     void columnMoved(const QByteArray &role, int currentIndex, int previousIndex);
0079 
0080     /**
0081      * Is emitted if the user has changed the sort order by clicking on a
0082      * header item. The sort order of the model has already been adjusted to
0083      * the current sort order. Note that no signal will be emitted if the
0084      * sort order of the model has been changed without user interaction.
0085      */
0086     void sortOrderChanged(Qt::SortOrder current, Qt::SortOrder previous);
0087 
0088     /**
0089      * Is emitted if the user has changed the sort role by clicking on a
0090      * header item. The sort role of the model has already been adjusted to
0091      * the current sort role. Note that no signal will be emitted if the
0092      * sort role of the model has been changed without user interaction.
0093      */
0094     void sortRoleChanged(const QByteArray &current, const QByteArray &previous);
0095 
0096     void columnUnHovered(int columnIndex);
0097     void columnHovered(int columnIndex);
0098 
0099 protected:
0100     void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
0101     void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
0102     void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
0103     void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) override;
0104     void hoverEnterEvent(QGraphicsSceneHoverEvent *event) override;
0105     void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) override;
0106     void hoverMoveEvent(QGraphicsSceneHoverEvent *event) override;
0107 
0108 private Q_SLOTS:
0109     void slotSortRoleChanged(const QByteArray &current, const QByteArray &previous);
0110     void slotSortOrderChanged(Qt::SortOrder current, Qt::SortOrder previous);
0111 
0112 private:
0113     enum PaddingGrip {
0114         Leading,
0115         Trailing,
0116     };
0117 
0118     void paintRole(QPainter *painter, const QByteArray &role, const QRectF &rect, int orderIndex, QWidget *widget = nullptr) const;
0119 
0120     void updatePressedRoleIndex(const QPointF &pos);
0121     void updateHoveredIndex(const QPointF &pos);
0122     int roleIndexAt(const QPointF &pos) const;
0123     bool isAboveRoleGrip(const QPointF &pos, int roleIndex) const;
0124     bool isAbovePaddingGrip(const QPointF &pos, PaddingGrip paddingGrip) const;
0125 
0126     /**
0127      * Creates a pixmap of the role with the index \a roleIndex that is shown
0128      * during moving a role.
0129      */
0130     QPixmap createRolePixmap(int roleIndex) const;
0131 
0132     /**
0133      * @return Target index of the currently moving visible role based on the current
0134      *         state of m_movingRole.
0135      */
0136     int targetOfMovingRole() const;
0137 
0138     /**
0139      * @return x-position of the left border of the role \a role.
0140      */
0141     qreal roleXPosition(const QByteArray &role) const;
0142 
0143 private:
0144     enum RoleOperation { NoRoleOperation, ResizeRoleOperation, ResizePaddingColumnOperation, MoveRoleOperation };
0145 
0146     bool m_automaticColumnResizing;
0147     KItemModelBase *m_model;
0148     qreal m_offset;
0149     qreal m_sidePadding;
0150     QList<QByteArray> m_columns;
0151     QHash<QByteArray, qreal> m_columnWidths;
0152     QHash<QByteArray, qreal> m_preferredColumnWidths;
0153 
0154     int m_hoveredIndex;
0155     int m_pressedRoleIndex;
0156     RoleOperation m_roleOperation;
0157     QPointF m_pressedMousePos;
0158 
0159     struct MovingRole {
0160         QPixmap pixmap;
0161         int x;
0162         int xDec;
0163         int index;
0164     };
0165     MovingRole m_movingRole;
0166 };
0167 
0168 #endif