|
QGIS API Documentation
master-6227475
|
00001 /*************************************************************************** 00002 qgsmessagebar.cpp - description 00003 ------------------- 00004 begin : June 2012 00005 copyright : (C) 2012 by Giuseppe Sucameli 00006 email : sucameli at faunalia dot it 00007 ***************************************************************************/ 00008 00009 /*************************************************************************** 00010 * * 00011 * This program is free software; you can redistribute it and/or modify * 00012 * it under the terms of the GNU General Public License as published by * 00013 * the Free Software Foundation; either version 2 of the License, or * 00014 * (at your option) any later version. * 00015 * * 00016 ***************************************************************************/ 00017 00018 #include "qgsmessagebar.h" 00019 #include "qgsapplication.h" 00020 00021 #include <QWidget> 00022 #include <QPalette> 00023 #include <QStackedWidget> 00024 #include <QLabel> 00025 #include <QProgressBar> 00026 #include <QToolButton> 00027 #include <QTimer> 00028 #include <QGridLayout> 00029 #include <QMenu> 00030 #include <QMouseEvent> 00031 #include <QTextEdit> 00032 00033 00034 QgsMessageBar::QgsMessageBar( QWidget *parent ) 00035 : QFrame( parent ), mCurrentItem( NULL ) 00036 { 00037 QPalette pal = palette(); 00038 pal.setBrush( backgroundRole(), pal.window() ); 00039 setPalette( pal ); 00040 setAutoFillBackground( true ); 00041 setFrameShape( QFrame::StyledPanel ); 00042 setFrameShadow( QFrame::Plain ); 00043 00044 mLayout = new QGridLayout( this ); 00045 mLayout->setContentsMargins( 9, 1, 9, 1 ); 00046 setLayout( mLayout ); 00047 00048 mCountProgress = new QProgressBar( this ); 00049 mCountProgress->setObjectName( "mCountProgress" ); 00050 mCountStyleSheet = QString( "QProgressBar { border: 1px solid rgba(0, 0, 0, 75%);" 00051 " border-radius: 2px; background: rgba(0, 0, 0, 0);" 00052 " image: url(:/images/themes/default/%1) }" 00053 "QProgressBar::chunk { background-color: rgba(0, 0, 0, 30%); width: 5px; }" ); 00054 00055 mCountProgress->setStyleSheet( mCountStyleSheet.arg( "mIconTimerPause.png" ) ); 00056 mCountProgress->setObjectName( "mCountdown" ); 00057 mCountProgress->setFixedSize( 25, 14 ); 00058 mCountProgress->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ); 00059 mCountProgress->setTextVisible( false ); 00060 mCountProgress->setRange( 0, 5 ); 00061 mCountProgress->setHidden( true ); 00062 mLayout->addWidget( mCountProgress, 0, 0, 1, 1 ); 00063 00064 mItemCount = new QLabel( this ); 00065 mItemCount->setObjectName( "mItemCount" ); 00066 mItemCount->setToolTip( tr( "Remaining messages" ) ); 00067 mItemCount->setSizePolicy( QSizePolicy::Maximum, QSizePolicy::Preferred ); 00068 mLayout->addWidget( mItemCount, 0, 2, 1, 1 ); 00069 00070 mCloseMenu = new QMenu( this ); 00071 mCloseMenu->setObjectName( "mCloseMenu" ); 00072 mActionCloseAll = new QAction( tr( "Close all" ), this ); 00073 mCloseMenu->addAction( mActionCloseAll ); 00074 connect( mActionCloseAll, SIGNAL( triggered() ), this, SLOT( clearWidgets() ) ); 00075 00076 mCloseBtn = new QToolButton( this ); 00077 mCloseMenu->setObjectName( "mCloseMenu" ); 00078 mCloseBtn->setToolTip( tr( "Close" ) ); 00079 mCloseBtn->setMinimumWidth( 40 ); 00080 mCloseBtn->setStyleSheet( 00081 "QToolButton { background-color: rgba(255, 255, 255, 0); } " 00082 "QToolButton::menu-indicator { subcontrol-position: right bottom; subcontrol-origin: padding; bottom: 2px; }" ); 00083 mCloseBtn->setCursor( Qt::PointingHandCursor ); 00084 mCloseBtn->setIcon( QgsApplication::getThemeIcon( "/mIconClose.png" ) ); 00085 mCloseBtn->setIconSize( QSize( 18, 18 ) ); 00086 mCloseBtn->setSizePolicy( QSizePolicy::Maximum, QSizePolicy::Maximum ); 00087 mCloseBtn->setMenu( mCloseMenu ); 00088 connect( mCloseBtn, SIGNAL( clicked() ), this, SLOT( popWidget() ) ); 00089 mLayout->addWidget( mCloseBtn, 0, 3, 1, 1 ); 00090 00091 mCountdownTimer = new QTimer( this ); 00092 mCountdownTimer->setInterval( 1000 ); 00093 connect( mCountdownTimer, SIGNAL( timeout() ), this, SLOT( updateCountdown() ) ); 00094 00095 connect( this, SIGNAL( widgetAdded( QWidget* ) ), this, SLOT( updateItemCount() ) ); 00096 connect( this, SIGNAL( widgetRemoved( QWidget* ) ), this, SLOT( updateItemCount() ) ); 00097 00098 // start hidden 00099 setVisible( false ); 00100 } 00101 00102 QgsMessageBar::~QgsMessageBar() 00103 { 00104 } 00105 00106 void QgsMessageBar::mousePressEvent( QMouseEvent * e ) 00107 { 00108 // stop/start mCountdownTimer 00109 QProgressBar *pb = static_cast<QProgressBar *>( childAt( e->pos() ) ); 00110 if ( pb && pb->objectName() == QString( "mCountdown" ) && e->button() == Qt::LeftButton ) 00111 { 00112 if ( mCountdownTimer->isActive() ) 00113 { 00114 mCountdownTimer->stop(); 00115 pb->setStyleSheet( mCountStyleSheet.arg( "mIconTimerContinue.png" ) ); 00116 } 00117 else 00118 { 00119 mCountdownTimer->start(); 00120 pb->setStyleSheet( mCountStyleSheet.arg( "mIconTimerPause.png" ) ); 00121 } 00122 } 00123 } 00124 00125 void QgsMessageBar::popItem( QgsMessageBarItem *item ) 00126 { 00127 Q_ASSERT( item ); 00128 00129 if ( item != mCurrentItem && !mList.contains( item ) ) 00130 return; 00131 00132 if ( item == mCurrentItem ) 00133 { 00134 if ( mCurrentItem ) 00135 { 00136 mLayout->removeWidget( mCurrentItem->widget() ); 00137 mCurrentItem->widget()->hide(); 00138 if ( mCurrentItem->widget()->parent() == this ) 00139 { 00140 delete mCurrentItem->widget(); 00141 } 00142 delete mCurrentItem; 00143 mCurrentItem = 0; 00144 } 00145 00146 if ( !mList.isEmpty() ) 00147 { 00148 pushItem( mList.first() ); 00149 } 00150 else 00151 { 00152 hide(); 00153 } 00154 } 00155 else 00156 { 00157 mList.removeOne( item ); 00158 } 00159 00160 emit widgetRemoved( item->widget() ); 00161 } 00162 00163 bool QgsMessageBar::popWidget( QWidget *widget ) 00164 { 00165 if ( !widget || !mCurrentItem ) 00166 return false; 00167 00168 if ( widget == mCurrentItem->widget() ) 00169 { 00170 popItem( mCurrentItem ); 00171 return true; 00172 } 00173 00174 foreach ( QgsMessageBarItem *item, mList ) 00175 { 00176 if ( item->widget() == widget ) 00177 { 00178 mList.removeOne( item ); 00179 if ( item->widget()->parent() == this ) 00180 { 00181 delete item->widget(); 00182 } 00183 delete item; 00184 return true; 00185 } 00186 } 00187 00188 return false; 00189 } 00190 00191 bool QgsMessageBar::popWidget() 00192 { 00193 if ( !mCurrentItem ) 00194 return false; 00195 00196 resetCountdown(); 00197 00198 QgsMessageBarItem *item = mCurrentItem; 00199 popItem( item ); 00200 00201 return true; 00202 } 00203 00204 bool QgsMessageBar::clearWidgets() 00205 { 00206 if ( !mCurrentItem && mList.empty() ) 00207 return true; 00208 00209 while ( mList.count() > 0 ) 00210 { 00211 popWidget(); 00212 } 00213 popWidget(); 00214 00215 return !mCurrentItem && mList.empty(); 00216 } 00217 00218 void QgsMessageBar::pushItem( QgsMessageBarItem *item ) 00219 { 00220 Q_ASSERT( item ); 00221 00222 if ( item == mCurrentItem ) 00223 return; 00224 00225 if ( mList.contains( item ) ) 00226 mList.removeOne( item ); 00227 00228 if ( mCurrentItem ) 00229 { 00230 mList.prepend( mCurrentItem ); 00231 mLayout->removeWidget( mCurrentItem->widget() ); 00232 mCurrentItem->widget()->hide(); 00233 } 00234 00235 mCurrentItem = item; 00236 mLayout->addWidget( item->widget(), 0, 1, 1, 1 ); 00237 mCurrentItem->widget()->show(); 00238 00239 if ( item->duration() > 0 ) 00240 { 00241 mCountProgress->setRange( 0, item->duration() ); 00242 mCountProgress->setValue( item->duration() ); 00243 mCountProgress->setVisible( true ); 00244 mCountdownTimer->start(); 00245 } 00246 00247 setStyleSheet( item->styleSheet() ); 00248 show(); 00249 00250 emit widgetAdded( item->widget() ); 00251 } 00252 00253 void QgsMessageBar::pushWidget( QWidget *widget, MessageLevel level, int duration ) 00254 { 00255 resetCountdown(); 00256 00257 QString stylesheet; 00258 if ( level >= CRITICAL ) 00259 { 00260 stylesheet = "QgsMessageBar { background-color: #d65253; border: 1px solid #9b3d3d; } " 00261 "QLabel,QTextEdit { color: white; } "; 00262 } 00263 else if ( level == WARNING ) 00264 { 00265 stylesheet = "QgsMessageBar { background-color: #ffc800; border: 1px solid #e0aa00; } " 00266 "QLabel,QTextEdit { color: black; } "; 00267 } 00268 else if ( level <= INFO ) 00269 { 00270 stylesheet = "QgsMessageBar { background-color: #e7f5fe; border: 1px solid #b9cfe4; } " 00271 "QLabel,QTextEdit { color: #2554a1; } "; 00272 } 00273 stylesheet += "QLabel#mItemCount { font-style: italic; }"; 00274 pushWidget( widget, stylesheet, duration ); 00275 } 00276 00277 void QgsMessageBar::pushWidget( QWidget *widget, const QString &styleSheet, int duration ) 00278 { 00279 if ( !widget ) 00280 return; 00281 00282 // avoid duplicated widget 00283 popWidget( widget ); 00284 00285 pushItem( new QgsMessageBarItem( widget, styleSheet, duration ) ); 00286 } 00287 00288 QWidget* QgsMessageBar::createMessage( const QString &title, const QString &text, const QIcon &icon, QWidget *parent ) 00289 { 00290 QWidget *widget = new QWidget( parent ); 00291 00292 QHBoxLayout *layout = new QHBoxLayout( widget ); 00293 layout->setContentsMargins( 0, 0, 0, 0 ); 00294 00295 if ( !icon.isNull() ) 00296 { 00297 QLabel *lblIcon = new QLabel( widget ); 00298 lblIcon->setPixmap( icon.pixmap( 24 ) ); 00299 layout->addWidget( lblIcon ); 00300 } 00301 00302 QTextEdit *msgText = new QTextEdit( widget ); 00303 msgText->setObjectName( "mMsgText" ); 00304 QString content = text; 00305 if ( !title.isEmpty() ) 00306 { 00307 // add ':' to end of title 00308 QString t = title.trimmed(); 00309 if ( !t.endsWith( ":" ) ) 00310 t += ": "; 00311 content.prepend( QString( "<b>" ) + t + "</b>" ); 00312 } 00313 msgText->setText( content ); 00314 msgText->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Maximum ); 00315 msgText->setReadOnly( true ); 00316 msgText->setFrameShape( QFrame::NoFrame ); 00317 // stylesheet set here so Qt-style substitued scrollbar arrows can show within limited height 00318 // adjusts to height of font set in app options 00319 msgText->setStyleSheet( "* { background-color: rgba(0,0,0,0); margin-top: 0.25em; max-height: 1.75em; min-height: 1.75em; } " 00320 "QScrollBar::add-page,QScrollBar::sub-page,QScrollBar::handle { background-color: rgba(0,0,0,0); color: rgba(0,0,0,0); }" ); 00321 layout->addWidget( msgText ); 00322 00323 return widget; 00324 } 00325 00326 void QgsMessageBar::pushMessage( const QString &title, const QString &text, MessageLevel level, int duration ) 00327 { 00328 QString msgIcon( "/mIconInfo.png" ); 00329 switch ( level ) 00330 { 00331 case QgsMessageBar::CRITICAL: 00332 msgIcon = QString( "/mIconCritical.png" ); 00333 break; 00334 case QgsMessageBar::WARNING: 00335 msgIcon = QString( "/mIconWarn.png" ); 00336 break; 00337 default: 00338 break; 00339 } 00340 00341 QWidget *msg = QgsMessageBar::createMessage( title, text, QgsApplication::getThemeIcon( msgIcon ), this ); 00342 pushWidget( msg, level, duration ); 00343 } 00344 00345 void QgsMessageBar::updateCountdown() 00346 { 00347 if ( !mCountdownTimer->isActive() ) 00348 { 00349 resetCountdown(); 00350 return; 00351 } 00352 if ( mCountProgress->value() < 2 ) 00353 { 00354 popWidget(); 00355 } 00356 else 00357 { 00358 mCountProgress->setValue( mCountProgress->value() - 1 ); 00359 } 00360 } 00361 00362 void QgsMessageBar::resetCountdown() 00363 { 00364 if ( mCountdownTimer->isActive() ) 00365 mCountdownTimer->stop(); 00366 00367 mCountProgress->setStyleSheet( mCountStyleSheet.arg( "mIconTimerPause.png" ) ); 00368 mCountProgress->setVisible( false ); 00369 } 00370 00371 void QgsMessageBar::updateItemCount() 00372 { 00373 mItemCount->setText( mList.count() > 0 ? QString::number( mList.count() ) + QString( " " ) + tr( "more" ) : QString( "" ) ); 00374 }