4 This file is part of libkdepim.
6 Copyright (C) 2004 Till Adam <adam@kde.org>
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
18 You should have received a copy of the GNU Library General Public License
19 along with this library; see the file COPYING.LIB. If not, write to
20 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA.
24 #ifndef KDEPIM_PROGRESSMANAGER_H
25 #define KDEPIM_PROGRESSMANAGER_H
27 #include "kdepim_export.h"
33 #include <QWeakPointer>
42 class ProgressManager
;
43 typedef QMap
<ProgressItem
*, bool> ProgressItemMap
;
45 class KDEPIM_EXPORT ProgressItem
: public QObject
48 friend class ProgressManager
;
53 * @return The id string which uniquely identifies the operation
54 * represented by this item.
56 const QString
&id() const { return mId
; }
59 * @return The parent item of this one, if there is one.
61 ProgressItem
*parent() const { return mParent
.data(); }
64 * @return The user visible string to be used to represent this item.
66 const QString
&label() const { return mLabel
; }
69 * @param v Set the user visible string identifying this item.
71 void setLabel( const QString
&v
);
74 * @return The string to be used for showing this item's current status.
76 const QString
&status() const { return mStatus
; }
78 * Set the string to be used for showing this item's current status.
79 * @param v The status string.
81 void setStatus( const QString
&v
);
84 * @return Whether this item can be canceled.
86 bool canBeCanceled() const { return mCanBeCanceled
; }
89 * @return Whether this item uses secure communication
90 * (Account uses ssl, for example.).
92 bool usesCrypto() const { return mUsesCrypto
; }
95 * Set whether this item uses crypted communication, so listeners
96 * can display a nice crypto icon.
99 void setUsesCrypto( bool v
);
102 * @return whether this item uses a busy indicator instead of real progress display
104 bool usesBusyIndicator() const { return mUsesBusyIndicator
; }
107 * Sets whether this item uses a busy indicator instead of real progress for its progress bar.
108 * If it uses a busy indicator, you are still responsible for calling setProgress() from time to
109 * time to update the busy indicator.
111 void setUsesBusyIndicator( bool useBusyIndicator
);
114 * @return The current progress value of this item in percent.
116 unsigned int progress() const { return mProgress
; }
119 * Set the progress (percentage of completion) value of this item.
120 * @param v The percentage value.
122 void setProgress( unsigned int v
);
125 * Tell the item it has finished. This will emit progressItemCompleted()
126 * result in the destruction of the item after all slots connected to this
127 * signal have executed. This is the only way to get rid of an item and
128 * needs to be called even if the item is canceled. Don't use the item
129 * after this has been called on it.
134 * Reset the progress value of this item to 0 and the status string to
140 setStatus( QString() );
146 // Often needed values for calculating progress.
147 void setTotalItems( unsigned int v
) { mTotal
= v
; }
148 unsigned int totalItems() const { return mTotal
; }
149 void setCompletedItems( unsigned int v
) { mCompleted
= v
; }
150 void incCompletedItems( unsigned int v
= 1 ) { mCompleted
+= v
; }
151 unsigned int completedItems() const { return mCompleted
; }
154 * Recalculate progress according to total/completed items and update.
156 void updateProgress()
158 setProgress( mTotal
? mCompleted
* 100 / mTotal
: 0 );
161 void addChild( ProgressItem
*kiddo
);
162 void removeChild( ProgressItem
*kiddo
);
164 bool canceled() const { return mCanceled
; }
168 * Emitted when a new ProgressItem is added.
169 * @param The ProgressItem that was added.
171 void progressItemAdded( KPIM::ProgressItem
* );
174 * Emitted when the progress value of an item changes.
175 * @param The item which got a new value.
176 * @param The value, for convenience.
178 void progressItemProgress( KPIM::ProgressItem
*, unsigned int );
181 * Emitted when a progress item was completed. The item will be
182 * deleted afterwards, so slots connected to this are the last
183 * chance to work with this item.
184 * @param The completed item.
186 void progressItemCompleted( KPIM::ProgressItem
* );
189 * Emitted when an item was canceled. It will _not_ go away immediately,
190 * only when the owner sets it complete, which will usually happen. Can be
191 * used to visually indicate the canceled status of an item. Should be used
192 * by the owner of the item to make sure it is set completed even if it is
193 * canceled. There is a ProgressManager::slotStandardCancelHandler which
194 * simply sets the item completed and can be used if no other work needs to
196 * @param The canceled item;
198 void progressItemCanceled( KPIM::ProgressItem
* );
201 * Emitted when the status message of an item changed. Should be used by
202 * progress dialogs to update the status message for an item.
203 * @param The updated item.
204 * @param The new message.
206 void progressItemStatus( KPIM::ProgressItem
*, const QString
& );
209 * Emitted when the label of an item changed. Should be used by
210 * progress dialogs to update the label of an item.
211 * @param The updated item.
212 * @param The new label.
214 void progressItemLabel( KPIM::ProgressItem
*, const QString
& );
217 * Emitted when the crypto status of an item changed. Should be used by
218 * progress dialogs to update the crypto indicator of an item.
219 * @param The updated item.
220 * @param The new state.
222 void progressItemUsesCrypto( KPIM::ProgressItem
*, bool );
225 * Emitted when the busy indicator state of an item changes. Should be used
226 * by progress dialogs so that they can adjust the display of the progress bar
228 * @param item The updated item
229 * @param value True if the item uses a busy indicator now, false otherwise
231 void progressItemUsesBusyIndicator( KPIM::ProgressItem
*item
, bool value
);
234 /* Only to be used by our good friend the ProgressManager */
235 ProgressItem( ProgressItem
*parent
, const QString
&id
, const QString
&label
,
236 const QString
&status
, bool isCancellable
, bool usesCrypto
);
237 virtual ~ProgressItem();
243 QWeakPointer
<ProgressItem
>mParent
;
245 unsigned int mProgress
;
246 ProgressItemMap mChildren
;
248 unsigned int mCompleted
;
249 bool mWaitingForKids
;
252 bool mUsesBusyIndicator
;
253 bool mCompletedCalled
;
256 struct ProgressManagerPrivate
;
259 * The ProgressManager singleton keeps track of all ongoing transactions
260 * and notifies observers (progress dialogs) when their progress percent value
261 * changes, when they are completed (by their owner), and when they are canceled.
262 * Each ProgressItem emits those signals individually and the singleton
263 * broadcasts them. Use the ::createProgressItem() statics to acquire an item
264 * and then call ->setProgress( int percent ) on it every time you want to
265 * update the item and ->setComplete() when the operation is done. This will
266 * delete the item. Connect to the item's progressItemCanceled() signal to be
267 * notified when the user cancels the transaction using one of the observing
268 * progress dialogs or by calling item->cancel() in some other way. The owner
269 * is responsible for calling setComplete() on the item, even if it is canceled.
270 * Use the standardCancelHandler() slot if that is all you want to do on cancel.
272 * Note that if you request an item with a certain id and there is already
273 * one with that id, there will not be a new one created but the existing
274 * one will be returned. This is convenient for accessing items that are
275 * needed regularly without the to store a pointer to them or to add child
276 * items to parents by id.
278 class KDEPIM_EXPORT ProgressManager
: public QObject
283 friend struct ProgressManagerPrivate
;
286 virtual ~ProgressManager();
289 * @return The singleton instance of this class.
291 static ProgressManager
*instance();
294 * Use this to acquire a unique id number which can be used to discern
295 * an operation from all others going on at the same time. Use that
296 * number as the id string for your progressItem to ensure it is unique.
299 static QString
getUniqueID()
301 return QString::number( ++uID
);
305 * Creates a ProgressItem with a unique id and the given label.
306 * This is the simplest way to acquire a progress item. It will not
307 * have a parent and will be set to be cancellable and not using crypto.
309 static ProgressItem
*createProgressItem( const QString
&label
)
311 return instance()->createProgressItemImpl( 0, getUniqueID(), label
,
312 QString(), true, false );
316 * Creates a new progressItem with the given parent, id, label and initial
319 * @param parent Specify an already existing item as the parent of this one.
320 * @param id Used to identify this operation for cancel and progress info.
321 * @param label The text to be displayed by progress handlers
322 * @param status Additional text to be displayed for the item.
323 * @param canBeCanceled can the user cancel this operation?
324 * @param usesCrypto does the operation use secure transports (SSL)
325 * Cancelling the parent will cancel the children as well (if they can be
326 * canceled) and ongoing children prevent parents from finishing.
327 * @return The ProgressItem representing the operation.
329 static ProgressItem
*createProgressItem( ProgressItem
*parent
,
331 const QString
&label
,
332 const QString
&status
= QString(),
333 bool canBeCanceled
= true,
334 bool usesCrypto
= false )
336 return instance()->createProgressItemImpl( parent
, id
, label
, status
,
337 canBeCanceled
, usesCrypto
);
341 * Use this version if you have the id string of the parent and want to
342 * add a subjob to it.
344 static ProgressItem
*createProgressItem( const QString
&parent
,
346 const QString
&label
,
347 const QString
&status
= QString(),
348 bool canBeCanceled
= true,
349 bool usesCrypto
= false )
351 return instance()->createProgressItemImpl( parent
, id
, label
,
352 status
, canBeCanceled
, usesCrypto
);
356 * Version without a parent.
358 static ProgressItem
*createProgressItem( const QString
&id
,
359 const QString
&label
,
360 const QString
&status
= QString(),
361 bool canBeCanceled
= true,
362 bool usesCrypto
= false )
364 return instance()->createProgressItemImpl( 0, id
, label
, status
,
365 canBeCanceled
, usesCrypto
);
369 * Version for Akonadi agents.
370 * This connects all the proper signals so that you do not have to
371 * worry about updating the progress or reacting to progressItemCanceled().
373 static ProgressItem
*createProgressItem( ProgressItem
*parent
,
374 const Akonadi::AgentInstance
&agent
,
376 const QString
&label
,
377 const QString
&status
= QString(),
378 bool canBeCanceled
= true,
379 bool usesCrypto
= false )
381 return instance()->createProgressItemForAgent( parent
, agent
, id
, label
,
382 status
, canBeCanceled
, usesCrypto
);
386 * @return true when there are no more progress items.
390 return mTransactions
.isEmpty();
394 * @return the only top level progressitem when there's only one.
395 * Returns 0 if there is no item, or more than one top level item.
396 * Since this is used to calculate the overall progress, it will also return
397 * 0 if there is an item which uses a busy indicator, since that will invalidate
398 * the overall progress.
400 ProgressItem
*singleItem() const;
403 * Ask all listeners to show the progress dialog, because there is
404 * something that wants to be shown.
406 static void emitShowProgressDialog()
408 instance()->emitShowProgressDialogImpl();
412 /** @see ProgressItem::progressItemAdded() */
413 void progressItemAdded( KPIM::ProgressItem
* );
414 /** @see ProgressItem::progressItemProgress() */
415 void progressItemProgress( KPIM::ProgressItem
*, unsigned int );
416 /** @see ProgressItem::progressItemCompleted() */
417 void progressItemCompleted( KPIM::ProgressItem
* );
418 /** @see ProgressItem::progressItemCanceled() */
419 void progressItemCanceled( KPIM::ProgressItem
* );
420 /** @see ProgressItem::progressItemStatus() */
421 void progressItemStatus( KPIM::ProgressItem
*, const QString
& );
422 /** @see ProgressItem::progressItemLabel() */
423 void progressItemLabel( KPIM::ProgressItem
*, const QString
& );
424 /** @see ProgressItem::progressItemUsesCrypto() */
425 void progressItemUsesCrypto( KPIM::ProgressItem
*, bool );
426 /** @see ProgressItem::progressItemUsesBusyIndicator */
427 void progressItemUsesBusyIndicator( KPIM::ProgressItem
*, bool );
430 * Emitted when an operation requests the listeners to be shown.
431 * Use emitShowProgressDialog() to trigger it.
433 void showProgressDialog();
438 * Calls setCompleted() on the item, to make sure it goes away.
439 * Provided for convenience.
440 * @param item the canceled item.
442 void slotStandardCancelHandler( KPIM::ProgressItem
*item
);
445 * Aborts all running jobs. Bound to "Esc"
450 void slotTransactionCompleted( KPIM::ProgressItem
*item
);
454 // prevent unsolicited copies
455 ProgressManager( const ProgressManager
& );
457 virtual ProgressItem
*createProgressItemImpl( ProgressItem
*parent
,
459 const QString
&label
,
460 const QString
&status
,
463 virtual ProgressItem
*createProgressItemImpl( const QString
&parent
,
465 const QString
&label
,
466 const QString
&status
,
469 ProgressItem
*createProgressItemForAgent( ProgressItem
*parent
,
470 const Akonadi::AgentInstance
&instance
,
472 const QString
&label
,
473 const QString
&status
,
476 void emitShowProgressDialogImpl();
478 QHash
< QString
, ProgressItem
* > mTransactions
;
479 static unsigned int uID
;
484 #endif // __KPIM_PROGRESSMANAGER_H__