1/*
2 This file is part of the KDE libraries
3
4 SPDX-FileCopyrightText: 2011 Aurélien Gâteau <agateau@kde.org>
5 SPDX-FileCopyrightText: 2014 Dominik Haumann <dhaumann@kde.org>
6
7 SPDX-License-Identifier: LGPL-2.1-or-later
8*/
9#ifndef KMESSAGEWIDGET_H
10#define KMESSAGEWIDGET_H
11
12#include <kwidgetsaddons_export.h>
13
14#include <QFrame>
15#include <memory>
16
17/**
18 * @class KMessageWidget kmessagewidget.h KMessageWidget
19 *
20 * @short A widget to provide feedback or propose opportunistic interactions.
21 *
22 * KMessageWidget can be used to provide inline positive or negative
23 * feedback, or to implement opportunistic interactions.
24 *
25 * As a feedback widget, KMessageWidget provides a less intrusive alternative
26 * to "OK Only" message boxes. If you want to avoid a modal KMessageBox,
27 * consider using KMessageWidget instead.
28 *
29 * Examples of KMessageWidget look as follows, all of them having an icon set
30 * with setIcon(), and the first three show a close button:
31 *
32 * \image html kmessagewidget.png "KMessageWidget with different message types"
33 *
34 * <b>Negative feedback</b>
35 *
36 * The KMessageWidget can be used as a secondary indicator of failure: the
37 * first indicator is usually the fact the action the user expected to happen
38 * did not happen.
39 *
40 * Example: User fills a form, clicks "Submit".
41 *
42 * @li Expected feedback: form closes
43 * @li First indicator of failure: form stays there
44 * @li Second indicator of failure: a KMessageWidget appears on top of the
45 * form, explaining the error condition
46 *
47 * When used to provide negative feedback, KMessageWidget should be placed
48 * close to its context. In the case of a form, it should appear on top of the
49 * form entries.
50 *
51 * KMessageWidget should get inserted in the existing layout. Space should not
52 * be reserved for it, otherwise it becomes "dead space", ignored by the user.
53 * KMessageWidget should also not appear as an overlay to prevent blocking
54 * access to elements the user needs to interact with to fix the failure.
55 *
56 * <b>Positive feedback</b>
57 *
58 * KMessageWidget can be used for positive feedback but it shouldn't be
59 * overused. It is often enough to provide feedback by simply showing the
60 * results of an action.
61 *
62 * Examples of acceptable uses:
63 *
64 * @li Confirm success of "critical" transactions
65 * @li Indicate completion of background tasks
66 *
67 * Example of unadapted uses:
68 *
69 * @li Indicate successful saving of a file
70 * @li Indicate a file has been successfully removed
71 *
72 * <b>Opportunistic interaction</b>
73 *
74 * Opportunistic interaction is the situation where the application suggests to
75 * the user an action he could be interested in perform, either based on an
76 * action the user just triggered or an event which the application noticed.
77 *
78 * Example of acceptable uses:
79 *
80 * @li A browser can propose remembering a recently entered password
81 * @li A music collection can propose ripping a CD which just got inserted
82 * @li A chat application may notify the user a "special friend" just connected
83 *
84 * @author Aurélien Gâteau <agateau@kde.org>
85 * @since 4.7
86 */
87class KWIDGETSADDONS_EXPORT KMessageWidget : public QFrame
88{
89 Q_OBJECT
90
91 Q_PROPERTY(QString text READ text WRITE setText)
92 Q_PROPERTY(Qt::TextFormat textFormat READ textFormat WRITE setTextFormat)
93 Q_PROPERTY(bool wordWrap READ wordWrap WRITE setWordWrap)
94 Q_PROPERTY(bool closeButtonVisible READ isCloseButtonVisible WRITE setCloseButtonVisible)
95 Q_PROPERTY(MessageType messageType READ messageType WRITE setMessageType)
96 Q_PROPERTY(QIcon icon READ icon WRITE setIcon)
97 Q_PROPERTY(Position position READ position WRITE setPosition)
98public:
99 /**
100 * Available message types.
101 * The background colors are chosen depending on the message type.
102 */
103 enum MessageType {
104 Positive, ///< Positive message type
105 Information, ///< Information message type
106 Warning, ///< Warning message type
107 Error, ///< Error message type
108 };
109 Q_ENUM(MessageType)
110
111 /**
112 * Position of the KMessageWidget
113 *
114 * This will update the look of the KMessageWidget to be appropriate to the position.
115 * @since 6.0
116 */
117 enum Position {
118 Inline, ///< The message widget is display inside the content.
119 Header, ///< The message widget is displayed as header.
120 Footer, ///< The message widget is displayed as footer.
121 };
122 Q_ENUM(Position);
123
124 /**
125 * Constructs a KMessageWidget with the specified @p parent.
126 */
127 explicit KMessageWidget(QWidget *parent = nullptr);
128
129 /**
130 * Constructs a KMessageWidget with the specified @p parent and
131 * contents @p text.
132 */
133 explicit KMessageWidget(const QString &text, QWidget *parent = nullptr);
134
135 /**
136 * Destructor.
137 */
138 ~KMessageWidget() override;
139
140 /**
141 * Get the position of this message. By default this is KMessageWidget::Inline.
142 * @see setPosition()
143 * @since 6.0
144 */
145 Position position() const;
146
147 /**
148 * Get the text of this message widget.
149 * @see setText()
150 */
151 QString text() const;
152
153 /**
154 * Get the text format of the message widget's label.
155 * @see QLabel::textFormat()
156 * @since 6.0
157 */
158 Qt::TextFormat textFormat() const;
159
160 /**
161 * Set the text format of the message widget's label.
162 * @see QLabel::setTextFormat()
163 * @since 6.0
164 */
165 void setTextFormat(Qt::TextFormat textFormat);
166
167 /**
168 * Check whether word wrap is enabled.
169 *
170 * If word wrap is enabled, the message widget wraps the displayed text
171 * as required to the available width of the widget. This is useful to
172 * avoid breaking widget layouts.
173 *
174 * @see setWordWrap()
175 */
176 bool wordWrap() const;
177
178 /**
179 * Check whether the close button is visible.
180 *
181 * @see setCloseButtonVisible()
182 */
183 bool isCloseButtonVisible() const;
184
185 /**
186 * Get the type of this message.
187 * By default, the type is set to KMessageWidget::Information.
188 *
189 * @see KMessageWidget::MessageType, setMessageType()
190 */
191 MessageType messageType() const;
192
193 /**
194 * Add @p action to the message widget.
195 * For each action a button is added to the message widget in the
196 * order the actions were added.
197 *
198 * @param action the action to add
199 * @see removeAction(), QWidget::actions()
200 */
201 void addAction(QAction *action);
202
203 /**
204 * Remove @p action from the message widget.
205 *
206 * @param action the action to remove
207 * @see KMessageWidget::MessageType, addAction(), setMessageType()
208 */
209 void removeAction(QAction *action);
210
211 /**
212 * Clears all actions from the message widget.
213 * @see KMessageWidget::MessageType, addAction() and removeAction()
214 * @since 5.100
215 */
216 void clearActions();
217
218 /**
219 * Returns the preferred size of the message widget.
220 */
221 QSize sizeHint() const override;
222
223 /**
224 * Returns the minimum size of the message widget.
225 */
226 QSize minimumSizeHint() const override;
227
228 /**
229 * Returns the required height for @p width.
230 * @param width the width in pixels
231 */
232 int heightForWidth(int width) const override;
233
234 /**
235 * The icon shown on the left of the text. By default, no icon is shown.
236 * @since 4.11
237 */
238 QIcon icon() const;
239
240 /**
241 * Check whether the hide animation started by calling animatedHide()
242 * is still running. If animations are disabled, this function always
243 * returns @e false.
244 *
245 * @see animatedHide(), hideAnimationFinished()
246 * @since 5.0
247 */
248 bool isHideAnimationRunning() const;
249
250 /**
251 * Check whether the show animation started by calling animatedShow()
252 * is still running. If animations are disabled, this function always
253 * returns @e false.
254 *
255 * @see animatedShow(), showAnimationFinished()
256 * @since 5.0
257 */
258 bool isShowAnimationRunning() const;
259
260public Q_SLOTS:
261 /**
262 * Set the text of the message widget to @p text.
263 * If the message widget is already visible, the text changes on the fly.
264 *
265 * @param text the text to display, rich text is allowed
266 * @see text()
267 */
268 void setText(const QString &text);
269
270 /**
271 * Set the position of this message
272 * @see position()
273 * @since 6.0
274 */
275 void setPosition(Position position);
276
277 /**
278 * Set word wrap to @p wordWrap. If word wrap is enabled, the text()
279 * of the message widget is wrapped to fit the available width.
280 * If word wrap is disabled, the message widget's minimum size is
281 * such that the entire text fits.
282 *
283 * By default word wrap is disabled.
284 *
285 * @param wordWrap disable/enable word wrap
286 * @see wordWrap()
287 */
288 void setWordWrap(bool wordWrap);
289
290 /**
291 * Set the visibility of the close button. If @p visible is @e true,
292 * a close button is shown that calls animatedHide() if clicked.
293 *
294 * By default the close button is set to be visible.
295 *
296 * @see closeButtonVisible(), animatedHide()
297 */
298 void setCloseButtonVisible(bool visible);
299
300 /**
301 * Set the message type to @p type.
302 * By default, the message type is set to KMessageWidget::Information.
303 * Appropriate colors are chosen to mimic the appearance of Kirigami's
304 * InlineMessage.
305 *
306 * @see messageType(), KMessageWidget::MessageType
307 */
308 void setMessageType(KMessageWidget::MessageType type);
309
310 /**
311 * Show the widget using an animation.
312 */
313 void animatedShow();
314
315 /**
316 * Hide the widget using an animation.
317 */
318 void animatedHide();
319
320 /**
321 * Define an icon to be shown on the left of the text
322 * @since 4.11
323 */
324 void setIcon(const QIcon &icon);
325
326Q_SIGNALS:
327 /**
328 * This signal is emitted when the user clicks a link in the text label.
329 * The URL referred to by the href anchor is passed in contents.
330 * @param contents text of the href anchor
331 * @see QLabel::linkActivated()
332 * @since 4.10
333 */
334 void linkActivated(const QString &contents);
335
336 /**
337 * This signal is emitted when the user hovers over a link in the text label.
338 * The URL referred to by the href anchor is passed in contents.
339 * @param contents text of the href anchor
340 * @see QLabel::linkHovered()
341 * @since 4.11
342 */
343 void linkHovered(const QString &contents);
344
345 /**
346 * This signal is emitted when the hide animation is finished, started by
347 * calling animatedHide(). If animations are disabled, this signal is
348 * emitted immediately after the message widget got hidden.
349 *
350 * @note This signal is @e not emitted if the widget was hidden by
351 * calling hide(), so this signal is only useful in conjunction
352 * with animatedHide().
353 *
354 * @see animatedHide()
355 * @since 5.0
356 */
357 void hideAnimationFinished();
358
359 /**
360 * This signal is emitted when the show animation is finished, started by
361 * calling animatedShow(). If animations are disabled, this signal is
362 * emitted immediately after the message widget got shown.
363 *
364 * @note This signal is @e not emitted if the widget was shown by
365 * calling show(), so this signal is only useful in conjunction
366 * with animatedShow().
367 *
368 * @see animatedShow()
369 * @since 5.0
370 */
371 void showAnimationFinished();
372
373protected:
374 void paintEvent(QPaintEvent *event) override;
375
376 bool event(QEvent *event) override;
377
378 void resizeEvent(QResizeEvent *event) override;
379
380private:
381 friend class KMessageWidgetPrivate;
382 std::unique_ptr<class KMessageWidgetPrivate> const d;
383};
384
385#endif /* KMESSAGEWIDGET_H */
386

source code of kwidgetsaddons/src/kmessagewidget.h