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 */ 87 class KWIDGETSADDONS_EXPORT KMessageWidget : public QFrame 88 { 89 Q_OBJECT 90 91 Q_PROPERTY(QString text READ text WRITE setText) 92 Q_PROPERTY(bool wordWrap READ wordWrap WRITE setWordWrap) 93 Q_PROPERTY(bool closeButtonVisible READ isCloseButtonVisible WRITE setCloseButtonVisible) 94 Q_PROPERTY(MessageType messageType READ messageType WRITE setMessageType) 95 Q_PROPERTY(QIcon icon READ icon WRITE setIcon) 96 public: 97 /** 98 * Available message types. 99 * The background colors are chosen depending on the message type. 100 */ 101 enum MessageType { 102 Positive, 103 Information, 104 Warning, 105 Error, 106 }; 107 Q_ENUM(MessageType) 108 109 /** 110 * Constructs a KMessageWidget with the specified @p parent. 111 */ 112 explicit KMessageWidget(QWidget *parent = nullptr); 113 114 /** 115 * Constructs a KMessageWidget with the specified @p parent and 116 * contents @p text. 117 */ 118 explicit KMessageWidget(const QString &text, QWidget *parent = nullptr); 119 120 /** 121 * Destructor. 122 */ 123 ~KMessageWidget() override; 124 125 /** 126 * Get the text of this message widget. 127 * @see setText() 128 */ 129 QString text() const; 130 131 /** 132 * Check whether word wrap is enabled. 133 * 134 * If word wrap is enabled, the message widget wraps the displayed text 135 * as required to the available width of the widget. This is useful to 136 * avoid breaking widget layouts. 137 * 138 * @see setWordWrap() 139 */ 140 bool wordWrap() const; 141 142 /** 143 * Check whether the close button is visible. 144 * 145 * @see setCloseButtonVisible() 146 */ 147 bool isCloseButtonVisible() const; 148 149 /** 150 * Get the type of this message. 151 * By default, the type is set to KMessageWidget::Information. 152 * 153 * @see KMessageWidget::MessageType, setMessageType() 154 */ 155 MessageType messageType() const; 156 157 /** 158 * Add @p action to the message widget. 159 * For each action a button is added to the message widget in the 160 * order the actions were added. 161 * 162 * @param action the action to add 163 * @see removeAction(), QWidget::actions() 164 */ 165 void addAction(QAction *action); 166 167 /** 168 * Remove @p action from the message widget. 169 * 170 * @param action the action to remove 171 * @see KMessageWidget::MessageType, addAction(), setMessageType() 172 */ 173 void removeAction(QAction *action); 174 175 /** 176 * Returns the preferred size of the message widget. 177 */ 178 QSize sizeHint() const override; 179 180 /** 181 * Returns the minimum size of the message widget. 182 */ 183 QSize minimumSizeHint() const override; 184 185 /** 186 * Returns the required height for @p width. 187 * @param width the width in pixels 188 */ 189 int heightForWidth(int width) const override; 190 191 /** 192 * The icon shown on the left of the text. By default, no icon is shown. 193 * @since 4.11 194 */ 195 QIcon icon() const; 196 197 /** 198 * Check whether the hide animation started by calling animatedHide() 199 * is still running. If animations are disabled, this function always 200 * returns @e false. 201 * 202 * @see animatedHide(), hideAnimationFinished() 203 * @since 5.0 204 */ 205 bool isHideAnimationRunning() const; 206 207 /** 208 * Check whether the show animation started by calling animatedShow() 209 * is still running. If animations are disabled, this function always 210 * returns @e false. 211 * 212 * @see animatedShow(), showAnimationFinished() 213 * @since 5.0 214 */ 215 bool isShowAnimationRunning() const; 216 217 public Q_SLOTS: 218 /** 219 * Set the text of the message widget to @p text. 220 * If the message widget is already visible, the text changes on the fly. 221 * 222 * @param text the text to display, rich text is allowed 223 * @see text() 224 */ 225 void setText(const QString &text); 226 227 /** 228 * Set word wrap to @p wordWrap. If word wrap is enabled, the text() 229 * of the message widget is wrapped to fit the available width. 230 * If word wrap is disabled, the message widget's minimum size is 231 * such that the entire text fits. 232 * 233 * By default word wrap is disabled. 234 * 235 * @param wordWrap disable/enable word wrap 236 * @see wordWrap() 237 */ 238 void setWordWrap(bool wordWrap); 239 240 /** 241 * Set the visibility of the close button. If @p visible is @e true, 242 * a close button is shown that calls animatedHide() if clicked. 243 * 244 * By default the close button is set to be visible. 245 * 246 * @see closeButtonVisible(), animatedHide() 247 */ 248 void setCloseButtonVisible(bool visible); 249 250 /** 251 * Set the message type to @p type. 252 * By default, the message type is set to KMessageWidget::Information. 253 * Appropriate colors are chosen to mimic the appearance of Kirigami's 254 * InlineMessage. 255 * 256 * @see messageType(), KMessageWidget::MessageType 257 */ 258 void setMessageType(KMessageWidget::MessageType type); 259 260 /** 261 * Show the widget using an animation. 262 */ 263 void animatedShow(); 264 265 /** 266 * Hide the widget using an animation. 267 */ 268 void animatedHide(); 269 270 /** 271 * Define an icon to be shown on the left of the text 272 * @since 4.11 273 */ 274 void setIcon(const QIcon &icon); 275 276 Q_SIGNALS: 277 /** 278 * This signal is emitted when the user clicks a link in the text label. 279 * The URL referred to by the href anchor is passed in contents. 280 * @param contents text of the href anchor 281 * @see QLabel::linkActivated() 282 * @since 4.10 283 */ 284 void linkActivated(const QString &contents); 285 286 /** 287 * This signal is emitted when the user hovers over a link in the text label. 288 * The URL referred to by the href anchor is passed in contents. 289 * @param contents text of the href anchor 290 * @see QLabel::linkHovered() 291 * @since 4.11 292 */ 293 void linkHovered(const QString &contents); 294 295 /** 296 * This signal is emitted when the hide animation is finished, started by 297 * calling animatedHide(). If animations are disabled, this signal is 298 * emitted immediately after the message widget got hidden. 299 * 300 * @note This signal is @e not emitted if the widget was hidden by 301 * calling hide(), so this signal is only useful in conjunction 302 * with animatedHide(). 303 * 304 * @see animatedHide() 305 * @since 5.0 306 */ 307 void hideAnimationFinished(); 308 309 /** 310 * This signal is emitted when the show animation is finished, started by 311 * calling animatedShow(). If animations are disabled, this signal is 312 * emitted immediately after the message widget got shown. 313 * 314 * @note This signal is @e not emitted if the widget was shown by 315 * calling show(), so this signal is only useful in conjunction 316 * with animatedShow(). 317 * 318 * @see animatedShow() 319 * @since 5.0 320 */ 321 void showAnimationFinished(); 322 323 protected: 324 void paintEvent(QPaintEvent *event) override; 325 326 bool event(QEvent *event) override; 327 328 void resizeEvent(QResizeEvent *event) override; 329 330 private: 331 friend class KMessageWidgetPrivate; 332 std::unique_ptr<class KMessageWidgetPrivate> const d; 333 }; 334 335 #endif /* KMESSAGEWIDGET_H */ 336