File indexing completed on 2024-04-28 15:32:07

0001 /*
0002     This file is part of the KDE libraries
0003 
0004     SPDX-FileCopyrightText: 2011 Aurélien Gâteau <agateau@kde.org>
0005     SPDX-FileCopyrightText: 2014 Dominik Haumann <dhaumann@kde.org>
0006 
0007     SPDX-License-Identifier: LGPL-2.1-or-later
0008 */
0009 #ifndef KMESSAGEWIDGET_H
0010 #define KMESSAGEWIDGET_H
0011 
0012 #include <kwidgetsaddons_export.h>
0013 
0014 #include <QFrame>
0015 #include <memory>
0016 
0017 /**
0018  * @class KMessageWidget kmessagewidget.h KMessageWidget
0019  *
0020  * @short A widget to provide feedback or propose opportunistic interactions.
0021  *
0022  * KMessageWidget can be used to provide inline positive or negative
0023  * feedback, or to implement opportunistic interactions.
0024  *
0025  * As a feedback widget, KMessageWidget provides a less intrusive alternative
0026  * to "OK Only" message boxes. If you want to avoid a modal KMessageBox,
0027  * consider using KMessageWidget instead.
0028  *
0029  * Examples of KMessageWidget look as follows, all of them having an icon set
0030  * with setIcon(), and the first three show a close button:
0031  *
0032  * \image html kmessagewidget.png "KMessageWidget with different message types"
0033  *
0034  * <b>Negative feedback</b>
0035  *
0036  * The KMessageWidget can be used as a secondary indicator of failure: the
0037  * first indicator is usually the fact the action the user expected to happen
0038  * did not happen.
0039  *
0040  * Example: User fills a form, clicks "Submit".
0041  *
0042  * @li Expected feedback: form closes
0043  * @li First indicator of failure: form stays there
0044  * @li Second indicator of failure: a KMessageWidget appears on top of the
0045  * form, explaining the error condition
0046  *
0047  * When used to provide negative feedback, KMessageWidget should be placed
0048  * close to its context. In the case of a form, it should appear on top of the
0049  * form entries.
0050  *
0051  * KMessageWidget should get inserted in the existing layout. Space should not
0052  * be reserved for it, otherwise it becomes "dead space", ignored by the user.
0053  * KMessageWidget should also not appear as an overlay to prevent blocking
0054  * access to elements the user needs to interact with to fix the failure.
0055  *
0056  * <b>Positive feedback</b>
0057  *
0058  * KMessageWidget can be used for positive feedback but it shouldn't be
0059  * overused. It is often enough to provide feedback by simply showing the
0060  * results of an action.
0061  *
0062  * Examples of acceptable uses:
0063  *
0064  * @li Confirm success of "critical" transactions
0065  * @li Indicate completion of background tasks
0066  *
0067  * Example of unadapted uses:
0068  *
0069  * @li Indicate successful saving of a file
0070  * @li Indicate a file has been successfully removed
0071  *
0072  * <b>Opportunistic interaction</b>
0073  *
0074  * Opportunistic interaction is the situation where the application suggests to
0075  * the user an action he could be interested in perform, either based on an
0076  * action the user just triggered or an event which the application noticed.
0077  *
0078  * Example of acceptable uses:
0079  *
0080  * @li A browser can propose remembering a recently entered password
0081  * @li A music collection can propose ripping a CD which just got inserted
0082  * @li A chat application may notify the user a "special friend" just connected
0083  *
0084  * @author Aurélien Gâteau <agateau@kde.org>
0085  * @since 4.7
0086  */
0087 class KWIDGETSADDONS_EXPORT KMessageWidget : public QFrame
0088 {
0089     Q_OBJECT
0090 
0091     Q_PROPERTY(QString text READ text WRITE setText)
0092     Q_PROPERTY(bool wordWrap READ wordWrap WRITE setWordWrap)
0093     Q_PROPERTY(bool closeButtonVisible READ isCloseButtonVisible WRITE setCloseButtonVisible)
0094     Q_PROPERTY(MessageType messageType READ messageType WRITE setMessageType)
0095     Q_PROPERTY(QIcon icon READ icon WRITE setIcon)
0096 public:
0097     /**
0098      * Available message types.
0099      * The background colors are chosen depending on the message type.
0100      */
0101     enum MessageType {
0102         Positive,
0103         Information,
0104         Warning,
0105         Error,
0106     };
0107     Q_ENUM(MessageType)
0108 
0109     /**
0110      * Constructs a KMessageWidget with the specified @p parent.
0111      */
0112     explicit KMessageWidget(QWidget *parent = nullptr);
0113 
0114     /**
0115      * Constructs a KMessageWidget with the specified @p parent and
0116      * contents @p text.
0117      */
0118     explicit KMessageWidget(const QString &text, QWidget *parent = nullptr);
0119 
0120     /**
0121      * Destructor.
0122      */
0123     ~KMessageWidget() override;
0124 
0125     /**
0126      * Get the text of this message widget.
0127      * @see setText()
0128      */
0129     QString text() const;
0130 
0131     /**
0132      * Check whether word wrap is enabled.
0133      *
0134      * If word wrap is enabled, the message widget wraps the displayed text
0135      * as required to the available width of the widget. This is useful to
0136      * avoid breaking widget layouts.
0137      *
0138      * @see setWordWrap()
0139      */
0140     bool wordWrap() const;
0141 
0142     /**
0143      * Check whether the close button is visible.
0144      *
0145      * @see setCloseButtonVisible()
0146      */
0147     bool isCloseButtonVisible() const;
0148 
0149     /**
0150      * Get the type of this message.
0151      * By default, the type is set to KMessageWidget::Information.
0152      *
0153      * @see KMessageWidget::MessageType, setMessageType()
0154      */
0155     MessageType messageType() const;
0156 
0157     /**
0158      * Add @p action to the message widget.
0159      * For each action a button is added to the message widget in the
0160      * order the actions were added.
0161      *
0162      * @param action the action to add
0163      * @see removeAction(), QWidget::actions()
0164      */
0165     void addAction(QAction *action);
0166 
0167     /**
0168      * Remove @p action from the message widget.
0169      *
0170      * @param action the action to remove
0171      * @see KMessageWidget::MessageType, addAction(), setMessageType()
0172      */
0173     void removeAction(QAction *action);
0174 
0175     /**
0176      * Clears all actions from the message widget.
0177      * @see KMessageWidget::MessageType, addAction() and removeAction()
0178      * @since 5.100
0179      */
0180     void clearActions();
0181 
0182     /**
0183      * Returns the preferred size of the message widget.
0184      */
0185     QSize sizeHint() const override;
0186 
0187     /**
0188      * Returns the minimum size of the message widget.
0189      */
0190     QSize minimumSizeHint() const override;
0191 
0192     /**
0193      * Returns the required height for @p width.
0194      * @param width the width in pixels
0195      */
0196     int heightForWidth(int width) const override;
0197 
0198     /**
0199      * The icon shown on the left of the text. By default, no icon is shown.
0200      * @since 4.11
0201      */
0202     QIcon icon() const;
0203 
0204     /**
0205      * Check whether the hide animation started by calling animatedHide()
0206      * is still running. If animations are disabled, this function always
0207      * returns @e false.
0208      *
0209      * @see animatedHide(), hideAnimationFinished()
0210      * @since 5.0
0211      */
0212     bool isHideAnimationRunning() const;
0213 
0214     /**
0215      * Check whether the show animation started by calling animatedShow()
0216      * is still running. If animations are disabled, this function always
0217      * returns @e false.
0218      *
0219      * @see animatedShow(), showAnimationFinished()
0220      * @since 5.0
0221      */
0222     bool isShowAnimationRunning() const;
0223 
0224 public Q_SLOTS:
0225     /**
0226      * Set the text of the message widget to @p text.
0227      * If the message widget is already visible, the text changes on the fly.
0228      *
0229      * @param text the text to display, rich text is allowed
0230      * @see text()
0231      */
0232     void setText(const QString &text);
0233 
0234     /**
0235      * Set word wrap to @p wordWrap. If word wrap is enabled, the text()
0236      * of the message widget is wrapped to fit the available width.
0237      * If word wrap is disabled, the message widget's minimum size is
0238      * such that the entire text fits.
0239      *
0240      * By default word wrap is disabled.
0241      *
0242      * @param wordWrap disable/enable word wrap
0243      * @see wordWrap()
0244      */
0245     void setWordWrap(bool wordWrap);
0246 
0247     /**
0248      * Set the visibility of the close button. If @p visible is @e true,
0249      * a close button is shown that calls animatedHide() if clicked.
0250      *
0251      * By default the close button is set to be visible.
0252      *
0253      * @see closeButtonVisible(), animatedHide()
0254      */
0255     void setCloseButtonVisible(bool visible);
0256 
0257     /**
0258      * Set the message type to @p type.
0259      * By default, the message type is set to KMessageWidget::Information.
0260      * Appropriate colors are chosen to mimic the appearance of Kirigami's
0261      * InlineMessage.
0262      *
0263      * @see messageType(), KMessageWidget::MessageType
0264      */
0265     void setMessageType(KMessageWidget::MessageType type);
0266 
0267     /**
0268      * Show the widget using an animation.
0269      */
0270     void animatedShow();
0271 
0272     /**
0273      * Hide the widget using an animation.
0274      */
0275     void animatedHide();
0276 
0277     /**
0278      * Define an icon to be shown on the left of the text
0279      * @since 4.11
0280      */
0281     void setIcon(const QIcon &icon);
0282 
0283 Q_SIGNALS:
0284     /**
0285      * This signal is emitted when the user clicks a link in the text label.
0286      * The URL referred to by the href anchor is passed in contents.
0287      * @param contents text of the href anchor
0288      * @see QLabel::linkActivated()
0289      * @since 4.10
0290      */
0291     void linkActivated(const QString &contents);
0292 
0293     /**
0294      * This signal is emitted when the user hovers over a link in the text label.
0295      * The URL referred to by the href anchor is passed in contents.
0296      * @param contents text of the href anchor
0297      * @see QLabel::linkHovered()
0298      * @since 4.11
0299      */
0300     void linkHovered(const QString &contents);
0301 
0302     /**
0303      * This signal is emitted when the hide animation is finished, started by
0304      * calling animatedHide(). If animations are disabled, this signal is
0305      * emitted immediately after the message widget got hidden.
0306      *
0307      * @note This signal is @e not emitted if the widget was hidden by
0308      *       calling hide(), so this signal is only useful in conjunction
0309      *       with animatedHide().
0310      *
0311      * @see animatedHide()
0312      * @since 5.0
0313      */
0314     void hideAnimationFinished();
0315 
0316     /**
0317      * This signal is emitted when the show animation is finished, started by
0318      * calling animatedShow(). If animations are disabled, this signal is
0319      * emitted immediately after the message widget got shown.
0320      *
0321      * @note This signal is @e not emitted if the widget was shown by
0322      *       calling show(), so this signal is only useful in conjunction
0323      *       with animatedShow().
0324      *
0325      * @see animatedShow()
0326      * @since 5.0
0327      */
0328     void showAnimationFinished();
0329 
0330 protected:
0331     void paintEvent(QPaintEvent *event) override;
0332 
0333     bool event(QEvent *event) override;
0334 
0335     void resizeEvent(QResizeEvent *event) override;
0336 
0337 private:
0338     friend class KMessageWidgetPrivate;
0339     std::unique_ptr<class KMessageWidgetPrivate> const d;
0340 };
0341 
0342 #endif /* KMESSAGEWIDGET_H */