libtdepim

progressmanager.cpp
00001 /*
00002   progressmanager.cpp
00003 
00004   This file is part of TDEPIM.
00005 
00006   Author: Till Adam <adam@kde.org> (C) 2004
00007 
00008   This library is free software; you can redistribute it and/or
00009   modify it under the terms of the GNU Library General Public
00010   License as published by the Free Software Foundation; either
00011   version 2 of the License, or (at your option) any later version.
00012 
00013   This library is distributed in the hope that it will be useful,
00014   but WITHOUT ANY WARRANTY; without even the implied warranty of
00015   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016   Library General Public License for more details.
00017 
00018   You should have received a copy of the GNU Library General Public License
00019   along with this library; see the file COPYING.LIB.  If not, write to
00020   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00021   Boston, MA 02110-1301, USA.
00022 */
00023 
00024 #include <tqvaluevector.h>
00025 #include <kdebug.h>
00026 
00027 #include <tdelocale.h>
00028 #include <kstaticdeleter.h>
00029 
00030 #include "progressmanager.h"
00031 
00032 namespace KPIM {
00033 
00034 KPIM::ProgressManager * KPIM::ProgressManager::mInstance = 0;
00035 unsigned int KPIM::ProgressManager::uID = 42;
00036 
00037 ProgressItem::ProgressItem(
00038        ProgressItem* parent, const TQString& id,
00039        const TQString& label, const TQString& status, bool canBeCanceled,
00040        bool usesCrypto )
00041        :mId( id ), mLabel( label ), mStatus( status ), mParent( parent ),
00042         mCanBeCanceled( canBeCanceled ), mProgress( 0 ), mTotal( 0 ),
00043         mCompleted( 0 ), mWaitingForKids( false ), mCanceled( false ),
00044         mUsesCrypto( usesCrypto ), mUsesBusyIndicator( false )
00045     {}
00046 
00047 ProgressItem::~ProgressItem()
00048 {
00049 }
00050 
00051 void ProgressItem::setComplete()
00052 {
00053 //   kdDebug(5300) << "ProgressItem::setComplete - " << label() << endl;
00054 
00055    if ( mChildren.isEmpty() ) {
00056      if ( !mCanceled )
00057        setProgress( 100 );
00058      emit progressItemCompleted( this );
00059      if ( parent() )
00060        parent()->removeChild( this );
00061      deleteLater();
00062    } else {
00063      mWaitingForKids = true;
00064    }
00065 }
00066 
00067 void ProgressItem::addChild( ProgressItem *kiddo )
00068 {
00069   mChildren.replace( kiddo, true );
00070 }
00071 
00072 void ProgressItem::removeChild( ProgressItem *kiddo )
00073 {
00074    mChildren.remove( kiddo );
00075    // in case we were waiting for the last kid to go away, now is the time
00076    if ( mChildren.count() == 0 && mWaitingForKids ) {
00077      emit progressItemCompleted( this );
00078      deleteLater();
00079    }
00080 }
00081 
00082 void ProgressItem::cancel()
00083 {
00084    if ( mCanceled || !mCanBeCanceled ) return;
00085    kdDebug(5300) << "ProgressItem::cancel() - " << label() << endl;
00086    mCanceled = true;
00087    // Cancel all children.
00088    TQValueList<ProgressItem*> kids = mChildren.keys();
00089    TQValueList<ProgressItem*>::Iterator it( kids.begin() );
00090    TQValueList<ProgressItem*>::Iterator end( kids.end() );
00091    for ( ; it != end; it++ ) {
00092      ProgressItem *kid = *it;
00093      if ( kid->canBeCanceled() )
00094        kid->cancel();
00095    }
00096    setStatus( i18n( "Aborting..." ) );
00097    emit progressItemCanceled( this );
00098 }
00099 
00100 
00101 void ProgressItem::setProgress( unsigned int v )
00102 {
00103    mProgress = v;
00104    // kdDebug(5300) << "ProgressItem::setProgress(): " << label() << " : " << v << endl;
00105    emit progressItemProgress( this, mProgress );
00106 }
00107 
00108 void ProgressItem::setLabel( const TQString& v )
00109 {
00110   mLabel = v;
00111   emit progressItemLabel( this, mLabel );
00112 }
00113 
00114 void ProgressItem::setStatus( const TQString& v )
00115 {
00116   mStatus = v;
00117   emit progressItemStatus( this, mStatus );
00118 }
00119 
00120 void ProgressItem::setUsesCrypto( bool v )
00121 {
00122   mUsesCrypto = v;
00123   emit progressItemUsesCrypto( this, v );
00124 }
00125 
00126 void ProgressItem::setUsesBusyIndicator( bool useBusyIndicator )
00127 {
00128   mUsesBusyIndicator = useBusyIndicator;
00129   emit progressItemUsesBusyIndicator( this, useBusyIndicator );
00130 }
00131 
00132 // ======================================
00133 
00134 ProgressManager::ProgressManager() :TQObject() {
00135   mInstance = this;
00136 }
00137 
00138 ProgressManager::~ProgressManager() { mInstance = 0; }
00139 static KStaticDeleter<ProgressManager> progressManagerDeleter;
00140 
00141 ProgressManager* ProgressManager::instance()
00142 {
00143    if ( !mInstance ) {
00144      progressManagerDeleter.setObject( mInstance, new ProgressManager() );
00145    }
00146    return mInstance;
00147 }
00148 
00149 ProgressItem* ProgressManager::createProgressItemImpl(
00150      ProgressItem* parent, const TQString& id,
00151      const TQString &label, const TQString &status,
00152      bool cancellable, bool usesCrypto )
00153 {
00154    ProgressItem *t = 0;
00155    if ( !mTransactions[ id ] ) {
00156      t = new ProgressItem ( parent, id, label, status, cancellable, usesCrypto );
00157      mTransactions.insert( id, t );
00158      if ( parent ) {
00159        ProgressItem *p = mTransactions[ parent->id() ];
00160        if ( p ) {
00161          p->addChild( t );
00162        }
00163      }
00164      // connect all signals
00165      connect ( t, TQT_SIGNAL( progressItemCompleted(KPIM::ProgressItem*) ),
00166                this, TQT_SLOT( slotTransactionCompleted(KPIM::ProgressItem*) ) );
00167      connect ( t, TQT_SIGNAL( progressItemProgress(KPIM::ProgressItem*, unsigned int) ),
00168                this, TQT_SIGNAL( progressItemProgress(KPIM::ProgressItem*, unsigned int) ) );
00169      connect ( t, TQT_SIGNAL( progressItemAdded(KPIM::ProgressItem*) ),
00170                this, TQT_SIGNAL( progressItemAdded(KPIM::ProgressItem*) ) );
00171      connect ( t, TQT_SIGNAL( progressItemCanceled(KPIM::ProgressItem*) ),
00172                this, TQT_SIGNAL( progressItemCanceled(KPIM::ProgressItem*) ) );
00173      connect ( t, TQT_SIGNAL( progressItemStatus(KPIM::ProgressItem*, const TQString&) ),
00174                this, TQT_SIGNAL( progressItemStatus(KPIM::ProgressItem*, const TQString&) ) );
00175      connect ( t, TQT_SIGNAL( progressItemLabel(KPIM::ProgressItem*, const TQString&) ),
00176                this, TQT_SIGNAL( progressItemLabel(KPIM::ProgressItem*, const TQString&) ) );
00177      connect ( t, TQT_SIGNAL( progressItemUsesCrypto(KPIM::ProgressItem*, bool) ),
00178                this, TQT_SIGNAL( progressItemUsesCrypto(KPIM::ProgressItem*, bool) ) );
00179      connect ( t, TQT_SIGNAL( progressItemUsesBusyIndicator(KPIM::ProgressItem*, bool) ),
00180                this, TQT_SIGNAL( progressItemUsesBusyIndicator(KPIM::ProgressItem*, bool) ) );
00181 
00182      emit progressItemAdded( t );
00183    } else {
00184      // Hm, is this what makes the most sense?
00185      t = mTransactions[id];
00186    }
00187    return t;
00188 }
00189 
00190 ProgressItem* ProgressManager::createProgressItemImpl(
00191      const TQString& parent, const TQString &id,
00192      const TQString &label, const TQString& status,
00193      bool canBeCanceled, bool usesCrypto )
00194 {
00195    ProgressItem * p = mTransactions[parent];
00196    return createProgressItemImpl( p, id, label, status, canBeCanceled, usesCrypto );
00197 }
00198 
00199 void ProgressManager::emitShowProgressDialogImpl()
00200 {
00201    emit showProgressDialog();
00202 }
00203 
00204 
00205 // slots
00206 
00207 void ProgressManager::slotTransactionCompleted( ProgressItem *item )
00208 {
00209    mTransactions.remove( item->id() );
00210    emit progressItemCompleted( item );
00211 }
00212 
00213 void ProgressManager::slotStandardCancelHandler( ProgressItem *item )
00214 {
00215   item->setComplete();
00216 }
00217 
00218 ProgressItem* ProgressManager::singleItem() const
00219 {
00220   ProgressItem *item = 0;
00221   TQDictIterator< ProgressItem > it( mTransactions );
00222   for ( ; it.current(); ++it ) {
00223 
00224     // No single item for progress possible, as one of them is a busy indicator one.
00225     if ( (*it)->usesBusyIndicator() )
00226       return 0;
00227 
00228     if ( !(*it)->parent() ) {             // if it's a top level one, only those count
00229       if ( item )
00230         return 0; // we found more than one
00231       else
00232         item = (*it);
00233     }
00234   }
00235   return item;
00236 }
00237 
00238 void ProgressManager::slotAbortAll()
00239 {
00240   TQDictIterator< ProgressItem > it( mTransactions );
00241   for ( ; it.current(); ++it ) {
00242     it.current()->cancel();
00243   }
00244 }
00245 
00246 } // namespace
00247 
00248 #include "progressmanager.moc"