summaryrefslogtreecommitdiff
path: root/src/mobile
diff options
context:
space:
mode:
Diffstat (limited to 'src/mobile')
-rw-r--r--src/mobile/bibletime.cpp101
-rw-r--r--src/mobile/bibletime.h31
-rw-r--r--src/mobile/bibletimeapp.cpp95
-rw-r--r--src/mobile/bibletimeapp.h55
-rw-r--r--src/mobile/bookshelfmanager/installmanager.cpp371
-rw-r--r--src/mobile/bookshelfmanager/installmanager.h82
-rw-r--r--src/mobile/bookshelfmanager/installprogress.cpp199
-rw-r--r--src/mobile/bookshelfmanager/installprogress.h61
-rw-r--r--src/mobile/bookshelfmanager/installsources.cpp75
-rw-r--r--src/mobile/bookshelfmanager/installsources.h52
-rw-r--r--src/mobile/bookshelfmanager/installsourcesmanager.cpp85
-rw-r--r--src/mobile/bookshelfmanager/installsourcesmanager.h45
-rw-r--r--src/mobile/btmmain.cpp106
-rw-r--r--src/mobile/btmmain.h23
-rw-r--r--src/mobile/keychooser/bookkeychooser.cpp272
-rw-r--r--src/mobile/keychooser/bookkeychooser.h81
-rw-r--r--src/mobile/keychooser/versechooser.cpp160
-rw-r--r--src/mobile/keychooser/versechooser.h86
-rw-r--r--src/mobile/models/bibletextmodelbuilder.cpp184
-rw-r--r--src/mobile/models/bibletextmodelbuilder.h46
-rw-r--r--src/mobile/models/booktextmodelbuilder.cpp101
-rw-r--r--src/mobile/models/booktextmodelbuilder.h40
-rw-r--r--src/mobile/models/roleitemmodel.cpp54
-rw-r--r--src/mobile/models/roleitemmodel.h24
-rw-r--r--src/mobile/qml/ContextMenu.qml62
-rw-r--r--src/mobile/qml/FontSizeSlider.qml139
-rw-r--r--src/mobile/qml/GridChooser.qml117
-rw-r--r--src/mobile/qml/GridChooserButton.qml52
-rw-r--r--src/mobile/qml/ImageButton.qml24
-rw-r--r--src/mobile/qml/InstallManagerChooser.qml153
-rw-r--r--src/mobile/qml/ListTextView.qml108
-rw-r--r--src/mobile/qml/ListWorksView.qml123
-rw-r--r--src/mobile/qml/MainToolbar.qml27
-rw-r--r--src/mobile/qml/MenuButton.qml30
-rw-r--r--src/mobile/qml/MenuView.qml28
-rw-r--r--src/mobile/qml/Menus.qml61
-rw-r--r--src/mobile/qml/ModuleChooser.qml109
-rw-r--r--src/mobile/qml/Progress.qml63
-rw-r--r--src/mobile/qml/Settings.qml93
-rw-r--r--src/mobile/qml/TreeChooser.qml167
-rw-r--r--src/mobile/qml/Window.qml178
-rw-r--r--src/mobile/qml/WindowManager.qml291
-rw-r--r--src/mobile/qml/checkmark.svg42
-rw-r--r--src/mobile/qml/leftarrow.svg83
-rw-r--r--src/mobile/qml/main.qml270
-rw-r--r--src/mobile/qml/rightarrow.svg82
-rw-r--r--src/mobile/qml/tab.pngbin0 -> 507 bytes
-rw-r--r--src/mobile/ui/btstyle.cpp334
-rw-r--r--src/mobile/ui/btstyle.h132
-rw-r--r--src/mobile/ui/btwindowinterface.cpp257
-rw-r--r--src/mobile/ui/btwindowinterface.h73
-rw-r--r--src/mobile/ui/gridchooser.cpp63
-rw-r--r--src/mobile/ui/gridchooser.h43
-rw-r--r--src/mobile/ui/modulechooser.cpp44
-rw-r--r--src/mobile/ui/modulechooser.h35
-rw-r--r--src/mobile/ui/moduleinterface.cpp187
-rw-r--r--src/mobile/ui/moduleinterface.h48
-rw-r--r--src/mobile/ui/qtquick2applicationviewer.cpp63
-rw-r--r--src/mobile/ui/qtquick2applicationviewer.h32
-rw-r--r--src/mobile/ui/treechoosermodel.cpp22
-rw-r--r--src/mobile/ui/treechoosermodel.h20
-rw-r--r--src/mobile/ui/viewmanager.cpp52
-rw-r--r--src/mobile/ui/viewmanager.h34
-rw-r--r--src/mobile/util/findqmlobject.cpp34
-rw-r--r--src/mobile/util/findqmlobject.h28
-rw-r--r--src/mobile/util/messagedialog.cpp36
-rw-r--r--src/mobile/util/messagedialog.h36
67 files changed, 6304 insertions, 0 deletions
diff --git a/src/mobile/bibletime.cpp b/src/mobile/bibletime.cpp
new file mode 100644
index 0000000..dd32bf4
--- /dev/null
+++ b/src/mobile/bibletime.cpp
@@ -0,0 +1,101 @@
+/*********
+*
+* 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 "bibletime.h"
+
+#include "backend/config/btconfig.h"
+#include "backend/managers/btstringmgr.h"
+#include "backend/managers/clanguagemgr.h"
+#include "backend/managers/cswordbackend.h"
+#include <QLocale>
+#include <stringmgr.h>
+#include <swlog.h>
+
+namespace btm {
+
+BibleTime::BibleTime(QObject* parent)
+ : QObject(parent) {
+ initBackends();
+}
+
+
+/** Initializes the backend */
+void BibleTime::initBackends() {
+ initSwordConfigFile();
+
+ sword::StringMgr::setSystemStringMgr( new BtStringMgr() );
+ sword::SWLog::getSystemLog()->setLogLevel(sword::SWLog::LOG_ERROR);
+
+ if (qApp->property("--debug").toBool()) {
+ sword::SWLog::getSystemLog()->setLogLevel(sword::SWLog::LOG_DEBUG);
+ }
+
+#ifdef Q_OS_MAC
+ // set a LocaleMgr with a fixed path to the locales.d of the DMG image on MacOS
+ // note: this must be done after setting the BTStringMgr, because this will reset the LocaleMgr
+ qDebug() << "Using sword locales dir: " << util::directory::getSwordLocalesDir().absolutePath().toUtf8();
+ sword::LocaleMgr::setSystemLocaleMgr(new sword::LocaleMgr(util::directory::getSwordLocalesDir().absolutePath().toUtf8()));
+#endif
+
+ CSwordBackend *backend = CSwordBackend::createInstance();
+ QString systemName = QLocale::system().name();
+ QString language = btConfig().value<QString>("language", systemName);
+ backend->booknameLanguage(language);
+
+ const CSwordBackend::LoadError errorCode = CSwordBackend::instance()->initModules(CSwordBackend::OtherChange);
+ if (errorCode != CSwordBackend::NoError) {
+ ; // TODO
+ }
+}
+
+void BibleTime::initSwordConfigFile() {
+// On Windows the sword.conf must be created before the initialization of sword
+// It will contain the LocalePath which is used for sword locales
+// It also contains a DataPath to the %ALLUSERSPROFILE%\Sword directory
+// If this is not done here, the sword locales.d won't be found
+#ifdef Q_OS_WIN
+ QString configFile = util::directory::getUserHomeSwordDir().filePath("sword.conf");
+ QFile file(configFile);
+ if (file.exists()) {
+ return;
+ }
+ if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
+ return;
+ }
+ QTextStream out(&file);
+ out << "\n";
+ out << "[Install]\n";
+ out << "DataPath=" << util::directory::convertDirSeparators( util::directory::getSharedSwordDir().absolutePath()) << "\n";
+ out << "LocalePath=" << util::directory::convertDirSeparators(util::directory::getApplicationSwordDir().absolutePath()) << "\n";
+ out << "\n";
+ file.close();
+#endif
+
+#ifdef Q_OS_MAC
+ QString configFile = util::directory::getUserHomeSwordDir().filePath("sword.conf");
+ QFile file(configFile);
+ if (file.exists()) {
+ return;
+ }
+ if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
+ return;
+ }
+ QTextStream out(&file);
+ out << "\n";
+ out << "[Install]\n";
+ out << "DataPath=" << util::directory::convertDirSeparators( util::directory::getUserHomeSwordDir().absolutePath()) << "\n";
+ out << "\n";
+ file.close();
+#endif
+}
+
+}
diff --git a/src/mobile/bibletime.h b/src/mobile/bibletime.h
new file mode 100644
index 0000000..b424571
--- /dev/null
+++ b/src/mobile/bibletime.h
@@ -0,0 +1,31 @@
+/*********
+*
+* 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.
+*
+**********/
+
+#pragma once
+
+#include <QObject>
+
+namespace btm {
+
+class BibleTime : public QObject {
+ Q_OBJECT
+
+public:
+ BibleTime(QObject* parent = 0);
+
+private:
+ void initBackends();
+ void initSwordConfigFile();
+
+};
+
+}
diff --git a/src/mobile/bibletimeapp.cpp b/src/mobile/bibletimeapp.cpp
new file mode 100644
index 0000000..f7801b8
--- /dev/null
+++ b/src/mobile/bibletimeapp.cpp
@@ -0,0 +1,95 @@
+/*********
+*
+* 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 "bibletimeapp.h"
+
+#include <QDebug>
+#include <QFile>
+#include "backend/config/btconfig.h"
+#include "backend/managers/cswordbackend.h"
+#include "backend/managers/cdisplaytemplatemgr.h"
+#include "frontend/messagedialog.h"
+#include "util/cresmgr.h"
+#include "util/geticon.h"
+#include "util/directory.h"
+
+
+BibleTimeApp::BibleTimeApp(int &argc, char **argv)
+ : QGuiApplication(argc, argv)
+ , m_init(false) {
+ setApplicationName("bibletime");
+ setApplicationVersion(BT_VERSION);
+}
+
+BibleTimeApp::~BibleTimeApp() {
+ // Prevent writing to the log file before the directory cache is init:
+ if (!m_init || BtConfig::m_instance == 0)
+ return;
+
+ //we can set this safely now because we close now (hopyfully without crash)
+ btConfig().setValue("state/crashedLastTime", false);
+ btConfig().setValue("state/crashedTwoTimes", false);
+
+ delete CDisplayTemplateMgr::instance();
+ CLanguageMgr::destroyInstance();
+ CSwordBackend::destroyInstance();
+ util::clearIconCache();
+
+ BtConfig::destroyInstance();
+}
+
+bool BibleTimeApp::initBtConfig() {
+ Q_ASSERT(m_init);
+
+ return BtConfig::initBtConfig();
+}
+
+bool BibleTimeApp::initDisplayTemplateManager() {
+ Q_ASSERT(m_init);
+
+ QString errorMessage;
+ new CDisplayTemplateMgr(errorMessage);
+ if (errorMessage.isNull())
+ return true;
+ message::showCritical(0, tr("Fatal error!"), errorMessage);
+ return false;
+}
+
+
+const QIcon & BibleTimeApp::getIcon(const QString & name) const {
+ QString plainName(name);
+ if (plainName.endsWith(".svg", Qt::CaseInsensitive))
+ plainName.chop(4);
+
+ const QMap<QString, QIcon>::const_iterator i = m_iconCache.find(plainName);
+ if (i != m_iconCache.end())
+ return *i;
+
+ const QString iconDir = util::directory::getIconDir().canonicalPath();
+ QString iconFileName = iconDir + "/" + plainName + ".svg";
+ if (QFile(iconFileName).exists())
+ return *m_iconCache.insert(plainName, QIcon(iconFileName));
+
+ iconFileName = iconDir + "/" + plainName + ".png";
+ if (QFile(iconFileName).exists())
+ return *m_iconCache.insert(plainName, QIcon(iconFileName));
+
+ if (plainName != "default") {
+ qWarning() << "Cannot find icon file" << iconFileName
+ << ", using default icon.";
+ return getIcon("default");
+ }
+
+ qWarning() << "Cannot find default icon" << iconFileName
+ << ", using null icon.";
+ return m_nullIcon;
+}
diff --git a/src/mobile/bibletimeapp.h b/src/mobile/bibletimeapp.h
new file mode 100644
index 0000000..08cd0a5
--- /dev/null
+++ b/src/mobile/bibletimeapp.h
@@ -0,0 +1,55 @@
+/*********
+*
+* 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 BIBLETIMEAPP_H
+#define BIBLETIMEAPP_H
+
+#include <QGuiApplication>
+#include <QIcon>
+#include <QMap>
+
+
+/**
+ The BibleTimeApp class is used to clean up all instances of the backend and to
+ delete all created module objects.
+*/
+class BibleTimeApp : public QGuiApplication {
+
+ Q_OBJECT
+
+ public: /* Methods: */
+
+ BibleTimeApp(int &argc, char **argv);
+ ~BibleTimeApp();
+
+ inline void startInit() { m_init = true; }
+ bool initBtConfig();
+ bool initDisplayTemplateManager();
+
+ /**
+ \param[in] name the name of the icon to return.
+ \returns a reference to the icon with the given name or to a NULL
+ icon if no such icon is found.
+ */
+ const QIcon & getIcon(const QString & name) const;
+
+ private: /* Fields: */
+
+ mutable QMap<QString, QIcon> m_iconCache;
+ const QIcon m_nullIcon;
+ bool m_init;
+
+};
+
+#define bApp (static_cast<BibleTimeApp *>(QCoreApplication::instance()))
+
+#endif
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
diff --git a/src/mobile/btmmain.cpp b/src/mobile/btmmain.cpp
new file mode 100644
index 0000000..12cbbf4
--- /dev/null
+++ b/src/mobile/btmmain.cpp
@@ -0,0 +1,106 @@
+/*********
+*
+* 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 "bibletime.h"
+#include "backend/config/btconfig.h"
+#include "backend/bookshelfmodel/btbookshelftreemodel.h"
+#include "mobile/bibletimeapp.h"
+#include "mobile/bookshelfmanager/installmanager.h"
+#include "mobile/ui/btstyle.h"
+#include "mobile/ui/btwindowinterface.h"
+#include "mobile/ui/moduleinterface.h"
+#include "mobile/ui/qtquick2applicationviewer.h"
+#include "mobile/ui/viewmanager.h"
+#include <QBrush>
+#include <QColor>
+#include <QGuiApplication>
+#include <QPalette>
+#include <QQuickItem>
+#include <QQmlDebuggingEnabler>
+#include <QMetaType>
+#include <QTranslator>
+#include "util/directory.h"
+
+btm::ViewManager* mgr = 0;
+
+void register_gml_classes() {
+ QQmlDebuggingEnabler enabler;
+
+ qmlRegisterType<btm::BtWindowInterface>("BibleTime", 1, 0, "BtWindowInterface");
+ qmlRegisterType<btm::BtStyle>("BibleTime", 1, 0, "BtStyle");
+ qmlRegisterType<btm::InstallManager>("BibleTime", 1, 0, "InstallManager");
+ qmlRegisterType<btm::ModuleInterface>("BibleTime", 1, 0, "ModuleInterface");
+}
+
+btm::ViewManager* getViewManager() {
+ return mgr;
+}
+
+/*******************************************************************************
+ Handle Qt's meta type system.
+*******************************************************************************/
+
+void registerMetaTypes() {
+ qRegisterMetaType<FilterOptions>("FilterOptions");
+ qRegisterMetaType<DisplayOptions>("DisplayOptions");
+ qRegisterMetaTypeStreamOperators<BtBookshelfTreeModel::Grouping>("BtBookshelfTreeModel::Grouping");
+
+ qRegisterMetaType<BTModuleTreeItem::Grouping>("Grouping");
+ qRegisterMetaTypeStreamOperators<BTModuleTreeItem::Grouping>("Grouping");
+
+ qRegisterMetaType<BtConfig::StringMap>("StringMap");
+ qRegisterMetaTypeStreamOperators<BtConfig::StringMap>("StringMap");
+
+ qRegisterMetaType<QList<int> >("QList<int>");
+ qRegisterMetaTypeStreamOperators<QList<int> >("QList<int>");
+}
+
+
+int main(int argc, char *argv[]) {
+ namespace DU = util::directory;
+
+ BibleTimeApp app(argc, argv); //for QApplication
+
+ registerMetaTypes();
+
+ if (!DU::initDirectoryCache()) {
+ qFatal("Error initializing directory cache!");
+ return EXIT_FAILURE;
+ }
+
+ app.startInit();
+ if (!app.initBtConfig()) {
+ return EXIT_FAILURE;
+ }
+
+ //first install QT's own translations
+ QTranslator qtTranslator;
+ qtTranslator.load("qt_" + QLocale::system().name());
+ app.installTranslator(&qtTranslator);
+ //then our own
+ QTranslator BibleTimeTranslator;
+ BibleTimeTranslator.load( QString("bibletime_ui_").append(QLocale::system().name()), DU::getLocaleDir().canonicalPath());
+ app.installTranslator(&BibleTimeTranslator);
+
+// // a new BibleTime version was installed (maybe a completely new installation)
+// if (btConfig().value<QString>("bibletimeVersion", BT_VERSION) != BT_VERSION) {
+// btConfig().setValue("bibletimeVersion", QString(BT_VERSION));
+// mainWindow->saveConfigSettings();
+// }
+
+ register_gml_classes();
+ mgr = new btm::ViewManager;
+ mgr->show();
+ btm::BibleTime btm;
+
+ return app.exec();
+}
diff --git a/src/mobile/btmmain.h b/src/mobile/btmmain.h
new file mode 100644
index 0000000..64bd25e
--- /dev/null
+++ b/src/mobile/btmmain.h
@@ -0,0 +1,23 @@
+/*********
+*
+* 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 VIEW_MANAGER_INCLUDED
+#define VIEW_MANAGER_INCLUDED
+
+namespace btm {
+ class ViewManager;
+}
+
+btm::ViewManager* getViewManager();
+
+#endif
+
diff --git a/src/mobile/keychooser/bookkeychooser.cpp b/src/mobile/keychooser/bookkeychooser.cpp
new file mode 100644
index 0000000..9ae3ef9
--- /dev/null
+++ b/src/mobile/keychooser/bookkeychooser.cpp
@@ -0,0 +1,272 @@
+/*********
+*
+* 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 "bookkeychooser.h"
+
+#include <cmath>
+#include "mobile/ui/btwindowinterface.h"
+#include "mobile/ui/qtquick2applicationviewer.h"
+#include <QCoreApplication>
+#include <QDebug>
+#include <QQmlProperty>
+#include <QQmlContext>
+#include <QQmlProperty>
+#include <QQuickItem>
+#include <QStandardItem>
+#include <QString>
+
+namespace btm {
+
+struct BookEntry {
+ enum BookRoles {
+ NameRole = Qt::UserRole + 1,
+ ChildCountRole
+ };
+};
+
+BookKeyChooser::BookKeyChooser(QtQuick2ApplicationViewer* viewer,
+ BtWindowInterface* windowInterface)
+ : m_viewer(viewer),
+ m_windowInterface(windowInterface),
+ m_key(0),
+ m_treeChooserObject(0),
+ m_state(CLOSED ) {
+ findTreeChooserObject();
+ initializeRoleNameModel();
+}
+
+void BookKeyChooser::copyKey()
+{
+ CSwordKey* key = m_windowInterface->getKey();
+ CSwordTreeKey* bookKey = dynamic_cast<CSwordTreeKey*>(key);
+ m_key = new CSwordTreeKey(*bookKey);
+}
+
+void BookKeyChooser::findTreeChooserObject() {
+ QQuickItem * rootObject = m_viewer->rootObject();
+ if (rootObject != 0)
+ m_treeChooserObject = rootObject->findChild<QQuickItem*>("treeChooser");
+}
+
+void BookKeyChooser::initializeRoleNameModel() {
+ QHash<int, QByteArray> roleNames;
+ roleNames[BookEntry::NameRole] = "name";
+ roleNames[BookEntry::ChildCountRole] = "childcount";
+ m_roleItemModel.setRoleNames(roleNames);
+}
+
+void BookKeyChooser::populateRoleNameModel(const QStringList& sibblings, const QList<int>& sibblingChildCounts) {
+ m_roleItemModel.clear();
+ Q_ASSERT(sibblings.count() == sibblingChildCounts.count());
+ for (int i=0; i< sibblings.count(); ++i) {
+ QString sibbling = sibblings.at(i);
+ int childCount = sibblingChildCounts.at(i);
+ QStandardItem* item = new QStandardItem();
+ item->setData(sibbling, BookEntry::NameRole);
+ item->setData(childCount, BookEntry::ChildCountRole);
+ m_roleItemModel.appendRow(item);
+ }
+}
+
+static QString constructPath(const QStringList& pathList) {
+ QString path;
+ for (int i=0; i< pathList.count(); ++i) {
+ QString leaf = QString("/") + pathList.at(i);
+ path.append(leaf);
+ }
+ return path;
+}
+
+static QString getBackPath(const CSwordTreeKey& key) {
+ QString path = key.key();
+ QStringList pathList = path.split('/', QString::SkipEmptyParts);
+ pathList.removeLast();
+
+ QString backPath;
+ if (pathList.count() == 0)
+ return backPath;
+
+ backPath = constructPath(pathList);
+ return backPath;
+}
+
+void BookKeyChooser::select(QString value) {
+ openChooser(false);
+
+ QStringList keyPathList = getKeyPath();
+ keyPathList.removeLast();
+ keyPathList.append(value);
+ QString newPath = constructPath(keyPathList);
+ CSwordTreeKey* tmpBookKey = dynamic_cast<CSwordTreeKey*>(m_key);
+ tmpBookKey->setKey(newPath);
+
+ CSwordKey* key = m_windowInterface->getKey();
+ CSwordTreeKey* bookKey = dynamic_cast<CSwordTreeKey*>(key);
+ bookKey->setKey(*tmpBookKey);
+
+ emit referenceChanged();
+}
+
+void BookKeyChooser::open() {
+ copyKey();
+
+ CSwordTreeKey tmpKey(*m_key);
+ m_backPath = getBackPath(tmpKey);
+ QStringList siblings;
+ QList<int> hasChildrenList;
+ parseKey(&siblings, &hasChildrenList, &tmpKey);
+ populateRoleNameModel(siblings, hasChildrenList);
+ openChooser(true);
+}
+
+void BookKeyChooser::next(QString value) {
+ openChooser(false);
+
+ QStringList keyPathList = getKeyPath();
+ keyPathList.removeLast();
+ keyPathList.append(value);
+
+ QString newPath = constructPath(keyPathList);
+ m_key->setKey(newPath);
+ m_key->firstChild();
+
+ CSwordTreeKey tmpKey(*m_key);
+ m_backPath = getBackPath(tmpKey);
+ QStringList siblings;
+ QList<int> counts;
+ parseKey(&siblings, &counts, &tmpKey);
+ populateRoleNameModel(siblings, counts);
+ openChooser(true);
+
+ m_key->setKey(tmpKey);
+}
+
+void BookKeyChooser::back() {
+ openChooser(false);
+
+ QStringList keyPathList = getKeyPath();
+ keyPathList.removeLast();
+
+ QString newPath = constructPath(keyPathList);
+ keyPathList.removeLast();
+ m_key->setKey(newPath);
+
+ CSwordTreeKey tmpKey(*m_key);
+ m_backPath = getBackPath(tmpKey);
+ QStringList siblings;
+ QList<int> counts;
+ parseKey(&siblings, &counts, &tmpKey);
+ populateRoleNameModel(siblings, counts);
+
+ openChooser(true);
+}
+
+void BookKeyChooser::stringCanceled() {
+}
+
+void BookKeyChooser::setProperties() {
+ m_treeChooserObject->setProperty("path",m_backPath);
+ m_treeChooserObject->setProperty("model", QVariant::fromValue(&m_roleItemModel));
+}
+
+void BookKeyChooser::openChooser(bool open) {
+ Q_ASSERT(m_treeChooserObject != 0);
+ if (m_treeChooserObject == 0)
+ return;
+
+ m_treeChooserObject->disconnect();
+ bool ok = connect(m_treeChooserObject, SIGNAL(select(QString)),
+ this, SLOT(select(QString)));
+ Q_ASSERT(ok);
+
+ ok = connect(m_treeChooserObject, SIGNAL(next(QString)),
+ this, SLOT(next(QString)));
+ Q_ASSERT(ok);
+
+ ok = connect(m_treeChooserObject, SIGNAL(back()),
+ this, SLOT(back()));
+ Q_ASSERT(ok);
+
+ setProperties();
+
+ m_treeChooserObject->setProperty("visible",open);
+}
+
+QStringList BookKeyChooser::getKeyPath() const {
+ QString oldKey = m_key->key(); //string backup of key
+
+ if (oldKey.isEmpty()) { //don't set keys equal to "/", always use a key which may have content
+ m_key->firstChild();
+ oldKey = m_key->key();
+ }
+
+ QStringList siblings; //split up key
+ if (!oldKey.isEmpty()) {
+ siblings = oldKey.split('/', QString::SkipEmptyParts);
+ }
+ return siblings;
+}
+
+static int findEntry(const QString& sibling, bool* found,
+ CSwordTreeKey* key, QString* matchingKey, QStringList* siblings, QList<int>* hasChildrenList) {
+ int index = 0;
+ int foundIndex = 0;
+ do { //look for matching sibling
+ QString keyName = key->getLocalNameUnicode();
+ if (keyName == sibling) {
+ *found = true;
+ foundIndex = index;
+ *matchingKey = key->key();
+ }
+ siblings->append(keyName);
+ bool hasChildren = key->hasChildren();
+ hasChildrenList->append(hasChildren ? 1 : 0);
+ ++index;
+ } while (key->nextSibling());
+ return foundIndex;
+}
+
+void BookKeyChooser::parseKey(QStringList * siblings,
+ QList<int>* hasChildrenList, CSwordTreeKey* key) {
+ QString oldKey = key->key();
+ QStringList pathDepthList = oldKey.split("/", QString::SkipEmptyParts);
+ int depth = 0;
+ key->root();
+
+ while ( key->firstChild() && (depth < pathDepthList.count()) ) {
+ QString localName = key->getLocalNameUnicode();
+ QString savedKey = key->key();
+ bool found = false;
+ QString path = pathDepthList[depth];
+ siblings->clear();
+ hasChildrenList->clear();
+ QString matchingKey;
+ findEntry(path, &found, key, &matchingKey, siblings, hasChildrenList);
+ if (found) {
+ key->setKey(matchingKey);
+ }
+ depth++;
+ }
+}
+
+void BookKeyChooser::createModel()
+{
+ m_model.clear();
+
+ QStandardItem *parentItem = m_model.invisibleRootItem();
+ for (int i = 0; i < 4; ++i) {
+ QStandardItem *item = new QStandardItem("item1");
+ parentItem->appendRow(item);
+ }
+}
+
+} // end namespace
diff --git a/src/mobile/keychooser/bookkeychooser.h b/src/mobile/keychooser/bookkeychooser.h
new file mode 100644
index 0000000..720e5f0
--- /dev/null
+++ b/src/mobile/keychooser/bookkeychooser.h
@@ -0,0 +1,81 @@
+/*********
+*
+* 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 BOOK_KEY_CHOOSER_H
+#define BOOK_KEY_CHOOSER_H
+
+#include "backend/keys/cswordtreekey.h"
+#include <QObject>
+#include <QList>
+#include <QStringList>
+#include <QStandardItemModel>
+#include "mobile/models/roleitemmodel.h"
+
+class QtQuick2ApplicationViewer;
+class QQmlComponent;
+class QQuickItem;
+
+namespace btm {
+
+class BtWindowInterface;
+
+class BookKeyChooser : public QObject {
+ Q_OBJECT
+
+ enum State {
+ CLOSED,
+ BOOK,
+ CHAPTER,
+ VERSE
+ };
+
+public:
+ BookKeyChooser(QtQuick2ApplicationViewer* viewer, BtWindowInterface* windowInterface);
+ void open();
+
+signals:
+ void referenceChanged();
+
+private slots:
+ void select(QString value);
+ void next(QString value);
+ void back();
+ void stringCanceled();
+
+private:
+ void copyKey();
+ void findTreeChooserObject();
+ QStringList getKeyPath() const;
+ void showGridChooser(const QStringList& list);
+ void setProperties(const QStringList& list);
+ void parseKey(QStringList * sibblings, QList<int>* hasChildrenList, CSwordTreeKey* key);
+ void createModel();
+ void setProperties();
+ void initializeRoleNameModel();
+ void populateRoleNameModel(const QStringList& sibblings, const QList<int>& sibblingChildCounts);
+ void openChooser(bool open);
+
+
+ QtQuick2ApplicationViewer* m_viewer;
+ BtWindowInterface* m_windowInterface;
+ CSwordTreeKey* m_key;
+ QQuickItem* m_treeChooserObject;
+ int m_state;
+ QString m_backPath;
+ QStringList m_sibblings;
+ QStandardItemModel m_model;
+ RoleItemModel m_roleItemModel;
+};
+
+} // end namespace
+
+#endif
diff --git a/src/mobile/keychooser/versechooser.cpp b/src/mobile/keychooser/versechooser.cpp
new file mode 100644
index 0000000..f510da0
--- /dev/null
+++ b/src/mobile/keychooser/versechooser.cpp
@@ -0,0 +1,160 @@
+/*********
+*
+* 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 "versechooser.h"
+
+#include "backend/keys/cswordversekey.h"
+#include "backend/drivers/cswordbiblemoduleinfo.h"
+#include "backend/drivers/cswordmoduleinfo.h"
+#include <cmath>
+#include "mobile/ui/btwindowinterface.h"
+#include "mobile/ui/gridchooser.h"
+#include "mobile/ui/qtquick2applicationviewer.h"
+#include <QQuickItem>
+#include <QQmlProperty>
+#include <QQmlContext>
+#include <QDebug>
+#include <QQmlProperty>
+#include <QCoreApplication>
+
+namespace btm {
+
+VerseChooser::VerseChooser(QtQuick2ApplicationViewer* viewer, BtWindowInterface* bibleVerse)
+ : m_viewer(viewer),
+ m_gridChooser(0),
+ bibleVerse_(bibleVerse),
+ m_key(0),
+ m_state(CLOSED ) {
+ m_gridChooser = new GridChooser(m_viewer);
+ bool ok = connect(m_gridChooser, SIGNAL(accepted(const QString&)),
+ this, SLOT(stringAccepted(const QString&)));
+ Q_ASSERT(ok);
+}
+
+void VerseChooser::open(CSwordVerseKey* key) {
+ if (key == 0)
+ return;
+ m_key = key;
+ m_oldBook = getBook();
+ m_oldChapter = getChapter();
+ m_oldVerse = getVerse();
+ m_state = BOOK;
+ QStringList books = getBooks();
+ m_gridChooser->open(books, m_oldBook, "Book");
+}
+
+void VerseChooser::stringAccepted(const QString& value) {
+ if (m_state == BOOK) {
+ m_newBook = value;
+ m_state = CHAPTER;
+ setBook(value);
+ QStringList chapters = getChapters();
+ m_gridChooser->open(chapters, m_oldChapter, "Chapter");
+ }
+ else if (m_state == CHAPTER) {
+ m_newChapter = value;
+ m_state = VERSE;
+ setChapter(value);
+ QStringList verses = getVerses();
+ m_gridChooser->open(verses, m_oldVerse, "Verse");
+ }
+ else if (m_state == VERSE) {
+ m_newVerse = value;
+ m_state = CLOSED;
+ setVerse(m_newVerse);
+ }
+}
+
+void VerseChooser::stringCanceled() {
+}
+
+QString VerseChooser::getBook() const {
+ QString book;
+ if (m_key)
+ book = m_key->book();
+ return book;
+}
+
+void VerseChooser::setBook(const QString& book) {
+ if (m_key) {
+ m_key->book(book);
+ }
+}
+
+QString VerseChooser::getChapter() const {
+ QString chapter;
+ if (m_key)
+ chapter = QString::number(m_key->getChapter());
+ return chapter;
+}
+
+void VerseChooser::setChapter(const QString& chapter) {
+ if (m_key) {
+ int iChapter = chapter.toInt();
+ m_key->setChapter(iChapter);
+ }
+}
+
+QString VerseChooser::getVerse() const {
+ QString verse;
+ if (m_key) {
+ verse = QString::number(m_key->getVerse());
+ }
+ return verse;
+}
+
+void VerseChooser::setVerse(const QString& verse) {
+ if (m_key) {
+ int iVerse = verse.toInt();
+ m_key->setVerse(iVerse);
+ emit referenceChanged();
+ }
+}
+
+QStringList VerseChooser::getBooks() const {
+ QStringList books;
+ const CSwordModuleInfo* module = m_key->module();
+ const CSwordBibleModuleInfo* bibleModule = qobject_cast<const CSwordBibleModuleInfo*>(module);
+ if (bibleModule)
+ books = *bibleModule->books();
+ return books;
+}
+
+QStringList VerseChooser::getChapters() const {
+ QStringList chapters;
+ const CSwordModuleInfo* module = m_key->module();
+ const CSwordBibleModuleInfo* m = qobject_cast<const CSwordBibleModuleInfo*>(module);
+
+ QString book = m_key->book();
+ int count = m->chapterCount(book);
+ for (int i = 1; i <= count; i++) {
+ chapters << QString::number(i);
+ }
+ return chapters;
+}
+
+QStringList VerseChooser::getVerses() const {
+ QStringList verses;
+ const CSwordModuleInfo* module = m_key->module();
+ const CSwordBibleModuleInfo* m = qobject_cast<const CSwordBibleModuleInfo*>(module);
+ QString book = m_key->book();
+ int chapter = m_key->getChapter();
+ int count = m->verseCount(book,chapter);
+ for (int i = 1; i <= count; i++) {
+ verses << QString::number(i);
+ }
+ return verses;
+}
+
+
+
+} // end namespace
diff --git a/src/mobile/keychooser/versechooser.h b/src/mobile/keychooser/versechooser.h
new file mode 100644
index 0000000..3c7f52b
--- /dev/null
+++ b/src/mobile/keychooser/versechooser.h
@@ -0,0 +1,86 @@
+/*********
+*
+* 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 VERSE_CHOOSER_H
+#define VERSE_CHOOSER_H
+
+#include <QObject>
+#include <QList>
+
+class CSwordVerseKey;
+class QtQuick2ApplicationViewer;
+class QQmlComponent;
+class QQuickItem;
+class QStringList;
+
+namespace btm {
+
+class GridChooser;
+
+class BtWindowInterface;
+
+class VerseChooser : public QObject {
+ Q_OBJECT
+
+ enum State {
+ CLOSED,
+ BOOK,
+ CHAPTER,
+ VERSE
+ };
+
+public:
+ VerseChooser(QtQuick2ApplicationViewer* viewer, BtWindowInterface* bibleVerse);
+ void open(CSwordVerseKey* key);
+
+signals:
+ void referenceChanged();
+
+private slots:
+ void stringAccepted(const QString& value);
+ void stringCanceled();
+
+private:
+ QString getBook() const;
+ void setBook(const QString& book);
+
+ QString getChapter() const;
+ void setChapter(const QString& chapter);
+
+ QString getVerse() const;
+ void setVerse(const QString& chapter);
+
+ QStringList getBooks() const;
+ QStringList getChapters() const;
+ QStringList getVerses() const;
+
+ void showGridChooser(const QStringList& list);
+ void setProperties(const QStringList& list);
+
+
+ QtQuick2ApplicationViewer* m_viewer;
+ GridChooser* m_gridChooser;
+ BtWindowInterface* bibleVerse_;
+ CSwordVerseKey* m_key;
+ int m_state;
+
+ QString m_oldBook;
+ QString m_oldChapter;
+ QString m_oldVerse;
+ QString m_newBook;
+ QString m_newChapter;
+ QString m_newVerse;
+};
+
+} // end namespace
+
+#endif
diff --git a/src/mobile/models/bibletextmodelbuilder.cpp b/src/mobile/models/bibletextmodelbuilder.cpp
new file mode 100644
index 0000000..20faf14
--- /dev/null
+++ b/src/mobile/models/bibletextmodelbuilder.cpp
@@ -0,0 +1,184 @@
+/*********
+*
+* 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 "bibletextmodelbuilder.h"
+
+#include "btglobal.h"
+#include "backend/keys/cswordversekey.h"
+#include "backend/drivers/cswordbiblemoduleinfo.h"
+#include "backend/managers/cswordbackend.h"
+
+namespace btm {
+
+struct BookEntry {
+ enum TextRoles {
+ ReferenceRole = Qt::UserRole + 1,
+ TextRole = Qt::UserRole + 2
+ };
+};
+
+BibleTextModelBuilder::BibleTextModelBuilder(RoleItemModel* model)
+ : m_model(model) {
+ QHash<int, QByteArray> roleNames;
+ roleNames[BookEntry::ReferenceRole] = "ref";
+ roleNames[BookEntry::TextRole] = "line";
+ m_model->setRoleNames(roleNames);
+}
+
+void BibleTextModelBuilder::updateModel(
+ QList<const CSwordModuleInfo*> modules,
+ const QString& keyName) {
+
+ Q_ASSERT( modules.count() >= 1 );
+ Q_ASSERT( !keyName.isEmpty() );
+
+ FilterOptions options;
+ options.footnotes = 0;
+ options.strongNumbers = 0;
+ options.headings = 1;
+ options.morphTags = 0;
+ options.lemmas = 0;
+ options.hebrewPoints = 0;
+ options.greekAccents = 0;
+ options.textualVariants = 0;
+ options.redLetterWords = 1;
+ options.scriptureReferences = 0;
+ options.morphSegmentation = 0;
+ CSwordBackend::instance()->setFilterOptions(options);
+
+ const CSwordModuleInfo *module = modules.first();
+
+ if (modules.count() == 1)
+ module->module()->setSkipConsecutiveLinks( true ); //skip empty, linked verses
+
+ QString startKey = keyName;
+ QString endKey = startKey;
+
+ //check whether there's an intro we have to include
+ Q_ASSERT((module->type() == CSwordModuleInfo::Bible));
+
+ if (module->type() == CSwordModuleInfo::Bible) {
+ ((sword::VerseKey*)(module->module()->getKey()))->setIntros(true);
+
+ Q_ASSERT(dynamic_cast<const CSwordBibleModuleInfo*>(module) != 0);
+ const CSwordBibleModuleInfo* bible =
+ static_cast<const CSwordBibleModuleInfo*>(module);
+
+ CSwordVerseKey k1(module);
+ k1.setIntros(true);
+ k1.setKey(keyName);
+
+ if (k1.getChapter() == 1)
+ k1.setChapter(0); // Chapter 1, start with 0:0, otherwise X:0
+
+ k1.setVerse(0);
+
+ startKey = k1.key();
+
+ if (k1.getChapter() == 0)
+ k1.setChapter(1);
+
+ k1.setVerse(bible->verseCount(k1.book(), k1.getChapter()));
+ endKey = k1.key();
+ }
+
+ updateKeyRange(modules, startKey, endKey, keyName);
+}
+
+void BibleTextModelBuilder::updateKeyRange(
+ QList<const CSwordModuleInfo*> modules,
+ const QString& startKey,
+ const QString& endKey,
+ const QString& highlightKey) {
+
+ m_model->clear();
+
+ const CSwordModuleInfo *module = modules.first();
+
+ QSharedPointer<CSwordKey> currentKey( CSwordKey::createInstance(module) );
+ currentKey->setKey(highlightKey);
+ CSwordVerseKey* vk_current = dynamic_cast<CSwordVerseKey*>(currentKey.data());
+ Q_ASSERT(vk_current);
+ m_currentVerse = vk_current->getVerse();
+
+ QSharedPointer<CSwordKey> lowerBound( CSwordKey::createInstance(module) );
+ lowerBound->setKey(startKey);
+
+ QSharedPointer<CSwordKey> upperBound( CSwordKey::createInstance(module) );
+ upperBound->setKey(endKey);
+
+ sword::SWKey* sw_start = dynamic_cast<sword::SWKey*>(lowerBound.data());
+ sword::SWKey* sw_stop = dynamic_cast<sword::SWKey*>(upperBound.data());
+
+ Q_ASSERT((*sw_start == *sw_stop) || (*sw_start < *sw_stop));
+
+ // if (*sw_start == *sw_stop) { //same key, render single key
+ // return renderSingleKey(lowerBound->key(), modules);
+ // }
+ // else if (*sw_start < *sw_stop) { // Render range
+ // KeyTree tree;
+ // KeyTreeItem::Settings settings = keySettings;
+
+ CSwordVerseKey* vk_start = dynamic_cast<CSwordVerseKey*>(lowerBound.data());
+ Q_ASSERT(vk_start);
+
+ CSwordVerseKey* vk_stop = dynamic_cast<CSwordVerseKey*>(upperBound.data());
+ Q_ASSERT(vk_stop);
+
+ while ((*vk_start < *vk_stop) || (*vk_start == *vk_stop)) {
+
+ //make sure the key given by highlightKey gets marked as current key
+ // settings.highlight = (!highlightKey.isEmpty() ? (vk_start->key() == highlightKey) : false);
+
+ /**
+ \todo We need to take care of linked verses if we render one or
+ (esp) more modules. If the verses 2,3,4,5 are linked to 1,
+ it should be displayed as one entry with the caption 1-5.
+ */
+
+ if (vk_start->getChapter() == 0) { // range was 0:0-1:x, render 0:0 first and jump to 1:0
+ vk_start->setVerse(0);
+ addVerseToModel(vk_start);
+ vk_start->setChapter(1);
+ vk_start->setVerse(0);
+ }
+ addVerseToModel(vk_start);
+ if (!vk_start->next(CSwordVerseKey::UseVerse)) {
+ /// \todo Notify the user about this failure.
+ break;
+ }
+ }
+}
+
+void BibleTextModelBuilder::addVerseToModel(CSwordVerseKey* key) {
+ int verseNumber = key->getVerse();
+ QString verse;
+ if (verseNumber != 0)
+ verse.setNum(verseNumber);
+ QString text = key->renderedText();
+ if (text.isEmpty())
+ return;
+ text.replace("<br /><br />", "<br />");
+ QStandardItem* item = new QStandardItem();
+ item->setData(verse, BookEntry::ReferenceRole);
+ item->setData(text, BookEntry::TextRole);
+ m_model->appendRow(item);
+
+ if (m_currentVerse == verseNumber)
+ m_currentModelIndex = m_model->rowCount() - 1;
+}
+
+int BibleTextModelBuilder::getCurrentModelIndex() const {
+ return m_currentModelIndex;
+}
+
+}
diff --git a/src/mobile/models/bibletextmodelbuilder.h b/src/mobile/models/bibletextmodelbuilder.h
new file mode 100644
index 0000000..620810a
--- /dev/null
+++ b/src/mobile/models/bibletextmodelbuilder.h
@@ -0,0 +1,46 @@
+/*********
+*
+* 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 "mobile/models/roleitemmodel.h"
+#include <QList>
+#include <QString>
+#include "backend/drivers/cswordmoduleinfo.h"
+
+class CSwordVerseKey;
+
+namespace btm {
+
+class BibleTextModelBuilder {
+public:
+ BibleTextModelBuilder(RoleItemModel* model);
+
+ void updateModel(
+ QList<const CSwordModuleInfo*> modules,
+ const QString& keyText);
+
+ void updateKeyRange(
+ QList<const CSwordModuleInfo*> modules,
+ const QString& startKey,
+ const QString& endKey,
+ const QString& highlightKey);
+
+ int getCurrentModelIndex() const;
+
+private:
+ void addVerseToModel(CSwordVerseKey* key);
+
+ RoleItemModel* m_model;
+ int m_currentVerse;
+ int m_currentModelIndex;
+};
+
+}
diff --git a/src/mobile/models/booktextmodelbuilder.cpp b/src/mobile/models/booktextmodelbuilder.cpp
new file mode 100644
index 0000000..44d5d92
--- /dev/null
+++ b/src/mobile/models/booktextmodelbuilder.cpp
@@ -0,0 +1,101 @@
+/*********
+*
+* 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 "booktextmodelbuilder.h"
+
+#include "btglobal.h"
+#include "backend/keys/cswordtreekey.h"
+#include "backend/drivers/cswordbookmoduleinfo.h"
+#include "backend/managers/cswordbackend.h"
+
+namespace btm {
+
+struct BookEntry {
+ enum TextRoles {
+ ReferenceRole = Qt::UserRole + 1,
+ TextRole = Qt::UserRole + 2
+ };
+};
+
+BookTextModelBuilder::BookTextModelBuilder(RoleItemModel* model)
+ : m_model(model) {
+ QHash<int, QByteArray> roleNames;
+ roleNames[BookEntry::ReferenceRole] = "ref";
+ roleNames[BookEntry::TextRole] = "line";
+ m_model->setRoleNames(roleNames);
+}
+
+void BookTextModelBuilder::updateModel(
+ QList<const CSwordModuleInfo*> modules,
+ const QString& keyName) {
+
+ Q_ASSERT( modules.count() >= 1 );
+ Q_ASSERT( !keyName.isEmpty() );
+
+ FilterOptions options;
+ options.footnotes = 0;
+ options.strongNumbers = 0;
+ options.headings = 1;
+ options.morphTags = 0;
+ options.lemmas = 0;
+ options.hebrewPoints = 0;
+ options.greekAccents = 0;
+ options.textualVariants = 0;
+ options.redLetterWords = 1;
+ options.scriptureReferences = 0;
+ options.morphSegmentation = 0;
+ CSwordBackend::instance()->setFilterOptions(options);
+
+ const CSwordModuleInfo *module = modules.first();
+
+ const CSwordBookModuleInfo* book = dynamic_cast<const CSwordBookModuleInfo*>(module);
+ Q_ASSERT(book);
+
+ QSharedPointer<CSwordTreeKey> key (
+ dynamic_cast<CSwordTreeKey*>( CSwordKey::createInstance(book) )
+ );
+ key->setKey(keyName); //set the key to position we'd like to get
+
+// const unsigned long offset = key->getOffset();
+
+ //check whether there's an intro we have to include
+ Q_ASSERT((module->type() == CSwordModuleInfo::GenericBook));
+
+ if (module->type() == CSwordModuleInfo::GenericBook) {
+ CSwordTreeKey* swKey = dynamic_cast<CSwordTreeKey*>(key.data());
+ addVerseToModel(swKey);
+ }
+}
+
+void BookTextModelBuilder::addVerseToModel(CSwordTreeKey* key) {
+// int verseNumber = key->getVerse();
+ QString verse;
+// if (verseNumber != 0)
+// verse.setNum(verseNumber);
+ QString text = key->renderedText(); // TODO - fix
+ if (text.isEmpty())
+ return;
+// text.replace("<br /><br />", "<br />");
+ QStandardItem* item = new QStandardItem();
+ item->setData(verse, BookEntry::ReferenceRole);
+ item->setData(text, BookEntry::TextRole);
+ m_model->appendRow(item);
+
+// if (m_currentVerse == verseNumber)
+// m_currentModelIndex = m_model->rowCount() - 1;
+}
+
+int BookTextModelBuilder::getCurrentModelIndex() const {
+ return m_currentModelIndex;
+}
+
+}
diff --git a/src/mobile/models/booktextmodelbuilder.h b/src/mobile/models/booktextmodelbuilder.h
new file mode 100644
index 0000000..a64c380
--- /dev/null
+++ b/src/mobile/models/booktextmodelbuilder.h
@@ -0,0 +1,40 @@
+/*********
+*
+* 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 "mobile/models/roleitemmodel.h"
+#include <QList>
+#include <QString>
+#include "backend/drivers/cswordmoduleinfo.h"
+
+class CSwordTreeKey;
+
+namespace btm {
+
+class BookTextModelBuilder {
+public:
+ BookTextModelBuilder(RoleItemModel* model);
+
+ void updateModel(
+ QList<const CSwordModuleInfo*> modules,
+ const QString& keyText);
+
+ int getCurrentModelIndex() const;
+
+private:
+ void addVerseToModel(CSwordTreeKey* key);
+
+ RoleItemModel* m_model;
+ int m_currentVerse;
+ int m_currentModelIndex;
+};
+
+}
diff --git a/src/mobile/models/roleitemmodel.cpp b/src/mobile/models/roleitemmodel.cpp
new file mode 100644
index 0000000..95634af
--- /dev/null
+++ b/src/mobile/models/roleitemmodel.cpp
@@ -0,0 +1,54 @@
+#include "roleitemmodel.h"
+
+/* Example usage:
+
+Enumerate the role ID's somewhere
+---------------------------------
+
+struct RedditEntry {
+
+ enum RedditRoles {
+ UrlRole = Qt::UserRole + 1,
+ DescRole,
+ ...
+ };
+ ...
+}
+
+Instantiate the class
+---------------------
+
+ QHash<int, QByteArray> roleNames;
+ roleNames[RedditEntry::UrlRole] = "url";
+ roleNames[RedditEntry::ScoreRole] = "score";
+ m_linksmodel = new RoleItemModel(roleNames);
+
+Populate with data:
+-------------------
+
+ QStandardItem* it = new QStandardItem();
+ it->setData(e.desc, RedditEntry::DescRole);
+ it->setData(e.score, RedditEntry::ScoreRole);
+
+ m_linksmodel->appendRow(it);
+
+Expose to QML:
+-------------
+
+QDeclarativeContext *ctx = ...
+
+ctx->setContextProperty("mdlLinks", m_linksmodel);
+
+*/
+
+//RoleItemModel::RoleItemModel(const QHash<int, QByteArray> &roleNames)
+// : m_roleNames(roleNames) {
+//}
+
+QHash<int, QByteArray> RoleItemModel::roleNames() const {
+ return m_roleNames;
+}
+
+void RoleItemModel::setRoleNames(const QHash<int, QByteArray> &roleNames) {
+ m_roleNames = roleNames;
+}
diff --git a/src/mobile/models/roleitemmodel.h b/src/mobile/models/roleitemmodel.h
new file mode 100644
index 0000000..46f02be
--- /dev/null
+++ b/src/mobile/models/roleitemmodel.h
@@ -0,0 +1,24 @@
+#ifndef ROLEITEMMODEL_H
+#define ROLEITEMMODEL_H
+
+#include <QStandardItemModel>
+
+/* class to allow easily exposing
+ C++ data as a model for QML View.
+*/
+
+class RoleItemModel : public QStandardItemModel {
+public:
+ // roleNames is a map describing what role id (e.g. Qt::UserRole+1)
+ // is associated with what name on QML side (e.g. 'bookTitle')
+ // RoleItemModel(const QHash<int, QByteArray> &roleNames);
+
+ QHash<int, QByteArray> roleNames() const;
+ void setRoleNames(const QHash<int, QByteArray> &roleNames);
+
+private:
+ QHash<int, QByteArray> m_roleNames;
+
+};
+
+#endif // ROLEITEMMODEL_H
diff --git a/src/mobile/qml/ContextMenu.qml b/src/mobile/qml/ContextMenu.qml
new file mode 100644
index 0000000..bf55ebf
--- /dev/null
+++ b/src/mobile/qml/ContextMenu.qml
@@ -0,0 +1,62 @@
+import QtQuick 2.1
+import BibleTime 1.0
+
+Rectangle {
+ id: contextMenu
+
+ property alias model: menuList.model
+
+ signal accepted(string action)
+
+ color: "white"
+ border.color: "black"
+ border.width: 1
+ anchors.centerIn: parent
+ height: 250
+ width: 250
+
+ onVisibleChanged: PropertyAnimation {
+ target: settings
+ property: "opacity"
+ from: 0
+ to: 1
+ duration: 400
+ easing.type: Easing.InOutCubic
+ }
+
+ BtStyle {
+ id: btStyle
+ }
+
+ ListView {
+ id: menuList
+
+ anchors.fill: parent
+ anchors.topMargin: 100
+
+ delegate: Rectangle {
+ color: "white"
+ border.color: "black"
+ border.width: 1
+ width: parent.width
+ height: children[0].height * 2.5
+
+ Text {
+ id: menuText
+ x: 40
+ anchors.verticalCenter: parent.verticalCenter
+ text: title
+ color: "black"
+ font.pointSize: btStyle.uiFontPointSize
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ contextMenu.visible = false;
+ contextMenu.accepted(action);
+ }
+ }
+ }
+ }
+}
diff --git a/src/mobile/qml/FontSizeSlider.qml b/src/mobile/qml/FontSizeSlider.qml
new file mode 100644
index 0000000..6c11dc0
--- /dev/null
+++ b/src/mobile/qml/FontSizeSlider.qml
@@ -0,0 +1,139 @@
+import QtQuick 2.1
+import BibleTime 1.0
+
+Rectangle {
+ id: fontPointSize
+
+ property string title: ""
+ property int min: 10
+ property int max: 22
+ property int current: 12
+ property int previous: 12
+
+ signal accepted(int pointSize);
+
+ color: "#f8f8f8"
+ border.color: "black"
+ border.width: 1
+ anchors.centerIn: parent
+ width: parent.width * 0.85
+ height: 140
+
+ Text {
+ text: title
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.top: parent.top
+ anchors.topMargin: 10
+ height: 40
+ font.pointSize: btStyle.uiFontPointSize
+ }
+
+ Rectangle {
+ id: bar
+
+ color: "blue"
+ width: parent.width *.80
+ height: 3
+ anchors.centerIn: parent
+ }
+
+ Rectangle {
+ id: indicator
+
+ width: 18
+ height: 18
+ color: "red"
+ y: bar.y - height / 2
+ x: {
+ var range = fontPointSize.max - fontPointSize.min;
+ var xpos = bar.width *
+ (fontPointSize.current - fontPointSize.min) / range;
+ xpos = xpos + bar.x
+ return xpos
+ }
+ }
+
+ MouseArea {
+ property bool active: false
+ width: bar.width
+ anchors.left: bar.left
+ height: 40
+ anchors.verticalCenter: bar.verticalCenter
+
+ onPressed: {
+ active = true;
+ }
+
+ onReleased: {
+ active = false;
+ }
+
+ onMouseXChanged: {
+ if ( ! active)
+ return;
+ var range = fontPointSize.max - fontPointSize.min;
+ var currentF = mouse.x / bar.width * range + fontPointSize.min;
+ var value = Math.round(currentF);
+ if (value < fontPointSize.min)
+ value = min;
+ if (value > fontPointSize.max)
+ value = max;
+ fontPointSize.current = value;
+ accepted(value);
+ }
+
+ }
+
+ Grid {
+ id: buttons
+
+ spacing: 10
+ columns: 2
+ anchors.right: parent.right
+ anchors.bottom: parent.bottom
+ anchors.rightMargin: 10
+ anchors.bottomMargin: 10
+
+ Rectangle {
+ height: 40
+ width: 120
+ border.color: "black"
+ border.width: 1
+
+ Text {
+ text: "Ok"
+ anchors.centerIn: parent
+ font.pointSize: btStyle.uiFontPointSize
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ fontPointSize.visible = false;
+ }
+ }
+ }
+
+ Rectangle {
+ height: 40
+ width: 120
+ border.color: "black"
+ border.width: 1
+
+ Text {
+ text: "Cancel"
+ anchors.centerIn: parent
+ font.pointSize: btStyle.uiFontPointSize
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ accepted(previous);
+ fontPointSize.visible = false;
+ }
+ }
+ }
+ }
+
+}
diff --git a/src/mobile/qml/GridChooser.qml b/src/mobile/qml/GridChooser.qml
new file mode 100644
index 0000000..b4d1612
--- /dev/null
+++ b/src/mobile/qml/GridChooser.qml
@@ -0,0 +1,117 @@
+import QtQuick 2.1
+import BibleTime 1.0
+
+Rectangle {
+ id: gridChooser
+
+ property int columns: 5
+ property int rows: 5
+ property int buttonWidth: 100
+ property int buttonHeight: 30
+ property int topMargin: 10
+ property int leftMargin: 10
+ property int titleHeight: 20
+ property int space:5
+ property string selected: ""
+ property string titleText: ""
+ property int maxLength: 0
+
+ signal accepted(string choosenText);
+ signal canceled();
+
+ onVisibleChanged: {
+
+ var count = gridChooserModel.length
+ if (count < 36)
+ count = 36;
+
+ calculateColumns(count);
+
+ buttonWidth = (width-50)/columns;
+ buttonHeight = Math.floor((height-(rows*5))/rows);
+
+ topMargin = (height - rows*(buttonHeight+space) + space)/2 +titleHeight;
+ leftMargin = (width - columns*(buttonWidth+space) + space)/2;
+ }
+
+ function calculateColumns(count) {
+ var aspectRatio = 0.175;
+ var columnsF = Math.sqrt(count * width * aspectRatio / height);
+ columns = Math.ceil(columnsF);
+ rows = Math.ceil((count-0.01)/columns);
+ }
+
+ function accept(value) {
+ visible = false;
+ gridChooser.accepted(value);
+ }
+
+ Text {
+ id: title
+
+ text: titleText
+ font.pointSize: btStyle.uiFontPointSize
+ height: titleHeight
+ anchors.top: parent.top
+ anchors.horizontalCenter: parent.horizontalCenter
+ }
+
+ BtStyle {
+ id: btStyle
+ }
+
+ MouseArea {
+ id: mouseArea
+
+ anchors.fill: parent
+ enabled: gridChooser.opacity
+ }
+
+ Rectangle {
+ anchors.fill: parent
+ color: btStyle.buttonBackground
+ }
+
+ Rectangle {
+ id: topSpace
+
+ width: leftMargin
+ height: topMargin
+ color: btStyle.buttonBackground
+ }
+
+ Grid {
+ id: grid
+
+ anchors.top: topSpace.bottom
+ anchors.bottom: bottom.top
+ anchors.left: topSpace.right
+ anchors.right: parent.right
+ columns: gridChooser.columns
+ spacing: gridChooser.space
+
+ Repeater {
+ id: repeater
+
+ model: gridChooserModel
+
+ GridChooserButton {
+ id: buttonX
+
+ text: modelData
+ textHeight: btStyle.uiFontPointSize
+ buttonWidth: gridChooser.buttonWidth
+ buttonHeight: gridChooser.buttonHeight
+ textColor: {
+ if (text == gridChooser.selected)
+ return btStyle.buttonHighlightedText
+ else
+ return btStyle.buttonTextColor
+ }
+ buttonColor: btStyle.buttonColor
+ activeButtonColor: btStyle.buttonTextColor
+ onClicked: gridChooser.accept(text)
+ }
+ }
+ }
+}
diff --git a/src/mobile/qml/GridChooserButton.qml b/src/mobile/qml/GridChooserButton.qml
new file mode 100644
index 0000000..9a65041
--- /dev/null
+++ b/src/mobile/qml/GridChooserButton.qml
@@ -0,0 +1,52 @@
+import QtQuick 2.1
+import BibleTime 1.0
+
+Rectangle {
+ id: button
+
+ property int buttonWidth
+ property int buttonHeight
+ property int textHeight
+ property color textColor
+ property color buttonColor
+ property color activeButtonColor
+ property alias text: buttonText.text
+
+ signal clicked
+
+ width: buttonWidth
+ height: buttonHeight
+ gradient: Gradient {
+ GradientStop { position: 0.0; color: btStyle.buttonGradient0 }
+ GradientStop { position: 0.15; color: btStyle.buttonGradient1 }
+ GradientStop { position: 0.85; color: btStyle.buttonGradient2 }
+ GradientStop { position: 1.0; color: btStyle.buttonGradient3 }
+ }
+ smooth: true
+
+ border {
+ width: 1
+ color: btStyle.buttonBorder
+ }
+
+ BtStyle {
+ id: btStyle
+ }
+
+ Text {
+ id: buttonText
+
+ width: buttonWidth-8
+ anchors.centerIn: parent
+ color: button.textColor
+ font.pointSize: parent.textHeight
+ elide: Text.ElideRight
+ }
+
+ MouseArea {
+ id: mouseArea
+
+ anchors.fill: parent
+ onClicked: button.clicked()
+ }
+}
diff --git a/src/mobile/qml/ImageButton.qml b/src/mobile/qml/ImageButton.qml
new file mode 100644
index 0000000..552a9b4
--- /dev/null
+++ b/src/mobile/qml/ImageButton.qml
@@ -0,0 +1,24 @@
+import QtQuick 2.1
+
+Rectangle {
+ id: imageButton
+
+ property bool show: true
+ property string icon: ""
+ property int corner: 6
+
+ border.width: 1
+ border.color: "gray"
+ radius: corner
+
+ Image{
+ id: nextIcon
+ anchors.fill: parent
+ fillMode: Image.PreserveAspectFit
+ source: imageButton.icon
+ height: parent.height
+ width: parent.height
+ anchors.right: parent.right
+ anchors.top: parent.top
+ }
+}
diff --git a/src/mobile/qml/InstallManagerChooser.qml b/src/mobile/qml/InstallManagerChooser.qml
new file mode 100644
index 0000000..15b6079
--- /dev/null
+++ b/src/mobile/qml/InstallManagerChooser.qml
@@ -0,0 +1,153 @@
+import QtQuick 2.1
+
+Rectangle {
+ id: installManager
+
+ property alias sourceModel: sourceView.model
+ property alias categoryModel: categoryView.model
+ property alias languageModel: languageView.model
+ property alias worksModel: worksView.model
+ property alias sourceIndex: sourceView.currentIndex
+ property alias categoryIndex: categoryView.currentIndex
+ property alias languageIndex: languageView.currentIndex
+ property int spacing: 8
+
+ objectName: "installManager"
+ color: "lightgray"
+ border.color: "black"
+ border.width: 2
+
+ signal sourceChanged(int index);
+ signal categoryChanged(int index);
+ signal languageChanged(int index);
+ signal workSelected(int index);
+ signal cancel();
+ signal installRemove();
+ signal refreshLists();
+
+ Grid {
+ id: grid
+ columns: 3
+ rows: 1
+ spacing: installManager.spacing
+ width: parent.width - installManager.spacing
+ height: installManager.height/3
+ anchors.left: parent.left
+ anchors.top: parent.top
+ anchors.margins: installManager.spacing
+
+ ListTextView {
+ id: sourceView
+ onItemSelected: {
+ sourceChanged(currentIndex)
+ }
+
+ title: "Source"
+ width: parent.width/3 - grid.spacing
+ height: installManager.height/3
+ }
+
+ ListTextView {
+ id: categoryView
+
+ title: "Category"
+ width: parent.width/3 - grid.spacing
+ height: installManager.height/3
+ onItemSelected: {
+ categoryChanged(currentIndex)
+ }
+ }
+
+ ListTextView {
+ id: languageView
+
+ title: "Language"
+ width: parent.width/3 - grid.spacing
+ height: installManager.height/3
+ onItemSelected: {
+ languageChanged(currentIndex)
+ }
+ }
+ }
+
+ ListWorksView {
+ id: worksView
+
+ title: "Work"
+ width: parent.width - 2 * installManager.spacing
+ anchors.top: grid.bottom
+ anchors.left: parent.left
+ anchors.bottom: installRemoveButton.top
+ anchors.margins: installManager.spacing
+ onItemSelected: {
+ workSelected(index)
+ }
+ }
+
+ Rectangle {
+ id: "refreshButton"
+ width:150
+ height: 40
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: 10
+ anchors.right: installRemoveButton.left
+ anchors.rightMargin: 10
+ border.width: 1
+ border.color: "black"
+
+ Text {
+ text: "Refresh Lists"
+ anchors.centerIn: parent
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: installManager.refreshLists()
+ }
+ }
+
+ Rectangle {
+ id: "installRemoveButton"
+ width:150
+ height: 40
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: 10
+ anchors.right: cancelButton.left
+ anchors.rightMargin: 10
+ border.width: 1
+ border.color: "black"
+
+ Text {
+ text: "Install / Remove"
+ anchors.centerIn: parent
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: installManager.installRemove()
+ }
+ }
+
+ Rectangle {
+ id: "cancelButton"
+ width: installRemoveButton.width
+ height: installRemoveButton.height
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: 10
+ anchors.right: parent.right
+ anchors.rightMargin: 10
+ border.width: 1
+ border.color: "black"
+
+ Text {
+ text: "Cancel"
+ anchors.centerIn: parent
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: installManager.cancel();
+ }
+ }
+
+}
diff --git a/src/mobile/qml/ListTextView.qml b/src/mobile/qml/ListTextView.qml
new file mode 100644
index 0000000..703fe48
--- /dev/null
+++ b/src/mobile/qml/ListTextView.qml
@@ -0,0 +1,108 @@
+import QtQuick 2.1
+
+Rectangle {
+ id: top
+
+ property alias model: listView.model
+ property alias currentIndex: listView.currentIndex
+ property alias title: title.text
+ property bool highlight: true
+
+ border.color: "black"
+ border.width: 2
+
+ signal itemSelected(int index)
+
+ Rectangle {
+ id: titleRect
+
+ border.color: "black"
+ border.width: 1
+ height:25
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.top: parent.top
+ anchors.leftMargin: 3
+ anchors.rightMargin: 3
+ anchors.topMargin: 3
+
+ Text {
+ id: title
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.centerIn: parent
+ horizontalAlignment: Text.AlignCenter
+ verticalAlignment: Text.AlignBottom
+ style: Text.Sunken
+ font.pointSize: btStyle.uiFontPointSize
+ }
+ }
+
+ ListView {
+ id: listView
+
+ anchors.top: titleRect.bottom
+ anchors.bottom: parent.bottom
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.leftMargin: 3
+ anchors.rightMargin: 3
+ anchors.bottomMargin: 3
+ clip: true
+ highlightFollowsCurrentItem: true
+ currentIndex: 2
+
+ function selectItem(x, y) {
+ var index = listView.indexAt(x+contentX,y+contentY);
+ currentIndex = index;
+ top.itemSelected(index);
+ }
+
+ Rectangle {
+ id: scrollbar
+ anchors.right: listView.right
+ y: listView.visibleArea.yPosition * listView.height
+ width: 7
+ height: listView.visibleArea.heightRatio * listView.height
+ color: "black"
+ visible: listView.visibleArea.heightRatio < 0.99
+ }
+
+ delegate {
+ Rectangle {
+ id: entry
+
+ property bool selected: ListView.isCurrentItem ? true : false
+ objectName: "entry"
+ color: (highlight && ListView.isCurrentItem) ? "#ffeeaa" : "white"
+ border.width: 1
+ border.color: "darkgray"
+ width: parent.width
+ height: 40
+
+ Text {
+ id: entryText
+
+ anchors.top: entry.top
+ anchors.left: entry.left
+ anchors.right: entry.right
+ width: parent.width
+ anchors.leftMargin: 10
+ anchors.rightMargin: 10
+ anchors.topMargin: 10
+ text: modelText
+ font.pointSize: btStyle.uiFontPointSize
+ font.bold: highlight && entry.selected
+ }
+ }
+ }
+
+ MouseArea {
+ anchors.fill: listView
+ onClicked: itemSelected()
+
+ function itemSelected() {
+ listView.selectItem(mouseX, mouseY);
+ }
+ }
+ }
+}
diff --git a/src/mobile/qml/ListWorksView.qml b/src/mobile/qml/ListWorksView.qml
new file mode 100644
index 0000000..6e6dd13
--- /dev/null
+++ b/src/mobile/qml/ListWorksView.qml
@@ -0,0 +1,123 @@
+import QtQuick 2.1
+import BibleTime 1.0
+
+Rectangle {
+ id: top
+ property alias model: listView.model
+ property alias title: title.text
+
+ border.color: "black"
+ border.width: 2
+
+ signal itemSelected(int index)
+
+ Rectangle {
+ id: titleRect
+
+ border.color: "black"
+ border.width: 1
+ height:25
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.top: parent.top
+ anchors.leftMargin: 3
+ anchors.rightMargin: 3
+ anchors.topMargin: 3
+
+ Text {
+ id: title
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.centerIn: parent
+ horizontalAlignment: Text.AlignCenter
+ verticalAlignment: Text.AlignBottom
+ style: Text.Sunken
+ font.pointSize: btStyle.uiFontPointSize
+ }
+ }
+
+ ListView {
+ id: listView
+ clip: true
+ anchors.top: titleRect.bottom
+ anchors.bottom: parent.bottom
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.margins: 3
+
+ function itemSelected(index) {
+ top.itemSelected(index);
+ }
+
+ Rectangle {
+ id: scrollbar
+ anchors.right: listView.right
+ y: listView.visibleArea.yPosition * listView.height
+ width: 5
+ height: listView.visibleArea.heightRatio * listView.height
+ color: "black"
+ visible: listView.visibleArea.heightRatio < 0.99
+ }
+
+ delegate {
+ Rectangle {
+ id: entry
+
+ color: "white"
+ border.width: 1
+ border.color: ListView.isCurrentItem ? "#c0c0c0" : "#a0a0a0"
+ width: parent.width
+ height: 60
+
+ Image {
+ id: installedCheckmark
+
+ source: "checkmark.svg"
+ height: entry.height - 15
+ width: 25
+ anchors.left: parent.left
+ anchors.top: parent.top
+ anchors.leftMargin: 5
+ anchors.topMargin: 5
+ visible: installed == 1
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {listView.itemSelected(index)}
+ }
+
+ Text {
+ anchors.top: entry.top
+ anchors.left: installedCheckmark.right
+ anchors.right: entry.right
+ width: parent.width
+ height: parent.height/2 -4
+ anchors.leftMargin: 10
+ anchors.rightMargin: 10
+ anchors.topMargin: 5
+ text: title
+ font.pointSize: btStyle.textFontPointSize
+ }
+
+ Text {
+ anchors.bottom: entry.bottom
+ anchors.left: installedCheckmark.right
+ anchors.right: entry.right
+ width: parent.width
+ height: parent.height/2 -4
+ anchors.leftMargin: 35
+ anchors.rightMargin: 10
+ anchors.topMargin: 25
+ text: desc
+ elide: Text.ElideMiddle
+ font.pointSize: btStyle.textFontPointSize
+ }
+ }
+ }
+
+ BtStyle {
+ id: btStyle
+ }
+ }
+}
+
diff --git a/src/mobile/qml/MainToolbar.qml b/src/mobile/qml/MainToolbar.qml
new file mode 100644
index 0000000..66513b2
--- /dev/null
+++ b/src/mobile/qml/MainToolbar.qml
@@ -0,0 +1,27 @@
+import QtQuick 2.1
+import BibleTime 1.0
+
+Rectangle {
+ id: toolbar
+
+ signal buttonClicked
+
+ BtStyle {
+ id: btStyle
+ }
+
+ color: btStyle.toolbarColor
+ z:0
+
+ MenuButton {
+ id: menuButton
+
+ width: parent.height
+ height: parent.height
+ anchors.right: parent.right
+ anchors.top: parent.top
+ onButtonClicked: {
+ toolbar.buttonClicked()
+ }
+ }
+}
diff --git a/src/mobile/qml/MenuButton.qml b/src/mobile/qml/MenuButton.qml
new file mode 100644
index 0000000..b3ba458
--- /dev/null
+++ b/src/mobile/qml/MenuButton.qml
@@ -0,0 +1,30 @@
+import QtQuick 2.1
+import BibleTime 1.0
+
+Rectangle {
+ id: menuButton
+
+ signal buttonClicked
+
+ color: "black"
+
+ BtStyle {
+ id: btStyle
+ }
+
+ Column {
+ spacing:3
+
+ Rectangle { color: "white"; width:2; height:2 }
+ Rectangle { color: "white"; width:2; height:2 }
+ Rectangle { color: "white"; width:2; height:2 }
+
+ anchors.centerIn: parent
+ }
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ menuButton.buttonClicked()
+ }
+ }
+}
diff --git a/src/mobile/qml/MenuView.qml b/src/mobile/qml/MenuView.qml
new file mode 100644
index 0000000..01b5142
--- /dev/null
+++ b/src/mobile/qml/MenuView.qml
@@ -0,0 +1,28 @@
+import QtQuick 2.1
+
+Column {
+ id: menus
+
+ width:120
+ height:20 * listModel.count
+ anchors.top: mainToolbar.bottom
+ anchors.right: mainToolbar.right
+ z: 100
+ visible: false
+
+ Repeater {
+ model: listModel
+ delegate: Rectangle {
+ width:parent.width
+ height:24
+ color: btStyle.menu
+ border.color: btStyle.menuBorder
+ border.width: 1
+ Text {
+ anchors.centerIn: parent
+ text: title
+ color: btStyle.menuText
+ }
+ }
+ }
+}
diff --git a/src/mobile/qml/Menus.qml b/src/mobile/qml/Menus.qml
new file mode 100644
index 0000000..1a9e53b
--- /dev/null
+++ b/src/mobile/qml/Menus.qml
@@ -0,0 +1,61 @@
+import QtQuick 2.1
+import BibleTime 1.0
+
+Rectangle {
+ id: menu
+
+ property alias model: menusRepeater.model
+ property int fontPointSize: 15
+ property int menuHeight: 70
+ property int topMenuMargin: 150
+ property int leftMenuMargin: 50
+
+ signal menuSelected(string action)
+
+ visible: false
+ anchors.fill: parent
+ color: "#f0f0f0"
+
+ BtStyle {
+ id: btStyle
+ }
+
+ Component {
+ id: eachMenu
+
+ Rectangle {
+ width: menu.width
+ height: menuHeight
+ color: "white"
+ border.color: "#f0f0f0"
+ border.width: 2
+
+ Text {
+ text: title
+ font.pointSize: btStyle.uiFontPointSize
+ color: "black"
+ anchors.fill: parent
+ anchors.leftMargin: leftMenuMargin
+ verticalAlignment: Text.AlignVCenter
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ menu.menuSelected(action);
+ }
+ }
+ }
+ }
+ }
+
+ ListView {
+ id: menusRepeater
+
+ delegate: eachMenu
+ width: parent.width
+ anchors.fill: parent
+ anchors.topMargin: topMenuMargin
+
+ }
+}
+
diff --git a/src/mobile/qml/ModuleChooser.qml b/src/mobile/qml/ModuleChooser.qml
new file mode 100644
index 0000000..49d19d1
--- /dev/null
+++ b/src/mobile/qml/ModuleChooser.qml
@@ -0,0 +1,109 @@
+import QtQuick 2.1
+import BibleTime 1.0
+
+Rectangle {
+ id: moduleChooser
+
+ property alias categoryModel: categoryView.model
+ property alias languageModel: languageView.model
+ property alias worksModel: worksView.model
+ property alias categoryIndex: categoryView.currentIndex
+ property alias languageIndex: languageView.currentIndex
+ property alias moduleIndex: worksView.currentIndex
+ property int lastCategoryIndex: 0
+ property int lastLanguageIndex: 0
+ property int spacing: 5
+ property string selectedModule: ""
+ property string selectedCategory: ""
+
+ objectName: "moduleChooser"
+ color: "lightgray"
+ border.color: "black"
+ border.width: 2
+
+ onVisibleChanged: {
+ if (visible == true) {
+ moduleInterface.updateCategoryAndLanguageModels();
+ categoryIndex = lastCategoryIndex;
+ languageIndex = lastLanguageIndex;
+ }
+ }
+
+ onCategoryIndexChanged: {
+ if (visible == true) {
+ moduleInterface.updateWorksModel();
+ }
+ }
+
+ onLanguageIndexChanged: {
+ if (visible == true) {
+ moduleInterface.updateWorksModel();
+ }
+ }
+
+ signal categoryChanged(int index);
+ signal languageChanged(int index);
+ signal moduleSelected();
+
+ ModuleInterface {
+ id: moduleInterface
+ }
+
+ Grid {
+ id: grid
+ columns: 2
+ rows: 1
+ spacing: parent.spacing
+ width: parent.width - moduleChooser.spacing
+ height: parent.height/2.5
+ anchors.left: parent.left
+ anchors.top: parent.top
+ anchors.margins: parent.spacing
+
+ ListTextView {
+ id: categoryView
+
+ title: "Category"
+ width: grid.width/2 - grid.spacing
+ height: grid.height
+ onItemSelected: {
+ categoryChanged(currentIndex)
+ }
+ }
+
+ ListTextView {
+ id: languageView
+
+ title: "Language"
+ width: grid.width/2 - grid.spacing
+ height: grid.height
+ onItemSelected: {
+ languageChanged(currentIndex);
+ }
+ }
+ }
+
+ ListTextView {
+ id: worksView
+
+ title: "Work"
+ width: parent.width - 2 * parent.spacing
+ anchors.top: grid.bottom
+ anchors.left: parent.left
+ anchors.bottom: parent.bottom
+ anchors.margins: moduleChooser.spacing
+ highlight: false
+ onItemSelected: {
+ selectedModule = moduleInterface.module(index);
+ selectedCategory = moduleInterface.category(index);
+ moduleSelected();
+ moduleChooser.visible = false;
+ }
+ }
+
+// MouseArea {
+// anchors.fill: parent
+// onClicked: moduleChooser.cancel();
+// }
+}
+
diff --git a/src/mobile/qml/Progress.qml b/src/mobile/qml/Progress.qml
new file mode 100644
index 0000000..e5f75b3
--- /dev/null
+++ b/src/mobile/qml/Progress.qml
@@ -0,0 +1,63 @@
+import QtQuick 2.1
+import QtQuick.Controls 1.0
+import QtQuick.Controls.Styles 1.0
+import BibleTime 1.0
+
+Rectangle {
+ id: installProgress
+
+ property alias minimumValue: progressBar.minimumValue
+ property alias value: progressBar.value
+ property alias maximumValue: progressBar.maximumValue
+ property alias text: label.text
+
+ color: btStyle.buttonBackground
+ border.color: "black"
+ border.width: 5
+
+ signal cancel()
+
+ BtStyle {
+ id: btStyle
+ }
+
+ Text {
+ id: label
+
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.bottom: progressBar.top
+ anchors.bottomMargin: 20
+ }
+
+ ProgressBar {
+ id: progressBar
+
+ anchors.centerIn: parent
+ width: parent.width - 100
+ height: 16
+ }
+
+ Rectangle {
+ color: "white"
+ border.color: "black"
+ border.width: 1
+ width: 100
+ height:30
+ anchors.top: progressBar.bottom
+ anchors.topMargin: 20
+ anchors.horizontalCenter: parent.horizontalCenter
+
+ Text {
+ anchors.centerIn: parent
+ text: "Cancel"
+
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ cancel();
+ }
+ }
+ }
+}
diff --git a/src/mobile/qml/Settings.qml b/src/mobile/qml/Settings.qml
new file mode 100644
index 0000000..391ce4c
--- /dev/null
+++ b/src/mobile/qml/Settings.qml
@@ -0,0 +1,93 @@
+import QtQuick 2.1
+import BibleTime 1.0
+
+Rectangle {
+ id: settings
+
+ property int finalHeight: 300
+
+ color: "white"
+ anchors.bottom: parent.bottom
+ anchors.left: parent.left
+ anchors.right: parent.right
+ height: parent.height
+
+ onVisibleChanged: PropertyAnimation {
+ target: settings
+ property: "opacity"
+ from: 0
+ to: 1
+ duration: 200
+ easing.type: Easing.InOutCubic
+ }
+
+ BtStyle {
+ id: btStyle
+ }
+
+ ListModel {
+ id: settingsModel
+
+ ListElement { title: "Ui Font Size"; action: "uiSize" }
+ ListElement { title: "Window Arrangement"; action: "arrangement" }
+ }
+
+ ListView {
+ id: settingsList
+
+ anchors.fill: parent
+ anchors.topMargin: 100
+ model: settingsModel
+
+ delegate: Rectangle {
+ color: "white"
+ border.color: "lightgray"
+ border.width: 1
+ width: parent.width
+ height: children[0].height * 2.5
+
+ Text {
+ id: menuText
+ x: 40
+ anchors.verticalCenter: parent.verticalCenter
+ text: title
+ color: "black"
+ font.pointSize: btStyle.uiFontPointSize
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ if (action == "arrangement") {
+ windowArrangementMenus.visible = true;
+ settings.visible = false;
+ }
+ else if (action == "uiSize") {
+ uiFontPointSize.visible = true;
+ settings.visible = false;
+ console.log("y")
+ }
+ }
+ }
+ }
+ }
+
+ ImageButton {
+ id: backButton
+
+ icon: "leftarrow.svg"
+ height: 36
+ width: 56
+ anchors.bottom: parent.bottom
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.bottomMargin: 8
+ visible: true
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ settings.visible = false;
+ }
+ }
+ }
+}
diff --git a/src/mobile/qml/TreeChooser.qml b/src/mobile/qml/TreeChooser.qml
new file mode 100644
index 0000000..5dc1eeb
--- /dev/null
+++ b/src/mobile/qml/TreeChooser.qml
@@ -0,0 +1,167 @@
+import QtQuick 2.1
+
+Rectangle {
+ id: treeChooser
+
+ property ListModel model: ListModel {
+ }
+ property string path: ""
+ property int pathCount: 0
+
+ color: "white"
+ border.width: 2
+ border.color: "black"
+
+ signal back()
+ signal next(string childText)
+ signal select(string childText)
+
+ Rectangle {
+ id: pathArea
+
+ border.color: "black"
+ border.width: 0
+ color: "white"
+
+ height: {20 * pathCount }
+ anchors.right: parent.right
+ anchors.left: parent.left
+ anchors.top: parent.top
+ anchors.margins: 4
+ visible: path.length > 0
+
+ function splitPath(path) {
+ var pathList = path.split("/");
+ var newPath = "";
+ var space = "";
+ var count = pathList.length;
+ treeChooser.pathCount = count;
+ // pathList[0] is empty
+ for (var i=1; i< count; ++i) {
+ var pathI = pathList[i];
+ newPath += space + pathI + "\n";
+ space += " ";
+ }
+ return newPath;
+ }
+
+ ImageButton {
+ id: backButton
+
+ icon: "leftarrow.svg"
+ height: 36
+ width: 56
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.right : parent.right
+ anchors.topMargin: 2
+ visible: true
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ treeChooser.back();
+ }
+ }
+ }
+
+ Text {
+ id: pathText
+
+ text: pathArea.splitPath(treeChooser.path)
+ font.pointSize: 12
+ height: parent.height
+// width: parent.width - backButton.width -50
+ anchors.top: parent.top
+ anchors.left: parent.left
+ anchors.right: backButton.left
+ anchors.leftMargin: 10
+ elide: Text.ElideRight
+ }
+ }
+
+ ListView {
+ id: listView
+
+ function next(index, name) {
+ treeChooser.next(name);
+ }
+
+ function select(index, name) {
+ treeChooser.select(name);
+ }
+
+ anchors.top: pathArea.bottom
+ anchors.bottom: parent.bottom
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.topMargin: 30
+ anchors.leftMargin: 4
+ anchors.rightMargin: 4
+ anchors.bottomMargin: 4
+ boundsBehavior: Flickable.StopAtBounds
+ width: pathArea.width
+ model: treeChooser.model
+ delegate:
+ Rectangle {
+ id: entry
+
+ property string action: ""
+
+
+ border.color: "#eeeeee"
+ border.width: 1
+ width: parent.width
+ height: 40
+
+ Text {
+ id: entryText
+
+ font.pointSize: 12
+// anchors.fill: entry
+ anchors.top: entry.top
+ anchors.left: entry.left
+ anchors.right: entry.right
+ width: 340
+ anchors.leftMargin: 10
+ anchors.rightMargin: 10
+ anchors.topMargin: 10
+ text: name
+ elide: Text.ElideRight
+ }
+
+ ImageButton {
+ id: imageButton
+ icon: "rightarrow.svg"
+
+ height: parent.height-4
+ width: 56
+ anchors.right: parent.right
+ anchors.top: parent.top
+ anchors.topMargin: 2
+ visible: childcount > 0
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ listView.currentIndex = index
+ listView.next(index, name)
+ }
+ }
+ }
+
+ MouseArea {
+ anchors.left: parent.left
+ anchors.right: imageButton.left
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+ onClicked: {
+ listView.currentIndex = index
+ listView.select(index, name)
+ }
+ }
+ }
+
+ snapMode: ListView.SnapToItem
+ focus: true
+ }
+}
diff --git a/src/mobile/qml/Window.qml b/src/mobile/qml/Window.qml
new file mode 100644
index 0000000..a14131f
--- /dev/null
+++ b/src/mobile/qml/Window.qml
@@ -0,0 +1,178 @@
+import QtQuick 2.1
+import BibleTime 1.0
+
+Rectangle {
+ id: windowView
+
+ property string title: toolbar.title
+
+ function setModule(module) {
+ btWindowInterface.moduleName = module;
+ }
+
+ function contextMenus() {
+// contextMenu.visible = true;
+ }
+
+ color: "black"
+
+ BtWindowInterface {
+ id: btWindowInterface
+ }
+
+ BtStyle {
+ id:btStyle
+ }
+
+ Rectangle {
+ id: toolbar
+
+ property string title: btWindowInterface.moduleName + " (" + btWindowInterface.reference + ")"
+
+ width: parent.width
+ height: 36
+ color: btStyle.toolbarColor
+ border.width: 1
+ border.color: "black"
+
+ Rectangle {
+ id: moduleDisplay
+
+ width: text.width +10
+ radius:btStyle.buttonRadius
+ anchors.left: parent.left
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+ anchors.topMargin: 4
+ anchors.leftMargin: 5
+ anchors.bottomMargin: 4
+ color: btStyle.toolbarButton
+ border.color: btStyle.buttonBorder
+ border.width: 1
+
+ Text {
+ id: text
+
+ anchors.centerIn: parent
+ anchors.leftMargin: 4
+ anchors.rightMargin: 4
+ font.pointSize: btStyle.uiFontPointSize
+ elide: Text.ElideMiddle
+ color: btStyle.toolbarButtonText
+ text: btWindowInterface.moduleName
+ }
+
+ MouseArea {
+ id: moduleMouseArea
+
+ anchors.fill: parent
+ onClicked: {
+ btWindowInterface.changeModule();
+ }
+ }
+ }
+
+
+ Rectangle {
+ id: referenceDisplay
+
+ width: {
+ var w1 = 300
+ var w2 = toolbar.width - moduleDisplay.width;
+ var w = Math.min(w1,w2);
+ return w - 15;
+ }
+ radius: btStyle.buttonRadius
+ anchors.left: moduleDisplay.right
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+ anchors.topMargin: 4
+ anchors.bottomMargin: 4
+ anchors.leftMargin: 5
+ color: btStyle.toolbarButton
+ border.color: btStyle.buttonBorder
+ border.width: 1
+
+ Text {
+ id: referenceText
+ anchors.centerIn: parent
+ anchors.leftMargin: 6
+ anchors.rightMargin: 4
+ width: referenceDisplay.width - 4
+ font.pointSize: btStyle.uiFontPointSize
+ elide: Text.ElideMiddle
+ color: btStyle.toolbarButtonText
+ text: btWindowInterface.reference
+ }
+
+ MouseArea {
+ id: mouseArea
+
+ anchors.fill: parent
+ onClicked: {
+ btWindowInterface.changeReference();
+ }
+ }
+ }
+
+ }
+
+ Rectangle {
+ id: mainTextView
+
+ color: "white"
+ anchors.top: toolbar.bottom
+ anchors.left: windowView.left
+ anchors.right: windowView.right
+ anchors.bottom: windowView.bottom
+
+ ListView {
+ id: listView
+
+ clip: true
+ anchors.fill: parent
+ anchors.leftMargin: 8
+ anchors.rightMargin: 8
+ model: btWindowInterface.textModel
+ currentIndex: btWindowInterface.currentModelIndex
+ delegate: Text {
+ text: "<font color=\"blue\">" + ref + "</font> " + line
+ width: parent.width
+ color: "black"
+ font.pointSize: btStyle.textFontPointSize
+ wrapMode: Text.WordWrap
+ }
+
+ MouseArea {
+
+ anchors.fill: parent
+ onDoubleClicked: {
+ windowView.contextMenus();
+ }
+
+ onPressAndHold: {
+ windowView.contextMenus();
+
+ }
+ }
+ }
+ }
+
+ ListModel {
+ id: contextMenuModel
+
+ ListElement { title: "Text Font Size"; action: "textSize" }
+ }
+
+ ContextMenu {
+ id: contextMenu
+
+ function doAction(action) {
+ }
+
+ model: contextMenuModel
+ visible: false
+ Component.onCompleted: contextMenu.accepted.connect(contextMenu.doAction)
+ }
+
+}
diff --git a/src/mobile/qml/WindowManager.qml b/src/mobile/qml/WindowManager.qml
new file mode 100644
index 0000000..3a66219
--- /dev/null
+++ b/src/mobile/qml/WindowManager.qml
@@ -0,0 +1,291 @@
+import QtQuick 2.1
+import BibleTime 1.0
+
+
+Rectangle {
+ id: windowArea
+
+ property var windows: []
+ property int single: 0
+ property int tabLayout: 1
+ property int autoTile: 2
+ property int autoTileHor: 3
+ property int autoTileVer: 4
+ property int windowLayout: single
+
+ function setCurrentTabbedWindow(index) {
+ tabbedWindows.current = index;
+ }
+
+ function setWindowArrangement(arrangement) {
+ if (arrangement < single || arrangement > autoTileVer)
+ return;
+ windowLayout = arrangement;
+ layoutWindows();
+ }
+
+ function createWindowMenus() {
+ windowsModel.clear();
+ for (var i=0; i<windows.length; ++i) {
+ var window = windows[i];
+ windowsModel.append (
+ { title: window.title, action: i.toString() }
+ )
+ }
+ windowTitlesMenus.model = windowsModel
+ windowTitlesMenus.visible = true;
+ }
+
+
+ function newWindow() {
+ moduleChooser.moduleSelected.connect(openWindowSlot);
+ moduleChooser.visible = true;
+ }
+
+ function openWindowSlot() {
+ moduleChooser.moduleSelected.disconnect(openWindowSlot);
+ openWindow(moduleChooser.selectedCategory, moduleChooser.selectedModule)
+ }
+
+ function openWindow(category, module) {
+ if (category == "Bibles")
+ component = Qt.createComponent("Window.qml");
+ else if (category == "Commentaries")
+ component = Qt.createComponent("Window.qml");
+ else if (category == "Books")
+ component = Qt.createComponent("Window.qml");
+ else {
+ console.log(category, " are not yet supported.");
+ return;
+ }
+
+ window = component.createObject(null, {"width": 250, "height": 200});
+ window.setModule(module);
+
+ if (window == null) {
+ // Error Handling
+ console.log("Error creating object");
+ }
+ else {
+ windows.push(window)
+ layoutWindows();
+ var curWindow = windows.length -1;
+ selectWindow(curWindow);
+ }
+ }
+
+ function layoutTiles(rows, columns)
+ {
+ gridWindows.columns = columns;
+ gridWindows.rows = rows;
+ var width = gridWindows.width/columns -2;
+ var height = gridWindows.height/rows -2;
+
+ for (var i=0; i<windows.length; ++i) {
+ var window = windows[i];
+ window.anchors.fill = undefined
+ window.height = height;
+ window.width = width;
+ window.parent = gridWindows;
+ }
+ }
+
+ function arrangeSingleWindow() {
+ tabbedWindows.z = 1;
+ tabbedWindows.tabVisible = false;
+ for (var i=0; i<windows.length; ++i) {
+ var window = windows[i];
+ window.parent = tabbedWindowsStack;
+ window.anchors.fill = tabbedWindowsStack
+ }
+ }
+
+ function arrangeTabbedWindows() {
+ tabbedWindows.z = 1;
+ tabbedWindows.tabVisible = true;
+ for (var i=0; i<windows.length; ++i) {
+ var window = windows[i];
+ window.parent = tabbedWindowsStack;
+ window.anchors.fill = tabbedWindowsStack
+ }
+ }
+
+ function arrangeTiledWindows() {
+ gridWindows.z = 1;
+ var columns = 1;
+ var rows = 1;
+ var count = windows.length;
+
+ if (windowLayout == autoTile) {
+ if (count > 1) {
+ columns = 2
+ rows = Math.floor((count+1)/2);
+ }
+ }
+ else if (windowLayout == autoTileHor)
+ {
+ rows = count;
+ }
+ else if (windowLayout == autoTileVer)
+ {
+ columns = count;
+ }
+ layoutTiles(rows, columns);
+ }
+
+ function layoutWindows() {
+ tabbedWindows.z = -2;
+ gridWindows.z = -3;
+
+ if (windowLayout == single) {
+ arrangeSingleWindow();
+ }
+ else if (windowLayout == tabLayout) {
+ arrangeTabbedWindows();
+ }
+ else {
+ arrangeTiledWindows();
+ }
+ }
+
+ function selectWindow(n) {
+ if (windowLayout == tabLayout || windowLayout == single) {
+ tabbedWindows.current = n;
+ }
+ }
+
+// anchors.top: spacer.bottom
+// anchors.left: parent.left
+// anchors.right: parent.right
+// anchors.bottom: parent.bottom
+// color: "#646464"
+
+ Grid {
+ id: gridWindows
+
+ objectName: "gridWindows"
+ anchors.fill: parent
+ columns: 2
+ spacing: 2
+ z: 2
+ }
+
+ Item {
+ id: tabbedWindows
+
+ default property alias content: tabbedWindowsStack.children
+ property bool tabVisible: true
+ property int current: 0
+
+ function changeTabs() {
+ setOpacities();
+ }
+
+ function setOpacities() {
+ for (var i = 0; i < tabbedWindowsStack.children.length; ++i) {
+ tabbedWindowsStack.children[i].z = (i == current ? 1 : 0)
+ }
+ }
+
+ objectName: "tabbedWindows"
+ anchors.fill: parent
+ onCurrentChanged: changeTabs()
+ Component.onCompleted: changeTabs()
+
+ Row {
+ id: header
+
+ objectName: "header"
+
+ Repeater {
+ id: tabRepeater
+
+ function setColors() {
+ if (tabbedWindows.current == tabbedWindowsStack.index) {
+ tabImage.color = btStyle.windowTabSelected
+ tabText.color = btStyle.windowTabTextSelected
+ }
+ else {
+ tabImage.color = btStyle.windowTab
+ tabText.color = btStyle.windowTabText
+ }
+ }
+
+ model: tabbedWindowsStack.children.length
+ delegate: Rectangle {
+ id: tab
+
+ function calculateTabWidth() {
+ var tabWidth = (tabbedWindows.width) / tabbedWindowsStack.children.length;
+ return tabWidth;
+ }
+
+ visible: tabbedWindows.tabVisible
+ //width: (tabbedWindows.width) / tabbedWindowsStack.children.length;
+ width: {
+ calculateTabWidth()
+ }
+ height: 36
+
+ Rectangle {
+ id: tabBorder
+ width: parent.width; height: 1
+ anchors { bottom: parent.bottom; bottomMargin: 1 }
+ color: "#acb2c2"
+ }
+
+ Rectangle {
+ id: tabImage
+
+ anchors { fill: parent; leftMargin: 8; topMargin: 4; rightMargin: 8 }
+ color: {
+ if (tabbedWindows.current == index)
+ return btStyle.windowTabSelected
+ else
+ return btStyle.windowTab
+ }
+ border.color: btStyle.windowTab
+ border.width: 2
+
+ Text {
+ id: tabText
+
+ horizontalAlignment: Qt.AlignHCenter;
+ verticalAlignment: Qt.AlignVCenter
+ anchors.fill: parent
+ anchors.topMargin: 6
+ font.pointSize: btStyle.uiFontPointSize -3
+ text: tabbedWindowsStack.children[index].title
+ elide: Text.ElideLeft
+ color: {
+ if (tabbedWindows.current == index)
+ return btStyle.windowTabTextSelected
+ else
+ return btStyle.windowTabText
+ }
+ }
+ }
+
+ MouseArea {
+ id: tabMouseArea
+
+ anchors.fill: parent
+ onClicked: {
+ tabbedWindows.current = index
+ }
+ }
+ }
+ }
+ }
+
+ Item {
+ id: tabbedWindowsStack
+
+ objectName: "tabbedWindowsStack"
+ width: parent.width
+ anchors.top: header.bottom;
+ anchors.bottom: tabbedWindows.bottom
+ }
+ }
+
+}
diff --git a/src/mobile/qml/checkmark.svg b/src/mobile/qml/checkmark.svg
new file mode 100644
index 0000000..07a3ad8
--- /dev/null
+++ b/src/mobile/qml/checkmark.svg
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="450" height="400" viewBox="85 145 450 400"
+ sodipodi:version="0.32"
+ inkscape:version="0.45"
+ sodipodi:docname="checkmark.svg">
+ <metadata>
+ <rdf:RDF>
+ <cc:Work rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <path
+ style="fill:#5fd35f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 508.74477,226.99015 C 459.42189,193.17234 436.08559,163.59563 436.08559,163.59563 C 344.99984,217.26626 248.26757,407.83719 248.26757,407.83719 C 202.93454,344.01939 157.35384,326.21932 157.35384,326.21932 C 136.86236,353.60112 101.54091,390.09316 101.54091,390.09316 C 183.924,412.28062 253.07323,493.70015 253.07323,493.70015 C 402.5571,259.01322 508.74477,226.99015 508.74477,226.99015 z "
+ sodipodi:nodetypes="ccccccc" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.2;fill:#999999;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0"
+ sodipodi:cx="238.57143"
+ sodipodi:cy="529.50507"
+ sodipodi:rx="64.285713"
+ sodipodi:ry="7.1428571"
+ d="M 302.03011,528.36301 A 64.285713,7.1428571 0 1 1 301.97855,528.32818"
+ sodipodi:start="6.1226078"
+ sodipodi:end="12.400852"
+ sodipodi:open="true"
+ transform="translate(8.5714285,-11.428571)" />
+ <path
+ style="opacity:0.27777782;fill:#5fd35f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 518.74479,227.27587 C 469.42191,193.45806 446.08561,163.88135 446.08561,163.88135 C 354.99986,217.55198 258.26759,408.12291 258.26759,408.12291 C 212.93456,344.30511 167.35386,326.50504 167.35386,326.50504 C 146.86238,353.88684 111.54093,390.37888 111.54093,390.37888 C 193.92402,412.56634 263.07325,493.98587 263.07325,493.98587 C 412.55712,259.29894 518.74479,227.27587 518.74479,227.27587 z "
+ sodipodi:nodetypes="ccccccc" />
+</svg>
diff --git a/src/mobile/qml/leftarrow.svg b/src/mobile/qml/leftarrow.svg
new file mode 100644
index 0000000..6143c87
--- /dev/null
+++ b/src/mobile/qml/leftarrow.svg
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="900"
+ height="900"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.4 r9939"
+ sodipodi:docname="rightarrow.svg">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="0.74333333"
+ inkscape:cx="450"
+ inkscape:cy="450"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ units="in"
+ inkscape:window-width="1600"
+ inkscape:window-height="868"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1">
+ <inkscape:grid
+ type="xygrid"
+ id="grid2985"
+ empspacing="5"
+ visible="true"
+ enabled="true"
+ snapvisiblegridlinesonly="true" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-152.3622)">
+ <path
+ sodipodi:type="star"
+ style="fill:#4d4d4d;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ id="path2995"
+ sodipodi:sides="3"
+ sodipodi:cx="460"
+ sodipodi:cy="420"
+ sodipodi:r1="380.52594"
+ sodipodi:r2="190.26299"
+ sodipodi:arg1="0"
+ sodipodi:arg2="1.0471976"
+ inkscape:flatsided="true"
+ inkscape:rounded="0"
+ inkscape:randomized="0"
+ d="m 840.52594,420 -570.78891,329.54513 0,-659.090261 z"
+ transform="matrix(-1,0,0,-1,1014.9543,1026.7074)"
+ inkscape:transform-center-y="-2.9985352e-05"
+ inkscape:transform-center-x="95.131485" />
+ </g>
+</svg>
diff --git a/src/mobile/qml/main.qml b/src/mobile/qml/main.qml
new file mode 100644
index 0000000..d7597b1
--- /dev/null
+++ b/src/mobile/qml/main.qml
@@ -0,0 +1,270 @@
+import QtQuick 2.1
+import BibleTime 1.0
+
+Rectangle {
+ id: root
+
+ property int opacitypopup: 0
+ property QtObject component: null;
+ property Item window: null;
+
+ ListModel {
+ id: windowsModel
+
+ ListElement { title: ""; action: "" }
+ }
+
+ function installModules() {
+ installManager.openChooser();
+ }
+
+// width: 1280 // Nexus 7 (2012)
+// height: 800
+
+ width: 480 // Phone
+ height: 800
+
+ rotation: 0
+
+ MainToolbar {
+ id: mainToolbar
+
+ anchors.left: parent.left
+ anchors.top: parent.top
+ anchors.right: parent.right
+ height: 30
+ onButtonClicked: {
+ mainMenus.visible = ! mainMenus.visible;
+ }
+ }
+
+ Rectangle {
+ id: spacer
+
+ anchors.top: mainToolbar.bottom
+ height:2
+ width: parent.width
+ color: "#646464"
+ }
+
+ WindowManager {
+ id: windowManager
+
+ anchors.top: spacer.bottom
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.bottom: parent.bottom
+ color: "#646464"
+
+ }
+
+ Settings {
+ id: settings
+
+ visible: false;
+ }
+
+ GridChooser {
+ id: gridChooser
+
+ objectName: "gridChooser"
+ width: parent.width
+ height: parent.height
+ visible: false
+ }
+
+ BtStyle {
+ id: btStyle
+ }
+
+ ModuleChooser {
+ id: moduleChooser
+
+ objectName: "moduleChooser"
+ visible: false
+ width: Math.min(parent.height, parent.width);
+ height: parent.height
+ anchors.centerIn: parent
+ }
+
+ TreeChooser {
+ id: treeChooser
+
+ objectName: "treeChooser"
+ width:480
+ height: parent.height
+ anchors.top: parent.top
+ anchors.horizontalCenter: parent.horizontalCenter
+ path: ""
+ visible: false
+ z: 100
+ }
+
+ InstallManager {
+ id: installManager
+ }
+
+ InstallManagerChooser {
+ id: installManagerChooser
+
+ objectName: "installManagerChooser"
+ width: Math.min(parent.height, parent.width);
+ height: parent.height
+ anchors.centerIn: parent
+ anchors.top: parent.top
+ visible: false
+ }
+
+ Progress {
+ id: progress
+
+ objectName: "progress"
+ value: 0.25
+ minimumValue: 0
+ maximumValue: 1
+ width:550
+ height: 200
+ anchors.centerIn: parent
+ anchors.top: parent.top
+ visible: false
+ }
+
+ ListModel {
+ id: mainMenusModel
+
+ ListElement { title: QT_TR_NOOP("New Window"); action: "newWindow" }
+ ListElement { title: QT_TR_NOOP("View Window"); action: "windows" }
+ ListElement { title: QT_TR_NOOP("Text Font Size"); action: "textFontSize"}
+ ListElement { title: QT_TR_NOOP("User Interface Font Size");action: "uiFontSize"}
+
+ //ListElement { title: QT_TR_NOOP("Settings"); action: "settings" }
+ ListElement { title: QT_TR_NOOP("Bookshelf Manager"); action: "install" }
+ // ListElement { title: QT_TR_NOOP("Gnome Style"); action: "gnomeStyle" }
+ // ListElement { title: QT_TR_NOOP("Android Style"); action: "androidStyle" }
+ }
+
+ Menus {
+ id: mainMenus
+
+ Component.onCompleted: menuSelected.connect(mainMenus.doAction)
+
+ function doAction(action) {
+ mainMenus.visible = false;
+ if (action == "newWindow") {
+ windowManager.newWindow();
+ }
+ else if (action == "windows") {
+ windowManager.createWindowMenus();
+ }
+ else if (action == "gnomeStyle") {
+ btStyle.setStyle(1)
+ }
+ else if (action == "androidStyle") {
+ btStyle.setStyle(2)
+ }
+ else if (action == "install") {
+ installModules();
+ }
+ else if (action == "settings") {
+ settings.visible = true;
+ }
+ else if (action == "textFontSize") {
+ textFontPointSize.visible = true;
+ }
+ else if (action == "uiFontSize") {
+ uiFontPointSize.visible = true;
+ }
+
+ }
+
+ model: mainMenusModel
+ topMenuMargin: 100
+ }
+
+ ListModel {
+ id: windowArrangementModel
+
+ ListElement { title: QT_TR_NOOP("Single"); action: "single" }
+ ListElement { title: QT_TR_NOOP("Tabbed"); action: "tabbed" }
+ ListElement { title: QT_TR_NOOP("Auto-tile"); action: "autoTile" }
+ ListElement { title: QT_TR_NOOP("Auto-tile horizontally"); action: "autoTileHor" }
+ ListElement { title: QT_TR_NOOP("Auto-tile vertically"); action: "autoTileVer" }
+ }
+
+ Menus {
+ id: windowArrangementMenus
+
+ Component.onCompleted: menuSelected.connect(windowArrangementMenus.doAction)
+
+ function doAction(action) {
+ windowArrangementMenus.visible = false;
+ if (action == "single") {
+ windowManager.setWindowArrangement(windowManager.single);
+ }
+ else if (action == "tabbed") {
+ windowManager.setWindowArrangement(windowManager.tabLayout);
+ }
+ else if (action == "autoTile") {
+ windowManager.setWindowArrangement(windowManager.autoTile);
+ }
+ else if (action == "autoTileHor") {
+ windowManager.setWindowArrangement(windowManager.autoTileHor);
+ }
+ else if (action == "autoTileVer") {
+ windowManager.setWindowArrangement(windowManager.autoTileVer);
+ }
+ }
+
+ model: windowArrangementModel
+ }
+
+ Menus {
+ id: windowTitlesMenus
+
+ model: windowsModel
+ visible: false
+ Component.onCompleted: menuSelected.connect(windowTitlesMenus.doAction)
+
+ function doAction(action) {
+ windowTitlesMenus.visible = false;
+ var index = Number(action)
+ windowManager.setCurrentTabbedWindow(index);
+ }
+ }
+
+ FontSizeSlider {
+ id: uiFontPointSize
+ visible: false
+ title: "User Interface Font Size"
+
+ onVisibleChanged: {
+ if (visible)
+ {
+ uiFontPointSize.current = btStyle.uiFontPointSize;
+ uiFontPointSize.previous = btStyle.uiFontPointSize;
+ }
+ }
+
+ onAccepted: {
+ btStyle.uiFontPointSize = pointSize
+ }
+ }
+
+ FontSizeSlider {
+ id: textFontPointSize
+ visible: false
+ title: "Text Font Size"
+
+ onVisibleChanged: {
+ if (visible)
+ {
+ textFontPointSize.current = btStyle.textFontPointSize;
+ textFontPointSize.previous = btStyle.textFontPointSize;
+ }
+ }
+
+ onAccepted: {
+ btStyle.textFontPointSize = pointSize;
+ }
+ }
+}
diff --git a/src/mobile/qml/rightarrow.svg b/src/mobile/qml/rightarrow.svg
new file mode 100644
index 0000000..e9fd5d1
--- /dev/null
+++ b/src/mobile/qml/rightarrow.svg
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="900"
+ height="900"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.4 r9939"
+ sodipodi:docname="New document 1">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="0.49497475"
+ inkscape:cx="21.09998"
+ inkscape:cy="433.47351"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ units="in"
+ inkscape:window-width="1600"
+ inkscape:window-height="868"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1">
+ <inkscape:grid
+ type="xygrid"
+ id="grid2985"
+ empspacing="5"
+ visible="true"
+ enabled="true"
+ snapvisiblegridlinesonly="true" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-152.3622)">
+ <path
+ sodipodi:type="star"
+ style="fill:#4d4d4d;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
+ id="path2995"
+ sodipodi:sides="3"
+ sodipodi:cx="460"
+ sodipodi:cy="420"
+ sodipodi:r1="380.52594"
+ sodipodi:r2="190.26299"
+ sodipodi:arg1="0"
+ sodipodi:arg2="1.0471976"
+ inkscape:flatsided="true"
+ inkscape:rounded="0"
+ inkscape:randomized="0"
+ d="m 840.52594,420 -570.78891,329.54513 0,-659.090261 z"
+ transform="translate(-101.01525,164.48403)"
+ inkscape:transform-center-x="-95.131488" />
+ </g>
+</svg>
diff --git a/src/mobile/qml/tab.png b/src/mobile/qml/tab.png
new file mode 100644
index 0000000..ad80216
--- /dev/null
+++ b/src/mobile/qml/tab.png
Binary files differ
diff --git a/src/mobile/ui/btstyle.cpp b/src/mobile/ui/btstyle.cpp
new file mode 100644
index 0000000..ee22d15
--- /dev/null
+++ b/src/mobile/ui/btstyle.cpp
@@ -0,0 +1,334 @@
+
+#include "btstyle.h"
+#include <QList>
+#include <QPointer>
+#include "backend/config/btconfig.h"
+
+// BtStyle is a class that is registered at a QML item. It can be placed into
+// QML files and its properties are available to be used in QML. It contains
+// colors, sizes, etc. that affect the look of the UI. You can have multipe
+// instances of the item. Changing a property on one of them changes all of them
+/*
+ import BibleTime 1.0
+
+ BtStyle {
+ id: btStyle
+ }
+
+ Rectangle {
+ color: btStyle.button
+ }
+*/
+
+namespace btm {
+
+// Only one copy of properties so they are the same everywhere used.
+static QColor buttonColor = QColor();
+static QColor buttonBackground = QColor();
+static QColor buttonTextColor = QColor();
+static QColor buttonHighlightedText = QColor();
+static QColor buttonBorder = QColor();
+static int buttonRadius = 0;
+static QColor buttonGradient0;
+static QColor buttonGradient1;
+static QColor buttonGradient2;
+static QColor buttonGradient3;
+
+static QColor windowTab = QColor();
+static QColor windowTabSelected = QColor();
+static QColor windowTabText = QColor();
+static QColor windowTabTextSelected = QColor();
+
+static QColor menu = QColor();
+static QColor menuBorder = QColor();
+static QColor menuText = QColor();
+static int menuHeight = 0;
+
+static QColor toolbarColor = QColor();
+static QColor toolbarButton = QColor();
+static QColor toolbarButtonText = QColor();
+static double toolbarTextPointSize = 6;
+
+
+static QList<QPointer<BtStyle> > styles;
+
+static void emitChanged() {
+ for (int i=0; i<styles.count(); ++i) {
+ QPointer<BtStyle> style = styles.at(i);
+ if (style != 0)
+ style->changed();
+ }
+}
+
+void BtStyle::setStyle(int style) {
+ if (style == BtStyle::gnome) {
+ setButtonColor(QColor(0,0,0));
+ setButtonBackground(QColor(237, 237, 237));
+ setButtonTextColor(QColor(0,0,0));
+ setButtonHighlightedText(QColor(0,0,255));
+ setButtonBorder(QColor(80,80,0));
+ setButtonRadius(3);
+ setButtonGradient0(QColor(200,200,200));
+ setButtonGradient1(QColor(246,246,246));
+ setButtonGradient2(QColor(246,246,246));
+ setButtonGradient3(QColor(200,200,200));
+
+ setWindowTab(QColor(206,206,206));
+ setWindowTabSelected(QColor(255,255,255));
+ setWindowTabText(QColor(0,0,0));
+ setWindowTabTextSelected(QColor(0,0,0));
+
+ setMenu(QColor(255,255,255));
+ setMenuBorder(QColor(255,255,255));
+ setMenuText(QColor(0,0,0));
+ setMenuHeight(40);
+
+ setToolbarColor(QColor(237,237,237));
+ setToolbarButton(QColor(237,237,237));
+ setToolbarButtonText(QColor(0,0,0));
+ setToolbarTextPointSize(10);
+ }
+ else if (style == BtStyle::android) {
+ setButtonColor(QColor(0,0,0));
+ setButtonBackground(QColor(35,35,100));
+ setButtonTextColor(QColor(255,210,0));
+ setButtonHighlightedText(QColor(255,255,0));
+ setButtonBorder(QColor(80,80,0));
+ setButtonRadius(3);
+ setButtonGradient0(QColor(125,125,125));
+ setButtonGradient1(QColor(60,60,60));
+ setButtonGradient2(QColor(50,50,50));
+ setButtonGradient3(QColor(20,20,20));
+
+ setWindowTab(QColor(100,100,100));
+ setWindowTabSelected(QColor(255,255,255));
+ setWindowTabText(QColor(255,255,255));
+ setWindowTabTextSelected(QColor(0,0,0));
+
+ setMenu(QColor(255,255,255));
+ setMenuBorder(QColor(224,224,224));
+ setMenuText(QColor(0,0,0));
+ setMenuHeight(34);
+
+ setToolbarColor(QColor(120,120,120));
+ setToolbarButton(QColor(255,210,0));
+ setToolbarButtonText(QColor(0,0,0));
+ setToolbarTextPointSize(10);
+ }
+
+ emitChanged();
+}
+
+BtStyle::BtStyle(QObject* parent)
+ : QObject(parent) {
+ styles.append(this);
+}
+
+QColor BtStyle::getButtonColor() const {
+ return buttonColor;
+}
+void BtStyle::setButtonColor(const QColor& color) {
+ buttonColor = color;
+ emitChanged();
+}
+
+
+QColor BtStyle::getButtonBackground() const {
+ return buttonBackground;
+}
+void BtStyle::setButtonBackground(const QColor& color) {
+ buttonBackground = color;
+ emitChanged();
+}
+
+
+QColor BtStyle::getButtonTextColor() const {
+ return buttonTextColor;
+}
+void BtStyle::setButtonTextColor(const QColor& color) {
+ buttonTextColor = color;
+ emitChanged();
+}
+
+
+QColor BtStyle::getButtonHighlightedText() const {
+ return buttonHighlightedText;
+}
+void BtStyle::setButtonHighlightedText(const QColor& color) {
+ buttonHighlightedText = color;
+ emitChanged();
+}
+
+
+QColor BtStyle::getButtonBorder() const {
+ return buttonBorder;
+}
+void BtStyle::setButtonBorder(const QColor& color) {
+ buttonBorder = color;
+ emitChanged();
+}
+
+int BtStyle::getButtonRadius() const {
+ return buttonRadius;
+}
+void BtStyle::setButtonRadius(int radius) {
+ buttonRadius = radius;
+ emitChanged();
+}
+
+QColor BtStyle::getButtonGradient0() const {
+ return buttonGradient0;
+}
+void BtStyle::setButtonGradient0(const QColor& color) {
+ buttonGradient0 = color;
+ emitChanged();
+}
+
+QColor BtStyle::getButtonGradient1() const {
+ return buttonGradient1;
+}
+void BtStyle::setButtonGradient1(const QColor& color) {
+ buttonGradient1 = color;
+ emitChanged();
+}
+
+QColor BtStyle::getButtonGradient2() const {
+ return buttonGradient2;
+}
+void BtStyle::setButtonGradient2(const QColor& color) {
+ buttonGradient2 = color;
+ emitChanged();
+}
+
+QColor BtStyle::getButtonGradient3() const {
+ return buttonGradient3;
+}
+void BtStyle::setButtonGradient3(const QColor& color) {
+ buttonGradient3 = color;
+ emitChanged();
+}
+
+QColor BtStyle::getWindowTab() const {
+ return windowTab;
+}
+
+void BtStyle::setWindowTab(const QColor& color) {
+ windowTab = color;
+ emitChanged();
+}
+
+QColor BtStyle::getWindowTabSelected() const {
+ return windowTabSelected;
+}
+
+void BtStyle::setWindowTabSelected(const QColor& color) {
+ windowTabSelected = color;
+ emitChanged();
+}
+
+QColor BtStyle::getWindowTabText() const {
+ return windowTabText;
+}
+
+void BtStyle::setWindowTabText(const QColor& color) {
+ windowTabText = color;
+ emitChanged();
+}
+
+QColor BtStyle::getWindowTabTextSelected() const {
+ return windowTabTextSelected;
+}
+
+void BtStyle::setWindowTabTextSelected(const QColor& color) {
+ windowTabTextSelected = color;
+ emitChanged();
+}
+
+QColor BtStyle::getMenu() const {
+ return menu;
+}
+
+void BtStyle::setMenu(const QColor& color) {
+ menu = color;
+ emitChanged();
+}
+
+QColor BtStyle::getMenuBorder() const {
+ return menuBorder;
+}
+
+void BtStyle::setMenuBorder(const QColor& color) {
+ menuBorder = color;
+ emitChanged();
+}
+
+QColor BtStyle::getMenuText() const {
+ return menuText;
+}
+
+void BtStyle::setMenuText(const QColor& color) {
+ menuText = color;
+ emitChanged();
+}
+
+int BtStyle::getMenuHeight() const {
+ return menuHeight;
+}
+void BtStyle::setMenuHeight(int height) {
+ menuHeight = height;
+ emitChanged();
+}
+
+QColor BtStyle::getToolbarColor() const {
+ return toolbarColor;
+}
+void BtStyle::setToolbarColor(const QColor& color) {
+ toolbarColor = color;
+ emitChanged();
+}
+
+QColor BtStyle::getToolbarButton() const {
+ return toolbarButton;
+}
+void BtStyle::setToolbarButton(const QColor& color) {
+ toolbarButton = color;
+ emitChanged();
+}
+
+QColor BtStyle::getToolbarButtonText() const {
+ return toolbarButtonText;
+}
+void BtStyle::setToolbarButtonText(const QColor& color) {
+ toolbarButtonText = color;
+ emitChanged();
+}
+
+double BtStyle::getToolbarTextPointSize() const {
+ return toolbarTextPointSize;
+}
+
+void BtStyle::setToolbarTextPointSize(double pointSize) {
+ toolbarTextPointSize = pointSize;
+ emitChanged();
+}
+
+double BtStyle::getTextFontPointSize() const {
+ return btConfig().value<int>("ui/textFontSize",14);
+}
+
+void BtStyle::setTextFontPointSize(double pointSize) {
+ btConfig().setValue<int>("ui/textFontSize", pointSize);
+ emitChanged();
+}
+
+double BtStyle::getUiFontPointSize() const {
+ return btConfig().value<int>("ui/uiFontSize",14);
+}
+
+void BtStyle::setUiFontPointSize(double pointSize) {
+ btConfig().setValue<int>("ui/uiFontSize", pointSize);
+ emitChanged();
+}
+
+} // end namespace
+
diff --git a/src/mobile/ui/btstyle.h b/src/mobile/ui/btstyle.h
new file mode 100644
index 0000000..7f65c22
--- /dev/null
+++ b/src/mobile/ui/btstyle.h
@@ -0,0 +1,132 @@
+#ifndef BT_STYLE_H
+#define BT_STYLE_H
+
+#include <QObject>
+#include <QColor>
+
+namespace btm {
+
+class BtStyle : public QObject {
+ Q_OBJECT
+
+ Q_PROPERTY(QColor buttonColor READ getButtonColor NOTIFY changed)
+ Q_PROPERTY(QColor buttonBackground READ getButtonBackground NOTIFY changed)
+ Q_PROPERTY(QColor buttonTextColor READ getButtonTextColor NOTIFY changed)
+ Q_PROPERTY(QColor buttonHighlightedText READ getButtonHighlightedText NOTIFY changed)
+ Q_PROPERTY(QColor buttonBorder READ getButtonBorder NOTIFY changed)
+ Q_PROPERTY(int buttonRadius READ getButtonRadius NOTIFY changed)
+
+ Q_PROPERTY(QColor buttonGradient0 READ getButtonGradient0 NOTIFY changed)
+ Q_PROPERTY(QColor buttonGradient1 READ getButtonGradient1 NOTIFY changed)
+ Q_PROPERTY(QColor buttonGradient2 READ getButtonGradient2 NOTIFY changed)
+ Q_PROPERTY(QColor buttonGradient3 READ getButtonGradient3 NOTIFY changed)
+
+
+ Q_PROPERTY(QColor windowTab READ getWindowTab NOTIFY changed)
+ Q_PROPERTY(QColor windowTabSelected READ getWindowTabSelected NOTIFY changed)
+ Q_PROPERTY(QColor windowTabText READ getWindowTabText NOTIFY changed)
+ Q_PROPERTY(QColor windowTabTextSelected READ getWindowTabTextSelected NOTIFY changed)
+
+ Q_PROPERTY(QColor menu READ getMenu NOTIFY changed)
+ Q_PROPERTY(QColor menuBorder READ getMenuBorder NOTIFY changed)
+ Q_PROPERTY(QColor menuText READ getMenuText NOTIFY changed)
+ Q_PROPERTY(int menuHeight READ getMenuHeight() NOTIFY changed)
+
+ Q_PROPERTY(QColor toolbarColor READ getToolbarColor NOTIFY changed)
+ Q_PROPERTY(QColor toolbarButton READ getToolbarButton NOTIFY changed)
+ Q_PROPERTY(QColor toolbarButtonText READ getToolbarButtonText NOTIFY changed)
+ Q_PROPERTY(double toolbarTextPointSize READ getToolbarTextPointSize NOTIFY changed);
+
+ Q_PROPERTY(double textFontPointSize READ getTextFontPointSize WRITE setTextFontPointSize NOTIFY changed);
+ Q_PROPERTY(double uiFontPointSize READ getUiFontPointSize WRITE setUiFontPointSize NOTIFY changed);
+
+public:
+ Q_INVOKABLE void setStyle(int style);
+
+ enum Style {
+ gnome = 1,
+ android = 2
+ };
+
+
+ BtStyle(QObject *parent = 0);
+
+ QColor getButtonColor() const;
+ void setButtonColor(const QColor& color);
+
+ QColor getButtonBackground() const;
+ void setButtonBackground(const QColor& color);
+
+ QColor getButtonTextColor() const;
+ void setButtonTextColor(const QColor& color);
+
+ QColor getButtonHighlightedText() const;
+ void setButtonHighlightedText(const QColor& color);
+
+ QColor getButtonBorder() const;
+ void setButtonBorder(const QColor& color);
+
+ int getButtonRadius() const;
+ void setButtonRadius(int radius);
+
+ QColor getButtonGradient0() const;
+ void setButtonGradient0(const QColor& color);
+
+ QColor getButtonGradient1() const;
+ void setButtonGradient1(const QColor& color);
+
+ QColor getButtonGradient2() const;
+ void setButtonGradient2(const QColor& color);
+
+ QColor getButtonGradient3() const;
+ void setButtonGradient3(const QColor& color);
+
+ QColor getWindowTab() const;
+ void setWindowTab(const QColor& color);
+
+ QColor getWindowTabSelected() const;
+ void setWindowTabSelected(const QColor& color);
+
+ QColor getWindowTabText() const;
+ void setWindowTabText(const QColor& color);
+
+ QColor getWindowTabTextSelected() const;
+ void setWindowTabTextSelected(const QColor& color);
+
+ QColor getMenu() const;
+ void setMenu(const QColor& color);
+
+ QColor getMenuBorder() const;
+ void setMenuBorder(const QColor& color);
+
+ QColor getMenuText() const;
+ void setMenuText(const QColor& color);
+
+ int getMenuHeight() const;
+ void setMenuHeight(int height);
+
+ QColor getToolbarColor() const;
+ void setToolbarColor(const QColor& color);
+
+ QColor getToolbarButton() const;
+ void setToolbarButton(const QColor& color);
+
+ QColor getToolbarButtonText() const;
+ void setToolbarButtonText(const QColor& color);
+
+ double getToolbarTextPointSize() const;
+ void setToolbarTextPointSize(double pointSize);
+
+ double getTextFontPointSize() const;
+ void setTextFontPointSize(double pointSize);
+
+ double getUiFontPointSize() const;
+ void setUiFontPointSize(double pointSize);
+
+signals:
+ void changed();
+};
+
+} // end namespace
+
+#endif
diff --git a/src/mobile/ui/btwindowinterface.cpp b/src/mobile/ui/btwindowinterface.cpp
new file mode 100644
index 0000000..1016055
--- /dev/null
+++ b/src/mobile/ui/btwindowinterface.cpp
@@ -0,0 +1,257 @@
+
+#include "btwindowinterface.h"
+
+#include "backend/config/btconfig.h"
+#include "backend/drivers/cswordbiblemoduleinfo.h"
+#include "backend/drivers/cswordmoduleinfo.h"
+#include "backend/keys/cswordkey.h"
+#include "backend/keys/cswordtreekey.h"
+#include "backend/managers/cswordbackend.h"
+#include "backend/rendering/centrydisplay.h"
+#include "backend/rendering/cdisplayrendering.h"
+#include "mobile/btmmain.h"
+#include "mobile/keychooser/versechooser.h"
+#include "mobile/keychooser/bookkeychooser.h"
+#include "mobile/ui/modulechooser.h"
+#include "mobile/ui/viewmanager.h"
+#include <QDebug>
+#include <QFile>
+#include <QObject>
+#include <QQmlContext>
+#include <QQmlEngine>
+#include <QQuickItem>
+#include <QStringList>
+
+
+namespace btm {
+
+BtWindowInterface::BtWindowInterface(QObject* parent)
+ : QObject(parent),
+ m_key(0),
+ m_textModel(new RoleItemModel()),
+ m_bookKeyChooser(0),
+ m_verseKeyChooser(0),
+ m_bibleTextModelBuilder(m_textModel),
+ m_bookTextModelBuilder(m_textModel){
+
+ QtQuick2ApplicationViewer* viewer = getViewManager()->getViewer();
+ m_verseKeyChooser = new VerseChooser(viewer, this);
+ bool ok = connect(m_verseKeyChooser, SIGNAL(referenceChanged()), this, SLOT(referenceChanged()));
+ Q_ASSERT(ok);
+
+ m_bookKeyChooser = new BookKeyChooser(viewer, this);
+ ok = connect(m_bookKeyChooser, SIGNAL(referenceChanged()), this, SLOT(referenceChanged()));
+ Q_ASSERT(ok);
+}
+
+static QString getKeyText(CSwordKey* key) {
+ QString keyText;
+ if ( ! key)
+ return keyText;
+
+ CSwordVerseKey* verseKey = dynamic_cast<CSwordVerseKey*>(key);
+ if (verseKey) {
+ keyText = verseKey->key();
+ return keyText;
+ }
+
+ CSwordTreeKey* treeKey = dynamic_cast<CSwordTreeKey*>(key);
+ if (treeKey) {
+ keyText = treeKey->key();
+ return keyText;
+ }
+ return keyText;
+}
+
+void BtWindowInterface::updateModel() {
+ QString moduleName= getModuleName();
+ QStringList moduleList = QStringList() << moduleName;
+ QList<const CSwordModuleInfo*> modules =
+ CSwordBackend::instance()->getConstPointerList(moduleList);
+ QString keyText = getKeyText(m_key);
+
+ m_textModel->clear();
+ if (modules.at(0)->type() == CSwordModuleInfo::Bible)
+ m_bibleTextModelBuilder.updateModel(modules, keyText);
+ else if (modules.at(0)->type() == CSwordModuleInfo::GenericBook)
+ m_bookTextModelBuilder.updateModel(modules, keyText);
+
+ emit currentModelIndexChanged();
+}
+
+int BtWindowInterface::getCurrentModelIndex() const {
+ return m_bibleTextModelBuilder.getCurrentModelIndex();
+}
+
+static bool moduleIsBibleOrCommentary(const CSwordModuleInfo* module) {
+ CSwordModuleInfo::Category category = module->category();
+ if (category == CSwordModuleInfo::Bibles ||
+ category == CSwordModuleInfo::Commentaries)
+ return true;
+ return false;
+}
+
+static bool moduleIsBook(const CSwordModuleInfo* module) {
+ CSwordModuleInfo::Category category = module->category();
+ if (category == CSwordModuleInfo::Books)
+ return true;
+ return false;
+}
+
+QString BtWindowInterface::getModuleName() const {
+ QString moduleName;
+ if (m_key)
+ moduleName = m_key->module()->name();
+ return moduleName;
+}
+
+void BtWindowInterface::setModuleName(const QString& moduleName) {
+ CSwordModuleInfo* m = CSwordBackend::instance()->findModuleByName(moduleName);
+ if (!m_key) {
+ m_key = CSwordKey::createInstance(m);
+ }
+ else {
+ if (moduleIsBibleOrCommentary(m) &&
+ moduleIsBibleOrCommentary(m_key->module())) {
+ m_key->setModule(m);
+ }
+ else if (moduleIsBook(m) &&
+ moduleIsBook(m_key->module())) {
+ m_key->setModule(m);
+ }
+
+ else {
+ delete m_key;
+ m_key = CSwordKey::createInstance(m);
+ }
+
+ }
+
+ CSwordTreeKey* treeKey = dynamic_cast<CSwordTreeKey*>(m_key);
+ if (treeKey)
+ treeKey->firstChild();
+
+ emit moduleChanged();
+ emit referenceChange();
+ updateModel();
+}
+
+QString BtWindowInterface::getReference() const {
+ QString reference;
+ if (m_key)
+ reference = m_key->key();
+ return reference;
+}
+
+void BtWindowInterface::changeModule() {
+ QtQuick2ApplicationViewer* viewer = getViewManager()->getViewer();
+ ModuleChooser* dlg = new ModuleChooser(viewer, this);
+ dlg->open();
+}
+
+static void parseKey(CSwordTreeKey* currentKey, QStringList* keyPath, QStringList* children)
+{
+ if (currentKey == 0)
+ return;
+
+ CSwordTreeKey localKey(*currentKey);
+
+ QString oldKey = localKey.key(); //string backup of key
+
+ if (oldKey.isEmpty()) { //don't set keys equal to "/", always use a key which may have content
+ localKey.firstChild();
+ oldKey = localKey.key();
+ }
+// const int oldOffset = localKey.getOffset(); //backup key position
+
+ QStringList siblings; //split up key
+ if (!oldKey.isEmpty()) {
+ siblings = oldKey.split('/', QString::SkipEmptyParts);
+ }
+
+ int depth = 0;
+ int index = 0;
+ localKey.root(); //start iteration at root node
+
+ while ( localKey.firstChild() && (depth < siblings.count()) ) {
+ QString key = localKey.key();
+ index = (depth == 0) ? -1 : 0;
+
+ bool found = false;
+ do { //look for matching sibling
+ ++index;
+ found = (localKey.getLocalNameUnicode() == siblings[depth]);
+ }
+ while (!found && localKey.nextSibling());
+
+ if (found)
+ key = localKey.key(); //found: change key to this level
+ else
+ localKey.setKey(key); //not found: restore old key
+
+ *keyPath << key;
+
+ //last iteration: get child entries
+ if (depth == siblings.count() - 1 && localKey.hasChildren()) {
+ localKey.firstChild();
+ ++depth;
+ do {
+ *children << localKey.getLocalNameUnicode();
+ }
+ while (localKey.nextSibling());
+ }
+ depth++;
+ }
+}
+
+void BtWindowInterface::changeReference() {
+ CSwordVerseKey* verseKey = dynamic_cast<CSwordVerseKey*>(m_key);
+ if (verseKey != 0) {
+ m_verseKeyChooser->open(verseKey);
+ }
+
+ CSwordTreeKey* treeKey = dynamic_cast<CSwordTreeKey*>(m_key);
+ if (treeKey != 0) {
+ QStringList keyPath;
+ QStringList children;
+ parseKey(treeKey, &keyPath, &children);
+ m_bookKeyChooser->open();
+ }
+}
+
+void BtWindowInterface::referenceChanged() {
+ emit referenceChange();
+ updateModel();
+}
+
+const CSwordModuleInfo* BtWindowInterface::module() const {
+ const CSwordModuleInfo* module = m_key->module();
+ return module;
+}
+
+CSwordKey* BtWindowInterface::getKey() const {
+ return m_key;
+}
+
+int BtWindowInterface::getFontSize() const {
+ const CLanguageMgr::Language* lang = module()->language();
+ BtConfig::FontSettingsPair fontPair = btConfig().getFontForLanguage(*lang);
+ QFont font = fontPair.second;
+ return font.pointSize();
+}
+
+void BtWindowInterface::setFontSize(int size) {
+ const CLanguageMgr::Language* lang = module()->language();
+ BtConfig::FontSettingsPair fontPair = btConfig().getFontForLanguage(*lang);
+ fontPair.second.setPointSize(size);
+ btConfig().setFontForLanguage(*lang, fontPair);
+ emit textChanged();
+}
+
+QVariant BtWindowInterface::getTextModel() {
+ QVariant var;
+ var.setValue(m_textModel);
+ return var;
+}
+
+} // end namespace
diff --git a/src/mobile/ui/btwindowinterface.h b/src/mobile/ui/btwindowinterface.h
new file mode 100644
index 0000000..c6c31b0
--- /dev/null
+++ b/src/mobile/ui/btwindowinterface.h
@@ -0,0 +1,73 @@
+#ifndef BT_WINDOW_INTERFACE_H
+#define BT_WINDOW_INTERFACE_H
+
+#include <QObject>
+#include <QString>
+#include "mobile/models/roleitemmodel.h"
+#include "mobile/models/bibletextmodelbuilder.h"
+#include "mobile/models/booktextmodelbuilder.h"
+
+class CSwordKey;
+class CSwordVerseKey;
+class CSwordModuleInfo;
+
+namespace btm {
+
+class BookKeyChooser;
+class VerseChooser;
+
+class BtWindowInterface : public QObject {
+
+ Q_OBJECT
+
+ Q_PROPERTY(QString moduleName READ getModuleName WRITE setModuleName NOTIFY moduleChanged)
+ Q_PROPERTY(QString reference READ getReference NOTIFY referenceChange)
+ Q_PROPERTY(int fontSize READ getFontSize WRITE setFontSize NOTIFY textChanged)
+ Q_PROPERTY(QVariant textModel READ getTextModel NOTIFY textModelChanged)
+ Q_PROPERTY(int currentModelIndex READ getCurrentModelIndex NOTIFY currentModelIndexChanged)
+
+public:
+ Q_INVOKABLE void changeModule();
+ Q_INVOKABLE void changeReference();
+
+ BtWindowInterface(QObject *parent = 0);
+
+ CSwordKey* getKey() const;
+
+ QString getModuleName() const;
+ void setModuleName(const QString& moduleName);
+
+ QString getReference() const;
+
+ int getCurrentModelIndex() const;
+
+ int getFontSize() const;
+ void setFontSize(int size);
+
+ QVariant getTextModel();
+
+signals:
+ void referenceChange();
+ void moduleChanged();
+ void textChanged();
+ void textModelChanged();
+ void currentModelIndexChanged();
+
+private slots:
+ void referenceChanged();
+
+private:
+ const CSwordModuleInfo* module() const;
+ void updateModel();
+
+ CSwordKey* m_key;
+ RoleItemModel* m_textModel;
+ BookKeyChooser* m_bookKeyChooser;
+ VerseChooser* m_verseKeyChooser;
+ BibleTextModelBuilder m_bibleTextModelBuilder;
+ BookTextModelBuilder m_bookTextModelBuilder;
+};
+
+} // end namespace
+
+#endif
diff --git a/src/mobile/ui/gridchooser.cpp b/src/mobile/ui/gridchooser.cpp
new file mode 100644
index 0000000..3836b18
--- /dev/null
+++ b/src/mobile/ui/gridchooser.cpp
@@ -0,0 +1,63 @@
+
+#include "gridchooser.h"
+
+#include "qtquick2applicationviewer.h"
+
+#include <algorithm>
+#include <cmath>
+#include <QEventLoop>
+#include <QQuickItem>
+#include <QQmlContext>
+#include <QDebug>
+#include <QCoreApplication>
+
+namespace btm {
+
+GridChooser::GridChooser(QtQuick2ApplicationViewer* viewer)
+ : viewer_(viewer),
+ gridChooserObject_(0) {
+ QQuickItem * rootObject = viewer_->rootObject();
+ if (rootObject != 0)
+ gridChooserObject_ = rootObject->findChild<QQuickItem*>("gridChooser");
+}
+
+GridChooser::~GridChooser() {
+}
+
+void GridChooser::open(const QStringList& stringList, const QString& highlight, const QString& title) {
+ Q_ASSERT(gridChooserObject_ != 0);
+ if (gridChooserObject_ == 0)
+ return;
+
+ gridChooserObject_->disconnect();
+ bool ok = connect(gridChooserObject_, SIGNAL(accepted(QString)),
+ this, SLOT(gridChooserAccepted(QString)));
+ Q_ASSERT(ok);
+ setProperties(stringList, highlight, title);
+}
+
+void GridChooser::setProperties(const QStringList& list, const QString& hightlight, const QString& title) {
+ QQmlContext* ctx = viewer_->rootContext();
+ ctx->setContextProperty("gridChooserModel",list);
+ gridChooserObject_->setProperty("selected",hightlight);
+ gridChooserObject_->setProperty("titleText",title);
+
+ int maxLength = 0;
+ for (int i = 0; i < list.count(); ++i) {
+ QString text = list.at(i);
+ maxLength = std::max(maxLength, text.length());
+ }
+ gridChooserObject_->setProperty("maxLength", maxLength);
+
+ gridChooserObject_->setProperty("visible",true);
+}
+
+void GridChooser::gridChooserAccepted(QString value) {
+ emit accepted(value);
+}
+
+void GridChooser::gridChooserCanceled() {
+ emit canceled();
+}
+
+} // end namespace
diff --git a/src/mobile/ui/gridchooser.h b/src/mobile/ui/gridchooser.h
new file mode 100644
index 0000000..8200f91
--- /dev/null
+++ b/src/mobile/ui/gridchooser.h
@@ -0,0 +1,43 @@
+#ifndef GRID_CHOOSER_H
+#define GRID_CHOOSER_H
+
+#include <QEventLoop>
+#include <QObject>
+#include <QList>
+
+class QtQuick2ApplicationViewer;
+class QQuickItem;
+class QStringList;
+class QEventLoop;
+
+namespace btm {
+
+class BtWindowInterface;
+
+class GridChooser : public QObject {
+ Q_OBJECT
+
+public:
+ GridChooser(QtQuick2ApplicationViewer* viewer);
+ ~GridChooser();
+ void open(const QStringList& stringList, const QString& highlight = QString(), const QString& title = QString());
+
+signals:
+ void accepted(const QString& value);
+ void canceled();
+
+private slots:
+ void gridChooserAccepted(QString value);
+ void gridChooserCanceled();
+
+private:
+ void setProperties(const QStringList& list, const QString& hightlight, const QString& title);
+
+ QtQuick2ApplicationViewer* viewer_;
+ QQuickItem* gridChooserObject_;
+ QEventLoop eventLoop_;
+};
+
+} // end namespace
+
+#endif
diff --git a/src/mobile/ui/modulechooser.cpp b/src/mobile/ui/modulechooser.cpp
new file mode 100644
index 0000000..bc3d582
--- /dev/null
+++ b/src/mobile/ui/modulechooser.cpp
@@ -0,0 +1,44 @@
+
+#include "modulechooser.h"
+
+#include "qtquick2applicationviewer.h"
+
+#include "backend/bookshelfmodel/btbookshelftreemodel.h"
+#include "backend/managers/cswordbackend.h"
+#include <cmath>
+#include <QQuickItem>
+#include <QQmlProperty>
+#include "btwindowinterface.h"
+#include "mobile/util/findqmlobject.h"
+
+namespace btm {
+
+ModuleChooser::ModuleChooser(QtQuick2ApplicationViewer* viewer, BtWindowInterface* bibleVerse)
+ : viewer_(viewer),
+ bibleVerse_(bibleVerse) {
+}
+
+void ModuleChooser::open() {
+ QQuickItem* item = findQmlObject("moduleChooser");
+ Q_ASSERT(item != 0);
+ if (item == 0)
+ return;
+
+ item->setProperty("visible", true);
+ bool ok = connect(item, SIGNAL(moduleSelected()), this, SLOT(moduleSelectedSlot()));
+ Q_ASSERT(ok);
+}
+
+void ModuleChooser::moduleSelectedSlot() {
+ QQuickItem* item = findQmlObject("moduleChooser");
+ Q_ASSERT(item != 0);
+ if (item == 0)
+ return;
+
+ item->setProperty("visible", false);
+ QVariant v = item->property("selectedModule");
+ QString moduleName = v.toString();
+ bibleVerse_->setModuleName(moduleName);
+}
+
+} // end namespace
diff --git a/src/mobile/ui/modulechooser.h b/src/mobile/ui/modulechooser.h
new file mode 100644
index 0000000..4e261f9
--- /dev/null
+++ b/src/mobile/ui/modulechooser.h
@@ -0,0 +1,35 @@
+#ifndef MODULE_CHOOSER_H
+#define MODULE_CHOOSER_H
+
+#include <QObject>
+
+class QtQuick2ApplicationViewer;
+class QStringList;
+
+namespace btm {
+
+class GridChooser;
+
+class BtWindowInterface;
+
+class ModuleChooser : public QObject {
+ Q_OBJECT
+
+public:
+ ModuleChooser(QtQuick2ApplicationViewer* viewer, BtWindowInterface* bibleVerse);
+ void open();
+
+private slots:
+ void moduleSelectedSlot();
+
+private:
+ void showGridChooser(const QStringList& list);
+ void setProperties(const QStringList& list);
+
+ QtQuick2ApplicationViewer* viewer_;
+ BtWindowInterface* bibleVerse_;
+};
+
+} // end namespace
+
+#endif
diff --git a/src/mobile/ui/moduleinterface.cpp b/src/mobile/ui/moduleinterface.cpp
new file mode 100644
index 0000000..4d898b4
--- /dev/null
+++ b/src/mobile/ui/moduleinterface.cpp
@@ -0,0 +1,187 @@
+
+#include "moduleinterface.h"
+
+#include "qtquick2applicationviewer.h"
+
+#include "backend/bookshelfmodel/btbookshelftreemodel.h"
+#include "backend/managers/cswordbackend.h"
+#include "mobile/util/findqmlobject.h"
+#include <cmath>
+#include <QQuickItem>
+#include <QQmlProperty>
+#include <QQmlContext>
+#include <QDebug>
+#include <QQmlProperty>
+#include <QCoreApplication>
+#include "btwindowinterface.h"
+#include "gridchooser.h"
+
+namespace btm {
+
+ModuleInterface::ModuleInterface() {
+}
+
+enum TextRoles {
+ TextRole = Qt::UserRole + 1
+};
+
+typedef BtBookshelfModel::ModuleRole MRole;
+static const MRole HR(BtBookshelfModel::ModuleHiddenRole);
+static const MRole PR(BtBookshelfModel::ModulePointerRole);
+static const MRole IR(BtBookshelfModel::ModuleHasIndexRole);
+static const MRole CR(BtBookshelfModel::ModuleCategoryRole);
+
+static void setupTextModel(const QSet<QString>& modelSet, RoleItemModel* model) {
+
+ QHash<int, QByteArray> roleNames;
+ roleNames[TextRole] = "modelText";
+ model->setRoleNames(roleNames);
+
+ QStringList modelList = modelSet.toList();
+ modelList.sort();
+
+ 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 CSwordModuleInfo* getModule(BtBookshelfModel* bookshelfModel, const QModelIndex& index) {
+ QVariant var = bookshelfModel->data(index, PR);
+ CSwordModuleInfo* module = static_cast<CSwordModuleInfo*>(var.value<void*>());
+ return module;
+}
+
+void ModuleInterface::updateCategoryAndLanguageModels() {
+ QQuickItem* object = findQmlObject("moduleChooser");
+ if (object == 0)
+ return;
+
+ getCategoriesAndLanguages();
+ setupTextModel(m_categories, &m_categoryModel);
+ setupTextModel(m_languages, &m_languageModel);
+ object->setProperty("categoryModel", QVariant::fromValue(&m_categoryModel));
+ object->setProperty("languageModel", QVariant::fromValue(&m_languageModel));
+}
+
+void ModuleInterface::getCategoriesAndLanguages() {
+
+ m_categories.clear();
+ m_languages.clear();
+
+ QQuickItem* object = findQmlObject("moduleChooser");
+ if (object == 0)
+ return;
+
+ BtBookshelfModel* bookshelfModel = CSwordBackend::instance()->model();
+ if (bookshelfModel == 0)
+ return;
+ int count = bookshelfModel->rowCount();
+ for (int row=0; row<count; ++row) {
+ QModelIndex index = bookshelfModel->index(row);
+ CSwordModuleInfo* module = getModule(bookshelfModel, index);
+ CSwordModuleInfo::Category category = module->category();
+ QString categoryName = module->categoryName(category);
+ const CLanguageMgr::Language* language = module->language();
+ QString languageName = language->translatedName();
+ m_categories.insert(categoryName);
+ m_languages.insert(languageName);
+ }
+}
+
+void ModuleInterface::updateWorksModel() {
+ m_worksModel.clear();
+ m_modules.clear();
+
+ QString currentLang = currentLanguage();
+ QString currentCat = currentCategory();
+
+ QHash<int, QByteArray> roleNames;
+ roleNames[TextRole] = "modelText";
+ m_worksModel.setRoleNames(roleNames);
+
+ BtBookshelfModel* bookshelfModel = CSwordBackend::instance()->model();
+ if (bookshelfModel == 0)
+ return;
+ int count = bookshelfModel->rowCount();
+ for (int row=0; row<count; ++row) {
+ QModelIndex index = bookshelfModel->index(row);
+ CSwordModuleInfo* module = getModule(bookshelfModel, index);
+ CSwordModuleInfo::Category category = module->category();
+ QString categoryName = module->categoryName(category);
+ const CLanguageMgr::Language* language = module->language();
+ QString languageName = language->translatedName();
+ if (languageName == currentLang &&
+ categoryName == currentCat) {
+ m_modules << module;
+ QString moduleName = module->name();
+ QStandardItem* item = new QStandardItem();
+ item->setData(moduleName, TextRole);
+ m_worksModel.appendRow(item);
+ }
+ }
+
+ QQuickItem* object = findQmlObject("moduleChooser");
+ if (object == 0)
+ return;
+ object->setProperty("worksModel", QVariant::fromValue(&m_worksModel));
+}
+
+QString ModuleInterface::currentLanguage() const {
+ QQuickItem* object = findQmlObject("moduleChooser");
+ if (object == 0)
+ return "";
+ int row = object->property("languageIndex").toInt();
+ QModelIndex modelIndex = m_languageModel.index(row,0);
+ QString language = modelIndex.data(TextRole).toString();
+ return language;
+
+}
+
+QString ModuleInterface::currentCategory() const {
+ QQuickItem* object = findQmlObject("moduleChooser");
+ if (object == 0)
+ return "";
+ int row = object->property("categoryIndex").toInt();
+ QModelIndex modelIndex = m_categoryModel.index(row,0);
+ QString category = modelIndex.data(TextRole).toString();
+ return category;
+}
+
+QString ModuleInterface::category(int index) {
+ if (index < 0 || index >= m_modules.count())
+ return "";
+ CSwordModuleInfo* module = m_modules.at(index);
+ if (module == 0)
+ return "";
+ CSwordModuleInfo::Category category = module->category();
+ if (category == 0)
+ return "";
+ return module->categoryName(category);
+}
+
+QString ModuleInterface::language(int index) {
+ if (index < 0 || index >= m_modules.count())
+ return "";
+ CSwordModuleInfo* module = m_modules.at(index);
+ if (module == 0)
+ return "";
+ const CLanguageMgr::Language* language = module->language();
+ if (language == 0)
+ return "";
+ return language->translatedName();
+}
+
+QString ModuleInterface::module(int index) {
+ if (index < 0 || index >= m_modules.count())
+ return "";
+ CSwordModuleInfo* module = m_modules.at(index);
+ if (module == 0)
+ return "";
+ return module->name();
+}
+
+} // end namespace
diff --git a/src/mobile/ui/moduleinterface.h b/src/mobile/ui/moduleinterface.h
new file mode 100644
index 0000000..165c30f
--- /dev/null
+++ b/src/mobile/ui/moduleinterface.h
@@ -0,0 +1,48 @@
+#ifndef MODULE_INTERFACE_H
+#define MODULE_INTERFACE_H
+
+#include "mobile/models/roleitemmodel.h"
+#include <QObject>
+#include <QList>
+#include <QSet>
+#include <QString>
+
+class QQuickItem;
+class QStringList;
+class CSwordModuleInfo;
+
+namespace btm {
+
+class GridChooser;
+
+class BtWindowInterface;
+
+class ModuleInterface : public QObject {
+ Q_OBJECT
+
+public:
+ ModuleInterface();
+ Q_INVOKABLE void updateCategoryAndLanguageModels();
+ Q_INVOKABLE void updateWorksModel();
+ Q_INVOKABLE QString category(int index);
+ Q_INVOKABLE QString language(int index);
+ Q_INVOKABLE QString module(int index);
+
+private:
+ void getCategoriesAndLanguages();
+ void setProperties(const QStringList& list);
+ QString currentLanguage() const;
+ QString currentCategory() const;
+
+ QSet<QString> m_categories;
+ QSet<QString> m_languages;
+ RoleItemModel m_categoryModel;
+ RoleItemModel m_languageModel;
+ RoleItemModel m_worksModel;
+ QList<CSwordModuleInfo*> m_modules;
+
+};
+
+} // end namespace
+
+#endif
diff --git a/src/mobile/ui/qtquick2applicationviewer.cpp b/src/mobile/ui/qtquick2applicationviewer.cpp
new file mode 100644
index 0000000..b6077d8
--- /dev/null
+++ b/src/mobile/ui/qtquick2applicationviewer.cpp
@@ -0,0 +1,63 @@
+// checksum 0x56a9 version 0x80001
+/*
+ This file was generated by the Qt Quick 2 Application wizard of Qt Creator.
+ QtQuick2ApplicationViewer is a convenience class containing mobile device specific
+ code such as screen orientation handling. Also QML paths and debugging are
+ handled here.
+ It is recommended not to modify this file, since newer versions of Qt Creator
+ may offer an updated version of it.
+*/
+
+#include "qtquick2applicationviewer.h"
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDir>
+#include <QtQml/QQmlEngine>
+
+class QtQuick2ApplicationViewerPrivate {
+ QString mainQmlFile;
+ friend class QtQuick2ApplicationViewer;
+ static QString adjustPath(const QString &path);
+};
+
+QString QtQuick2ApplicationViewerPrivate::adjustPath(const QString &path) {
+#if defined(Q_OS_MAC)
+ if (!QDir::isAbsolutePath(path))
+ return QString::fromLatin1("%1/../Resources/%2")
+ .arg(QCoreApplication::applicationDirPath(), path);
+#elif defined(Q_OS_UNIX)
+ const QString pathInInstallDir =
+ QString::fromLatin1("%1/../%2").arg(QCoreApplication::applicationDirPath(), path);
+ if (QFileInfo(pathInInstallDir).exists())
+ return pathInInstallDir;
+#endif
+ return path;
+}
+
+QtQuick2ApplicationViewer::QtQuick2ApplicationViewer(QWindow *parent)
+ : QQuickView(parent)
+ , d(new QtQuick2ApplicationViewerPrivate()) {
+ connect(engine(), SIGNAL(quit()), SLOT(close()));
+ setResizeMode(QQuickView::SizeRootObjectToView);
+}
+
+QtQuick2ApplicationViewer::~QtQuick2ApplicationViewer() {
+ delete d;
+}
+
+void QtQuick2ApplicationViewer::setMainQmlFile(const QString &file) {
+ d->mainQmlFile = QtQuick2ApplicationViewerPrivate::adjustPath(file);
+ setSource(QUrl::fromLocalFile(d->mainQmlFile));
+}
+
+void QtQuick2ApplicationViewer::addImportPath(const QString &path) {
+ engine()->addImportPath(QtQuick2ApplicationViewerPrivate::adjustPath(path));
+}
+
+void QtQuick2ApplicationViewer::showExpanded() {
+#if defined(Q_WS_SIMULATOR)
+ showFullScreen();
+#else
+ show();
+#endif
+}
diff --git a/src/mobile/ui/qtquick2applicationviewer.h b/src/mobile/ui/qtquick2applicationviewer.h
new file mode 100644
index 0000000..a3db59d
--- /dev/null
+++ b/src/mobile/ui/qtquick2applicationviewer.h
@@ -0,0 +1,32 @@
+// checksum 0xfde6 version 0x80001
+/*
+ This file was generated by the Qt Quick 2 Application wizard of Qt Creator.
+ QtQuick2ApplicationViewer is a convenience class containing mobile device specific
+ code such as screen orientation handling. Also QML paths and debugging are
+ handled here.
+ It is recommended not to modify this file, since newer versions of Qt Creator
+ may offer an updated version of it.
+*/
+
+#ifndef QTQUICK2APPLICATIONVIEWER_H
+#define QTQUICK2APPLICATIONVIEWER_H
+
+#include <QtQuick/QQuickView>
+
+class QtQuick2ApplicationViewer : public QQuickView {
+ Q_OBJECT
+
+public:
+ explicit QtQuick2ApplicationViewer(QWindow *parent = 0);
+ virtual ~QtQuick2ApplicationViewer();
+
+ void setMainQmlFile(const QString &file);
+ void addImportPath(const QString &path);
+
+ void showExpanded();
+
+private:
+ class QtQuick2ApplicationViewerPrivate *d;
+};
+
+#endif // QTQUICK2APPLICATIONVIEWER_H
diff --git a/src/mobile/ui/treechoosermodel.cpp b/src/mobile/ui/treechoosermodel.cpp
new file mode 100644
index 0000000..cc5e2a7
--- /dev/null
+++ b/src/mobile/ui/treechoosermodel.cpp
@@ -0,0 +1,22 @@
+
+#include "treechoosermodel.h"
+
+
+TreeChooserModel::TreeChooserModel(QObject *parent)
+ : QAbstractListModel(parent)
+{
+}
+
+QHash<int, QByteArray> TreeChooserModel::roleNames() const {
+ QHash<int, QByteArray> roles;
+ roles[NameRole] = "name";
+ roles[ChildCountRole] = "childCount";
+ return roles;
+}
+
+void TreeChooserModel::addEntry(const QString& name, int childCount) {
+ int count = rowCount();
+ beginInsertRows(count, count);
+ insertRow(count);
+ endInsertRows();
+}
diff --git a/src/mobile/ui/treechoosermodel.h b/src/mobile/ui/treechoosermodel.h
new file mode 100644
index 0000000..c1575ae
--- /dev/null
+++ b/src/mobile/ui/treechoosermodel.h
@@ -0,0 +1,20 @@
+#ifndef TREE_CHOOSER_MODEL_H
+#define TREE_CHOOSER_MODEL_H
+
+#include <QAbstractItemModel>
+
+class TreeChooserModel : public QAbstractListModel
+{
+ Q_OBJECT
+public:
+ enum TreeEntryRoles {
+ NameRole = Qt::UserRole + 1,
+ ChildCountRole
+ };
+
+ TreeChooserModel(QObject *parent = 0);
+ QHash<int, QByteArray> TreeChooserModel::roleNames() const;
+
+};
+
+#endif
diff --git a/src/mobile/ui/viewmanager.cpp b/src/mobile/ui/viewmanager.cpp
new file mode 100644
index 0000000..041699a
--- /dev/null
+++ b/src/mobile/ui/viewmanager.cpp
@@ -0,0 +1,52 @@
+
+#include "viewmanager.h"
+
+#include "qtquick2applicationviewer.h"
+
+#include "btstyle.h"
+#include <cmath>
+#include <QGuiApplication>
+#include <QJsonValue>
+#include <QQuickItem>
+#include <QQmlProperty>
+#include <QQmlContext>
+#include <QUrl>
+#include <QDebug>
+
+namespace btm {
+
+static QString qmlFilePath(const QString& parentName, const QString& fileName) {
+ QString filePath = QCoreApplication::applicationDirPath() + "/../share/";
+ filePath += parentName + "/";
+ filePath += fileName;
+ return filePath;
+}
+
+ViewManager::ViewManager()
+ : viewer_(new QtQuick2ApplicationViewer()) {
+ BtStyle style;
+ style.setStyle(BtStyle::gnome);
+ initialize_string_list_chooser_model();
+ initialize_main_qml();
+}
+
+void ViewManager::initialize_string_list_chooser_model() {
+ QQmlContext* ctx = viewer_->rootContext();
+ QStringList list = QStringList();
+ ctx->setContextProperty("gridChooserModel",list);
+}
+
+void ViewManager::initialize_main_qml() {
+ QString mainQml = qmlFilePath("qml", "main.qml");
+ viewer_->setMainQmlFile(mainQml);
+}
+
+void ViewManager::show() {
+ viewer_->showExpanded();
+}
+
+QtQuick2ApplicationViewer* ViewManager::getViewer() const {
+ return viewer_;
+}
+
+} // end namespace
diff --git a/src/mobile/ui/viewmanager.h b/src/mobile/ui/viewmanager.h
new file mode 100644
index 0000000..7c50d35
--- /dev/null
+++ b/src/mobile/ui/viewmanager.h
@@ -0,0 +1,34 @@
+#ifndef VIEW_MANAGER_H
+#define VIEW_MANAGER_H
+
+#include <QObject>
+#include <QList>
+
+class QtQuick2ApplicationViewer;
+class QStringList;
+
+namespace btm {
+class BtWindowInterface;
+}
+
+namespace btm {
+
+class ViewManager : public QObject {
+ Q_OBJECT
+
+public:
+ ViewManager();
+
+ void show();
+ QtQuick2ApplicationViewer* getViewer() const;
+
+private:
+ void initialize_main_qml();
+ void initialize_string_list_chooser_model();
+
+ QtQuick2ApplicationViewer* viewer_;
+};
+
+} // end namespace
+
+#endif
diff --git a/src/mobile/util/findqmlobject.cpp b/src/mobile/util/findqmlobject.cpp
new file mode 100644
index 0000000..25a317c
--- /dev/null
+++ b/src/mobile/util/findqmlobject.cpp
@@ -0,0 +1,34 @@
+/*********
+*
+* 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 "mobile/util/findqmlobject.h"
+#include <QQuickItem>
+#include "mobile/btmmain.h"
+#include "mobile/ui/qtquick2applicationviewer.h"
+#include "mobile/ui/viewmanager.h"
+
+namespace btm {
+
+QQuickItem* findQmlObject(const QString& objectName) {
+
+ QtQuick2ApplicationViewer* viewer = getViewManager()->getViewer();
+ QQuickItem * rootObject = 0;
+ if (viewer != 0)
+ rootObject = viewer->rootObject();
+ QQuickItem* object = 0;
+ if (rootObject != 0)
+ object = rootObject->findChild<QQuickItem*>(objectName);
+ Q_ASSERT(object != 0);
+ return object;
+}
+
+}
diff --git a/src/mobile/util/findqmlobject.h b/src/mobile/util/findqmlobject.h
new file mode 100644
index 0000000..bfbbcac
--- /dev/null
+++ b/src/mobile/util/findqmlobject.h
@@ -0,0 +1,28 @@
+/*********
+*
+* 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 FIND_QML_OBJECT
+#define FIND_QML_OBJECT
+
+#include <QString>
+
+class QQuickItem;
+
+namespace btm {
+
+// Finds the named QML object that is located at the
+// top level of the QML objects.
+QQuickItem* findQmlObject(const QString& objectName);
+
+}
+
+#endif
diff --git a/src/mobile/util/messagedialog.cpp b/src/mobile/util/messagedialog.cpp
new file mode 100644
index 0000000..a68857a
--- /dev/null
+++ b/src/mobile/util/messagedialog.cpp
@@ -0,0 +1,36 @@
+/*********
+*
+* 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 "messagedialog.h"
+
+#include <QMessageBox>
+#include <QString>
+
+
+namespace message {
+
+int showWarning(QWidget * /*parent*/,
+ const QString & /*title*/,
+ const QString & /*text*/,
+ QMessageBox::StandardButtons /*buttons*/,
+ QMessageBox::StandardButton /*defaultButton*/) {
+ // TODO - implement showWarning
+ return 0;
+}
+
+int showQuestion(QWidget * /*parent*/,
+ const QString & /*title*/,
+ const QString & /*text*/,
+ QMessageBox::StandardButtons /*buttons*/,
+ QMessageBox::StandardButton /*defaultButton*/) {
+ // TODO - implement showQuestion
+ return 0;
+}
+
+} // namespace message
diff --git a/src/mobile/util/messagedialog.h b/src/mobile/util/messagedialog.h
new file mode 100644
index 0000000..d56b9ea
--- /dev/null
+++ b/src/mobile/util/messagedialog.h
@@ -0,0 +1,36 @@
+/*********
+*
+* 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 UTIL_DIALOG_UTIL_H
+#define UTIL_DIALOG_UTIL_H
+
+#include <QString>
+#include <QMessageBox>
+
+class QWidget;
+
+namespace message {
+
+int showWarning(QWidget * parent,
+ const QString & title,
+ const QString & text,
+ QMessageBox::StandardButtons buttons = QMessageBox::Ok,
+ QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
+
+int showQuestion(QWidget * parent,
+ const QString & title,
+ const QString & text,
+ QMessageBox::StandardButtons buttons = QMessageBox::Ok,
+ QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
+
+} // namespace message
+
+#endif