statusbarprogresswidget.cpp
00001 /* 00002 statusbarprogresswidget.cpp 00003 00004 This file is part of KMail, the KDE mail client. 00005 00006 (C) 2004 KMail Authors 00007 Includes StatusbarProgressWidget which is based on KIOLittleProgressDlg 00008 by Matt Koss <koss@miesto.sk> 00009 00010 KMail is free software; you can redistribute it and/or modify it 00011 under the terms of the GNU General Public License, version 2, as 00012 published by the Free Software Foundation. 00013 00014 KMail is distributed in the hope that it will be useful, but 00015 WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 General Public License for more details. 00018 00019 You should have received a copy of the GNU General Public License 00020 along with this program; if not, write to the Free Software 00021 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00022 00023 In addition, as a special exception, the copyright holders give 00024 permission to link the code of this program with any edition of 00025 the TQt library by Trolltech AS, Norway (or with modified versions 00026 of TQt that use the same license as TQt), and distribute linked 00027 combinations including the two. You must obey the GNU General 00028 Public License in all respects for all of the code used other than 00029 TQt. If you modify this file, you may extend this exception to 00030 your version of the file, but you are not obligated to do so. If 00031 you do not wish to do so, delete this exception statement from 00032 your version. 00033 */ 00034 00035 00036 #include "ssllabel.h" 00037 using KPIM::SSLLabel; 00038 #include "progressmanager.h" 00039 using KPIM::ProgressItem; 00040 using KPIM::ProgressManager; 00041 00042 #include <kprogress.h> 00043 #include <kiconloader.h> 00044 #include <kdebug.h> 00045 00046 #include <tqtimer.h> 00047 #include <tqlabel.h> 00048 #include <tqpushbutton.h> 00049 #include <tqtooltip.h> 00050 #include <klocale.h> 00051 #include <tqlayout.h> 00052 #include <tqwidgetstack.h> 00053 #include <tqframe.h> 00054 00055 #include "progressdialog.h" 00056 #include "statusbarprogresswidget.h" 00057 00058 using namespace KPIM; 00059 00060 //----------------------------------------------------------------------------- 00061 StatusbarProgressWidget::StatusbarProgressWidget( ProgressDialog* progressDialog, TQWidget* parent, bool button ) 00062 : TQFrame( parent ), mCurrentItem( 0 ), mProgressDialog( progressDialog ), 00063 mDelayTimer( 0 ), mBusyTimer( 0 ) 00064 { 00065 m_bShowButton = button; 00066 int w = fontMetrics().width( " 999.9 kB/s 00:00:01 " ) + 8; 00067 box = new TQHBoxLayout( this, 0, 0 ); 00068 00069 m_pButton = new TQPushButton( this ); 00070 m_pButton->setSizePolicy( TQSizePolicy( TQSizePolicy::Minimum, 00071 TQSizePolicy::Minimum ) ); 00072 m_pButton->setPixmap( SmallIcon( "up" ) ); 00073 box->addWidget( m_pButton ); 00074 stack = new TQWidgetStack( this ); 00075 stack->setMaximumHeight( fontMetrics().height() ); 00076 box->addWidget( stack ); 00077 00078 m_sslLabel = new SSLLabel( this ); 00079 box->addWidget( m_sslLabel ); 00080 00081 TQToolTip::add( m_pButton, i18n("Open detailed progress dialog") ); 00082 00083 m_pProgressBar = new KProgress( this ); 00084 m_pProgressBar->setLineWidth( 1 ); 00085 m_pProgressBar->setFrameStyle( TQFrame::Box ); 00086 m_pProgressBar->installEventFilter( this ); 00087 m_pProgressBar->setMinimumWidth( w ); 00088 stack->addWidget( m_pProgressBar, 1 ); 00089 00090 m_pLabel = new TQLabel( TQString(), this ); 00091 m_pLabel->setAlignment( AlignHCenter | AlignVCenter ); 00092 m_pLabel->installEventFilter( this ); 00093 m_pLabel->setMinimumWidth( w ); 00094 stack->addWidget( m_pLabel, 2 ); 00095 m_pButton->setMaximumHeight( fontMetrics().height() ); 00096 setMinimumWidth( minimumSizeHint().width() ); 00097 00098 mode = None; 00099 setMode(); 00100 00101 connect( m_pButton, TQT_SIGNAL( clicked() ), 00102 progressDialog, TQT_SLOT( slotToggleVisibility() ) ); 00103 00104 connect ( ProgressManager::instance(), TQT_SIGNAL( progressItemAdded( KPIM::ProgressItem * ) ), 00105 this, TQT_SLOT( slotProgressItemAdded( KPIM::ProgressItem * ) ) ); 00106 connect ( ProgressManager::instance(), TQT_SIGNAL( progressItemCompleted( KPIM::ProgressItem * ) ), 00107 this, TQT_SLOT( slotProgressItemCompleted( KPIM::ProgressItem * ) ) ); 00108 connect ( ProgressManager::instance(), TQT_SIGNAL(progressItemUsesBusyIndicator(KPIM::ProgressItem*,bool)), 00109 this, TQT_SLOT( updateBusyMode() ) ); 00110 00111 connect ( progressDialog, TQT_SIGNAL( visibilityChanged( bool )), 00112 this, TQT_SLOT( slotProgressDialogVisible( bool ) ) ); 00113 00114 mDelayTimer = new TQTimer( this ); 00115 connect ( mDelayTimer, TQT_SIGNAL( timeout() ), 00116 this, TQT_SLOT( slotShowItemDelayed() ) ); 00117 } 00118 00119 // There are three cases: no progressitem, one progressitem (connect to it directly), 00120 // or many progressitems (display busy indicator). Let's call them 0,1,N. 00121 // In slot..Added we can only end up in 1 or N. 00122 // In slot..Removed we can end up in 0, 1, or we can stay in N if we were already. 00123 00124 void StatusbarProgressWidget::updateBusyMode() 00125 { 00126 connectSingleItem(); // if going to 1 item 00127 if ( mCurrentItem ) { // Exactly one item 00128 delete mBusyTimer; 00129 mBusyTimer = 0; 00130 mDelayTimer->start( 1000, true ); 00131 } 00132 else { // N items 00133 if ( !mBusyTimer ) { 00134 mBusyTimer = new TQTimer( this ); 00135 connect( mBusyTimer, TQT_SIGNAL( timeout() ), 00136 this, TQT_SLOT( slotBusyIndicator() ) ); 00137 mDelayTimer->start( 1000, true ); 00138 } 00139 } 00140 } 00141 00142 void StatusbarProgressWidget::slotProgressItemAdded( ProgressItem *item ) 00143 { 00144 if ( item->parent() ) 00145 return; // we are only interested in top level items 00146 00147 updateBusyMode(); 00148 } 00149 00150 void StatusbarProgressWidget::slotProgressItemCompleted( ProgressItem *item ) 00151 { 00152 if ( item->parent() ) return; // we are only interested in top level items 00153 connectSingleItem(); // if going back to 1 item 00154 if ( ProgressManager::instance()->isEmpty() ) { // No item 00155 // Done. In 5s the progress-widget will close, then we can clean up the statusbar 00156 TQTimer::singleShot( 5000, this, TQT_SLOT( slotClean() ) ); 00157 } else if ( mCurrentItem ) { // Exactly one item 00158 delete mBusyTimer; 00159 mBusyTimer = 0; 00160 activateSingleItemMode(); 00161 } 00162 } 00163 00164 void StatusbarProgressWidget::connectSingleItem() 00165 { 00166 if ( mCurrentItem ) { 00167 disconnect ( mCurrentItem, TQT_SIGNAL( progressItemProgress( KPIM::ProgressItem *, unsigned int ) ), 00168 this, TQT_SLOT( slotProgressItemProgress( KPIM::ProgressItem *, unsigned int ) ) ); 00169 mCurrentItem = 0; 00170 } 00171 mCurrentItem = ProgressManager::instance()->singleItem(); 00172 if ( mCurrentItem ) { 00173 connect ( mCurrentItem, TQT_SIGNAL( progressItemProgress( KPIM::ProgressItem *, unsigned int ) ), 00174 this, TQT_SLOT( slotProgressItemProgress( KPIM::ProgressItem *, unsigned int ) ) ); 00175 } 00176 } 00177 00178 void StatusbarProgressWidget::activateSingleItemMode() 00179 { 00180 m_pProgressBar->setTotalSteps( 100 ); 00181 m_pProgressBar->setProgress( mCurrentItem->progress() ); 00182 m_pProgressBar->setPercentageVisible( true ); 00183 } 00184 00185 void StatusbarProgressWidget::slotShowItemDelayed() 00186 { 00187 bool noItems = ProgressManager::instance()->isEmpty(); 00188 if ( mCurrentItem ) { 00189 activateSingleItemMode(); 00190 } else if ( !noItems ) { // N items 00191 m_pProgressBar->setTotalSteps( 0 ); 00192 m_pProgressBar->setPercentageVisible( false ); 00193 Q_ASSERT( mBusyTimer ); 00194 if ( mBusyTimer ) 00195 mBusyTimer->start( 100 ); 00196 } 00197 00198 if ( !noItems && mode == None ) { 00199 mode = Progress; 00200 setMode(); 00201 } 00202 } 00203 00204 void StatusbarProgressWidget::slotBusyIndicator() 00205 { 00206 int p = m_pProgressBar->progress(); 00207 m_pProgressBar->setProgress( p + 10 ); 00208 } 00209 00210 void StatusbarProgressWidget::slotProgressItemProgress( ProgressItem *item, unsigned int value ) 00211 { 00212 Q_ASSERT( item == mCurrentItem); // the only one we should be connected to 00213 m_pProgressBar->setProgress( value ); 00214 } 00215 00216 void StatusbarProgressWidget::slotSetSSL( bool ssl ) 00217 { 00218 m_sslLabel->setEncrypted( ssl ); 00219 } 00220 00221 void StatusbarProgressWidget::setMode() { 00222 switch ( mode ) { 00223 case None: 00224 if ( m_bShowButton ) { 00225 m_pButton->hide(); 00226 } 00227 m_sslLabel->setState( SSLLabel::Done ); 00228 // show the empty label in order to make the status bar look better 00229 stack->show(); 00230 stack->raiseWidget( m_pLabel ); 00231 break; 00232 00233 #if 0 00234 case Label: 00235 if ( m_bShowButton ) { 00236 m_pButton->show(); 00237 } 00238 m_sslLabel->setState( m_sslLabel->lastState() ); 00239 stack->show(); 00240 stack->raiseWidget( m_pLabel ); 00241 break; 00242 #endif 00243 00244 case Progress: 00245 stack->show(); 00246 stack->raiseWidget( m_pProgressBar ); 00247 if ( m_bShowButton ) { 00248 m_pButton->show(); 00249 } 00250 m_sslLabel->setState( m_sslLabel->lastState() ); 00251 break; 00252 } 00253 } 00254 00255 void StatusbarProgressWidget::slotClean() 00256 { 00257 // check if a new item showed up since we started the timer. If not, clear 00258 if ( ProgressManager::instance()->isEmpty() ) { 00259 m_pProgressBar->setProgress( 0 ); 00260 //m_pLabel->clear(); 00261 mode = None; 00262 setMode(); 00263 } 00264 } 00265 00266 bool StatusbarProgressWidget::eventFilter( TQObject *, TQEvent *ev ) 00267 { 00268 if ( ev->type() == TQEvent::MouseButtonPress ) { 00269 TQMouseEvent *e = (TQMouseEvent*)ev; 00270 00271 if ( e->button() == Qt::LeftButton && mode != None ) { // toggle view on left mouse button 00272 // Consensus seems to be that we should show/hide the fancy dialog when the user 00273 // clicks anywhere in the small one. 00274 mProgressDialog->slotToggleVisibility(); 00275 return true; 00276 } 00277 } 00278 return false; 00279 } 00280 00281 void StatusbarProgressWidget::slotProgressDialogVisible( bool b ) 00282 { 00283 // Update the hide/show button when the detailed one is shown/hidden 00284 if ( b ) { 00285 m_pButton->setPixmap( SmallIcon( "down" ) ); 00286 TQToolTip::remove( m_pButton ); 00287 TQToolTip::add( m_pButton, i18n("Hide detailed progress window") ); 00288 setMode(); 00289 } else { 00290 m_pButton->setPixmap( SmallIcon( "up" ) ); 00291 TQToolTip::remove( m_pButton ); 00292 TQToolTip::add( m_pButton, i18n("Show detailed progress window") ); 00293 } 00294 } 00295 00296 #include "statusbarprogresswidget.moc"