1 /*************************************************************************** 2 qgsmessagebar.h - description 3 ------------------- 4 begin : June 2012 5 copyright : (C) 2012 by Giuseppe Sucameli 6 email : sucameli at faunalia dot it 7 ***************************************************************************/ 8 9 /*************************************************************************** 10 * * 11 * This program is free software; you can redistribute it and/or modify * 12 * it under the terms of the GNU General Public License as published by * 13 * the Free Software Foundation; either version 2 of the License, or * 14 * (at your option) any later version. * 15 * * 16 ***************************************************************************/ 17 #ifndef QGSMESSAGEBAR_H 18 #define QGSMESSAGEBAR_H 19 20 #include "qgsguiutils.h" 21 #include "qgis.h" 22 23 #include <QString> 24 #include <QFrame> 25 #include <QIcon> 26 #include <QColor> 27 #include <QList> 28 #include "qgis_gui.h" 29 30 class QWidget; 31 class QGridLayout; 32 class QMenu; 33 class QProgressBar; 34 class QToolButton; 35 class QLabel; 36 class QAction; 37 class QTimer; 38 39 class QgsMessageBarItem; 40 41 /** 42 * \ingroup gui 43 * \brief A bar for displaying non-blocking messages to the user. 44 * 45 * QgsMessageBar is a reusable widget which allows for providing feedback to users in 46 * a non-intrusive way. Messages are shown in a horizontal bar widget, which is styled 47 * automatically to reflect the severity ("message level") of the displayed message (e.g. 48 * warning messages are styled in an orange color scheme, critical errors are shown in 49 * red, etc). 50 * 51 * The message bar supports automatic stacking of multiple messages, so that 52 * only the most recent message is shown to users. Users can then manually dismiss 53 * individual messages to remove them from the stack, causing the next-most-recent 54 * message to be shown. If no messages are available to show then the message bar 55 * automatically hides. 56 * 57 * The class also supports pushing custom widgets to the notification stack via 58 * the pushWidget() method. 59 */ 60 class GUI_EXPORT QgsMessageBar: public QFrame 61 { 62 Q_OBJECT 63 64 public: 65 66 //! Constructor for QgsMessageBar 67 QgsMessageBar( QWidget *parent SIP_TRANSFERTHIS = nullptr ); 68 69 /** 70 * Display a message \a item on the bar, after hiding the currently visible one 71 * and putting it in a stack. 72 * 73 * The message bar will take ownership of \a item. 74 */ 75 void pushItem( QgsMessageBarItem *item SIP_TRANSFER ); 76 77 /** 78 * Display a \a widget as a message on the bar, after hiding the currently visible one 79 * and putting it in a stack. 80 * 81 * \param widget message widget to display 82 * \param level is Qgis::MessageLevel::Info, Warning, Critical or Success 83 * \param duration timeout duration of message in seconds, 0 value indicates no timeout (i.e. 84 * the message must be manually cleared by the user). 85 */ 86 QgsMessageBarItem *pushWidget( QWidget *widget SIP_TRANSFER, Qgis::MessageLevel level = Qgis::MessageLevel::Info, int duration = 0 ); 87 88 /** 89 * Remove the specified \a item from the bar, and display the next most recent one in the stack. 90 * If no messages remain in the stack, then the bar will be hidden. 91 * 92 * \param item previously added item to remove. 93 * \returns TRUE if \a item was removed, FALSE otherwise 94 */ 95 bool popWidget( QgsMessageBarItem *item ); 96 97 /** 98 * Creates message bar item widget containing a message \a text to be displayed on the bar. 99 * 100 * The caller takes ownership of the returned item. 101 * 102 * \note This is a low-level API call. Users are recommended to use the high-level pushMessage() API call 103 * instead. 104 */ 105 static QgsMessageBarItem *createMessage( const QString &text, QWidget *parent = nullptr ) SIP_FACTORY; 106 107 /** 108 * Creates message bar item widget containing a \a title and message \a text to be displayed on the bar. 109 * 110 * The caller takes ownership of the returned item. 111 * 112 * \note This is a low-level API call. Users are recommended to use the high-level pushMessage() API call 113 * instead. 114 */ 115 static QgsMessageBarItem *createMessage( const QString &title, const QString &text, QWidget *parent = nullptr ) SIP_FACTORY; 116 117 /** 118 * Creates message bar item widget containing a custom \a widget to be displayed on the bar. 119 * 120 * The caller takes ownership of the returned item. 121 * 122 * \note This is a low-level API call. Users are recommended to use the high-level pushWidget() API call 123 * instead. 124 */ 125 static QgsMessageBarItem *createMessage( QWidget *widget, QWidget *parent = nullptr ) SIP_FACTORY; 126 127 /** 128 * A convenience method for pushing a message with the specified \a text to the bar. 129 * 130 * The \a level argument specifies the desired message level (severity) of the message, which controls 131 * how the message bar is styled. 132 * 133 * The optional \a duration argument can be used to specify the message timeout in seconds. If \a duration 134 * is set to 0, then the message must be manually dismissed by the user. Since QGIS 3.18, a duration of -1 indicates that 135 * the default timeout for the message \a level should be used. 136 */ 137 void pushMessage( const QString &text, Qgis::MessageLevel level = Qgis::MessageLevel::Info, int duration = -1 ); 138 139 /** 140 * A convenience method for pushing a message with the specified \a title and \a text to the bar. 141 * 142 * The \a level argument specifies the desired message level (severity) of the message, which controls 143 * how the message bar is styled. 144 * 145 * The optional \a duration argument can be used to specify the message timeout in seconds. If \a duration 146 * is set to 0, then the message must be manually dismissed by the user. Since QGIS 3.18, a duration of -1 indicates that 147 * the default timeout for the message \a level should be used. 148 */ 149 void pushMessage( const QString &title, const QString &text, Qgis::MessageLevel level = Qgis::MessageLevel::Info, int duration = -1 ); 150 151 /** 152 * A convenience method for pushing a message with the specified \a title and \a text to the bar. Additional 153 * message content specified via \a showMore will be shown when the user presses a "more" button. 154 * 155 * The \a level argument specifies the desired message level (severity) of the message, which controls 156 * how the message bar is styled. 157 * 158 * The optional \a duration argument can be used to specify the message timeout in seconds. If \a duration 159 * is set to 0, then the message must be manually dismissed by the user. Since QGIS 3.18, a duration of -1 indicates that 160 * the default timeout for the message \a level should be used. 161 */ 162 void pushMessage( const QString &title, const QString &text, const QString &showMore, Qgis::MessageLevel level = Qgis::MessageLevel::Info, int duration = -1 ); 163 164 /** 165 * Returns the current visible item, or NULLPTR if no item is shown. 166 */ 167 QgsMessageBarItem *currentItem(); 168 169 /** 170 * Returns a list of all items currently visible or queued for the bar. 171 * 172 * \since QGIS 3.14 173 */ 174 QList<QgsMessageBarItem *> items(); 175 176 /** 177 * Returns the default timeout in seconds for timed messages of the specified \a level. 178 * \since QGIS 3.18 179 */ 180 static int defaultMessageTimeout( Qgis::MessageLevel level = Qgis::MessageLevel::NoLevel ); 181 182 signals: 183 184 /** 185 * Emitted whenever an \a item is added to the bar. 186 */ 187 void widgetAdded( QgsMessageBarItem *item ); 188 189 /** 190 * Emitted whenever an \a item was removed from the bar. 191 */ 192 void widgetRemoved( QgsMessageBarItem *item ); 193 194 public slots: 195 196 /** 197 * Remove the currently displayed item from the bar and display the next item 198 * in the stack. If no remaining items are present, the bar will be hidden. 199 * 200 * \returns TRUE if the widget was removed, FALSE otherwise 201 */ 202 bool popWidget(); 203 204 /** 205 * Removes all items from the bar. 206 * 207 * \returns TRUE if all items were removed, FALSE otherwise 208 */ 209 bool clearWidgets(); 210 211 /** 212 * Pushes a success \a message with default timeout to the message bar. 213 * 214 * \param title title string for message 215 * \param message The message to be displayed 216 * 217 * \since QGIS 2.8 218 */ 219 void pushSuccess( const QString &title, const QString &message ); 220 221 /** 222 * Pushes a information \a message with default timeout to the message bar. 223 * 224 * \param title title string for message 225 * \param message The message to be displayed 226 * 227 * \since QGIS 2.8 228 */ 229 void pushInfo( const QString &title, const QString &message ); 230 231 /** 232 * Pushes a warning \a message that must be manually dismissed by the user. Before QGIS 3.18 the default timeout was used. 233 * 234 * \param title title string for message 235 * \param message The message to be displayed 236 * 237 * \since QGIS 2.8 238 */ 239 void pushWarning( const QString &title, const QString &message ); 240 241 /** 242 * Pushes a critical warning \a message that must be manually dismissed by the user. Before QGIS 3.18 the default timeout was used. 243 * 244 * \param title title string for message 245 * \param message The message to be displayed 246 * 247 * \since QGIS 2.8 248 */ 249 void pushCritical( const QString &title, const QString &message ); 250 251 protected: 252 void mousePressEvent( QMouseEvent *e ) override; 253 254 private: 255 void popItem( QgsMessageBarItem *item ); 256 void showItem( QgsMessageBarItem *item ); 257 QgsMessageBarItem *mCurrentItem = nullptr; 258 QList<QgsMessageBarItem *> mItems; 259 QMenu *mCloseMenu = nullptr; 260 QToolButton *mCloseBtn = nullptr; 261 QGridLayout *mLayout = nullptr; 262 QLabel *mItemCount = nullptr; 263 QAction *mActionCloseAll = nullptr; 264 QTimer *mCountdownTimer = nullptr; 265 QProgressBar *mCountProgress = nullptr; 266 QString mCountStyleSheet; 267 Qgis::MessageLevel mPrevLevel = Qgis::MessageLevel::NoLevel; 268 269 static constexpr int MAX_ITEMS = 100; 270 271 void removeLowestPriorityOldestItem(); 272 273 private slots: 274 //! updates count of items in widget list 275 void updateItemCount(); 276 277 //! updates the countdown for widgets that have a timeout duration 278 void updateCountdown(); 279 void resetCountdown(); 280 281 friend class TestQgsMessageBar; 282 }; 283 284 #endif 285