Libkdepim

progressmanager.cpp
1/*
2 progressmanager.cpp
3
4 This file is part of libkdepim.
5
6 SPDX-FileCopyrightText: 2004 Till Adam <adam@kde.org>
7
8 SPDX-License-Identifier: LGPL-2.0-or-later
9*/
10
11#include "progressmanager.h"
12
13#include "libkdepim_debug.h"
14#include <KLocalizedString>
15
16using namespace KPIM;
17unsigned int KPIM::ProgressManager::uID = 42;
18
19ProgressItem::ProgressItem(ProgressItem *parent, const QString &id, const QString &label, const QString &status, bool canBeCanceled, CryptoStatus cryptoStatus)
20 : mId(id)
21 , mLabel(label)
22 , mStatus(status)
23 , mParent(parent)
24 , mCanBeCanceled(canBeCanceled)
25 , mCryptoStatus(cryptoStatus)
26{
27}
28
29ProgressItem::~ProgressItem() = default;
30
32{
33 // qCDebug(LIBKDEPIM_LOG) << label();
34 if (mChildren.isEmpty()) {
35 if (mCompletedCalled) {
36 return;
37 }
38 if (!mCanceled) {
39 setProgress(100);
40 }
41 mCompletedCalled = true;
42 if (parent()) {
43 parent()->removeChild(this);
44 }
46 } else {
47 mWaitingForKids = true;
48 }
49}
50
52{
53 setProgress(0);
55 mCompleted = 0;
56}
57
58void ProgressItem::addChild(ProgressItem *kiddo)
59{
60 mChildren.insert(kiddo, true);
61}
62
63void ProgressItem::removeChild(ProgressItem *kiddo)
64{
65 if (mChildren.isEmpty()) {
66 mWaitingForKids = false;
67 return;
68 }
69
70 if (mChildren.remove(kiddo) == 0) {
71 // do nothing if the specified item is not in the map
72 return;
73 }
74
75 // in case we were waiting for the last kid to go away, now is the time
76 if (mChildren.isEmpty() && mWaitingForKids) {
78 }
79}
80
81bool ProgressItem::canceled() const
82{
83 return mCanceled;
84}
85
86unsigned int ProgressItem::typeProgressItem() const
87{
88 return mType;
89}
90
91void ProgressItem::setTypeProgressItem(unsigned int type)
92{
93 mType = type;
94}
95
96void ProgressItem::cancel()
97{
98 if (mCanceled || !mCanBeCanceled) {
99 return;
100 }
101
102 qCDebug(LIBKDEPIM_LOG) << label();
103 mCanceled = true;
104 // Cancel all children.
105 for (auto it = mChildren.cbegin(), end = mChildren.cend(); it != end; ++it) {
106 ProgressItem *kid = it.key();
107 if (kid->canBeCanceled()) {
108 kid->cancel();
109 }
110 }
111 setStatus(i18n("Aborting…"));
113}
114
116{
117 setProgress(mTotal ? mCompleted * 100 / mTotal : 0);
118}
119
120void ProgressItem::setProgress(unsigned int v)
121{
122 mProgress = v;
123 // qCDebug(LIBKDEPIM_LOG) << label() << " :" << v;
124 Q_EMIT progressItemProgress(this, mProgress);
125}
126
128{
129 return mId;
130}
131
133{
134 return mParent.data();
135}
136
138{
139 return mLabel;
140}
141
143{
144 mLabel = v;
145 Q_EMIT progressItemLabel(this, mLabel);
146}
147
149{
150 return mStatus;
151}
152
154{
155 mStatus = v;
156 Q_EMIT progressItemStatus(this, mStatus);
157}
158
160{
161 return mCanBeCanceled;
162}
163
165{
166 mCanBeCanceled = b;
167}
168
169ProgressItem::CryptoStatus ProgressItem::cryptoStatus() const
170{
171 return mCryptoStatus;
172}
173
174void ProgressItem::setCryptoStatus(ProgressItem::CryptoStatus v)
175{
176 mCryptoStatus = v;
178}
179
181{
182 return mUsesBusyIndicator;
183}
184
185void ProgressItem::setUsesBusyIndicator(bool useBusyIndicator)
186{
187 mUsesBusyIndicator = useBusyIndicator;
188 Q_EMIT progressItemUsesBusyIndicator(this, useBusyIndicator);
189}
190
191unsigned int ProgressItem::progress() const
192{
193 return mProgress;
194}
195
196// ======================================
197
198struct KPIM::ProgressManagerPrivate {
199 ProgressManager instance;
200};
201
202Q_GLOBAL_STATIC(KPIM::ProgressManagerPrivate, progressManagerPrivate)
203
204ProgressManager::ProgressManager()
205 : QObject()
206{
207}
208
209ProgressManager::~ProgressManager() = default;
210
212{
213 return progressManagerPrivate.isDestroyed() ? nullptr : &progressManagerPrivate->instance;
214}
215
220
222{
223 return mTransactions.isEmpty();
224}
225
227ProgressManager::createProgressItem(const QString &id, const QString &label, const QString &status, bool canBeCanceled, ProgressItem::CryptoStatus cryptoStatus)
228{
229 return instance()->createProgressItemImpl(nullptr, id, label, status, canBeCanceled, cryptoStatus);
230}
231
233 const QString &id,
234 const QString &label,
235 const QString &status,
236 bool canBeCanceled,
237 ProgressItem::CryptoStatus cryptoStatus)
238{
239 return instance()->createProgressItemImpl(parent, id, label, status, canBeCanceled, cryptoStatus);
240}
241
243 const QString &id,
244 const QString &label,
245 const QString &status,
246 bool canBeCanceled,
247 ProgressItem::CryptoStatus cryptoStatus)
248{
249 return instance()->createProgressItemImpl(parent, id, label, status, canBeCanceled, cryptoStatus);
250}
251
253{
254 return instance()->createProgressItemImpl(nullptr, getUniqueID(), label, QString(), true, KPIM::ProgressItem::Unencrypted);
255}
256
257ProgressItem *ProgressManager::createProgressItem(unsigned int progressType, const QString &label)
258{
259 return instance()->createProgressItemImpl(nullptr, getUniqueID(), label, QString(), true, KPIM::ProgressItem::Unencrypted, progressType);
260}
261
262ProgressItem *ProgressManager::createProgressItemImpl(ProgressItem *parent,
263 const QString &id,
264 const QString &label,
265 const QString &status,
266 bool cancellable,
267 ProgressItem::CryptoStatus cryptoStatus,
268 unsigned int progressType)
269{
270 ProgressItem *t = nullptr;
271 if (!mTransactions.value(id)) {
272 t = new ProgressItem(parent, id, label, status, cancellable, cryptoStatus);
273 t->setTypeProgressItem(progressType);
274 mTransactions.insert(id, t);
275 if (parent) {
276 ProgressItem *p = mTransactions.value(parent->id());
277 if (p) {
278 p->addChild(t);
279 }
280 }
281 // connect all signals
282 connect(t, &ProgressItem::progressItemCompleted, this, &ProgressManager::slotTransactionCompleted);
290
292 } else {
293 // Hm, is this what makes the most sense?
294 t = mTransactions.value(id);
295 }
296 return t;
297}
298
299ProgressItem *ProgressManager::createProgressItemImpl(const QString &parent,
300 const QString &id,
301 const QString &label,
302 const QString &status,
303 bool canBeCanceled,
304 ProgressItem::CryptoStatus cryptoStatus,
305 unsigned int progressType)
306{
307 ProgressItem *p = mTransactions.value(parent);
308 return createProgressItemImpl(p, id, label, status, canBeCanceled, cryptoStatus, progressType);
309}
310
311void ProgressManager::emitShowProgressDialogImpl()
312{
314}
315
316// slots
317
318void ProgressManager::slotTransactionCompleted(ProgressItem *item)
319{
320 mTransactions.remove(item->id());
322}
323
328
330{
331 ProgressItem *item = nullptr;
332 QHash<QString, ProgressItem *>::const_iterator it = mTransactions.constBegin();
333 QHash<QString, ProgressItem *>::const_iterator end = mTransactions.constEnd();
334 while (it != end) {
335 // No single item for progress possible, as one of them is a busy indicator one.
336 if ((*it)->usesBusyIndicator()) {
337 return nullptr;
338 }
339
340 if (!(*it)->parent()) { // if it's a top level one, only those count
341 if (item) {
342 return nullptr; // we found more than one
343 } else {
344 item = (*it);
345 }
346 }
347 ++it;
348 }
349 return item;
350}
351
353{
354 instance()->emitShowProgressDialogImpl();
355}
356
357ProgressItem *ProgressManager::progressItem(const QString &id) const
358{
359 return mTransactions.value(id);
360}
361
363{
365 while (it.hasNext()) {
366 it.next().value()->cancel();
367 }
368}
369
370void KPIM::ProgressItem::setTotalItems(unsigned int v)
371{
372 mTotal = v;
373}
374
375unsigned int ProgressItem::totalItems() const
376{
377 return mTotal;
378}
379
380void ProgressItem::setCompletedItems(unsigned int v)
381{
382 mCompleted = v;
383}
384
385void ProgressItem::incCompletedItems(unsigned int v)
386{
387 mCompleted += v;
388}
389
390unsigned int ProgressItem::completedItems() const
391{
392 return mCompleted;
393}
394
395#include "moc_progressmanager.cpp"
The ProgressItem class.
void setComplete()
Tell the item it has finished.
CryptoStatus cryptoStatus() const
void progressItemAdded(KPIM::ProgressItem *)
Emitted when a new ProgressItem is added.
void setStatus(const QString &v)
Set the string to be used for showing this item's current status.
void setProgress(unsigned int v)
Set the progress (percentage of completion) value of this item.
bool usesBusyIndicator() const
unsigned int progress() const
void setUsesBusyIndicator(bool useBusyIndicator)
Sets whether this item uses a busy indicator instead of real progress for its progress bar.
void setCanBeCanceled(bool b)
void progressItemCryptoStatus(KPIM::ProgressItem *, KPIM::ProgressItem::CryptoStatus)
Emitted when the crypto status of an item changed.
const QString & label() const
void reset()
Reset the progress value of this item to 0 and the status string to the empty string.
void progressItemLabel(KPIM::ProgressItem *, const QString &)
Emitted when the label of an item changed.
void progressItemCompleted(KPIM::ProgressItem *)
Emitted when a progress item was completed.
const QString & id() const
void setLabel(const QString &v)
void progressItemStatus(KPIM::ProgressItem *, const QString &)
Emitted when the status message of an item changed.
ProgressItem * parent() const
void progressItemUsesBusyIndicator(KPIM::ProgressItem *item, bool value)
Emitted when the busy indicator state of an item changes.
void updateProgress()
Recalculate progress according to total/completed items and update.
void progressItemProgress(KPIM::ProgressItem *, unsigned int)
Emitted when the progress value of an item changes.
void progressItemCanceled(KPIM::ProgressItem *)
Emitted when an item was canceled.
void setCryptoStatus(ProgressItem::CryptoStatus v)
Set whether this item uses encrypted communication, so listeners can display a nice crypto icon.
const QString & status() const
The ProgressManager singleton keeps track of all ongoing transactions and notifies observers (progres...
void progressItemAdded(KPIM::ProgressItem *)
void progressItemCanceled(KPIM::ProgressItem *)
void progressItemLabel(KPIM::ProgressItem *, const QString &)
static ProgressManager * instance()
ProgressItem * singleItem() const
void slotAbortAll()
Aborts all running jobs.
void progressItemUsesBusyIndicator(KPIM::ProgressItem *, bool)
static QString getUniqueID()
Use this to acquire a unique id number which can be used to discern an operation from all others goin...
void progressItemStatus(KPIM::ProgressItem *, const QString &)
void progressItemCryptoStatus(KPIM::ProgressItem *, KPIM::ProgressItem::CryptoStatus)
void progressItemProgress(KPIM::ProgressItem *, unsigned int)
void progressItemCompleted(KPIM::ProgressItem *)
void showProgressDialog()
Emitted when an operation requests the listeners to be shown.
static ProgressItem * createProgressItem(unsigned int progressType, const QString &label)
Creates a ProgressItem with a unique id and the given label.
void slotStandardCancelHandler(KPIM::ProgressItem *item)
Calls setCompleted() on the item, to make sure it goes away.
static void emitShowProgressDialog()
Ask all listeners to show the progress dialog, because there is something that wants to be shown.
Q_SCRIPTABLE CaptureState status()
QString i18n(const char *text, const TYPE &arg...)
Type type(const QSqlDatabase &db)
Class KCheckComboBox::KCheckComboBoxPrivate.
QString label(StandardShortcut id)
bool hasNext() const const
const_iterator cbegin() const const
const_iterator cend() const const
iterator insert(const Key &key, const T &value)
bool isEmpty() const const
size_type remove(const Key &key)
Q_EMITQ_EMIT
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QObject * parent() const const
QString number(double n, char format, int precision)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 18 2024 12:18:17 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.