diff options
Diffstat (limited to 'src/progressmanager.cpp')
-rw-r--r-- | src/progressmanager.cpp | 183 |
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 + email : [email protected] + ***************************************************************************/ + +/*************************************************************************** + * * + * 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" |