diff options
Diffstat (limited to 'src/mobile/bookshelfmanager')
-rw-r--r-- | src/mobile/bookshelfmanager/installmanager.cpp | 371 | ||||
-rw-r--r-- | src/mobile/bookshelfmanager/installmanager.h | 82 | ||||
-rw-r--r-- | src/mobile/bookshelfmanager/installprogress.cpp | 199 | ||||
-rw-r--r-- | src/mobile/bookshelfmanager/installprogress.h | 61 | ||||
-rw-r--r-- | src/mobile/bookshelfmanager/installsources.cpp | 75 | ||||
-rw-r--r-- | src/mobile/bookshelfmanager/installsources.h | 52 | ||||
-rw-r--r-- | src/mobile/bookshelfmanager/installsourcesmanager.cpp | 85 | ||||
-rw-r--r-- | src/mobile/bookshelfmanager/installsourcesmanager.h | 45 |
8 files changed, 970 insertions, 0 deletions
diff --git a/src/mobile/bookshelfmanager/installmanager.cpp b/src/mobile/bookshelfmanager/installmanager.cpp new file mode 100644 index 0000000..99a72a0 --- /dev/null +++ b/src/mobile/bookshelfmanager/installmanager.cpp @@ -0,0 +1,371 @@ +/********* +* +* In the name of the Father, and of the Son, and of the Holy Spirit. +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2014 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +#include "installmanager.h" + +#include "backend/btinstallbackend.h" +#include "backend/managers/clanguagemgr.h" +#include "backend/btinstallmgr.h" +#include "mobile/btmmain.h" +#include "mobile/ui/qtquick2applicationviewer.h" +#include "mobile/ui/viewmanager.h" +#include <QDebug> +#include <QQuickItem> +#include <QtAlgorithms> + +namespace btm { + +enum TextRoles { + TextRole = Qt::UserRole + 1 +}; + +enum WorksRoles { + TitleRole = Qt::UserRole + 1, + DescriptionRole = Qt::UserRole + 2, + InstalledRole = Qt::UserRole + 3 +}; + +static bool moduleInstalled(const CSwordModuleInfo& moduleInfo) { + const CSwordModuleInfo *installedModule = CSwordBackend::instance()->findModuleByName(moduleInfo.name()); + return installedModule != 0; +} + +static void setupTextModel(const QStringList& modelList, RoleItemModel* model) { + QHash<int, QByteArray> roleNames; + roleNames[TextRole] = "modelText"; + model->setRoleNames(roleNames); + + model->clear(); + for (int i=0; i< modelList.count(); ++i) { + QString source = modelList.at(i); + QStandardItem* item = new QStandardItem(); + item->setData(source, TextRole); + model->appendRow(item); + } +} + +static void setupWorksModel(const QStringList& titleList, + const QStringList& descriptionList, + const QList<int>& installedList, + RoleItemModel* model) { + Q_ASSERT(titleList.count() == descriptionList.count()); + Q_ASSERT(titleList.count() == installedList.count()); + + QHash<int, QByteArray> roleNames; + roleNames[TitleRole] = "title"; + roleNames[DescriptionRole] = "desc"; + roleNames[InstalledRole] = "installed"; + model->setRoleNames(roleNames); + + model->clear(); + for (int i=0; i< titleList.count(); ++i) { + QStandardItem* item = new QStandardItem(); + QString title = titleList.at(i); + item->setData(title, TitleRole); + QString description = descriptionList.at(i); + item->setData(description, DescriptionRole); + int installed = installedList.at(i); + item->setData(installed, InstalledRole); + model->appendRow(item); + } +} + +InstallManager::InstallManager(QObject* /* parent */) + : m_installManagerChooserObject(0), + m_btInstallMgr(0) { +} + +void InstallManager::openChooser() { + + if (m_installManagerChooserObject == 0) + findInstallManagerObject(); + if (m_installManagerChooserObject == 0) + return; + + setupSourceModel(); + makeConnections(); + setProperties(); + sourceIndexChanged(0); +} + +void InstallManager::findInstallManagerObject() { + + QtQuick2ApplicationViewer* viewer = getViewManager()->getViewer(); + QQuickItem * rootObject = 0; + if (viewer != 0) + rootObject = viewer->rootObject(); + if (rootObject != 0) + m_installManagerChooserObject = rootObject->findChild<QQuickItem*>("installManagerChooser"); +} + +void InstallManager::findProgressObject() { + QtQuick2ApplicationViewer* viewer = getViewManager()->getViewer(); + QQuickItem * rootObject = 0; + if (viewer != 0) + rootObject = viewer->rootObject(); + if (rootObject != 0) + m_progressObject = rootObject->findChild<QQuickItem*>("progress"); +} + + +void InstallManager::setupSourceModel() { + m_sourceList = BtInstallBackend::sourceNameList(); + setupTextModel(m_sourceList, &m_sourceModel); +} + +void InstallManager::makeConnections() +{ + m_installManagerChooserObject->disconnect(); + + bool ok = connect(m_installManagerChooserObject, SIGNAL(sourceChanged(int)), + this, SLOT(sourceIndexChanged(int))); + Q_ASSERT(ok); + + ok = connect(m_installManagerChooserObject, SIGNAL(categoryChanged(int)), + this, SLOT(categoryIndexChanged(int))); + Q_ASSERT(ok); + + ok = connect(m_installManagerChooserObject, SIGNAL(languageChanged(int)), + this, SLOT(languageIndexChanged(int))); + Q_ASSERT(ok); + + ok = connect(m_installManagerChooserObject, SIGNAL(workSelected(int)), + this, SLOT(workSelected(int))); + Q_ASSERT(ok); + + ok = connect(m_installManagerChooserObject, SIGNAL(cancel()), + this, SLOT(cancel())); + Q_ASSERT(ok); + + ok = connect(m_installManagerChooserObject, SIGNAL(installRemove()), + this, SLOT(installRemove())); + Q_ASSERT(ok); + + ok = connect(m_installManagerChooserObject, SIGNAL(refreshLists()), + this, SLOT(refreshLists())); + Q_ASSERT(ok); +} + +void InstallManager::setProperties() { + m_installManagerChooserObject->setProperty("sourceModel", QVariant::fromValue(&m_sourceModel)); + m_installManagerChooserObject->setProperty("categoryModel", QVariant::fromValue(&m_categoryModel)); + m_installManagerChooserObject->setProperty("languageModel", QVariant::fromValue(&m_languageModel)); + m_installManagerChooserObject->setProperty("worksModel", QVariant::fromValue(&m_worksModel)); + m_installManagerChooserObject->setProperty("sourceIndex", 0); + m_installManagerChooserObject->setProperty("visible", true); +} + +void InstallManager::sourceIndexChanged(int index) +{ + if (index < 0 || index >= m_sourceList.count()) + return; + + updateCategoryAndLanguageModels(); + updateWorksModel(); +} + +void InstallManager::categoryIndexChanged(int index) +{ + if (index < 0 || index >= m_categoryList.count()) + return; + updateWorksModel(); +} + +void InstallManager::languageIndexChanged(int index) +{ + if (index < 0 || index >= m_languageList.count()) + return; + updateWorksModel(); +} + +void InstallManager::workSelected(int index) { + QStandardItem* item = m_worksModel.item(index,0); + QVariant vInstalled = item->data(InstalledRole); + int installed = vInstalled.toInt(); + installed = installed == 0 ? 1 : 0; + item->setData(installed, InstalledRole); + + CSwordModuleInfo* moduleInfo = m_worksList.at(index); + m_modulesToInstallRemove[moduleInfo] = installed == 1; +} + +void InstallManager::cancel() { + m_installManagerChooserObject->setProperty("visible", false); +} + +void InstallManager::installRemove() { + m_installManagerChooserObject->setProperty("visible", false); + + QList<CSwordModuleInfo*> modulesToRemove; + QList<CSwordModuleInfo*> modulesToInstall; + QMap<CSwordModuleInfo*, bool>::const_iterator it; + for(it=m_modulesToInstallRemove.constBegin(); + it!=m_modulesToInstallRemove.constEnd(); + ++it) { + CSwordModuleInfo* moduleInfo = it.key(); + bool install = it.value(); + QString name = moduleInfo->name(); + if (moduleInstalled(*moduleInfo) && install == false) { + modulesToRemove.append(moduleInfo); + } + else if ( ! moduleInstalled(*moduleInfo) && install == true) { + modulesToInstall.append(moduleInfo); + } + } + removeModules(modulesToRemove); + installModules(modulesToInstall); +} + +void InstallManager::updateCategoryAndLanguageModels() +{ + QString sourceName = getCurrentListItem("sourceIndex", m_sourceList); + sword::InstallSource source = BtInstallBackend::source(sourceName); + CSwordBackend* backend = BtInstallBackend::backend(source); + const QList<CSwordModuleInfo*> modules = backend->moduleList(); + + QSet<QString> categories; + QSet<QString> languages; + for (int moduleIndex=0; moduleIndex<modules.count(); ++moduleIndex) { + CSwordModuleInfo* module = modules.at(moduleIndex); + CSwordModuleInfo::Category category = module->category(); + // QString name = module->name(); + QString categoryName = module->categoryName(category); + const CLanguageMgr::Language* language = module->language(); + QString languageName = language->englishName(); + categories.insert(categoryName); + languages.insert(languageName); + } + + QString currentCategory = getCurrentListItem("categoryIndex", m_categoryList); + m_categoryList = categories.toList(); + m_categoryList.sort(); + setupTextModel(m_categoryList, &m_categoryModel); + setCurrentListItem("categoryIndex", m_categoryList, currentCategory); + + QString currentLanguage = getCurrentListItem("languageIndex", m_languageList); + m_languageList = languages.toList(); + m_languageList.sort(); + setupTextModel(m_languageList, &m_languageModel); + setCurrentListItem("languageIndex", m_languageList, currentLanguage); +} + +QString InstallManager::getCurrentListItem(const char* propertyName, const QStringList& list) { + QString value; + QVariant vIndex = m_installManagerChooserObject->property(propertyName); + bool ok; + int index = vIndex.toInt(&ok); + if (ok) { + if (index >= 0 && index < list.count()) + value = list.at(index); + } + return value; +} + +void InstallManager::setCurrentListItem(const char* propertyName, + const QStringList& list, + const QString& itemName) { + int index = list.indexOf(itemName); + if (index < 0) + index = 0; + m_installManagerChooserObject->setProperty(propertyName, index); +} + +void InstallManager::updateWorksModel() +{ + QString sourceName = getCurrentListItem("sourceIndex", m_sourceList); + QString categoryName = getCurrentListItem("categoryIndex", m_categoryList); + QString languageName = getCurrentListItem("languageIndex", m_languageList); + + sword::InstallSource source = BtInstallBackend::source(sourceName); + CSwordBackend* backend = BtInstallBackend::backend(source); + const QList<CSwordModuleInfo*> modules = backend->moduleList(); + + m_worksTitleList.clear(); + m_worksDescList.clear(); + m_worksList.clear(); + m_worksInstalledList.clear(); + for (int moduleIndex=0; moduleIndex<modules.count(); ++moduleIndex) { + CSwordModuleInfo* module = modules.at(moduleIndex); + module->setProperty("installSourceName", sourceName); + CSwordModuleInfo::Category category = module->category(); + QString moduleCategoryName = module->categoryName(category); + const CLanguageMgr::Language* language = module->language(); + QString moduleLanguageName = language->englishName(); + if (moduleCategoryName == categoryName && + moduleLanguageName == languageName ) { + QString name = module->name(); + QString description = module->config(CSwordModuleInfo::Description); + QString version = module->config(CSwordModuleInfo::ModuleVersion); + QString info = description + ": " + version;\ + int installed = moduleInstalled(*module) ? 1 : 0; + m_worksTitleList.append(name); + m_worksDescList.append(info); + m_worksList.append(module); + m_worksInstalledList.append(installed); + } + } + setupWorksModel(m_worksTitleList, m_worksDescList, m_worksInstalledList, &m_worksModel); +} + +void InstallManager::removeModules(const QList<CSwordModuleInfo*>& modules) { + + QStringList moduleNames; + foreach ( CSwordModuleInfo* mInfo, modules ) { + QString moduleName = mInfo->name(); + moduleNames.append(moduleName); + } + // Update the module list before really removing. Remember deleting the pointers later. + QList<CSwordModuleInfo*> toBeDeleted = CSwordBackend::instance()->takeModulesFromList(moduleNames); + + sword::InstallMgr installMgr; + QMap<QString, sword::SWMgr*> mgrDict; //maps config paths to SWMgr objects + foreach ( CSwordModuleInfo* mInfo, toBeDeleted ) { + Q_ASSERT(mInfo); // Only installed modules could have been selected and returned by takeModulesFromList + // Find the install path for the sword manager + QString prefixPath = mInfo->config(CSwordModuleInfo::AbsoluteDataPath) + "/"; + QString dataPath = mInfo->config(CSwordModuleInfo::DataPath); + if (dataPath.left(2) == "./") { + dataPath = dataPath.mid(2); + } + if (prefixPath.contains(dataPath)) { //remove module part to get the prefix path + prefixPath = prefixPath.remove( prefixPath.indexOf(dataPath), dataPath.length() ); + } + else { //This is an error, should not happen + qWarning() << "Removing" << mInfo->name() << "didn't succeed because the absolute path" << prefixPath << "didn't contain the data path" << dataPath; + continue; // don't remove this, go to next of the for loop + } + + // Create the sword manager and remove the module + sword::SWMgr* mgr = mgrDict[ prefixPath ]; + if (!mgr) { //create new mgr if it's not yet available + mgrDict.insert(prefixPath, new sword::SWMgr(prefixPath.toLocal8Bit())); + mgr = mgrDict[ prefixPath ]; + } + qDebug() << "Removing the module" << mInfo->name() << "..."; + installMgr.removeModule(mgr, mInfo->module()->getName()); + } + //delete the removed moduleinfo pointers + qDeleteAll(modules); + //delete all mgrs which were created above + qDeleteAll(mgrDict); + mgrDict.clear(); +} + +void InstallManager::installModules(const QList<CSwordModuleInfo*>& modules) { + m_installProgress.openProgress(modules); +} + +void InstallManager::refreshLists() { + m_installSourcesManager.refreshSources(); +} + +} // end namespace diff --git a/src/mobile/bookshelfmanager/installmanager.h b/src/mobile/bookshelfmanager/installmanager.h new file mode 100644 index 0000000..a976ad8 --- /dev/null +++ b/src/mobile/bookshelfmanager/installmanager.h @@ -0,0 +1,82 @@ +/********* +* +* In the name of the Father, and of the Son, and of the Holy Spirit. +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2014 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +#ifndef INSTALL_MODULE_CHOOSER_H +#define INSTALL_MODULE_CHOOSER_H + +#include "installsourcesmanager.h" +#include "mobile/models/roleitemmodel.h" +#include "installprogress.h" +#include <QMap> +#include <QObject> + +class QQuickItem; +class CSwordModuleInfo; +class BtInstallMgr; + +namespace btm { + +class InstallManager :public QObject { + Q_OBJECT + +public: + InstallManager(QObject* parent = 0); + + Q_INVOKABLE void openChooser(); + +private slots: + void cancel(); + void categoryIndexChanged(int index); + void installRemove(); + void languageIndexChanged(int index); + void refreshLists(); + void sourceIndexChanged(int index); + void workSelected(int index); + +private: + QString getCurrentListItem(const char* propertyName, + const QStringList& list); + void findInstallManagerObject(); + void findProgressObject(); + void installModules(const QList<CSwordModuleInfo*>& modules); + void makeConnections(); + void removeModules(const QList<CSwordModuleInfo*>& modules); + void setProperties(); + void setupSourceModel(); + void setCurrentListItem(const char* propertyName, + const QStringList& list, + const QString& itemName); + void updateCategoryAndLanguageModels(); + void updateWorksModel(); + + QQuickItem* m_installManagerChooserObject; + QQuickItem* m_progressObject; + BtInstallMgr* m_btInstallMgr; + InstallSourcesManager m_installSourcesManager; + + InstallProgress m_installProgress; + QStringList m_sourceList; + QStringList m_categoryList; + QStringList m_languageList; + QStringList m_worksTitleList; + QStringList m_worksDescList; + QList<CSwordModuleInfo*> m_worksList; + QList<int> m_worksInstalledList; + QMap<CSwordModuleInfo*, bool> m_modulesToInstallRemove; + RoleItemModel m_sourceModel; + RoleItemModel m_categoryModel; + RoleItemModel m_languageModel; + RoleItemModel m_worksModel; +}; + +} // end namespace +#endif diff --git a/src/mobile/bookshelfmanager/installprogress.cpp b/src/mobile/bookshelfmanager/installprogress.cpp new file mode 100644 index 0000000..dd113ec --- /dev/null +++ b/src/mobile/bookshelfmanager/installprogress.cpp @@ -0,0 +1,199 @@ +/********* +* +* In the name of the Father, and of the Son, and of the Holy Spirit. +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2014 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +#include "installprogress.h" + +#include "backend/btinstallbackend.h" +#include "backend/managers/cswordbackend.h" +#include "backend/btinstallthread.h" +#include "mobile/btmmain.h" +#include "mobile/ui/qtquick2applicationviewer.h" +#include "mobile/ui/viewmanager.h" +#include <QQuickItem> +#include <QDebug> + +namespace btm { + +InstallProgress::InstallProgress(QObject* parent) + : QObject(parent), m_progressObject(0) { +} + +void InstallProgress::openProgress(const QList<CSwordModuleInfo*>& modules) { + if (modules.count() == 0) + return; + + if (m_progressObject == 0) + findProgressObject(); + if (m_progressObject == 0) + return; + + QString destination = getSourcePath(); + if (destination.isEmpty()) + return; + + setProperties(); + + Q_FOREACH(const CSwordModuleInfo *module, modules) { + const QString sourceName(module->property("installSourceName").toString()); + // create a thread for this module + BtInstallThread* thread = new BtInstallThread(module->name(), sourceName, destination); + m_waitingThreads.insert(sourceName, thread); + m_threadsByModule.insert(module->name(), thread); + + QObject::connect(thread, SIGNAL(installStopped(QString, QString)), + this, SLOT(slotOneItemStopped(QString, QString)), Qt::QueuedConnection); + 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); + } + + connect(m_progressObject, SIGNAL(cancel()), this, SLOT(slotStopInstall())); + startThreads(); +} + +void InstallProgress::cancel() { + m_progressObject->setProperty("visible", false); +} + +void InstallProgress::close() { + m_progressObject->setProperty("visible", false); + CSwordBackend::instance()->reloadModules(CSwordBackend::AddedModules); +} + +void InstallProgress::slotOneItemCompleted(QString module, QString source, int status) { + QString message; + //status comes from the sword installer. + if (status != 0) { + message = tr("Failed"); + } + else { + message = tr("Completed"); + } + oneItemStoppedOrCompleted(module, source, message); +} + +void InstallProgress::slotOneItemStopped(QString module, QString source) { + oneItemStoppedOrCompleted(module, source, tr("Cancelled")); +} + +// TODO show failed status +void InstallProgress::oneItemStoppedOrCompleted(QString module, QString source, QString statusMessage) { + qDebug() << "\n**********************************\nBtInstallProgressDialog::oneItemStoppedOrCompleted" << module << statusMessage << "\n******************************************"; + 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)); + + //non-concurrent + QMultiMap<QString, BtInstallThread*>::iterator threadIterator = m_waitingThreads.end(); + if (m_runningThreads.isEmpty() && 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 InstallProgress::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 InstallProgress::slotStatusUpdated(QString /* module */, int status) { + m_progressObject->setProperty("value", status); +} + +void InstallProgress::slotInstallStarted(QString /* module */, QString) { +} + +void InstallProgress::slotDownloadStarted(QString module) { + QString message = "Installing " + module; + m_progressObject->setProperty("text", message); + m_progressObject->setProperty("value", 0); +} + +void InstallProgress::startThreads() { + QMultiMap<QString, BtInstallThread*>::iterator threadIterator = m_waitingThreads.end(); + 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(); + } +} + +bool InstallProgress::threadsDone() { + return (m_waitingThreads.isEmpty() && m_runningThreads.isEmpty()); +} + +void InstallProgress::findProgressObject() { + QtQuick2ApplicationViewer* viewer = getViewManager()->getViewer(); + QQuickItem * rootObject = 0; + if (viewer != 0) + rootObject = viewer->rootObject(); + if (rootObject != 0) + m_progressObject = rootObject->findChild<QQuickItem*>("progress"); +} + +void InstallProgress::setProperties() { + m_progressObject->setProperty("visible", true); + m_progressObject->setProperty("minimumValue", 0.0); + m_progressObject->setProperty("maximumValue", 100.0); + m_progressObject->setProperty("value", 0.0); +} + +QString InstallProgress::getSourcePath() { + QStringList targets = BtInstallBackend::targetList(); + for (QStringList::iterator it = targets.begin(); it != targets.end(); ++it) { + // Add the path only if it's writable + QString sourcePath = *it; + if (sourcePath.isEmpty()) + continue; + QDir dir(sourcePath); + if (!dir.exists()) + continue; + if (!dir.isReadable()) + continue; + QFileInfo fi( dir.canonicalPath()); + if (!fi.isWritable()) + continue; + return sourcePath; + } + return QString(); +} + +} diff --git a/src/mobile/bookshelfmanager/installprogress.h b/src/mobile/bookshelfmanager/installprogress.h new file mode 100644 index 0000000..4f9908c --- /dev/null +++ b/src/mobile/bookshelfmanager/installprogress.h @@ -0,0 +1,61 @@ +/********* +* +* In the name of the Father, and of the Son, and of the Holy Spirit. +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2014 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +#ifndef INSTALL_PROGRESS_H +#define INSTALL_PROGRESS_H + +#include <QObject> +#include <QMultiMap> +#include <QMap> + +class QQuickItem; +class CSwordModuleInfo; +class BtInstallThread; + +namespace btm { + +class InstallProgress: public QObject { + Q_OBJECT + +public: + InstallProgress(QObject* parent = 0); + + void openProgress(const QList<CSwordModuleInfo*>& modules); + +private slots: + void cancel(); + void close(); + void slotOneItemCompleted(QString module, QString source, int status); + void slotOneItemStopped(QString module, QString source); + void slotStopInstall(); + void slotStatusUpdated(QString module, int status); + void slotDownloadStarted(QString module); + void slotInstallStarted(QString module, QString); + bool threadsDone(); + +private: + void findProgressObject(); + QString getSourcePath(); + void oneItemStoppedOrCompleted(QString module, QString source, QString message); + void setProperties(); + void startThreads(); + + QQuickItem* m_progressObject; + QMultiMap<QString, BtInstallThread*> m_waitingThreads; + QMultiMap<QString, BtInstallThread*> m_runningThreads; + QMap<QString, BtInstallThread*> m_threadsByModule; +}; + + +} + +#endif diff --git a/src/mobile/bookshelfmanager/installsources.cpp b/src/mobile/bookshelfmanager/installsources.cpp new file mode 100644 index 0000000..6f6fa91 --- /dev/null +++ b/src/mobile/bookshelfmanager/installsources.cpp @@ -0,0 +1,75 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2014 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#include "installsources.h" + +#include "backend/btinstallbackend.h" +#include "backend/btinstallmgr.h" +#include <QDebug> + +namespace btm { + +InstallSources::InstallSources(QObject *parent) + : QObject(parent), + done(false), + m_cancelled(false) { + m_iMgr = new BtInstallMgr(); +} + + +InstallSources::~InstallSources() { + delete m_iMgr; +} + +void InstallSources::process() { + + m_canceled = false; + refreshSourceList(); + if (m_canceled) + return; + QStringList sourceNames = BtInstallBackend::sourceNameList(); + refreshWorks(sourceNames); + emit finished(); +} + +void InstallSources::refreshSourceList() { + int ret = m_iMgr->refreshRemoteSourceConfiguration(); + if (ret ) { + qWarning("InstallMgr: getting remote list returned an error."); + } +} + +void InstallSources::refreshWorks(const QStringList& sourceNames) { + int sourceCount = sourceNames.count(); + for (int i=0; i<sourceCount; ++i) { + if (m_canceled) + break; + QString sourceName = sourceNames.at(i); + int percent = 10 + 90 *((double)i/sourceCount); + QString title = "Refreshing " + sourceName; + emit percentComplete(percent, title); + qDebug() << title << percent; + sword::InstallSource source = BtInstallBackend::source(sourceName); + bool result = (m_iMgr->refreshRemoteSource(&source) == 0); + if (result) { + ; + } else { + QString error = QString(tr("Failed to refresh source %1")).arg(sourceName); + qDebug() << error; + } + } + emit percentComplete(100, "Done"); +} + +void InstallSources::cancel() { + m_canceled = true; + qDebug() << "IS canceled"; +} + +} diff --git a/src/mobile/bookshelfmanager/installsources.h b/src/mobile/bookshelfmanager/installsources.h new file mode 100644 index 0000000..f552c68 --- /dev/null +++ b/src/mobile/bookshelfmanager/installsources.h @@ -0,0 +1,52 @@ +/********* +* +* In the name of the Father, and of the Son, and of the Holy Spirit. +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2014 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef INSTALLSOURCESTHREAD_H +#define INSTALLSOURCESTHREAD_H + +#include <QObject> + +class BtInstallMgr; + +namespace btm { + +class InstallSources : public QObject { + Q_OBJECT + public: + InstallSources(QObject *parent = 0); + + ~InstallSources(); + + public slots: + void process(); + void cancel(); + + public: + bool done; + + protected: + void refreshSourceList(); + void refreshWorks(const QStringList& sourceNames); + + bool m_cancelled; + BtInstallMgr* m_iMgr; + + signals: + void finished(); + void error(QString err); + void percentComplete(int percent, const QString& title); + +private: + bool m_canceled; +}; + +} +#endif diff --git a/src/mobile/bookshelfmanager/installsourcesmanager.cpp b/src/mobile/bookshelfmanager/installsourcesmanager.cpp new file mode 100644 index 0000000..bc55f12 --- /dev/null +++ b/src/mobile/bookshelfmanager/installsourcesmanager.cpp @@ -0,0 +1,85 @@ +/********* +* +* In the name of the Father, and of the Son, and of the Holy Spirit. +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2014 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +#include "installsourcesmanager.h" + +#include "installsources.h" +#include "backend/btinstallbackend.h" +#include "mobile/btmmain.h" +#include "mobile/ui/qtquick2applicationviewer.h" +#include "mobile/ui/viewmanager.h" +#include <QDebug> +#include <QQuickItem> +#include <QThread> + +namespace btm { + +InstallSourcesManager::InstallSourcesManager(QObject* /* parent */) + : m_worker(0) { +} + +InstallSourcesManager::~InstallSourcesManager() { +} + +void InstallSourcesManager::refreshSources() { + findProgressObject(); + Q_ASSERT(m_progressObject != 0); + if (m_progressObject == 0) + return; + m_progressObject->disconnect(this); + connect(m_progressObject, SIGNAL(cancel()), this, SLOT(cancel())); + + m_progressObject->setProperty("minimumValue", 0.0); + m_progressObject->setProperty("maximumValue", 100.0); + m_progressObject->setProperty("value", 0.0); + m_progressObject->setProperty("visible", true); + m_progressObject->setProperty("text", "Refreshing Source List"); + + runThread(); +} + +void InstallSourcesManager::cancel() { + m_worker->cancel(); + m_progressObject->setProperty("visible", false); +} + +void InstallSourcesManager::runThread() { + QThread* thread = new QThread; + m_worker = new InstallSources(); + m_worker->moveToThread(thread); +// connect(m_worker, SIGNAL(error(QString)), this, SLOT(errorString(QString))); + connect(thread, SIGNAL(started()), m_worker, SLOT(process())); + connect(m_worker, SIGNAL(finished()), thread, SLOT(quit())); + connect(m_worker, SIGNAL(finished()), m_worker, SLOT(deleteLater())); + connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); + connect(m_worker, SIGNAL(percentComplete(int, const QString&)), + this, SLOT(percentComplete(int, const QString&))); + thread->start(); +} + +void InstallSourcesManager::percentComplete(int percent, const QString& title) { + m_progressObject->setProperty("value", percent); + m_progressObject->setProperty("text", title); + if (percent == 100) + m_progressObject->setProperty("visible", false); +} + +void InstallSourcesManager::findProgressObject() { + QtQuick2ApplicationViewer* viewer = getViewManager()->getViewer(); + QQuickItem * rootObject = 0; + if (viewer != 0) + rootObject = viewer->rootObject(); + if (rootObject != 0) + m_progressObject = rootObject->findChild<QQuickItem*>("progress"); +} + +} // end namespace diff --git a/src/mobile/bookshelfmanager/installsourcesmanager.h b/src/mobile/bookshelfmanager/installsourcesmanager.h new file mode 100644 index 0000000..07665b4 --- /dev/null +++ b/src/mobile/bookshelfmanager/installsourcesmanager.h @@ -0,0 +1,45 @@ +/********* +* +* In the name of the Father, and of the Son, and of the Holy Spirit. +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2014 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +#ifndef INSTALL_SOURCES_MANAGER_H +#define INSTALL_SOURCES_MANAGER_H + +#include <QObject> +#include <QQuickItem> + +namespace btm { + +class InstallSources; + +class InstallSourcesManager :public QObject { + Q_OBJECT + +public: + InstallSourcesManager(QObject* parent = 0); + ~InstallSourcesManager(); + + void refreshSources(); + +private slots: + void cancel(); + void percentComplete(int percent, const QString& title); + +private: + void findProgressObject(); + void runThread(); + + QQuickItem* m_progressObject; + InstallSources* m_worker; +}; + +} // end namespace +#endif |