Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Add optional message timeout with countdown progress bar to QgsMessag…
…eBar
  • Loading branch information
dakcarto committed Jan 10, 2013
1 parent 7ca3656 commit d66b6b3
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 12 deletions.
74 changes: 67 additions & 7 deletions src/gui/qgsmessagebar.cpp
Expand Up @@ -22,7 +22,9 @@
#include <QPalette>
#include <QStackedWidget>
#include <QLabel>
#include <QProgressBar>
#include <QToolButton>
#include <QTimer>
#include <QGridLayout>
#include <QMenu>

Expand All @@ -41,11 +43,28 @@ QgsMessageBar::QgsMessageBar( QWidget *parent )
mLayout->setContentsMargins( 9, 1, 9, 1 );
setLayout( mLayout );

mCountProgress = new QProgressBar( this );

mCountProgress->setStyleSheet( "QProgressBar { border: 1px solid rgba(0, 0, 0, 75%);"
" border-radius: 2px; background: rgba(0, 0, 0, 0); }"
"QProgressBar::chunk { background-color: rgba(0, 0, 0, 50%); width: 5px; }" );
mCountProgress->setObjectName( "mCountdown" );
mCountProgress->setToolTip( tr( "Countdown" ) );
mCountProgress->setMinimumWidth( 25 );
mCountProgress->setMaximumWidth( 25 );
mCountProgress->setMinimumHeight( 10 );
mCountProgress->setMaximumHeight( 10 );
mCountProgress->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
mCountProgress->setTextVisible( false );
mCountProgress->setRange( 0, 5 );
mCountProgress->setHidden( true );
mLayout->addWidget( mCountProgress, 0, 0, 1, 1 );

mItemCount = new QLabel( this );
mItemCount->setObjectName( "mItemCount" );
mItemCount->setToolTip( tr( "Remaining messages" ) );
mItemCount->setSizePolicy( QSizePolicy::Maximum, QSizePolicy::Preferred );
mLayout->addWidget( mItemCount, 0, 1, 1, 1 );
mLayout->addWidget( mItemCount, 0, 2, 1, 1 );

mCloseMenu = new QMenu( this );
mCloseMenu->setObjectName( "mCloseMenu" );
Expand All @@ -64,7 +83,11 @@ QgsMessageBar::QgsMessageBar( QWidget *parent )
mCloseBtn->setSizePolicy( QSizePolicy::Maximum, QSizePolicy::Preferred );
mCloseBtn->setMenu( mCloseMenu );
connect( mCloseBtn, SIGNAL( clicked() ), this, SLOT( popWidget() ) );
mLayout->addWidget( mCloseBtn, 0, 2, 1, 1 );
mLayout->addWidget( mCloseBtn, 0, 3, 1, 1 );

mCountdownTimer = new QTimer( this );
mCountdownTimer->setInterval( 1000 );
connect( mCountdownTimer, SIGNAL( timeout() ), this, SLOT( updateCountdown() ) );

connect( this, SIGNAL( widgetAdded( QWidget* ) ), this, SLOT( updateItemCount() ) );
connect( this, SIGNAL( widgetRemoved( QWidget* ) ), this, SLOT( updateItemCount() ) );
Expand Down Expand Up @@ -148,6 +171,8 @@ bool QgsMessageBar::popWidget()
if ( !mCurrentItem )
return false;

resetCountdown();

QgsMessageBarItem *item = mCurrentItem;
popItem( item );

Expand Down Expand Up @@ -186,17 +211,27 @@ void QgsMessageBar::pushItem( QgsMessageBarItem *item )
}

mCurrentItem = item;
mLayout->addWidget( item->widget(), 0, 0, 1, 1 );
mLayout->addWidget( item->widget(), 0, 1, 1, 1 );
mCurrentItem->widget()->show();

if ( item->duration() > 0 )
{
mCountProgress->setRange( 0, item->duration() );
mCountProgress->setValue( item->duration() );
mCountProgress->setVisible( true );
mCountdownTimer->start();
}

setStyleSheet( item->styleSheet() );
show();

emit widgetAdded( item->widget() );
}

void QgsMessageBar::pushWidget( QWidget *widget, int level )
void QgsMessageBar::pushWidget( QWidget *widget, int level, int duration )
{
resetCountdown();

QString stylesheet;
if ( level >= 2 )
{
Expand All @@ -215,18 +250,18 @@ void QgsMessageBar::pushWidget( QWidget *widget, int level )
}
stylesheet += "QLabel#mMsgTitle { font-weight: bold; } "
"QLabel#mItemCount { font-style: italic; }";
pushWidget( widget, stylesheet );
pushWidget( widget, stylesheet, duration );
}

void QgsMessageBar::pushWidget( QWidget *widget, const QString &styleSheet )
void QgsMessageBar::pushWidget( QWidget *widget, const QString &styleSheet, int duration )
{
if ( !widget )
return;

// avoid duplicated widget
popWidget( widget );

pushItem( new QgsMessageBarItem( widget, styleSheet ) );
pushItem( new QgsMessageBarItem( widget, styleSheet, duration ) );
}

QWidget* QgsMessageBar::createMessage( const QString &title, const QString &text, const QIcon &icon, QWidget *parent )
Expand Down Expand Up @@ -259,6 +294,31 @@ QWidget* QgsMessageBar::createMessage( const QString &title, const QString &text
return widget;
}

void QgsMessageBar::updateCountdown()
{
if ( !mCountdownTimer->isActive() )
{
resetCountdown();
return;
}
if ( mCountProgress->value() < 2 )
{
popWidget();
}
else
{
mCountProgress->setValue( mCountProgress->value() - 1 );
}
}

void QgsMessageBar::resetCountdown()
{
if ( mCountdownTimer->isActive() )
mCountdownTimer->stop();

mCountProgress->setVisible( false );
}

void QgsMessageBar::updateItemCount()
{
mItemCount->setText( mList.count() > 0 ? QString::number( mList.count() ) + QString( " " ) + tr( "more" ) : QString( "" ) );
Expand Down
20 changes: 15 additions & 5 deletions src/gui/qgsmessagebar.h
Expand Up @@ -28,9 +28,11 @@
class QWidget;
class QGridLayout;
class QMenu;
class QProgressBar;
class QToolButton;
class QLabel;
class QAction;
class QTimer;

/** \ingroup gui
* A bar for displaying non-blocking messages to the user.
Expand All @@ -48,8 +50,9 @@ class GUI_EXPORT QgsMessageBar: public QFrame
* and putting it in a stack
* @param widget widget to add
* @param level is 0 for information, 1 for warning, 2 for critical
* @param duration timeout duration of message in seconds, 0 value indicates no timeout
*/
void pushWidget( QWidget *widget, int level = 0 );
void pushWidget( QWidget *widget, int level = 0, int duration = 0 );

/*! remove the passed widget from the bar (if previously added),
* then display the next one in the stack if any or hide the bar
Expand Down Expand Up @@ -90,20 +93,21 @@ class GUI_EXPORT QgsMessageBar: public QFrame
class QgsMessageBarItem
{
public:
QgsMessageBarItem( QWidget *widget, const QString &styleSheet ):
mWidget( widget ), mStyleSheet( styleSheet ) {}
QgsMessageBarItem( QWidget *widget, const QString &styleSheet, int duration = 0 ):
mWidget( widget ), mStyleSheet( styleSheet ), mDuration( duration ) {}
~QgsMessageBarItem() {}

QWidget* widget() const { return mWidget; }
QString styleSheet() const { return mStyleSheet; }
int duration() const { return mDuration; }

private:
QWidget *mWidget;
QString mStyleSheet;
int mDuration; // 0 value indicates no timeout duration
};

//! display a widget on the bar
void pushWidget( QWidget *widget, const QString &styleSheet );
void pushWidget( QWidget *widget, const QString &styleSheet, int duration = 0 );

void popItem( QgsMessageBarItem *item );
void pushItem( QgsMessageBarItem *item );
Expand All @@ -115,10 +119,16 @@ class GUI_EXPORT QgsMessageBar: public QFrame
QGridLayout *mLayout;
QLabel *mItemCount;
QAction *mActionCloseAll;
QTimer *mCountdownTimer;
QProgressBar *mCountProgress;

private slots:
//! updates count of items in widget list
void updateItemCount();

//! updates the countdown for widgets that have a timeout duration
void updateCountdown();
void resetCountdown();
};

#endif

0 comments on commit d66b6b3

Please sign in to comment.