]> cloud.milkyroute.net Git - dolphin.git/blob - src/kitemviews/private/kitemlistheaderwidget.h
Mirror details view mode for right-to-left languages
[dolphin.git] / src / kitemviews / private / kitemlistheaderwidget.h
1 /*
2 * SPDX-FileCopyrightText: 2011 Peter Penz <peter.penz19@gmail.com>
3 * SPDX-FileCopyrightText: 2022, 2024 Felix Ernst <felixernst@kde.org>
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 */
7
8 #ifndef KITEMLISTHEADERWIDGET_H
9 #define KITEMLISTHEADERWIDGET_H
10
11 #include "dolphin_export.h"
12
13 #include <QGraphicsWidget>
14 #include <QHash>
15 #include <QList>
16
17 class KItemModelBase;
18
19 /**
20 * @brief Widget the implements the header for KItemListView showing the currently used roles.
21 *
22 * The widget is an internal API, the user of KItemListView may only access the
23 * class KItemListHeader.
24 */
25 class DOLPHIN_EXPORT KItemListHeaderWidget : public QGraphicsWidget
26 {
27 Q_OBJECT
28
29 public:
30 explicit KItemListHeaderWidget(QGraphicsWidget *parent = nullptr);
31 ~KItemListHeaderWidget() override;
32
33 void setModel(KItemModelBase *model);
34 KItemModelBase *model() const;
35
36 void setAutomaticColumnResizing(bool automatic);
37 bool automaticColumnResizing() const;
38
39 void setColumns(const QList<QByteArray> &roles);
40 QList<QByteArray> columns() const;
41
42 void setColumnWidth(const QByteArray &role, qreal width);
43 qreal columnWidth(const QByteArray &role) const;
44
45 /**
46 * Sets the column-width that is required to show the role unclipped.
47 */
48 void setPreferredColumnWidth(const QByteArray &role, qreal width);
49 qreal preferredColumnWidth(const QByteArray &role) const;
50
51 void setOffset(qreal offset);
52 qreal offset() const;
53
54 void setSidePadding(qreal leftPaddingWidth, qreal rightPaddingWidth);
55 qreal leftPadding() const;
56 qreal rightPadding() const;
57
58 qreal minimumColumnWidth() const;
59
60 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override;
61
62 Q_SIGNALS:
63 /**
64 * Is emitted if the width of a visible role has been adjusted by the user with the mouse
65 * (no signal is emitted if KItemListHeader::setVisibleRoleWidth() is invoked).
66 */
67 void columnWidthChanged(const QByteArray &role, qreal currentWidth, qreal previousWidth);
68
69 void sidePaddingChanged(qreal leftPaddingWidth, qreal rightPaddingWidth);
70
71 /**
72 * Is emitted if the user has released the mouse button after adjusting the
73 * width of a visible role.
74 */
75 void columnWidthChangeFinished(const QByteArray &role, qreal currentWidth);
76
77 /**
78 * Is emitted if the position of the column has been changed.
79 */
80 void columnMoved(const QByteArray &role, int currentIndex, int previousIndex);
81
82 /**
83 * Is emitted if the user has changed the sort order by clicking on a
84 * header item. The sort order of the model has already been adjusted to
85 * the current sort order. Note that no signal will be emitted if the
86 * sort order of the model has been changed without user interaction.
87 */
88 void sortOrderChanged(Qt::SortOrder current, Qt::SortOrder previous);
89
90 /**
91 * Is emitted if the user has changed the sort role by clicking on a
92 * header item. The sort role of the model has already been adjusted to
93 * the current sort role. Note that no signal will be emitted if the
94 * sort role of the model has been changed without user interaction.
95 */
96 void sortRoleChanged(const QByteArray &current, const QByteArray &previous);
97
98 void columnUnHovered(int columnIndex);
99 void columnHovered(int columnIndex);
100
101 protected:
102 void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
103 void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
104 void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
105 void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) override;
106 void hoverEnterEvent(QGraphicsSceneHoverEvent *event) override;
107 void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) override;
108 void hoverMoveEvent(QGraphicsSceneHoverEvent *event) override;
109
110 private Q_SLOTS:
111 void slotSortRoleChanged(const QByteArray &current, const QByteArray &previous);
112 void slotSortOrderChanged(Qt::SortOrder current, Qt::SortOrder previous);
113
114 private:
115 struct Grip {
116 QByteArray roleToTheLeft;
117 QByteArray roleToTheRight;
118 };
119
120 void paintRole(QPainter *painter, const QByteArray &role, const QRectF &rect, int orderIndex, QWidget *widget = nullptr) const;
121
122 void updatePressedRoleIndex(const QPointF &pos);
123 void updateHoveredIndex(const QPointF &pos);
124 int roleIndexAt(const QPointF &pos) const;
125
126 /**
127 * @returns std::nullopt if none of the resize grips is below @p position.
128 * Otherwise returns a Grip defined by the two roles on each side of @p position.
129 * @note If the Grip is between a padding and a role, a class-specific "leftPadding" or "rightPadding" role is used.
130 */
131 std::optional<const Grip> isAboveResizeGrip(const QPointF &position) const;
132
133 /**
134 * Creates a pixmap of the role with the index \a roleIndex that is shown
135 * during moving a role.
136 */
137 QPixmap createRolePixmap(int roleIndex) const;
138
139 /**
140 * @return Target index of the currently moving visible role based on the current
141 * state of m_movingRole.
142 */
143 int targetOfMovingRole() const;
144
145 /**
146 * @return x-position of the left border of the role \a role.
147 */
148 qreal roleXPosition(const QByteArray &role) const;
149
150 /**
151 * @returns 0 for left-to-right layoutDirection().
152 * Otherwise returns the space that is left over when space is distributed between padding and role columns.
153 * Used to make the column headers stay above their information columns for right-to-left layout directions.
154 */
155 qreal unusedSpace() const;
156
157 private:
158 bool m_automaticColumnResizing;
159 KItemModelBase *m_model;
160 qreal m_offset;
161 qreal m_leftPadding;
162 qreal m_rightPadding;
163 QList<QByteArray> m_columns;
164 QHash<QByteArray, qreal> m_columnWidths;
165 QHash<QByteArray, qreal> m_preferredColumnWidths;
166
167 int m_hoveredIndex;
168 std::optional<Grip> m_pressedGrip;
169 int m_pressedRoleIndex;
170 QPointF m_pressedMousePos;
171
172 struct MovingRole {
173 QPixmap pixmap;
174 int x;
175 int xDec;
176 int index;
177 };
178 MovingRole m_movingRole;
179 };
180
181 #endif