You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdepim/libkdepim/progressmanager.h

437 lines
16 KiB

/*
progressmanager.h
This file is part of KDEPIM.
Author: Till Adam <adam@kde.org> (C) 2004
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef __KPIM_PROGRESSMANAGER_H__
#define __KPIM_PROGRESSMANAGER_H__
#include <tqobject.h>
#include <tqdict.h>
#include <tqstring.h>
#include <kdepimmacros.h>
namespace KPIM {
class ProgressItem;
class ProgressManager;
typedef TQMap<ProgressItem*, bool> ProgressItemMap;
class KDE_EXPORT ProgressItem : public QObject
{
Q_OBJECT
friend class ProgressManager;
friend class TQDict< ProgressItem >; // so it can be deleted from dicts
public:
/**
* @return The id string which uniquely identifies the operation
* represented by this item.
*/
const TQString& id() const { return mId; }
/**
* @return The parent item of this one, if there is one.
*/
ProgressItem *parent() const { return mParent; }
/**
* @return The user visible string to be used to represent this item.
*/
const TQString& label() const { return mLabel; }
/**
* @param v Set the user visible string identifying this item. @p v will
be interpreted as rich text, so it might have to be escaped.
*/
void setLabel( const TQString& v );
/**
* @return The string to be used for showing this item's current status.
*/
const TQString& status() const { return mStatus; }
/**
* Set the string to be used for showing this item's current status.
* @p v will be interpreted as rich text, so it might have to be escaped.
* @param v The status string.
*/
void setStatus( const TQString& v );
/**
* @return Whether this item can be cancelled.
*/
bool canBeCanceled() const { return mCanBeCanceled; }
/**
* @return Whether this item uses secure communication
* (Account uses ssl, for example.).
*/
bool usesCrypto() const { return mUsesCrypto; }
/**
* Set whether this item uses crypted communication, so listeners
* can display a nice crypto icon.
* @param v The value.
*/
void setUsesCrypto( bool v );
/**
* @return whether this item uses a busy indicator instead of real progress display
*/
bool usesBusyIndicator() const { return mUsesBusyIndicator; }
/**
* Sets whether this item uses a busy indicator instead of real progress for its progress bar.
* If it uses a busy indicator, you are still responsible for calling setProgress() from time to
* time to update the busy indicator.
*/
void setUsesBusyIndicator( bool useBusyIndicator );
/**
* @return The current progress value of this item in percent.
*/
unsigned int progress() const { return mProgress; }
/**
* Set the progress (percentage of completion) value of this item.
* @param v The percentage value.
*/
void setProgress( unsigned int v );
/**
* Tell the item it has finished. This will emit progressItemCompleted()
* result in the destruction of the item after all slots connected to this
* signal have executed. This is the only way to get rid of an item and
* needs to be called even if the item is cancelled. Don't use the item
* after this has been called on it.
*/
void setComplete();
/**
* Reset the progress value of this item to 0 and the status string to
* the empty string.
*/
void reset() { setProgress( 0 ); setStatus( TQString::null ); mCompleted = 0; }
void cancel();
// Often needed values for calculating progress.
void setTotalItems( unsigned int v ) { mTotal = v; }
unsigned int totalItems() const { return mTotal; }
void setCompletedItems( unsigned int v ) { mCompleted = v; }
void incCompletedItems( unsigned int v = 1 ) { mCompleted += v; }
unsigned int completedItems() const { return mCompleted; }
/**
* Recalculate progress according to total/completed items and update.
*/
void updateProgress() { setProgress( mTotal? mCompleted*100/mTotal: 0 ); }
void addChild( ProgressItem *kiddo );
void removeChild( ProgressItem *kiddo );
bool canceled() const { return mCanceled; }
signals:
/**
* Emitted when a new ProgressItem is added.
* @param The ProgressItem that was added.
*/
void progressItemAdded( KPIM::ProgressItem* );
/**
* Emitted when the progress value of an item changes.
* @param The item which got a new value.
* @param The value, for convenience.
*/
void progressItemProgress( KPIM::ProgressItem*, unsigned int );
/**
* Emitted when a progress item was completed. The item will be
* deleted afterwards, so slots connected to this are the last
* chance to work with this item.
* @param The completed item.
*/
void progressItemCompleted( KPIM::ProgressItem* );
/**
* Emitted when an item was cancelled. It will _not_ go away immediately,
* only when the owner sets it complete, which will usually happen. Can be
* used to visually indicate the cancelled status of an item. Should be used
* by the owner of the item to make sure it is set completed even if it is
* cancelled. There is a ProgressManager::slotStandardCancelHandler which
* simply sets the item completed and can be used if no other work needs to
* be done on cancel.
* @param The canceled item;
*/
void progressItemCanceled( KPIM::ProgressItem* );
/**
* Emitted when the status message of an item changed. Should be used by
* progress dialogs to update the status message for an item.
* @param The updated item.
* @param The new message.
*/
void progressItemStatus( KPIM::ProgressItem*, const TQString& );
/**
* Emitted when the label of an item changed. Should be used by
* progress dialogs to update the label of an item.
* @param The updated item.
* @param The new label.
*/
void progressItemLabel( KPIM::ProgressItem*, const TQString& );
/**
* Emitted when the crypto status of an item changed. Should be used by
* progress dialogs to update the crypto indicator of an item.
* @param The updated item.
* @param The new state.
*/
void progressItemUsesCrypto( KPIM::ProgressItem*, bool );
/**
* Emitted when the busy indicator state of an item changes. Should be used
* by progress dialogs so that they can adjust the display of the progress bar
* to the new mode.
* @param item The updated item
* @param value True if the item uses a busy indicator now, false otherwise
*/
void progressItemUsesBusyIndicator( KPIM::ProgressItem *item, bool value );
protected:
/* Only to be used by our good friend the ProgressManager */
ProgressItem( ProgressItem* parent,
const TQString& id,
const TQString& label,
const TQString& status,
bool isCancellable,
bool usesCrypto );
virtual ~ProgressItem();
private:
TQString mId;
TQString mLabel;
TQString mStatus;
ProgressItem* mParent;
bool mCanBeCanceled;
unsigned int mProgress;
ProgressItemMap mChildren;
unsigned int mTotal;
unsigned int mCompleted;
bool mWaitingForKids;
bool mCanceled;
bool mUsesCrypto;
bool mUsesBusyIndicator;
};
/**
* The ProgressManager singleton keeps track of all ongoing transactions
* and notifies observers (progress dialogs) when their progress percent value
* changes, when they are completed (by their owner), and when they are canceled.
* Each ProgressItem emits those signals individually and the singleton
* broadcasts them. Use the ::createProgressItem() statics to acquire an item
* and then call ->setProgress( int percent ) on it everytime you want to update
* the item and ->setComplete() when the operation is done. This will delete the
* item. Connect to the item's progressItemCanceled() signal to be notified when
* the user cancels the transaction using one of the observing progress dialogs
* or by calling item->cancel() in some other way. The owner is responsible for
* calling setComplete() on the item, even if it is canceled. Use the
* standardCancelHandler() slot if that is all you want to do on cancel.
*
* Note that if you request an item with a certain id and there is already
* one with that id, there will not be a new one created but the existing
* one will be returned. This is convenient for accessing items that are
* needed regularly without the to store a pointer to them or to add child
* items to parents by id.
*/
class KDE_EXPORT ProgressManager : public QObject
{
Q_OBJECT
public:
virtual ~ProgressManager();
/**
* @return The singleton instance of this class.
*/
static ProgressManager * instance();
/**
* Use this to aquire a unique id number which can be used to discern
* an operation from all others going on at the same time. Use that
* number as the id string for your progressItem to ensure it is unique.
* @return
*/
static TQString getUniqueID() { return TQString::number( ++uID ); }
/**
* Creates a ProgressItem with a unique id and the given label.
* This is the simplest way to aquire a progress item. It will not
* have a parent and will be set to be cancellable and not using crypto.
*
* @param label The text to be displayed by progress handlers. It will be
* interpreted as rich text, so it might have to be escaped.
*/
static ProgressItem * createProgressItem( const TQString &label ) {
return instance()->createProgressItemImpl( 0, getUniqueID(), label,
TQString::null, true, false );
}
/**
* Creates a new progressItem with the given parent, id, label and initial
* status.
*
* @param parent Specify an already existing item as the parent of this one.
* @param id Used to identify this operation for cancel and progress info.
* @param label The text to be displayed by progress handlers. It will be
* interpreted as rich text, so it might have to be escaped.
* @param status Additional text to be displayed for the item. It will be
* interpreted as rich text, so it might have to be escaped.
* @param canBeCanceled can the user cancel this operation?
* @param usesCrypto does the operation use secure transports (SSL)
* Cancelling the parent will cancel the children as well (if they can be
* cancelled) and ongoing children prevent parents from finishing.
* @return The ProgressItem representing the operation.
*/
static ProgressItem * createProgressItem( ProgressItem* parent,
const TQString& id,
const TQString& label,
const TQString& status = TQString::null,
bool canBeCanceled = true,
bool usesCrypto = false ) {
return instance()->createProgressItemImpl( parent, id, label, status,
canBeCanceled, usesCrypto );
}
/**
* Use this version if you have the id string of the parent and want to
* add a subjob to it.
*/
static ProgressItem * createProgressItem( const TQString& parent,
const TQString& id,
const TQString& label,
const TQString& status = TQString::null,
bool canBeCanceled = true,
bool usesCrypto = false ) {
return instance()->createProgressItemImpl( parent, id, label,
status, canBeCanceled, usesCrypto );
}
/**
* Version without a parent.
*/
static ProgressItem * createProgressItem( const TQString& id,
const TQString& label,
const TQString& status = TQString::null,
bool canBeCanceled = true,
bool usesCrypto = false ) {
return instance()->createProgressItemImpl( 0, id, label, status,
canBeCanceled, usesCrypto );
}
/**
* @return true when there is no more progress item
*/
bool isEmpty() const { return mTransactions.isEmpty(); }
/**
* @return the only top level progressitem when there's only one.
* Returns 0 if there is no item, or more than one top level item.
* Since this is used to calculate the overall progress, it will also return
* 0 if there is an item which uses a busy indicator, since that will invalidate
* the overall progress.
*/
ProgressItem* singleItem() const;
/**
* Ask all listeners to show the progress dialog, because there is
* something that wants to be shown.
*/
static void emitShowProgressDialog() {
instance()->emitShowProgressDialogImpl();
}
signals:
/** @see ProgressItem::progressItemAdded() */
void progressItemAdded( KPIM::ProgressItem* );
/** @see ProgressItem::progressItemProgress() */
void progressItemProgress( KPIM::ProgressItem*, unsigned int );
/** @see ProgressItem::progressItemCompleted() */
void progressItemCompleted( KPIM::ProgressItem* );
/** @see ProgressItem::progressItemCanceled() */
void progressItemCanceled( KPIM::ProgressItem* );
/** @see ProgressItem::progressItemStatus() */
void progressItemStatus( KPIM::ProgressItem*, const TQString& );
/** @see ProgressItem::progressItemLabel() */
void progressItemLabel( KPIM::ProgressItem*, const TQString& );
/** @see ProgressItem::progressItemUsesCrypto() */
void progressItemUsesCrypto( KPIM::ProgressItem*, bool );
/** @see ProgressItem::progressItemUsesBusyIndicator */
void progressItemUsesBusyIndicator( KPIM::ProgressItem*, bool );
/**
* Emitted when an operation requests the listeners to be shown.
* Use emitShowProgressDialog() to trigger it.
*/
void showProgressDialog();
public slots:
/**
* Calls setCompleted() on the item, to make sure it goes away.
* Provided for convenience.
* @param item the canceled item.
*/
void slotStandardCancelHandler( KPIM::ProgressItem* item );
/**
* Aborts all running jobs. Bound to "Esc"
*/
void slotAbortAll();
private slots:
void slotTransactionCompleted( KPIM::ProgressItem *item );
private:
ProgressManager();
// prevent unsolicited copies
ProgressManager( const ProgressManager& );
virtual ProgressItem* createProgressItemImpl(
ProgressItem* parent, const TQString& id,
const TQString& label, const TQString& status,
bool cancellable, bool usesCrypto );
virtual ProgressItem* createProgressItemImpl(
const TQString& parent, const TQString& id,
const TQString& label, const TQString& status,
bool cancellable, bool usesCrypto );
void emitShowProgressDialogImpl();
TQDict< ProgressItem > mTransactions;
static ProgressManager *mInstance;
static unsigned int uID;
};
}
#endif // __KPIM_PROGRESSMANAGER_H__