]> cloud.milkyroute.net Git - dolphin.git/blob - src/kitemviews/kstandarditemlistwidget.h
New selection effects
[dolphin.git] / src / kitemviews / kstandarditemlistwidget.h
1 /*
2 * SPDX-FileCopyrightText: 2012 Peter Penz <peter.penz19@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7 #ifndef KSTANDARDITEMLISTWIDGET_H
8 #define KSTANDARDITEMLISTWIDGET_H
9
10 #include "dolphin_export.h"
11 #include "kitemviews/kitemlistwidget.h"
12
13 #include <QPixmap>
14 #include <QPointer>
15 #include <QPointF>
16 #include <QStaticText>
17
18 class KItemListRoleEditor;
19 class KItemListStyleOption;
20 class KItemListView;
21 class QVariantAnimation;
22
23 /**
24 * @brief standard implementation of the ItemList widget informant for use with KStandardItemListView and KStandardItemModel.
25 *
26 * @see KItemListWidgetInformant
27 */
28 class DOLPHIN_EXPORT KStandardItemListWidgetInformant : public KItemListWidgetInformant
29 {
30 public:
31 KStandardItemListWidgetInformant();
32 ~KStandardItemListWidgetInformant() override;
33
34 void calculateItemSizeHints(QVector<std::pair<qreal /* height */, bool /* isElided */>> &logicalHeightHints,
35 qreal &logicalWidthHint,
36 const KItemListView *view) const override;
37
38 qreal preferredRoleColumnWidth(const QByteArray &role, int index, const KItemListView *view) const override;
39
40 protected:
41 /**
42 * @return The value of the "text" role. The default implementation returns
43 * view->model()->data(index)["text"]. If a derived class can
44 * prevent the (possibly expensive) construction of the
45 * QHash<QByteArray, QVariant> returned by KItemModelBase::data(int),
46 * it can reimplement this function.
47 */
48 virtual QString itemText(int index, const KItemListView *view) const;
49
50 /**
51 * @return The value of the "isLink" role. The default implementation returns false.
52 * The derived class should reimplement this function, when information about
53 * links is available and in usage.
54 */
55 virtual bool itemIsLink(int index, const KItemListView *view) const;
56
57 /** Configure whether the requested text should be optimized for viewing on a screen or for being read out aloud by a text-to-speech engine. */
58 enum class ForUsageAs { DisplayedText, SpokenText };
59
60 /**
61 * @param role The role the text is being requested for.
62 * @param values The data of the item. All the data is passed because the text might depend on multiple data points.
63 * @param forUsageAs Whether the roleText should be optimized for displaying (i.e. kept somewhat short) or optimized for speaking e.g. by screen readers
64 * or text-to-speech in general (i.e. by prefering announcing a month as July instead of as the number 7).
65 * @return String representation of the role \a role. The representation of
66 * a role might depend on other roles, so the values of all roles
67 * are passed as parameter.
68 */
69 virtual QString roleText(const QByteArray &role, const QHash<QByteArray, QVariant> &values, ForUsageAs forUsageAs = ForUsageAs::DisplayedText) const;
70
71 /**
72 * @return A font based on baseFont which is customized for symlinks.
73 */
74 virtual QFont customizedFontForLinks(const QFont &baseFont) const;
75
76 void calculateIconsLayoutItemSizeHints(QVector<std::pair<qreal, bool>> &logicalHeightHints, qreal &logicalWidthHint, const KItemListView *view) const;
77 void calculateCompactLayoutItemSizeHints(QVector<std::pair<qreal, bool>> &logicalHeightHints, qreal &logicalWidthHint, const KItemListView *view) const;
78 void calculateDetailsLayoutItemSizeHints(QVector<std::pair<qreal, bool>> &logicalHeightHints, qreal &logicalWidthHint, const KItemListView *view) const;
79
80 friend class KStandardItemListWidget; // Accesses roleText()
81 };
82
83 /**
84 * @brief standard implementation of an ItemList widget for KStandardItemListView and KStandardItemModel.
85 *
86 * @see KItemListWidget
87 */
88 class DOLPHIN_EXPORT KStandardItemListWidget : public KItemListWidget
89 {
90 Q_OBJECT
91
92 public:
93 enum Layout { IconsLayout, CompactLayout, DetailsLayout };
94
95 KStandardItemListWidget(KItemListWidgetInformant *informant, QGraphicsItem *parent);
96 ~KStandardItemListWidget() override;
97
98 void setLayout(Layout layout);
99
100 void setHighlightEntireRow(bool highlightEntireRow);
101 bool highlightEntireRow() const;
102
103 void setSupportsItemExpanding(bool supportsItemExpanding);
104 bool supportsItemExpanding() const;
105
106 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override;
107
108 QRectF textRect() const override;
109 QRectF textFocusRect() const override;
110 QRectF selectionRectFull() const override;
111 QRectF selectionRectCore() const override;
112 QRectF expansionToggleRect() const override;
113 QRectF selectionToggleRect() const override;
114 QPixmap createDragPixmap(const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override;
115 /** @see KItemListWidget::startActivateSoonAnimation() */
116 void startActivateSoonAnimation(int timeUntilActivation) override;
117
118 static KItemListWidgetInformant *createInformant();
119
120 protected:
121 /**
122 * Invalidates the cache which results in calling KStandardItemListWidget::refreshCache() as
123 * soon as the item need to gets repainted.
124 */
125 void invalidateCache();
126
127 /**
128 * Invalidates the icon cache which results in calling KStandardItemListWidget::refreshCache() as
129 * soon as the item needs to get repainted.
130 */
131 void invalidateIconCache();
132
133 /**
134 * Is called if the cache got invalidated by KStandardItemListWidget::invalidateCache().
135 * The default implementation is empty.
136 */
137 virtual void refreshCache();
138
139 /**
140 * @return True if the give role should be right aligned when showing it inside a column.
141 * Per default false is returned.
142 */
143 virtual bool isRoleRightAligned(const QByteArray &role) const;
144
145 /**
146 * @return True if the item should be visually marked as hidden item. Per default
147 * false is returned.
148 */
149 virtual bool isHidden() const;
150
151 /**
152 * @return A font based on baseFont which is customized according to the data shown in the widget.
153 */
154 virtual QFont customizedFont(const QFont &baseFont) const;
155
156 virtual QPalette::ColorRole normalTextColorRole() const;
157
158 void setTextColor(const QColor &color);
159 QColor textColor(const QWidget &widget) const;
160
161 void setOverlays(QHash<Qt::Corner, QString> &overlay);
162 QHash<Qt::Corner, QString> overlays() const;
163
164 /**
165 * @see KStandardItemListWidgetInformant::roleText().
166 */
167 QString roleText(const QByteArray &role, const QHash<QByteArray, QVariant> &values) const;
168
169 static int numberOfUnicodeCharactersIn(const QString &text);
170
171 /**
172 * @return Selection length (with or without MIME-type extension) in number of unicode characters, which might be different from number of QChars.
173 */
174 virtual int selectionLength(const QString &text) const;
175
176 void dataChanged(const QHash<QByteArray, QVariant> &current, const QSet<QByteArray> &roles = QSet<QByteArray>()) override;
177 void visibleRolesChanged(const QList<QByteArray> &current, const QList<QByteArray> &previous) override;
178 void columnWidthChanged(const QByteArray &role, qreal current, qreal previous) override;
179 void sidePaddingChanged(qreal leftPaddingWidth, qreal rightPaddingWidth) override;
180 void styleOptionChanged(const KItemListStyleOption &current, const KItemListStyleOption &previous) override;
181 void hoveredChanged(bool hovered) override;
182 void selectedChanged(bool selected) override;
183 void siblingsInformationChanged(const QBitArray &current, const QBitArray &previous) override;
184 void editedRoleChanged(const QByteArray &current, const QByteArray &previous) override;
185 void iconSizeChanged(int current, int previous) override;
186 void resizeEvent(QGraphicsSceneResizeEvent *event) override;
187 void showEvent(QShowEvent *event) override;
188 void hideEvent(QHideEvent *event) override;
189 bool event(QEvent *event) override;
190
191 struct TextInfo {
192 QPointF pos;
193 QStaticText staticText;
194 };
195 void updateAdditionalInfoTextColor();
196
197 public Q_SLOTS:
198 void finishRoleEditing();
199
200 private Q_SLOTS:
201 void slotCutItemsChanged();
202 void slotRoleEditingCanceled(const QByteArray &role, const QVariant &value);
203 void slotRoleEditingFinished(const QByteArray &role, const QVariant &value);
204
205 private:
206 void triggerCacheRefreshing();
207 void updateExpansionArea();
208 void updatePixmapCache();
209
210 void updateTextsCache();
211 void updateIconsLayoutTextCache();
212 void updateCompactLayoutTextCache();
213 void updateDetailsLayoutTextCache();
214
215 QPixmap addOverlays(const QPixmap &pixmap,
216 const QHash<Qt::Corner, QString> &overlays,
217 const QSize &size,
218 qreal devicePixelRatioF,
219 QIcon::Mode mode = QIcon::Normal) const;
220
221 void drawPixmap(QPainter *painter, const QPixmap &pixmap);
222 /** Draw the lines and arrows that visualize the expanded state and level of this row. */
223 void drawSiblingsInformation(QPainter *painter);
224
225 QRectF roleEditingRect(const QByteArray &role) const;
226
227 QString elideText(QString text, qreal elidingWidth) const;
228
229 /**
230 * Escapes text for display purposes.
231 *
232 * Replaces '\n' with Unicode line break (U+21B5).
233 */
234 QString escapeString(const QString &text) const;
235
236 /**
237 * Closes the role editor and returns the focus back
238 * to the KItemListContainer.
239 */
240 void closeRoleEditor();
241
242 QPixmap pixmapForIcon(const QString &name, const QSize &size, QIcon::Mode mode) const;
243
244 /**
245 * @return Preferred size of the rating-image based on the given
246 * style-option. The height of the font is taken as
247 * reference.
248 */
249 static QSizeF preferredRatingSize(const KItemListStyleOption &option);
250
251 /**
252 * @return Horizontal padding in pixels that is added to the required width of
253 * a column to display the content.
254 */
255 static qreal columnPadding(const KItemListStyleOption &option);
256
257 /** @returns whether the usual icon should be shown or not. */
258 bool isIconControlledByActivateSoonAnimation() const;
259
260 protected:
261 QHash<QByteArray, TextInfo *> m_textInfo; // PlacesItemListWidget needs to access this
262
263 private:
264 bool m_isCut;
265 bool m_isHidden;
266 QFont m_customizedFont;
267 QFontMetrics m_customizedFontMetrics;
268 bool m_isExpandable;
269 bool m_highlightEntireRow;
270 bool m_supportsItemExpanding;
271
272 bool m_dirtyLayout;
273 bool m_dirtyContent;
274 QSet<QByteArray> m_dirtyContentRoles;
275
276 Layout m_layout;
277 QPointF m_pixmapPos;
278 QPixmap m_pixmap;
279 QSize m_scaledPixmapSize; //Size of the pixmap in device independent pixels
280
281 qreal m_columnWidthSum;
282 QRectF m_iconRect; // Cache for KItemListWidget::iconRect()
283
284 QRectF m_textRect;
285
286 QList<QByteArray> m_sortedVisibleRoles;
287
288 QRectF m_expansionArea;
289
290 QColor m_customTextColor;
291 QColor m_additionalInfoTextColor;
292
293 QHash<Qt::Corner, QString> m_overlays;
294 QPixmap m_rating;
295
296 KItemListRoleEditor *m_roleEditor;
297 KItemListRoleEditor *m_oldRoleEditor;
298
299 /** @see startActivateSoonAnimation() */
300 QPointer<QVariantAnimation> m_activateSoonAnimation;
301
302 friend class KStandardItemListWidgetInformant; // Accesses private static methods to be able to
303 // share a common layout calculation
304 };
305
306 #endif