libkdepim Library API Documentation

progressdialog.cpp

00001 
00032 #ifdef HAVE_CONFIG_H
00033 #include <config.h>
00034 #endif
00035 
00036 #include <qapplication.h>
00037 #include <qlayout.h>
00038 #include <qprogressbar.h>
00039 #include <qtimer.h>
00040 #include <qheader.h>
00041 #include <qobject.h>
00042 #include <qscrollview.h>
00043 #include <qtoolbutton.h>
00044 #include <qpushbutton.h>
00045 #include <qvbox.h>
00046 #include <qtooltip.h>
00047 
00048 #include <klocale.h>
00049 #include <kdialog.h>
00050 #include <kstdguiitem.h>
00051 #include <kiconloader.h>
00052 #include <kdebug.h>
00053 
00054 #include "progressdialog.h"
00055 #include "progressmanager.h"
00056 #include "ssllabel.h"
00057 #include <qwhatsthis.h>
00058 
00059 namespace KPIM {
00060 
00061 class TransactionItem;
00062 
00063 TransactionItemView::TransactionItemView( QWidget * parent,
00064                                           const char * name,
00065                                           WFlags f )
00066     : QScrollView( parent, name, f ) {
00067   setFrameStyle( NoFrame );
00068   mBigBox = new QVBox( viewport() );
00069   mBigBox->setSpacing( 5 );
00070   addChild( mBigBox );
00071   setResizePolicy( QScrollView::AutoOneFit ); // Fit so that the box expands horizontally
00072 }
00073 
00074 TransactionItem* TransactionItemView::addTransactionItem( ProgressItem* item, bool first )
00075 {
00076    TransactionItem *ti = new TransactionItem( mBigBox, item, first );
00077    ti->hide();
00078    QTimer::singleShot( 1000, ti, SLOT( show() ) );
00079    return ti;
00080 }
00081 
00082 void TransactionItemView::resizeContents( int w, int h )
00083 {
00084   //kdDebug(5300) << k_funcinfo << w << "," << h << endl;
00085   QScrollView::resizeContents( w, h );
00086   // Tell the layout in the parent (progressdialog) that our size changed
00087   updateGeometry();
00088   // Resize the parent (progressdialog) - this works but resize horizontally too often
00089   //parentWidget()->adjustSize();
00090 
00091   QApplication::sendPostedEvents( 0, QEvent::ChildInserted );
00092   QApplication::sendPostedEvents( 0, QEvent::LayoutHint );
00093   QSize sz = parentWidget()->sizeHint();
00094   int currentWidth = parentWidget()->width();
00095   // Don't resize to sz.width() every time when it only reduces a little bit
00096   if ( currentWidth < sz.width() || currentWidth > sz.width() + 100 )
00097     currentWidth = sz.width();
00098   parentWidget()->resize( currentWidth, sz.height() );
00099 }
00100 
00101 QSize TransactionItemView::sizeHint() const
00102 {
00103   return minimumSizeHint();
00104 }
00105 
00106 QSize TransactionItemView::minimumSizeHint() const
00107 {
00108   int f = 2 * frameWidth();
00109   // Make room for a vertical scrollbar in all cases, to avoid a horizontal one
00110   int vsbExt = verticalScrollBar()->sizeHint().width();
00111   int minw = topLevelWidget()->width() / 3;
00112   int maxh = topLevelWidget()->height() / 2;
00113   QSize sz( mBigBox->minimumSizeHint() );
00114   sz.setWidth( QMAX( sz.width(), minw ) + f + vsbExt );
00115   sz.setHeight( QMIN( sz.height(), maxh ) + f );
00116   return sz;
00117 }
00118 
00119 
00120 void TransactionItemView::slotLayoutFirstItem()
00121 {
00122   /*
00123      The below relies on some details in Qt's behaviour regarding deleting
00124      objects. This slot is called from the destroyed signal of an item just
00125      going away. That item is at that point still in the  list of chilren, but
00126      since the vtable is already gone, it will have type QObject. The first
00127      one with both the right name and the right class therefor is what will
00128      be the first item very shortly. That's the one we want to remove the
00129      hline for.
00130   */
00131   QObject *o = mBigBox->child( "TransactionItem", "KPIM::TransactionItem" );
00132   TransactionItem *ti = dynamic_cast<TransactionItem*>( o );
00133   if ( ti ) {
00134     ti->hideHLine();
00135   }
00136 }
00137 
00138 
00139 // ----------------------------------------------------------------------------
00140 
00141 TransactionItem::TransactionItem( QWidget* parent,
00142                                   ProgressItem *item, bool first )
00143   : QVBox( parent, "TransactionItem" ), mCancelButton( 0 ), mItem( item )
00144 
00145 {
00146   setSpacing( 2 );
00147   setMargin( 2 );
00148   setSizePolicy( QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed ) );
00149 
00150   mFrame = new QFrame( this );
00151   mFrame->setFrameShape( QFrame::HLine );
00152   mFrame->setFrameShadow( QFrame::Raised );
00153   mFrame->show();
00154   setStretchFactor( mFrame, 3 );
00155 
00156   QHBox *h = new QHBox( this );
00157   h->setSpacing( 5 );
00158 
00159   mItemLabel = new QLabel( item->label(), h );
00160   h->setSizePolicy( QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed ) );
00161 
00162 
00163   if ( item->canBeCanceled() ) {
00164     mCancelButton = new QPushButton( SmallIcon( "cancel" ), QString::null, h );
00165     QToolTip::add( mCancelButton, i18n("Cancel this operation.") );
00166     connect ( mCancelButton, SIGNAL( clicked() ),
00167               this, SLOT( slotItemCanceled() ));
00168   }
00169   mProgress = new QProgressBar( 100, h );
00170   mProgress->setProgress( item->progress() );
00171 
00172   h = new QHBox( this );
00173   h->setSpacing( 5 );
00174   h->setSizePolicy( QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed ) );
00175   mSSLLabel = new SSLLabel( h );
00176   mSSLLabel->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) );
00177   mItemStatus =  new QLabel( item->status(), h );
00178   setCrypto( item->usesCrypto() );
00179   if( first ) hideHLine();
00180 }
00181 
00182 TransactionItem::~TransactionItem()
00183 {
00184 }
00185 
00186 void TransactionItem::hideHLine()
00187 {
00188     mFrame->hide();
00189 }
00190 
00191 void TransactionItem::setProgress( int progress )
00192 {
00193   mProgress->setProgress( progress );
00194 }
00195 
00196 void TransactionItem::setLabel( const QString& label )
00197 {
00198   mItemLabel->setText( label );
00199 }
00200 
00201 void TransactionItem::setStatus( const QString& status )
00202 {
00203   mItemStatus->setText( status );
00204 }
00205 
00206 void TransactionItem::setCrypto( bool on )
00207 {
00208   if (on)
00209     mSSLLabel->setEncrypted( true );
00210   else
00211     mSSLLabel->setEncrypted( false );
00212 
00213   mSSLLabel->setState( mSSLLabel->lastState() );
00214 }
00215 
00216 void TransactionItem::slotItemCanceled()
00217 {
00218   if ( mItem )
00219     mItem->cancel();
00220 }
00221 
00222 
00223 void TransactionItem::addSubTransaction( ProgressItem* /*item*/ )
00224 {
00225 
00226 }
00227 
00228 
00229 // ---------------------------------------------------------------------------
00230 
00231 ProgressDialog::ProgressDialog( QWidget* alignWidget, QWidget* parent, const char* name )
00232     : OverlayWidget( alignWidget, parent, name )
00233 {
00234     setFrameStyle( QFrame::Panel | QFrame::Sunken ); // QFrame
00235     setSpacing( 0 ); // QHBox
00236     setMargin( 1 );
00237 
00238     mScrollView = new TransactionItemView( this, "ProgressScrollView" );
00239 
00240     QVBox* rightBox = new QVBox( this );
00241     QToolButton* pbClose = new QToolButton( rightBox );
00242     pbClose->setAutoRaise(true);
00243     pbClose->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) );
00244     pbClose->setFixedSize( 16, 16 );
00245     pbClose->setIconSet( KGlobal::iconLoader()->loadIconSet( "fileclose", KIcon::Small, 14 ) );
00246     QToolTip::add( pbClose, i18n( "Hide detailed progress window" ) );
00247     connect(pbClose, SIGNAL(clicked()), this, SLOT(slotClose()));
00248     QWidget* spacer = new QWidget( rightBox ); // don't let the close button take up all the height
00249     rightBox->setStretchFactor( spacer, 100 );
00250 
00251 
00252     /*
00253      * Get the singleton ProgressManager item which will inform us of
00254      * appearing and vanishing items.
00255      */
00256     ProgressManager *pm = ProgressManager::instance();
00257     connect ( pm, SIGNAL( progressItemAdded( ProgressItem* ) ),
00258               this, SLOT( slotTransactionAdded( ProgressItem* ) ) );
00259     connect ( pm, SIGNAL( progressItemCompleted( ProgressItem* ) ),
00260               this, SLOT( slotTransactionCompleted( ProgressItem* ) ) );
00261     connect ( pm, SIGNAL( progressItemProgress( ProgressItem*, unsigned int ) ),
00262               this, SLOT( slotTransactionProgress( ProgressItem*, unsigned int ) ) );
00263     connect ( pm, SIGNAL( progressItemStatus( ProgressItem*, const QString& ) ),
00264               this, SLOT( slotTransactionStatus( ProgressItem*, const QString& ) ) );
00265     connect ( pm, SIGNAL( progressItemLabel( ProgressItem*, const QString& ) ),
00266               this, SLOT( slotTransactionLabel( ProgressItem*, const QString& ) ) );
00267     connect ( pm, SIGNAL( progressItemUsesCrypto( ProgressItem*, bool ) ),
00268               this, SLOT( slotTransactionUsesCrypto( ProgressItem*, bool ) ) );
00269     connect ( pm, SIGNAL( showProgressDialog() ),
00270               this, SLOT( slotShow() ) );
00271 }
00272 
00273 void ProgressDialog::closeEvent( QCloseEvent* e )
00274 {
00275   e->accept();
00276   hide();
00277 }
00278 
00279 
00280 /*
00281  *  Destructor
00282  */
00283 ProgressDialog::~ProgressDialog()
00284 {
00285     // no need to delete child widgets.
00286 }
00287 
00288 void ProgressDialog::slotTransactionAdded( ProgressItem *item )
00289 {
00290    TransactionItem *parent = 0;
00291    if ( item->parent() ) {
00292      if ( mTransactionsToListviewItems.contains( item->parent() ) ) {
00293        parent = mTransactionsToListviewItems[ item->parent() ];
00294        parent->addSubTransaction( item );
00295      }
00296    } else {
00297      TransactionItem *ti = mScrollView->addTransactionItem( item, mTransactionsToListviewItems.empty() );
00298      if ( ti )
00299        mTransactionsToListviewItems.replace( item, ti );
00300    }
00301 }
00302 
00303 void ProgressDialog::slotTransactionCompleted( ProgressItem *item )
00304 {
00305    if ( mTransactionsToListviewItems.contains( item ) ) {
00306      TransactionItem *ti = mTransactionsToListviewItems[ item ];
00307      mTransactionsToListviewItems.remove( item );
00308      ti->setItemComplete();
00309      QTimer::singleShot( 3000, ti, SLOT( deleteLater() ) );
00310      // see the slot for comments as to why that works
00311      connect ( ti, SIGNAL( destroyed() ),
00312                mScrollView, SLOT( slotLayoutFirstItem() ) );
00313    }
00314    // This was the last item, hide.
00315    if ( mTransactionsToListviewItems.empty() )
00316      QTimer::singleShot( 3000, this, SLOT( slotHide() ) );
00317 }
00318 
00319 void ProgressDialog::slotTransactionCanceled( ProgressItem* )
00320 {
00321 }
00322 
00323 void ProgressDialog::slotTransactionProgress( ProgressItem *item,
00324                                               unsigned int progress )
00325 {
00326    if ( mTransactionsToListviewItems.contains( item ) ) {
00327      TransactionItem *ti = mTransactionsToListviewItems[ item ];
00328      ti->setProgress( progress );
00329    }
00330 }
00331 
00332 void ProgressDialog::slotTransactionStatus( ProgressItem *item,
00333                                             const QString& status )
00334 {
00335    if ( mTransactionsToListviewItems.contains( item ) ) {
00336      TransactionItem *ti = mTransactionsToListviewItems[ item ];
00337      ti->setStatus( status );
00338    }
00339 }
00340 
00341 void ProgressDialog::slotTransactionLabel( ProgressItem *item,
00342                                            const QString& label )
00343 {
00344    if ( mTransactionsToListviewItems.contains( item ) ) {
00345      TransactionItem *ti = mTransactionsToListviewItems[ item ];
00346      ti->setLabel( label );
00347    }
00348 }
00349 
00350 
00351 void ProgressDialog::slotTransactionUsesCrypto( ProgressItem *item,
00352                                                 bool value )
00353 {
00354    if ( mTransactionsToListviewItems.contains( item ) ) {
00355      TransactionItem *ti = mTransactionsToListviewItems[ item ];
00356      ti->setCrypto( value );
00357    }
00358 }
00359 
00360 void ProgressDialog::slotShow()
00361 {
00362    setVisible( true );
00363 }
00364 
00365 void ProgressDialog::slotHide()
00366 {
00367   // check if a new item showed up since we started the timer. If not, hide
00368   if ( mTransactionsToListviewItems.isEmpty() ) {
00369     setVisible( false );
00370   }
00371 }
00372 
00373 void ProgressDialog::slotClose()
00374 {
00375   setVisible( false );
00376 }
00377 
00378 void ProgressDialog::setVisible( bool b )
00379 {
00380   if ( b )
00381       show();
00382     else
00383       hide();
00384   emit visibilityChanged( b );
00385 }
00386 
00387 void ProgressDialog::slotToggleVisibility()
00388 {
00389   /* Since we are only hiding with a timeout, there is a short period of
00390    * time where the last item is still visible, but clicking on it in
00391    * the statusbarwidget should not display the dialog, because there
00392    * are no items to be shown anymore. Guard against that.
00393    */
00394   if ( isShown() || !mTransactionsToListviewItems.isEmpty() )
00395     setVisible( !isShown() );
00396 }
00397 
00398 }
00399 
00400 #include "progressdialog.moc"
KDE Logo
This file is part of the documentation for libkdepim Library Version 3.3.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu Oct 4 14:40:45 2007 by doxygen 1.4.2 written by Dimitri van Heesch, © 1997-2003