QGIS API Documentation  2.0.1-Dufour
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
qgsmessagebar.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsmessagebar.cpp - 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 
18 #include "qgsmessagebar.h"
19 #include "qgsmessagebaritem.h"
20 #include "qgsapplication.h"
21 
22 #include <QWidget>
23 #include <QPalette>
24 #include <QStackedWidget>
25 #include <QProgressBar>
26 #include <QToolButton>
27 #include <QTimer>
28 #include <QGridLayout>
29 #include <QMenu>
30 #include <QMouseEvent>
31 #include <QLabel>
32 
33 QgsMessageBar::QgsMessageBar( QWidget *parent )
34  : QFrame( parent ), mCurrentItem( NULL )
35 {
36  QPalette pal = palette();
37  pal.setBrush( backgroundRole(), pal.window() );
38  setPalette( pal );
39  setAutoFillBackground( true );
40  setFrameShape( QFrame::StyledPanel );
41  setFrameShadow( QFrame::Plain );
42 
43  mLayout = new QGridLayout( this );
44  mLayout->setContentsMargins( 9, 1, 9, 1 );
45  setLayout( mLayout );
46 
47  mCountProgress = new QProgressBar( this );
48  mCountStyleSheet = QString( "QProgressBar { border: 1px solid rgba(0, 0, 0, 75%);"
49  " border-radius: 2px; background: rgba(0, 0, 0, 0);"
50  " image: url(:/images/themes/default/%1) }"
51  "QProgressBar::chunk { background-color: rgba(0, 0, 0, 30%); width: 5px; }" );
52 
53  mCountProgress->setStyleSheet( mCountStyleSheet.arg( "mIconTimerPause.png" ) );
54  mCountProgress->setObjectName( "mCountdown" );
55  mCountProgress->setFixedSize( 25, 14 );
56  mCountProgress->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
57  mCountProgress->setTextVisible( false );
58  mCountProgress->setRange( 0, 5 );
59  mCountProgress->setHidden( true );
60  mLayout->addWidget( mCountProgress, 0, 0, 1, 1 );
61 
62  mItemCount = new QLabel( this );
63  mItemCount->setObjectName( "mItemCount" );
64  mItemCount->setToolTip( tr( "Remaining messages" ) );
65  mItemCount->setSizePolicy( QSizePolicy::Maximum, QSizePolicy::Preferred );
66  mLayout->addWidget( mItemCount, 0, 2, 1, 1 );
67 
68  mCloseMenu = new QMenu( this );
69  mCloseMenu->setObjectName( "mCloseMenu" );
70  mActionCloseAll = new QAction( tr( "Close all" ), this );
71  mCloseMenu->addAction( mActionCloseAll );
72  connect( mActionCloseAll, SIGNAL( triggered() ), this, SLOT( clearWidgets() ) );
73 
74  mCloseBtn = new QToolButton( this );
75  mCloseMenu->setObjectName( "mCloseMenu" );
76  mCloseBtn->setToolTip( tr( "Close" ) );
77  mCloseBtn->setMinimumWidth( 40 );
78  mCloseBtn->setStyleSheet(
79  "QToolButton { background-color: rgba(255, 255, 255, 0); } "
80  "QToolButton::menu-indicator { subcontrol-position: right bottom; subcontrol-origin: padding; bottom: 2px; }" );
81  mCloseBtn->setCursor( Qt::PointingHandCursor );
82  mCloseBtn->setIcon( QgsApplication::getThemeIcon( "/mIconClose.png" ) );
83  mCloseBtn->setIconSize( QSize( 18, 18 ) );
84  mCloseBtn->setSizePolicy( QSizePolicy::Maximum, QSizePolicy::Maximum );
85  mCloseBtn->setMenu( mCloseMenu );
86  connect( mCloseBtn, SIGNAL( clicked() ), this, SLOT( popWidget() ) );
87  mLayout->addWidget( mCloseBtn, 0, 3, 1, 1 );
88 
89  mCountdownTimer = new QTimer( this );
90  mCountdownTimer->setInterval( 1000 );
91  connect( mCountdownTimer, SIGNAL( timeout() ), this, SLOT( updateCountdown() ) );
92 
93  connect( this, SIGNAL( widgetAdded( QgsMessageBarItem* ) ), this, SLOT( updateItemCount() ) );
94  connect( this, SIGNAL( widgetRemoved( QgsMessageBarItem* ) ), this, SLOT( updateItemCount() ) );
95 
96  // start hidden
97  setVisible( false );
98 }
99 
101 {
102 }
103 
104 void QgsMessageBar::mousePressEvent( QMouseEvent * e )
105 {
106  if ( mCountProgress == childAt( e->pos() ) && e->button() == Qt::LeftButton )
107  {
108  if ( mCountdownTimer->isActive() )
109  {
110  mCountdownTimer->stop();
111  mCountProgress->setStyleSheet( mCountStyleSheet.arg( "mIconTimerContinue.png" ) );
112  }
113  else
114  {
115  mCountdownTimer->start();
116  mCountProgress->setStyleSheet( mCountStyleSheet.arg( "mIconTimerPause.png" ) );
117  }
118  }
119 }
120 
122 {
123  Q_ASSERT( item );
124 
125  if ( item != mCurrentItem && !mItems.contains( item ) )
126  return;
127 
128  if ( item == mCurrentItem )
129  {
130  if ( mCurrentItem )
131  {
132  QWidget *widget = dynamic_cast<QWidget*>( mCurrentItem );
133  mLayout->removeWidget( widget );
134  mCurrentItem->hide();
135  disconnect( mCurrentItem, SIGNAL( styleChanged( QString ) ), this, SLOT( setStyleSheet( QString ) ) );
136  delete mCurrentItem;
137  mCurrentItem = 0;
138  }
139 
140  if ( !mItems.isEmpty() )
141  {
142  showItem( mItems.first() );
143  }
144  else
145  {
146  hide();
147  }
148  }
149  else
150  {
151  mItems.removeOne( item );
152  }
153 
154  emit widgetRemoved( item );
155 }
156 
158 {
159  if ( !item || !mCurrentItem )
160  return false;
161 
162  if ( item == mCurrentItem )
163  {
165  return true;
166  }
167 
168  foreach ( QgsMessageBarItem *existingItem, mItems )
169  {
170  if ( existingItem == item )
171  {
172  mItems.removeOne( existingItem );
173  delete existingItem;
174  return true;
175  }
176  }
177 
178  return false;
179 }
180 
182 {
183  if ( !mCurrentItem )
184  return false;
185 
186  resetCountdown();
187 
189  popItem( item );
190 
191  return true;
192 }
193 
195 {
196  if ( !mCurrentItem && mItems.empty() )
197  return true;
198 
199  while ( mItems.count() > 0 )
200  {
201  popWidget();
202  }
203  popWidget();
204 
205  return !mCurrentItem && mItems.empty();
206 }
207 
209 {
210  Q_ASSERT( item );
211 
212  if ( mCurrentItem != 0 )
213  disconnect( mCurrentItem, SIGNAL( styleChanged( QString ) ), this, SLOT( setStyleSheet( QString ) ) );
214 
215  if ( item == mCurrentItem )
216  return;
217 
218  if ( mItems.contains( item ) )
219  mItems.removeOne( item );
220 
221  if ( mCurrentItem )
222  {
223  mItems.prepend( mCurrentItem );
224  mLayout->removeWidget( mCurrentItem );
225  mCurrentItem->hide();
226  }
227 
228  mCurrentItem = item;
229  mLayout->addWidget( item, 0, 1, 1, 1 );
230  mCurrentItem->show();
231 
232  if ( item->duration() > 0 )
233  {
234  mCountProgress->setRange( 0, item->duration() );
235  mCountProgress->setValue( item->duration() );
236  mCountProgress->setVisible( true );
237  mCountdownTimer->start();
238  }
239 
240  connect( mCurrentItem, SIGNAL( styleChanged( QString ) ), this, SLOT( setStyleSheet( QString ) ) );
241  setStyleSheet( item->getStyleSheet() );
242  show();
243 
244  emit widgetAdded( item );
245 }
246 
248 {
249  resetCountdown();
250  // avoid duplicated widget
251  popWidget( item );
252  showItem( item );
253 }
254 
256 {
257  QgsMessageBarItem *item;
258  item = dynamic_cast<QgsMessageBarItem*>( widget );
259  if ( item )
260  {
261  item->setLevel( level )->setDuration( duration );
262  }
263  else
264  {
265  item = new QgsMessageBarItem( widget, level, duration );
266  }
267  pushItem( item );
268  return item;
269 }
270 
271 void QgsMessageBar::pushMessage( const QString &title, const QString &text, QgsMessageBar::MessageLevel level, int duration )
272 {
273  QgsMessageBarItem *item = new QgsMessageBarItem( title, text, level, duration );
274  pushItem( item );
275 }
276 
277 QgsMessageBarItem* QgsMessageBar::createMessage( const QString &text, QWidget *parent )
278 {
279  QgsMessageBarItem* item = new QgsMessageBarItem( text, INFO, 0, parent );
280  return item;
281 }
282 
283 QgsMessageBarItem* QgsMessageBar::createMessage( const QString &title, const QString &text, QWidget *parent )
284 {
285  return new QgsMessageBarItem( title, text, QgsMessageBar::INFO, 0, parent );
286 }
287 
288 QgsMessageBarItem* QgsMessageBar::createMessage( QWidget *widget, QWidget *parent )
289 {
290  return new QgsMessageBarItem( widget, INFO, 0, parent );
291 }
292 
294 {
295  if ( !mCountdownTimer->isActive() )
296  {
297  resetCountdown();
298  return;
299  }
300  if ( mCountProgress->value() < 2 )
301  {
302  popWidget();
303  }
304  else
305  {
306  mCountProgress->setValue( mCountProgress->value() - 1 );
307  }
308 }
309 
311 {
312  if ( mCountdownTimer->isActive() )
313  mCountdownTimer->stop();
314 
315  mCountProgress->setStyleSheet( mCountStyleSheet.arg( "mIconTimerPause.png" ) );
316  mCountProgress->setVisible( false );
317 }
318 
320 {
321  mItemCount->setText( mItems.count() > 0 ? tr( "%n more", "unread messages", mItems.count() ) : QString( "" ) );
322 }