summaryrefslogtreecommitdiffstats
path: root/src/progressmanager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/progressmanager.cpp')
-rw-r--r--src/progressmanager.cpp183
1 files changed, 183 insertions, 0 deletions
diff --git a/src/progressmanager.cpp b/src/progressmanager.cpp
new file mode 100644
index 0000000..a487710
--- /dev/null
+++ b/src/progressmanager.cpp
@@ -0,0 +1,183 @@
+/***************************************************************************
+ copyright : (C) 2005-2006 by Robby Stephenson
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License as *
+ * published by the Free Software Foundation; *
+ * *
+ ***************************************************************************/
+
+#include "progressmanager.h"
+#include "tellico_debug.h"
+
+#include <qtimer.h>
+
+using Tellico::ProgressItem;
+using Tellico::ProgressManager;
+ProgressManager* ProgressManager::s_self = 0;
+
+ProgressItem::Done::~Done() {
+ ProgressManager::self()->setDone(m_object);
+}
+
+ProgressItem::ProgressItem(const QString& label_, bool canCancel_)
+ : m_label(label_)
+ , m_canCancel(canCancel_)
+ , m_progress(0)
+ , m_total(0)
+ , m_cancelled(false) {
+}
+
+ProgressItem::~ProgressItem() {
+// myDebug() << "~ProgressItem() - " << m_label << endl;
+}
+
+void ProgressItem::setProgress(uint steps_) {
+ m_progress = steps_;
+ emit signalProgress(this);
+
+ if(m_progress >= m_total) {
+ setDone();
+ }
+}
+
+void ProgressItem::setTotalSteps(uint steps_) {
+ m_total = steps_;
+ emit signalTotalSteps(this);
+}
+
+void ProgressItem::setDone() {
+ if(!m_cancelled) {
+ m_progress = m_total;
+ }
+ emit signalDone(this);
+ // make sure the deleting doesn't interfere with anything
+ QTimer::singleShot(3000, this, SLOT(deleteLater()));
+}
+
+void ProgressItem::cancel() {
+// myDebug() << "ProgressItem::cancel()" << endl;
+ if(!m_canCancel || m_cancelled) {
+ return;
+ }
+
+ m_cancelled = true;
+ emit signalCancelled(this);
+}
+
+ProgressManager::ProgressManager() : QObject() {
+}
+
+void ProgressManager::setProgress(const QObject* owner_, uint steps_) {
+ if(!m_items.contains(owner_)) {
+ return;
+ }
+
+ m_items[owner_] ->setProgress(steps_);
+// slotUpdateTotalProgress(); // called in ProgressItem::setProgress()
+// emit signalItemProgress(m_items[owner_]);
+}
+
+void ProgressManager::setTotalSteps(const QObject* owner_, uint steps_) {
+ if(!m_items.contains(owner_)) {
+ return;
+ }
+
+ m_items[owner_]->setTotalSteps(steps_);
+// updateTotalProgress(); // called in ProgressItem::setTotalSteps()
+}
+
+void ProgressManager::setDone(const QObject* owner_) {
+ if(!m_items.contains(owner_)) {
+ return;
+ }
+ setDone(m_items[owner_]);
+}
+
+void ProgressManager::setDone(ProgressItem* item_) {
+ if(!item_) {
+ myDebug() << "ProgressManager::setDone() - null ProgressItem!" << endl;
+ return;
+ }
+ item_->setDone();
+// updateTotalProgress();
+}
+
+void ProgressManager::slotItemDone(ProgressItem* item_) {
+// cancel ends up removing it from the map, so make a copy
+ ProgressMap map = m_items;
+ for(ProgressMap::Iterator it = map.begin(); it != map.end(); ++it) {
+ if(static_cast<ProgressItem*>(it.data()) == item_) {
+ m_items.remove(it.key());
+ break;
+ }
+ }
+ slotUpdateTotalProgress();
+// emit signalItemDone(item_);
+}
+
+ProgressItem& ProgressManager::newProgressItemImpl(const QObject* owner_,
+ const QString& label_,
+ bool canCancel_) {
+// myDebug() << "ProgressManager::newProgressItem() - " << owner_->className() << ":" << label_ << endl;
+ if(m_items.contains(owner_)) {
+ return *m_items[owner_];
+ }
+
+ ProgressItem* item = new ProgressItem(label_, canCancel_);
+ m_items.insert(owner_, item);
+
+ connect(item, SIGNAL(signalTotalSteps(ProgressItem*)), SLOT(slotUpdateTotalProgress()));
+ connect(item, SIGNAL(signalProgress(ProgressItem*)), SLOT(slotUpdateTotalProgress()));
+ connect(item, SIGNAL(signalDone(ProgressItem*)), SLOT(slotUpdateTotalProgress()));
+ connect(item, SIGNAL(signalDone(ProgressItem*)), SLOT(slotItemDone(ProgressItem*)));
+
+// connect(item, SIGNAL(signalProgress(ProgressItem*)), SIGNAL(signalItemProgress(ProgressItem*)));
+// emit signalItemAdded(item);
+ return *item;
+}
+
+void ProgressManager::slotUpdateTotalProgress() {
+ uint progress = 0;
+ uint total = 0;
+
+ for(ProgressMap::ConstIterator it = m_items.begin(); it != m_items.end(); ++it) {
+ if(it.data()) {
+ progress += (*it)->progress();
+ total += (*it)->totalSteps();
+ }
+ }
+
+ if(total == 0) {
+ emit signalTotalProgress(100);
+ return;
+ }
+
+ emit signalTotalProgress(100*progress/total);
+}
+
+void ProgressManager::slotCancelAll() {
+// cancel ends up removing it from the map, so make a copy
+ ProgressMap map = m_items;
+ for(ProgressMap::ConstIterator it = map.begin(), end = map.end(); it != end; ++it) {
+ if(it.data()) {
+ it.data()->cancel();
+ setDone(it.data());
+ }
+ }
+}
+
+bool ProgressManager::anyCanBeCancelled() const {
+ for(ProgressMap::ConstIterator it = m_items.begin(), end = m_items.end(); it != end; ++it) {
+ if(it.data() && it.data()->canCancel()) {
+ return true;
+ }
+ }
+ return false;
+}
+
+#include "progressmanager.moc"