summaryrefslogtreecommitdiff
path: root/src/frontend/bookshelfmanager/installpage/btinstallprogressdialog.cpp
diff options
context:
space:
mode:
authorRoberto C. Sanchez <roberto@connexer.com>2014-10-21 22:48:19 -0400
committerRoberto C. Sanchez <roberto@connexer.com>2014-10-21 22:48:19 -0400
commit1af3b165c9377702ca62a64112bc089a6f575c30 (patch)
tree4df9cca5543b2cab5ca56dbb1214d7d3b1f291e3 /src/frontend/bookshelfmanager/installpage/btinstallprogressdialog.cpp
parent5b5fd0dce407556f98ed8edee89dc830bf1437b1 (diff)
Imported Upstream version 2.0~beta2
Diffstat (limited to 'src/frontend/bookshelfmanager/installpage/btinstallprogressdialog.cpp')
-rw-r--r--src/frontend/bookshelfmanager/installpage/btinstallprogressdialog.cpp261
1 files changed, 261 insertions, 0 deletions
diff --git a/src/frontend/bookshelfmanager/installpage/btinstallprogressdialog.cpp b/src/frontend/bookshelfmanager/installpage/btinstallprogressdialog.cpp
new file mode 100644
index 0000000..2f60fc9
--- /dev/null
+++ b/src/frontend/bookshelfmanager/installpage/btinstallprogressdialog.cpp
@@ -0,0 +1,261 @@
+/*********
+*
+* This file is part of BibleTime's source code, http://www.bibletime.info/.
+*
+* Copyright 1999-2008 by the BibleTime developers.
+* The BibleTime source code is licensed under the GNU General Public License version 2.0.
+*
+**********/
+
+#include "btinstallprogressdialog.h"
+
+#include "btinstallthread.h"
+
+#include "util/ctoolclass.h"
+#include "util/cpointers.h"
+#include "backend/managers/cswordbackend.h"
+
+#include <QTreeWidget>
+#include <QTreeWidgetItem>
+#include <QDialog>
+#include <QHeaderView>
+#include <QProgressBar>
+#include <QPushButton>
+#include <QVBoxLayout>
+#include <QApplication>
+#include <QCloseEvent>
+#include <QMultiMap>
+
+#include <QDebug>
+
+
+BtInstallProgressDialog::BtInstallProgressDialog(QWidget* parent, QTreeWidget* selectedModulesTreeWidget, QString destination)
+ : QDialog(parent)
+{
+ // we want this dialog to be deleted when user closes it or the downloads are completed
+ setAttribute(Qt::WA_DeleteOnClose, true);
+ setWindowTitle(tr("Install Progress"));
+ //create the dialog which shows the status and lets the user stop installation
+ m_statusWidget = new QTreeWidget();
+ m_statusWidget->setRootIsDecorated(false);
+ m_statusWidget->setHeaderLabels(QStringList(tr("Work")) << tr("Progress") << QString::null);
+ m_statusWidget->header()->setStretchLastSection(false);
+ m_statusWidget->header()->setResizeMode(1, QHeaderView::Stretch);
+ m_statusWidget->header()->setMovable(false);
+ //m_statusWidget->setColumnWidth(1, CToolClass::mWidth(m_statusWidget, 2));
+
+ foreach (QTreeWidgetItem* sourceItem, selectedModulesTreeWidget->invisibleRootItem()->takeChildren()) {
+ // create items and threads for modules under this source
+ foreach (QTreeWidgetItem* moduleItem, sourceItem->takeChildren()) {
+ if (moduleItem->checkState(0) == Qt::Checked) {
+ // create a thread for this module
+ BtInstallThread* thread = new BtInstallThread(this, moduleItem->text(0), sourceItem->text(0), destination);
+ m_waitingThreads.insert(sourceItem->text(0), thread);
+ m_threadsByModule.insert(moduleItem->text(0), thread);
+ // progress widget/item
+ QPushButton* stopButton = new QPushButton(tr("Stop"), m_statusWidget);
+ stopButton->setFixedSize(stopButton->sizeHint());
+
+ // the item
+ QTreeWidgetItem* progressItem = new QTreeWidgetItem(m_statusWidget);
+ m_statusWidget->setColumnWidth(2, stopButton->sizeHint().width());
+ progressItem->setSizeHint(2, stopButton->sizeHint());
+ progressItem->setText(0, moduleItem->text(0));
+ progressItem->setFlags(Qt::ItemIsEnabled);
+ m_statusWidget->setItemWidget(progressItem, 2, stopButton);
+ progressItem->setText(1, tr("Waiting for turn..."));
+
+ //connect the signals between the dialog, items and threads
+ QObject::connect(stopButton, SIGNAL(clicked()), thread, SLOT(slotStopInstall()), Qt::QueuedConnection);
+ QObject::connect(thread, SIGNAL(installStopped(QString, QString)), this, SLOT(slotOneItemStopped(QString, QString)), Qt::QueuedConnection);
+ //is this needed or is statusUpdated enough?
+ QObject::connect(thread, SIGNAL(installCompleted(QString, QString, int)), this, SLOT(slotOneItemCompleted(QString, QString, int)), Qt::QueuedConnection);
+ QObject::connect(thread, SIGNAL(statusUpdated(QString, int)), this, SLOT(slotStatusUpdated(QString, int)), Qt::QueuedConnection);
+ QObject::connect(thread, SIGNAL(downloadStarted(QString)), this, SLOT(slotDownloadStarted(QString)), Qt::QueuedConnection);
+
+ QObject::connect(thread, SIGNAL(preparingInstall(QString, QString)), this, SLOT(slotInstallStarted(QString, QString)), Qt::QueuedConnection);
+
+ }
+ }
+ }
+
+ m_statusWidget->setMinimumWidth(m_statusWidget->size().width());
+ QPushButton* stopAllButton = new QPushButton(tr("Stop All"), this);
+
+ QVBoxLayout* layout = new QVBoxLayout(this);
+ layout->addWidget(m_statusWidget);
+ layout->addWidget(stopAllButton);
+
+ connect(stopAllButton, SIGNAL(clicked()), SLOT(slotStopInstall()) );
+
+ qApp->processEvents();
+
+ startThreads();
+
+}
+
+void BtInstallProgressDialog::startThreads()
+{
+ // remove all the updated modules from the backend module list at once
+ //foreach (QString mName, m_threadsByModule.keys()) {
+ //}
+ //QList<CSwordModuleInfo*> CPointers::backend()->takeModulesFromList(m_threadsByModule.keys());
+ qDebug() << "start threads...";
+ //loop through the multimap of the waiting threads, start at most 3 threads for each source
+ QMultiMap<QString, BtInstallThread*>::iterator threadIterator = m_waitingThreads.end();
+// concurrency is disabled for now
+// while (threadIterator != m_waitingThreads.end()) {
+// QString sourceName = threadIterator.key();
+// qDebug() << sourceName;
+// if (m_runningThreads.values(sourceName).count() < 3) {
+// BtInstallThread* t = threadIterator.value();
+// m_runningThreads.insert(sourceName, t);
+// threadIterator = m_waitingThreads.erase(threadIterator);
+// t->start();
+// }
+// else ++threadIterator;
+// }
+ //non-concurrent
+ if (threadIterator != m_waitingThreads.begin()) {
+ // go to the last item which is actually the first in the visible list
+ // because the iterator is reversed compared to insert order
+ threadIterator--;
+ QString sourceName = threadIterator.key();
+ BtInstallThread* t = threadIterator.value();
+ m_runningThreads.insert(sourceName, t);
+ threadIterator = m_waitingThreads.erase(threadIterator);
+ t->start();
+ }
+
+ qDebug("BtInstallProgressDialog::startThreads end");
+}
+
+BtInstallProgressDialog::~BtInstallProgressDialog()
+{}
+
+
+void BtInstallProgressDialog::slotOneItemCompleted(QString module, QString source, int status)
+{
+ QString message;
+ //status comes from the sword installer. TODO: Additionally we should check that there are files really installed.
+ if (status != 0) {
+ message = tr("Failed");
+ }
+ else {
+ message = tr("Completed");
+ }
+ oneItemStoppedOrCompleted(module, source, message);
+}
+
+void BtInstallProgressDialog::slotOneItemStopped(QString module, QString source)
+{
+ oneItemStoppedOrCompleted(module, source, tr("Cancelled"));
+}
+
+void BtInstallProgressDialog::oneItemStoppedOrCompleted(QString module, QString source, QString statusMessage)
+{
+ qDebug() << "\n**********************************\nBtInstallProgressDialog::oneItemStoppedOrCompleted" << module << statusMessage << "\n******************************************";
+ // update the list item
+ m_statusWidget->setItemWidget(getItem(module), 1, 0);
+ getItem(module)->setText(1, statusMessage);
+ m_statusWidget->itemWidget(getItem(module), 2)->setEnabled(false);
+ getItem(module)->setDisabled(true);
+
+ qDebug() << "remove from threads maps" << source << m_threadsByModule.value(module);
+ m_runningThreads.remove(source, m_threadsByModule.value(module));
+ m_waitingThreads.remove(source, m_threadsByModule.value(module));
+
+//concurrency is disabled for now
+// //start a waiting thread if there are any
+// QList<BtInstallThread*> threadsForSource = m_waitingThreads.values(source);
+// qDebug() << threadsForSource;
+// if (!threadsForSource.isEmpty()) {
+// qDebug() << "Threads are waiting for turn";
+// BtInstallThread* thread = threadsForSource.at(0);
+// m_waitingThreads.remove(source, thread);
+// m_runningThreads.insert(source, thread);
+// thread->start();
+// }
+
+ //non-concurrent
+ QMultiMap<QString, BtInstallThread*>::iterator threadIterator = m_waitingThreads.end();
+ if (m_runningThreads.size() == 0 && threadIterator != m_waitingThreads.begin()) {
+ threadIterator--; // the last item
+ QString sourceName = threadIterator.key();
+ BtInstallThread* t = threadIterator.value();
+ m_runningThreads.insert(sourceName, t);
+ threadIterator = m_waitingThreads.erase(threadIterator);
+ t->start();
+ }
+
+ if (threadsDone()) {
+ qDebug() << "close the dialog";
+ close();
+ }
+}
+
+void BtInstallProgressDialog::slotStopInstall()
+{
+ qDebug("BtInstallProgressDialog::slotStopInstall");
+
+ // Clear the waiting threads map, stop all running threads.
+
+ m_waitingThreads.clear();
+ if (m_runningThreads.count() > 0) {
+ foreach(BtInstallThread* thread, m_runningThreads) {
+ thread->slotStopInstall();
+ }
+ } else {
+ close();
+ }
+}
+
+void BtInstallProgressDialog::slotStatusUpdated(QString module, int status)
+{
+ //qDebug("BtInstallProgressDialog::slotStatusUpdated");
+ //qDebug() << "module:" << module << "status:" << status;
+ // find the progress bar for this module and update the value
+ QWidget* itemWidget = m_statusWidget->itemWidget(getItem(module) , 1);
+ QProgressBar* bar = dynamic_cast<QProgressBar*>(itemWidget);
+ if (bar) bar->setValue(status);
+}
+
+void BtInstallProgressDialog::slotInstallStarted(QString module, QString)
+{
+ getItem(module)->setText(1, tr("Preparing install..."));
+}
+
+void BtInstallProgressDialog::slotDownloadStarted(QString module)
+{
+ qDebug() << "BtInstallProgressDialog::slotDownloadStarted" << module;
+ getItem(module)->setText(1, QString::null);
+ //m_statusWidget->itemWidget(getItem(module), 1)->setVisible(true);
+
+ QProgressBar* bar = new QProgressBar(m_statusWidget);
+ bar->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed);
+ bar->setValue(0);
+ m_statusWidget->setItemWidget(getItem(module), 1, bar);
+}
+
+QTreeWidgetItem* BtInstallProgressDialog::getItem(QString moduleName)
+{
+ //qDebug() << "BtInstallProgressDialog::getItem" << moduleName;
+ return m_statusWidget->findItems(moduleName, Qt::MatchExactly).at(0);
+}
+
+void BtInstallProgressDialog::closeEvent(QCloseEvent* event)
+{
+ qDebug("BtInstallProgressDialog::closeEvent");
+
+ if (event->spontaneous()) {
+ event->ignore();
+ return;
+ }
+ // other parts of the UI/engine must be updated
+ CPointers::backend()->reloadModules(CSwordBackend::AddedModules);
+}
+
+bool BtInstallProgressDialog::threadsDone()
+{
+ return (m_waitingThreads.count() == 0 && m_runningThreads.count() == 0);
+}