diff options
Diffstat (limited to 'src')
471 files changed, 18999 insertions, 14787 deletions
diff --git a/src/backend/bookshelfmodel/btbookshelffiltermodel.cpp b/src/backend/bookshelfmodel/btbookshelffiltermodel.cpp index 320d693..2908db3 100644 --- a/src/backend/bookshelfmodel/btbookshelffiltermodel.cpp +++ b/src/backend/bookshelfmodel/btbookshelffiltermodel.cpp @@ -4,15 +4,16 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * **********/ -#include "backend/bookshelfmodel/btbookshelffiltermodel.h" +#include "btbookshelffiltermodel.h" -#include "backend/bookshelfmodel/btbookshelfmodel.h" +#include "btbookshelfmodel.h" +#include "../../util/btassert.h" BtBookshelfFilterModel::BtBookshelfFilterModel(QObject * parent) @@ -148,7 +149,7 @@ bool BtBookshelfFilterModel::nameFilterAcceptsRow(int row, return true; const QAbstractItemModel * const m = sourceModel(); - Q_ASSERT(m != 0); + BT_ASSERT(m); QModelIndex itemIndex(m->index(row, m_nameFilterColumn, parent)); int numChildren(m->rowCount(itemIndex)); @@ -170,7 +171,7 @@ bool BtBookshelfFilterModel::hiddenFilterAcceptsRow(int row, return true; const QAbstractItemModel * const m = sourceModel(); - Q_ASSERT(m != 0); + BT_ASSERT(m); const QModelIndex itemIndex = m->index(row, m_hiddenFilterColumn, parent); const int numChildren = m->rowCount(itemIndex); @@ -193,7 +194,7 @@ bool BtBookshelfFilterModel::categoryFilterAcceptsRow(int row, return true; const QAbstractItemModel * const m = sourceModel(); - Q_ASSERT(m != 0); + BT_ASSERT(m); const QModelIndex itemIndex(m->index(row, m_categoryFilterColumn, parent)); const int numChildren(m->rowCount(itemIndex)); diff --git a/src/backend/bookshelfmodel/btbookshelffiltermodel.h b/src/backend/bookshelfmodel/btbookshelffiltermodel.h index b1b22e6..b59079f 100644 --- a/src/backend/bookshelfmodel/btbookshelffiltermodel.h +++ b/src/backend/bookshelfmodel/btbookshelffiltermodel.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -15,7 +15,7 @@ #include <QSortFilterProxyModel> -#include "backend/drivers/cswordmoduleinfo.h" +#include "../drivers/cswordmoduleinfo.h" class BtBookshelfFilterModel: public QSortFilterProxyModel { @@ -24,13 +24,13 @@ class BtBookshelfFilterModel: public QSortFilterProxyModel { public: /* Methods: */ - BtBookshelfFilterModel(QObject * parent = 0); + BtBookshelfFilterModel(QObject * parent = nullptr); inline bool enabled() const { return m_enabled; } - virtual bool filterAcceptsRow(int row, const QModelIndex & parent) const; + bool filterAcceptsRow(int row, const QModelIndex & parent) const override; // Name filter: inline int nameFilterRole() const { diff --git a/src/backend/bookshelfmodel/btbookshelfmodel.cpp b/src/backend/bookshelfmodel/btbookshelfmodel.cpp index c19e429..c675076 100644 --- a/src/backend/bookshelfmodel/btbookshelfmodel.cpp +++ b/src/backend/bookshelfmodel/btbookshelfmodel.cpp @@ -4,17 +4,18 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * **********/ -#include "backend/bookshelfmodel/btbookshelfmodel.h" +#include "btbookshelfmodel.h" #include <QIcon> -#include <QSet> -#include "util/macros.h" +#include "../../util/btassert.h" +#include "../../util/btconnect.h" +#include "../../util/macros.h" int BtBookshelfModel::rowCount(const QModelIndex & parent) const { @@ -25,11 +26,13 @@ int BtBookshelfModel::rowCount(const QModelIndex & parent) const { } QVariant BtBookshelfModel::data(CSwordModuleInfo * module, int role) const { - Q_ASSERT(module); + BT_ASSERT(module); switch (role) { - case ModuleNameRole: // Qt::DisplayRole + case Qt::DisplayRole: + case ModuleNameRole: return module->name(); - case ModuleIconRole: // Qt::DecorationRole + case Qt::DecorationRole: + case ModuleIconRole: return CSwordModuleInfo::moduleIcon(*module); case ModulePointerRole: return qVariantFromValue(static_cast<void *>(module)); @@ -44,7 +47,7 @@ QVariant BtBookshelfModel::data(CSwordModuleInfo * module, int role) const { case ModuleHasIndexRole: return module->hasIndex(); case ModuleIndexSizeRole: - return (qulonglong) module->indexSize(); + return static_cast<qulonglong>(module->indexSize()); case ModuleDescriptionRole: return module->config(CSwordModuleInfo::Description); case Qt::ToolTipRole: @@ -114,7 +117,7 @@ void BtBookshelfModel::clear(bool destroy) { } void BtBookshelfModel::addModule(CSwordModuleInfo * const module) { - Q_ASSERT(module != 0); + BT_ASSERT(module); if (m_data.contains(module)) return; @@ -122,12 +125,12 @@ void BtBookshelfModel::addModule(CSwordModuleInfo * const module) { const int index(m_data.size()); beginInsertRows(QModelIndex(), index, index); m_data.append(module); - connect(module, SIGNAL(hiddenChanged(bool)), - this, SLOT(moduleHidden(bool))); - connect(module, SIGNAL(hasIndexChanged(bool)), - this, SLOT(moduleIndexed(bool))); - connect(module, SIGNAL(unlockedChanged(bool)), - this, SLOT(moduleUnlocked(bool))); + BT_CONNECT(module, &CSwordModuleInfo::hiddenChanged, + this, &BtBookshelfModel::moduleHidden); + BT_CONNECT(module, &CSwordModuleInfo::hasIndexChanged, + this, &BtBookshelfModel::moduleIndexed); + BT_CONNECT(module, &CSwordModuleInfo::unlockedChanged, + this, &BtBookshelfModel::moduleUnlocked); endInsertRows(); } @@ -135,9 +138,9 @@ void BtBookshelfModel::addModules(const QList<CSwordModuleInfo *> & modules) { addModules(modules.toSet()); } -void BtBookshelfModel::addModules(const QSet<CSwordModuleInfo *> & modules) { +void BtBookshelfModel::addModules(BtModuleSet const & modules) { QList<CSwordModuleInfo *> newModules; - Q_FOREACH (CSwordModuleInfo * module, modules) + Q_FOREACH(CSwordModuleInfo * const module, modules) if (!m_data.contains(module)) newModules.append(module); @@ -147,14 +150,14 @@ void BtBookshelfModel::addModules(const QSet<CSwordModuleInfo *> & modules) { beginInsertRows(QModelIndex(), m_data.size(), m_data.size() + newModules.size() - 1); - Q_FOREACH (CSwordModuleInfo * module, newModules) { + Q_FOREACH(CSwordModuleInfo * const module, newModules) { m_data.append(module); - connect(module, SIGNAL(hiddenChanged(bool)), - this, SLOT(moduleHidden(bool))); - connect(module, SIGNAL(hasIndexChanged(bool)), - this, SLOT(moduleIndexed(bool))); - connect(module, SIGNAL(unlockedChanged(bool)), - this, SLOT(moduleUnlocked(bool))); + BT_CONNECT(module, &CSwordModuleInfo::hiddenChanged, + this, &BtBookshelfModel::moduleHidden); + BT_CONNECT(module, &CSwordModuleInfo::hasIndexChanged, + this, &BtBookshelfModel::moduleIndexed); + BT_CONNECT(module, &CSwordModuleInfo::unlockedChanged, + this, &BtBookshelfModel::moduleUnlocked); } endInsertRows(); } @@ -166,12 +169,12 @@ void BtBookshelfModel::removeModule(CSwordModuleInfo * const module, return; beginRemoveRows(QModelIndex(), index, index); - disconnect(module, SIGNAL(hiddenChanged(bool)), - this, SLOT(moduleHidden(bool))); - disconnect(module, SIGNAL(hasIndexChanged(bool)), - this, SLOT(moduleIndexed(bool))); - disconnect(module, SIGNAL(unlockedChanged(bool)), - this, SLOT(moduleUnlocked(bool))); + disconnect(module, &CSwordModuleInfo::hiddenChanged, + this, &BtBookshelfModel::moduleHidden); + disconnect(module, &CSwordModuleInfo::hasIndexChanged, + this, &BtBookshelfModel::moduleIndexed); + disconnect(module, &CSwordModuleInfo::unlockedChanged, + this, &BtBookshelfModel::moduleUnlocked); m_data.removeAt(index); endRemoveRows(); if (destroy) @@ -184,42 +187,39 @@ void BtBookshelfModel::removeModules(const QList<CSwordModuleInfo *> & modules, removeModules(modules.toSet(), destroy); } -void BtBookshelfModel::removeModules(const QSet<CSwordModuleInfo *> & modules, - bool destroy) -{ +void BtBookshelfModel::removeModules(BtConstModuleSet const & modules, bool destroy){ // This is inefficient, since signals are emitted for each removed module: - Q_FOREACH (CSwordModuleInfo * module, modules) - removeModule(module, destroy); + Q_FOREACH(CSwordModuleInfo const * const module, modules) + removeModule(const_cast<CSwordModuleInfo *>(module), destroy); } CSwordModuleInfo * BtBookshelfModel::getModule(const QString & name) const { - Q_FOREACH (CSwordModuleInfo * module, m_data) + Q_FOREACH(CSwordModuleInfo * const module, m_data) if (UNLIKELY(module->name() == name)) return module; - - return 0; + return nullptr; } void BtBookshelfModel::moduleHidden(bool) { - Q_ASSERT(qobject_cast<CSwordModuleInfo *>(sender()) != 0); + BT_ASSERT(qobject_cast<CSwordModuleInfo *>(sender())); moduleDataChanged(static_cast<CSwordModuleInfo *>(sender())); } void BtBookshelfModel::moduleIndexed(bool) { - Q_ASSERT(qobject_cast<CSwordModuleInfo *>(sender()) != 0); + BT_ASSERT(qobject_cast<CSwordModuleInfo *>(sender())); moduleDataChanged(static_cast<CSwordModuleInfo *>(sender())); } void BtBookshelfModel::moduleUnlocked(bool) { - Q_ASSERT(qobject_cast<CSwordModuleInfo *>(sender()) != 0); + BT_ASSERT(qobject_cast<CSwordModuleInfo *>(sender())); moduleDataChanged(static_cast<CSwordModuleInfo *>(sender())); } void BtBookshelfModel::moduleDataChanged(CSwordModuleInfo * module) { - Q_ASSERT(m_data.count(module) == 1); + BT_ASSERT(m_data.count(module) == 1); QModelIndex i(index(m_data.indexOf(module), 0)); emit dataChanged(i, i); diff --git a/src/backend/bookshelfmodel/btbookshelfmodel.h b/src/backend/bookshelfmodel/btbookshelfmodel.h index 0884b4c..d63fd4b 100644 --- a/src/backend/bookshelfmodel/btbookshelfmodel.h +++ b/src/backend/bookshelfmodel/btbookshelfmodel.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -15,7 +15,9 @@ #include <QAbstractListModel> -#include "backend/drivers/cswordmoduleinfo.h" +#include "../drivers/btconstmoduleset.h" +#include "../drivers/btmoduleset.h" +#include "../drivers/cswordmoduleinfo.h" /** @@ -31,34 +33,34 @@ class BtBookshelfModel: public QAbstractListModel { public: /* Types: */ enum ModuleRole { - ModuleNameRole = Qt::DisplayRole, - ModuleIconRole = Qt::DecorationRole, - ModulePointerRole = Qt::UserRole, - ModuleCategoryRole = Qt::UserRole + 1, - ModuleLanguageRole = Qt::UserRole + 2, - ModuleHiddenRole = Qt::UserRole + 3, - ModuleInstallPathRole = Qt::UserRole + 4, - ModuleHasIndexRole = Qt::UserRole + 5, - ModuleIndexSizeRole = Qt::UserRole + 6, - ModuleDescriptionRole = Qt::UserRole + 7, - UserRole = Qt::UserRole + 100 + ModuleNameRole = Qt::UserRole, + ModuleIconRole, + ModulePointerRole, + ModuleCategoryRole, + ModuleLanguageRole, + ModuleHiddenRole, + ModuleInstallPathRole, + ModuleHasIndexRole, + ModuleIndexSizeRole, + ModuleDescriptionRole, + UserRole }; public: /* Methods: */ - inline BtBookshelfModel(QObject * const parent = 0) + inline BtBookshelfModel(QObject * const parent = nullptr) : QAbstractListModel(parent) {} // Virtual methods implemented from QAbstractListModel: - int rowCount(const QModelIndex & parent = QModelIndex()) const; + int rowCount(const QModelIndex & parent = QModelIndex()) const override; QVariant data(CSwordModuleInfo * module, int role) const; - QVariant data(const QModelIndex & index, int role) const; + QVariant data(const QModelIndex & index, int role) const override; QVariant headerData(int section, Qt::Orientation orientation, - int role = Qt::DisplayRole) const; + int role = Qt::DisplayRole) const override; bool setData(const QModelIndex & index, const QVariant & value, - int role = ModuleHiddenRole); + int role = ModuleHiddenRole) override; /** Given an index of this model, this method returns a pointer to the underlying @@ -67,7 +69,8 @@ public: /* Methods: */ */ inline CSwordModuleInfo * module(const QModelIndex & index) const { return static_cast<CSwordModuleInfo *>( - data(index, BtBookshelfModel::ModulePointerRole).value<void *>()); + data(index, + BtBookshelfModel::ModulePointerRole).value<void *>()); } /** @@ -87,7 +90,7 @@ public: /* Methods: */ Appends the all the modules in the given set to this model. \param[in] modules Set of modules to add. */ - void addModules(const QSet<CSwordModuleInfo *> & modules); + void addModules(BtModuleSet const & modules); /** Appends the all the modules in the given list to this model. @@ -109,7 +112,7 @@ public: /* Methods: */ \param[in] modules The set of modules to remove from this model. \param[in] destroy If true, the given CSwordModuleInfo instances are destroyed. */ - void removeModules(const QSet<CSwordModuleInfo *> & modules, + void removeModules(BtConstModuleSet const & modules, bool destroy = false); /** diff --git a/src/backend/bookshelfmodel/btbookshelftreemodel.cpp b/src/backend/bookshelfmodel/btbookshelftreemodel.cpp index f3dbc4a..803281f 100644 --- a/src/backend/bookshelfmodel/btbookshelftreemodel.cpp +++ b/src/backend/bookshelfmodel/btbookshelftreemodel.cpp @@ -4,27 +4,29 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * **********/ -#include "backend/bookshelfmodel/btbookshelftreemodel.h" +#include "btbookshelftreemodel.h" -#include <QSet> -#include "backend/bookshelfmodel/categoryitem.h" -#include "backend/bookshelfmodel/indexingitem.h" -#include "backend/bookshelfmodel/languageitem.h" -#include "backend/bookshelfmodel/moduleitem.h" -#include "backend/config/btconfig.h" -#include "util/macros.h" +#include "../../util/btassert.h" +#include "../../util/btconnect.h" +#include "../../util/macros.h" +#include "../config/btconfig.h" +#include "categoryitem.h" +#include "indexingitem.h" +#include "languageitem.h" +#include "moduleitem.h" +#include <QDebug> using namespace BookshelfModel; bool BtBookshelfTreeModel::Grouping::loadFrom(const QString & configKey) { - Q_ASSERT(!configKey.isNull()); + BT_ASSERT(!configKey.isNull()); QVariant v = btConfig().qVariantValue(configKey, QVariant()); if (!v.canConvert<Grouping>()) return false; @@ -34,13 +36,13 @@ bool BtBookshelfTreeModel::Grouping::loadFrom(const QString & configKey) { } void BtBookshelfTreeModel::Grouping::saveTo(const QString & configKey) const { - Q_ASSERT(!configKey.isNull()); + BT_ASSERT(!configKey.isNull()); btConfig().setValue(configKey, QVariant::fromValue(*this)); } BtBookshelfTreeModel::BtBookshelfTreeModel(QObject * parent) : QAbstractItemModel(parent) - , m_sourceModel(0) + , m_sourceModel(nullptr) , m_rootItem(new RootItem) , m_defaultChecked(MODULE_HIDDEN) , m_checkable(false) {} @@ -48,7 +50,7 @@ BtBookshelfTreeModel::BtBookshelfTreeModel(QObject * parent) BtBookshelfTreeModel::BtBookshelfTreeModel(const QString & configKey, QObject * parent) : QAbstractItemModel(parent) - , m_sourceModel(0) + , m_sourceModel(nullptr) , m_rootItem(new RootItem) , m_groupingOrder(configKey) , m_defaultChecked(MODULE_HIDDEN) @@ -57,7 +59,7 @@ BtBookshelfTreeModel::BtBookshelfTreeModel(const QString & configKey, BtBookshelfTreeModel::BtBookshelfTreeModel(const Grouping & grouping, QObject * parent) : QAbstractItemModel(parent) - , m_sourceModel(0) + , m_sourceModel(nullptr) , m_rootItem(new RootItem) , m_groupingOrder(grouping) , m_defaultChecked(MODULE_HIDDEN) @@ -99,9 +101,9 @@ QModelIndex BtBookshelfTreeModel::parent(const QModelIndex & index) const { return QModelIndex(); Item * childItem(static_cast<Item*>(index.internalPointer())); - Q_ASSERT(childItem != 0); + BT_ASSERT(childItem); Item * parentItem(childItem->parent()); - Q_ASSERT(parentItem != 0); + BT_ASSERT(parentItem); if (parentItem == m_rootItem) return QModelIndex(); @@ -114,7 +116,7 @@ QVariant BtBookshelfTreeModel::data(const QModelIndex & index, int role) const { return QVariant(); const Item * const i = static_cast<Item*>(index.internalPointer()); - Q_ASSERT(i != 0); + BT_ASSERT(i); switch (role) { case Qt::CheckStateRole: @@ -146,15 +148,15 @@ QVariant BtBookshelfTreeModel::data(const QModelIndex & index, int role) const { } QVariant BtBookshelfTreeModel::data(CSwordModuleInfo & module, int role) const { - Q_ASSERT(m_sourceIndexMap.contains(&module)); + BT_ASSERT(m_sourceIndexMap.contains(&module)); return m_sourceModel->data(m_sourceIndexMap.value(&module), role); } bool BtBookshelfTreeModel::setData(const QModelIndex & itemIndex, const QVariant & value, int role) { - Q_ASSERT(itemIndex.isValid()); - typedef QPair<Item *, QModelIndex> IP; + BT_ASSERT(itemIndex.isValid()); + using IP = QPair<Item *, QModelIndex>; if (UNLIKELY(role != Qt::CheckStateRole)) return false; @@ -169,7 +171,7 @@ bool BtBookshelfTreeModel::setData(const QModelIndex & itemIndex, newState = Qt::Checked; Item * item = static_cast<Item *>(itemIndex.internalPointer()); - Q_ASSERT(item != 0); + BT_ASSERT(item); if (item->checkState() == newState) return false; // Recursively (un)check all children: @@ -209,7 +211,7 @@ bool BtBookshelfTreeModel::setData(const QModelIndex & itemIndex, Qt::ItemFlags BtBookshelfTreeModel::flags(const QModelIndex & index) const { if (!index.isValid()) - return 0; + return nullptr; Qt::ItemFlags f(Qt::ItemIsEnabled | Qt::ItemIsSelectable); @@ -238,10 +240,13 @@ void BtBookshelfTreeModel::setSourceModel(QAbstractItemModel * sourceModel) { if (m_sourceModel == sourceModel) return; - if (m_sourceModel != 0) { - disconnect(this, SLOT(moduleInserted(QModelIndex, int, int))); - disconnect(this, SLOT(moduleRemoved(QModelIndex, int, int))); - disconnect(this, SLOT(moduleDataChanged(QModelIndex, QModelIndex))); + if (m_sourceModel != nullptr) { + disconnect(m_sourceModel, &QAbstractItemModel::rowsAboutToBeRemoved, + this, &BtBookshelfTreeModel::moduleRemoved); + disconnect(m_sourceModel, &QAbstractItemModel::rowsInserted, + this, &BtBookshelfTreeModel::moduleInserted); + disconnect(m_sourceModel, &QAbstractItemModel::dataChanged, + this, &BtBookshelfTreeModel::moduleDataChanged); beginRemoveRows(QModelIndex(), 0, m_rootItem->children().size() - 1); delete m_rootItem; m_modules.clear(); @@ -253,13 +258,13 @@ void BtBookshelfTreeModel::setSourceModel(QAbstractItemModel * sourceModel) { m_sourceModel = sourceModel; - if (sourceModel != 0) { - connect(sourceModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex, int, int)), - this, SLOT(moduleRemoved(QModelIndex, int, int))); - connect(sourceModel, SIGNAL(rowsInserted(QModelIndex, int, int)), - this, SLOT(moduleInserted(QModelIndex, int, int))); - connect(sourceModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)), - this, SLOT(moduleDataChanged(QModelIndex, QModelIndex))); + if (sourceModel != nullptr) { + BT_CONNECT(sourceModel, &QAbstractItemModel::rowsAboutToBeRemoved, + this, &BtBookshelfTreeModel::moduleRemoved); + BT_CONNECT(sourceModel, &QAbstractItemModel::rowsInserted, + this, &BtBookshelfTreeModel::moduleInserted); + BT_CONNECT(sourceModel, &QAbstractItemModel::dataChanged, + this, &BtBookshelfTreeModel::moduleDataChanged); for (int i = 0; i < sourceModel->rowCount(); i++) { const QModelIndex moduleIndex(sourceModel->index(i, 0)); @@ -291,8 +296,8 @@ void BtBookshelfTreeModel::setGroupingOrder(const Grouping & groupingOrder, m_groupingOrder = groupingOrder; - if (m_sourceModel != 0) { - const QSet<CSwordModuleInfo *> checked(m_checkedModulesCache); + if (m_sourceModel != nullptr) { + BtModuleSet const checked(m_checkedModulesCache); m_checkedModulesCache.clear(); beginRemoveRows(QModelIndex(), 0, m_rootItem->children().size() - 1); @@ -319,15 +324,15 @@ void BtBookshelfTreeModel::setCheckable(bool checkable) { if (m_checkable == checkable) return; m_checkable = checkable; - if (m_sourceModel == 0) + if (m_sourceModel == nullptr) return; // Notify views that flags changed for all items: resetData(); } -void BtBookshelfTreeModel::setCheckedModules(const QSet<CSwordModuleInfo *> & modules) { - typedef ModuleItemMap::const_iterator MIMCI; +void BtBookshelfTreeModel::setCheckedModules(BtConstModuleSet const & modules) { + using MIMCI = ModuleItemMap::const_iterator; for (MIMCI it = m_modules.constBegin(); it != m_modules.constEnd(); ++it) { if (modules.contains(it.key())) { @@ -357,9 +362,7 @@ void BtBookshelfTreeModel::addModule(CSwordModuleInfo & module, bool checked) { if (m_modules.contains(&module)) return; -#if QT_VERSION >= 0x040600 beginResetModel(); -#endif Grouping g(m_groupingOrder); addModule(module, QModelIndex(), g, checked); @@ -370,11 +373,7 @@ void BtBookshelfTreeModel::addModule(CSwordModuleInfo & module, bool checked) { themselves. */ -#if QT_VERSION >= 0x040600 endResetModel(); -#else - reset(); -#endif } void BtBookshelfTreeModel::addModule(CSwordModuleInfo & module, @@ -422,7 +421,7 @@ void BtBookshelfTreeModel::addModule(CSwordModuleInfo & module, } void BtBookshelfTreeModel::removeModule(CSwordModuleInfo & module) { - typedef ModuleItemMap::iterator MIMI; + using MIMI = ModuleItemMap::iterator; const MIMI it = m_modules.find(&module); if (it == m_modules.end()) return; @@ -430,11 +429,11 @@ void BtBookshelfTreeModel::removeModule(CSwordModuleInfo & module) { Item * i = it.value(); // Set i to be the lowest item (including empty groups) to remove: - Q_ASSERT(i->parent()); + BT_ASSERT(i->parent()); while (i->parent() != m_rootItem && i->parent()->children().size() <= 1) i = i->parent(); - Q_ASSERT(i); - Q_ASSERT(i->parent()); + BT_ASSERT(i); + BT_ASSERT(i->parent()); // Calculate item indexes: const int index = i->childIndex(); @@ -456,7 +455,7 @@ Item & BtBookshelfTreeModel::getItem(const QModelIndex & index) const { return *m_rootItem; Item * const item = static_cast<Item *>(index.internalPointer()); - Q_ASSERT(item); + BT_ASSERT(item); return *item; } @@ -495,7 +494,7 @@ void BtBookshelfTreeModel::resetParentCheckStates(QModelIndex parentIndex) { if (haveUncheckedChildren) break; } else { - Q_ASSERT(state == Qt::Unchecked); + BT_ASSERT(state == Qt::Unchecked); haveUncheckedChildren = true; if (haveCheckedChildren) break; @@ -523,10 +522,10 @@ void BtBookshelfTreeModel::resetParentCheckStates(QModelIndex parentIndex) { void BtBookshelfTreeModel::moduleDataChanged(const QModelIndex & topLeft, const QModelIndex & bottomRight) { - Q_ASSERT(!topLeft.parent().isValid()); - Q_ASSERT(!bottomRight.parent().isValid()); - Q_ASSERT(topLeft.column() == 0); - Q_ASSERT(bottomRight.column() == 0); + BT_ASSERT(!topLeft.parent().isValid()); + BT_ASSERT(!bottomRight.parent().isValid()); + BT_ASSERT(topLeft.column() == 0); + BT_ASSERT(bottomRight.column() == 0); for (int i = topLeft.row(); i <= bottomRight.row(); i++) { const QModelIndex moduleIndex(m_sourceModel->index(i, 0, topLeft.parent())); @@ -534,7 +533,7 @@ void BtBookshelfTreeModel::moduleDataChanged(const QModelIndex & topLeft, BtBookshelfModel::ModulePointerRole)); CSwordModuleInfo & module = *static_cast<CSwordModuleInfo *>(data.value<void *>()); QModelIndex itemIndex(getIndex(*m_modules[&module])); - Q_ASSERT(itemIndex.isValid()); + BT_ASSERT(itemIndex.isValid()); emit dataChanged(itemIndex, itemIndex); @@ -553,7 +552,7 @@ void BtBookshelfTreeModel::moduleInserted(const QModelIndex & parent, int start, int end) { - Q_ASSERT(start <= end); + BT_ASSERT(start <= end); for (int i = start; i <= end; i++) { const QModelIndex moduleIndex(m_sourceModel->index(i, 0, parent)); @@ -569,7 +568,7 @@ void BtBookshelfTreeModel::moduleInserted(const QModelIndex & parent, checked = !m_sourceModel->data(moduleIndex, BtBookshelfModel::ModuleHasIndexRole).toBool(); } else { - Q_ASSERT(m_defaultChecked == CHECKED || m_defaultChecked == UNCHECKED); + BT_ASSERT(m_defaultChecked == CHECKED || m_defaultChecked == UNCHECKED); checked = (m_defaultChecked == CHECKED); } m_sourceIndexMap[&module] = moduleIndex; @@ -581,7 +580,7 @@ void BtBookshelfTreeModel::moduleRemoved(const QModelIndex & parent, int start, int end) { - Q_ASSERT(start <= end); + BT_ASSERT(start <= end); for (int i = start; i <= end; i++) { const QModelIndex moduleIndex(m_sourceModel->index(i, 0, parent)); @@ -597,8 +596,8 @@ QDataStream & operator <<(QDataStream & os, const BtBookshelfTreeModel::Grouping & o) { os << o.size(); - Q_FOREACH(BtBookshelfTreeModel::Group g, o) - os << static_cast<int>(g); + Q_FOREACH(BtBookshelfTreeModel::Group const g, o) + os << static_cast<int const>(g); return os; } diff --git a/src/backend/bookshelfmodel/btbookshelftreemodel.h b/src/backend/bookshelfmodel/btbookshelftreemodel.h index 14c3289..6192ca2 100644 --- a/src/backend/bookshelfmodel/btbookshelftreemodel.h +++ b/src/backend/bookshelfmodel/btbookshelftreemodel.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -18,9 +18,10 @@ #include <QList> #include <QMap> #include <QPersistentModelIndex> -#include <QSet> -#include "backend/bookshelfmodel/btbookshelfmodel.h" -#include "backend/bookshelfmodel/item.h" +#include "../drivers/btconstmoduleset.h" +#include "../drivers/btmoduleset.h" +#include "btbookshelfmodel.h" +#include "item.h" namespace BookshelfModel { class ModuleItem; } @@ -34,8 +35,8 @@ class BtBookshelfTreeModel: public QAbstractItemModel { private: /* Types: */ - typedef QMap<CSwordModuleInfo *, BookshelfModel::ModuleItem *> ModuleItemMap; - typedef QMap<CSwordModuleInfo *, QPersistentModelIndex> SourceIndexMap; + using ModuleItemMap = QMap<CSwordModuleInfo *, BookshelfModel::ModuleItem *>; + using SourceIndexMap = QMap<CSwordModuleInfo *, QPersistentModelIndex>; public: /* Types: */ @@ -90,36 +91,41 @@ public: /* Types: */ public: /* Methods: */ - BtBookshelfTreeModel(QObject * parent = 0); - BtBookshelfTreeModel(const QString & configKey, QObject * parent = 0); - BtBookshelfTreeModel(const Grouping & grouping, QObject * parent = 0); - virtual ~BtBookshelfTreeModel(); - - virtual int rowCount(const QModelIndex & parent = QModelIndex()) const; - virtual int columnCount(const QModelIndex & parent = QModelIndex()) - const; - virtual bool hasChildren(const QModelIndex & parent = QModelIndex()) - const; - virtual QModelIndex index(int row, - int column, - const QModelIndex & parent = QModelIndex()) - const; - virtual QModelIndex parent(const QModelIndex & index) const; - virtual QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const; + BtBookshelfTreeModel(QObject * parent = nullptr); + BtBookshelfTreeModel(const QString & configKey, QObject * parent = nullptr); + BtBookshelfTreeModel(const Grouping & grouping, QObject * parent = nullptr); + ~BtBookshelfTreeModel() override; + + int rowCount(const QModelIndex & parent = QModelIndex()) const override; + int columnCount(const QModelIndex & parent = QModelIndex()) const override; + bool hasChildren(const QModelIndex & parent = QModelIndex()) const override; + QModelIndex index(int row, + int column, + const QModelIndex & parent = QModelIndex()) + const override; + QModelIndex parent(const QModelIndex & index) const override; + QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) + const override; QVariant data(CSwordModuleInfo & module, int role = Qt::DisplayRole) const; - virtual Qt::ItemFlags flags(const QModelIndex & index) const; - virtual QVariant headerData(int section, Qt::Orientation orientation, - int role = Qt::DisplayRole) const; - virtual bool setData(const QModelIndex & index, - const QVariant & value, - int role); - + Qt::ItemFlags flags(const QModelIndex & index) const override; + QVariant headerData(int section, + Qt::Orientation orientation, + int role = Qt::DisplayRole) const override; + bool setData(const QModelIndex & index, + const QVariant & value, + int role) override; + + inline CSwordModuleInfo * module(QModelIndex const & index) const { + return static_cast<CSwordModuleInfo *>( + data(index, + BtBookshelfModel::ModulePointerRole).value<void *>()); + } inline QAbstractItemModel * sourceModel() const { return m_sourceModel; } inline const Grouping & groupingOrder() const { return m_groupingOrder; } inline bool checkable() const { return m_checkable; } inline CheckedBehavior defaultChecked() const { return m_defaultChecked; } inline QList<CSwordModuleInfo *> modules() const { return m_modules.keys(); } - inline const QSet<CSwordModuleInfo *> & checkedModules() const { + inline BtModuleSet const & checkedModules() const { return m_checkedModulesCache; } @@ -132,7 +138,7 @@ public slots: inline void setDefaultChecked(CheckedBehavior b) { m_defaultChecked = b; } - void setCheckedModules(const QSet<CSwordModuleInfo *> & modules); + void setCheckedModules(BtConstModuleSet const & modules); signals: @@ -191,7 +197,7 @@ private: /* Fields: */ CheckedBehavior m_defaultChecked; bool m_checkable; - QSet<CSwordModuleInfo *> m_checkedModulesCache; + BtModuleSet m_checkedModulesCache; }; diff --git a/src/backend/bookshelfmodel/categoryitem.cpp b/src/backend/bookshelfmodel/categoryitem.cpp index 20ba8e4..490237c 100644 --- a/src/backend/bookshelfmodel/categoryitem.cpp +++ b/src/backend/bookshelfmodel/categoryitem.cpp @@ -4,13 +4,13 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * **********/ -#include "backend/bookshelfmodel/categoryitem.h" +#include "categoryitem.h" namespace BookshelfModel { diff --git a/src/backend/bookshelfmodel/categoryitem.h b/src/backend/bookshelfmodel/categoryitem.h index 135f337..9e6a328 100644 --- a/src/backend/bookshelfmodel/categoryitem.h +++ b/src/backend/bookshelfmodel/categoryitem.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -13,11 +13,11 @@ #ifndef CATEGORYITEM_H #define CATEGORYITEM_H -#include "backend/bookshelfmodel/item.h" +#include "item.h" #include <QCoreApplication> -#include "backend/bookshelfmodel/btbookshelfmodel.h" -#include "backend/drivers/cswordmoduleinfo.h" +#include "../drivers/cswordmoduleinfo.h" +#include "btbookshelfmodel.h" namespace BookshelfModel { @@ -33,13 +33,13 @@ public: /* Methods: */ return m_category; } - QVariant data(int role = Qt::DisplayRole) const; + QVariant data(int role = Qt::DisplayRole) const override; - inline bool fitFor(const CSwordModuleInfo & module) const { + inline bool fitFor(const CSwordModuleInfo & module) const override { return module.category() == m_category; } - bool operator<(const Item & other) const; + bool operator<(const Item & other) const override; private: /* Fields: */ diff --git a/src/backend/bookshelfmodel/indexingitem.cpp b/src/backend/bookshelfmodel/indexingitem.cpp index 46488a4..991c5ef 100644 --- a/src/backend/bookshelfmodel/indexingitem.cpp +++ b/src/backend/bookshelfmodel/indexingitem.cpp @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * diff --git a/src/backend/bookshelfmodel/indexingitem.h b/src/backend/bookshelfmodel/indexingitem.h index 3e1e0cd..0483726 100644 --- a/src/backend/bookshelfmodel/indexingitem.h +++ b/src/backend/bookshelfmodel/indexingitem.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -13,9 +13,9 @@ #ifndef INDEXINGITEM_H #define INDEXINGITEM_H -#include "backend/bookshelfmodel/item.h" +#include "item.h" -#include "backend/drivers/cswordmoduleinfo.h" +#include "../drivers/cswordmoduleinfo.h" namespace BookshelfModel { @@ -27,9 +27,9 @@ public: /* Methods: */ inline IndexingItem(const CSwordModuleInfo & module) : m_indexed(module.hasIndex()) {} - QVariant data(int role = Qt::DisplayRole) const; + QVariant data(int role = Qt::DisplayRole) const override; - inline bool fitFor(const CSwordModuleInfo & module) const { + inline bool fitFor(const CSwordModuleInfo & module) const override { return module.hasIndex() == m_indexed; } diff --git a/src/backend/bookshelfmodel/item.cpp b/src/backend/bookshelfmodel/item.cpp index 9d6e5af..a6fcf0b 100644 --- a/src/backend/bookshelfmodel/item.cpp +++ b/src/backend/bookshelfmodel/item.cpp @@ -4,15 +4,15 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * **********/ -#include "backend/bookshelfmodel/item.h" +#include "item.h" -#include "backend/bookshelfmodel/btbookshelfmodel.h" +#include "btbookshelfmodel.h" namespace BookshelfModel { @@ -22,7 +22,7 @@ Item::~Item() { } int Item::indexFor(Item * newItem) { - Q_ASSERT(newItem); + BT_ASSERT(newItem); if (m_children.empty()) return 0; @@ -30,7 +30,7 @@ int Item::indexFor(Item * newItem) { int i = 0; for (;;) { Item * const nextItem(m_children.at(i)); - Q_ASSERT(nextItem->type() == newItem->type()); + BT_ASSERT(nextItem->type() == newItem->type()); if (*newItem < *nextItem) return i; @@ -50,7 +50,7 @@ QVariant Item::data(int role) const { if (m_children.empty()) return true; - Q_FOREACH (Item * child, m_children) + Q_FOREACH(Item const * const child, m_children) if (!child->data(role).toBool()) return false; return true; diff --git a/src/backend/bookshelfmodel/item.h b/src/backend/bookshelfmodel/item.h index 712d4a2..9f12d4a 100644 --- a/src/backend/bookshelfmodel/item.h +++ b/src/backend/bookshelfmodel/item.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -15,6 +15,7 @@ #include <QList> #include <QVariant> +#include "../../util/btassert.h" class CSwordModuleInfo; @@ -37,7 +38,7 @@ public: /* Methods: */ inline Item(Type type) : m_type(type) - , m_parent(0) + , m_parent(nullptr) , m_checkState(Qt::Unchecked) {} virtual ~Item(); @@ -69,7 +70,7 @@ public: /* Methods: */ \retval -1 if this item has no parent. */ inline int childIndex() const { - return m_parent == 0 + return m_parent == nullptr ? -1 : m_parent->m_children.indexOf(const_cast<Item *>(this)); } @@ -88,8 +89,8 @@ public: /* Methods: */ \param[in] newItem The item to insert. */ inline void insertChild(int index, Item * newItem) { - Q_ASSERT(newItem != 0); - Q_ASSERT(index >= 0 && index <= m_children.size()); + BT_ASSERT(newItem); + BT_ASSERT(index >= 0 && index <= m_children.size()); m_children.insert(index, newItem); newItem->setParent(this); } @@ -97,14 +98,14 @@ public: /* Methods: */ template <class T> inline T * getGroupItem(CSwordModuleInfo & module, int & outIndex) { for (int i = 0; i < m_children.size(); i++) { - Q_ASSERT(m_children.at(i)->type() == T::staticItemType()); + BT_ASSERT(m_children.at(i)->type() == T::staticItemType()); T * item = static_cast<T *>(m_children.at(i)); if (item->fitFor(module)) { outIndex = i; return item; } } - return 0; + return nullptr; } /** @@ -142,10 +143,8 @@ public: /* Methods: */ private: /* Methods: */ - inline void setParent(Item * parent) { - Q_ASSERT(parent != 0); - m_parent = parent; - } + inline void setParent(Item * parent) noexcept + { m_parent = (BT_ASSERT(parent), parent); } private: /* Fields: */ @@ -163,9 +162,7 @@ public: /* Methods: */ inline RootItem() : Item(Item::ITEM_ROOT) {} - inline virtual bool fitFor(const CSwordModuleInfo &) const { - return true; - } + inline bool fitFor(const CSwordModuleInfo &) const override { return true; } }; diff --git a/src/backend/bookshelfmodel/languageitem.cpp b/src/backend/bookshelfmodel/languageitem.cpp index 072d720..3831b96 100644 --- a/src/backend/bookshelfmodel/languageitem.cpp +++ b/src/backend/bookshelfmodel/languageitem.cpp @@ -4,15 +4,15 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * **********/ -#include "backend/bookshelfmodel/languageitem.h" +#include "languageitem.h" -#include "util/geticon.h" +#include "../../util/cresmgr.h" namespace BookshelfModel { @@ -24,7 +24,7 @@ QVariant LanguageItem::data(int role) const { return m_language->translatedName(); case Qt::DecorationRole: - return util::getIcon("flag.svg"); + return CResMgr::modules::icon_moduleLanguage(); default: return Item::data(role); diff --git a/src/backend/bookshelfmodel/languageitem.h b/src/backend/bookshelfmodel/languageitem.h index 1d1d5fa..9587e3d 100644 --- a/src/backend/bookshelfmodel/languageitem.h +++ b/src/backend/bookshelfmodel/languageitem.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -13,10 +13,10 @@ #ifndef LANGUAGEITEM_H #define LANGUAGEITEM_H -#include "backend/bookshelfmodel/item.h" +#include "item.h" -#include "backend/bookshelfmodel/btbookshelfmodel.h" -#include "backend/drivers/cswordmoduleinfo.h" +#include "../drivers/cswordmoduleinfo.h" +#include "btbookshelfmodel.h" namespace BookshelfModel { @@ -28,9 +28,9 @@ public: /* Methods: */ inline LanguageItem(const CSwordModuleInfo & module) : m_language(module.language()) {} - QVariant data(int role = Qt::DisplayRole) const; + QVariant data(int role = Qt::DisplayRole) const override; - inline bool fitFor(const CSwordModuleInfo & module) const { + inline bool fitFor(const CSwordModuleInfo & module) const override { return module.language() == m_language; } diff --git a/src/backend/bookshelfmodel/moduleitem.cpp b/src/backend/bookshelfmodel/moduleitem.cpp index ffe8eb8..9c6112a 100644 --- a/src/backend/bookshelfmodel/moduleitem.cpp +++ b/src/backend/bookshelfmodel/moduleitem.cpp @@ -4,16 +4,15 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * **********/ -#include "backend/bookshelfmodel/moduleitem.h" +#include "moduleitem.h" -#include "backend/bookshelfmodel/btbookshelftreemodel.h" -#include "util/cresmgr.h" +#include "btbookshelftreemodel.h" namespace BookshelfModel { diff --git a/src/backend/bookshelfmodel/moduleitem.h b/src/backend/bookshelfmodel/moduleitem.h index 071e3fe..3182c06 100644 --- a/src/backend/bookshelfmodel/moduleitem.h +++ b/src/backend/bookshelfmodel/moduleitem.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -13,10 +13,10 @@ #ifndef MODULEITEM_H #define MODULEITEM_H -#include "backend/bookshelfmodel/item.h" +#include "item.h" -#include "backend/bookshelfmodel/btbookshelfmodel.h" -#include "backend/drivers/cswordmoduleinfo.h" +#include "../drivers/cswordmoduleinfo.h" +#include "btbookshelfmodel.h" class BtBookshelfTreeModel; @@ -37,13 +37,13 @@ public: /* Methods: */ Reimplementation of Item::data() which dispatches all requests to the parent model (BtBookshelfTreeModel). */ - virtual QVariant data(int role = Qt::DisplayRole) const; + QVariant data(int role = Qt::DisplayRole) const override; inline CSwordModuleInfo & moduleInfo() const { return m_moduleInfo; } - inline virtual bool fitFor(const CSwordModuleInfo &) const { + inline bool fitFor(const CSwordModuleInfo &) const override { return false; } diff --git a/src/backend/btbookmarksmodel.cpp b/src/backend/btbookmarksmodel.cpp new file mode 100644 index 0000000..10398c8 --- /dev/null +++ b/src/backend/btbookmarksmodel.cpp @@ -0,0 +1,985 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + + +/** + Total change list that should be applied after refactoring complete: + non latin bookmark titles shown with unrecognized symbols + feature request: hold Shift and Ctrl upon dragging item + move loader to private class + add ability to create bookmarks data with setData/insertRows + unrecognized characters increaases in size file each save/load + root folder for bookmarks +*/ + +#include "btbookmarksmodel.h" + +#include <memory> +#include <QDomElement> +#include <QDomNode> +#include <QFile> +#include <QIODevice> +#include <QList> +#include <QString> +#include <QTextCodec> +#include <QTextStream> +#include <QTime> +#include <QTimer> +#include "../bibletimeapp.h" +#include "../util/btassert.h" +#include "../util/btconnect.h" +#include "../util/cresmgr.h" +#include "../util/directory.h" +#include "../util/tool.h" +#include "btglobal.h" +#include "config/btconfig.h" +#include "drivers/cswordmoduleinfo.h" +#include "keys/cswordversekey.h" +#include "managers/cswordbackend.h" + + +#define CURRENT_SYNTAX_VERSION 1 + + +namespace { +inline QString toHeader(QString const & key, QString const & moduleName) +{ return QString::fromLatin1("%1 (%2)").arg(key).arg(moduleName); } +} + +class BtBookmarksModelPrivate { + +public: /* Tyepes */ + + class BookmarkItemBase { + + public: /* Methods: */ + + inline BookmarkItemBase(BookmarkItemBase * parent = nullptr) + : m_parent(parent) { + if(m_parent) { + BT_ASSERT(!m_parent->m_children.contains(this)); + m_parent->m_children.append(this); + } + } + BookmarkItemBase(const BookmarkItemBase & other) + : m_flags(other.m_flags) + , m_icon(other.m_icon) + , m_parent(other.m_parent) + , m_text(other.m_text) + , m_tooltip(other.m_tooltip) {;} + virtual ~BookmarkItemBase() { + qDeleteAll(m_children); + } + + /** Children routines. */ + inline void addChild(BookmarkItemBase * child) { + child->setParent(this); + BT_ASSERT(!m_children.contains(child)); + m_children.append(child); + } + + inline int childCount() const { return m_children.size(); } + + inline BookmarkItemBase * child(int index) const { + return m_children[index]; + } + + inline QList<BookmarkItemBase *> & children() { + return m_children; + } + + inline void insertChild(int index, BookmarkItemBase * child) { + child->setParent(this); + BT_ASSERT(!m_children.contains(child)); + m_children.insert(index, child); + } + + inline void insertChildren(int index, QList<BookmarkItemBase *> children) { + Q_FOREACH(BookmarkItemBase * const c, children) + insertChild(index++, c); + } + + inline void removeChild(int index) { + delete m_children[index]; + m_children.removeAt(index); + } + + + inline void setText(const QString & text) { m_text = text; } + + inline const QString & text() const { return m_text; } + + inline void setToolTip(const QString & tooltip) { m_tooltip = tooltip; } + + virtual QString toolTip() const { return m_tooltip; } + + inline void setFlags(Qt::ItemFlags flags) { m_flags = flags; } + + inline Qt::ItemFlags flags() const { return m_flags; } + + inline void setIcon(const QIcon & icon) { m_icon = icon; } + + inline QIcon icon() const { return m_icon; } + + inline void setParent(BookmarkItemBase * parent) { + m_parent = parent; + } + + inline BookmarkItemBase * parent() const { return m_parent; } + + /** + \returns index of this item in parent's child array. + */ + inline int index() const { + BT_ASSERT(parent()); + for(int i = 0; i < parent()->childCount(); ++i) + if(parent()->child(i) == this) + return i; + return -1; + } + + private: + + QList<BookmarkItemBase *> m_children; + Qt::ItemFlags m_flags; + QIcon m_icon; + BookmarkItemBase * m_parent; + QString m_text; + QString m_tooltip; + + }; + + class BookmarkItem : public BookmarkItemBase { + public: + friend class BookmarkLoader; + + BookmarkItem(BookmarkItemBase * parent); + + /** Creates a bookmark with module, key and description. */ + BookmarkItem(const CSwordModuleInfo & module, const QString & key, + const QString & description, const QString & title); + + /** Creates a copy. */ + BookmarkItem(const BookmarkItem & other); + + /** Returns the used module, 0 if there is no such module. */ + CSwordModuleInfo * module() const; + + /** Returns the used key. */ + QString key() const; + + inline void setKey(const QString & key) { m_key = key; } + + /** Returns the used description. */ + inline const QString &description() const { return m_description; } + + inline void setDescription(const QString & description) { m_description = description; } + + /** Returns a tooltip for this bookmark. */ + QString toolTip() const override; + + /** Returns the english key.*/ + inline const QString & englishKey() const { return m_key; } + + inline void setModule(const QString & moduleName) { m_moduleName = moduleName; } + + inline const QString & moduleName() const { return m_moduleName; } + + private: + QString m_key; + QString m_description; + QString m_moduleName; + + }; + + class BookmarkFolder : public BookmarkItemBase { + public: + + BookmarkFolder(const QString & name, BookmarkItemBase * parent = nullptr); + + /** Returns a list of direct childs of this item. */ + QList<BookmarkItemBase *> getChildList() const; + + /** Returns true if the given item is this or a direct or indirect subitem of this. */ + bool hasDescendant(BookmarkItemBase const * item) const; + + /** Creates a deep copy of this item. */ + BookmarkFolder * deepCopy() const; + + }; + + +public: /* Methods */ + + BtBookmarksModelPrivate(BtBookmarksModel * parent) + : m_rootItem(new BookmarkFolder("Root")) + , q_ptr(parent) + { + m_saveTimer.setInterval(0.5 * 60 * 1000); + m_saveTimer.setSingleShot(true); + } + ~BtBookmarksModelPrivate() { delete m_rootItem; } + + inline static QString defaultBookmarksFile() { + return util::directory::getUserBaseDir().absolutePath() + "/bookmarks.xml"; + } + + BookmarkItemBase * item(const QModelIndex & index) const { + if(index.isValid()) { +#ifdef QT_DEBUG + { + // check for item in tree + QList<BookmarkItemBase *> items; + items << m_rootItem; + for(int c = 0; ; ++c) { + if(items[c] == index.internalPointer()) + break; + if(items[c]->childCount()) + items.append(items[c]->children()); + BT_ASSERT(c < items.size()); + } + } +#endif + return reinterpret_cast<BookmarkItemBase *>(index.internalPointer()); + } + else + return m_rootItem; + } + + template <typename T> + inline T * itemAs(QModelIndex const & index) const + { return dynamic_cast<T *>(item(index)); } + + /// \test + void printItems() const { + QList<BookmarkItemBase *> items; + QList<int> spaces; + items << m_rootItem; + spaces << 0; + for(int c = 0; c < items.size(); ++c) { + // qDebug() << QString().fill('\t', spaces[c]) << items[c]->text().left(24) << items[c] + // << items[c]->parent() << items[c]->childCount(); + if(items[c]->childCount()) + for(int i = 0; i < items[c]->childCount(); ++i) { + items.insert(c + i + 1, items[c]->children()[i]); + spaces.insert(c + i + 1, spaces[c] + 1); + } + } + } + + void needSave(){ + if(m_defaultModel == q_ptr){ + if(!m_saveTimer.isActive()) + m_saveTimer.start(); + } + } +public: /* Loader */ + + /** Loads a list of items (with subitem trees) from a named file + * or from the default bookmarks file. */ + QList<BookmarkItemBase *> loadTree(QString fileName = QString::null) { + QList<BookmarkItemBase*> itemList; + + QDomDocument doc; + QString bookmarksFile = loadXmlFromFile(fileName); + if (bookmarksFile.isNull()) + return QList<BookmarkItemBase*>(); + + doc.setContent(bookmarksFile); + QDomElement document = doc.documentElement(); + if ( document.tagName() != "SwordBookmarks" ) { + qWarning("Not a BibleTime Bookmark XML file"); + return QList<BookmarkItemBase*>(); + } + + QDomElement child = document.firstChild().toElement(); + + while ( !child.isNull() && child.parentNode() == document) { + BookmarkItemBase* i = handleXmlElement(child, nullptr); + itemList.append(i); + if (!child.nextSibling().isNull()) { + child = child.nextSibling().toElement(); + } + else { + child = QDomElement(); //null + } + + } + + return itemList; + } + + /** Create a new item from a document element. */ + BookmarkItemBase * handleXmlElement(QDomElement & element, BookmarkItemBase * parent) { + BookmarkItemBase* newItem = nullptr; + if (element.tagName() == "Folder") { + BookmarkFolder* newFolder = new BookmarkFolder(QString::null, parent); + if (element.hasAttribute("caption")) { + newFolder->setText(element.attribute("caption")); + } + QDomNodeList childList = element.childNodes(); + for (int i = 0; i < childList.length(); i++) { + QDomElement newElement = childList.at(i).toElement(); + handleXmlElement(newElement, newFolder); // passing parent in constructor will add items to tree + } + newItem = newFolder; + } + else if (element.tagName() == "Bookmark") { + BookmarkItem* newBookmarkItem = new BookmarkItem(parent); + if (element.hasAttribute("modulename")) { + //we use the name in all cases, even if the module isn't installed anymore + newBookmarkItem->setModule(element.attribute("modulename")); + } + if (element.hasAttribute("key")) { + newBookmarkItem->setKey(element.attribute("key")); + } + if (element.hasAttribute("description")) { + newBookmarkItem->setDescription(element.attribute("description")); + } + if (element.hasAttribute("title")) { + newBookmarkItem->setText(element.attribute("title")); + } + newItem = newBookmarkItem; + } + return newItem; + } + + /** Loads a bookmark XML document from a named file or from the default bookmarks file. */ + QString loadXmlFromFile(QString fileName = QString::null) { + + if (fileName.isEmpty()) + fileName = defaultBookmarksFile(); + + QFile file(fileName); + if (!file.exists()) + return QString::null; + + QString xml; + if (file.open(QIODevice::ReadOnly)) { + QTextStream t; + t.setAutoDetectUnicode(false); + t.setCodec(QTextCodec::codecForName("UTF-8")); + t.setDevice(&file); + xml = t.readAll(); + file.close(); + } + return xml; + } + + /** Takes one item and saves the tree which is under it to a named file + * or to the default bookmarks file, asking the user about overwriting if necessary. */ + QString serializeTreeFromRootItem(BookmarkItemBase * rootItem) { + BT_ASSERT(rootItem); + + QDomDocument doc("DOC"); + doc.appendChild( doc.createProcessingInstruction( "xml", "version=\"1.0\" encoding=\"UTF-8\"" ) ); + + QDomElement content = doc.createElement("SwordBookmarks"); + content.setAttribute("syntaxVersion", CURRENT_SYNTAX_VERSION); + doc.appendChild(content); + + //append the XML nodes of all child items + + for (int i = 0; i < rootItem->childCount(); i++) { + saveItem(rootItem->child(i), content); + } + return doc.toString(); + } + + /** Writes one item to a document element. */ + void saveItem(BookmarkItemBase * item, QDomElement & parentElement) { + BookmarkFolder* folderItem = nullptr; + BookmarkItem* bookmarkItem = nullptr; + + if ((folderItem = dynamic_cast<BookmarkFolder*>(item))) { + QDomElement elem = parentElement.ownerDocument().createElement("Folder"); + elem.setAttribute("caption", folderItem->text()); + + parentElement.appendChild(elem); + + for (int i = 0; i < folderItem->childCount(); i++) { + saveItem(folderItem->child(i), elem); + } + } + else if ((bookmarkItem = dynamic_cast<BookmarkItem*>(item))) { + QDomElement elem = parentElement.ownerDocument().createElement("Bookmark"); + + elem.setAttribute("key", bookmarkItem->englishKey()); + elem.setAttribute("description", bookmarkItem->description()); + elem.setAttribute("modulename", bookmarkItem->moduleName()); + elem.setAttribute("moduledescription", bookmarkItem->module() ? bookmarkItem->module()->config(CSwordModuleInfo::Description) : QString::null); + if (!bookmarkItem->text().isEmpty()) { + elem.setAttribute("title", bookmarkItem->text()); + } + parentElement.appendChild(elem); + } + } + + +public: /* Fields */ + + BookmarkFolder * m_rootItem; + QTimer m_saveTimer; + static BtBookmarksModel * m_defaultModel; + + Q_DECLARE_PUBLIC(BtBookmarksModel); + BtBookmarksModel * const q_ptr; + +}; + +BtBookmarksModel * BtBookmarksModelPrivate::m_defaultModel = nullptr; + +using BookmarkItemBase = BtBookmarksModelPrivate::BookmarkItemBase; +using BookmarkItem = BtBookmarksModelPrivate::BookmarkItem; +using BookmarkFolder = BtBookmarksModelPrivate::BookmarkFolder; + + +BookmarkFolder::BookmarkFolder(const QString & name, BookmarkItemBase * parent) + : BookmarkItemBase(parent) { + setText(name); + setFlags(Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsEnabled); + setIcon(CResMgr::mainIndex::closedFolder::icon()); +} + +QList<BookmarkItemBase*> BookmarkFolder::getChildList() const { + QList<BookmarkItemBase*> list; + for (int i = 0; i < childCount(); i++) { + list.append(child(i)); + } + return list; +} + +bool BookmarkFolder::hasDescendant(BookmarkItemBase const * const item) const { + if (this == item) + return true; + if (getChildList().indexOf(const_cast<BookmarkItemBase *>(item)) > -1) + return true; + Q_FOREACH(BookmarkItemBase const * const childItem, getChildList()) + if (BookmarkFolder const * const folder = + dynamic_cast<BookmarkFolder const *>(childItem)) + if (folder->hasDescendant(childItem)) + return true; + return false; +} + +BookmarkFolder * BookmarkFolder::deepCopy() const { + BookmarkFolder* newFolder = new BookmarkFolder(this->text()); + Q_FOREACH(BookmarkItemBase const * const subitem, getChildList()) { + if (BookmarkItem const * const bmItem = + dynamic_cast<BookmarkItem const *>(subitem)) + { + newFolder->addChild(new BookmarkItem(*bmItem)); + } else if (BookmarkFolder const * const bmFolder = + dynamic_cast<BookmarkFolder const *>(subitem)) + { + newFolder->addChild(bmFolder->deepCopy()); + } + } + return newFolder; +} + +BookmarkItem::BookmarkItem(CSwordModuleInfo const & module, + const QString & key, + const QString & description, + const QString & title) + : m_description(description) + , m_moduleName(module.name()) +{ + Q_UNUSED(title); + + if (((module.type() == CSwordModuleInfo::Bible) || (module.type() == CSwordModuleInfo::Commentary))) { + /// here we only translate \param key into english + sword::VerseKey vk(key.toUtf8().constData(), key.toUtf8().constData(), + static_cast<sword::VerseKey *>(module.module().getKey())->getVersificationSystem()); + CSwordVerseKey k(&vk, &module); + k.setLocale("en"); + m_key = k.key(); + } + else { + m_key = key; + }; + + setIcon(CResMgr::mainIndex::bookmark::icon()); + setText(toHeader(key, module.name())); + setFlags(Qt::ItemIsSelectable /*| Qt::ItemIsEditable*/ | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsEnabled); +} + +BookmarkItem::BookmarkItem(BookmarkItemBase * parent) + : BookmarkItemBase(parent) { + setFlags(Qt::ItemIsSelectable /*| Qt::ItemIsEditable*/ | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsEnabled); + setIcon(CResMgr::mainIndex::bookmark::icon()); + setText(toHeader(key(), module() ? module()->name() : QObject::tr("unknown"))); +} + +BookmarkItem::BookmarkItem(const BookmarkItem & other) + : BookmarkItemBase(other) + , m_key(other.m_key) + , m_description(other.m_description) + , m_moduleName(other.m_moduleName) +{ + setIcon(CResMgr::mainIndex::bookmark::icon()); + setText(toHeader(key(), module() ? module()->name() : QObject::tr("unknown"))); +} + +CSwordModuleInfo *BookmarkItem::module() const { + return CSwordBackend::instance()->findModuleByName(m_moduleName); +} + +QString BookmarkItem::key() const { + const QString englishKeyName = englishKey(); + if (!module()) { + return englishKeyName; + } + + QString returnKeyName = englishKeyName; + if ((module()->type() == CSwordModuleInfo::Bible) || (module()->type() == CSwordModuleInfo::Commentary)) { + /// here we only translate \param key into current book name language + sword::VerseKey vk(englishKeyName.toUtf8().constData(), englishKeyName.toUtf8().constData(), + static_cast<sword::VerseKey *>(module()->module().getKey())->getVersificationSystem()); + CSwordVerseKey k(&vk, module()); + k.setLocale(CSwordBackend::instance()->booknameLanguage().toLatin1() ); + returnKeyName = k.key(); + } + + return returnKeyName; +} + +QString BookmarkItem::toolTip() const { + if (!module()) + return QString::null; + + FilterOptions filterOptions = btConfig().getFilterOptions(); + filterOptions.footnotes = false; + filterOptions.scriptureReferences = false; + CSwordBackend::instance()->setFilterOptions(filterOptions); + + std::unique_ptr<CSwordKey> k(CSwordKey::createInstance(module())); + BT_ASSERT(k); + k->setKey(key()); + + // const CLanguageMgr::Language* lang = module()->language(); + // BtConfig::FontSettingsPair fontPair = getBtConfig().getFontForLanguage(lang); + + QString const header(toHeader(key(), module()->name())); + QString ret("<b>"); + ret.append(header).append(")</b>"); + QString const txt(text()); + if (txt != header) + ret.append("<br>").append(txt); + return ret.append("<hr>").append(description()); +} + + +BtBookmarksModel::BtBookmarksModel(QObject * parent) + : QAbstractItemModel(parent) + , d_ptr(new BtBookmarksModelPrivate(this)) +{ + load(); +} + +BtBookmarksModel::BtBookmarksModel(const QString & fileName, const QString & rootFolder, QObject * parent) + : QAbstractItemModel(parent) + , d_ptr(new BtBookmarksModelPrivate(this)) +{ + /// \todo take into account rootFolder + BT_ASSERT(rootFolder.isEmpty() && "specifying root folder for bookmarks is not supported at moment"); + + load(fileName); +} + +BtBookmarksModel::~BtBookmarksModel() { + Q_D(BtBookmarksModel); + + if(d->m_saveTimer.isActive()) + save(); + + delete d_ptr; +} + +int BtBookmarksModel::rowCount(const QModelIndex & parent) const { + Q_D(const BtBookmarksModel); + + return d->item(parent)->childCount(); +} + +int BtBookmarksModel::columnCount(const QModelIndex & parent) const { + Q_UNUSED(parent); + return 1; +} + +bool BtBookmarksModel::hasChildren(const QModelIndex & parent) const { + return rowCount(parent) > 0; +} +QModelIndex BtBookmarksModel::index(int row, int column, const QModelIndex & parent) const { + Q_D(const BtBookmarksModel); + + const BookmarkItemBase * i = d->item(parent); + if(i->childCount() > row && row >= 0) + return createIndex(row, column, i->child(row)); + return QModelIndex(); +} + +QModelIndex BtBookmarksModel::parent(const QModelIndex & index) const { + Q_D(const BtBookmarksModel); + + const BookmarkItemBase * i = d->item(index); + return (i->parent() == nullptr || i->parent()->parent() == nullptr) ? + QModelIndex() : createIndex(i->parent()->index(), 0, i->parent()); +} + +QVariant BtBookmarksModel::data(const QModelIndex & index, int role) const { + Q_D(const BtBookmarksModel); + + const BookmarkItemBase * i = d->item(index); + + switch(role) + { + case Qt::DisplayRole: + case Qt::EditRole: + return i->text(); + case Qt::ToolTipRole: + return i->toolTip(); + case Qt::DecorationRole: + return i->icon(); + } + return QVariant(); +} + +Qt::ItemFlags BtBookmarksModel::flags(const QModelIndex & index) const { + Q_D(const BtBookmarksModel); + + return d->item(index)->flags(); +} + +QVariant BtBookmarksModel::headerData(int section, Qt::Orientation orientation, int role) const { + Q_UNUSED(section); + Q_UNUSED(orientation); + Q_UNUSED(role); + + return QVariant(); +} + +bool BtBookmarksModel::setData(const QModelIndex & index, const QVariant & val, int role) { + Q_D(BtBookmarksModel); + + BookmarkItemBase * i = d->item(index); + switch(role) + { + case Qt::DisplayRole: + case Qt::EditRole: + { + i->setText(val.toString()); + if(dynamic_cast<BookmarkFolder *>(i) || dynamic_cast<BookmarkItem *>(i)) + d->needSave(); + return true; + } + case Qt::ToolTipRole: + { + i->setToolTip(val.toString()); + if(dynamic_cast<BookmarkFolder *>(i) || dynamic_cast<BookmarkItem *>(i)) + d->needSave(); + return true; + } + } + return false; +} + +bool BtBookmarksModel::removeRows(int row, int count, const QModelIndex & parent) +{ + Q_D(BtBookmarksModel); + + BT_ASSERT(rowCount(parent) >= row + count); + + beginRemoveRows(parent, row, row + count - 1); + + for(int i = 0; i < count; ++i) { + d->item(parent)->removeChild(row); + } + endRemoveRows(); + + d->needSave(); + + return true; +} + +bool BtBookmarksModel::insertRows(int row, int count, const QModelIndex &parent) +{ + Q_D(BtBookmarksModel); + + BT_ASSERT(rowCount(parent) >= row + count - 1); + + beginInsertRows(parent, row, row + count - 1); + + for(int i = 0; i < count; ++i) { + d->item(parent)->insertChild(row, new BookmarkItemBase); + } + endInsertRows(); + + return true; + +} + +bool BtBookmarksModel::save(QString fileName, const QModelIndex & rootItem) { + Q_D(BtBookmarksModel); + + QString const serializedTree( + d->serializeTreeFromRootItem(d->item(rootItem))); + if (fileName.isEmpty()) + fileName = BtBookmarksModelPrivate::defaultBookmarksFile(); + + util::tool::savePlainFile(fileName, + serializedTree, + true, + QTextCodec::codecForName("UTF-8")); + + if(d->m_saveTimer.isActive()) + d->m_saveTimer.stop(); + + return true; +} + +bool BtBookmarksModel::load(QString fileName, const QModelIndex & rootItem) { + Q_D(BtBookmarksModel); + + BookmarkItemBase * i = d->item(rootItem); + QList<BookmarkItemBase *> items = d->loadTree(fileName); + + if(!rootItem.isValid() && fileName.isEmpty()) { + BT_ASSERT(!d->m_defaultModel && "Only one default model allowed!"); + BT_CONNECT(&d->m_saveTimer, &QTimer::timeout, + this, &BtBookmarksModel::slotSave); + d->m_defaultModel = this; + } + + if(items.size() == 0) + return false; + + beginInsertRows(rootItem, i->childCount(), i->childCount() + items.size() - 1); + + i->insertChildren(i->childCount(), items); + + endInsertRows(); + + return true; +} + +bool BtBookmarksModel::isFolder(const QModelIndex &index) const +{ + Q_D(const BtBookmarksModel); + return d->itemAs<BookmarkFolder const>(index); +} + +bool BtBookmarksModel::isBookmark(const QModelIndex &index) const +{ + Q_D(const BtBookmarksModel); + return d->itemAs<BookmarkItem const>(index); +} + +QModelIndexList BtBookmarksModel::copyItems(int row, const QModelIndex & parent, const QModelIndexList & toCopy) +{ + Q_D(BtBookmarksModel); + + bool bookmarksOnly = true; + bool targetIncluded = false; + bool moreThanOneFolder = false; + + QList<BookmarkItemBase *> newList; + + Q_FOREACH(QModelIndex const index, toCopy) { + if (BookmarkFolder const * const folder = + d->itemAs<BookmarkFolder const>(index)) + { + bookmarksOnly = false; + if (toCopy.count() > 1) { // only one item allowed if a folder is selected + moreThanOneFolder = true; + break; + } + if (folder->hasDescendant(d->item(parent))) { // dropping to self or descendand not allowed + targetIncluded = true; + break; + } + } + else { + newList.append(new BookmarkItem(*(d->itemAs<BookmarkItem>(index)))); + } + } + + if (!bookmarksOnly && toCopy.count() == 1) + newList.append(d->itemAs<BookmarkFolder const>(toCopy[0])->deepCopy()); + if (!bookmarksOnly && toCopy.count() > 1) { + // wrong amount of items + moreThanOneFolder = true; + } + + if (moreThanOneFolder || targetIncluded) { + return QModelIndexList(); + } + + + beginInsertRows(parent, row, row + newList.size() - 1); + + d->item(parent)->insertChildren(row, newList); + + endInsertRows(); + + d->needSave(); + + QModelIndexList result; + for(int i = 0; i < newList.size(); ++i) { + result.append(index(row + i, 0, parent)); + } + return result; +} + +CSwordModuleInfo * BtBookmarksModel::module(const QModelIndex & index) const +{ + Q_D(const BtBookmarksModel); + + if (BookmarkItem const * const i = d->itemAs<BookmarkItem const>(index)) + return i->module(); + return nullptr; +} + +QString BtBookmarksModel::key(const QModelIndex & index) const +{ + Q_D(const BtBookmarksModel); + + if (BookmarkItem const * const i = d->itemAs<BookmarkItem const>(index)) + return i->key(); + return QString(); +} + +QString BtBookmarksModel::description(const QModelIndex &index) const +{ + Q_D(const BtBookmarksModel); + + if (BookmarkItem const * const i = d->itemAs<BookmarkItem const>(index)) + return i->description(); + return QString(); +} + +void BtBookmarksModel::setDescription(const QModelIndex &index, const QString &description) +{ + Q_D(BtBookmarksModel); + + if (BookmarkItem * const i = d->itemAs<BookmarkItem>(index)) { + i->setDescription(description); + d->needSave(); + } +} + +QModelIndex BtBookmarksModel::addBookmark(int const row, + QModelIndex const & parent, + CSwordModuleInfo const & module, + QString const & key, + QString const & description, + QString const & title) +{ + Q_D(BtBookmarksModel); + + if (BookmarkFolder * const i = d->itemAs<BookmarkFolder>(parent)) { + int r = row < 0 ? row + rowCount(parent) + 1 : row; + + beginInsertRows(parent, r, r); + + BookmarkItem * c = new BookmarkItem(module, key, description, title); + i->insertChild(r, c); + + endInsertRows(); + + d->needSave(); + + return createIndex(c->index(), 0, c); + } + return QModelIndex(); +} + +QModelIndex BtBookmarksModel::addFolder(int row, const QModelIndex &parent, const QString &name) +{ + Q_D(BtBookmarksModel); + + if (BookmarkFolder * const i = d->itemAs<BookmarkFolder>(parent)) { + beginInsertRows(parent, row, row); + + BookmarkFolder * c = new BookmarkFolder(name.isEmpty() ? QObject::tr("New folder") : name); + i->insertChild(row, c); + + endInsertRows(); + + d->needSave(); + + return createIndex(c->index(), 0, c); + } + return QModelIndex(); +} + +bool BtBookmarksModel::hasDescendant(const QModelIndex &baseIndex, const QModelIndex &testIndex) const +{ + Q_D(const BtBookmarksModel); + + if (BookmarkFolder const * const f = + d->itemAs<BookmarkFolder const>(baseIndex)) + return f->hasDescendant(d->item(testIndex)); + return false; +} + +bool BtBookmarksModelSortAscending(BookmarkItemBase * i1, BookmarkItemBase * i2) +{ + return i1->text().localeAwareCompare(i2->text()) < 0; +} + +bool BtBookmarksModelSortDescending(BookmarkItemBase * i1, BookmarkItemBase * i2) +{ + return i1->text().localeAwareCompare(i2->text()) > 0; +} + +void BtBookmarksModel::sortItems(QModelIndex const & parent, + Qt::SortOrder const order) +{ + Q_D(BtBookmarksModel); + + if(BookmarkFolder * const f = d->itemAs<BookmarkFolder>(parent)) { + QList<BookmarkFolder *> parents; + if(f == d->m_rootItem) { + QList<BookmarkItemBase *> items; + items.append(f); + for(int i = 0; i < items.size(); ++i) { + items.append(items[i]->children()); + if(BookmarkFolder * ff = dynamic_cast<BookmarkFolder *>(items[i])) + parents.append(ff); + } + } + else + parents.append(f); + + Q_FOREACH(BookmarkFolder * const f, parents) { + emit layoutAboutToBeChanged(); + + QModelIndexList indexes; + for(int i = 0; i < f->children().size(); ++i) + indexes.append(createIndex(i, 0, f->children()[i])); + + qSort(f->children().begin(), f->children().end(), order == Qt::AscendingOrder ? + BtBookmarksModelSortAscending : BtBookmarksModelSortDescending); + + for(int i = 0; i < f->children().size(); ++i) { + BookmarkItemBase * iii = f->children()[i]; + for(int ii = 0; ii < indexes.size(); ++ii) + if(iii == indexes[ii].internalPointer()) + changePersistentIndex(createIndex(ii, 0, iii), createIndex(i, 0, iii)); + } + emit layoutChanged(); + + d->needSave(); + } + } +} diff --git a/src/backend/btbookmarksmodel.h b/src/backend/btbookmarksmodel.h new file mode 100644 index 0000000..0ef90f0 --- /dev/null +++ b/src/backend/btbookmarksmodel.h @@ -0,0 +1,161 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +#ifndef BTBOOKMARKSMODEL_H +#define BTBOOKMARKSMODEL_H + +#include <QAbstractItemModel> + + +class BtBookmarksModelPrivate; +class CSwordModuleInfo; + +/** + Model to load and display bookmarks. It is saved periodically if it was loaded + from default bookmarks file. No more one such model allowed at time. +*/ +class BtBookmarksModel: public QAbstractItemModel { + + Q_OBJECT + + +public: /* Methods: */ + + /** + \brief Constructor/destructor for new bookmarks model, data is loaded on first + constructor call and unloaded on last destructor call. + + \param[in] fileName loads a list of items (with subitem trees) from a named file + or from the default bookmarks file if empty. + \param[in] rootFolder would be used if you need only to display particular + bookmarks folder. + */ + BtBookmarksModel(QObject * parent = nullptr); + BtBookmarksModel(const QString & fileName = QString(), + const QString & rootFolder = QString(), QObject * parent = nullptr); + ~BtBookmarksModel(); + + /** Reimplemented from QAbstractItemModel */ + int rowCount(const QModelIndex & parent = QModelIndex()) const override; + int columnCount(const QModelIndex & parent = QModelIndex()) const override; + bool hasChildren(const QModelIndex & parent = QModelIndex()) const override; + QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const override; + QModelIndex parent(const QModelIndex & index) const override; + QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override; + Qt::ItemFlags flags(const QModelIndex & index) const override; + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + bool setData(const QModelIndex & index, const QVariant & value, int role = Qt::EditRole) override; + bool removeRows(int row, int count, const QModelIndex & parent = QModelIndex()) override; + bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override; + + /** + \brief add new item with given parameters + */ + QModelIndex addBookmark(int const row, + QModelIndex const & parent, + CSwordModuleInfo const & module, + QString const & key, + QString const & description = QString(), + QString const & title = QString()); + + /** + \brief add new folder. + */ + QModelIndex addFolder(int row, const QModelIndex & parent, const QString & name = QString()); + + /** + \brief Copies item to target position. + + \param[in] row new item will occupy given row. + \param[in] parent if invalid new item will be placed on top level. + \param[in] toCopy item to copy. + \returns newly created itemS that are copy of toCopy. + */ + QModelIndexList copyItems(int row, const QModelIndex & parent, const QModelIndexList & toCopy); + + /** + \returns whether item of index is a folder. + */ + bool isFolder(const QModelIndex & index) const; + + /** + \returns whether item of index is a bookmark. + */ + bool isBookmark(const QModelIndex & index) const; + + /** + \returns true if the testIndex is baseIndex or a direct or indirect subitem of baseIndex. + */ + bool hasDescendant(const QModelIndex & baseIndex, const QModelIndex & testIndex) const; + + /** + \returns description for specified index if have. + */ + QString description(const QModelIndex & index) const; + + /** + \brief set descritpion for index. + */ + void setDescription(const QModelIndex & index, const QString & description); + + /** + \returns sword module for specified index if have. + */ + CSwordModuleInfo * module(const QModelIndex & index) const; + + /** + \returns key for specified index if have. + */ + QString key(const QModelIndex & index) const; + + /** + \param[in] parent sort items under specified index, if invalid sort all + items. + */ + void sortItems(QModelIndex const & parent = QModelIndex(), + Qt::SortOrder const order = Qt::AscendingOrder); + + +public slots: + + /** + \brief Save bookmarks or specified branch to file. + + \param[in] fileName use file or save to the default bookmarks file if it is empty, + file will be overwriten if it exists. + \param[in] rootItem is used to save specified branch of bookmark items or save all + bookmarks if it is empty. + \returns true if success. + */ + bool save(QString fileName = QString(), const QModelIndex & rootItem = QModelIndex()); + + /** + \brief Import bookmarks from file. + + \param[in] fileName file to load bookmarks. + \param[in] rootItem bookmarks will be loaded under specified item, if empty, items + will be loaded on top level. Items will be placed in append mode. + \returns true if success. + */ + bool load(QString fileName = QString(), const QModelIndex & rootItem = QModelIndex()); + +private: + + inline bool slotSave() { return save(); } + +private: /* Fields: */ + Q_DECLARE_PRIVATE(BtBookmarksModel) + BtBookmarksModelPrivate * const d_ptr; + +}; + +#endif // BTBOOKMARKSMODEL_H diff --git a/src/backend/btglobal.cpp b/src/backend/btglobal.cpp new file mode 100644 index 0000000..e2907f2 --- /dev/null +++ b/src/backend/btglobal.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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#include "btglobal.h" + +#include <QDataStream> + + +QDataStream &operator<<(QDataStream &out, const alignmentMode &mode) { + out << static_cast<qint8>(mode); + return out; +} + +QDataStream &operator>>(QDataStream &in, alignmentMode &mode) { + qint8 i; + in >> i; + mode = static_cast<alignmentMode>(i); + return in; +} + +FilterOptions::FilterOptions() + : footnotes(0), strongNumbers(0), headings(0), morphTags(0), + lemmas(0), hebrewPoints(0), hebrewCantillation(0), greekAccents(0), + textualVariants(0), redLetterWords(0), scriptureReferences(0), + morphSegmentation(0) { +} diff --git a/src/btglobal.h b/src/backend/btglobal.h index 1b956b7..2412985 100644 --- a/src/btglobal.h +++ b/src/backend/btglobal.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -35,6 +35,7 @@ struct FilterOptions { int redLetterWords; /**< 0 for disabled, 1 for enabled */ int scriptureReferences; /**< 0 for disabled, 1 for enabled */ int morphSegmentation; /**< 0 for disabled, 1 for enabled */ + FilterOptions(); }; Q_DECLARE_METATYPE(FilterOptions) diff --git a/src/backend/btinstallbackend.cpp b/src/backend/btinstallbackend.cpp index 7eb3ff4..fd6db33 100644 --- a/src/backend/btinstallbackend.cpp +++ b/src/backend/btinstallbackend.cpp @@ -2,21 +2,21 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ -#include "backend/btinstallbackend.h" +#include "btinstallbackend.h" #include <QDebug> #include <QDir> #include <QFile> #include <QFileInfo> -#include "backend/managers/cswordbackend.h" -#include "backend/btinstallmgr.h" -#include "util/directory.h" -#include "frontend/messagedialog.h" +#include "../util/btassert.h" +#include "../util/directory.h" +#include "managers/cswordbackend.h" +#include "btinstallmgr.h" // Sword includes: #include <filemgr.h> @@ -130,9 +130,11 @@ bool deleteSource(const QString &name) { } /** Returns the moduleinfo list for the source. Delete the pointer after using. IS THIS POSSIBLE?*/ -QList<CSwordModuleInfo*> moduleList(QString /*name*/) { - QList<CSwordModuleInfo*> list; /// \todo dummy - return list; +QList<CSwordModuleInfo*> moduleList(QString name) { + /// \todo dummy + Q_UNUSED(name); + BT_ASSERT(false && "not implemented"); + return QList<CSwordModuleInfo*>(); } bool isRemote(const sword::InstallSource& source) { @@ -163,23 +165,17 @@ bool setTargetList( const QStringList& targets ) { //QString filename = util::DirectoryUtil::getUserBaseDir().canonicalPath().append("/.sword/sword.conf"); //bool directAccess = false; QString filename = swordConfigFilename(); - QFileInfo i(filename); - QFileInfo dirInfo(i.absolutePath()); - - - if ( !i.exists() && dirInfo.isWritable() ) { - // if the file doesn't exist but the parent is writable, create it - qWarning() << "The Sword config file does not exist, it has to be created"; + { QFile f(filename); - f.open(QIODevice::WriteOnly); - f.close(); - i.refresh(); - } - if (!i.exists() || !i.isWritable()) { - // There is no way to save to the file - qWarning() << "The Sword config file is not writable!"; - message::showWarning(0, QObject::tr("Can't write file"), QObject::tr("The Sword config file can't be written!")); - return false; + if (!f.exists()) { + if (!f.open(QIODevice::ReadWrite)) { + qWarning() << "The Sword config file can't be created!"; + return false; + } + f.close(); + qDebug() << "The Sword config file \"" << filename + << "\" had to be (re)created!"; + } } filename = util::directory::convertDirSeparators(filename); @@ -219,7 +215,7 @@ bool setTargetList( const QStringList& targets ) { QStringList sourceNameList() { BtInstallMgr mgr; - Q_ASSERT(mgr.installConf); + BT_ASSERT(mgr.installConf); QStringList names; diff --git a/src/backend/btinstallbackend.h b/src/backend/btinstallbackend.h index 1827f64..743cf4e 100644 --- a/src/backend/btinstallbackend.h +++ b/src/backend/btinstallbackend.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -14,7 +14,7 @@ #include <QDir> #include <QString> -#include "backend/managers/cswordbackend.h" +#include "managers/cswordbackend.h" // Sword includes: #include <installmgr.h> diff --git a/src/backend/btinstallmgr.cpp b/src/backend/btinstallmgr.cpp index 2734dd3..03be190 100644 --- a/src/backend/btinstallmgr.cpp +++ b/src/backend/btinstallmgr.cpp @@ -2,14 +2,15 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ -#include "backend/btinstallmgr.h" +#include "btinstallmgr.h" -#include "backend/btinstallbackend.h" +#include "../util/btassert.h" +#include "btinstallbackend.h" namespace { @@ -25,8 +26,8 @@ inline T normalizeCompletionPercentage(const T value) { template <typename T> inline int calculateIntPercentage(T done, T total) { - Q_ASSERT(done >= 0); - Q_ASSERT(total >= 0); + BT_ASSERT(done >= 0); + BT_ASSERT(total >= 0); // Special care (see warning in BtInstallMgr::statusUpdate()). if (done > total) @@ -89,7 +90,7 @@ void BtInstallMgr::preStatus(long totalBytes, const char * message) { Q_UNUSED(message); - Q_ASSERT(completedBytes <= totalBytes); + BT_ASSERT(completedBytes <= totalBytes); if (m_firstCallOfPreStatus) { m_firstCallOfPreStatus = false; emit downloadStarted(); diff --git a/src/backend/btinstallmgr.h b/src/backend/btinstallmgr.h index e82b470..8234bdd 100644 --- a/src/backend/btinstallmgr.h +++ b/src/backend/btinstallmgr.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -13,6 +13,7 @@ #define BTINSTALLMGR_H #include <QObject> + // Sword includes: #include <installmgr.h> #include <remotetrans.h> @@ -31,10 +32,10 @@ class BtInstallMgr public: /* Methods: */ - BtInstallMgr(QObject * parent = 0); + BtInstallMgr(QObject * parent = nullptr); ~BtInstallMgr(); - virtual bool isUserDisclaimerConfirmed() const; + bool isUserDisclaimerConfirmed() const override; signals: @@ -49,7 +50,7 @@ signals: protected: /* Methods: */ /** \note Reimplementation of sword::StatusReporter::statusUpdate(). */ - virtual void statusUpdate(double dltotal, double dlnow); + void statusUpdate(double dltotal, double dlnow) override; /** * \note Reimplementation of sword::StatusReporter::preStatus(). @@ -58,9 +59,9 @@ protected: /* Methods: */ * The sword message is not i18n'ed, it's in the form "Downloading (1 of 6): nt.bzs". * This function is not utilized in the UI ATM. */ - virtual void preStatus(long totalBytes, - long completedBytes, - const char * message); + void preStatus(long totalBytes, + long completedBytes, + const char * message) override; private: /* Fields: */ diff --git a/src/backend/btinstallthread.cpp b/src/backend/btinstallthread.cpp index 69e5fb8..b2e7679 100644 --- a/src/backend/btinstallthread.cpp +++ b/src/backend/btinstallthread.cpp @@ -2,20 +2,20 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ -#include "backend/btinstallthread.h" +#include "btinstallthread.h" +#include <memory> #include <QDebug> #include <QDir> #include <QString> #include <QThread> -#include "backend/managers/cswordbackend.h" - -#include "backend/btinstallbackend.h" +#include "btinstallbackend.h" +#include "managers/cswordbackend.h" // Sword includes: #include <filemgr.h> @@ -47,21 +47,14 @@ void BtInstallThread::run() { return; } - m_stopRequestedMutex.lock(); - try { - for (m_currentModuleIndex = 0; - !m_stopRequested && (m_currentModuleIndex < m_modules.size()); - m_currentModuleIndex++) - { - m_stopRequestedMutex.unlock(); - installModule(); - m_stopRequestedMutex.lock(); - } - } catch (...) { - m_stopRequestedMutex.unlock(); - throw; + for (m_currentModuleIndex = 0; + m_currentModuleIndex < m_modules.size(); + ++m_currentModuleIndex) + { + installModule(); + if (m_stopRequested.load(std::memory_order_relaxed)) + break; } - m_stopRequestedMutex.unlock(); } void BtInstallThread::installModule() { @@ -69,22 +62,21 @@ void BtInstallThread::installModule() { const CSwordModuleInfo * const module = m_modules.at(m_currentModuleIndex); - sword::InstallSource installSource = BtInstallBackend::source(module->property("installSourceName").toString()); - QScopedPointer<CSwordBackend> backendForSource(BtInstallBackend::backend(installSource)); + QVariant vModuleName = module->property("installSourceName"); + QString moduleName = vModuleName.toString(); + sword::InstallSource installSource = BtInstallBackend::source(moduleName); + std::unique_ptr<CSwordBackend> backendForSource(BtInstallBackend::backend(installSource)); // Check whether it's an update. If yes, remove existing module first: /// \todo silently removing without undo if the user cancels the update is WRONG!!! - if (!removeModule()) { - QMutexLocker lock(&m_stopRequestedMutex); - if (m_stopRequested) - return; - } + if (!removeModule() && m_stopRequested.load(std::memory_order_relaxed)) + return; // manager for the destination path sword::SWMgr lMgr(m_destination.toLatin1()); if (BtInstallBackend::isRemote(installSource)) { int status = m_iMgr.installModule(&lMgr, - 0, + nullptr, module->name().toLatin1(), &installSource); if (status == 0) { diff --git a/src/backend/btinstallthread.h b/src/backend/btinstallthread.h index d4cbdc3..ae9488c 100644 --- a/src/backend/btinstallthread.h +++ b/src/backend/btinstallthread.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -14,10 +14,9 @@ #include <QThread> -#include <QMutex> -#include <QMutexLocker> -#include <QSharedPointer> -#include "backend/btinstallmgr.h" +#include <atomic> +#include "btinstallmgr.h" +#include "../util/btconnect.h" class BtInstallProgressDialog; @@ -33,24 +32,22 @@ class BtInstallThread: public QThread { BtInstallThread(const QList<CSwordModuleInfo *> & modules, const QString & destination, - QObject * const parent = 0) + QObject * const parent = nullptr) : QThread(parent) , m_modules(modules) , m_destination(destination) , m_stopRequested(false) { - connect(&m_iMgr, SIGNAL(percentCompleted(int, int)), - this, SLOT(slotManagerStatusUpdated(int, int)), - Qt::QueuedConnection); - connect(&m_iMgr, SIGNAL(downloadStarted()), - this, SLOT(slotDownloadStarted()), - Qt::QueuedConnection); + BT_CONNECT(&m_iMgr, &BtInstallMgr::percentCompleted, + this, &BtInstallThread::slotManagerStatusUpdated, + Qt::QueuedConnection); + BT_CONNECT(&m_iMgr, &BtInstallMgr::downloadStarted, + this, &BtInstallThread::slotDownloadStarted, + Qt::QueuedConnection); } - void stopInstall() { - const QMutexLocker lock(&m_stopRequestedMutex); - m_stopRequested = true; - } + void stopInstall() + { m_stopRequested.store(true, std::memory_order_relaxed); } signals: @@ -68,7 +65,7 @@ class BtInstallThread: public QThread { protected: /* Methods: */ - virtual void run(); + void run() override; private: /* Methods: */ @@ -86,8 +83,7 @@ class BtInstallThread: public QThread { const QString m_destination; BtInstallMgr m_iMgr; int m_currentModuleIndex; - QMutex m_stopRequestedMutex; - bool m_stopRequested; + std::atomic<bool> m_stopRequested; }; diff --git a/src/backend/btmoduletreeitem.cpp b/src/backend/btmoduletreeitem.cpp index 7900ef0..ea11073 100644 --- a/src/backend/btmoduletreeitem.cpp +++ b/src/backend/btmoduletreeitem.cpp @@ -2,26 +2,25 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ -#include "backend/btmoduletreeitem.h" +#include "btmoduletreeitem.h" #include <QList> #include <QString> -#include "backend/drivers/cswordmoduleinfo.h" -#include "backend/managers/cswordbackend.h" -#include "util/cresmgr.h" -#include "util/tool.h" +#include "drivers/cswordmoduleinfo.h" +#include "managers/cswordbackend.h" +#include "../util/tool.h" //This ctor creates the root item and the tree. BTModuleTreeItem::BTModuleTreeItem(QList<BTModuleTreeItem::Filter*>& filters, BTModuleTreeItem::Grouping grouping, QList<CSwordModuleInfo*>* modules) - : m_moduleInfo(0), - m_firstChild(0), - m_next(0), + : m_moduleInfo(nullptr), + m_firstChild(nullptr), + m_next(nullptr), m_type(BTModuleTreeItem::Root), m_category(CSwordModuleInfo::UnknownCategory), m_grouping (grouping) { @@ -42,8 +41,8 @@ BTModuleTreeItem::BTModuleTreeItem(QList<BTModuleTreeItem::Filter*>& filters, BT BTModuleTreeItem::BTModuleTreeItem(BTModuleTreeItem* parentItem, const QString& text, BTModuleTreeItem::Type type, CSwordModuleInfo* info, CSwordModuleInfo::Category category) : m_moduleInfo(info), m_text(text), - m_firstChild(0), - m_next(0), + m_firstChild(nullptr), + m_next(nullptr), m_type(type), m_category(category) { if (info) { @@ -58,9 +57,8 @@ BTModuleTreeItem::BTModuleTreeItem(BTModuleTreeItem* parentItem, const QString& BTModuleTreeItem::~BTModuleTreeItem() { // this works recursively - foreach(BTModuleTreeItem* i, children()) { + Q_FOREACH(BTModuleTreeItem * const i, children()) delete i; - } } QList<BTModuleTreeItem*> BTModuleTreeItem::children() const { @@ -75,49 +73,6 @@ QList<BTModuleTreeItem*> BTModuleTreeItem::children() const { return childList; } -/// \todo -QString BTModuleTreeItem::iconName() const { - if (m_type == Category) { - switch ( m_category) { - case CSwordModuleInfo::Bibles: - return CResMgr::categories::bibles::icon; - break; - case CSwordModuleInfo::Commentaries: - return CResMgr::categories::commentaries::icon; - break; - case CSwordModuleInfo::Books: - return CResMgr::categories::books::icon; - break; - case CSwordModuleInfo::Cult: - return CResMgr::categories::cults::icon; - break; - case CSwordModuleInfo::Images: - return CResMgr::categories::images::icon; - break; - case CSwordModuleInfo::DailyDevotional: - return CResMgr::categories::dailydevotional::icon; - break; - case CSwordModuleInfo::Lexicons: - return CResMgr::categories::lexicons::icon; - break; - case CSwordModuleInfo::Glossary: - return CResMgr::categories::glossary::icon; - break; - default: - break; - } - } - else if (m_type == Module) { - return util::tool::getIconNameForModule(m_moduleInfo); - } - else if (m_type == Language) { - /// \todo don't hardcode here - return "flag.svg"; - } - - return QString::null; -} - bool BTModuleTreeItem::m_map_initialized = false; QMap<CSwordModuleInfo::Category, QString> BTModuleTreeItem::m_CategoryNamesMap; @@ -138,11 +93,11 @@ void BTModuleTreeItem::create_tree(QList<BTModuleTreeItem::Filter*>& filters) { } void BTModuleTreeItem::add_items(QList<BTModuleTreeItem::Filter*>& filters) { - foreach (CSwordModuleInfo* info, m_originalModuleList) { + Q_FOREACH(CSwordModuleInfo * const info, m_originalModuleList) { bool included; included = true; - foreach (BTModuleTreeItem::Filter* f, filters) { - if (!f->filter(info)) { + Q_FOREACH(BTModuleTreeItem::Filter const * const f, filters) { + if (!f->filter(*info)) { included = false; break; } @@ -195,25 +150,18 @@ BTModuleTreeItem* BTModuleTreeItem::create_parent_item( BTModuleTreeItem* parentGroup, const QString& itemText, BTModuleTreeItem::Type type, - CSwordModuleInfo::Category category) { - BTModuleTreeItem* item = 0; - foreach(BTModuleTreeItem* it, parentGroup->children()) { - if (it->text() == itemText) { - item = it; - break; - } - } - if (!item) - item = new BTModuleTreeItem(parentGroup, itemText, type, 0, category); - - return item; + CSwordModuleInfo::Category category) +{ + Q_FOREACH(BTModuleTreeItem * const item, parentGroup->children()) + if (item->text() == itemText) + return item; + return new BTModuleTreeItem(parentGroup, itemText, type, nullptr, category); } void BTModuleTreeItem::sort_children(BTModuleTreeItem* parent) { // sort each child recursively depth-first - foreach(BTModuleTreeItem* item, parent->children()) { + Q_FOREACH(BTModuleTreeItem * const item, parent->children()) sort_children(item); - } QList<BTModuleTreeItem*> items = parent->children(); if (items.size() > 0) { @@ -222,11 +170,11 @@ void BTModuleTreeItem::sort_children(BTModuleTreeItem* parent) { //put the children back to tree in sorted order BTModuleTreeItem* first = items.at(0); BTModuleTreeItem* prev = first; - foreach (BTModuleTreeItem* item2, items) { + Q_FOREACH(BTModuleTreeItem * const item2, items) { prev->m_next = item2; prev = item2; } - prev->m_next = 0; + prev->m_next = nullptr; parent->m_firstChild = first; // attach the partial tree to the parent } } @@ -255,13 +203,13 @@ bool BTModuleTreeItem::localeAwareLessThan(BTModuleTreeItem* first, BTModuleTree } QDataStream &operator<<(QDataStream &out, const BTModuleTreeItem::Grouping &grouping) { - out << (qint8) grouping; + out << static_cast<qint8>(grouping); return out; } QDataStream &operator>>(QDataStream &in, BTModuleTreeItem::Grouping &grouping) { qint8 i; in >> i; - grouping = (BTModuleTreeItem::Grouping) i; + grouping = static_cast<BTModuleTreeItem::Grouping>(i); return in; } diff --git a/src/backend/btmoduletreeitem.h b/src/backend/btmoduletreeitem.h index 189f9b2..1bd855b 100644 --- a/src/backend/btmoduletreeitem.h +++ b/src/backend/btmoduletreeitem.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -14,7 +14,7 @@ #include <QMap> #include <QString> -#include "backend/drivers/cswordmoduleinfo.h" +#include "drivers/cswordmoduleinfo.h" /** @@ -36,9 +36,8 @@ Example: add_to_view(&root, qtreewidget->invisibleRootItem()); ... void add_to_view(BTModuleTreeItem* item, QTreeWidgetItem* widgetItem) { - foreach (BTModuleTreeItem* i, item->children()) { + Q_FOREACH(BTModuleTreeItem * const i, item->children()) add_to_view(i, new QTreeWidgetItem(widgetItem)); - } if (item->type() == BTModuleTreeItem::Category) prepare_category_item(widgetItem, item); ... } @@ -72,17 +71,16 @@ class BTModuleTreeItem { * BTModuleTreeItem root(filters, BTModuleTreeItem::CatLangMod); */ struct Filter { - virtual bool filter(CSwordModuleInfo*) = 0; + virtual bool filter(CSwordModuleInfo const &) const = 0; }; /** * One example of a filter which can be used with any view. If the module has been * set "hidden" it will be filtered out. */ - struct HiddenOff : public Filter { - inline bool filter(CSwordModuleInfo* mi) { - return !mi->isHidden(); - } + struct HiddenOff final: public Filter { + inline bool filter(CSwordModuleInfo const & mi) const final override + { return !mi.isHidden(); } }; /** @@ -112,7 +110,7 @@ class BTModuleTreeItem { * (by default CSwordBackend::instance()()->moduleList() is used). */ BTModuleTreeItem(QList<BTModuleTreeItem::Filter*>& filters, - BTModuleTreeItem::Grouping grouping, QList<CSwordModuleInfo*>* modules = 0); + BTModuleTreeItem::Grouping grouping, QList<CSwordModuleInfo*>* modules = nullptr); /** When the root item is deleted the whole tree is deleted. */ ~BTModuleTreeItem(); @@ -129,13 +127,10 @@ class BTModuleTreeItem { /** * Returns the item text (category name, language name or module name). */ - inline QString text() const { + inline QString const & text() const { return m_text; } - /** - * Returns the path to the icon which is appropriate for this type of item, or QString::null. - */ - QString iconName() const; + /** * If the type is Module returns a pointer to the corresponding CSwordModuleInfo object, * otherwise returns 0. @@ -159,7 +154,7 @@ class BTModuleTreeItem { /** * Private constructor which sets the members. */ - BTModuleTreeItem(BTModuleTreeItem* parentItem, const QString& text, Type type, CSwordModuleInfo* info = 0, CSwordModuleInfo::Category category = CSwordModuleInfo::UnknownCategory); + BTModuleTreeItem(BTModuleTreeItem* parentItem, const QString& text, Type type, CSwordModuleInfo* info = nullptr, CSwordModuleInfo::Category category = CSwordModuleInfo::UnknownCategory); /** Default ctor is private because it is not to be called.*/ BTModuleTreeItem(); diff --git a/src/util/btsignal.h b/src/backend/btsignal.h index a680311..94cfbc4 100644 --- a/src/util/btsignal.h +++ b/src/backend/btsignal.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -31,7 +31,7 @@ class BtSignal: public QObject { public: - inline BtSignal(QObject *parent = 0) + inline BtSignal(QObject *parent = nullptr) : QObject(parent) {} /** diff --git a/src/backend/btsourcesthread.cpp b/src/backend/btsourcesthread.cpp new file mode 100644 index 0000000..8189835 --- /dev/null +++ b/src/backend/btsourcesthread.cpp @@ -0,0 +1,67 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#include "btsourcesthread.h" + +#include <QString> +#include <memory> +#include "btinstallbackend.h" +#include "backend/btinstallmgr.h" +#include "util/btassert.h" + + +void BtSourcesThread::run() { + emit percentComplete(0); + emit showMessage(tr("Getting Library List")); + if (BtInstallMgr().refreshRemoteSourceConfiguration()) + qWarning("InstallMgr: getting remote list returned an error."); + emit percentComplete(10); + + if (shouldStop()) { + emit showMessage(tr("Updating stopped")); + return; + } + + QStringList const sourceNames = BtInstallBackend::sourceNameList(); + int const sourceCount = sourceNames.count(); + std::unique_ptr<int[]> failedSources{new int[sourceCount]}; + int numFailedSources = 0; + BtInstallMgr iMgr; + for (int i = 0; i < sourceCount; ++i) { + if (shouldStop()) { + emit showMessage(tr("Updating stopped")); + return; + } + QString const & sourceName = sourceNames[i]; + emit showMessage(tr("Updating remote library \"%1\"").arg(sourceName)); + { + sword::InstallSource source = BtInstallBackend::source(sourceName); + if (iMgr.refreshRemoteSource(&source)) { + failedSources[numFailedSources] = i; + ++numFailedSources; + } + } + emit percentComplete(10 + 90 * ((i + 1.0) / sourceCount)); + } + emit percentComplete(100); + if (numFailedSources <= 0) { + emit showMessage(tr("Remote libraries have been updated.")); + m_finishedSuccessfully.store(true, std::memory_order_release); + } else { + QString msg = tr("The following remote libraries failed to update: "); + for (int i = 0;;) { + msg += sourceNames[failedSources[i]]; + if (++i >= numFailedSources) + break; + msg += ", "; + }; + emit showMessage(std::move(msg)); + m_finishedSuccessfully.store(true, std::memory_order_release); + } +} diff --git a/src/backend/btsourcesthread.h b/src/backend/btsourcesthread.h new file mode 100644 index 0000000..3c2300e --- /dev/null +++ b/src/backend/btsourcesthread.h @@ -0,0 +1,58 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef BTSOURCESTHREAD_H +#define BTSOURCESTHREAD_H + +#include <QThread> + +#include <atomic> + + +class BtSourcesThread: public QThread { + + Q_OBJECT + +public: /* Methods: */ + + inline BtSourcesThread(QObject * parent = nullptr) + : QThread(parent) + , m_stop(false) + , m_finishedSuccessfully(false) + {} + + inline void stop() noexcept { m_stop.store(std::memory_order_release); } + + inline bool finishedSuccessfully() const noexcept + { return m_finishedSuccessfully.load(std::memory_order_acquire); } + +signals: + + void percentComplete(int percent); + void showMessage(QString const & msg); + +protected: /* Methods: */ + + void run() override; + +private: /* Methods: */ + + inline bool shouldStop() const noexcept + { return m_stop.load(std::memory_order_acquire); } + +private: /* Fields: */ + + std::atomic<bool> m_stop; + std::atomic<bool> m_finishedSuccessfully; + +}; /* class BtSourcesThread */ + +#endif diff --git a/src/backend/config/btconfig.cpp b/src/backend/config/btconfig.cpp index e76b246..98db556 100644 --- a/src/backend/config/btconfig.cpp +++ b/src/backend/config/btconfig.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -11,13 +11,13 @@ #include <QDebug> #include <QLocale> -#include "backend/btmoduletreeitem.h" -#include "backend/managers/cdisplaytemplatemgr.h" -#include "frontend/messagedialog.h" -#include "util/directory.h" // DU::getUserBaseDir() +#include "../../util/btassert.h" +#include "../../util/directory.h" // DU::getUserBaseDir() +#include "../btmoduletreeitem.h" +#include "../managers/cdisplaytemplatemgr.h" +#include "../managers/cswordbackend.h" // Sword includes: -#include <backend/managers/cswordbackend.h> #include <versekey.h> // For search scope configuration @@ -31,7 +31,7 @@ const QString BTCONFIG_API_VERSION_KEY = "btconfig_api_version"; * set the instance variable initially to 0, so it can be safely checked * whether the variable has been initialized yet. */ -BtConfig * BtConfig::m_instance = NULL; +BtConfig * BtConfig::m_instance = nullptr; BtConfig::StringMap BtConfig::m_defaultSearchScopes; @@ -39,7 +39,7 @@ BtConfig::StringMap BtConfig::m_defaultSearchScopes; BtConfig::BtConfig(const QString & settingsFile) : BtConfigCore(settingsFile) { - Q_ASSERT_X(!m_instance, "BtConfig", "Already initialized!"); + BT_ASSERT(!m_instance && "BtConfig already initialized!"); m_instance = this; if (m_defaultSearchScopes.isEmpty()) { @@ -52,10 +52,17 @@ BtConfig::BtConfig(const QString & settingsFile) m_defaultSearchScopes.insert(tr("Letters/Epistles"), QString("Rom - Jude")); m_defaultSearchScopes.insert(tr("Paul's Epistles"), QString("Rom - Phile")); } + +#ifdef Q_OS_WIN + const double minPointSize = 14.0; + double pointSize = m_defaultFont.pointSizeF(); + if (pointSize < minPointSize) + m_defaultFont.setPointSizeF(minPointSize); +#endif } -bool BtConfig::initBtConfig() { - Q_ASSERT(!m_instance); +BtConfig::InitState BtConfig::initBtConfig() { + BT_ASSERT(!m_instance); const QString confFileName = util::directory::getUserBaseDir().absolutePath() + "/bibletimerc"; @@ -63,83 +70,57 @@ bool BtConfig::initBtConfig() { m_instance = new BtConfig(confFileName); if (!confExisted) { m_instance->setValue<int>(BTCONFIG_API_VERSION_KEY, BTCONFIG_API_VERSION); - return true; + return INIT_OK; } int btConfigOldApi = m_instance->value<int>(BTCONFIG_API_VERSION_KEY, 0); if (btConfigOldApi == BTCONFIG_API_VERSION) - return true; - - bool cont; - if (btConfigOldApi < BTCONFIG_API_VERSION) { - /// \todo Migrate from btConfigOldApi to BTCONFIG_API_VERSION - qWarning() << "BibleTime configuration migration is not yet implemented!!!"; - cont = message::showWarning( - 0, "Warning!", - "Migration to the new configuration system is not yet " - "implemented. Proceeding might result in <b>loss of data" - "</b>. Please backup your configuration files before you " - "continue!<br/><br/>Do you want to continue? Press \"No\" " - "to quit BibleTime immediately.", - QMessageBox::Yes | QMessageBox::No, - QMessageBox::No) == QMessageBox::Yes; - } else { - Q_ASSERT(btConfigOldApi > BTCONFIG_API_VERSION); - cont = message::showWarning( - 0, tr("Error loading configuration!"), - tr("Failed to load BibleTime's configuration, because it " - "appears that the configuration file corresponds to a " - "newer version of BibleTime. This is likely caused by " - "BibleTime being downgraded. Loading the new " - "configuration file may result in <b>loss of data</b>." - "<br/><br/>Do you still want to try to load the new " - "configuration file? Press \"No\" to quit BibleTime " - "immediately."), - QMessageBox::Yes | QMessageBox::No, - QMessageBox::No) == QMessageBox::Yes; - } - if (cont) - m_instance->setValue<int>(BTCONFIG_API_VERSION_KEY, BTCONFIG_API_VERSION); - return cont; + return INIT_OK; + return (btConfigOldApi < BTCONFIG_API_VERSION) + ? INIT_NEED_UNIMPLEMENTED_FORWARD_MIGRATE + : INIT_NEED_UNIMPLEMENTED_BACKWARD_MIGRATE; } +void BtConfig::forceMigrate() +{ m_instance->setValue<int>(BTCONFIG_API_VERSION_KEY, BTCONFIG_API_VERSION); } + BtConfig& BtConfig::getInstance() { - Q_ASSERT_X(m_instance, "BtConfig", "Not yet initialized!"); + BT_ASSERT(m_instance && "BtConfig not yet initialized!"); return *m_instance; } void BtConfig::destroyInstance() { delete m_instance; - m_instance = NULL; + m_instance = nullptr; } void BtConfig::setModuleEncryptionKey(const QString & name, const QString & key) { - Q_ASSERT(!name.isEmpty()); + BT_ASSERT(!name.isEmpty()); setValue("Module keys/" + name, key); } QString BtConfig::getModuleEncryptionKey(const QString & name) { - Q_ASSERT(!name.isEmpty()); + BT_ASSERT(!name.isEmpty()); return value<QString>("Module keys/" + name, QString::null); } -QHash<QString, QList<QKeySequence> > BtConfig::getShortcuts(const QString & shortcutGroup) { +BtConfig::ShortcutsMap BtConfig::getShortcuts(QString const & shortcutGroup) { beginGroup(shortcutGroup); - QHash<QString, QList<QKeySequence> > allShortcuts; - Q_FOREACH (const QString & key, childKeys()) { + ShortcutsMap allShortcuts; + for (QString const & key : childKeys()) { QVariant variant = qVariantValue(key); QList<QKeySequence> shortcuts; if (variant.type() == QVariant::List) { // For BibleTime before 2.9 - Q_FOREACH (const QVariant & shortcut, variant.toList()) + for (QVariant const & shortcut : variant.toList()) shortcuts.append(shortcut.toString()); } else if (variant.type() == QVariant::StringList || variant.type() == QVariant::String) { // a StringList with one element is recognized as a QVariant::String - Q_FOREACH (const QString & shortcut, variant.toStringList()) + for (QString const & shortcut : variant.toStringList()) shortcuts.append(shortcut); } else { // it's something we don't know, skip it continue; @@ -151,17 +132,15 @@ QHash<QString, QList<QKeySequence> > BtConfig::getShortcuts(const QString & shor return allShortcuts; } -void BtConfig::setShortcuts(const QString & shortcutGroup, - const QHash<QString, QList<QKeySequence> > & shortcuts) +void BtConfig::setShortcuts(QString const & shortcutGroup, + ShortcutsMap const & shortcuts) { - typedef QHash<QString, QList<QKeySequence> >::const_iterator SHMCI; - beginGroup(shortcutGroup); - for (SHMCI it = shortcuts.begin(); it != shortcuts.end(); ++it) { + for (auto it = shortcuts.begin(); it != shortcuts.end(); ++it) { // Write beautiful string lists (since 2.9): /// \note saving QKeySequences directly doesn't appear to work! QStringList varList; - Q_FOREACH (const QKeySequence & shortcut, it.value()) + for (QKeySequence const & shortcut : it.value()) varList.append(shortcut.toString()); if (!varList.empty()) @@ -226,7 +205,7 @@ void BtConfig::setFontForLanguage(const CLanguageMgr::Language & language, const FontSettingsPair & fontSettings) { const QString & englishName = language.englishName(); - Q_ASSERT(!englishName.isEmpty()); + BT_ASSERT(!englishName.isEmpty()); QMutexLocker lock(&this->m_mutex); // write the language to the settings @@ -241,7 +220,7 @@ BtConfig::FontSettingsPair BtConfig::getFontForLanguage( const CLanguageMgr::Language & language) { const QString & englishName = language.englishName(); - Q_ASSERT(!englishName.isEmpty()); + BT_ASSERT(!englishName.isEmpty()); QMutexLocker lock(&this->m_mutex); // Check the cache first: @@ -302,7 +281,7 @@ void BtConfig::setSearchScopesWithCurrentLocale(StringMap searchScopes) { for (int i = 0; i < list.getCount(); i++) { sword::VerseKey * verse(dynamic_cast<sword::VerseKey *>(list.getElement(i))); - if (verse != 0) { + if (verse != nullptr) { verse->setLocale("en"); data.append(QString::fromUtf8(verse->getRangeText())); data.append(";"); @@ -327,7 +306,7 @@ void BtConfig::deleteSearchScopesWithCurrentLocale() { CSwordModuleInfo *BtConfig::getDefaultSwordModuleByType(const QString & moduleType) { const QString moduleName = value<QString>("settings/defaults/" + moduleType, QString()); if (moduleName.isEmpty()) - return 0; + return nullptr; return CSwordBackend::instance()->findModuleByName(moduleName); } @@ -336,7 +315,7 @@ void BtConfig::setDefaultSwordModuleByType(const QString &moduleType, const CSwordModuleInfo * const module) { setValue("settings/defaults/" + moduleType, - module != 0 ? module->name() : QString::null); + module != nullptr ? module->name() : QString::null); } /** diff --git a/src/backend/config/btconfig.h b/src/backend/config/btconfig.h index be19d41..785a89f 100644 --- a/src/backend/config/btconfig.h +++ b/src/backend/config/btconfig.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -22,20 +22,16 @@ #include <QString> #include <QStringList> #include <QVariant> - -#include "backend/config/btconfigcore.h" - -#include "backend/btmoduletreeitem.h" // for BTModuleTreeItem::Grouping -#include "backend/drivers/cswordmoduleinfo.h" -#include "btglobal.h" +#include "../btglobal.h" +#include "../btmoduletreeitem.h" // for BTModuleTreeItem::Grouping +#include "../drivers/cswordmoduleinfo.h" +#include "btconfigcore.h" class BibleTimeApp; class BtConfig: public BtConfigCore { - Q_DISABLE_COPY(BtConfig) - friend class BibleTimeApp; public: /* Types: */ @@ -44,12 +40,19 @@ public: /* Types: */ * The first parameter indicates whether the custom font should be used or not. * The second parameter is the custom font that has been set. */ - typedef QPair<bool, QFont> FontSettingsPair; - typedef QMap<QString, QString> StringMap; + using FontSettingsPair = QPair<bool, QFont>; + using StringMap = QMap<QString, QString>; + using ShortcutsMap = QHash<QString, QList<QKeySequence> >; private: /* Types: */ - typedef QHash<const CLanguageMgr::Language *, FontSettingsPair> FontCacheMap; + using FontCacheMap = QHash<const CLanguageMgr::Language *, FontSettingsPair>; + + enum InitState { + INIT_NEED_UNIMPLEMENTED_BACKWARD_MIGRATE = -2, + INIT_OK = 0, + INIT_NEED_UNIMPLEMENTED_FORWARD_MIGRATE = 2, + }; public: /* Methods: */ @@ -86,7 +89,7 @@ public: /* Methods: */ * \param[in] shortcutGroup The group to retrieve shortcuts for. * \returns Hash of strings and lists of shortcuts. */ - QHash<QString, QList<QKeySequence> > getShortcuts(const QString & shortcutGroup); + ShortcutsMap getShortcuts(QString const & shortcutGroup); /*! * \brief Sets the shortcuts for the given group. @@ -96,8 +99,8 @@ public: /* Methods: */ * \param[in] shortcutGroup The group to retrieve shortcuts for. * \param[in] Hash of strings and lists of shortcuts to write. */ - void setShortcuts(const QString & shortcutGroup, - const QHash<QString, QList<QKeySequence> > & shortcuts); + void setShortcuts(QString const & shortcutGroup, + ShortcutsMap const & shortcuts); /*! * \brief Returns current filter options. @@ -218,7 +221,8 @@ private: /* Methods: */ explicit BtConfig(const QString & settingsFile); - static bool initBtConfig(); + static InitState initBtConfig(); + static void forceMigrate(); static void destroyInstance(); diff --git a/src/backend/config/btconfigcore.cpp b/src/backend/config/btconfigcore.cpp index 0914508..b290e2d 100644 --- a/src/backend/config/btconfigcore.cpp +++ b/src/backend/config/btconfigcore.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -55,7 +55,8 @@ BtConfigCore::BtConfigCore(const QString & settingsFile) || !m_sessionNames.contains(m_currentSessionKey)) { if (m_sessionNames.isEmpty()) { - const QString &newSessionName = QString::number((qulonglong) 0u, 36); + QString const & newSessionName = + QString::number(static_cast<qulonglong>(0u), 36); m_currentSessionKey = newSessionName; m_settings.setValue(KEY_CURRENT_SESSION, newSessionName); m_settings.setValue(KEY_SESSION_NAME.arg(newSessionName), @@ -68,10 +69,10 @@ BtConfigCore::BtConfigCore(const QString & settingsFile) } void BtConfigCore::setCurrentSession(const QString & key) { - Q_ASSERT(!key.isEmpty()); + BT_ASSERT(!key.isEmpty()); QMutexLocker lock(&m_mutex); - Q_ASSERT(m_sessionNames.contains(key)); + BT_ASSERT(m_sessionNames.contains(key)); m_currentSessionKey = key; m_cachedCurrentSessionGroup = GROUP_SESSION.arg(key); @@ -80,7 +81,7 @@ void BtConfigCore::setCurrentSession(const QString & key) { } QString BtConfigCore::addSession(const QString & name) { - Q_ASSERT(!name.isEmpty()); + BT_ASSERT(!name.isEmpty()); // Generate a new session key: QString key = QString::number(0u, 36); @@ -100,7 +101,7 @@ QString BtConfigCore::addSession(const QString & name) { } }; } - Q_ASSERT(!m_sessionNames.contains(key)); + BT_ASSERT(!m_sessionNames.contains(key)); m_sessionNames.insert(key, name); m_settings.setValue(KEY_SESSION_NAME.arg(key), name); @@ -111,8 +112,8 @@ QString BtConfigCore::addSession(const QString & name) { void BtConfigCore::deleteSession(const QString & key) { QMutexLocker lock(&m_mutex); - Q_ASSERT(m_sessionNames.contains(key)); - Q_ASSERT(key != m_currentSessionKey); + BT_ASSERT(m_sessionNames.contains(key)); + BT_ASSERT(key != m_currentSessionKey); m_sessionNames.remove(key); m_settings.remove(GROUP_SESSIONS + key); @@ -121,7 +122,7 @@ void BtConfigCore::deleteSession(const QString & key) { QStringList BtConfigCore::childKeys() { QMutexLocker lock(&m_mutex); - return childGroups__(); + return childKeys__(); } QStringList BtConfigCore::childKeys__() { diff --git a/src/backend/config/btconfigcore.h b/src/backend/config/btconfigcore.h index 5c24b4f..257295d 100644 --- a/src/backend/config/btconfigcore.h +++ b/src/backend/config/btconfigcore.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -18,6 +18,7 @@ #include <QHash> #include <QMutex> #include <QStringList> +#include "../../util/btassert.h" /** @@ -27,15 +28,17 @@ */ class BtConfigCore { - Q_DISABLE_COPY(BtConfigCore) Q_DECLARE_TR_FUNCTIONS(BtConfigCore) public: /* Types: */ - typedef QHash<QString, QString> SessionNamesHashMap; + using SessionNamesHashMap = QHash<QString, QString>; public: /* Methods: */ + BtConfigCore(BtConfigCore const &) = delete; + BtConfigCore & operator=(BtConfigCore const &) = delete; + /** \param[in] settingsFile The filename of the settings file. */ @@ -57,9 +60,9 @@ public: /* Methods: */ */ inline const QString & currentSessionName() const { QMutexLocker lock(&m_mutex); - typedef QHash<QString, QString>::const_iterator SSHCI; + using SSHCI = QHash<QString, QString>::const_iterator; SSHCI it = m_sessionNames.constFind(m_currentSessionKey); - Q_ASSERT(it != m_sessionNames.constEnd()); + BT_ASSERT(it != m_sessionNames.constEnd()); return it.value(); } @@ -239,13 +242,13 @@ public: /* Methods: */ \param[in] prefix the prefix to append */ inline void beginGroup(QString prefix) { - Q_ASSERT(!prefix.isEmpty()); + BT_ASSERT(!prefix.isEmpty()); while (prefix.startsWith('/')) prefix.remove(0, 1); - Q_ASSERT(!prefix.isEmpty()); + BT_ASSERT(!prefix.isEmpty()); while (prefix.endsWith('/')) prefix.chop(1); - Q_ASSERT(!prefix.isEmpty()); + BT_ASSERT(!prefix.isEmpty()); m_mutex.lock(); m_groups.append(prefix); @@ -262,7 +265,8 @@ public: /* Methods: */ \warning Locks the object (recursively) until endGroup(). */ inline void endGroup() { - Q_ASSERT_X(!m_groups.isEmpty(), "BtConfig", "endGroup() called, but no beginGroup() active."); + BT_ASSERT(!m_groups.isEmpty() + && "BtConfig::endGroup() called, but no beginGroup() active"); m_groups.removeLast(); m_cachedGroup = QString(); m_mutex.unlock(); diff --git a/src/backend/cswordmodulesearch.cpp b/src/backend/cswordmodulesearch.cpp index 799032b..ff5f20b 100644 --- a/src/backend/cswordmodulesearch.cpp +++ b/src/backend/cswordmodulesearch.cpp @@ -2,34 +2,33 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ -#include <QDebug> +#include "cswordmodulesearch.h" -#include "backend/cswordmodulesearch.h" - -#include "backend/config/btconfig.h" -#include "backend/managers/cswordbackend.h" +#include "../util/tool.h" #include "btglobal.h" -#include "util/tool.h" +#include "config/btconfig.h" +#include "managers/cswordbackend.h" void CSwordModuleSearch::startSearch() { // Clear old search results: m_results.clear(); - m_foundItems = 0; + m_foundItems = 0u; /// \todo What is the purpose of the following statement? CSwordBackend::instance()->setFilterOptions(btConfig().getFilterOptions()); // Search module-by-module: - Q_FOREACH(const CSwordModuleInfo *m, m_searchModules) { + Q_FOREACH(CSwordModuleInfo const * const m, m_searchModules) { sword::ListKey results; - int found = m->searchIndexed(m_searchText, m_searchScope, results); - if (found > 0) { + size_t const found = + m->searchIndexed(m_searchText, m_searchScope, results); + if (found > 0u) { m_results.insert(m, results); m_foundItems += found; } @@ -53,81 +52,68 @@ void CSwordModuleSearch::setSearchScope(const sword::ListKey &scope) { } } -QList<const CSwordModuleInfo*> CSwordModuleSearch::unindexedModules( - const QList<const CSwordModuleInfo*> &modules) +const BtConstModuleList CSwordModuleSearch::unindexedModules( + const BtConstModuleList &modules) { - QList<const CSwordModuleInfo*> unindexed; - Q_FOREACH (const CSwordModuleInfo *m, modules) { - if (!m->hasIndex()) { + BtConstModuleList unindexed; + Q_FOREACH(CSwordModuleInfo const * const m, modules) + if (!m->hasIndex()) unindexed.append(m); - } - } return unindexed; } QString CSwordModuleSearch::highlightSearchedText(const QString& content, const QString& searchedText) { QString ret = content; - const Qt::CaseSensitivity cs = Qt::CaseInsensitive; + static Qt::CaseSensitivity const cs = Qt::CaseInsensitive; // int index = 0; int index = ret.indexOf("<body", 0); - int matchLen = 0; - int length = searchedText.length(); - // Highlighting constants - - // \todo We need to make the highlight color configurable. - const QString rep1("<span style=\"background-color:#FFFF66;\">"); + // Work around Qt5 QML bug + // QTBUG-36837 "background-color" css style in QML TextEdit does not work on most tags + const QString rep1("<span class=\"highlightwords\">"); + const QString rep3("class=\"highlightwords\" "); const QString rep2("</span>"); const unsigned int repLength = rep1.length() + rep1.length(); - const QString rep3("style=\"background-color:#FFFF66;\" "); const unsigned int rep3Length = rep3.length(); - - QString newSearchText; - - newSearchText = searchedText; - // find the strongs search lemma and highlight it // search the searched text for "strong:" until it is not found anymore - QStringList list; - // split the search string - some possibilities are "\\s|\\|", "\\s|\\+", or "\\s|\\|\\+" // \todo find all possible seperators - QString regExp = "\\s"; - list = searchedText.split(QRegExp(regExp)); - foreach (QString newSearchText, list) { - int sstIndex; // strong search text index for finding "strong:" - int idx1, idx2; - QString sNumber, lemmaText; - - sstIndex = newSearchText.indexOf("strong:"); + Q_FOREACH (QString const & newSearchText, + searchedText.split(QRegExp("\\s"))) + { + // strong search text index for finding "strong:" + int sstIndex = newSearchText.indexOf("strong:"); if (sstIndex == -1) continue; - // set the start index to the start of <body> - int strongIndex = index; - // Get the strongs number from the search text. // First, find the first space after "strong:" sstIndex = sstIndex + 7; + + // set the start index to the start of <body> + int strongIndex = index; + // get the strongs number -> the text following "strong:" to the end of the string. - sNumber = newSearchText.mid(sstIndex, -1); // find all the "lemma=" inside the the content while ((strongIndex = ret.indexOf("lemma=", strongIndex, cs)) != -1) { // get the strongs number after the lemma and compare it with the // strongs number we are looking for - idx1 = ret.indexOf("\"", strongIndex) + 1; - idx2 = ret.indexOf("\"", idx1 + 1); - lemmaText = ret.mid(idx1, idx2 - idx1); + int const idx1 = ret.indexOf("\"", strongIndex) + 1; + int const idx2 = ret.indexOf("\"", idx1 + 1); // this is interesting because we could have a strongs number like: G3218|G300 // To handle this we will use some extra cpu cycles and do a partial match against // the lemmaText - if (lemmaText.contains(sNumber)) { + if (ret.mid(idx1, idx2 - idx1).contains(newSearchText.mid(sstIndex, + -1))) + { // strongs number is found now we need to highlight it // I believe the easiest way is to insert rep3 just before "lemma=" - ret = ret.insert(strongIndex, rep3); + ret = ret.insert(strongIndex, rep3); /// \bug ? strongIndex += rep3Length; } strongIndex += 6; // 6 is the length of "lemma=" @@ -162,9 +148,13 @@ QString CSwordModuleSearch::highlightSearchedText(const QString& content, const // since I could not figure out the lucene query parser, I // made a simple parser. //=========================================================== - QStringList words = queryParser(newSearchText); - qDebug() << "btsearchresultarea.cpp: " << __LINE__ << ": " << words << '\n'; - foreach (QString word, words) { //search for every word in the list + int length = searchedText.length(); + int matchLen = 0; + for (QStringList words(queryParser(searchedText)); + !words.empty(); + words.pop_front()) + { + QString & word = words.first(); QRegExp findExp; if (word.contains("*")) { length = word.length() - 1; @@ -198,27 +188,20 @@ QString CSwordModuleSearch::highlightSearchedText(const QString& content, const index += length; } } - qDebug() << "btsearchresultarea.cpp: " << __LINE__ << ": " << words << '\n'; - //qWarning("\n\n\n%s", ret.latin1()); return ret; } QStringList CSwordModuleSearch::queryParser(const QString& queryString) { - QString token; + QString token(""); QStringList tokenList; - int cnt, pos; - - token = ""; - cnt = 0; - while (cnt < queryString.length()) { + for (int cnt = 0; cnt < queryString.length(); cnt++) { + loop1_body: // add to token if ((queryString[cnt]).isLetterOrNumber() || (queryString[cnt] == '*')) { token = token + queryString[cnt]; - cnt++; } else if ((queryString[cnt]).isLetterOrNumber() || (queryString[cnt] == '?')) { token = token + queryString[cnt]; - cnt++; } // token break else if (queryString[cnt] == ' ') { @@ -226,14 +209,11 @@ QStringList CSwordModuleSearch::queryParser(const QString& queryString) { if ((token != "*") && (token != "")) tokenList.append(token); token = ""; - cnt++; } // clucene appears to ignore quoted strings in the sence // that it treats all the words within quoted strings as // regular tokens and not as a single token. - else if (queryString[cnt] == '"') { - cnt++; - } + else if (queryString[cnt] == '"') {} // wild card - treat as a special token break //else if (queryString[cnt] == '*') { // token = token + queryString[cnt]; @@ -242,7 +222,6 @@ QStringList CSwordModuleSearch::queryParser(const QString& queryString) { // tokenList.append(token); // // start next token with wildcard (kin*m -> kin* *m) // token = "*"; - // cnt++; //} // the ! token is also a token break else if (queryString[cnt] == '!') { @@ -253,7 +232,6 @@ QStringList CSwordModuleSearch::queryParser(const QString& queryString) { // add the ! token tokenList.append("!"); token = ""; - cnt++; } // the - token is also a token break else if (queryString[cnt] == '-') { @@ -264,7 +242,6 @@ QStringList CSwordModuleSearch::queryParser(const QString& queryString) { // add the ! token tokenList.append("-"); token = ""; - cnt++; } // the + token is also a token break else if (queryString[cnt] == '+') { @@ -275,39 +252,40 @@ QStringList CSwordModuleSearch::queryParser(const QString& queryString) { // add the + token tokenList.append("+"); token = ""; - cnt++; } // the || token is also a token break - else if ((queryString[cnt] == '|') && (queryString[cnt+1] == '|')) { - // store away current token - token = token.simplified(); - if ((token != "*") && (token != "")) - tokenList.append(token); - // add the || token - tokenList.append("||"); - token = ""; - cnt += 2; - } - // the && token is also a token break - else if ((queryString[cnt] == '&') && (queryString[cnt+1] == '&')) { - // store away current token - token = token.simplified(); - if ((token != "*") && (token != "")) - tokenList.append(token); - // add the || token - tokenList.append("&&"); + else { + if ((queryString[cnt] == '|') && (queryString[cnt+1] == '|')) { + // store away current token + token = token.simplified(); + if ((token != "*") && (token != "")) + tokenList.append(token); + // add the || token + tokenList.append("||"); + } + // the && token is also a token break + else if ((queryString[cnt] == '&') && (queryString[cnt+1] == '&')) { + // store away current token + token = token.simplified(); + if ((token != "*") && (token != "")) + tokenList.append(token); + // add the || token + tokenList.append("&&"); + } else { + continue; + } token = ""; cnt += 2; + goto loop1_body; } - else cnt++; } token = token.simplified(); if ((token != "*") && (token != "")) tokenList.append(token); - cnt = 0; - QStringList::iterator it; - for (it = tokenList.begin(); it != tokenList.end(); ++it) { + using TLI = QStringList::iterator; + for (TLI it = tokenList.begin(); it != tokenList.end(); ++it) { + int pos; //----------------------------------------------------------- // remove all the NOT(!) tokens - these do not need to be // highlighted in the highlighter @@ -334,7 +312,7 @@ QStringList CSwordModuleSearch::queryParser(const QString& queryString) { } // if the token contains a ^ then trim the remainder of the // token from the ^ - //What??? error: invalid conversion from ‘const void*’ to ‘int’ + //What??? error: invalid conversion from 'const void*' to 'int' // and how come "contains" returns bool but is used as int? //else if ( (pos = (*it).contains("^")) >= 0 ) { else if ( (pos = (*it).indexOf("^") ) >= 0 ) { @@ -348,3 +326,33 @@ QStringList CSwordModuleSearch::queryParser(const QString& queryString) { } return(tokenList); } + +QString CSwordModuleSearch::prepareSearchText( + QString const & orig, + SearchType const searchType) +{ + if (searchType == FullType) + return orig; + static const QRegExp syntaxCharacters("[+\\-()!\"~]"); + static const QRegExp andWords("\\band\\b", Qt::CaseInsensitive); + static const QRegExp orWords("\\bor\\b", Qt::CaseInsensitive); + QString text(orig.simplified()); + text.remove(syntaxCharacters); + text.replace(andWords, "\"and\""); + text.replace(orWords, "\"or\""); + if (searchType == AndType) + text.replace(" ", " AND "); + return text; +} + +QDataStream &operator<<(QDataStream &out, const CSwordModuleSearch::SearchType &searchType) { + out << static_cast<qint8>(searchType); + return out; +} + +QDataStream &operator>>(QDataStream &in, CSwordModuleSearch::SearchType &searchType) { + qint8 i; + in >> i; + searchType = static_cast<CSwordModuleSearch::SearchType>(i); + return in; +} diff --git a/src/backend/cswordmodulesearch.h b/src/backend/cswordmodulesearch.h index 48b66d2..5ceb085 100644 --- a/src/backend/cswordmodulesearch.h +++ b/src/backend/cswordmodulesearch.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -15,13 +15,14 @@ #include <QObject> #include <QHash> +#include <QMetaType> +#include "../util/btassert.h" +#include "drivers/btmodulelist.h" // Sword includes: #include <listkey.h> -class CSwordModuleInfo; - /** * CSwordModuleSearch manages the search on Sword modules. It manages the thread(s) * and manages the different modules. @@ -34,11 +35,17 @@ class CSwordModuleSearch: public QObject { Q_OBJECT public: /* Types: */ - typedef QHash<const CSwordModuleInfo*, sword::ListKey> Results; + using Results = QHash<const CSwordModuleInfo*, sword::ListKey>; + + enum SearchType { /* Values provided for serialization */ + AndType = 0, + OrType = 1, + FullType = 2 + }; public: /* Methods: */ inline CSwordModuleSearch() - : m_foundItems(0) {} + : m_foundItems(0u) {} /** Sets the text which should be search in the modules. @@ -52,9 +59,9 @@ class CSwordModuleSearch: public QObject { Set the modules which should be searched. \param[in] modules the modules to search in. */ - inline void setModules(const QList<const CSwordModuleInfo*> &modules) { - Q_ASSERT(!modules.empty()); - Q_ASSERT(unindexedModules(modules).empty()); + inline void setModules(const BtConstModuleList &modules) { + BT_ASSERT(!modules.empty()); + BT_ASSERT(unindexedModules(modules).empty()); m_searchModules = modules; } @@ -80,13 +87,14 @@ class CSwordModuleSearch: public QObject { /** Starts the search for the search text. + \throws on error */ void startSearch(); /** \returns the number of found items in the last search. */ - inline unsigned long foundItems() const { + inline size_t foundItems() const { return m_foundItems; } @@ -100,14 +108,19 @@ class CSwordModuleSearch: public QObject { /** \returns the list of unindexed modules in the given list. */ - static QList<const CSwordModuleInfo*> unindexedModules( - const QList<const CSwordModuleInfo*> &modules); + static const BtConstModuleList unindexedModules(const BtConstModuleList & modules); /** * This function highlights the searched text in the content using the search type given by search flags */ static QString highlightSearchedText(const QString& content, const QString& searchedText); + /** + Prepares the search string given by user for a specific search type + */ + static QString prepareSearchText(QString const & orig, + SearchType const searchType); + protected: /** * This function breakes the queryString into clucene tokens @@ -117,10 +130,14 @@ class CSwordModuleSearch: public QObject { private: /* Fields: */ QString m_searchText; sword::ListKey m_searchScope; - QList<const CSwordModuleInfo*> m_searchModules; + BtConstModuleList m_searchModules; Results m_results; - unsigned long m_foundItems; + size_t m_foundItems; }; +QDataStream &operator<<(QDataStream &out, const CSwordModuleSearch::SearchType &searchType); +QDataStream &operator>>(QDataStream &in, CSwordModuleSearch::SearchType &searchType); +Q_DECLARE_METATYPE(CSwordModuleSearch::SearchType) + #endif diff --git a/src/backend/drivers/btconstmoduleset.h b/src/backend/drivers/btconstmoduleset.h new file mode 100644 index 0000000..2e8138c --- /dev/null +++ b/src/backend/drivers/btconstmoduleset.h @@ -0,0 +1,35 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef BTCONSTMODULESET_H +#define BTCONSTMODULESET_H + +#include <QSet> + + +class CSwordModuleInfo; + +class BtConstModuleSet: public QSet<CSwordModuleInfo const *> { + +public: /* Methods: */ + + BtConstModuleSet(QSet<CSwordModuleInfo const *> const & copy) + : QSet<CSwordModuleInfo const *>(copy) + {} + + BtConstModuleSet(QSet<CSwordModuleInfo *> other) { + Q_FOREACH(CSwordModuleInfo const * const item, other) + insert(item); + } + +}; + +#endif /* BTCONSTMODULESET_H */ diff --git a/src/backend/drivers/btdisplayholder.h b/src/backend/drivers/btdisplayholder.h new file mode 100644 index 0000000..6c3393d --- /dev/null +++ b/src/backend/drivers/btdisplayholder.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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef BTDISPLAYHOLDER_H +#define BTDISPLAYHOLDER_H + +#include "../rendering/centrydisplay.h" + + +template <typename CRTP> +class BtDisplayHolder { + +public: /* Methods: */ + + BtDisplayHolder(Rendering::CEntryDisplay * display = nullptr) noexcept + : m_display(display) + {} + + virtual ~BtDisplayHolder() noexcept {} + + void setDisplay(Rendering::CEntryDisplay * display = nullptr) noexcept + { m_display = display; } + + Rendering::CEntryDisplay * getDisplay() const noexcept { return m_display; } + + void display() noexcept { + if (auto * display = m_display) + display->display(static_cast<CRTP &>(*this)); + } + +private: /* Fields: */ + + Rendering::CEntryDisplay * m_display = nullptr; + +}; + +#endif /* BTDISPLAYHOLDER_H */ diff --git a/src/backend/drivers/btmodulelist.h b/src/backend/drivers/btmodulelist.h new file mode 100644 index 0000000..9506215 --- /dev/null +++ b/src/backend/drivers/btmodulelist.h @@ -0,0 +1,35 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef BTMODULELIST_H +#define BTMODULELIST_H + +#include <QList> + +class CSwordModuleInfo; + +using BtModuleList = QList<CSwordModuleInfo *>; /* +using BtConstModuleList = QList<CSwordModuleInfo const *>; */ + +class BtConstModuleList : public QList<CSwordModuleInfo const *> { +public: /* Methods */ + inline BtConstModuleList() {} + inline BtConstModuleList(BtModuleList const & other) { + Q_FOREACH(CSwordModuleInfo const * const m, other) + this->append(m); + } + inline BtConstModuleList(QList<CSwordModuleInfo const *> const & other) { + Q_FOREACH(CSwordModuleInfo const * const m, other) + this->append(m); + } +}; + +#endif // BTMODULELIST_H diff --git a/src/backend/drivers/btmoduleset.h b/src/backend/drivers/btmoduleset.h new file mode 100644 index 0000000..c4ce047 --- /dev/null +++ b/src/backend/drivers/btmoduleset.h @@ -0,0 +1,37 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef BTMODULESET_H +#define BTMODULESET_H + +#include <QSet> + + +class CSwordModuleInfo; + +class BtModuleSet: public QSet<CSwordModuleInfo *> { + +public: /* Methods: */ + + inline BtModuleSet() {}; + + inline BtModuleSet(QSet<CSwordModuleInfo *> const & copy) + : QSet<CSwordModuleInfo *>(copy) + {} + + inline bool contains(CSwordModuleInfo const * const m) const { + return this->QSet<CSwordModuleInfo *>::contains( + const_cast<CSwordModuleInfo *>(m)); + } + +}; + +#endif /* BTMODULESET_H */ diff --git a/src/backend/drivers/cswordbiblemoduleinfo.cpp b/src/backend/drivers/cswordbiblemoduleinfo.cpp index 1c1d124..266e874 100644 --- a/src/backend/drivers/cswordbiblemoduleinfo.cpp +++ b/src/backend/drivers/cswordbiblemoduleinfo.cpp @@ -2,29 +2,30 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ -#include "backend/drivers/cswordbiblemoduleinfo.h" +#include "cswordbiblemoduleinfo.h" -#include <QSharedPointer> +#include <memory> #include <QFile> -#include "backend/managers/cswordbackend.h" +#include "../../util/btassert.h" +#include "../managers/cswordbackend.h" // Sword includes: #include <versekey.h> -CSwordBibleModuleInfo::CSwordBibleModuleInfo(sword::SWModule *module, +CSwordBibleModuleInfo::CSwordBibleModuleInfo(sword::SWModule & module, CSwordBackend & backend, ModuleType type) : CSwordModuleInfo(module, backend, type) , m_boundsInitialized(false) - , m_lowerBound(0) - , m_upperBound(0) - , m_bookList(0) + , m_lowerBound(nullptr) + , m_upperBound(nullptr) + , m_bookList(nullptr) { // Intentionally empty } @@ -32,21 +33,21 @@ CSwordBibleModuleInfo::CSwordBibleModuleInfo(sword::SWModule *module, void CSwordBibleModuleInfo::initBounds() const { /// \todo The fields calculated by this method could be cached to disk. - Q_ASSERT(!m_boundsInitialized); + BT_ASSERT(!m_boundsInitialized); - sword::SWModule *m = module(); - const bool oldStatus = m->isSkipConsecutiveLinks(); - m->setSkipConsecutiveLinks(true); + auto & m = module(); + const bool oldStatus = m.isSkipConsecutiveLinks(); + m.setSkipConsecutiveLinks(true); - m->setPosition(sword::TOP); // position to first entry - sword::VerseKey key(module()->getKeyText()); + m.setPosition(sword::TOP); // position to first entry + sword::VerseKey key(m.getKeyText()); m_hasOT = (key.getTestament() == 1); - m->setPosition(sword::BOTTOM); - key = module()->getKeyText(); + m.setPosition(sword::BOTTOM); + key = m.getKeyText(); m_hasNT = (key.getTestament() == 2); - m->setSkipConsecutiveLinks(oldStatus); + m.setSkipConsecutiveLinks(oldStatus); m_lowerBound.setKey(m_hasOT ? "Genesis 1:1" : "Matthew 1:1"); m_upperBound.setKey(!m_hasNT ? "Malachi 4:6" : "Revelation of John 22:21"); @@ -63,7 +64,7 @@ QStringList *CSwordBibleModuleInfo::books() const { // Reset the booklist because the locale has changed m_cachedLocale = b.booknameLanguage(); delete m_bookList; - m_bookList = 0; + m_bookList = nullptr; } } @@ -84,9 +85,10 @@ QStringList *CSwordBibleModuleInfo::books() const { max--; // max == 1 if (min > max) { - qWarning("CSwordBibleModuleInfo (%s) no OT and not NT! Check your config!", module()->getName()); + qWarning("CSwordBibleModuleInfo (%s) no OT and not NT! Check your config!", module().getName()); } else { - QSharedPointer<sword::VerseKey> key((sword::VerseKey *)module()->createKey()); + std::unique_ptr<sword::VerseKey> key( + static_cast<sword::VerseKey *>(module().createKey())); key->setPosition(sword::TOP); for (key->setTestament(min); !key->popError() && key->getTestament() <= max; key->setBook(key->getBook() + 1)) { @@ -101,7 +103,8 @@ QStringList *CSwordBibleModuleInfo::books() const { unsigned int CSwordBibleModuleInfo::chapterCount(const unsigned int book) const { int result = 0; - QSharedPointer<sword::VerseKey> key((sword::VerseKey *)module()->createKey()); + std::unique_ptr<sword::VerseKey> key( + static_cast<sword::VerseKey *>(module().createKey())); key->setPosition(sword::TOP); // works for old and new versions @@ -123,7 +126,8 @@ unsigned int CSwordBibleModuleInfo::verseCount(const unsigned int book, { unsigned int result = 0; - QSharedPointer<sword::VerseKey> key((sword::VerseKey *)module()->createKey()); + std::unique_ptr<sword::VerseKey> key( + static_cast<sword::VerseKey *>(module().createKey())); key->setPosition(sword::TOP); // works for old and new versions @@ -144,7 +148,8 @@ unsigned int CSwordBibleModuleInfo::verseCount(const QString &book, unsigned int CSwordBibleModuleInfo::bookNumber(const QString &book) const { unsigned int bookNumber = 0; - QSharedPointer<sword::VerseKey> key((sword::VerseKey *)module()->createKey()); + std::unique_ptr<sword::VerseKey> key( + static_cast<sword::VerseKey *>(module().createKey())); key->setPosition(sword::TOP); key->setBookName(book.toUtf8().constData()); diff --git a/src/backend/drivers/cswordbiblemoduleinfo.h b/src/backend/drivers/cswordbiblemoduleinfo.h index fb630c3..4107a48 100644 --- a/src/backend/drivers/cswordbiblemoduleinfo.h +++ b/src/backend/drivers/cswordbiblemoduleinfo.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -12,10 +12,10 @@ #ifndef CSWORDBIBLEMODULEINFO_H #define CSWORDBIBLEMODULEINFO_H -#include "backend/drivers/cswordmoduleinfo.h" +#include "cswordmoduleinfo.h" #include <QStringList> -#include "backend/keys/cswordversekey.h" +#include "../keys/cswordversekey.h" /** @@ -27,7 +27,7 @@ class CSwordBibleModuleInfo: public CSwordModuleInfo { Q_OBJECT public: /* Methods: */ - CSwordBibleModuleInfo(sword::SWModule * module, + CSwordBibleModuleInfo(sword::SWModule & module, CSwordBackend & backend, ModuleType type = Bible); diff --git a/src/backend/drivers/cswordbookmoduleinfo.cpp b/src/backend/drivers/cswordbookmoduleinfo.cpp index bae54b9..aab5a32 100644 --- a/src/backend/drivers/cswordbookmoduleinfo.cpp +++ b/src/backend/drivers/cswordbookmoduleinfo.cpp @@ -2,21 +2,22 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ -#include "backend/drivers/cswordbookmoduleinfo.h" +#include "cswordbookmoduleinfo.h" -#include "backend/keys/cswordtreekey.h" +#include "../../util/btassert.h" +#include "../keys/cswordtreekey.h" // Sword includes: #include <treekey.h> #include <treekeyidx.h> -CSwordBookModuleInfo::CSwordBookModuleInfo(sword::SWModule * module, +CSwordBookModuleInfo::CSwordBookModuleInfo(sword::SWModule & module, CSwordBackend & backend) : CSwordModuleInfo(module, backend, CSwordModuleInfo::GenericBook) , m_depth(-1) @@ -47,7 +48,8 @@ void CSwordBookModuleInfo::computeDepth(sword::TreeKeyIdx * const key, /** Returns a treekey filled with the structure of this module */ sword::TreeKeyIdx* CSwordBookModuleInfo::tree() const { - sword::TreeKeyIdx* treeKey = dynamic_cast<sword::TreeKeyIdx*>((sword::SWKey*) * (module())); - Q_ASSERT(treeKey); + sword::TreeKeyIdx * const treeKey = + dynamic_cast<sword::TreeKeyIdx *>(module().getKey()); + BT_ASSERT(treeKey); return treeKey; } diff --git a/src/backend/drivers/cswordbookmoduleinfo.h b/src/backend/drivers/cswordbookmoduleinfo.h index d540932..9085755 100644 --- a/src/backend/drivers/cswordbookmoduleinfo.h +++ b/src/backend/drivers/cswordbookmoduleinfo.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -12,7 +12,7 @@ #ifndef CSWORDGENBOOKMODULEINFO_H #define CSWORDGENBOOKMODULEINFO_H -#include "backend/drivers/cswordmoduleinfo.h" +#include "cswordmoduleinfo.h" // Sword includes: #include <treekeyidx.h> @@ -29,12 +29,9 @@ class CSwordBookModuleInfo: public CSwordModuleInfo { \param module The module which belongs to this object \param backend The parent backend for this book module. */ - CSwordBookModuleInfo(sword::SWModule * module, + CSwordBookModuleInfo(sword::SWModule & module, CSwordBackend & usedBackend); - inline CSwordBookModuleInfo(const CSwordBookModuleInfo ©) - : CSwordModuleInfo(copy), m_depth(copy.m_depth) {} - /** \returns the maximal depth of sections and subsections. */ diff --git a/src/backend/drivers/cswordcommentarymoduleinfo.cpp b/src/backend/drivers/cswordcommentarymoduleinfo.cpp index 9baaf97..67c1351 100644 --- a/src/backend/drivers/cswordcommentarymoduleinfo.cpp +++ b/src/backend/drivers/cswordcommentarymoduleinfo.cpp @@ -2,17 +2,19 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ -#include "backend/drivers/cswordcommentarymoduleinfo.h" +#include "cswordcommentarymoduleinfo.h" + bool CSwordCommentaryModuleInfo::isWritable() const { /* A module is only writable if it's a RawFiles module with writable returning true. */ - return !qstrcmp(module()->getConfigEntry("ModDrv"), "RawFiles") && module()->isWritable(); + return !qstrcmp(module().getConfigEntry("ModDrv"), "RawFiles") + && module().isWritable(); } diff --git a/src/backend/drivers/cswordcommentarymoduleinfo.h b/src/backend/drivers/cswordcommentarymoduleinfo.h index 688ae53..30c5162 100644 --- a/src/backend/drivers/cswordcommentarymoduleinfo.h +++ b/src/backend/drivers/cswordcommentarymoduleinfo.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -12,7 +12,7 @@ #ifndef CSWORDCOMMENTARYMODULEINFO_H #define CSWORDCOMMENTARYMODULEINFO_H -#include "backend/drivers/cswordbiblemoduleinfo.h" +#include "cswordbiblemoduleinfo.h" /** @@ -25,14 +25,13 @@ class CSwordCommentaryModuleInfo: public CSwordBibleModuleInfo { public: /* Methods: */ - inline CSwordCommentaryModuleInfo(sword::SWModule * module, + inline CSwordCommentaryModuleInfo(sword::SWModule & module, CSwordBackend & backend) : CSwordBibleModuleInfo(module, backend, CSwordModuleInfo::Commentary) {} - /* Reimplementation of CSwordModuleInfo::isWritable(). */ - virtual bool isWritable() const; + bool isWritable() const override; }; #endif diff --git a/src/backend/drivers/cswordlexiconmoduleinfo.cpp b/src/backend/drivers/cswordlexiconmoduleinfo.cpp index 350a49c..d523fa0 100644 --- a/src/backend/drivers/cswordlexiconmoduleinfo.cpp +++ b/src/backend/drivers/cswordlexiconmoduleinfo.cpp @@ -2,19 +2,19 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ -#include "backend/drivers/cswordlexiconmoduleinfo.h" +#include "cswordlexiconmoduleinfo.h" #include <QFile> #include <QDataStream> #include <QTextCodec> #include <QDebug> -#include "util/directory.h" +#include "../../util/directory.h" // Sword includes: #include <swmodule.h> @@ -69,25 +69,26 @@ const QStringList &CSwordLexiconModuleInfo::entries() const { */ qDebug() << "Read all entries of lexicon" << name(); - module()->setSkipConsecutiveLinks(true); - module()->setPosition(sword::TOP); + auto & m = module(); + m.setSkipConsecutiveLinks(true); + m.setPosition(sword::TOP); snap(); //snap to top entry do { if ( isUnicode() ) { - m_entries.append(QString::fromUtf8(module()->getKeyText())); + m_entries.append(QString::fromUtf8(m.getKeyText())); } else { //for latin1 modules use fromLatin1 because of speed QTextCodec* codec = QTextCodec::codecForName("Windows-1252"); - m_entries.append(codec->toUnicode(module()->getKeyText())); + m_entries.append(codec->toUnicode(m.getKeyText())); } - module()->increment(); - } while (!module()->popError()); + m.increment(); + } while (!m.popError()); - module()->setPosition(sword::TOP); // back to the first entry - module()->setSkipConsecutiveLinks(false); + m.setPosition(sword::TOP); // back to the first entry + m.setSkipConsecutiveLinks(false); /// \todo Document why the following code is here: if (!m_entries.empty() && m_entries.front().simplified().isEmpty()) diff --git a/src/backend/drivers/cswordlexiconmoduleinfo.h b/src/backend/drivers/cswordlexiconmoduleinfo.h index 74fad8c..bd69dcc 100644 --- a/src/backend/drivers/cswordlexiconmoduleinfo.h +++ b/src/backend/drivers/cswordlexiconmoduleinfo.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -12,7 +12,7 @@ #ifndef CSWORDLEXICONMODULEINFO_H #define CSWORDLEXICONMODULEINFO_H -#include "backend/drivers/cswordmoduleinfo.h" +#include "cswordmoduleinfo.h" #include <QStringList> @@ -24,13 +24,10 @@ class CSwordLexiconModuleInfo: public CSwordModuleInfo { Q_OBJECT public: /* Methods: */ - inline CSwordLexiconModuleInfo(sword::SWModule * module, + inline CSwordLexiconModuleInfo(sword::SWModule & module, CSwordBackend & backend) : CSwordModuleInfo(module, backend, Lexicon) {} - inline CSwordLexiconModuleInfo(const CSwordLexiconModuleInfo ©) - : CSwordModuleInfo(copy), m_entries(copy.m_entries) {} - /** This method returns the entries of the modules represented by this object. If this function is called for the first time the list is load @@ -44,8 +41,8 @@ class CSwordLexiconModuleInfo: public CSwordModuleInfo { /** Jumps to the closest entry in the module. */ - virtual inline bool snap() const { - return module()->getRawEntry(); + inline bool snap() const override { + return module().getRawEntry(); } private: /* Fields: */ diff --git a/src/backend/drivers/cswordmoduleinfo.cpp b/src/backend/drivers/cswordmoduleinfo.cpp index f86f9ac..70f83e3 100644 --- a/src/backend/drivers/cswordmoduleinfo.cpp +++ b/src/backend/drivers/cswordmoduleinfo.cpp @@ -2,37 +2,37 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ -#include "backend/drivers/cswordmoduleinfo.h" +#include "cswordmoduleinfo.h" +#include <memory> +#include <cassert> +#ifndef BT_NO_LUCENE #include <CLucene.h> +#endif #include <QByteArray> #include <QCoreApplication> #include <QDebug> #include <QDir> #include <QFileInfo> #include <QSettings> -#include <QSharedPointer> #include <QTextDocument> -#include "backend/config/btconfig.h" -#include "backend/drivers/cswordlexiconmoduleinfo.h" -#include "backend/keys/cswordkey.h" -#include "backend/managers/clanguagemgr.h" -#include "backend/managers/cswordbackend.h" -#include "backend/rendering/centrydisplay.h" -#include "backend/cswordmodulesearch.h" -#include "bibletimeapp.h" -#include "btglobal.h" -#include "frontend/messagedialog.h" -#include "util/cresmgr.h" -#include "util/directory.h" -#include "util/exceptions.h" -#include "util/geticon.h" -#include "util/htmlescape.h" +#include "../../util/btassert.h" +#include "../../util/btscopeexit.h" +#include "../../util/cresmgr.h" +#include "../../util/directory.h" +#include "../config/btconfig.h" +#include "../keys/cswordkey.h" +#include "../managers/clanguagemgr.h" +#include "../managers/cswordbackend.h" +#include "../rendering/centrydisplay.h" +#include "../cswordmodulesearch.h" +#include "cswordbiblemoduleinfo.h" +#include "cswordlexiconmoduleinfo.h" // Sword includes: #include <listkey.h> @@ -45,25 +45,71 @@ //Increment this, if the index format changes //Then indices on the user's systems will be rebuilt -const unsigned int INDEX_VERSION = 7; +constexpr static unsigned const INDEX_VERSION = 7; //Maximum index entry size, 1MiB for now //Lucene default is too small -const unsigned long BT_MAX_LUCENE_FIELD_LENGTH = 1024 * 1024; +constexpr static unsigned long const BT_MAX_LUCENE_FIELD_LENGTH = 1024 * 1024; + +namespace { -CSwordModuleInfo::CSwordModuleInfo(sword::SWModule * module, +inline CSwordModuleInfo::Category retrieveCategory( + CSwordModuleInfo::ModuleType const type, + sword::SWModule & module) +{ + /// \todo Maybe we can use raw string comparsion instead of QString? + QString const cat(module.getConfigEntry("Category")); + + // Category has to be checked before type: + if (cat == "Cults / Unorthodox / Questionable Material") { + return CSwordModuleInfo::Cult; + } else if (cat == "Daily Devotional" + || module.getConfig().has("Feature","DailyDevotion")) + { + return CSwordModuleInfo::DailyDevotional; + } else if (cat == "Glossaries" + || module.getConfig().has("Feature", "Glossary")) + { + return CSwordModuleInfo::Glossary; + } else if (cat == "Images" || cat == "Maps") { + return CSwordModuleInfo::Images; + } else { + switch (type) { + case CSwordModuleInfo::Bible: + return CSwordModuleInfo::Bibles; + case CSwordModuleInfo::Commentary: + return CSwordModuleInfo::Commentaries; + case CSwordModuleInfo::Lexicon: + return CSwordModuleInfo::Lexicons; + case CSwordModuleInfo::GenericBook: + return CSwordModuleInfo::Books; + case CSwordModuleInfo::Unknown: // Fall thru + default: + return CSwordModuleInfo::UnknownCategory; + } + } +} + +} + +CSwordModuleInfo::CSwordModuleInfo(sword::SWModule & module, CSwordBackend & backend, ModuleType type) - : m_module((Q_ASSERT(module), module)), - m_backend(backend), - m_type(type), - m_cancelIndexing(false), - m_cachedName(QString::fromUtf8(module->getName())), - m_cachedHasVersion(!QString((*m_backend.getConfig())[module->getName()]["Version"]).isEmpty()) + : m_module(module) + , m_backend(backend) + , m_type(type) + , m_cancelIndexing(false) + , m_cachedName(QString::fromUtf8(module.getName())) + , m_cachedCategory(retrieveCategory(type, module)) + , m_cachedLanguage( + CLanguageMgr::instance()->languageForAbbrev( + m_cachedCategory == Glossary + /* Special handling for glossaries, we use the "from language" as + language for the module: */ + ? config(GlossaryFrom) + : module.getLanguage())) + , m_cachedHasVersion(!QString((*m_backend.getConfig())[module.getName()]["Version"]).isEmpty()) { - initCachedCategory(); - initCachedLanguage(); - m_hidden = btConfig().value<QStringList>("state/hiddenModules", QStringList()).contains(m_cachedName); @@ -79,21 +125,6 @@ CSwordModuleInfo::CSwordModuleInfo(sword::SWModule * module, } } -CSwordModuleInfo::CSwordModuleInfo(const CSwordModuleInfo & copy) - : QObject(NULL) - , m_module(copy.m_module) - , m_backend(copy.m_backend) - , m_type(copy.m_type) - , m_hidden(copy.m_hidden) - , m_cancelIndexing(copy.m_cancelIndexing) - , m_cachedName(copy.m_cachedName) - , m_cachedCategory(copy.m_cachedCategory) - , m_cachedLanguage(copy.m_cachedLanguage) - , m_cachedHasVersion(copy.m_cachedHasVersion) -{ - // Intentionally empty -} - bool CSwordModuleInfo::unlock(const QString & unlockKey) { if (!isEncrypted()) return false; @@ -107,7 +138,7 @@ bool CSwordModuleInfo::unlock(const QString & unlockKey) { backend->setCipherKey() does not work correctly for modules from which data was already fetched. Therefore we have to reload the modules in bibletime.cpp */ - m_backend.setCipherKey(m_module->getName(), unlockKey.toUtf8().constData()); + m_backend.setCipherKey(m_module.getName(), unlockKey.toUtf8().constData()); /// \todo write to Sword config as well @@ -131,7 +162,7 @@ bool CSwordModuleInfo::isEncrypted() const { /* This code is still right, though we do no longer write to the module config files any more. */ - typedef sword::SectionMap::const_iterator SMCI; + using SMCI = sword::SectionMap::const_iterator; SMCI it = m_backend.getConfig()->Sections.find(m_cachedName.toUtf8().constData()); if (it == m_backend.getConfig()->Sections.end()) return false; @@ -141,7 +172,7 @@ bool CSwordModuleInfo::isEncrypted() const { } bool CSwordModuleInfo::unlockKeyIsValid() const { - m_module->setPosition(sword::TOP); + m_module.setPosition(sword::TOP); /* This needs to use ::fromLatin1 because if the text is still locked, a lot of garbage will show up. It will also work with properly decrypted @@ -149,8 +180,8 @@ bool CSwordModuleInfo::unlockKeyIsValid() const { and therefore contain no control (nonprintable) characters, which are all <127. */ const QString test(isUnicode() - ? QString::fromUtf8(m_module->getRawEntryBuf().c_str()) - : QString::fromLatin1(m_module->getRawEntryBuf().c_str())); + ? QString::fromUtf8(m_module.getRawEntry()) + : QString::fromLatin1(m_module.getRawEntry())); if (test.isEmpty()) return false; @@ -175,6 +206,9 @@ QString CSwordModuleInfo::getModuleStandardIndexLocation() const { } bool CSwordModuleInfo::hasIndex() const { +#ifdef BT_NO_LUCENE + return false; +#else { // Is this a directory? QFileInfo fi(getModuleStandardIndexLocation()); if (!fi.isDir()) @@ -203,11 +237,14 @@ bool CSwordModuleInfo::hasIndex() const { // Is the index there? return lucene::index::IndexReader::indexExists(getModuleStandardIndexLocation() .toLatin1().constData()); +#endif } -bool CSwordModuleInfo::buildIndex() { - m_cancelIndexing = false; +void CSwordModuleInfo::buildIndex() { + BT_SCOPE_EXIT(m_cancelIndexing.store(false, std::memory_order_relaxed);); +#define CANCEL_INDEXING (m_cancelIndexing.load(std::memory_order_relaxed)) +#ifndef BT_NO_LUCENE try { // Without this we don't get strongs, lemmas, etc. m_backend.setFilterOptions(btConfig().getFilterOptions()); @@ -225,7 +262,7 @@ bool CSwordModuleInfo::buildIndex() { m_backend.setOption(CSwordModuleInfo::redLetterWords, false); // Do not use any stop words: - static const TCHAR * stop_words[1u] = { NULL }; + static const TCHAR * stop_words[1u] = { nullptr }; lucene::analysis::standard::StandardAnalyzer an(static_cast<const TCHAR **>(stop_words)); const QString index(getModuleStandardIndexLocation()); @@ -239,18 +276,31 @@ bool CSwordModuleInfo::buildIndex() { lucene::index::IndexReader::unlock(index.toLatin1().constData()); // Always create a new index: - typedef lucene::index::IndexWriter IW; - QSharedPointer<IW> writer(new IW(index.toLatin1().constData(), &an, true)); + using IW = lucene::index::IndexWriter; + std::unique_ptr<IW> writer(new IW(index.toLatin1().constData(), &an, true)); writer->setMaxFieldLength(BT_MAX_LUCENE_FIELD_LENGTH); writer->setUseCompoundFile(true); // Merge segments into a single file #ifndef CLUCENE2 writer->setMinMergeDocs(1000); #endif - m_module->setPosition(sword::TOP); - unsigned long verseLowIndex = m_module->getIndex(); - m_module->setPosition(sword::BOTTOM); - unsigned long verseHighIndex = m_module->getIndex(); + CSwordBibleModuleInfo *bm = qobject_cast<CSwordBibleModuleInfo*>(this); + + unsigned long verseLowIndex; + unsigned long verseHighIndex; + + if(bm) + { + verseLowIndex = bm->lowerBound().getIndex(); + verseHighIndex = bm->upperBound().getIndex(); + } + else + { + m_module.setPosition(sword::TOP); + verseLowIndex = m_module.getIndex(); + m_module.setPosition(sword::BOTTOM); + verseHighIndex = m_module.getIndex(); + } // verseLowIndex is not 0 in all cases (i.e. NT-only modules) unsigned long verseIndex = verseLowIndex + 1; @@ -265,7 +315,7 @@ bool CSwordModuleInfo::buildIndex() { emit indexingProgress(0); - sword::SWKey * const key = m_module->getKey(); + sword::SWKey * const key = m_module.getKey(); sword::VerseKey * const vk = dynamic_cast<sword::VerseKey *>(key); if (vk) { @@ -281,15 +331,19 @@ bool CSwordModuleInfo::buildIndex() { // we start with the first module entry, key is automatically updated // because key is a pointer to the modules key - m_module->setSkipConsecutiveLinks(true); + m_module.setSkipConsecutiveLinks(true); - QScopedPointer<wchar_t, QScopedPointerArrayDeleter<wchar_t> > - sPwcharBuffer(new wchar_t[BT_MAX_LUCENE_FIELD_LENGTH + 1]); - wchar_t * const wcharBuffer = sPwcharBuffer.data(); - Q_ASSERT(wcharBuffer); + std::unique_ptr<wchar_t[]> sPwcharBuffer( + new wchar_t[BT_MAX_LUCENE_FIELD_LENGTH + 1]); + wchar_t * const wcharBuffer = sPwcharBuffer.get(); + BT_ASSERT(wcharBuffer); - m_module->setPosition(sword::TOP); - while (!(m_module->popError()) && !m_cancelIndexing) { + if(bm) + vk->setIndex(bm->lowerBound().getIndex()); + else + m_module.setPosition(sword::TOP); + + while (!(m_module.popError()) && !CANCEL_INDEXING) { /* Also index Chapter 0 and Verse 0, because they might have information in the entry attributes. We used to just put their @@ -297,7 +351,8 @@ bool CSwordModuleInfo::buildIndex() { with entry attributes this doesn't work any more. Hits in the search dialog will show up as 1:1 (instead of 0). */ - QSharedPointer<lucene::document::Document> doc(new lucene::document::Document()); + std::unique_ptr<lucene::document::Document> doc( + new lucene::document::Document()); //index the key lucene_utf8towcs(wcharBuffer, key->getText(), BT_MAX_LUCENE_FIELD_LENGTH); @@ -310,7 +365,7 @@ bool CSwordModuleInfo::buildIndex() { /* At this point we have to make sure we disabled the strongs and the other options, so the plain filters won't include the numbers somehow. */ - textBuffer.append(m_module->stripText()); + textBuffer.append(m_module.stripText()); lucene_utf8towcs(wcharBuffer, static_cast<const char *>(textBuffer), BT_MAX_LUCENE_FIELD_LENGTH); @@ -320,11 +375,11 @@ bool CSwordModuleInfo::buildIndex() { | lucene::document::Field::INDEX_TOKENIZED))); textBuffer.clear(); - typedef sword::AttributeList::iterator ALI; - typedef sword::AttributeValue::iterator AVI; + using ALI = sword::AttributeList::iterator; + using AVI = sword::AttributeValue::iterator; - for (ALI it = m_module->getEntryAttributes()["Footnote"].begin(); - it != m_module->getEntryAttributes()["Footnote"].end(); + for (ALI it = m_module.getEntryAttributes()["Footnote"].begin(); + it != m_module.getEntryAttributes()["Footnote"].end(); ++it) { lucene_utf8towcs(wcharBuffer, it->second["body"], BT_MAX_LUCENE_FIELD_LENGTH); @@ -335,8 +390,8 @@ bool CSwordModuleInfo::buildIndex() { } // Headings - for (AVI it = m_module->getEntryAttributes()["Heading"]["Preverse"].begin(); - it != m_module->getEntryAttributes()["Heading"]["Preverse"].end(); + for (AVI it = m_module.getEntryAttributes()["Heading"]["Preverse"].begin(); + it != m_module.getEntryAttributes()["Heading"]["Preverse"].end(); ++it) { lucene_utf8towcs(wcharBuffer, it->second, BT_MAX_LUCENE_FIELD_LENGTH); @@ -347,17 +402,27 @@ bool CSwordModuleInfo::buildIndex() { } // Strongs/Morphs - for (ALI it = m_module->getEntryAttributes()["Word"].begin(); - it != m_module->getEntryAttributes()["Word"].end(); + for (ALI it = m_module.getEntryAttributes()["Word"].begin(); + it != m_module.getEntryAttributes()["Word"].end(); ++it) { - if (it->second["LemmaClass"] == "strong") { - lucene_utf8towcs(wcharBuffer, it->second["Lemma"], BT_MAX_LUCENE_FIELD_LENGTH); - doc->add(*(new lucene::document::Field(static_cast<const TCHAR *>(_T("strong")), - static_cast<const TCHAR *>(wcharBuffer), - lucene::document::Field::STORE_NO - | lucene::document::Field::INDEX_TOKENIZED))); + int partCount = QString(it->second["PartCount"]).toInt(); + for (int i=0; i<partCount; i++) { + + sword::SWBuf lemmaKey = "Lemma"; + if (partCount > 1) + lemmaKey.appendFormatted(".%d", i+1); + sword::AttributeValue::iterator lemmaIter = it->second.find(lemmaKey); + if (lemmaIter != it->second.end()) { + lucene_utf8towcs(wcharBuffer, it->second[lemmaKey], BT_MAX_LUCENE_FIELD_LENGTH); + doc->add(*(new lucene::document::Field(static_cast<const TCHAR *>(_T("strong")), + static_cast<const TCHAR *>(wcharBuffer), + lucene::document::Field::STORE_NO + | lucene::document::Field::INDEX_TOKENIZED))); + } + } + if (it->second.find("Morph") != it->second.end()) { lucene_utf8towcs(wcharBuffer, it->second["Morph"], BT_MAX_LUCENE_FIELD_LENGTH); doc->add(*(new lucene::document::Field(static_cast<const TCHAR *>(_T("morph")), @@ -367,35 +432,36 @@ bool CSwordModuleInfo::buildIndex() { } } - writer->addDocument(doc.data()); + writer->addDocument(doc.get()); //Index() is not implemented properly for lexicons, so we use a //workaround. if (m_type == CSwordModuleInfo::Lexicon) { verseIndex++; } else { - verseIndex = m_module->getIndex(); + verseIndex = m_module.getIndex(); } if (verseIndex % 200 == 0) { - int indexingProgressValue; if (verseSpan == 0) { // Prevent division by zero - indexingProgressValue = 0; + emit indexingProgress(0); } else { - indexingProgressValue = (int)((100 * (verseIndex - verseLowIndex)) / (verseSpan)); + emit indexingProgress( + static_cast<int>( + (100 * (verseIndex - verseLowIndex)) + / verseSpan)); } - emit indexingProgress(indexingProgressValue); } - m_module->increment(); - } // while (!(m_module->Error()) && !m_cancelIndexing) + m_module.increment(); + } // while (!(m_module.Error()) && !CANCEL_INDEXING) - if (!m_cancelIndexing) + if (!CANCEL_INDEXING) writer->optimize(); writer->close(); + writer.reset(); - if (m_cancelIndexing) { + if (CANCEL_INDEXING) { deleteIndex(); - m_cancelIndexing = false; } else { QSettings module_config(getModuleBaseIndexLocation() + QString("/bibletime-index.conf"), @@ -406,27 +472,14 @@ bool CSwordModuleInfo::buildIndex() { module_config.setValue("index-version", INDEX_VERSION); emit hasIndexChanged(true); } - } catch (CLuceneError & e) { - qWarning() << "CLucene exception occurred while indexing:" << e.what(); - message::showWarning(0, - QCoreApplication::tr("Indexing aborted"), - QCoreApplication::tr("An internal error occurred " - "while building the index: %1") - .arg(e.what())); - deleteIndex(); - m_cancelIndexing = false; - return false; + // } catch (CLuceneError & e) { } catch (...) { - qWarning("CLucene exception occurred while indexing"); - message::showWarning(0, - QCoreApplication::tr("Indexing aborted"), - QCoreApplication::tr("An internal error occurred " - "while building the index.")); deleteIndex(); - m_cancelIndexing = false; - return false; + throw; } - return true; +#else + return false; +#endif } void CSwordModuleInfo::deleteIndex() { @@ -438,97 +491,95 @@ void CSwordModuleInfo::deleteIndexForModule(const QString & name) { util::directory::removeRecursive(getGlobalBaseIndexLocation() + "/" + name); } -unsigned long CSwordModuleInfo::indexSize() const { +size_t CSwordModuleInfo::indexSize() const { namespace DU = util::directory; return DU::getDirSizeRecursive(getModuleBaseIndexLocation()); } -int CSwordModuleInfo::searchIndexed(const QString & searchedText, - const sword::ListKey & scope, - sword::ListKey & results) const +size_t CSwordModuleInfo::searchIndexed(const QString & searchedText, + const sword::ListKey & scope, + sword::ListKey & results) const { - QScopedPointer<char, QScopedPointerArrayDeleter<char> > - sPutfBuffer(new char[BT_MAX_LUCENE_FIELD_LENGTH + 1]); - QScopedPointer<wchar_t, QScopedPointerArrayDeleter<wchar_t> > - sPwcharBuffer(new wchar_t[BT_MAX_LUCENE_FIELD_LENGTH + 1]); - char * const utfBuffer = sPutfBuffer.data(); - Q_ASSERT(utfBuffer); - wchar_t * const wcharBuffer = sPwcharBuffer.data(); - Q_ASSERT(wcharBuffer); + std::unique_ptr<char[]> sPutfBuffer( + new char[BT_MAX_LUCENE_FIELD_LENGTH + 1]); + std::unique_ptr<wchar_t[]> sPwcharBuffer( + new wchar_t[BT_MAX_LUCENE_FIELD_LENGTH + 1]); + char * const utfBuffer = sPutfBuffer.get(); + BT_ASSERT(utfBuffer); + wchar_t * const wcharBuffer = sPwcharBuffer.get(); + BT_ASSERT(wcharBuffer); // work around Swords thread insafety for Bibles and Commentaries - QSharedPointer<CSwordKey> key(CSwordKey::createInstance(this)); { - const sword::SWKey * const s = dynamic_cast<sword::SWKey *>(key.data()); + std::unique_ptr<CSwordKey> key(CSwordKey::createInstance(this)); + const sword::SWKey * const s = dynamic_cast<sword::SWKey *>(key.get()); if (s) - m_module->setKey(*s); + m_module.setKey(*s); } QList<sword::VerseKey *> list; results.clear(); - try { - // do not use any stop words - static const TCHAR * stop_words[1u] = { NULL }; - lucene::analysis::standard::StandardAnalyzer analyzer(stop_words); - lucene::search::IndexSearcher searcher(getModuleStandardIndexLocation().toLatin1().constData()); - lucene_utf8towcs(wcharBuffer, searchedText.toUtf8().constData(), BT_MAX_LUCENE_FIELD_LENGTH); - QSharedPointer<lucene::search::Query> q(lucene::queryParser::QueryParser::parse(static_cast<const TCHAR *>(wcharBuffer), - static_cast<const TCHAR *>(_T("content")), - &analyzer)); - - QSharedPointer<lucene::search::Hits> h(searcher.search(q.data(), - #ifdef CLUCENE2 - lucene::search::Sort::INDEXORDER())); - #else - lucene::search::Sort::INDEXORDER)); - #endif - - const bool useScope = (scope.getCount() > 0); - - lucene::document::Document * doc = 0; - QSharedPointer<sword::SWKey> swKey(m_module->createKey()); +#ifndef BT_NO_LUCENE + // do not use any stop words + static const TCHAR * stop_words[1u] = { nullptr }; + lucene::analysis::standard::StandardAnalyzer analyzer(stop_words); + lucene::search::IndexSearcher searcher(getModuleStandardIndexLocation().toLatin1().constData()); + lucene_utf8towcs(wcharBuffer, searchedText.toUtf8().constData(), BT_MAX_LUCENE_FIELD_LENGTH); + std::unique_ptr<lucene::search::Query> q(lucene::queryParser::QueryParser::parse(static_cast<const TCHAR *>(wcharBuffer), + static_cast<const TCHAR *>(_T("content")), + &analyzer)); + + std::unique_ptr<lucene::search::Hits> h(searcher.search(q.get(), + #ifdef CLUCENE2 + lucene::search::Sort::INDEXORDER())); + #else + lucene::search::Sort::INDEXORDER)); + #endif + + const bool useScope = (scope.getCount() > 0); + + lucene::document::Document * doc = nullptr; + std::unique_ptr<sword::SWKey> swKey(m_module.createKey()); + + sword::VerseKey * const vk = dynamic_cast<sword::VerseKey *>(swKey.get()); + if (vk) + vk->setIntros(true); #ifdef CLUCENE2 - for (unsigned int i = 0; i < h->length(); ++i) { + for (size_t i = 0; i < h->length(); ++i) { #else - for (int i = 0; i < h->length(); ++i) { + for (int i = 0; i < h->length(); ++i) { #endif - doc = &h->doc(i); - lucene_wcstoutf8(utfBuffer, - static_cast<const wchar_t *>(doc->get(static_cast<const TCHAR *>(_T("key")))), - BT_MAX_LUCENE_FIELD_LENGTH); - - swKey->setText(utfBuffer); - - // Limit results based on scope: - if (useScope) { - for (int j = 0; j < scope.getCount(); j++) { - Q_ASSERT(dynamic_cast<const sword::VerseKey *>(scope.getElement(j))); - const sword::VerseKey * const vkey = static_cast<const sword::VerseKey *>(scope.getElement(j)); - if (vkey->getLowerBound().compare(*swKey) <= 0 - && vkey->getUpperBound().compare(*swKey) >= 0) - { - results.add(*swKey); - } + doc = &h->doc(i); + lucene_wcstoutf8(utfBuffer, + static_cast<const wchar_t *>(doc->get(static_cast<const TCHAR *>(_T("key")))), + BT_MAX_LUCENE_FIELD_LENGTH); + + + swKey->setText(utfBuffer); + + // Limit results based on scope: + if (useScope) { + for (int j = 0; j < scope.getCount(); j++) { + BT_ASSERT(dynamic_cast<const sword::VerseKey *>(scope.getElement(j))); + const sword::VerseKey * const vkey = static_cast<const sword::VerseKey *>(scope.getElement(j)); + if (vkey->getLowerBound().compare(*swKey) <= 0 + && vkey->getUpperBound().compare(*swKey) >= 0) + { + results.add(*swKey); } - } else { - results.add(*swKey); // No scope, give me all buffers } + } else { + results.add(*swKey); // No scope, give me all buffers } - } catch (...) { - qWarning("CLucene exception occurred"); - message::showWarning(0, - QCoreApplication::tr("Search aborted"), - QCoreApplication::tr("An internal error occurred " - "while executing your search.")); - return 0; } +#endif qDeleteAll(list); list.clear(); - return results.getCount(); + return static_cast<size_t>(results.getCount()); } sword::SWVersion CSwordModuleInfo::minimumSwordVersion() const { @@ -544,7 +595,7 @@ QString CSwordModuleInfo::config(const CSwordModuleInfo::ConfigEntry entry) cons case CipherKey: { if (btConfig().getModuleEncryptionKey(m_cachedName).isNull()) { - return QString(m_module->getConfigEntry("CipherKey")); // Fallback + return QString(m_module.getConfigEntry("CipherKey")); // Fallback } else { return btConfig().getModuleEncryptionKey(m_cachedName); } @@ -654,10 +705,10 @@ QString CSwordModuleInfo::config(const CSwordModuleInfo::ConfigEntry entry) cons bool CSwordModuleInfo::has(const CSwordModuleInfo::Feature feature) const { switch (feature) { - case GreekDef: return m_module->getConfig().has("Feature", "GreekDef"); - case HebrewDef: return m_module->getConfig().has("Feature", "HebrewDef"); - case GreekParse: return m_module->getConfig().has("Feature", "GreekParse"); - case HebrewParse: return m_module->getConfig().has("Feature", "HebrewParse"); + case GreekDef: return m_module.getConfig().has("Feature", "GreekDef"); + case HebrewDef: return m_module.getConfig().has("Feature", "HebrewDef"); + case GreekParse: return m_module.getConfig().has("Feature", "GreekParse"); + case HebrewParse: return m_module.getConfig().has("Feature", "HebrewParse"); } return false; } @@ -665,95 +716,43 @@ bool CSwordModuleInfo::has(const CSwordModuleInfo::Feature feature) const { bool CSwordModuleInfo::has(const CSwordModuleInfo::FilterTypes option) const { /// \todo This is a BAD workaround to see if the filter is GBF, OSIS or ThML! const QString name = m_backend.configOptionName(option); - return m_module->getConfig().has("GlobalOptionFilter", - QString("OSIS").append(name).toUtf8().constData()) - || m_module->getConfig().has("GlobalOptionFilter", - QString("GBF").append(name).toUtf8().constData()) - || m_module->getConfig().has("GlobalOptionFilter", - QString("ThML").append(name).toUtf8().constData()) - || m_module->getConfig().has("GlobalOptionFilter", - QString("UTF8").append(name).toUtf8().constData()) - || m_module->getConfig().has("GlobalOptionFilter", - name.toUtf8().constData()); + return m_module.getConfig().has("GlobalOptionFilter", + QString("OSIS").append(name).toUtf8().constData()) + || m_module.getConfig().has("GlobalOptionFilter", + QString("GBF").append(name).toUtf8().constData()) + || m_module.getConfig().has("GlobalOptionFilter", + QString("ThML").append(name).toUtf8().constData()) + || m_module.getConfig().has("GlobalOptionFilter", + QString("UTF8").append(name).toUtf8().constData()) + || m_module.getConfig().has("GlobalOptionFilter", + name.toUtf8().constData()); } -CSwordModuleInfo::TextDirection CSwordModuleInfo::textDirection() const { - return (config(TextDir) == "RtoL") - ? CSwordModuleInfo::RightToLeft - : CSwordModuleInfo::LeftToRight; -} +CSwordModuleInfo::TextDirection CSwordModuleInfo::textDirection() const +{ return (config(TextDir) == "RtoL") ? RightToLeft : LeftToRight; } + +char const * CSwordModuleInfo::textDirectionAsHtml() const +{ return textDirection() == RightToLeft ? "rtl" : "ltr"; } void CSwordModuleInfo::write(CSwordKey * key, const QString & newText) { - m_module->setKey(key->key().toUtf8().constData()); + m_module.setKey(key->key().toUtf8().constData()); /* Don't store a pointer to the const char* value somewhere because QCString doesn't keep the value of it. */ - m_module->setEntry(isUnicode() - ? newText.toUtf8().constData() - : newText.toLocal8Bit().constData()); -} - -bool CSwordModuleInfo::deleteEntry(CSwordKey * const key) { - m_module->setKey(isUnicode() - ? key->key().toUtf8().constData() - : key->key().toLocal8Bit().constData()); - - if (m_module) { - m_module->deleteEntry(); - return true; - } - return false; -} - -void CSwordModuleInfo::initCachedCategory() { - /// \todo Maybe we can use raw string comparsion instead of QString? - const QString cat(m_module->getConfigEntry("Category")); - - /// \warning cat has to be checked before m_type !!! - if (cat == "Cults / Unorthodox / Questionable Material") { - m_cachedCategory = Cult; - } else if (cat == "Daily Devotional" - || m_module->getConfig().has("Feature","DailyDevotion")) - { - m_cachedCategory = DailyDevotional; - } else if (cat == "Glossaries" - || m_module->getConfig().has("Feature", "Glossary")) - { - m_cachedCategory = Glossary; - } else if (cat == "Images" || cat == "Maps") { - m_cachedCategory = Images; - } else { - switch (m_type) { - case Bible: m_cachedCategory = Bibles; break; - case Commentary: m_cachedCategory = Commentaries; break; - case Lexicon: m_cachedCategory = Lexicons; break; - case GenericBook: m_cachedCategory = Books; break; - case Unknown: // Fall thru - default: m_cachedCategory = UnknownCategory; break; - } - } -} - -void CSwordModuleInfo::initCachedLanguage() { - const CLanguageMgr & lm = *CLanguageMgr::instance(); - if (m_cachedCategory == Glossary) { - /* - Special handling for glossaries, we use the "from language" as - language for the module. - */ - m_cachedLanguage = lm.languageForAbbrev(config(GlossaryFrom)); - } else { - m_cachedLanguage = lm.languageForAbbrev(m_module->getLanguage()); - } + m_module.setEntry(isUnicode() + ? newText.toUtf8().constData() + : newText.toLocal8Bit().constData()); } -Rendering::CEntryDisplay * CSwordModuleInfo::getDisplay() const { - return dynamic_cast<Rendering::CEntryDisplay *>(m_module->getDisplay()); +void CSwordModuleInfo::deleteEntry(CSwordKey * const key) { + BT_ASSERT(key); + m_module.setKey(isUnicode() + ? key->key().toUtf8().constData() + : key->key().toLocal8Bit().constData()); + m_module.deleteEntry(); } QString CSwordModuleInfo::aboutText() const { - using util::htmlEscape; - static const QString row("<tr><td><b>%1</b></td><td>%2</td></tr>"); QString text; @@ -762,35 +761,33 @@ QString CSwordModuleInfo::aboutText() const { text += row .arg(tr("Version")) .arg(m_cachedHasVersion - ? htmlEscape(config(CSwordModuleInfo::ModuleVersion)) + ? config(CSwordModuleInfo::ModuleVersion).toHtmlEscaped() : tr("unknown")); { - const QString sourceType(m_module->getConfigEntry("SourceType")); + const QString sourceType(m_module.getConfigEntry("SourceType")); text += row .arg(tr("Markup")) .arg(!sourceType.isEmpty() - ? htmlEscape(sourceType) + ? sourceType.toHtmlEscaped() : tr("unknown")); } text += row .arg(tr("Location")) - .arg(htmlEscape(config(CSwordModuleInfo::AbsoluteDataPath))); + .arg(config(CSwordModuleInfo::AbsoluteDataPath).toHtmlEscaped()); text += row .arg(tr("Language")) - .arg(htmlEscape(m_cachedLanguage->translatedName())); + .arg(m_cachedLanguage->translatedName().toHtmlEscaped()); - if (m_module->getConfigEntry("Category")) - text += row - .arg(tr("Category")) - .arg(htmlEscape(m_module->getConfigEntry("Category"))); + if (char const * const e = m_module.getConfigEntry("Category")) + text += row.arg(tr("Category")) + .arg(QString{e}.toHtmlEscaped()); - if (m_module->getConfigEntry("LCSH")) - text += row - .arg(tr("LCSH")) - .arg(htmlEscape(m_module->getConfigEntry("LCSH"))); + if (char const * const e = m_module.getConfigEntry("LCSH")) + text += row.arg(tr("LCSH")) + .arg(QString{e}.toHtmlEscaped()); text += row .arg(tr("Writable")) @@ -799,7 +796,7 @@ QString CSwordModuleInfo::aboutText() const { if (isEncrypted()) text += row .arg(tr("Unlock key")) - .arg(htmlEscape(config(CSwordModuleInfo::CipherKey))); + .arg(config(CSwordModuleInfo::CipherKey).toHtmlEscaped()); QString options; @@ -812,7 +809,7 @@ QString CSwordModuleInfo::aboutText() const { if (has(static_cast < CSwordModuleInfo::FilterTypes > (opts))) { if (!options.isEmpty()) options += QString::fromLatin1(", "); - typedef CSwordModuleInfo::FilterTypes FT; + using FT = CSwordModuleInfo::FilterTypes; options += CSwordBackend::translatedOptionName(static_cast<FT>(opts)); } } @@ -820,7 +817,7 @@ QString CSwordModuleInfo::aboutText() const { if (!options.isEmpty()) text += row .arg(tr("Features")) - .arg(htmlEscape(options)); + .arg(options.toHtmlEscaped()); text += "</table><hr>"; @@ -834,25 +831,7 @@ QString CSwordModuleInfo::aboutText() const { .arg(tr("About")) .arg(config(AboutInformation)); // May contain HTML, don't escape - typedef QList<CSwordModuleInfo::ConfigEntry> ListConfigEntry; - - ListConfigEntry entries; - - entries.append(DistributionLicense); - entries.append(DistributionSource); - entries.append(DistributionNotes); - entries.append(TextSource); - entries.append(CopyrightNotes); - entries.append(CopyrightHolder); - entries.append(CopyrightDate); - entries.append(CopyrightContactName); - entries.append(CopyrightContactAddress); - entries.append(CopyrightContactEmail); - - typedef QMap<CSwordModuleInfo::ConfigEntry, QString> MapConfigEntry; - - MapConfigEntry entryMap; - + QMap<CSwordModuleInfo::ConfigEntry, QString> entryMap; entryMap[DistributionLicense] = tr("Distribution license"); entryMap[DistributionSource] = tr("Distribution source"); entryMap[DistributionNotes] = tr("Distribution notes"); @@ -866,46 +845,53 @@ QString CSwordModuleInfo::aboutText() const { text += ("<hr><table>"); - for (ListConfigEntry::iterator it(entries.begin()); it != entries.end(); ++it) + static CSwordModuleInfo::ConfigEntry const entries[] = { + DistributionLicense, + DistributionSource, + DistributionNotes, + TextSource, + CopyrightNotes, + CopyrightHolder, + CopyrightDate, + CopyrightContactName, + CopyrightContactAddress, + CopyrightContactEmail + }; + for (CSwordModuleInfo::ConfigEntry const * it = &entries[0u]; + it != &entries[sizeof(entries) / sizeof(entries[0u])]; + ++it) if (!config(*it).isEmpty()) text += row - .arg(htmlEscape(entryMap[*it])) - .arg(htmlEscape(config(*it))); + .arg(entryMap[*it].toHtmlEscaped()) + .arg(config(*it).toHtmlEscaped()); text += "</table></font>"; return text; } -QIcon CSwordModuleInfo::moduleIcon(const CSwordModuleInfo & module) { - const QString & filename = moduleIconFilename(module); - if (filename.isEmpty()) - return QIcon(); - return util::getIcon(filename); -} - -const QString & CSwordModuleInfo::moduleIconFilename(const CSwordModuleInfo & module) { - const CSwordModuleInfo::Category cat(module.m_cachedCategory); +QIcon const & CSwordModuleInfo::moduleIcon(const CSwordModuleInfo & module) { + CSwordModuleInfo::Category const cat(module.m_cachedCategory); switch (cat) { case CSwordModuleInfo::Bibles: return module.isLocked() - ? CResMgr::modules::bible::icon_locked - : CResMgr::modules::bible::icon_unlocked; + ? CResMgr::modules::bible::icon_locked() + : CResMgr::modules::bible::icon_unlocked(); case CSwordModuleInfo::Commentaries: return module.isLocked() - ? CResMgr::modules::commentary::icon_locked - : CResMgr::modules::commentary::icon_unlocked; + ? CResMgr::modules::commentary::icon_locked() + : CResMgr::modules::commentary::icon_unlocked(); case CSwordModuleInfo::Lexicons: return module.isLocked() - ? CResMgr::modules::lexicon::icon_locked - : CResMgr::modules::lexicon::icon_unlocked; + ? CResMgr::modules::lexicon::icon_locked() + : CResMgr::modules::lexicon::icon_unlocked(); case CSwordModuleInfo::Books: return module.isLocked() - ? CResMgr::modules::book::icon_locked - : CResMgr::modules::book::icon_unlocked; + ? CResMgr::modules::book::icon_locked() + : CResMgr::modules::book::icon_unlocked(); case CSwordModuleInfo::Cult: case CSwordModuleInfo::Images: @@ -913,40 +899,31 @@ const QString & CSwordModuleInfo::moduleIconFilename(const CSwordModuleInfo & mo case CSwordModuleInfo::Glossary: case CSwordModuleInfo::UnknownCategory: default: - return categoryIconFilename(cat); + return categoryIcon(cat); } } -QIcon CSwordModuleInfo::categoryIcon(const CSwordModuleInfo::Category & category) { - const QString filename(categoryIconFilename(category)); - if (filename.isEmpty()) - return QIcon(); - return util::getIcon(filename); -} - -const QString & CSwordModuleInfo::categoryIconFilename(const CSwordModuleInfo::Category & category) { - static const QString noFilename; - +QIcon const & CSwordModuleInfo::categoryIcon(CSwordModuleInfo::Category category) { switch (category) { case CSwordModuleInfo::Bibles: - return CResMgr::categories::bibles::icon; + return CResMgr::categories::bibles::icon(); case CSwordModuleInfo::Commentaries: - return CResMgr::categories::commentaries::icon; + return CResMgr::categories::commentaries::icon(); case CSwordModuleInfo::Books: - return CResMgr::categories::books::icon; + return CResMgr::categories::books::icon(); case CSwordModuleInfo::Cult: - return CResMgr::categories::cults::icon; + return CResMgr::categories::cults::icon(); case CSwordModuleInfo::Images: - return CResMgr::categories::images::icon; + return CResMgr::categories::images::icon(); case CSwordModuleInfo::DailyDevotional: - return CResMgr::categories::dailydevotional::icon; + return CResMgr::categories::dailydevotional::icon(); case CSwordModuleInfo::Lexicons: - return CResMgr::categories::lexicons::icon; + return CResMgr::categories::lexicons::icon(); case CSwordModuleInfo::Glossary: - return CResMgr::categories::glossary::icon; + return CResMgr::categories::glossary::icon(); case CSwordModuleInfo::UnknownCategory: default: - return noFilename; + return BtIcons::instance().icon_null; } } @@ -973,10 +950,33 @@ QString CSwordModuleInfo::categoryName(const CSwordModuleInfo::Category & catego } } +QString CSwordModuleInfo::englishCategoryName(const CSwordModuleInfo::Category & category) { + switch (category) { + case CSwordModuleInfo::Bibles: + return "Bibles"; + case CSwordModuleInfo::Commentaries: + return "Commentaries"; + case CSwordModuleInfo::Books: + return "Books"; + case CSwordModuleInfo::Cult: + return "Cults/Unorthodox"; + case CSwordModuleInfo::Images: + return "Maps and Images"; + case CSwordModuleInfo::DailyDevotional: + return "Daily Devotionals"; + case CSwordModuleInfo::Lexicons: + return "Lexicons and Dictionaries"; + case CSwordModuleInfo::Glossary: + return "Glossaries"; + default: + return "Unknown"; + } +} + QString CSwordModuleInfo::getSimpleConfigEntry(const QString & name) const { QString ret = isUnicode() - ? QString::fromUtf8(m_module->getConfigEntry(name.toUtf8().constData())) - : QString::fromLatin1(m_module->getConfigEntry(name.toUtf8().constData())); + ? QString::fromUtf8(m_module.getConfigEntry(name.toUtf8().constData())) + : QString::fromLatin1(m_module.getConfigEntry(name.toUtf8().constData())); return ret.isEmpty() ? QString::null : ret; } @@ -986,12 +986,12 @@ QString CSwordModuleInfo::getFormattedConfigEntry(const QString & name) const { const QStringList localeNames(QLocale(CSwordBackend::instance()->booknameLanguage()).uiLanguages()); for (int i = localeNames.size() - 1; i >= -1; --i) { sword::SWBuf RTF_Buffer = - m_module->getConfigEntry( + m_module.getConfigEntry( QString(i >= 0 ? name + "_" + localeNames[i] : name) .toUtf8().constData()); if (RTF_Buffer.length() > 0) { sword::RTFHTML RTF_Filter; - RTF_Filter.processText(RTF_Buffer, 0, 0); + RTF_Filter.processText(RTF_Buffer, nullptr, nullptr); return isUnicode() ? QString::fromUtf8(RTF_Buffer.c_str()) : QString::fromLatin1(RTF_Buffer.c_str()); @@ -1006,7 +1006,7 @@ bool CSwordModuleInfo::setHidden(bool hide) { m_hidden = hide; QStringList hiddenModules(btConfig().value<QStringList>("state/hiddenModules")); - Q_ASSERT(hiddenModules.contains(m_cachedName) != hide); + BT_ASSERT(hiddenModules.contains(m_cachedName) != hide); if (hide) { hiddenModules.append(m_cachedName); } else { diff --git a/src/backend/drivers/cswordmoduleinfo.h b/src/backend/drivers/cswordmoduleinfo.h index c1b6c88..e332ddf 100644 --- a/src/backend/drivers/cswordmoduleinfo.h +++ b/src/backend/drivers/cswordmoduleinfo.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -12,8 +12,12 @@ #ifndef CSWORDMODULEINFO_H #define CSWORDMODULEINFO_H -#include "backend/managers/clanguagemgr.h" +#include <QObject> +#include "btdisplayholder.h" +#include "../managers/clanguagemgr.h" + +#include <atomic> #include <QIcon> #include <QList> #include <QMetaType> @@ -21,11 +25,11 @@ // Sword includes: #include <listkey.h> -#include <swdisp.h> #include <swmodule.h> #include <swsearchable.h> #include <swversion.h> + #ifdef CLUCENE2 // CLucene no longer lists the following functions in its headers extern size_t lucene_utf8towcs(wchar_t *, const char *, size_t maxslen); @@ -35,10 +39,6 @@ extern size_t lucene_wcstoutf8 (char *, const wchar_t *, size_t maxslen); class CSwordBackend; class CSwordKey; -namespace Rendering { - -class CEntryDisplay; -} /** * Base class for Sword modules. @@ -49,11 +49,14 @@ class CEntryDisplay; * @version $Id: cswordmoduleinfo.h,v 1.83 2007/02/04 23:12:32 joachim Exp $ */ -class CSwordModuleInfo: public QObject { +class CSwordModuleInfo + : public QObject + , public BtDisplayHolder<CSwordModuleInfo> +{ Q_OBJECT -public: /* Methods: */ +public: /* Types: */ /** * These are the options which could be supported by modules and by this backend. @@ -155,6 +158,13 @@ public: /* Methods: */ }; Q_DECLARE_FLAGS(Categories, Category) +public: /* Methods: */ + + CSwordModuleInfo(CSwordModuleInfo &&) = delete; + CSwordModuleInfo(CSwordModuleInfo const &) = delete; + CSwordModuleInfo & operator=(CSwordModuleInfo &&) = delete; + CSwordModuleInfo & operator=(CSwordModuleInfo const &) = delete; + /** * Returns the base directory for search indices */ @@ -179,7 +189,7 @@ public: /* Methods: */ /** * Returns the module object so all objects can access the original Sword module. */ - inline sword::SWModule * module() const { + inline sword::SWModule & module() const { return m_module; } @@ -191,15 +201,6 @@ wrong, or if the config file was write protected return false. bool unlock(const QString & unlockKey); /** - * Returns the display object for this module. Normally every module should have a Display object. - * Please don't use module()->Display() because this function does return the Sword display and does - * render the text, too. - * This function performs some casts to return the correct display. If it returns 0 there's no valid - * display object. - */ - Rendering::CEntryDisplay * getDisplay() const; - - /** * This function does return true if the data files of the module are encrypted by the module author * (the on who made the module) no matter if it's locked or not. * @return True if this module is encryped @@ -248,23 +249,24 @@ wrong, or if the config file was write protected return false. /** Builds a search index for this module - \returns Whether indexing this module was successful. + \throws when unsuccessful */ - bool buildIndex(); + void buildIndex(); /** \returns index size */ - unsigned long indexSize() const; + size_t indexSize() const; /** This function uses CLucene to perform and index based search. It also overwrites the variable containing the last search result. \returns the number of results found + \throws on error */ - int searchIndexed(const QString & searchedText, - const sword::ListKey & scope, - sword::ListKey & results) const; + size_t searchIndexed(const QString & searchedText, + const sword::ListKey & scope, + sword::ListKey & results) const; /** \returns the type of the module. @@ -303,11 +305,12 @@ wrong, or if the config file was write protected return false. bool has(const CSwordModuleInfo::FilterTypes ) const; - /** - \returns the text direction of the module's text. - */ + /** \returns the text direction of the module's text. */ CSwordModuleInfo::TextDirection textDirection() const; + /** \returns the text direction of the module's text as an HTML value. */ + char const * textDirectionAsHtml() const; + /** Writes the new text at the given position into the module. This does only work for writabe modules. @@ -317,7 +320,7 @@ wrong, or if the config file was write protected return false. /** Deletes the current entry and removes it from the module. */ - bool deleteEntry(CSwordKey * const key); + void deleteEntry(CSwordKey * const key); /** \returns the language of the module. @@ -364,7 +367,7 @@ wrong, or if the config file was write protected return false. * Protected because it should not be used outside of the CSword*ModuleInfo classes. */ inline bool isUnicode() const { - return m_module->isUnicode(); + return m_module.isUnicode(); } /** @@ -378,25 +381,13 @@ wrong, or if the config file was write protected return false. Returns an icon for the given module. \param[in] module The module whose icon to return. */ - static QIcon moduleIcon(const CSwordModuleInfo & module); - - /** - Returns the icon filename for the given module. - \param[in] module The module whose icon filename to return. - */ - static const QString & moduleIconFilename(const CSwordModuleInfo & module); + static QIcon const & moduleIcon(CSwordModuleInfo const & module); /** Returns an icon for the category of given module. \param[in] module The module whose category icon to return. */ - static QIcon categoryIcon(const CSwordModuleInfo::Category & category); - - /** - Returns the icon filename for the category of given module. - \param[in] module The module whose category icon filename to return. - */ - static const QString & categoryIconFilename(const CSwordModuleInfo::Category & category); + static QIcon const & categoryIcon(CSwordModuleInfo::Category category); /** Returns a translated name for the given category. @@ -404,20 +395,24 @@ wrong, or if the config file was write protected return false. */ static QString categoryName(const CSwordModuleInfo::Category & category); + /** + Returns a english name for the given category. + \param[in] module The category whose english name to return. + */ + static QString englishCategoryName(const CSwordModuleInfo::Category & category); + public slots: - inline void cancelIndexing() { - m_cancelIndexing = true; - } + inline void cancelIndexing(std::memory_order const memoryOrder = + std::memory_order_relaxed) noexcept + { m_cancelIndexing.store(true, memoryOrder); } protected: /* Methods: */ - CSwordModuleInfo(sword::SWModule * module, + CSwordModuleInfo(sword::SWModule & module, CSwordBackend & backend, ModuleType type); - CSwordModuleInfo(const CSwordModuleInfo & copy); - inline CSwordBackend & backend() const { return m_backend; } @@ -425,21 +420,6 @@ protected: /* Methods: */ QString getSimpleConfigEntry(const QString & name) const; QString getFormattedConfigEntry(const QString & name) const; -private: /* Methods: */ - - /** - Initializes CSwordModuleInfo::m_cachedCategory. - \pre m_module must be set - */ - void initCachedCategory(); - - /** - Initializes CSwordModuleInfo::m_cachedLanguage. - \pre CSwordModuleInfo::m_module must be set - \pre CSwordModuleInfo::m_cachedLanguage must be set - */ - void initCachedLanguage(); - signals: void hasIndexChanged(bool hasIndex); @@ -450,17 +430,17 @@ signals: private: /* Fields: */ - sword::SWModule * const m_module; + sword::SWModule & m_module; CSwordBackend & m_backend; - ModuleType m_type; + ModuleType const m_type; bool m_hidden; - bool m_cancelIndexing; + std::atomic<bool> m_cancelIndexing; // Cached data: - const QString m_cachedName; - CSwordModuleInfo::Category m_cachedCategory; - const CLanguageMgr::Language * m_cachedLanguage; - bool m_cachedHasVersion; + QString const m_cachedName; + CSwordModuleInfo::Category const m_cachedCategory; + const CLanguageMgr::Language * const m_cachedLanguage; + bool const m_cachedHasVersion; }; diff --git a/src/backend/filters/btosismorphsegmentation.cpp b/src/backend/filters/btosismorphsegmentation.cpp deleted file mode 100644 index 1675476..0000000 --- a/src/backend/filters/btosismorphsegmentation.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/********* -* -* 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 "backend/filters/btosismorphsegmentation.h" - -// Sword includes: -#include <utilxml.h> - - -const char Filters::BtOSISMorphSegmentation::oName[] = "Morph segmentation"; -const char Filters::BtOSISMorphSegmentation::oTip[] = "Toggles morph " - "segmentation On and Off " - "if they exist"; - -const sword::SWBuf Filters::BtOSISMorphSegmentation::choices[3] = { "Off", - "On", - "" }; - -const sword::StringList Filters::BtOSISMorphSegmentation::oValues(&choices[0], - &choices[2]); - -Filters::BtOSISMorphSegmentation::BtOSISMorphSegmentation() - : sword::SWOptionFilter(oName, oTip, &oValues) -{ - setOptionValue("Off"); -} - -char Filters::BtOSISMorphSegmentation::processText(sword::SWBuf & text, - const sword::SWKey * key, - const sword::SWModule * mod) -{ - (void) key; - (void) mod; - - sword::SWBuf token; - bool intoken = false; - bool hide = false; - - sword::SWBuf orig(text); - const char * from = orig.c_str(); - - sword::XMLTag tag; - - for (text = ""; *from; ++from) { - if (*from == '<') { - intoken = true; - token = ""; - continue; - } - - if (*from == '>') { // process tokens - intoken = false; - - if (!strncmp(token.c_str(), "seg ", 4) - || !strncmp(token.c_str(), "/seg", 4)) - { - tag = token; - - if (!tag.isEndTag() - && tag.getAttribute("type") - && !strcmp("morph", tag.getAttribute("type"))) - { // <seg type="morph"> start tag - hide = (option == 0); // only hide if option is Off - } - - if (hide) { // hides start and end tags as long as hide is set - if (tag.isEndTag()) //</seg> - hide = false; - continue; // leave out the current token - } - } // end of seg tag handling - - text.append('<'); - text.append(token); - text.append('>'); - // hide = false; // not right, because there may be child tags in seg. Only /seg may disable the seg hiding. - continue; - } // end of intoken part - - if (intoken) { - token.append(*from); // copy token - } else { - text.append(*from); // copy text which is not inside of a tag - } - } - - return 0; -} - diff --git a/src/backend/filters/btosismorphsegmentation.h b/src/backend/filters/btosismorphsegmentation.h deleted file mode 100644 index 66d4724..0000000 --- a/src/backend/filters/btosismorphsegmentation.h +++ /dev/null @@ -1,47 +0,0 @@ -/********* -* -* 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 BTOSISMORPHSEGMENTATION_H -#define BTOSISMORPHSEGMENTATION_H - -// Sword includes: -#include <swbuf.h> -#include <swoptfilter.h> - - -namespace Filters { - -/** - \brief This Filter shows/hides headings in a OSIS text. - \author Martin Gruner -*/ -class BtOSISMorphSegmentation: public sword::SWOptionFilter { - -public: /* Methods: */ - - BtOSISMorphSegmentation(); - - virtual char processText(sword::SWBuf & text, - const sword::SWKey * key = 0, - const sword::SWModule * module = 0); - -private: /* Fields: */ - - static const char oName[]; - static const char oTip[]; - static const sword::SWBuf choices[3]; - static const sword::StringList oValues; - -}; - -} /* namespace Filters { */ - -#endif /* BTOSISMORPHSEGMENTATION_H */ diff --git a/src/backend/filters/gbftohtml.cpp b/src/backend/filters/gbftohtml.cpp index 8f2fcc5..fc9dd35 100644 --- a/src/backend/filters/gbftohtml.cpp +++ b/src/backend/filters/gbftohtml.cpp @@ -2,17 +2,19 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ -#include "backend/filters/gbftohtml.h" +#include "gbftohtml.h" +#include <cstdlib> #include <QRegExp> #include <QString> -#include "backend/drivers/cswordmoduleinfo.h" -#include "backend/managers/cswordbackend.h" +#include "../../util/btassert.h" +#include "../drivers/cswordmoduleinfo.h" +#include "../managers/cswordbackend.h" // Sword includes: #include <utilxml.h> @@ -219,68 +221,84 @@ char Filters::GbfToHtml::processText(sword::SWBuf& buf, const sword::SWKey * key result += e; } - if (list.count()) { - buf = (const char*)result.toUtf8().constData(); - } + if (list.count()) + buf = result.toUtf8().constData(); return 1; } +namespace { +int hexDigitValue(char const hex) { + switch (hex) { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + return hex - '0'; + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + return hex - 'a' + 10; + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + return hex - 'A' + 10; + default: + BT_ASSERT(false && "Invalid hex code in GBF"); + abort(); + } +} + +char hexToChar(char const * const hex) { + int const first = hexDigitValue(hex[0u]); + return (first * 16u) + hexDigitValue(hex[1u]); +} +} + bool Filters::GbfToHtml::handleToken(sword::SWBuf &buf, const char *token, sword::BasicFilterUserData *userData) { - if (!substituteToken(buf, token)) { //more than a simple replace - const unsigned int tokenLength = strlen(token); - - UserData* myUserData = dynamic_cast<UserData*>(userData); - sword::SWModule* myModule = const_cast<sword::SWModule*>(myUserData->module); //hack to be able to call stuff like Lang() - - if ( !strncmp(token, "WG", 2) - || !strncmp(token, "WH", 2) - || !strncmp(token, "WT", 2) ) { - buf.append('<'); - buf.append(token); - buf.append('>'); - } - else if (!strncmp(token, "RB", 2)) { + if (!substituteToken(buf, token)) { // More than a simple replace + size_t const tokenLength = strlen(token); + + BT_ASSERT(dynamic_cast<UserData *>(userData)); + UserData * const myUserData = static_cast<UserData *>(userData); + // Hack to be able to call stuff like Lang(): + sword::SWModule const * const myModule = + const_cast<sword::SWModule *>(myUserData->module); + + /* We use several append calls because appendFormatted slows down + filtering, which should be fast. */ + + if (!strncmp(token, "WG", 2u) + || !strncmp(token, "WH", 2u) + || !strncmp(token, "WT", 2u)) + { + buf.append('<').append(token).append('>'); + } else if (!strncmp(token, "RB", 2u)) { myUserData->hasFootnotePreTag = true; buf.append("<span class=\"footnotepre\">"); - } - else if (!strncmp(token, "RF", 2)) { - //we use several append calls because appendFormatted slows down filtering, which should be fast - + } else if (!strncmp(token, "RF", 2u)) { if (myUserData->hasFootnotePreTag) { // qWarning("inserted footnotepre end"); buf.append("</span>"); myUserData->hasFootnotePreTag = false; } - buf.append(" <span class=\"footnote\" note=\""); - buf.append(myModule->getName()); - buf.append('/'); - buf.append(myUserData->key->getShortText()); - buf.append('/'); - buf.append( QString::number(myUserData->swordFootnote++).toUtf8().constData() ); - buf.append("\">*</span> "); - + buf.append(" <span class=\"footnote\" note=\"") + .append(myModule->getName()) + .append('/') + .append(myUserData->key->getShortText()) + .append('/') + .append(QString::number(myUserData->swordFootnote).toUtf8().constData()) + .append("\">*</span> "); + myUserData->swordFootnote++; userData->suspendTextPassThru = true; - } - else if (!strncmp(token, "Rf", 2)) { //end of footnote + } else if (!strncmp(token, "Rf", 2u)) { // End of footnote userData->suspendTextPassThru = false; - } - else if (!strncmp(token, "FN", 2)) { //the end </font> tag is inserted in addTokenSubsitute + } else if (!strncmp(token, "FN", 2u)) { + // The end </font> tag is inserted in addTokenSubsitute buf.append("<font face=\""); - - for (unsigned long i = 2; i < tokenLength; i++) { - if (token[i] != '\"') { - buf.append( token[i] ); - } - } - + for (size_t i = 2u; i < tokenLength; i++) + if (token[i] != '\"') + buf.append(token[i]); buf.append("\">"); - } - else if (!strncmp(token, "CA", 2)) { // ASCII value - buf.append( (char)atoi(&token[2]) ); - } - else { + } else if (!strncmp(token, "CA", 2u)) { // ASCII value <CA##> in hex + BT_ASSERT(tokenLength == 4u); + buf.append(static_cast<char>(hexToChar(token + 2u))); + } else { return GBFHTML::handleToken(buf, token, userData); } } diff --git a/src/backend/filters/gbftohtml.h b/src/backend/filters/gbftohtml.h index bfe8501..9b8da9e 100644 --- a/src/backend/filters/gbftohtml.h +++ b/src/backend/filters/gbftohtml.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -40,19 +40,19 @@ class GbfToHtml: public sword::GBFHTML { GbfToHtml(); /** Reimplemented from sword::OSISHTMLHREF. */ - virtual bool handleToken(sword::SWBuf &buf, - const char *token, - sword::BasicFilterUserData *userData); + bool handleToken(sword::SWBuf &buf, + const char *token, + sword::BasicFilterUserData *userData) override; /** Reimplemented from sword::SWFilter. */ - virtual char processText(sword::SWBuf &buf, - const sword::SWKey *key, - const sword::SWModule *module = 0); + char processText(sword::SWBuf &buf, + const sword::SWKey *key, + const sword::SWModule *module = nullptr) override; protected: /* Methods: */ /** Reimplemented from sword::OSISHTMLHREF. */ - virtual inline sword::BasicFilterUserData *createUserData( - const sword::SWModule *module, const sword::SWKey *key) + inline sword::BasicFilterUserData *createUserData( + const sword::SWModule *module, const sword::SWKey *key) override { return new UserData(module, key); } diff --git a/src/backend/filters/osistohtml.cpp b/src/backend/filters/osistohtml.cpp index 3a8d65f..bca5670 100644 --- a/src/backend/filters/osistohtml.cpp +++ b/src/backend/filters/osistohtml.cpp @@ -2,19 +2,20 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ -#include "backend/filters/osistohtml.h" +#include "osistohtml.h" #include <QString> -#include "backend/config/btconfig.h" -#include "backend/drivers/cswordmoduleinfo.h" -#include "backend/managers/clanguagemgr.h" -#include "backend/managers/referencemanager.h" -#include "backend/managers/cswordbackend.h" +#include "../../util/btassert.h" +#include "../config/btconfig.h" +#include "../drivers/cswordmoduleinfo.h" +#include "../managers/clanguagemgr.h" +#include "../managers/cswordbackend.h" +#include "../managers/referencemanager.h" // Sword includes: #include <swbuf.h> @@ -272,7 +273,7 @@ bool Filters::OsisToHtml::handleToken(sword::SWBuf &buf, const char *token, swor } } else { //if (tag.isEndTag()) { - Q_ASSERT(myUserData->noteType != UserData::Unknown); + BT_ASSERT(myUserData->noteType != UserData::Unknown); if (myUserData->noteType == UserData::CrossReference) { buf.append("</span> "); @@ -540,7 +541,7 @@ bool Filters::OsisToHtml::handleToken(sword::SWBuf &buf, const char *token, swor void Filters::OsisToHtml::renderReference(const char *osisRef, sword::SWBuf &buf, sword::SWModule *myModule, UserData *myUserData) { QString ref( osisRef ); QString hrefRef( ref ); - //Q_ASSERT(!ref.isEmpty()); checked later + //BT_ASSERT(!ref.isEmpty()); checked later if (!ref.isEmpty()) { //find out the mod, using the current module makes sense if it's a bible or commentary because the refs link into a bible by default. @@ -548,14 +549,14 @@ void Filters::OsisToHtml::renderReference(const char *osisRef, sword::SWBuf &buf // modulename is given, so we'll use that one CSwordModuleInfo* mod = CSwordBackend::instance()->findSwordModuleByPointer(myModule); - //Q_ASSERT(mod); checked later + //BT_ASSERT(mod); checked later if (!mod || (mod->type() != CSwordModuleInfo::Bible && mod->type() != CSwordModuleInfo::Commentary)) { mod = btConfig().getDefaultSwordModuleByType("standardBible"); } - // Q_ASSERT(mod); There's no necessarily a module or standard Bible + // BT_ASSERT(mod); There's no necessarily a module or standard Bible //if the osisRef like "GerLut:key" contains a module, use that int pos = ref.indexOf(":"); @@ -570,23 +571,22 @@ void Filters::OsisToHtml::renderReference(const char *osisRef, sword::SWBuf &buf } if (mod) { - ReferenceManager::ParseOptions options; - options.refBase = QString::fromUtf8(myUserData->key->getText()); - options.refDestinationModule = QString(mod->name()); - options.sourceLanguage = QString(myModule->getLanguage()); - options.destinationLanguage = QString("en"); - - buf.append("<a href=\""); - buf.append( //create the hyperlink with key and mod - ReferenceManager::encodeHyperlink( + ReferenceManager::ParseOptions const options( mod->name(), - ReferenceManager::parseVerseReference(hrefRef, options), - ReferenceManager::typeFromModule(mod->type()) - ).toUtf8().constData() - ); - buf.append("\" crossrefs=\""); - buf.append((const char*)ReferenceManager::parseVerseReference(ref, options).toUtf8().constData()); //ref must contain the osisRef module marker if there was any - buf.append("\">"); + QString::fromUtf8(myUserData->key->getText()), + myModule->getLanguage()); + + buf.append("<a href=\"") + .append( //create the hyperlink with key and mod + ReferenceManager::encodeHyperlink( + mod->name(), + ReferenceManager::parseVerseReference(hrefRef, options), + ReferenceManager::typeFromModule(mod->type()) + ).toUtf8().constData() + ) + .append("\" crossrefs=\"") + .append(ReferenceManager::parseVerseReference(ref, options).toUtf8().constData()) //ref must contain the osisRef module marker if there was any + .append("\">"); } // should we add something if there were no referenced module available? } diff --git a/src/backend/filters/osistohtml.h b/src/backend/filters/osistohtml.h index 1c59ae1..c1ad9ba 100644 --- a/src/backend/filters/osistohtml.h +++ b/src/backend/filters/osistohtml.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -54,15 +54,15 @@ class OsisToHtml: public sword::OSISHTMLHREF { OsisToHtml(); /** Reimplemented from sword::OSISHTMLHREF. */ - virtual bool handleToken(sword::SWBuf &buf, - const char *token, - sword::BasicFilterUserData *userData); + bool handleToken(sword::SWBuf &buf, + const char *token, + sword::BasicFilterUserData *userData) override; protected: /* Methods: */ /** Reimplemented from sword::OSISHTMLHREF. */ - virtual inline sword::BasicFilterUserData *createUserData( + inline sword::BasicFilterUserData *createUserData( const sword::SWModule *module, - const sword::SWKey *key) + const sword::SWKey *key) override { return new UserData(module, key); } diff --git a/src/backend/filters/plaintohtml.cpp b/src/backend/filters/plaintohtml.cpp index edb6208..a1ead4d 100644 --- a/src/backend/filters/plaintohtml.cpp +++ b/src/backend/filters/plaintohtml.cpp @@ -2,12 +2,12 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ -#include "backend/filters/plaintohtml.h" +#include "plaintohtml.h" #include <QDebug> diff --git a/src/backend/filters/plaintohtml.h b/src/backend/filters/plaintohtml.h index e8ae570..0f077b6 100644 --- a/src/backend/filters/plaintohtml.h +++ b/src/backend/filters/plaintohtml.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -31,9 +31,9 @@ class PlainToHtml: public sword::SWFilter { protected: /* Methods: */ /** Reimplemented from sword::SWFilter. */ - virtual char processText(sword::SWBuf &buf, - const sword::SWKey *key, - const sword::SWModule *module = 0); + char processText(sword::SWBuf &buf, + const sword::SWKey *key, + const sword::SWModule *module = nullptr) override; }; diff --git a/src/backend/filters/teitohtml.cpp b/src/backend/filters/teitohtml.cpp index 6367e22..91902d8 100644 --- a/src/backend/filters/teitohtml.cpp +++ b/src/backend/filters/teitohtml.cpp @@ -2,19 +2,19 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ -#include "backend/filters/teitohtml.h" +#include "teitohtml.h" #include <QString> -#include "backend/config/btconfig.h" -#include "backend/drivers/cswordmoduleinfo.h" -#include "backend/managers/clanguagemgr.h" -#include "backend/managers/referencemanager.h" -#include "backend/managers/cswordbackend.h" +#include "../config/btconfig.h" +#include "../drivers/cswordmoduleinfo.h" +#include "../managers/clanguagemgr.h" +#include "../managers/cswordbackend.h" +#include "../managers/referencemanager.h" // Sword includes: #include <swbuf.h> @@ -111,7 +111,7 @@ void TeiToHtml::renderReference(const char *osisRef, sword::SWBuf &buf, CSwordModuleInfo* mod = btConfig().getDefaultSwordModuleByType( "standardBible" ); - // Q_ASSERT(mod); There's no necessarily a module or standard Bible + // BT_ASSERT(mod); There's no necessarily a module or standard Bible //if the osisRef like "GerLut:key" contains a module, use that int pos = ref.indexOf(":"); @@ -126,23 +126,23 @@ void TeiToHtml::renderReference(const char *osisRef, sword::SWBuf &buf, } if (mod) { - ReferenceManager::ParseOptions options; - options.refBase = QString::fromUtf8(myUserData->key->getText()); - options.refDestinationModule = QString(mod->name()); - options.sourceLanguage = QString(mod->module()->getLanguage()); - options.destinationLanguage = QString("en"); - - buf.append("<a href=\""); - buf.append( //create the hyperlink with key and mod - ReferenceManager::encodeHyperlink( + ReferenceManager::ParseOptions const options( mod->name(), - ReferenceManager::parseVerseReference(hrefRef, options), - ReferenceManager::typeFromModule(mod->type()) - ).toUtf8().constData() - ); - buf.append("\" crossrefs=\""); - buf.append((const char*)ReferenceManager::parseVerseReference(ref, options).toUtf8().constData()); //ref must contain the osisRef module marker if there was any - buf.append("\">"); + QString::fromUtf8(myUserData->key->getText()), + mod->module().getLanguage()); + + buf.append("<a href=\"") + .append( // create the hyperlink with key and mod + ReferenceManager::encodeHyperlink( + mod->name(), + ReferenceManager::parseVerseReference(hrefRef, options), + ReferenceManager::typeFromModule(mod->type()) + ).toUtf8().constData() + ) + .append("\" crossrefs=\"") + // ref must contain the osisRef module marker if there was any: + .append(ReferenceManager::parseVerseReference(ref, options).toUtf8().constData()) + .append("\">"); } // should we add something if there were no referenced module available? } diff --git a/src/backend/filters/teitohtml.h b/src/backend/filters/teitohtml.h index f365616..e5ba8f6 100644 --- a/src/backend/filters/teitohtml.h +++ b/src/backend/filters/teitohtml.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -25,9 +25,9 @@ class TeiToHtml: public sword::TEIHTMLHREF { public: /* Methods: */ TeiToHtml(); - /** Reimplemented from sword::OSISHTMLHREF. */ - virtual bool handleToken(sword::SWBuf &buf, const char *token, - sword::BasicFilterUserData *userData); + bool handleToken(sword::SWBuf &buf, + const char *token, + sword::BasicFilterUserData *userData) override; private: /* Methods: */ void renderReference(const char *osisRef, sword::SWBuf &buf, diff --git a/src/backend/filters/thmltohtml.cpp b/src/backend/filters/thmltohtml.cpp index 0bf6e63..5f85766 100644 --- a/src/backend/filters/thmltohtml.cpp +++ b/src/backend/filters/thmltohtml.cpp @@ -2,22 +2,23 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ -#include "backend/filters/thmltohtml.h" +#include "thmltohtml.h" -#include <QString> #include <QRegExp> -#include <QUrl> +#include <QString> #include <QTextCodec> -#include "backend/config/btconfig.h" -#include "backend/drivers/cswordmoduleinfo.h" -#include "backend/managers/clanguagemgr.h" -#include "backend/managers/referencemanager.h" -#include "backend/managers/cswordbackend.h" +#include <QUrl> +#include "../../util/btassert.h" +#include "../config/btconfig.h" +#include "../drivers/cswordmoduleinfo.h" +#include "../managers/clanguagemgr.h" +#include "../managers/cswordbackend.h" +#include "../managers/referencemanager.h" // Sword includes: #include <swmodule.h> @@ -191,9 +192,8 @@ char ThmlToHtml::processText(sword::SWBuf &buf, const sword::SWKey *key, result.append( e ); } - if (list.count()) { - buf = (const char*)result.toUtf8(); - } + if (list.count()) + buf = result.toUtf8(); return 1; } @@ -203,52 +203,51 @@ bool ThmlToHtml::handleToken(sword::SWBuf &buf, const char *token, sword::BasicFilterUserData *userData) { if (!substituteToken(buf, token) && !substituteEscapeString(buf, token)) { - sword::XMLTag tag(token); - UserData* myUserData = dynamic_cast<UserData*>(userData); - sword::SWModule* myModule = const_cast<sword::SWModule*>(myUserData->module); //hack to be able to call stuff like Lang() - - if ( tag.getName() && !sword::stricmp(tag.getName(), "foreign") ) { // a text part in another language, we have to set the right font - - if (tag.getAttribute("lang")) { - const char* abbrev = tag.getAttribute("lang"); - //const CLanguageMgr::Language* const language = CLanguageMgr::instance()->languageForAbbrev( QString::fromLatin1(abbrev) ); - - buf.append("<span class=\"foreign\" lang=\""); - buf.append(abbrev); - buf.append("\">"); - } - } - else if (tag.getName() && !sword::stricmp(tag.getName(), "sync")) { //lemmas, morph codes or strongs - - if (tag.getAttribute("type") && (!sword::stricmp(tag.getAttribute("type"), "morph") || !sword::stricmp(tag.getAttribute("type"), "Strongs") || !sword::stricmp(tag.getAttribute("type"), "lemma"))) { // Morph or Strong - buf.append('<'); - buf.append(token); - buf.append('>'); - } - } - else if (tag.getName() && !sword::stricmp(tag.getName(), "note")) { // <note> tag - - if (!tag.isEndTag() && !tag.isEmpty()) { - //appending is faster than appendFormatted - buf.append(" <span class=\"footnote\" note=\""); - buf.append(myModule->getName()); - buf.append('/'); - buf.append(myUserData->key->getShortText()); - buf.append('/'); - buf.append( QString::number(myUserData->swordFootnote++).toUtf8().constData() ); - buf.append("\">*</span> "); - - myUserData->suspendTextPassThru = true; - myUserData->inFootnoteTag = true; - } - else if (tag.isEndTag() && !tag.isEmpty()) { //end tag - //buf += ")</span>"; - myUserData->suspendTextPassThru = false; - myUserData->inFootnoteTag = false; + sword::XMLTag const tag(token); + BT_ASSERT(dynamic_cast<UserData *>(userData)); + UserData * const myUserData = static_cast<UserData *>(userData); + // Hack to be able to call stuff like Lang(): + sword::SWModule const * const myModule = + const_cast<sword::SWModule *>(myUserData->module); + char const * const tagName = tag.getName(); + if (!tagName) // unknown tag, pass through: + return sword::ThMLHTML::handleToken(buf, token, userData); + if (!sword::stricmp(tagName, "foreign")) { + // A text part in another language, we have to set the right font + + if (const char * const tagLang = tag.getAttribute("lang")) + buf.append("<span class=\"foreign\" lang=\"") + .append(tagLang) + .append("\">"); + } else if (!sword::stricmp(tagName, "sync")) { + // If Morph or Strong or Lemma: + if (const char * const tagType = tag.getAttribute("type")) + if (!sword::stricmp(tagType, "morph") + || !sword::stricmp(tagType, "Strongs") + || !sword::stricmp(tagType, "lemma")) + buf.append('<').append(token).append('>'); + } else if (!sword::stricmp(tagName, "note")) { // <note> tag + if (!tag.isEmpty()) { + if (!tag.isEndTag()) { + buf.append(" <span class=\"footnote\" note=\"") + .append(myModule->getName()) + .append('/') + .append(myUserData->key->getShortText()) + .append('/') + .append(QString::number(myUserData->swordFootnote).toUtf8().constData()) + .append("\">*</span> "); + + myUserData->swordFootnote++; + myUserData->suspendTextPassThru = true; + myUserData->inFootnoteTag = true; + } else if (tag.isEndTag()) { // end tag + // buf += ")</span>"; + myUserData->suspendTextPassThru = false; + myUserData->inFootnoteTag = false; + } } - } - else if (tag.getName() && !sword::stricmp(tag.getName(), "scripRef")) { // a scripRef - //scrip refs which are embeded in footnotes may not be displayed! + } else if (!sword::stricmp(tagName, "scripRef")) { // a scripRef + // scrip refs which are embeded in footnotes may not be displayed! if (!myUserData->inFootnoteTag) { if (tag.isEndTag()) { @@ -257,136 +256,131 @@ bool ThmlToHtml::handleToken(sword::SWBuf &buf, const char *token, myUserData->inscriptRef = false; myUserData->suspendTextPassThru = false; - } - else { // like "<scripRef>John 3:16</scripRef>" - - CSwordModuleInfo* mod = btConfig().getDefaultSwordModuleByType("standardBible"); - //Q_ASSERT(mod); tested later - if (mod) { - ReferenceManager::ParseOptions options; - options.refBase = QString::fromUtf8(myUserData->key->getText()); //current module key - options.refDestinationModule = QString(mod->name()); - options.sourceLanguage = QString(myModule->getLanguage()); - options.destinationLanguage = QString("en"); + } else { // like "<scripRef>John 3:16</scripRef>" + if (CSwordModuleInfo const * const mod = + btConfig().getDefaultSwordModuleByType( + "standardBible")) + { + ReferenceManager::ParseOptions options( + mod->name(), + // current module key: + QString::fromUtf8(myUserData->key->getText()), + myModule->getLanguage()); //it's ok to split the reference, because to descriptive text is given bool insertSemicolon = false; buf.append("<span class=\"crossreference\">"); - QStringList refs = QString::fromUtf8(myUserData->lastTextNode.c_str()).split(";"); - QString oldRef; //the previous reference to use as a base for the next refs - for (QStringList::iterator it(refs.begin()); it != refs.end(); ++it) { - - if (! oldRef.isEmpty() ) { - options.refBase = oldRef; //use the last ref as a base, e.g. Rom 1,2-3, when the next ref is only 3:3-10 - } - const QString completeRef( ReferenceManager::parseVerseReference((*it), options) ); - - oldRef = completeRef; //use the parsed result as the base for the next ref. - - if (insertSemicolon) { //prepend a ref divider if we're after the first one + QStringList const refs( + QString::fromUtf8( + myUserData->lastTextNode.c_str()).split(";")); + QString oldRef; // the previous reference to use as a base for the next refs + for (QStringList::const_iterator it(refs.begin()); + it != refs.end(); + ++it) + { + if (!oldRef.isEmpty()) + options.refBase = oldRef; // Use the last ref as a base, e.g. Rom 1,2-3, when the next ref is only 3:3-10 + + // Use the parsed result as the base for the next ref: + oldRef = ReferenceManager::parseVerseReference( + (*it), + options); + + // Prepend a ref divider if we're after the first one + if (insertSemicolon) buf.append("; "); - } - - buf.append("<a href=\""); - buf.append( - ReferenceManager::encodeHyperlink( - mod->name(), - completeRef, - ReferenceManager::typeFromModule(mod->type()) - ).toUtf8().constData() - ); - - buf.append("\" crossrefs=\""); - buf.append((const char*)completeRef.toUtf8()); - buf.append("\">"); - - buf.append((const char*)(*it).toUtf8()); - - buf.append("</a>"); + buf.append("<a href=\"") + .append( + ReferenceManager::encodeHyperlink( + mod->name(), + oldRef, + ReferenceManager::typeFromModule(mod->type()) + ).toUtf8().constData() + ) + .append("\" crossrefs=\"") + .append(oldRef.toUtf8().constData()) + .append("\">") + .append(it->toUtf8().constData()) + .append("</a>"); insertSemicolon = true; } buf.append("</span>"); //crossref end } - myUserData->suspendTextPassThru = false; } - } - else if (tag.getAttribute("passage") ) { //the passage was given as a parameter value + } else if (tag.getAttribute("passage") ) { + // The passage was given as a parameter value myUserData->inscriptRef = true; myUserData->suspendTextPassThru = false; - const char* ref = tag.getAttribute("passage"); - Q_ASSERT(ref); - - CSwordModuleInfo* mod = btConfig().getDefaultSwordModuleByType("standardBible"); - //Q_ASSERT(mod); tested later - - ReferenceManager::ParseOptions options; - options.refBase = QString::fromUtf8(myUserData->key->getText()); - - options.sourceLanguage = myModule->getLanguage(); - options.destinationLanguage = QString("en"); - - const QString completeRef = ReferenceManager::parseVerseReference(QString::fromUtf8(ref), options); - - if (mod) { - options.refDestinationModule = QString(mod->name()); - buf.append("<span class=\"crossreference\">"); - buf.append("<a href=\""); - buf.append( - ReferenceManager::encodeHyperlink( - mod->name(), - completeRef, - ReferenceManager::typeFromModule(mod->type()) - ).toUtf8().constData() - ); - buf.append("\" crossrefs=\""); - buf.append((const char*)completeRef.toUtf8()); - buf.append("\">"); - } - else { + if (CSwordModuleInfo const * const mod = + btConfig().getDefaultSwordModuleByType( + "standardBible")) + { + ; + BT_ASSERT(tag.getAttribute("passage")); + QString const completeRef( + ReferenceManager::parseVerseReference( + QString::fromUtf8( + tag.getAttribute("passage")), + ReferenceManager::ParseOptions( + mod->name(), + QString::fromUtf8( + myUserData->key->getText()), + myModule->getLanguage()))); + buf.append("<span class=\"crossreference\">") + .append("<a href=\"") + .append( + ReferenceManager::encodeHyperlink( + mod->name(), + completeRef, + ReferenceManager::typeFromModule( + mod->type()) + ).toUtf8().constData() + ) + .append("\" crossrefs=\"") + .append(completeRef.toUtf8().constData()) + .append("\">"); + } else { buf.append("<span><a>"); } - } - else if ( !tag.getAttribute("passage") ) { // we're starting a scripRef like "<scripRef>John 3:16</scripRef>" + } else { // We're starting a scripRef like "<scripRef>John 3:16</scripRef>" myUserData->inscriptRef = false; - - // let's stop text from going to output, the text get's added in the -tag handler + /* Let's stop text from going to output, the text get's + added in the -tag handler: */ myUserData->suspendTextPassThru = true; } } - } - else if (tag.getName() && !sword::stricmp(tag.getName(), "div")) { + } else if (!sword::stricmp(tagName, "div")) { if (tag.isEndTag()) { buf.append("</div>"); + } else if (char const * const tagClass = tag.getAttribute("class")){ + if (!sword::stricmp(tagClass, "sechead") ) { + buf.append("<div class=\"sectiontitle\">"); + } else if (!sword::stricmp(tagClass, "title")) { + buf.append("<div class=\"booktitle\">"); + } } - else if ( tag.getAttribute("class") && !sword::stricmp(tag.getAttribute("class"), "sechead") ) { - buf.append("<div class=\"sectiontitle\">"); - } - else if (tag.getAttribute("class") && !sword::stricmp(tag.getAttribute("class"), "title")) { - buf.append("<div class=\"booktitle\">"); - } - } - else if (tag.getName() && !sword::stricmp(tag.getName(), "img") && tag.getAttribute("src")) { - const char* value = tag.getAttribute("src"); + } else if (!sword::stricmp(tagName, "img") && tag.getAttribute("src")) { + const char * value = tag.getAttribute("src"); - if (value[0] == '/') { + if (value[0] == '/') value++; //strip the first / - } - buf.append("<img src=\""); - QString absPath(QTextCodec::codecForLocale()->toUnicode(myUserData->module->getConfigEntry("AbsoluteDataPath"))); - QString relPath(QString::fromUtf8(value)); - QString url(QUrl::fromLocalFile(absPath.append('/').append(relPath)).toString()); - buf.append(url.toUtf8().data()); - buf.append("\" />"); - } - else { // let unknown token pass thru + buf.append("<img src=\"") + .append( + QUrl::fromLocalFile( + QTextCodec::codecForLocale()->toUnicode( + myUserData->module->getConfigEntry( + "AbsoluteDataPath") + ).append('/').append(QString::fromUtf8(value)) + ).toString().toUtf8().constData()) + .append("\" />"); + } else { // Let unknown token pass thru: return sword::ThMLHTML::handleToken(buf, token, userData); } } - return true; } diff --git a/src/backend/filters/thmltohtml.h b/src/backend/filters/thmltohtml.h index ff40cf9..24b2e1a 100644 --- a/src/backend/filters/thmltohtml.h +++ b/src/backend/filters/thmltohtml.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -40,20 +40,18 @@ class ThmlToHtml: public sword::ThMLHTML { public: /* Methods: */ ThmlToHtml(); - /** Reimplemented from sword::OSISHTMLHREF. */ - virtual bool handleToken(sword::SWBuf &buf, - const char *token, - sword::BasicFilterUserData *userData); + bool handleToken(sword::SWBuf &buf, + const char *token, + sword::BasicFilterUserData *userData) override; - /** Reimplemented from sword::SWFilter. */ - virtual char processText(sword::SWBuf &buf, - const sword::SWKey *key, - const sword::SWModule *module = 0); + char processText(sword::SWBuf &buf, + const sword::SWKey *key, + const sword::SWModule *module = nullptr) override; protected: /* Methods: */ - /** Reimplemented from sword::OSISHTMLHREF. */ - virtual inline sword::BasicFilterUserData *createUserData( - const sword::SWModule *module, const sword::SWKey *key) + + inline sword::BasicFilterUserData *createUserData( + const sword::SWModule *module, const sword::SWKey *key) override { return new UserData(module, key); } diff --git a/src/backend/filters/thmltoplain.cpp b/src/backend/filters/thmltoplain.cpp deleted file mode 100644 index 9f81173..0000000 --- a/src/backend/filters/thmltoplain.cpp +++ /dev/null @@ -1,222 +0,0 @@ -/********* -* -* 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 "backend/filters/thmltoplain.h" - -#include <QtGlobal> - - -namespace Filters { - -char ThmlToPlain::processText(sword::SWBuf &text, - const sword::SWKey *key, - const sword::SWModule *module) -{ - Q_UNUSED(key); - Q_UNUSED(module); - - char token[2048]; - int tokpos = 0; - bool intoken = false; - bool ampersand = false; - - const char *from; - sword::SWBuf orig = text; - from = orig.c_str(); - for (text = ""; *from; from++) { - if (*from == 10 || *from == 13) - from++; - if (*from == '<') { - intoken = true; - tokpos = 0; - token[0] = 0; - token[1] = 0; - token[2] = 0; - ampersand = false; - continue; - } - else if (*from == '&') { - intoken = true; - tokpos = 0; - token[0] = 0; - token[1] = 0; - token[2] = 0; - ampersand = true; - continue; - } - if (*from == ';' && ampersand) { - intoken = false; - ampersand = false; - - if (!strncmp("nbsp", token, 4)) text += " "; - else if (!strncmp("quot", token, 4)) text += "\""; - else if (!strncmp("amp", token, 3)) text += "&"; - else if (!strncmp("lt", token, 2)) text += "<"; - else if (!strncmp("gt", token, 2)) text += ">"; - else if (!strncmp("brvbar", token, 6)) text += "¦"; - else if (!strncmp("sect", token, 4)) text += "§"; - else if (!strncmp("copy", token, 4)) text += "©"; - else if (!strncmp("laquo", token, 5)) text += "«"; - else if (!strncmp("reg", token, 3)) text += "®"; - else if (!strncmp("acute", token, 5)) text += "´"; - else if (!strncmp("para", token, 4)) text += "¶"; - else if (!strncmp("raquo", token, 5)) text += "»"; - - else if (!strncmp("Aacute", token, 6)) text += "Á"; - else if (!strncmp("Agrave", token, 6)) text += "À"; - else if (!strncmp("Acirc", token, 5)) text += "Â"; - else if (!strncmp("Auml", token, 4)) text += "Ä"; - else if (!strncmp("Atilde", token, 6)) text += "Ã"; - else if (!strncmp("Aring", token, 5)) text += "Å"; - else if (!strncmp("aacute", token, 6)) text += "á"; - else if (!strncmp("agrave", token, 6)) text += "à"; - else if (!strncmp("acirc", token, 5)) text += "â"; - else if (!strncmp("auml", token, 4)) text += "ä"; - else if (!strncmp("atilde", token, 6)) text += "ã"; - else if (!strncmp("aring", token, 5)) text += "å"; - else if (!strncmp("Eacute", token, 6)) text += "É"; - else if (!strncmp("Egrave", token, 6)) text += "È"; - else if (!strncmp("Ecirc", token, 5)) text += "Ê"; - else if (!strncmp("Euml", token, 4)) text += "Ë"; - else if (!strncmp("eacute", token, 6)) text += "é"; - else if (!strncmp("egrave", token, 6)) text += "è"; - else if (!strncmp("ecirc", token, 5)) text += "ê"; - else if (!strncmp("euml", token, 4)) text += "ë"; - else if (!strncmp("Iacute", token, 6)) text += "Í"; - else if (!strncmp("Igrave", token, 6)) text += "Ì"; - else if (!strncmp("Icirc", token, 5)) text += "Î"; - else if (!strncmp("Iuml", token, 4)) text += "Ï"; - else if (!strncmp("iacute", token, 6)) text += "í"; - else if (!strncmp("igrave", token, 6)) text += "ì"; - else if (!strncmp("icirc", token, 5)) text += "î"; - else if (!strncmp("iuml", token, 4)) text += "ï"; - else if (!strncmp("Oacute", token, 6)) text += "Ó"; - else if (!strncmp("Ograve", token, 6)) text += "Ò"; - else if (!strncmp("Ocirc", token, 5)) text += "Ô"; - else if (!strncmp("Ouml", token, 4)) text += "Ö"; - else if (!strncmp("Otilde", token, 6)) text += "Õ"; - else if (!strncmp("oacute", token, 6)) text += "ó"; - else if (!strncmp("ograve", token, 6)) text += "ò"; - else if (!strncmp("ocirc", token, 5)) text += "ô"; - else if (!strncmp("ouml", token, 4)) text += "ö"; - else if (!strncmp("otilde", token, 6)) text += "õ"; - else if (!strncmp("Uacute", token, 6)) text += "Ú"; - else if (!strncmp("Ugrave", token, 6)) text += "Ù"; - else if (!strncmp("Ucirc", token, 5)) text += "Û"; - else if (!strncmp("Uuml", token, 4)) text += "Ü"; - else if (!strncmp("uacute", token, 6)) text += "ú"; - else if (!strncmp("ugrave", token, 6)) text += "ù"; - else if (!strncmp("ucirc", token, 5)) text += "û"; - else if (!strncmp("uuml", token, 4)) text += "ü"; - else if (!strncmp("Yacute", token, 6)) text += "Ý"; - else if (!strncmp("yacute", token, 6)) text += "ý"; - else if (!strncmp("yuml", token, 4)) text += "ÿ"; - - else if (!strncmp("deg", token, 3)) text += "°"; - else if (!strncmp("plusmn", token, 6)) text += "±"; - else if (!strncmp("sup2", token, 4)) text += "²"; - else if (!strncmp("sup3", token, 4)) text += "³"; - else if (!strncmp("sup1", token, 4)) text += "¹"; - else if (!strncmp("nbsp", token, 4)) text += "º"; - else if (!strncmp("pound", token, 5)) text += "£"; - else if (!strncmp("cent", token, 4)) text += "¢"; - else if (!strncmp("frac14", token, 6)) text += "¼"; - else if (!strncmp("frac12", token, 6)) text += "½"; - else if (!strncmp("frac34", token, 6)) text += "¾"; - else if (!strncmp("iquest", token, 6)) text += "¿"; - else if (!strncmp("iexcl", token, 5)) text += "¡"; - else if (!strncmp("ETH", token, 3)) text += "Ð"; - else if (!strncmp("eth", token, 3)) text += "ð"; - else if (!strncmp("THORN", token, 5)) text += "Þ"; - else if (!strncmp("thorn", token, 5)) text += "þ"; - else if (!strncmp("AElig", token, 5)) text += "Æ"; - else if (!strncmp("aelig", token, 5)) text += "æ"; - else if (!strncmp("Oslash", token, 6)) text += "Ø"; - else if (!strncmp("curren", token, 6)) text += "¤"; - else if (!strncmp("Ccedil", token, 6)) text += "Ç"; - else if (!strncmp("ccedil", token, 6)) text += "ç"; - else if (!strncmp("szlig", token, 5)) text += "ß"; - else if (!strncmp("Ntilde", token, 6)) text += "Ñ"; - else if (!strncmp("ntilde", token, 6)) text += "ñ"; - else if (!strncmp("yen", token, 3)) text += "¥"; - else if (!strncmp("not", token, 3)) text += "¬"; - else if (!strncmp("ordf", token, 4)) text += "ª"; - else if (!strncmp("uml", token, 3)) text += "¨"; - else if (!strncmp("shy", token, 3)) text += ""; - else if (!strncmp("macr", token, 4)) text += "¯"; - else if (!strncmp("micro", token, 5)) text += "µ"; - else if (!strncmp("middot", token, 6)) text += "·"; - else if (!strncmp("cedil", token, 5)) text += "¸"; - else if (!strncmp("ordm", token, 4)) text += "º"; - else if (!strncmp("times", token, 5)) text += "×"; - else if (!strncmp("divide", token, 6)) text += "÷"; - else if (!strncmp("oslash", token, 6)) text += "ø"; - continue; - - } - else if (*from == '>' && !ampersand) { - intoken = false; - // process desired tokens - if (!strncmp(token, "sync type=\"Strongs\" value=\"", 27)) { - text += ' '; - text += '<'; - for (unsigned int i = 27; token[i] != '\"'; i++) - text += token[i]; - text += '>'; - continue; - } - if (!strncmp(token, "sync type=\"morph\" value=\"", 25)) { - text += ' '; - text += '('; - for (unsigned int i = 25; token[i] != '\"'; i++) - text += token[i]; - text += ')'; - continue; - } - if (!strncmp("note", token, 4)) { - text += ' '; - text += '('; - } - else if (!strncmp("br", token, 2)) - text += '\n'; - else if (!strncmp("/p", token, 2)) - text += '\n'; - else if (!strncmp("/note", token, 5)) { - text += ')'; - text += ' '; - } - continue; - } - if (intoken) { - if (tokpos < 2045) - token[tokpos++] = *from; - token[tokpos+2] = 0; - } - else text += *from; - } - - orig = text; - from = orig.c_str(); - for (text = ""; *from; from++) { //loop to remove extra spaces - if ((strchr(" \t\n\r", *from))) { - while (*(from + 1) && (strchr(" \t\n\r", *(from + 1)))) { - from++; - } - text += " "; - } - else { - text += *from; - } - } - text += (char)0; - - return 0; -} - -} // namespace Filters diff --git a/src/backend/filters/thmltoplain.h b/src/backend/filters/thmltoplain.h deleted file mode 100644 index 68a5d95..0000000 --- a/src/backend/filters/thmltoplain.h +++ /dev/null @@ -1,35 +0,0 @@ -/********* -* -* 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 FILTERS_THMLTOPLAIN_H -#define FILTERS_THMLTOPLAIN_H - -// Sword includes: -#include <swbuf.h> -#include <swfilter.h> - - -namespace Filters { - -/** - \brief ThML text to plain text conversion filter -*/ -class ThmlToPlain: public sword::SWFilter { - protected: /* Methods: */ - /** Reimplemented from sword::SWFilter. */ - virtual char processText(sword::SWBuf &text, - const sword::SWKey *key = 0, - const sword::SWModule *module = 0); -}; - -} // namespace Filters - -#endif diff --git a/src/backend/keys/cswordkey.cpp b/src/backend/keys/cswordkey.cpp index 5fc37bd..24a47e7 100644 --- a/src/backend/keys/cswordkey.cpp +++ b/src/backend/keys/cswordkey.cpp @@ -2,20 +2,21 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ -#include "backend/keys/cswordkey.h" +#include "cswordkey.h" #include <QRegExp> #include <QString> #include <QTextCodec> -#include "backend/drivers/cswordmoduleinfo.h" -#include "backend/keys/cswordldkey.h" -#include "backend/keys/cswordtreekey.h" -#include "backend/keys/cswordversekey.h" +#include "../../util/btassert.h" +#include "../drivers/cswordmoduleinfo.h" +#include "cswordldkey.h" +#include "cswordtreekey.h" +#include "cswordversekey.h" // Sword includes: #include <swkey.h> @@ -32,36 +33,38 @@ QString CSwordKey::rawText() { if (!m_module) return QString::null; - if (dynamic_cast<sword::SWKey*>(this)) - m_module->module()->getKey()->setText( rawKey() ); + auto & m = m_module->module(); + if (dynamic_cast<sword::SWKey *>(this)) + m.getKey()->setText( rawKey() ); if (key().isNull()) return QString::null; - return QString::fromUtf8(m_module->module()->getRawEntry()); + return QString::fromUtf8(m.getRawEntry()); } QString CSwordKey::renderedText(const CSwordKey::TextRenderType mode) { - Q_ASSERT(m_module); + BT_ASSERT(m_module); sword::SWKey * const k = dynamic_cast<sword::SWKey *>(this); + auto & m = m_module->module(); if (k) { - sword::VerseKey * vk_mod = dynamic_cast<sword::VerseKey *>(m_module->module()->getKey()); + sword::VerseKey * vk_mod = dynamic_cast<sword::VerseKey *>(m.getKey()); if (vk_mod) vk_mod->setIntros(true); - m_module->module()->getKey()->setText(rawKey()); + m.getKey()->setText(rawKey()); if (m_module->type() == CSwordModuleInfo::Lexicon) { m_module->snap(); /* In lexicons make sure that our key (e.g. 123) was successfully set to the module, i.e. the module key contains this key (e.g. 0123 contains 123) */ - if (sword::stricmp(m_module->module()->getKey()->getText(), rawKey()) - && !strstr(m_module->module()->getKey()->getText(), rawKey())) + if (sword::stricmp(m.getKey()->getText(), rawKey()) + && !strstr(m.getKey()->getText(), rawKey())) { - qDebug("return an empty key for %s", m_module->module()->getKey()->getText()); + qDebug("return an empty key for %s", m.getKey()->getText()); return QString::null; } } @@ -71,7 +74,7 @@ QString CSwordKey::renderedText(const CSwordKey::TextRenderType mode) { return QString::null; bool DoRender = mode != ProcessEntryAttributesOnly; - QString text = QString::fromUtf8(m_module->module()->renderText(0, -1, DoRender)); + QString text = QString::fromUtf8(m.renderText(nullptr, -1, DoRender)); if (!DoRender) return QString::null; @@ -126,14 +129,15 @@ QString CSwordKey::strippedText() { if (!m_module) return QString::null; + auto & m = m_module->module(); if (dynamic_cast<sword::SWKey*>(this)) { char * buffer = new char[strlen(rawKey()) + 1]; strcpy(buffer, rawKey()); - m_module->module()->getKey()->setText(buffer); + m.getKey()->setText(buffer); delete [] buffer; } - return QString::fromUtf8(m_module->module()->stripText()); + return QString::fromUtf8(m.stripText()); } void CSwordKey::emitBeforeChanged() { @@ -148,16 +152,16 @@ void CSwordKey::emitAfterChanged() { CSwordKey * CSwordKey::createInstance(const CSwordModuleInfo * module) { if (!module) - return 0; + return nullptr; - sword::SWKey * const key = module->module()->getKey(); + sword::SWKey * const key = module->module().getKey(); switch (module->type()) { case CSwordModuleInfo::Bible: // Fall through case CSwordModuleInfo::Commentary: - Q_ASSERT(dynamic_cast<sword::VerseKey *>(key) != 0); + BT_ASSERT(dynamic_cast<sword::VerseKey *>(key)); return new CSwordVerseKey(static_cast<sword::VerseKey *>(key), module); @@ -167,13 +171,13 @@ CSwordKey * CSwordKey::createInstance(const CSwordModuleInfo * module) { case CSwordModuleInfo::GenericBook: - Q_ASSERT(dynamic_cast<sword::TreeKeyIdx *>(key) != 0); + BT_ASSERT(dynamic_cast<sword::TreeKeyIdx *>(key)); return new CSwordTreeKey(dynamic_cast<sword::TreeKeyIdx *>(key), module ); default: - return 0; + return nullptr; } } diff --git a/src/backend/keys/cswordkey.h b/src/backend/keys/cswordkey.h index ee816a5..6d7ffa0 100644 --- a/src/backend/keys/cswordkey.h +++ b/src/backend/keys/cswordkey.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -14,7 +14,7 @@ #include <QPointer> #include <QString> -#include "util/btsignal.h" +#include "../btsignal.h" class CSwordModuleInfo; @@ -31,6 +31,10 @@ public: /* Types: */ ProcessEntryAttributesOnly = 2 // in this case, renderText() will not return text, but only cause EntryAttribute processing }; +public: /* Methods: */ + + CSwordKey & operator=(CSwordKey const &) = delete; + virtual inline ~CSwordKey() { delete m_beforeChangedSignaller; } /** @@ -96,6 +100,9 @@ public: /* Types: */ */ static CSwordKey * createInstance(const CSwordModuleInfo * module); + /** Check whether key is valid. Can be invalidated during av11n mapping. */ + inline bool isValid() const { return m_valid; } + /** This is called before a key change to emit a signal */ @@ -108,11 +115,13 @@ public: /* Types: */ protected: /* Methods: */ - inline CSwordKey(const CSwordModuleInfo * const module = 0) - : m_module(module) {} + inline CSwordKey(const CSwordModuleInfo * const module = nullptr) + : m_module(module) + , m_valid(true) {} inline CSwordKey(const CSwordKey & copy) - : m_module(copy.m_module) {} + : m_module(copy.m_module) + , m_valid(copy.m_valid) {} /** \returns the encoded key appropriate for use directly with Sword. @@ -121,13 +130,6 @@ protected: /* Methods: */ static inline const QTextCodec * cp1252Codec() { return m_cp1252Codec; } -private: /* Methods: */ - - /** - Disable the assignment operator - */ - CSwordKey & operator=(const CSwordKey &); - protected: /* Fields: */ static const QTextCodec * m_cp1252Codec; @@ -135,6 +137,7 @@ protected: /* Fields: */ QPointer<BtSignal> m_beforeChangedSignaller; QPointer<BtSignal> m_afterChangedSignaller; + bool m_valid; }; #endif diff --git a/src/backend/keys/cswordldkey.cpp b/src/backend/keys/cswordldkey.cpp index f6ffb25..caa8471 100644 --- a/src/backend/keys/cswordldkey.cpp +++ b/src/backend/keys/cswordldkey.cpp @@ -2,15 +2,16 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ -#include "backend/keys/cswordldkey.h" +#include "cswordldkey.h" #include <QTextCodec> -#include "backend/drivers/cswordlexiconmoduleinfo.h" +#include "../../util/btassert.h" +#include "../drivers/cswordlexiconmoduleinfo.h" // Sword includes: #include <swmodule.h> @@ -27,7 +28,10 @@ CSwordLDKey::CSwordLDKey(const CSwordModuleInfo *module) { } /** No descriptions */ -CSwordLDKey::CSwordLDKey( const CSwordLDKey &k ) : CSwordKey(k), SWKey((const char*)k) {} +CSwordLDKey::CSwordLDKey(CSwordLDKey const & k) + : CSwordKey(k) + , SWKey(k.getText()) +{} /** No descriptions */ CSwordLDKey::CSwordLDKey(const SWKey *k, const CSwordModuleInfo *module) @@ -43,9 +47,9 @@ CSwordLDKey* CSwordLDKey::copy() const { /** Sets the module of this key. */ void CSwordLDKey::setModule(const CSwordModuleInfo *newModule) { - Q_ASSERT(newModule); + BT_ASSERT(newModule); if (m_module == newModule) return; - Q_ASSERT(newModule->type() == CSwordModuleInfo::Lexicon); + BT_ASSERT(newModule->type() == CSwordModuleInfo::Lexicon); const QString oldKey = key(); m_module = newModule; @@ -54,13 +58,12 @@ void CSwordLDKey::setModule(const CSwordModuleInfo *newModule) { QString CSwordLDKey::key() const { //return QString::fromUtf8((const char*)*this); - Q_ASSERT(m_module); + BT_ASSERT(m_module); if (m_module->isUnicode()) { - return QString::fromUtf8((const char*)*this); - } - else { - return cp1252Codec()->toUnicode((const char*)*this); + return QString::fromUtf8(getText()); + } else { + return cp1252Codec()->toUnicode(getText()); } } @@ -69,7 +72,7 @@ const char * CSwordLDKey::rawKey() const { } bool CSwordLDKey::setKey(const QString &newKey) { - Q_ASSERT(m_module); + BT_ASSERT(m_module); if (m_module->isUnicode()) { return setKey(newKey.toUtf8().constData()); @@ -82,11 +85,11 @@ bool CSwordLDKey::setKey(const QString &newKey) { /** Sets the key of this instance */ bool CSwordLDKey::setKey(const char *newKey) { - Q_ASSERT(newKey); + BT_ASSERT(newKey); if (newKey) { SWKey::operator = (newKey); //set the key - m_module->module()->setKey(this); + m_module->module().setKey(this); m_module->snap(); } @@ -95,29 +98,31 @@ bool CSwordLDKey::setKey(const char *newKey) { /** Uses the parameter to returns the next entry afer this key. */ CSwordLDKey* CSwordLDKey::NextEntry() { - m_module->module()->setKey(this); // use this key as base for the next one! - // m_module->module()->getKey()->setText( (const char*)key().utf8() ); + auto & m = m_module->module(); + m.setKey(this); // use this key as base for the next one! + // m.getKey()->setText( (const char*)key().utf8() ); - m_module->module()->setSkipConsecutiveLinks(true); - ( *( m_module->module() ) )++; - m_module->module()->setSkipConsecutiveLinks(false); + m.setSkipConsecutiveLinks(true); + m++; + m.setSkipConsecutiveLinks(false); - setKey(m_module->module()->getKeyText()); - setText(m_module->module()->getKeyText()); + setKey(m.getKeyText()); + setText(m.getKeyText()); return this; } /** Uses the parameter to returns the next entry afer this key. */ CSwordLDKey* CSwordLDKey::PreviousEntry() { - m_module->module()->setKey(this); // use this key as base for the next one! - // m_module->module()->getKey()->setText( (const char*)key().utf8() ); + auto & m = m_module->module(); + m.setKey(this); // use this key as base for the next one! + // m.getKey()->setText( (const char*)key().utf8() ); - m_module->module()->setSkipConsecutiveLinks(true); - ( *( m_module->module() ) )--; - m_module->module()->setSkipConsecutiveLinks(false); + m.setSkipConsecutiveLinks(true); + m--; + m.setSkipConsecutiveLinks(false); - setText(m_module->module()->getKeyText()); + setText(m.getKeyText()); return this; } diff --git a/src/backend/keys/cswordldkey.h b/src/backend/keys/cswordldkey.h index e8fba24..92c88ef 100644 --- a/src/backend/keys/cswordldkey.h +++ b/src/backend/keys/cswordldkey.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -12,7 +12,7 @@ #ifndef CSWORDLDKEY_H #define CSWORDLDKEY_H -#include "backend/keys/cswordkey.h" +#include "cswordkey.h" #include <QString> @@ -53,6 +53,9 @@ class CSwordModuleInfo; class CSwordLDKey : public CSwordKey, public sword::SWKey { public: + + CSwordLDKey & operator=(CSwordLDKey const &) = delete; + /** \todo Document param */ @@ -65,50 +68,27 @@ class CSwordLDKey : public CSwordKey, public sword::SWKey { */ CSwordLDKey(const sword::SWKey *k, const CSwordModuleInfo *module); - /** - Reimplementation of CSwordKey::copy() - */ - virtual CSwordLDKey* copy() const; + CSwordLDKey* copy() const override; /** * Uses the parameter to returns the next entry afer this key. */ - CSwordLDKey* NextEntry( void ); + CSwordLDKey* NextEntry(); /** * Uses the parameter to returns the previous entry afer this key. */ - CSwordLDKey* PreviousEntry( void ); + CSwordLDKey* PreviousEntry(); - /** - Sets the module of this key. - */ - virtual void setModule(const CSwordModuleInfo *module); + void setModule(const CSwordModuleInfo *module) override; - /** - * Returns the current key as a QString - */ - virtual QString key() const; + QString key() const override; - /** - Reimplemented from CSwordKey::setKey(const QString &key). - */ - virtual bool setKey(const QString &newKey); + bool setKey(const QString &newKey) override; - /** - Reimplemented from CSwordKey::setKey(const char *key). - */ - virtual bool setKey(const char *key); + bool setKey(const char *key) override; protected: - /** - * Returns the raw key appropriate for use directly with Sword. - */ - virtual const char* rawKey() const; - private: - /** - * Disable assignment operator - */ - CSwordLDKey& operator= (const CSwordLDKey& ); + const char* rawKey() const override; }; diff --git a/src/backend/keys/cswordtreekey.cpp b/src/backend/keys/cswordtreekey.cpp index 2823e5f..1b3b1e7 100644 --- a/src/backend/keys/cswordtreekey.cpp +++ b/src/backend/keys/cswordtreekey.cpp @@ -2,16 +2,17 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ -#include "backend/keys/cswordtreekey.h" +#include "cswordtreekey.h" #include <QDebug> #include <QTextCodec> -#include "backend/drivers/cswordbookmoduleinfo.h" +#include "../../util/btassert.h" +#include "../drivers/cswordbookmoduleinfo.h" CSwordTreeKey::CSwordTreeKey( const CSwordTreeKey& k ) : CSwordKey(k), TreeKeyIdx(k) {} @@ -30,7 +31,7 @@ CSwordTreeKey* CSwordTreeKey::copy() const { /** Sets the key of this instance */ QString CSwordTreeKey::key() const { //return getTextUnicode(); - Q_ASSERT(m_module); + BT_ASSERT(m_module); if (m_module->isUnicode()) { return QString::fromUtf8(getText()); } @@ -46,7 +47,7 @@ const char * CSwordTreeKey::rawKey() const { bool CSwordTreeKey::setKey(const QString &newKey) { //return key( newKey.toLocal8Bit().constData() ); //return key(m_module->getTextCodec()->fromUnicode(newKey).constData()); - Q_ASSERT(m_module); + BT_ASSERT(m_module); if (m_module->isUnicode()) { return setKey(newKey.toUtf8().constData()); } @@ -56,7 +57,7 @@ bool CSwordTreeKey::setKey(const QString &newKey) { } bool CSwordTreeKey::setKey(const char *newKey) { - Q_ASSERT(newKey); + BT_ASSERT(newKey); if (newKey) { TreeKeyIdx::operator = (newKey); @@ -71,7 +72,7 @@ bool CSwordTreeKey::setKey(const char *newKey) { QString CSwordTreeKey::getLocalNameUnicode() { //return m_module->getTextCodec()->toUnicode(getLocalName()); //Only UTF-8 and latin1 are legal Sword module encodings - Q_ASSERT(m_module); + BT_ASSERT(m_module); if (m_module->isUnicode()) { return QString::fromUtf8(getLocalName()); } @@ -81,9 +82,9 @@ QString CSwordTreeKey::getLocalNameUnicode() { } void CSwordTreeKey::setModule(const CSwordModuleInfo *newModule) { - Q_ASSERT(newModule); + BT_ASSERT(newModule); if (m_module == newModule) return; - Q_ASSERT(newModule->type() == CSwordModuleInfo::GenericBook); + BT_ASSERT(newModule->type() == CSwordModuleInfo::GenericBook); m_module = newModule; diff --git a/src/backend/keys/cswordtreekey.h b/src/backend/keys/cswordtreekey.h index 2bdfd6c..2aa3b50 100644 --- a/src/backend/keys/cswordtreekey.h +++ b/src/backend/keys/cswordtreekey.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -12,7 +12,7 @@ #ifndef CSWORDTREEKEYIDX_H #define CSWORDTREEKEYIDX_H -#include "backend/keys/cswordkey.h" +#include "cswordkey.h" // Sword includes: #include <treekeyidx.h> @@ -28,6 +28,9 @@ class CSwordModuleInfo; class CSwordTreeKey : public CSwordKey, public sword::TreeKeyIdx { public: + + CSwordTreeKey & operator=(CSwordTreeKey const &) = delete; + /** \param k The Sword tree key which belongs to this key \param module The module which belongs to this key @@ -37,15 +40,9 @@ class CSwordTreeKey : public CSwordKey, public sword::TreeKeyIdx { CSwordTreeKey( const CSwordTreeKey& k ); - /** - Reimplemented from CSwordKey. - */ - virtual void setModule(const CSwordModuleInfo *newModule); + void setModule(const CSwordModuleInfo *newModule) override; - /** Copy method. - * @return A new copy of this object. - */ - virtual CSwordTreeKey* copy() const; + CSwordTreeKey* copy() const override; /** * Returns the TreeKeyIdx::getLocalKey value in unicode. @@ -53,34 +50,16 @@ class CSwordTreeKey : public CSwordKey, public sword::TreeKeyIdx { * Use this instead of getLocalKey() to avoid encoding problems. */ QString getLocalNameUnicode(); - /** - * Returns the current key as unicode decoded QString. - */ - virtual QString key() const; - /** - Reimplemented from CSwordKey::setKey(const QString &key). - */ - virtual bool setKey(const QString &key); + QString key() const override; - /** - Reimplemented from CSwordKey::setKey(const char *key). - */ - virtual bool setKey(const char *key); + bool setKey(const QString &key) override; + + bool setKey(const char *key) override; protected: - /** - * Returns the raw key appropriate for use directly with Sword. - */ - virtual const char * rawKey() const; - - private: - /** Disable assignment operator */ - CSwordTreeKey& operator= (const CSwordTreeKey&); - /** Disable from base class to prevent compiler warnings */ - inline virtual CSwordTreeKey& operator= (const sword::TreeKeyIdx&) { - return (*this); - }; + + const char * rawKey() const override; }; #endif diff --git a/src/backend/keys/cswordversekey.cpp b/src/backend/keys/cswordversekey.cpp index 3dc0c75..f417800 100644 --- a/src/backend/keys/cswordversekey.cpp +++ b/src/backend/keys/cswordversekey.cpp @@ -2,19 +2,18 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ -#include "backend/keys/cswordversekey.h" +#include "cswordversekey.h" -#include <QStringList> #include <QDebug> - -#include "backend/drivers/cswordbiblemoduleinfo.h" -#include "backend/drivers/cswordcommentarymoduleinfo.h" -#include "util/btsignal.h" +#include <QStringList> +#include "../../util/btassert.h" +#include "../drivers/cswordbiblemoduleinfo.h" +#include "../drivers/cswordcommentarymoduleinfo.h" // Sword includes: #include <swmodule.h> @@ -24,12 +23,12 @@ CSwordVerseKey::CSwordVerseKey(const CSwordModuleInfo *module) : CSwordKey(module) { - typedef CSwordBibleModuleInfo CSBMI; - if (const CSBMI *bible = dynamic_cast<const CSBMI*>(module) ) { + if(CSwordBibleModuleInfo const * bible = + dynamic_cast<CSwordBibleModuleInfo const *>(module)) + { // Copy important settings like versification system - copyFrom((sword::VerseKey*) bible->module()->getKey()); - - setKey( bible->lowerBound().key() ); + copyFrom(bible->module().getKey()); + setKey(bible->lowerBound().key()); } this->VerseKey::setAutoNormalize(true); } @@ -52,35 +51,53 @@ CSwordKey* CSwordVerseKey::copy() const { /** Sets the module for this key */ void CSwordVerseKey::setModule(const CSwordModuleInfo *newModule) { - typedef CSwordBibleModuleInfo CSBMI; - - Q_ASSERT(newModule); + BT_ASSERT(newModule); if (m_module == newModule) return; - Q_ASSERT(newModule->type() == CSwordModuleInfo::Bible - || newModule->type() == CSwordModuleInfo::Commentary); + BT_ASSERT(newModule->type() == CSwordModuleInfo::Bible || + newModule->type() == CSwordModuleInfo::Commentary); - m_module = newModule; + CSwordBibleModuleInfo const * bible = static_cast<CSwordBibleModuleInfo const *>(newModule); + const char * newVersification = + static_cast<VerseKey *>(bible->module().getKey())->getVersificationSystem(); + bool inVersification = true; + + emitBeforeChanged(); + + if(strcmp(getVersificationSystem(), newVersification)) { + /// Remap key position to new versification + sword::VerseKey oldKey(*this); - //check if the module contains the key we present - const CSBMI* bible = dynamic_cast<const CSBMI*>(newModule); + setVersificationSystem(newVersification); - if (_compare(bible->lowerBound()) < 0) { - setKey(bible->lowerBound()); + positionFrom(oldKey); + inVersification = !popError(); } - if (_compare(bible->upperBound()) > 0) { - setKey(bible->upperBound()); + m_module = newModule; + + emitAfterChanged(); + + if(inVersification) { + /// Limit to Bible bounds + if (_compare(bible->lowerBound()) < 0) { + setKey(bible->lowerBound()); + } + if (_compare(bible->upperBound()) > 0) { + setKey(bible->upperBound()); + } } + + m_valid = inVersification; } /** Returns the current book as Text, not as integer. */ QString CSwordVerseKey::book( const QString& newBook ) { - typedef CSwordBibleModuleInfo CSBMI; + using CSBMI = CSwordBibleModuleInfo; int min = 0; int max = 1; const CSBMI *bible = dynamic_cast<const CSBMI*>(module()); - if (bible != 0) { + if (bible != nullptr) { const bool hasOT = bible->hasOldTestament(); const bool hasNT = bible->hasNewTestament(); @@ -116,7 +133,7 @@ QString CSwordVerseKey::book( const QString& newBook ) { /** Sets the key we use to the parameter. */ QString CSwordVerseKey::key() const { - return QString::fromUtf8(getText()); + return QString::fromUtf8(isBoundSet() ? getRangeText() : getText()); } const char * CSwordVerseKey::rawKey() const { @@ -128,34 +145,27 @@ bool CSwordVerseKey::setKey(const QString &newKey) { } bool CSwordVerseKey::setKey(const char *newKey) { - typedef CSwordBibleModuleInfo CSBMI; - - /// \todo Is this check necessary? - if (newKey) { - /// \todo Is this check necessary? - // Check if empty string: - if (*newKey != '\0') { - QString newKeyStr = newKey; - emitBeforeChanged(); - positionFrom(newKey); - } else { - const CSwordModuleInfo *m = module(); - if (m->type() == CSwordModuleInfo::Bible) { - Q_ASSERT(dynamic_cast<const CSBMI*>(m) != 0); - const CSBMI *bible = static_cast<const CSBMI*>(m); - emitBeforeChanged(); - positionFrom(bible->lowerBound().key().toUtf8().constData()); - } - } + emitBeforeChanged(); + + if(QByteArray(newKey).contains('-')) { + VerseKey vk(newKey, newKey, getVersificationSystem()); + setLowerBound(vk.getLowerBound()); + setUpperBound(vk.getUpperBound()); + setPosition(sword::TOP); + } else { + clearBounds(); + positionFrom(newKey); } - /// \todo Do we ALWAYS need to emit this signal and check for errors? - emitAfterChanged(); - return !popError(); + m_valid = !popError(); + + emitAfterChanged(); /// \todo Do we ALWAYS need to emit this signal + + return m_valid; } bool CSwordVerseKey::next( const JumpType type ) { - typedef CSwordBibleModuleInfo CSBMI; + using CSBMI = CSwordBibleModuleInfo; popError(); //clear Error status bool ret = true; @@ -185,36 +195,36 @@ bool CSwordVerseKey::next( const JumpType type ) { } case UseVerse: { - if (m_module && m_module->module()) { - const bool oldStatus = m_module->module()->isSkipConsecutiveLinks(); - m_module->module()->setSkipConsecutiveLinks(true); - - //disable headings for next verse - const bool useHeaders = 1; //(Verse() == 0); - const bool oldHeadingsStatus = ((VerseKey*)(m_module->module()->getKey()))->isIntros(); - ((VerseKey*)(m_module->module()->getKey()))->setIntros( useHeaders ); + if (!m_module) { + setVerse(getVerse() + 1); + } else { + auto & m = m_module->module(); + const bool oldStatus = m.isSkipConsecutiveLinks(); + m.setSkipConsecutiveLinks(true); + + VerseKey * vKey = static_cast<VerseKey *>(m.getKey()); + + // disable headings for next verse + bool const oldHeadingsStatus = vKey->isIntros(); + vKey->setIntros(true); //don't use setKey(), that would create a new key without Headings set - m_module->module()->getKey()->setText( key().toUtf8().constData() ); + vKey->setText(key().toUtf8().constData()); - (*(m_module->module()) )++; + m++; - ((VerseKey*)(m_module->module()->getKey()))->setIntros(oldHeadingsStatus); - m_module->module()->setSkipConsecutiveLinks(oldStatus); + vKey = static_cast<VerseKey *>(m.getKey()); + vKey->setIntros(oldHeadingsStatus); + m.setSkipConsecutiveLinks(oldStatus); - if (!m_module->module()->popError()) { - setKey(QString::fromUtf8(m_module->module()->getKeyText())); - } - else { + if (!m.popError()) { + setKey(QString::fromUtf8(vKey->getText())); + } else { // Verse(Verse()+1); //don't change the key, restore the module's position - m_module->module()->getKey()->setText( key().toUtf8().constData() ); + vKey->setText(key().toUtf8().constData()); ret = false; break; } - - } - else { - setVerse(getVerse() + 1); } break; @@ -225,7 +235,7 @@ bool CSwordVerseKey::next( const JumpType type ) { } const CSBMI *bible = dynamic_cast<const CSBMI*>(module()); - if (bible != 0) { + if (bible != nullptr) { if (_compare(bible->lowerBound()) < 0 ) { emitBeforeChanged(); setKey(bible->lowerBound()); @@ -250,7 +260,7 @@ bool CSwordVerseKey::next( const JumpType type ) { } bool CSwordVerseKey::previous( const JumpType type ) { - typedef CSwordBibleModuleInfo CSBMI; + using CSBMI = CSwordBibleModuleInfo; bool ret = true; @@ -277,32 +287,34 @@ bool CSwordVerseKey::previous( const JumpType type ) { } case UseVerse: { - if (m_module && m_module->module()) { - const bool useHeaders = 1; //(Verse() == 0); - const bool oldHeadingsStatus = ((VerseKey*)(m_module->module()->getKey()))->isIntros(); - ((VerseKey*)(m_module->module()->getKey()))->setIntros( useHeaders ); - - m_module->module()->getKey()->setText( key().toUtf8().constData() ); - - const bool oldStatus = m_module->module()->isSkipConsecutiveLinks(); - m_module->module()->setSkipConsecutiveLinks(true); - ( *( m_module->module() ) )--; - - ((VerseKey*)(m_module->module()->getKey()))->setIntros( oldHeadingsStatus ); - m_module->module()->setSkipConsecutiveLinks(oldStatus); - - if (!m_module->module()->popError()) { - setKey(QString::fromUtf8(m_module->module()->getKeyText())); // don't use fromUtf8 - } - else { + if (!m_module) { + setVerse(getVerse() - 1); + } else { + auto & m = m_module->module(); + VerseKey * vKey = static_cast<VerseKey *>(m.getKey()); + bool const oldHeadingsStatus = vKey->isIntros(); + vKey->setIntros(true); + vKey->setText(key().toUtf8().constData()); + + bool const oldStatus = m.isSkipConsecutiveLinks(); + m.setSkipConsecutiveLinks(true); + m--; + + vKey = static_cast<VerseKey *>(m.getKey()); + vKey->setIntros(oldHeadingsStatus); + m.setSkipConsecutiveLinks(oldStatus); + + if (!m.popError()) { + /// \warning Weird comment: + // don't use fromUtf8: + setKey(QString::fromUtf8(vKey->getText())); + } else { ret = false; // Verse(Verse()-1); - m_module->module()->getKey()->setText( key().toUtf8().constData() ); //restore module's key + // Restore module's key: + vKey->setText(key().toUtf8().constData()); } } - else { - setVerse(getVerse() - 1); - } break; } @@ -312,7 +324,7 @@ bool CSwordVerseKey::previous( const JumpType type ) { } const CSBMI *bible = dynamic_cast<const CSBMI*>(module()); - if (bible != 0) { + if (bible != nullptr) { if (_compare(bible->lowerBound()) < 0 ) { emitBeforeChanged(); setKey(bible->lowerBound()); diff --git a/src/backend/keys/cswordversekey.h b/src/backend/keys/cswordversekey.h index 4f33521..69a686b 100644 --- a/src/backend/keys/cswordversekey.h +++ b/src/backend/keys/cswordversekey.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -12,7 +12,7 @@ #ifndef CSWORDVERSEKEY_H #define CSWORDVERSEKEY_H -#include "backend/keys/cswordkey.h" +#include "cswordkey.h" #include <QString> @@ -47,13 +47,17 @@ class CSwordModuleInfo; class CSwordVerseKey : public CSwordKey, public sword::VerseKey { - public: + public: /* Types: */ enum JumpType { UseBook, UseChapter, UseVerse }; + public: /* Methods: */ + + CSwordVerseKey & operator=(CSwordVerseKey const &) = delete; + /** Constructs a versekey with the current module position and setups the m_module members. @@ -72,26 +76,13 @@ class CSwordVerseKey : public CSwordKey, public sword::VerseKey { CSwordVerseKey(const sword::VerseKey *k, const CSwordModuleInfo *module); - /** - Reimplementation of CSwordKey::copy(). - */ - virtual CSwordKey* copy() const; + CSwordKey* copy() const override; - /** - * Set/get the key. If the parameter is not set (means equal to QString::null) - * the used key is returned. Otherwise the key is set and the new on ei returned. - */ - virtual QString key() const; + QString key() const override; - /** - Reimplemented from CSwordKey::setKey(const QString &key). - */ - virtual bool setKey(const QString &key); + bool setKey(const QString &key) override; - /** - Reimplemented from CSwordKey::setKey(const char *key). - */ - virtual bool setKey(const char *key); + bool setKey(const char *key) override; /** * Jumps to the next entry of the given type @@ -109,24 +100,12 @@ class CSwordVerseKey : public CSwordKey, public sword::VerseKey { */ QString book(const QString& newBook = QString::null); - /** - Sets the module for this key. - */ - virtual void setModule(const CSwordModuleInfo *newModule); + void setModule(const CSwordModuleInfo *newModule) override; protected: - /** - * Returns the raw key appropriate for use directly with Sword. - */ - virtual const char * rawKey() const; - - private: - /** Disable assignment operator */ - CSwordVerseKey& operator= (const CSwordVerseKey&); - /** Disable from base class to prevent compiler warnings */ - inline virtual CSwordVerseKey& operator= (const sword::VerseKey&) { - return (*this); - }; + + const char * rawKey() const override; + }; #endif diff --git a/src/backend/managers/btstringmgr.cpp b/src/backend/managers/btstringmgr.cpp index 2e2e22a..f7919e5 100644 --- a/src/backend/managers/btstringmgr.cpp +++ b/src/backend/managers/btstringmgr.cpp @@ -2,68 +2,37 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ -#include "backend/managers/btstringmgr.h" +#include "btstringmgr.h" #include <cstring> -#include "util/macros.h" +#include <QString> +#include "../../util/btassert.h" +#include "../../util/macros.h" -char * BtStringMgr::upperUTF8(char * const text, unsigned int maxlen) const { - size_t max = (maxlen > 0u) ? maxlen : strlen(text); - - if (LIKELY(max > 1u)) { - max--; - if (isUtf8(text)) { - strncpy(text, QString::fromUtf8(text).toUpper().toUtf8().constData(), max); - } - else { - strncpy(text, QString::fromLatin1(text).toUpper().toLatin1().constData(), max); - } - text[max] = '\0'; - } else if (max == 1u) { - text[0u] = '\0'; - } else { - Q_ASSERT(max == 0u); - } - - return text; -} - -char * BtStringMgr::upperLatin1(char * const text, unsigned int maxlen) const { - size_t max = (maxlen > 0u) ? maxlen : strlen(text); - - if (LIKELY(max > 1u)) { - max--; - strncpy(text, QString::fromLatin1(text).toUpper().toLatin1().constData(), max); - text[max] = '\0'; - } else if (max == 1u) { - text[0u] = '\0'; - } else { - Q_ASSERT(max == 0u); - } +namespace { - return text; -} - -bool BtStringMgr::supportsUnicode() const { - return true; -} - -bool BtStringMgr::isUtf8(const char *buf) const { +/** CODE TAKEN FROM KDELIBS 3.2, which is licensed under the LGPL 2. +* +* This code was taken from KStringHandler, which is part of the KDE libraries. +* +* This function checks whether a string is utf8 or not. +* It was taken from kdelibs so we do not depend on KDE 3.2. +*/ +bool isUtf8(const char * buf) { int i, n; - register unsigned char c; + unsigned char c; bool gotone = false; #define F 0 /* character never appears in text */ #define T 1 /* character appears in plain ASCII text */ #define I 2 /* character appears in ISO-8859 text */ #define X 3 /* character appears in non-ISO extended ASCII (Mac, IBM PC) */ - static const unsigned char text_chars[256] = { /* BEL BS HT LF FF CR */ F, F, F, F, F, F, F, T, T, T, T, F, T, T, F, F, /* 0x0X */ @@ -85,6 +54,9 @@ bool BtStringMgr::isUtf8(const char *buf) const { I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, /* 0xeX */ I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I /* 0xfX */ }; + #undef F + #undef I + #undef X /* *ulen = 0; */ @@ -97,6 +69,7 @@ bool BtStringMgr::isUtf8(const char *buf) const { if (text_chars[c] != T) return false; + #undef T } else if ((c & 0x40) == 0) { /* 10xxxxxx never 1st byte */ @@ -141,7 +114,45 @@ done: return gotone; /* don't claim it's UTF-8 if it's all 7-bit */ } -#undef F -#undef T -#undef I -#undef X +} // anonymous namespace + +char * BtStringMgr::upperUTF8(char * text, unsigned int maxlen) const { + size_t max = (maxlen > 0u) ? maxlen : strlen(text); + + if (LIKELY(max > 1u)) { + max--; + if (isUtf8(text)) { + strncpy(text, QString::fromUtf8(text).toUpper().toUtf8().constData(), max); + } + else { + strncpy(text, QString::fromLatin1(text).toUpper().toLatin1().constData(), max); + } + text[max] = '\0'; + } else if (max == 1u) { + text[0u] = '\0'; + } else { + BT_ASSERT(max == 0u); + } + + return text; +} + +char * BtStringMgr::upperLatin1(char * text, unsigned int maxlen) const { + size_t max = (maxlen > 0u) ? maxlen : strlen(text); + + if (LIKELY(max > 1u)) { + max--; + strncpy(text, QString::fromLatin1(text).toUpper().toLatin1().constData(), max); + text[max] = '\0'; + } else if (max == 1u) { + text[0u] = '\0'; + } else { + BT_ASSERT(max == 0u); + } + + return text; +} + +bool BtStringMgr::supportsUnicode() const { + return true; +} diff --git a/src/backend/managers/btstringmgr.h b/src/backend/managers/btstringmgr.h index 3fd0175..2a5b508 100644 --- a/src/backend/managers/btstringmgr.h +++ b/src/backend/managers/btstringmgr.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -12,9 +12,6 @@ #ifndef BTSTRINGMGR_H #define BTSTRINGMGR_H -#include <QString> - -/* Sword includes: */ #include <stringmgr.h> @@ -23,37 +20,25 @@ A Qt-based sword::StringMgr is better than the default one in Sword, in case Sword is not compiled against ICU regarding this. However, we have no good - means to check this, so let's use this class as default. This is currently - done in BibleTime::initBackends() as follows: - sword::StringMgr::setSystemStringMgr(new BtStringMgr()); + means to check this at compile time, hence we provide this class. It is + initialized in BibleTime::initBackends() as follows: + \code{.cpp} + if (!sword::SWMgr::isICU) + sword::StringMgr::setSystemStringMgr(new BtStringMgr()); + \endcode */ class BtStringMgr : public sword::StringMgr { public: - /** Converts the param to an upper case Utf8 string - * @param The text encoded in utf8 which should be turned into an upper case string - */ - virtual char *upperUTF8(char *text, unsigned int max = 0) const; - /** Converts the param to an uppercase latin1 string - * @param The text encoded in latin1 which should be turned into an upper case string - */ - virtual char *upperLatin1(char *text, unsigned int max = 0) const; + char *upperUTF8(char *text, unsigned int max = 0) const override; + + char *upperLatin1(char *text, unsigned int max = 0) const override; protected: - /** Enable Unicode support. - * Reimplementation to show unicode support. - */ - virtual bool supportsUnicode() const; - - /** CODE TAKEN FROM KDELIBS 3.2, which is licensed under the LGPL 2. - * - * This code was taken from KStringHandler, which is part of the KDE libraries. - * - * This function checks whether a string is utf8 or not. - * It was taken from kdelibs so we do not depend on KDE 3.2. - */ - bool isUtf8(const char *buf) const; + + bool supportsUnicode() const override; + }; #endif /* BTSTRINGMGR_H */ diff --git a/src/backend/managers/cdisplaytemplatemgr.cpp b/src/backend/managers/cdisplaytemplatemgr.cpp index 734d912..c302c02 100644 --- a/src/backend/managers/cdisplaytemplatemgr.cpp +++ b/src/backend/managers/cdisplaytemplatemgr.cpp @@ -2,24 +2,25 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ -#include "backend/managers/cdisplaytemplatemgr.h" +#include "cdisplaytemplatemgr.h" #include <QFile> #include <QFileInfo> #include <QStringList> #include <QTextStream> -#include "backend/config/btconfig.h" -#include "backend/drivers/cswordmoduleinfo.h" -#include "backend/managers/clanguagemgr.h" -#include "util/directory.h" +#include "../../util/directory.h" +#include "../config/btconfig.h" +#include "../drivers/cswordmoduleinfo.h" +#include "clanguagemgr.h" #define CSSTEMPLATEBASE "Basic.tmpl" +#define CSSTEMPLATEBASEMOBILE "Basic-mobile.tmpl" namespace { @@ -30,10 +31,10 @@ inline QString readFileToString(const QString & filename) { } // anonymous namespace -CDisplayTemplateMgr * CDisplayTemplateMgr::m_instance = 0; +CDisplayTemplateMgr * CDisplayTemplateMgr::m_instance = nullptr; CDisplayTemplateMgr::CDisplayTemplateMgr(QString & errorMessage) { - Q_ASSERT(m_instance == 0); + BT_ASSERT(!m_instance); m_instance = this; { @@ -79,7 +80,7 @@ CDisplayTemplateMgr::CDisplayTemplateMgr(QString & errorMessage) { // Create template names cache: m_availableTemplateNamesCache = m_templateMap.keys(); const bool b = m_availableTemplateNamesCache.removeOne(CSSTEMPLATEBASE); - Q_ASSERT(b); + BT_ASSERT(b); m_availableTemplateNamesCache.append(m_cssMap.keys()); qSort(m_availableTemplateNamesCache); @@ -90,10 +91,10 @@ QString CDisplayTemplateMgr::fillTemplate(const QString & name, const QString & content, const Settings & settings) const { - Q_ASSERT(name != CSSTEMPLATEBASE); - Q_ASSERT(name.endsWith(".css") || name.endsWith(".tmpl")); - Q_ASSERT(!name.endsWith(".css") || m_cssMap.contains(name)); - Q_ASSERT(!name.endsWith(".tmpl") || m_templateMap.contains(name)); + BT_ASSERT(name != CSSTEMPLATEBASE); + BT_ASSERT(name.endsWith(".css") || name.endsWith(".tmpl")); + BT_ASSERT(!name.endsWith(".css") || m_cssMap.contains(name)); + BT_ASSERT(!name.endsWith(".tmpl") || m_templateMap.contains(name)); const bool templateIsCss = name.endsWith(".css"); QString displayTypeString; @@ -137,9 +138,9 @@ QString CDisplayTemplateMgr::fillTemplate(const QString & name, // qDebug() << "There were more than 1 module, create headers"; QString header; - Q_FOREACH(const CSwordModuleInfo * mi, settings.modules) { + Q_FOREACH(const CSwordModuleInfo * const mi, settings.modules) { header.append("<th style=\"width:") - .append(QString::number(int( 100.0 / (float)moduleCount ))) + .append(QString::number(static_cast<int>(100.0 / moduleCount))) .append("%;\">") .append(mi->name()) .append("</th>"); @@ -163,7 +164,7 @@ QString CDisplayTemplateMgr::fillTemplate(const QString & name, } { const CLanguageMgr::LangMap & langMap = CLanguageMgr::instance()->availableLanguages(); - Q_FOREACH (const CLanguageMgr::Language * lang, langMap) { + Q_FOREACH(const CLanguageMgr::Language * const lang, langMap) { if (lang->abbrev().isEmpty()) continue; @@ -211,17 +212,17 @@ QString CDisplayTemplateMgr::activeTemplateName() { } void CDisplayTemplateMgr::loadTemplate(const QString & filename) { - Q_ASSERT(filename.endsWith(".tmpl")); - Q_ASSERT(QFileInfo(filename).isFile()); + BT_ASSERT(filename.endsWith(".tmpl")); + BT_ASSERT(QFileInfo(filename).isFile()); const QString templateString = readFileToString(filename); if (!templateString.isEmpty()) m_templateMap.insert(QFileInfo(filename).fileName(), templateString); } void CDisplayTemplateMgr::loadCSSTemplate(const QString & filename) { - Q_ASSERT(filename.endsWith(".css")); + BT_ASSERT(filename.endsWith(".css")); const QFileInfo fi(filename); - Q_ASSERT(fi.isFile()); + BT_ASSERT(fi.isFile()); if (fi.isReadable()) m_cssMap.insert(fi.fileName(), filename); } diff --git a/src/backend/managers/cdisplaytemplatemgr.h b/src/backend/managers/cdisplaytemplatemgr.h index 823312c..a270d91 100644 --- a/src/backend/managers/cdisplaytemplatemgr.h +++ b/src/backend/managers/cdisplaytemplatemgr.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -14,6 +14,8 @@ #include <QHash> #include <QStringList> +#include "../../util/btassert.h" +#include "../drivers/btmodulelist.h" #include "../drivers/cswordmoduleinfo.h" @@ -39,7 +41,7 @@ class CDisplayTemplateMgr { } /** The list of modules */ - QList<const CSwordModuleInfo *> modules; + BtConstModuleList modules; /** The title which is used for the new processed HTML page */ QString title; @@ -100,7 +102,7 @@ class CDisplayTemplateMgr { \returns The singleton instance of the instance of this class. */ static inline CDisplayTemplateMgr * instance() { - Q_ASSERT(m_instance != 0); + BT_ASSERT(m_instance); return m_instance; } diff --git a/src/backend/managers/clanguagemgr.cpp b/src/backend/managers/clanguagemgr.cpp index 49cc1a1..5914336 100644 --- a/src/backend/managers/clanguagemgr.cpp +++ b/src/backend/managers/clanguagemgr.cpp @@ -2,30 +2,30 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ -#include "backend/managers/clanguagemgr.h" +#include "clanguagemgr.h" -#include "backend/drivers/cswordmoduleinfo.h" -#include "backend/managers/cswordbackend.h" +#include "../drivers/cswordmoduleinfo.h" +#include "cswordbackend.h" /****************************************************/ /******************** CLanguageMgr ******************/ /****************************************************/ -CLanguageMgr *CLanguageMgr::m_instance = 0; +CLanguageMgr *CLanguageMgr::m_instance = nullptr; void CLanguageMgr::destroyInstance() { delete m_instance; - m_instance = 0; + m_instance = nullptr; } CLanguageMgr *CLanguageMgr::instance() { - if (m_instance == 0) { + if (m_instance == nullptr) { m_instance = new CLanguageMgr(); } @@ -48,23 +48,24 @@ CLanguageMgr::~CLanguageMgr() { } const CLanguageMgr::LangMap& CLanguageMgr::availableLanguages() { - QList<CSwordModuleInfo*> mods = CSwordBackend::instance()->moduleList(); + QList<CSwordModuleInfo*> const & mods = CSwordBackend::instance()->moduleList(); - if ( m_availableModulesCache.moduleCount != (unsigned int)mods.count() ) { //we have to refill the cached map + // Do we have to refill the cached map? + if (m_availableModulesCache.moduleCount != mods.count()) { m_availableModulesCache.availableLanguages.clear(); m_availableModulesCache.moduleCount = mods.count(); //collect the languages abbrevs of all modules QStringList abbrevs; - foreach (const CSwordModuleInfo* mod, mods) { - if (!abbrevs.contains(mod->module()->getLanguage())) { - abbrevs.append(mod->module()->getLanguage()); - } + Q_FOREACH(const CSwordModuleInfo * const mod, mods) { + auto & m = mod->module(); + if (!abbrevs.contains(m.getLanguage())) + abbrevs.append(m.getLanguage()); } //now create a map of available langs - foreach ( QString abbrev, abbrevs ) { + Q_FOREACH(QString const & abbrev, abbrevs) { const Language* const lang = languageForAbbrev(abbrev); if (lang->isValid()) { @@ -85,9 +86,9 @@ const CLanguageMgr::Language* CLanguageMgr::languageForAbbrev( const QString& ab if (it != m_langMap.constEnd()) return *it; //Language is already here //try to search in the alternative abbrevs - foreach (const Language* lang, m_langList ) { - if (lang->alternativeAbbrevs().contains(abbrev)) return lang; - } + Q_FOREACH(const Language * const lang, m_langList) + if (lang->alternativeAbbrevs().contains(abbrev)) + return lang; // Invalid lang used by a modules, create a new language using the abbrev Language* newLang = new Language(abbrev, abbrev, abbrev); //return a language which holds the valid abbrev @@ -97,9 +98,9 @@ const CLanguageMgr::Language* CLanguageMgr::languageForAbbrev( const QString& ab } const CLanguageMgr::Language* CLanguageMgr::languageForTranslatedName( const QString& name ) const { - foreach ( const Language* lang, m_langList ) { - if (lang->translatedName() == name) return lang; - } + Q_FOREACH(const Language * const lang, m_langList) + if (lang->translatedName() == name) + return lang; return &m_defaultLanguage; //invalid language } @@ -524,7 +525,6 @@ void CLanguageMgr::init() { //: Language name zu m_langList.append( new Language("zu", "Zulu", QObject::tr("Zulu")) ); - foreach (Language* lang, m_langList) { + Q_FOREACH(Language * const lang, m_langList) m_langMap.insert( lang->abbrev(), lang); - } } diff --git a/src/backend/managers/clanguagemgr.h b/src/backend/managers/clanguagemgr.h index fee236f..c9a4d8f 100644 --- a/src/backend/managers/clanguagemgr.h +++ b/src/backend/managers/clanguagemgr.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -114,9 +114,9 @@ class CLanguageMgr { }; /* class Language { */ - typedef QList<Language*> LanguageList; - typedef QHash<QString, const Language*> LangMap; - typedef QHash<QString, const Language*>::const_iterator LangMapIterator; + using LanguageList = QList<Language *>; + using LangMap = QHash<QString, Language const *>; + using LangMapIterator = LangMap::const_iterator; /** Returns the singleton instance, creating it if one does not exist. */ @@ -171,7 +171,7 @@ class CLanguageMgr { mutable LanguageList m_cleanupLangPtrs; struct ModuleCache { - unsigned int moduleCount; + int moduleCount; LangMap availableLanguages; } m_availableModulesCache; diff --git a/src/backend/managers/cswordbackend.cpp b/src/backend/managers/cswordbackend.cpp index c126c47..7abef64 100644 --- a/src/backend/managers/cswordbackend.cpp +++ b/src/backend/managers/cswordbackend.cpp @@ -2,12 +2,12 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ -#include "backend/managers/cswordbackend.h" +#include "cswordbackend.h" #include <QDebug> #include <QDir> @@ -15,21 +15,19 @@ #include <QSet> #include <QString> #include <QTextCodec> -#include "backend/config/btconfig.h" -#include "backend/drivers/cswordbiblemoduleinfo.h" -#include "backend/drivers/cswordbookmoduleinfo.h" -#include "backend/drivers/cswordcommentarymoduleinfo.h" -#include "backend/drivers/cswordlexiconmoduleinfo.h" -#include "backend/filters/btosismorphsegmentation.h" -#include "backend/filters/thmltoplain.h" -#include "btglobal.h" -#include "util/directory.h" +#include "../../util/directory.h" +#include "../btglobal.h" +#include "../btinstallmgr.h" +#include "../config/btconfig.h" +#include "../drivers/cswordbiblemoduleinfo.h" +#include "../drivers/cswordbookmoduleinfo.h" +#include "../drivers/cswordcommentarymoduleinfo.h" +#include "../drivers/cswordlexiconmoduleinfo.h" // Sword includes: #include <encfiltmgr.h> #include <filemgr.h> #include <rtfhtml.h> -#include <swdisp.h> #include <swfiltermgr.h> #include <swfilter.h> #include <utilstr.h> @@ -37,80 +35,89 @@ using namespace Rendering; -CSwordBackend * CSwordBackend::m_instance = 0; +CSwordBackend * CSwordBackend::m_instance = nullptr; CSwordBackend::CSwordBackend() - : sword::SWMgr(0, 0, false, + : sword::SWMgr(nullptr, nullptr, false, new sword::EncodingFilterMgr(sword::ENC_UTF8), true) , m_dataModel(this) -{ - filterInit(); -} +{} CSwordBackend::CSwordBackend(const QString & path, const bool augmentHome) - : sword::SWMgr(!path.isEmpty() ? path.toLocal8Bit().constData() : 0, + : sword::SWMgr(!path.isEmpty() ? path.toLocal8Bit().constData() : nullptr, false, new sword::EncodingFilterMgr(sword::ENC_UTF8), false, augmentHome) -{ // don't allow module renaming, because we load from a path - filterInit(); -} +{} CSwordBackend::~CSwordBackend() { shutdownModules(); } -void CSwordBackend::filterInit() { - // HACK: replace Sword's OSISMorphSegmentation filter, seems to be buggy, ours works - if (sword::SWOptionFilter * const filter = optionFilters["OSISMorphSegmentation"]) { - cleanupFilters.remove(filter); - optionFilters.erase("OSISMorphSegmentation"); - delete filter; - } - sword::SWOptionFilter * const tmpFilter = new Filters::BtOSISMorphSegmentation(); - optionFilters.insert(sword::OptionFilterMap::value_type("OSISMorphSegmentation", tmpFilter)); - cleanupFilters.push_back(tmpFilter); - - // HACK: replace Sword's ThML strip filter with our own version - // Remove this hack as soon as Sword is fixed - cleanupFilters.remove(thmlplain); - delete thmlplain; - thmlplain = new Filters::ThmlToPlain(); - cleanupFilters.push_back(thmlplain); +BtModuleList CSwordBackend::moduleList(CSwordModuleInfo::ModuleType type) const +{ + BtModuleList l; + Q_FOREACH(CSwordModuleInfo * m, moduleList()) + if(m->type() == type) + l.append(m); + return l; } -QList<CSwordModuleInfo *> CSwordBackend::takeModulesFromList(const QStringList & names) { - QList<CSwordModuleInfo *> list; - Q_FOREACH (const QString & name, names) { - CSwordModuleInfo * const mInfo = findModuleByName(name); - if (mInfo) { - m_dataModel.removeModule(mInfo); - list.append(mInfo); +void CSwordBackend::uninstallModules(BtConstModuleSet const & toBeDeleted) { + if (toBeDeleted.empty()) + return; + m_dataModel.removeModules(toBeDeleted); + emit sigSwordSetupChanged(RemovedModules); + + BtInstallMgr installMgr; + QMap<QString, sword::SWMgr *> mgrDict; // Maps config paths to SWMgr objects + for (CSwordModuleInfo const * const mInfo : toBeDeleted) { + // Find the install path for the sword manager: + QString dataPath = mInfo->config(CSwordModuleInfo::DataPath); + if (dataPath.left(2) == "./") + dataPath = dataPath.mid(2); + + QString prefixPath = + mInfo->config(CSwordModuleInfo::AbsoluteDataPath) + "/"; + 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()); } - if (!list.isEmpty()) - emit sigSwordSetupChanged(RemovedModules); - return list; + qDeleteAll(toBeDeleted); + qDeleteAll(mgrDict); + mgrDict.clear(); } QList<CSwordModuleInfo *> CSwordBackend::getPointerList(const QStringList & names) const { QList<CSwordModuleInfo *> list; - Q_FOREACH (const QString & name, names) { - CSwordModuleInfo * const mInfo = findModuleByName(name); - if (mInfo) + Q_FOREACH (const QString & name, names) + if (CSwordModuleInfo * const mInfo = findModuleByName(name)) list.append(mInfo); - } return list; } -QList<const CSwordModuleInfo *> CSwordBackend::getConstPointerList( - const QStringList & names) const -{ - QList<const CSwordModuleInfo *> list; - Q_FOREACH (const QString & name, names) { - const CSwordModuleInfo * const mInfo = findModuleByName(name); - if (mInfo) +BtConstModuleList CSwordBackend::getConstPointerList(const QStringList & names) const { + BtConstModuleList list; + Q_FOREACH (const QString & name, names) + if (CSwordModuleInfo const * const mInfo = findModuleByName(name)) list.append(mInfo); - } return list; } @@ -125,21 +132,22 @@ CSwordBackend::LoadError CSwordBackend::initModules(const SetupChangedReason rea for (sword::ModMap::iterator it = Modules.begin(); it != end; ++it) { sword::SWModule * const curMod = it->second; + BT_ASSERT(curMod); CSwordModuleInfo * newModule; const char * const modType = curMod->getType(); if (!strcmp(modType, "Biblical Texts")) { - newModule = new CSwordBibleModuleInfo(curMod, *this); - newModule->module()->setDisplay(&m_chapterDisplay); + newModule = new CSwordBibleModuleInfo(*curMod, *this); + newModule->setDisplay(&m_chapterDisplay); } else if (!strcmp(modType, "Commentaries")) { - newModule = new CSwordCommentaryModuleInfo(curMod, *this); - newModule->module()->setDisplay(&m_entryDisplay); + newModule = new CSwordCommentaryModuleInfo(*curMod, *this); + newModule->setDisplay(&m_entryDisplay); } else if (!strcmp(modType, "Lexicons / Dictionaries")) { - newModule = new CSwordLexiconModuleInfo(curMod, *this); - newModule->module()->setDisplay(&m_entryDisplay); + newModule = new CSwordLexiconModuleInfo(*curMod, *this); + newModule->setDisplay(&m_entryDisplay); } else if (!strcmp(modType, "Generic Books")) { - newModule = new CSwordBookModuleInfo(curMod, *this); - newModule->module()->setDisplay(&m_bookDisplay); + newModule = new CSwordBookModuleInfo(*curMod, *this); + newModule->setDisplay(&m_bookDisplay); } else { continue; } @@ -156,7 +164,7 @@ CSwordBackend::LoadError CSwordBackend::initModules(const SetupChangedReason rea } // Unlock modules if keys are present: - Q_FOREACH(CSwordModuleInfo * mod, m_dataModel.moduleList()) { + Q_FOREACH(CSwordModuleInfo const * const mod, m_dataModel.moduleList()) { if (mod->isEncrypted()) { const QString unlockKey = btConfig().getModuleEncryptionKey(mod->name()); if (!unlockKey.isNull()) @@ -208,7 +216,7 @@ void CSwordBackend::shutdownModules() { * modules. If these modules are removed, the filters need to be removed as well, * so that they are re-created for the new module objects. */ - typedef sword::FilterMap::const_iterator FMCI; + using FMCI = sword::FilterMap::const_iterator; for (FMCI it = cipherFilters.begin(); it != cipherFilters.end(); ++it) { //Delete the Filter and remove it from the cleanup list cleanupFilters.remove(it->second); @@ -258,24 +266,24 @@ void CSwordBackend::setFilterOptions(const FilterOptions & options) { } CSwordModuleInfo * CSwordBackend::findModuleByDescription(const QString & description) const { - Q_FOREACH (CSwordModuleInfo * mod, m_dataModel.moduleList()) + Q_FOREACH(CSwordModuleInfo * const mod, m_dataModel.moduleList()) if (mod->config(CSwordModuleInfo::Description) == description) return mod; - return 0; + return nullptr; } CSwordModuleInfo * CSwordBackend::findModuleByName(const QString & name) const { - Q_FOREACH (CSwordModuleInfo * mod, m_dataModel.moduleList()) + Q_FOREACH(CSwordModuleInfo * const mod, m_dataModel.moduleList()) if (mod->name() == name) return mod; - return 0; + return nullptr; } CSwordModuleInfo * CSwordBackend::findSwordModuleByPointer(const sword::SWModule * const swmodule) const { - Q_FOREACH (CSwordModuleInfo * mod, m_dataModel.moduleList()) - if (mod->module() == swmodule) + Q_FOREACH(CSwordModuleInfo * const mod, m_dataModel.moduleList()) + if (&mod->module() == swmodule) return mod; - return 0; + return nullptr; } QString CSwordBackend::optionName(const CSwordModuleInfo::FilterTypes option) { @@ -377,13 +385,13 @@ const QString CSwordBackend::booknameLanguage(const QString & language) { // Use what sword returns, language may be different. const QByteArray newLocaleName(QString(sword::LocaleMgr::getSystemLocaleMgr()->getDefaultLocaleName()).toUtf8()); - Q_FOREACH (CSwordModuleInfo * mod, m_dataModel.moduleList()) { + Q_FOREACH(CSwordModuleInfo const * const mod, m_dataModel.moduleList()) { if (mod->type() == CSwordModuleInfo::Bible || mod->type() == CSwordModuleInfo::Commentary) { // Create a new key, it will get the default bookname language: - typedef sword::VerseKey VK; - VK & vk = *static_cast<VK *>(mod->module()->getKey()); + using VK = sword::VerseKey; + VK & vk = *static_cast<VK *>(mod->module().getKey()); vk.setLocale(newLocaleName.constData()); } } @@ -399,7 +407,7 @@ void CSwordBackend::reloadModules(const SetupChangedReason reason) { if (myconfig) { // force reload on config object because we may have changed the paths delete myconfig; - config = myconfig = 0; + config = myconfig = nullptr; // we need to call findConfig to make sure that augPaths are reloaded findConfig(&configType, &prefixPath, &configPath, &augPaths, &sysConfig); // now re-read module configuration files @@ -415,7 +423,7 @@ void CSwordBackend::reloadModules(const SetupChangedReason reason) { QStringList CSwordBackend::getSharedSwordConfigFiles() const { #ifdef Q_OS_WIN // %ALLUSERSPROFILE%\Sword\sword.conf - return QStringList(util::directory::convertDirSeparators(QString(getenv("SWORD_PATH"))) += "/Sword/sword.conf"); + return QStringList(util::directory::convertDirSeparators(qgetenv("SWORD_PATH")) += "/Sword/sword.conf"); #else // /etc/sword.conf, /usr/local/etc/sword.conf return QString(globalConfPath).split(":"); @@ -434,7 +442,7 @@ QString CSwordBackend::getPrivateSwordConfigFile() const { // Return a list of used Sword dirs. Useful for the installer. QStringList CSwordBackend::swordDirList() const { namespace DU = util::directory; - typedef QStringList::const_iterator SLCI; + using SLCI = QStringList::const_iterator; // Get the set of sword directories that could contain modules: QSet<QString> swordDirSet; @@ -457,7 +465,7 @@ QStringList CSwordBackend::swordDirList() const { private sword.conf will have it. The user could decide to delete this shared path and it will not automatically come back. */ - swordDirSet << DU::convertDirSeparators(QString(getenv("SWORD_PATH"))); + swordDirSet << DU::convertDirSeparators(qgetenv("SWORD_PATH")); #endif } @@ -474,7 +482,7 @@ QStringList CSwordBackend::swordDirList() const { swordDirSet << QDir(QTextCodec::codecForLocale()->toUnicode(conf["Install"]["DataPath"].c_str())).absolutePath(); const sword::ConfigEntMap group(conf["Install"]); - typedef sword::ConfigEntMap::const_iterator CEMCI; + using CEMCI = sword::ConfigEntMap::const_iterator ; for (std::pair<CEMCI, CEMCI> its = group.equal_range("AugmentPath"); its.first != its.second; ++(its.first)) @@ -495,8 +503,7 @@ void CSwordBackend::deleteOrphanedIndices() { Q_FOREACH(const QString & entry, entries) { if (entry == "." || entry == "..") continue; - CSwordModuleInfo * const module = findModuleByName(entry); - if (module) { //mod exists + if (CSwordModuleInfo * const module = findModuleByName(entry)) { if (!module->hasIndex()) { //index files found, but wrong version etc. qDebug() << "deleting outdated index for module" << entry; CSwordModuleInfo::deleteIndexForModule(entry); diff --git a/src/backend/managers/cswordbackend.h b/src/backend/managers/cswordbackend.h index 21da696..ff85bf6 100644 --- a/src/backend/managers/cswordbackend.h +++ b/src/backend/managers/cswordbackend.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -15,16 +15,18 @@ #include <QObject> #include <QString> #include <QStringList> -#include "backend/drivers/cswordmoduleinfo.h" -#include "backend/bookshelfmodel/btbookshelfmodel.h" -#include "backend/filters/gbftohtml.h" -#include "backend/filters/osistohtml.h" -#include "backend/filters/plaintohtml.h" -#include "backend/filters/teitohtml.h" -#include "backend/filters/thmltohtml.h" -#include "backend/rendering/cbookdisplay.h" -#include "backend/rendering/cchapterdisplay.h" -#include "backend/rendering/centrydisplay.h" +#include "../../util/btassert.h" +#include "../drivers/cswordmoduleinfo.h" +#include "../drivers/btconstmoduleset.h" +#include "../bookshelfmodel/btbookshelfmodel.h" +#include "../filters/gbftohtml.h" +#include "../filters/osistohtml.h" +#include "../filters/plaintohtml.h" +#include "../filters/teitohtml.h" +#include "../filters/thmltohtml.h" +#include "../rendering/cbookdisplay.h" +#include "../rendering/cchapterdisplay.h" +#include "../rendering/centrydisplay.h" // Sword includes: #include <swmgr.h> @@ -89,7 +91,7 @@ public: /* Methods: */ /** \returns the CSwordBackend singleton instance (created if needed). */ static inline CSwordBackend * createInstance() { - Q_ASSERT(!m_instance); + BT_ASSERT(!m_instance); m_instance = new CSwordBackend(); return m_instance; } @@ -100,7 +102,7 @@ public: /* Methods: */ /** \brief Destroys the singleton instance, if one exists. */ static inline void destroyInstance() { delete m_instance; - m_instance = NULL; + m_instance = nullptr; } /** @@ -108,9 +110,14 @@ public: /* Methods: */ \note This method is equivalent to model()->modules(). \returns The list of modules managed by this backend. */ - inline const QList<CSwordModuleInfo *> & moduleList() const; + inline const QList<CSwordModuleInfo*> & moduleList() const { + return m_dataModel.moduleList(); + } + BtModuleList moduleList(CSwordModuleInfo::ModuleType type) const; - inline BtBookshelfModel * model(); + inline BtBookshelfModel * model() { + return &m_dataModel; + } /** \brief Initializes the Sword modules. @@ -165,7 +172,9 @@ public: /* Methods: */ \returns The global config object containing the configs of all modules merged together. */ - inline sword::SWConfig * getConfig() const; + inline sword::SWConfig * getConfig() const { + return config; + } /** \param[in] option The option name to return. @@ -192,26 +201,24 @@ public: /* Methods: */ void reloadModules(const SetupChangedReason reason); /** - \brief Takes off the given modules from the list and returns them. - \param[in] names The names of the modules to take. - \note User must take care of the deletion of the returned CSwordModuleInfo - pointers. + \brief Uninstalls the given modules. + \param[in] modules The modules to uninstall. */ - QList<CSwordModuleInfo *> takeModulesFromList(const QStringList & names); + void uninstallModules(BtConstModuleSet const & modules); /** \param[in] names The names of the modules to return. \returns a list of pointers to modules, created from a list of module names. */ - QList<CSwordModuleInfo *> getPointerList(const QStringList & names) const; + QList<CSwordModuleInfo*> getPointerList(const QStringList & names) const; /** \param[in] names The names of the modules to return. \returns a list of pointers to const modules, created from a list of module names. */ - QList<const CSwordModuleInfo *> getConstPointerList(const QStringList & names) const; + BtConstModuleList getConstPointerList(const QStringList & names) const; /** \brief Sword prefix list. @@ -240,10 +247,7 @@ protected: /* Methods: */ /** Reimplemented from sword::SWMgr. */ void AddRenderFilters(sword::SWModule * module, - sword::ConfigEntMap & section); - - /** Overrides Sword filters which appear to be buggy. */ - void filterInit(); + sword::ConfigEntMap & section) override; QStringList getSharedSwordConfigFiles() const; QString getPrivateSwordConfigPath() const; @@ -269,18 +273,4 @@ private: /* Fields: */ }; -/**Returns The list of modules managed by this backend*/ -inline const QList<CSwordModuleInfo *> & CSwordBackend::moduleList() const { - return m_dataModel.moduleList(); -} - -inline BtBookshelfModel * CSwordBackend::model() { - return &m_dataModel; -} - -/** Returns our local config object to store the cipher keys etc. locally for each user. The values of the config are merged with the global config. */ -inline sword::SWConfig * CSwordBackend::getConfig() const { - return config; -} - #endif diff --git a/src/backend/managers/referencemanager.cpp b/src/backend/managers/referencemanager.cpp index 144ad8c..ebbc999 100644 --- a/src/backend/managers/referencemanager.cpp +++ b/src/backend/managers/referencemanager.cpp @@ -2,20 +2,21 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ -#include "backend/managers/referencemanager.h" +#include "referencemanager.h" #include <algorithm> #include <QRegExp> #include <QDebug> -#include "backend/config/btconfig.h" -#include "backend/keys/cswordversekey.h" -#include "backend/drivers/cswordmoduleinfo.h" -#include "backend/managers/cswordbackend.h" +#include "../../util/btassert.h" +#include "../config/btconfig.h" +#include "../keys/cswordversekey.h" +#include "../drivers/cswordmoduleinfo.h" +#include "cswordbackend.h" /** Returns a hyperlink used to be imbedded in the display windows. At the moment the format is sword://module/key */ @@ -247,7 +248,7 @@ bool ReferenceManager::isHyperlink( const QString& hyperlink ) { /** Returns the preferred module name for the given type. */ const QString ReferenceManager::preferredModule( const ReferenceManager::Type type ) { QString moduleName = QString::null; - CSwordModuleInfo* module = 0; + CSwordModuleInfo* module = nullptr; switch (type) { @@ -273,7 +274,7 @@ const QString ReferenceManager::preferredModule( const ReferenceManager::Type ty module = btConfig().getDefaultSwordModuleByType( "standardGreekMorphLexicon" ); break; default: - module = 0; + module = nullptr; break; } @@ -305,7 +306,7 @@ ReferenceManager::Type ReferenceManager::typeFromModule( const CSwordModuleInfo: const QString ReferenceManager::parseVerseReference( const QString& ref, const ReferenceManager::ParseOptions& options) { CSwordModuleInfo* const mod = CSwordBackend::instance()->findModuleByName(options.refDestinationModule); - //Q_ASSERT(mod); tested later + //BT_ASSERT(mod); tested later if (!mod) { //parsing of non-verse based references is not supported @@ -332,7 +333,7 @@ const QString ReferenceManager::parseVerseReference( const QString& ref, const R QString ret; QStringList refList = ref.split(";"); - CSwordVerseKey baseKey(0); + CSwordVerseKey baseKey(nullptr); baseKey.setLocale( sourceLanguage.toUtf8().constData() ); baseKey.setKey(options.refBase); //probably in the sourceLanguage baseKey.setLocale( "en_US" ); //english works in all environments as base @@ -344,16 +345,16 @@ const QString ReferenceManager::parseVerseReference( const QString& ref, const R sword::VerseKey dummy; dummy.setLocale( sourceLanguage.toUtf8().constData() ); - Q_ASSERT( !strcmp(dummy.getLocale(), sourceLanguage.toUtf8().constData()) ); + BT_ASSERT(!strcmp(dummy.getLocale(), sourceLanguage.toUtf8().constData())); // qDebug("Parsing '%s' in '%s' using '%s' as base, source lang '%s', dest lang '%s'", ref.latin1(), options.refDestinationModule.latin1(), baseKey.key().latin1(), sourceLanguage.latin1(), destinationLanguage.latin1()); for (QStringList::iterator it = refList.begin(); it != refList.end(); ++it) { //The listkey may contain more than one item, because a ref lik "Gen 1:3,5" is parsed into two single refs sword::ListKey lk = dummy.parseVerseList((*it).toUtf8().constData(), baseKey.key().toUtf8().constData(), true); - Q_ASSERT(!dummy.popError()); + BT_ASSERT(!dummy.popError()); - //Q_ASSERT(lk.Count()); + //BT_ASSERT(lk.Count()); if (!lk.getCount()) { ret.append( *it ); //don't change the original continue; @@ -362,7 +363,7 @@ const QString ReferenceManager::parseVerseReference( const QString& ref, const R for (int i = 0; i < lk.getCount(); ++i) { if (dynamic_cast<sword::VerseKey*>(lk.getElement(i))) { // a range sword::VerseKey* k = dynamic_cast<sword::VerseKey*>(lk.getElement(i)); - Q_ASSERT(k); + BT_ASSERT(k); k->setLocale( destinationLanguage.toUtf8().constData() ); ret.append( QString::fromUtf8(k->getRangeText()) ).append("; "); diff --git a/src/backend/managers/referencemanager.h b/src/backend/managers/referencemanager.h index 80d00d6..107be7f 100644 --- a/src/backend/managers/referencemanager.h +++ b/src/backend/managers/referencemanager.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -13,7 +13,7 @@ #define REFERENCEMANAGER_H #include <QString> -#include "backend/drivers/cswordmoduleinfo.h" +#include "../drivers/cswordmoduleinfo.h" /** Contains functions to work with references used for Drag & Drop and for hyperlinks used in our @@ -71,14 +71,27 @@ ReferenceManager::Type typeFromModule( const CSwordModuleInfo::ModuleType type ) struct ParseOptions { + +/* Methods: */ + + inline ParseOptions(QString const & refDestinationModule_ = QString::null, + QString const & refBase_ = QString::null, + QString const & sourceLanguage_ = QString::null, + QString const & destinationLanguage_ = "en") + : refDestinationModule(refDestinationModule_) + , refBase(refBase_) + , sourceLanguage(sourceLanguage_) + , destinationLanguage(destinationLanguage_) + {} + +/* Fields: */ + QString refDestinationModule; - QString refBase; /* only valid for verse based destination modules*/ - QString sourceLanguage; /* only valid for verse based destination modules*/ - QString destinationLanguage; /* only valid for verse based destination modules*/ + /* The following are only valid for verse-based destination modules: */ + QString refBase; + QString sourceLanguage; + QString destinationLanguage; - ParseOptions() { - destinationLanguage = "en"; - }; }; /** Parses the given verse references using the given language and the module. diff --git a/src/backend/models/btlistmodel.cpp b/src/backend/models/btlistmodel.cpp new file mode 100644 index 0000000..a397fc2 --- /dev/null +++ b/src/backend/models/btlistmodel.cpp @@ -0,0 +1,38 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +#include "btlistmodel.h" + +#include <QStandardItem> + +BtListModel::BtListModel(bool checkable, QObject *parent, int numColumns) + : QStandardItemModel(parent), + m_checkable(checkable), + m_columnCount(numColumns) { + if (numColumns > 0) + setColumnCount(numColumns); +} + +void BtListModel::appendItem(const QString& title, const QString& tooltip){ + QList<QStandardItem*> items; + QStandardItem* item = new QStandardItem(title); + items.append(item); + item->setToolTip(tooltip); + if (m_checkable) + item->setCheckable(true); + for (int column = 1; column < m_columnCount; ++column) { + QStandardItem* item2 = new QStandardItem(); + items.append(item2); + } + appendRow(items); + +} diff --git a/src/backend/models/btlistmodel.h b/src/backend/models/btlistmodel.h new file mode 100644 index 0000000..a31ec96 --- /dev/null +++ b/src/backend/models/btlistmodel.h @@ -0,0 +1,38 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +#ifndef BTLISTMODEL_H +#define BTLISTMODEL_H + +#include <QStandardItemModel> + +/** + \brief This is a generic list model with optional checkboxes on first + column and optional delete icon in second column. +\ */ + +class BtListModel: public QStandardItemModel { + + Q_OBJECT + +public: + + BtListModel(bool checkable, QObject *parent = nullptr, int numColumns = 1); + + void appendItem(const QString& title, const QString& tooltip = QString()); + +private: + bool m_checkable; + int m_columnCount; + +}; +#endif diff --git a/src/backend/models/btmoduletextmodel.cpp b/src/backend/models/btmoduletextmodel.cpp new file mode 100644 index 0000000..78d73b2 --- /dev/null +++ b/src/backend/models/btmoduletextmodel.cpp @@ -0,0 +1,279 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +#include "btmoduletextmodel.h" + +#include "../../util/btassert.h" +#include "../drivers/cswordmoduleinfo.h" +#include "../drivers/cswordbiblemoduleinfo.h" +#include "../drivers/cswordbookmoduleinfo.h" +#include "../drivers/cswordlexiconmoduleinfo.h" +#include "../cswordmodulesearch.h" +#include "../keys/cswordtreekey.h" +#include "../keys/cswordldkey.h" +#include "../managers/cswordbackend.h" +#include "../rendering/ctextrendering.h" + + +// Static so all models use the same colors +static QColor s_linkColor = QColor(0,191,255); +static QColor s_highlightColor = QColor(255,255,0); +static QColor s_jesusWordsColor = QColor(255,0,0); + +/*static*/ void BtModuleTextModel::setLinkColor(const QColor& color) { + s_linkColor = color; +} + +/*static*/ void BtModuleTextModel::setHighlightColor(const QColor& color) { + s_highlightColor = color; +} + +/*static*/ void BtModuleTextModel::setJesusWordsColor(const QColor& color) { + s_jesusWordsColor = color; +} + + + +BtModuleTextModel::BtModuleTextModel(QObject *parent) + : QAbstractListModel(parent), m_firstEntry(0), m_maxEntries(0) { + QHash<int, QByteArray> roleNames; + roleNames[ModuleEntry::ReferenceRole] = "keyName"; + roleNames[ModuleEntry::TextRole] = "line"; + setRoleNames(roleNames); + m_displayOptions.verseNumbers = 0; + m_displayOptions.lineBreaks = 1; + m_filterOptions.footnotes = 0; + m_filterOptions.greekAccents = 1; + m_filterOptions.headings = 1; + m_filterOptions.hebrewCantillation = 1; + m_filterOptions.hebrewPoints = 1; + m_filterOptions.lemmas = 0; + m_filterOptions.morphSegmentation = 1; + m_filterOptions.morphTags = 1; + m_filterOptions.redLetterWords = 1; + m_filterOptions.scriptureReferences = 0; + m_filterOptions.strongNumbers = 0; + m_filterOptions.textualVariants = 1; + m_filterOptions.textualVariants = 0; +} + +void BtModuleTextModel::setModules(const QStringList& modules) { + beginResetModel(); + + m_moduleInfoList.clear(); + for (int i = 0; i < modules.count(); ++i) { + QString moduleName = modules.at(i); + CSwordModuleInfo* module = CSwordBackend::instance()->findModuleByName(moduleName); + m_moduleInfoList.append(module); + } + + const CSwordModuleInfo* firstModule = m_moduleInfoList.at(0); + + if (isBible() || isCommentary()) { + auto & m = firstModule->module(); + m.setPosition(sword::TOP); + m_firstEntry = m.getIndex(); + m.setPosition(sword::BOTTOM); + m_maxEntries = m.getIndex() - m_firstEntry + 1; + } else if(isLexicon()) { + m_maxEntries = + static_cast<CSwordLexiconModuleInfo const *>(firstModule) + ->entries().size(); + } else if(isBook()) { + sword::TreeKeyIdx tk( + *static_cast<CSwordBookModuleInfo const *>(firstModule) + ->tree()); + tk.root(); + tk.firstChild(); + BT_ASSERT(tk.getOffset() == 4); + tk.setPosition(sword::BOTTOM); + m_maxEntries = tk.getOffset() / 4; + } + + endResetModel(); +} + +QVariant BtModuleTextModel::data(const QModelIndex & index, int role) const { + + if (isBible() || isCommentary()) + return verseData(index, role); + else if (isBook()) + return bookData(index, role); + else if (isLexicon()) + return lexiconData(index, role); + return QVariant("invalid"); +} + +QVariant BtModuleTextModel::lexiconData(const QModelIndex & index, int role) const { + int row = index.row(); + + const CSwordLexiconModuleInfo *lexiconModule = qobject_cast<const CSwordLexiconModuleInfo*>(m_moduleInfoList.at(0)); + BtConstModuleList moduleList; + moduleList << lexiconModule; + QString keyName = lexiconModule->entries()[row]; + + if (role == ModuleEntry::TextRole) { + Rendering::CEntryDisplay entryDisplay; + QString text = entryDisplay.text(moduleList, keyName, + m_displayOptions, m_filterOptions); + text.replace("#CHAPTERTITLE#", ""); + text = replaceColors(text); + return CSwordModuleSearch::highlightSearchedText(text, m_highlightWords); + } + else if (role == ModuleEntry::ReferenceRole){ + return keyName; + } + return QString(); +} + +QVariant BtModuleTextModel::bookData(const QModelIndex & index, int role) const { + if (role == ModuleEntry::TextRole) { + const CSwordBookModuleInfo *bookModule = qobject_cast<const CSwordBookModuleInfo*>(m_moduleInfoList.at(0)); + CSwordTreeKey key(bookModule->tree(), bookModule); + int bookIndex = index.row() * 4; + key.setIndex(bookIndex); + Rendering::CEntryDisplay entryDisplay; + BtConstModuleList moduleList; + moduleList << bookModule; + QString text = entryDisplay.textKeyRendering(moduleList, key.key(), + m_displayOptions, m_filterOptions, + Rendering::CTextRendering::KeyTreeItem::Settings::SimpleKey); + text.replace("#CHAPTERTITLE#", ""); + return CSwordModuleSearch::highlightSearchedText(text, m_highlightWords); + return text; + } + return QString(); +} + +QVariant BtModuleTextModel::verseData(const QModelIndex & index, int role) const { + int row = index.row(); + CSwordVerseKey key = indexToVerseKey(row); + int verse = key.getVerse(); + if (role == ModuleEntry::TextRole) { + if (verse == 0) + return QString(); + QString text; + + QString chapterTitle; + if (verse == 1) + chapterTitle = key.book() + " " + QString::number(key.getChapter()); + + text += Rendering::CEntryDisplay().textKeyRendering(m_moduleInfoList, + key.key(), m_displayOptions, m_filterOptions, + Rendering::CTextRendering::KeyTreeItem::Settings::SimpleKey); + text.replace("#CHAPTERTITLE#", chapterTitle); + text = replaceColors(text); + return CSwordModuleSearch::highlightSearchedText(text, m_highlightWords); + } + return QString(); +} + +QString BtModuleTextModel::replaceColors(const QString& text) const { + QString newText = text; + newText.replace("#JESUS_WORDS_COLOR#", s_jesusWordsColor.name()); + newText.replace("#LINK_COLOR#", s_linkColor.name()); + newText.replace("#HIGHLIGHT_COLOR#", s_highlightColor.name()); + return newText; +} + +int BtModuleTextModel::columnCount(const QModelIndex & /*parent*/) const { + return 1; +} + +int BtModuleTextModel::rowCount(const QModelIndex & /*parent*/) const { + return m_maxEntries; +} + +QHash<int, QByteArray> BtModuleTextModel::roleNames() const { + return m_roleNames; +} + +void BtModuleTextModel::setRoleNames(const QHash<int, QByteArray> &roleNames) { + m_roleNames = roleNames; +} + +bool BtModuleTextModel::isBible() const { + const CSwordModuleInfo* module = m_moduleInfoList.at(0); + if (module == nullptr) + return false; + return module->type() == CSwordModuleInfo::Bible; +} + +bool BtModuleTextModel::isBook() const { + const CSwordModuleInfo* module = m_moduleInfoList.at(0); + if (module == nullptr) + return false; + return module->type() == CSwordModuleInfo::GenericBook; +} + +bool BtModuleTextModel::isCommentary() const { + const CSwordModuleInfo* module = m_moduleInfoList.at(0); + if (module == nullptr) + return false; + return module->type() == CSwordModuleInfo::Commentary; +} + +bool BtModuleTextModel::isLexicon() const { + const CSwordModuleInfo* module = m_moduleInfoList.at(0); + if (module == nullptr) + return false; + return module->type() == CSwordModuleInfo::Lexicon; +} + +int BtModuleTextModel::verseKeyToIndex(const CSwordVerseKey& key) const { + int index = key.getIndex() - m_firstEntry; + return index; +} + +CSwordVerseKey BtModuleTextModel::indexToVerseKey(int index) const +{ + const CSwordModuleInfo* module = m_moduleInfoList.at(0); + CSwordVerseKey key(module); + + key.setIntros(true); + key.setIndex(index + m_firstEntry); + return key; +} + +CSwordTreeKey BtModuleTextModel::indexToBookKey(int index) const +{ + const CSwordModuleInfo* module = m_moduleInfoList.at(0); + const CSwordBookModuleInfo *bookModule = qobject_cast<const CSwordBookModuleInfo*>(module); + CSwordTreeKey key(bookModule->tree(), bookModule); + int bookIndex = index * 4; + key.setIndex(bookIndex); + return key; +} + +QString BtModuleTextModel::indexToKeyName(int index) const { + QString keyName = "???"; + if (isBible() || isCommentary()) { + CSwordVerseKey key = indexToVerseKey(index); + keyName = key.key(); + } + else if (isBook()) { + CSwordTreeKey key = indexToBookKey(index); + keyName = key.key(); + } + else if (isLexicon()) { + const CSwordLexiconModuleInfo *lexiconModule = qobject_cast<const CSwordLexiconModuleInfo*>(m_moduleInfoList.at(0)); + keyName = lexiconModule->entries()[index]; + } + return keyName; +} + +void BtModuleTextModel::setHighlightWords(const QString& highlightWords) { + beginResetModel(); + m_highlightWords = highlightWords; + endResetModel(); +} + diff --git a/src/backend/models/btmoduletextmodel.h b/src/backend/models/btmoduletextmodel.h new file mode 100644 index 0000000..416fbca --- /dev/null +++ b/src/backend/models/btmoduletextmodel.h @@ -0,0 +1,102 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +#ifndef BTMODULETEXTMODEL_H +#define BTMODULETEXTMODEL_H + +#include <QAbstractListModel> +#include <QColor> +#include <QStringList> +#include "../btglobal.h" +#include "../drivers/btmodulelist.h" +#include "../keys/cswordversekey.h" +#include "../keys/cswordtreekey.h" +#include "../keys/cswordldkey.h" + + +struct ModuleEntry { + enum TextRoles { + ReferenceRole = Qt::UserRole + 1, + TextRole = Qt::UserRole + 2 + }; +}; + +/** + \brief Model that represents the entire text of a given module + + This model will display the entire text of a module. It is made to be + used by a QML ListView and to view a small portion of the available text. + It can be continuously scrolled to any location within the module. + + \note Currently Bible, Commentary, and Book modules are supported. + \note Parallel Bible text not yet supported. + */ + + + +class BtModuleTextModel: public QAbstractListModel { + + Q_OBJECT + +public: + + BtModuleTextModel(QObject *parent = nullptr); + + /** Specifies one or more module names for use by the model */ + void setModules(const QStringList& modules); + + bool isBible() const; + bool isBook() const; + bool isCommentary() const; + bool isLexicon() const; + + /** functions to convert from book or verse key to row index and back */ + CSwordTreeKey indexToBookKey(int index) const; + CSwordVerseKey indexToVerseKey(int index) const; + + int verseKeyToIndex(const CSwordVerseKey& key) const; + QString indexToKeyName(int index) const; + + /** Reimplemented from QAbstractItemModel. */ + int columnCount(const QModelIndex & parent = QModelIndex()) const override; + QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override; + int rowCount(const QModelIndex & parent = QModelIndex()) const override; + QHash<int, QByteArray> roleNames() const override; + void setRoleNames(const QHash<int, QByteArray> &roleNames); + void setHighlightWords(const QString& highlightWords); + + static void setLinkColor(const QColor& color); + static void setHighlightColor(const QColor& color); + static void setJesusWordsColor(const QColor& color); + +private: + + /** returns text string for each model index */ + QVariant bookData(const QModelIndex & index, int role = Qt::DisplayRole) const; + QVariant verseData(const QModelIndex & index, int role = Qt::DisplayRole) const; + QVariant lexiconData(const QModelIndex & index, int role = Qt::DisplayRole) const; + + QString replaceColors(const QString& text) const; + + BtConstModuleList m_moduleInfoList; + QHash<int, QByteArray> m_roleNames; + QStringList m_modules; + QString m_highlightWords; + + int m_firstEntry; + int m_maxEntries; + DisplayOptions m_displayOptions; + FilterOptions m_filterOptions; +}; + + +#endif diff --git a/src/backend/rendering/btinforendering.cpp b/src/backend/rendering/btinforendering.cpp new file mode 100644 index 0000000..c2e0efc --- /dev/null +++ b/src/backend/rendering/btinforendering.cpp @@ -0,0 +1,497 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#include "btinforendering.h" + +#include <QStringList> +#include "../../util/btassert.h" +#include "../btglobal.h" +#include "../keys/cswordversekey.h" +#include "../managers/cdisplaytemplatemgr.h" +#include "../managers/referencemanager.h" +#include "chtmlexportrendering.h" + + +using namespace Rendering; +using namespace sword; + +namespace Rendering { + +class CrossRefRendering : public CHTMLExportRendering { +public: + CrossRefRendering( + const DisplayOptions &displayOptions = btConfig().getDisplayOptions(), + const FilterOptions &filterOptions = btConfig().getFilterOptions()) + : CHTMLExportRendering(true, displayOptions, filterOptions) {;} + + QString entryLink(const KeyTreeItem &item, const CSwordModuleInfo *module) override { + BT_ASSERT(module); + + QString linkText; + + const bool isBible = (module->type() == CSwordModuleInfo::Bible); + CSwordVerseKey vk(module); //only valid for bible modules, i.e. isBible == true + if (isBible) { + vk.setKey(item.key()); + } + + switch (item.settings().keyRenderingFace) { + case KeyTreeItem::Settings::NoKey: { + linkText = QString::null; + break; //no key is valid for all modules + } + case KeyTreeItem::Settings::CompleteShort: { + if (isBible) { + linkText = QString::fromUtf8(vk.getShortText()); + break; + } + //fall through for non-Bible modules + } + case KeyTreeItem::Settings::CompleteLong: { + if (isBible) { + linkText = vk.key(); + break; + } + //fall through for non-Bible modules + } + case KeyTreeItem::Settings::SimpleKey: { + if (isBible) { + linkText = QString::number(vk.getVerse()); + break; + } + //fall through for non-Bible modules + } + default: { //default behaviour to return the passed key + linkText = item.key(); + break; + } + } + + if (!linkText.isEmpty()) { //if we have a valid link text + // qWarning("rendering"); + return QString("<a href=\"%1\">%2</a>") + .arg( + ReferenceManager::encodeHyperlink( + module->name(), + item.key(), + ReferenceManager::typeFromModule(module->type()) + ) + ) + .arg(linkText); + } + + return QString::null; + } + + QString finishText(const QString &text, const KeyTree &tree) override { + Q_UNUSED(tree); + return text; + } +}; + + +ListInfoData detectInfo(QString const &data) +{ + ListInfoData list; + QStringList attrList = data.split("||"); + + for (int i = 0; i < attrList.count(); i++) { + QString attrPair = attrList[i]; + QStringList attr = attrPair.split("="); + if (attr.count() == 2) { + QString attrName = attr[0]; + QString attrValue = attr[1]; + if (attrName == "note") { + list.append( qMakePair(Footnote, attrValue)); + } + if (attrName == "lemma") { + list.append( qMakePair(Lemma, attrValue)); + } + if (attrName == "morph") { + list.append( qMakePair(Morph, attrValue)); + } + if (attrName == "expansion") { + list.append( qMakePair(Abbreviation, attrValue)); + } + if (attrName == "crossrefs") { + list.append( qMakePair(CrossReference, attrValue)); + } + if (attrName == "href") { + list.append( qMakePair(Reference, attrValue)); + } + if (attrName == "key") { + list.append( qMakePair(Key, attrValue)); + } + } + } + + return list; +} + + +QString formatInfo(const ListInfoData & list, BtConstModuleList const & modules) +{ + BT_ASSERT(!modules.contains(nullptr) && (modules.size() <= 1 && "not implemented")); + + if (list.isEmpty()) + return QString(); + + QString text; + + ListInfoData::const_iterator end = list.end(); + for (ListInfoData::const_iterator it = list.begin(); it != end; ++it) { + switch ( (*it).first ) { + case Lemma: + text.append( decodeStrongs( (*it).second ) ); + continue; + case Morph: + text.append( decodeMorph( (*it).second ) ); + continue; + case CrossReference: + text.append( decodeCrossReference( (*it).second, modules ) ); + continue; + case Footnote: + text.append( decodeFootnote( (*it).second ) ); + continue; + case WordTranslation: + text.append( getWordTranslation( (*it).second ) ); + continue; + case WordGloss: + //text.append( getWordTranslation( (*it).second ) ); + continue; + case Abbreviation: + text.append( decodeAbbreviation( (*it).second ) ); + continue; + case Text: + text.append( (*it).second ); + continue; + case Reference: + if((*it).second.contains("strongs:")) + { + QString v = (*it).second.right((*it).second.size() - + (*it).second.lastIndexOf('/') - 1); + + if((*it).second.contains("GREEK")) + v.prepend('G'); + else if((*it).second.contains("HEBREW")) + v.prepend('H'); + else + BT_ASSERT(false && "not implemented"); + + text.append(decodeStrongs(v)); + } + else if ((*it).second.contains("sword:")) + { + //text.append("Not implemented yet."); + } + else + BT_ASSERT(false); /// \todo Why is this here? + default: + continue; + }; + } + + return formatInfo(text); +} + +QString formatInfo(QString const & info, QString const & lang) { + CDisplayTemplateMgr *mgr = CDisplayTemplateMgr::instance(); + BT_ASSERT(mgr); + + CDisplayTemplateMgr::Settings settings; + settings.pageCSS_ID = "infodisplay"; + + QString div = "<div class=\"infodisplay\""; + if (!lang.isEmpty()) + div.append(" lang=\"").append(lang).append("\""); + div.append(">"); + + QString content(mgr->fillTemplate(CDisplayTemplateMgr::activeTemplateName(), + div + info + "</div>", + settings)); + return content; +} + + +QString decodeAbbreviation(QString const & data) { + // QStringList strongs = QStringList::split("|", data); + return QString("<div class=\"abbreviation\"><h3>%1: %2</h3><p>%3</p></div>") + .arg(QObject::tr("Abbreviation")) + .arg("text") + .arg(data); +} + +QString decodeCrossReference(QString const & data, BtConstModuleList const & modules) { + if (data.isEmpty()) + return QString("<div class=\"crossrefinfo\"><h3>%1</h3></div>") + .arg(QObject::tr("Cross references")); + + // qWarning("setting crossref %s", data.latin1()); + + DisplayOptions dispOpts; + dispOpts.lineBreaks = false; + dispOpts.verseNumbers = true; + + FilterOptions filterOpts; + CrossRefRendering renderer(dispOpts, filterOpts); + CTextRendering::KeyTree tree; + + // const bool isBible = true; + const CSwordModuleInfo * module(nullptr); + + // a prefixed module gives the module to look into + QRegExp re("^[^ ]+:"); + // re.setMinimal(true); + int pos = re.indexIn(data); + if (pos != -1) + pos += re.matchedLength() - 1; + + if (pos > 0) { + const QString moduleName = data.left(pos); + // qWarning("found module %s", moduleName.latin1()); + module = CSwordBackend::instance()->findModuleByName(moduleName); + } + + if (!module) + module = btConfig().getDefaultSwordModuleByType("standardBible"); + + if (!module && modules.size() > 0) + module = modules.at(0); + + // BT_ASSERT(module); // why? the existense of the module is tested later + CTextRendering::KeyTreeItem::Settings settings( + false, + CTextRendering::KeyTreeItem::Settings::CompleteShort + ); + + if (module && (module->type() == CSwordModuleInfo::Bible)) { + sword::VerseKey vk; + sword::ListKey refs = vk.parseVerseList((const char*) data.mid((pos == -1) ? 0 : pos + 1).toUtf8(), "Gen 1:1", true); + + for (int i = 0; i < refs.getCount(); i++) { + sword::SWKey * const key = refs.getElement(i); + BT_ASSERT(key); + sword::VerseKey * const vk = dynamic_cast<sword::VerseKey*>(key); + + if (vk && vk->isBoundSet()) { // render a range of keys + tree.append(new CTextRendering::KeyTreeItem( + QString::fromUtf8(vk->getLowerBound().getText()), + QString::fromUtf8(vk->getUpperBound().getText()), + module, + settings + )); + } else { + tree.append(new CTextRendering::KeyTreeItem( + QString::fromUtf8(key->getText()), + QString::fromUtf8(key->getText()), + module, + settings + )); + } + } + } else if (module) { + tree.append(new CTextRendering::KeyTreeItem(data.mid((pos == -1) + ? 0 + : pos + 1), + module, + settings)); + } + + // qWarning("rendered the tree: %s", renderer.renderKeyTree(tree).latin1()); + // spanns containing rtl text need dir=rtl on their parent tag to be aligned properly + QString lang = "en"; // default english + if (module) + lang = module->language()->abbrev(); + + return QString("<div class=\"crossrefinfo\" lang=\"%1\"><h3>%2</h3><div class=\"para\" dir=\"%3\">%4</div></div>") + .arg(lang) + .arg(QObject::tr("Cross references")) + .arg(module ? ((module->textDirection() == CSwordModuleInfo::LeftToRight) ? "ltr" : "rtl") : "") + .arg(renderer.renderKeyTree(tree)); +} + +/*! + \fn CInfoDisplay::decodeFootnote(QString const & data) + */ +QString decodeFootnote(QString const & data) { + QStringList list = data.split("/"); + BT_ASSERT(list.count() >= 3); + if (!list.count()) + return QString::null; + + FilterOptions filterOpts; + filterOpts.footnotes = true; + CSwordBackend::instance()->setFilterOptions(filterOpts); + + const QString modulename = list.first(); + const QString swordFootnote = list.last(); + + // remove the first and the last and then rejoin it to get a key + list.pop_back(); + list.pop_front(); + const QString keyname = list.join("/"); + + CSwordModuleInfo * const module = CSwordBackend::instance()->findModuleByName(modulename); + if (!module) + return QString::null; + + QSharedPointer<CSwordKey> key(CSwordKey::createInstance(module)); + key->setKey(keyname); + key->renderedText(CSwordKey::ProcessEntryAttributesOnly); // force entryAttributes + + auto & m = module->module(); + const char * const note = + m.getEntryAttributes() + ["Footnote"][swordFootnote.toLatin1().data()]["body"].c_str(); + + QString text = module->isUnicode() ? QString::fromUtf8(note) : QString(note); + text = QString::fromUtf8(m.renderText( + module->isUnicode() + ? static_cast<const char *>(text.toUtf8()) + : static_cast<const char *>(text.toLatin1()))); + + return QString("<div class=\"footnoteinfo\" lang=\"%1\"><h3>%2</h3><p>%3</p></div>") + .arg(module->language()->abbrev()) + .arg(QObject::tr("Footnote")) + .arg(text); +} + +QString decodeStrongs(QString const & data) { + QStringList strongs = data.split("|"); + QString ret; + + QStringList::const_iterator end = strongs.end(); + for (QStringList::const_iterator it = strongs.begin(); it != end; ++it) { + CSwordModuleInfo * const module = btConfig().getDefaultSwordModuleByType + ( + ((*it).left(1) == QString("H")) ? + "standardHebrewStrongsLexicon" : + "standardGreekStrongsLexicon" + ); + + QString text; + if (module) { + QSharedPointer<CSwordKey> key(CSwordKey::createInstance(module)); + key->setKey((*it).mid(1)); // skip H or G (language sign), will have to change later if we have better modules + text = key->renderedText(); + } + //if the module could not be found just display an empty lemma info + + QString lang = "en"; // default english + if (module) + lang = module->language()->abbrev(); + ret.append( + QString("<div class=\"strongsinfo\" lang=\"%1\"><h3>%2: %3</h3><p>%4</p></div>") + .arg(lang) + .arg(QObject::tr("Strongs")) + .arg(*it) + .arg(text) + ); + } + + return ret; +} + +QString decodeMorph(QString const & data) { + QStringList morphs = data.split("|"); + QString ret; + + Q_FOREACH (QString morph, morphs) { + //qDebug() << "CInfoDisplay::decodeMorph, morph: " << morph; + CSwordModuleInfo * module = nullptr; + bool skipFirstChar = false; + QString value = ""; + QString valueClass = ""; + + int valStart = morph.indexOf(':'); + if (valStart > -1) { + valueClass = morph.mid(0, valStart); + // qDebug() << "valueClass: " << valueClass; + module = CSwordBackend::instance()->findModuleByName(valueClass); + } + value = morph.mid(valStart + 1); //works for prepended module and without (-1 +1 == 0). + + // if we don't have a class assigned or desired one isn't installed... + if (!module) { + // Morphs usually don't have [GH] prepended, but some old OLB + // codes do. We should check if we're digit after first char + // to better guess this. + if (value.size() > 1 && value.at(1).isDigit()) { + switch (value.at(0).toLatin1()) { + case 'G': + module = btConfig().getDefaultSwordModuleByType("standardGreekMorphLexicon"); + skipFirstChar = true; + break; + case 'H': + module = btConfig().getDefaultSwordModuleByType("standardHebrewMorphLexicon"); + skipFirstChar = true; + break; + default: + skipFirstChar = false; + /// \todo we can't tell here if it's a greek or hebrew moprh code, that's a problem we have to solve + // module = getBtConfig().getDefaultSwordModuleByType("standardGreekMorphLexicon"); + break; + } + } + //if it is still not set use the default + if (!module) + module = btConfig().getDefaultSwordModuleByType("standardGreekMorphLexicon"); + } + + QString text; + // BT_ASSERT(module); + if (module) { + QSharedPointer<CSwordKey> key(CSwordKey::createInstance(module)); + + // skip H or G (language sign) if we have to skip it + const bool isOk = key->setKey(skipFirstChar ? value.mid(1) : value); + // BT_ASSERT(isOk); + if (!isOk) { // try to use the other morph lexicon, because this one failed with the current morph code + key->setModule(btConfig().getDefaultSwordModuleByType("standardHebrewMorphLexicon")); /// \todo: what if the module doesn't exist? + key->setKey(skipFirstChar ? value.mid(1) : value); + } + + text = key->renderedText(); + } + + // if the module wasn't found just display an empty morph info + QString lang = "en"; // default to english + if (module) + lang = module->language()->abbrev(); + ret.append(QString("<div class=\"morphinfo\" lang=\"%1\"><h3>%2: %3</h3><p>%4</p></div>") + .arg(lang) + .arg(QObject::tr("Morphology")) + .arg(value) + .arg(text) + ); + } + + return ret; +} + +QString getWordTranslation(QString const & data) { + CSwordModuleInfo * const module = btConfig().getDefaultSwordModuleByType("standardLexicon"); + if (!module) + return QString::null; + + QSharedPointer<CSwordKey> key(CSwordKey::createInstance(module)); + key->setKey(data); + if (key->key().toUpper() != data.toUpper()) //key not present in the lexicon + return QString::null; + + return QString("<div class=\"translationinfo\" lang=\"%1\"><h3>%2: %3</h3><p>%4</p></div>") + .arg(module->language()->abbrev()) + .arg(QObject::tr("Word lookup")) + .arg(data) + .arg(key->renderedText()); +} + +} // namespace Rendering { diff --git a/src/backend/rendering/btinforendering.h b/src/backend/rendering/btinforendering.h new file mode 100644 index 0000000..c8452fb --- /dev/null +++ b/src/backend/rendering/btinforendering.h @@ -0,0 +1,63 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef BTINFORENDERING_H +#define BTINFORENDERING_H + + +#include <QList> +#include <QPair> +#include <QString> + +#include "../drivers/btmodulelist.h" + + +namespace Rendering { + +enum InfoType { + Abbreviation, + CrossReference, + Footnote, + Lemma, + Morph, + WordTranslation, + WordGloss, + Text, + Reference, // for rendering references + Key // sword key reference for commentary display +}; + +using InfoData = QPair<InfoType, QString>; +using ListInfoData = QList<InfoData>; + + +/** Parse string for attributes */ +ListInfoData detectInfo(QString const & data); + +/** Process list of InfoData and format all data into string */ +QString formatInfo(const ListInfoData & info, BtConstModuleList const & modules = BtConstModuleList()); +QString formatInfo(QString const & info, QString const & lang = QString()); + +QString decodeAbbreviation(QString const & data); + +/** +* \param modules render references to each Bible module in the list, if empty use standard Bible. +* If module was provided in reference (KJV:John.1.1) this parameter has no effect. +*/ +QString decodeCrossReference(QString const & data, BtConstModuleList const & modules = BtConstModuleList()); +QString decodeFootnote(QString const & data); +QString decodeStrongs(QString const & data); +QString decodeMorph(QString const & data); +QString getWordTranslation(QString const & data); + +} /* namespace Rendering { */ + +#endif // BTINFORENDERING_H diff --git a/src/backend/rendering/cbookdisplay.cpp b/src/backend/rendering/cbookdisplay.cpp index e139c6f..4e5a1dd 100644 --- a/src/backend/rendering/cbookdisplay.cpp +++ b/src/backend/rendering/cbookdisplay.cpp @@ -2,31 +2,31 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ -#include "backend/rendering/cbookdisplay.h" +#include "cbookdisplay.h" -#include <QSharedPointer> +#include <memory> #include <QtAlgorithms> - -#include "backend/drivers/cswordbookmoduleinfo.h" -#include "backend/keys/cswordtreekey.h" -#include "backend/rendering/cdisplayrendering.h" +#include "../../util/btassert.h" +#include "../drivers/cswordbookmoduleinfo.h" +#include "../keys/cswordtreekey.h" +#include "cdisplayrendering.h" const QString Rendering::CBookDisplay::text( - const QList<const CSwordModuleInfo*> &modules, + const BtConstModuleList &modules, const QString &keyName, const DisplayOptions &displayOptions, const FilterOptions &filterOptions) { - typedef CSwordBookModuleInfo CSBMI; + using CSBMI = CSwordBookModuleInfo; const CSBMI* book = dynamic_cast<const CSBMI*>(modules.first()); - Q_ASSERT(book); + BT_ASSERT(book); DisplayOptions dOpts = displayOptions; dOpts.lineBreaks = true; //books should render with blocks, not with inlined sections @@ -38,9 +38,8 @@ const QString Rendering::CBookDisplay::text( // the number of levels which should be display together, 1 means display no entries together int displayLevel = book->config( CSwordModuleInfo::DisplayLevel ).toInt(); - QSharedPointer<CSwordTreeKey> key ( - dynamic_cast<CSwordTreeKey*>( CSwordKey::createInstance(book) ) - ); + std::unique_ptr<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(); @@ -110,7 +109,7 @@ const QString Rendering::CBookDisplay::text( //const bool hasToplevelText = !key->strippedText().isEmpty(); key->firstChild(); //go to the first sibling on the same level - setupRenderTree(key.data(), &tree, keyName); + setupRenderTree(key.get(), &tree, keyName); const QString renderedText = render.renderKeyTree(tree); diff --git a/src/backend/rendering/cbookdisplay.h b/src/backend/rendering/cbookdisplay.h index 6ed1bba..1a72e1e 100644 --- a/src/backend/rendering/cbookdisplay.h +++ b/src/backend/rendering/cbookdisplay.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -12,9 +12,9 @@ #ifndef RENDERINGCBOOKDISPLAY_H #define RENDERINGCBOOKDISPLAY_H -#include "backend/rendering/centrydisplay.h" +#include "centrydisplay.h" -#include "backend/rendering/ctextrendering.h" +#include "ctextrendering.h" class CSwordTreeKey; @@ -31,10 +31,10 @@ class CBookDisplay: public CEntryDisplay { public: /* Methods: */ - virtual const QString text(const QList<const CSwordModuleInfo*> &modules, - const QString &key, - const DisplayOptions &displayOptions, - const FilterOptions &filterOptions); + const QString text(const BtConstModuleList &modules, + const QString &key, + const DisplayOptions &displayOptions, + const FilterOptions &filterOptions) override; protected: /* Methods: */ diff --git a/src/backend/rendering/cchapterdisplay.cpp b/src/backend/rendering/cchapterdisplay.cpp index e4fd1a1..a5cb55a 100644 --- a/src/backend/rendering/cchapterdisplay.cpp +++ b/src/backend/rendering/cchapterdisplay.cpp @@ -2,32 +2,34 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ -#include "backend/rendering/cchapterdisplay.h" +#include "cchapterdisplay.h" -#include "backend/drivers/cswordbiblemoduleinfo.h" -#include "backend/keys/cswordversekey.h" -#include "backend/rendering/cdisplayrendering.h" +#include "../../util/btassert.h" +#include "../drivers/cswordbiblemoduleinfo.h" +#include "../keys/cswordversekey.h" +#include "cdisplayrendering.h" const QString Rendering::CChapterDisplay::text( - const QList<const CSwordModuleInfo*> &modules, + const BtConstModuleList &modules, const QString &keyName, const DisplayOptions &displayOptions, const FilterOptions &filterOptions) { - typedef CSwordBibleModuleInfo CSBMI; + using CSBMI = CSwordBibleModuleInfo; - Q_ASSERT( modules.count() >= 1 ); - Q_ASSERT( !keyName.isEmpty() ); + BT_ASSERT(modules.count() >= 1); + BT_ASSERT(!keyName.isEmpty()); const CSwordModuleInfo *module = modules.first(); - if (modules.count() == 1) module->module()->setSkipConsecutiveLinks( true ); //skip empty, linked verses + if (modules.count() == 1) + module->module().setSkipConsecutiveLinks( true ); //skip empty, linked verses CTextRendering::KeyTreeItem::Settings settings; settings.keyRenderingFace = @@ -39,12 +41,14 @@ const QString Rendering::CChapterDisplay::text( QString endKey = startKey; //check whether there's an intro we have to include - Q_ASSERT((module->type() == CSwordModuleInfo::Bible)); + BT_ASSERT((module->type() == CSwordModuleInfo::Bible)); if (module->type() == CSwordModuleInfo::Bible) { - ((sword::VerseKey*)(module->module()->getKey()))->setIntros(true); //HACK: enable headings for VerseKeys + // HACK: enable headings for VerseKeys: + static_cast<sword::VerseKey *>(module->module().getKey()) + ->setIntros(true); - Q_ASSERT(dynamic_cast<const CSBMI*>(module) != 0); + BT_ASSERT(dynamic_cast<CSBMI const *>(module)); const CSBMI *bible = static_cast<const CSBMI*>(module); CSwordVerseKey k1(module); diff --git a/src/backend/rendering/cchapterdisplay.h b/src/backend/rendering/cchapterdisplay.h index b19f103..9037b6b 100644 --- a/src/backend/rendering/cchapterdisplay.h +++ b/src/backend/rendering/cchapterdisplay.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -12,7 +12,7 @@ #ifndef RENDERINGCCHAPTERDISPLAY_H #define RENDERINGCCHAPTERDISPLAY_H -#include "backend/rendering/centrydisplay.h" +#include "centrydisplay.h" namespace Rendering { @@ -27,10 +27,10 @@ class CChapterDisplay: public CEntryDisplay { public: /* Methods: */ - virtual const QString text(const QList<const CSwordModuleInfo*> &modules, - const QString &key, - const DisplayOptions &displayOptions, - const FilterOptions &filterOptions); + const QString text(const BtConstModuleList &modules, + const QString &key, + const DisplayOptions &displayOptions, + const FilterOptions &filterOptions) override; }; /* class CChapterDisplay */ diff --git a/src/backend/rendering/cdisplayrendering.cpp b/src/backend/rendering/cdisplayrendering.cpp index cbcc046..283336a 100644 --- a/src/backend/rendering/cdisplayrendering.cpp +++ b/src/backend/rendering/cdisplayrendering.cpp @@ -2,20 +2,20 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ -#include "backend/rendering/cdisplayrendering.h" +#include "cdisplayrendering.h" -#include <QString> #include <QRegExp> -#include "backend/keys/cswordkey.h" -#include "backend/keys/cswordversekey.h" -#include "backend/managers/cdisplaytemplatemgr.h" -#include "backend/managers/referencemanager.h" -#include "backend/config/btconfig.h" +#include <QString> +#include "../config/btconfig.h" +#include "../keys/cswordkey.h" +#include "../keys/cswordversekey.h" +#include "../managers/cdisplaytemplatemgr.h" +#include "../managers/referencemanager.h" namespace Rendering { @@ -37,7 +37,7 @@ QString CDisplayRendering::entryLink(const KeyTreeItem &item, vk.setIntros(true); if (isBible) { - vk.setKey(item.key()); + vk.setKey(item.mappedKey() ? item.mappedKey()->key() : item.key()); } if (isBible && (vk.getVerse() == 0)) { @@ -51,16 +51,30 @@ QString CDisplayRendering::entryLink(const KeyTreeItem &item, break; //no key is valid for all modules } - case KeyTreeItem::Settings::CompleteShort: { - if (isBible) { - linkText = QString::fromUtf8(vk.getShortText()); - break; - } + case KeyTreeItem::Settings::ExpandedShort: { + if (isBible) { + linkText = module->name() + ':' + QString::fromUtf8(vk.getShortText()); + break; + } + } - //fall through for non-Bible modules + case KeyTreeItem::Settings::CompleteShort: { + if (isBible) { + linkText = QString::fromUtf8(vk.getShortText()); + break; } - case KeyTreeItem::Settings::CompleteLong: { + //fall through for non-Bible modules + } + + case KeyTreeItem::Settings::ExpandedLong: { + if (isBible) { + linkText = QString("%1 (%2)").arg(vk.key()).arg(module->name()); + break; + } + } + + case KeyTreeItem::Settings::CompleteLong: { if (isBible) { linkText = vk.key(); break; @@ -69,14 +83,38 @@ QString CDisplayRendering::entryLink(const KeyTreeItem &item, //fall through for non-Bible modules } - case KeyTreeItem::Settings::SimpleKey: { + case KeyTreeItem::Settings::SimpleKey: if (isBible) { - linkText = QString::number(vk.getVerse()); + if(item.mappedKey() != nullptr) { + CSwordVerseKey baseKey(*item.modules().begin()); + baseKey.setKey(item.key()); + + if (vk.book() != baseKey.book()) { + linkText = QString::fromUtf8(vk.getShortText()); + } else if (vk.getChapter() != baseKey.getChapter()) { + linkText = QString("%1:%2").arg(vk.getChapter()).arg(vk.getVerse()); + } else { + linkText = QString::number(vk.getVerse()); + } + + if(vk.isBoundSet()) { + linkText += "-"; + sword::VerseKey const upper = vk.getUpperBound(); + sword::VerseKey const lower = vk.getLowerBound(); + if (upper.getBook() != lower.getBook()) { + linkText += QString::fromUtf8(upper.getShortText()); + } else if(upper.getChapter() != lower.getChapter()) { + linkText += QString("%1:%2").arg(upper.getChapter()) + .arg(lower.getVerse()); + } else { + linkText += QString::number(upper.getVerse()); + } + } + } else { + linkText = QString::number(vk.getVerse()); + } break; - } - - //fall through for non-Bible modules - } + } // else fall through for non-Bible modules default: { //default behaviour to return the passed key linkText = item.key(); @@ -107,7 +145,7 @@ QString CDisplayRendering::keyToHTMLAnchor(const QString& key) { } QString CDisplayRendering::finishText(const QString &text, const KeyTree &tree) { - QList<const CSwordModuleInfo*> modules = collectModules(tree); + BtConstModuleList modules = collectModules(tree); //marking words is very slow, we have to find a better solution @@ -144,7 +182,7 @@ QString CDisplayRendering::finishText(const QString &text, const KeyTree &tree) CDisplayTemplateMgr *tMgr = CDisplayTemplateMgr::instance(); - //Q_ASSERT(modules.count() >= 1); + //BT_ASSERT(modules.count() >= 1); CDisplayTemplateMgr::Settings settings; settings.modules = modules; diff --git a/src/backend/rendering/cdisplayrendering.h b/src/backend/rendering/cdisplayrendering.h index da87b79..bfb0339 100644 --- a/src/backend/rendering/cdisplayrendering.h +++ b/src/backend/rendering/cdisplayrendering.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -12,8 +12,9 @@ #ifndef RENDERINGCDISPLAYRENDERING_H #define RENDERINGCDISPLAYRENDERING_H -#include "backend/rendering/chtmlexportrendering.h" -#include "backend/config/btconfig.h" +#include "chtmlexportrendering.h" + +#include "../config/btconfig.h" namespace Rendering { @@ -35,10 +36,10 @@ class CDisplayRendering : public CHTMLExportRendering { protected: /* Methods: */ - virtual QString entryLink(const KeyTreeItem &item, - const CSwordModuleInfo * module); + QString entryLink(const KeyTreeItem &item, + const CSwordModuleInfo * module) override; - virtual QString finishText(const QString &text, const KeyTree &tree); + QString finishText(const QString &text, const KeyTree &tree) override; }; /* class CDisplayRendering */ diff --git a/src/backend/rendering/centrydisplay.cpp b/src/backend/rendering/centrydisplay.cpp index 3dbe63f..bed32ac 100644 --- a/src/backend/rendering/centrydisplay.cpp +++ b/src/backend/rendering/centrydisplay.cpp @@ -2,44 +2,59 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ -#include "backend/rendering/centrydisplay.h" +#include "centrydisplay.h" #include <QApplication> #include <QRegExp> -#include "backend/drivers/cswordbookmoduleinfo.h" -#include "backend/keys/cswordkey.h" -#include "backend/keys/cswordversekey.h" -#include "backend/managers/cdisplaytemplatemgr.h" -#include "backend/managers/referencemanager.h" -#include "backend/rendering/cdisplayrendering.h" -#include "backend/rendering/ctextrendering.h" +#include "../drivers/cswordbookmoduleinfo.h" +#include "../keys/cswordkey.h" +#include "../keys/cswordversekey.h" +#include "../managers/cdisplaytemplatemgr.h" +#include "../managers/referencemanager.h" +#include "cdisplayrendering.h" +#include "ctextrendering.h" using namespace Rendering; const QString CEntryDisplay::text( - const QList<const CSwordModuleInfo*> &modules, + const BtConstModuleList &modules, const QString &keyName, const DisplayOptions &displayOptions, - const FilterOptions &filterOptions) -{ + const FilterOptions &filterOptions) { + return textKeyRendering(modules, keyName, displayOptions, filterOptions, + CTextRendering::KeyTreeItem::Settings::CompleteShort); +} + +const QString CEntryDisplay::textKeyRendering( + const BtConstModuleList &modules, + const QString &keyName, + const DisplayOptions &displayOptions, + const FilterOptions &filterOptions, + CTextRendering::KeyTreeItem::Settings::KeyRenderingFace keyRendering) { + + if (keyName.isEmpty()) + return QString(""); + CDisplayRendering render(displayOptions, filterOptions); //no highlighted key and no extra key link in the text - CTextRendering::KeyTreeItem::Settings normal_settings(false, CTextRendering::KeyTreeItem::Settings::CompleteShort); + CTextRendering::KeyTreeItem::Settings normal_settings(false, keyRendering); const CSwordModuleInfo *module = modules.first(); Rendering::CTextRendering::KeyTree tree; //in Bibles and Commentaries we need to check if 0:0 and X:0 contain something if (module->type() == CSwordModuleInfo::Bible || module->type() == CSwordModuleInfo::Commentary) { - ((sword::VerseKey*)(module->module()->getKey()))->setIntros(true); //HACK: enable headings for VerseKeys + // HACK: enable headings for VerseKeys + static_cast<sword::VerseKey *>(module->module().getKey()) + ->setIntros(true); CSwordVerseKey k1(module); k1.setIntros(true); diff --git a/src/backend/rendering/centrydisplay.h b/src/backend/rendering/centrydisplay.h index 8773eb7..c482e9a 100644 --- a/src/backend/rendering/centrydisplay.h +++ b/src/backend/rendering/centrydisplay.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -13,18 +13,19 @@ #define CENTRYDISPLAY_H #include <QString> +#include "../drivers/btmodulelist.h" +#include "ctextrendering.h" // Sword includes: -#include <swdisp.h> #include <swmodule.h> -class CSwordModuleInfo; + struct DisplayOptions; struct FilterOptions; namespace Rendering { -class CEntryDisplay: public sword::SWDisplay { +class CEntryDisplay { public: /* Methods: */ @@ -32,12 +33,18 @@ class CEntryDisplay: public sword::SWDisplay { \returns the rendered text using the modules in the list and using the key parameter. */ - virtual const QString text(const QList<const CSwordModuleInfo*> &modules, + virtual const QString text(const BtConstModuleList &modules, const QString &key, const DisplayOptions &displayOptions, const FilterOptions &filterOptions); - virtual char display(sword::SWModule& mod) { (void)mod; return 'c';} + const QString textKeyRendering(const BtConstModuleList &modules, + const QString &key, + const DisplayOptions &displayOptions, + const FilterOptions &filterOptions, + CTextRendering::KeyTreeItem::Settings::KeyRenderingFace keyRendering); + + virtual char display(CSwordModuleInfo & mod) { (void)mod; return 'c';} }; /* class CEntryDisplay */ diff --git a/src/backend/rendering/chtmlexportrendering.cpp b/src/backend/rendering/chtmlexportrendering.cpp index 7c467b1..f9802db 100644 --- a/src/backend/rendering/chtmlexportrendering.cpp +++ b/src/backend/rendering/chtmlexportrendering.cpp @@ -2,105 +2,75 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ -#include "backend/rendering/chtmlexportrendering.h" +#include "chtmlexportrendering.h" -#include <QSharedPointer> +#include <memory> +#include "../../util/btassert.h" +#include "../drivers/cswordmoduleinfo.h" +#include "../keys/cswordkey.h" +#include "../keys/cswordversekey.h" +#include "../managers/cdisplaytemplatemgr.h" +#include "../managers/clanguagemgr.h" -#include "backend/drivers/cswordmoduleinfo.h" -#include "backend/keys/cswordkey.h" -#include "backend/keys/cswordversekey.h" -#include "backend/managers/cdisplaytemplatemgr.h" -#include "backend/managers/clanguagemgr.h" - - -#if 0 -#include <QDebug> - -namespace { - -/** Helper function to dump a verse with all its enty attributes. */ -void dumpEntryAttributes(sword::SWModule *module) { - qDebug() << "Attributes for key: " << module->getKeyText(); - sword::AttributeTypeList::iterator i1; - sword::AttributeList::iterator i2; - sword::AttributeValue::iterator i3; - for (i1 = module->getEntryAttributes().begin(); i1 != module->getEntryAttributes().end(); i1++) { - qDebug() << "[ " << i1->first << " ]"; - for (i2 = i1->second.begin(); i2 != i1->second.end(); i2++) { - qDebug() << "\t[ " << i2->first << " ]"; - for (i3 = i2->second.begin(); i3 != i2->second.end(); i3++) { - qDebug() << "\t\t" << i3->first << " = " << i3->second; - } - } - } -} - -} // anonymous namespace -#endif namespace Rendering { CHTMLExportRendering::CHTMLExportRendering( bool addText, - const DisplayOptions &displayOptions, - const FilterOptions &filterOptions) + DisplayOptions const & displayOptions, + FilterOptions const & filterOptions) : m_displayOptions(displayOptions) , m_filterOptions(filterOptions) , m_addText(addText) -{ - // Intentionally empty -} - -QString CHTMLExportRendering::renderEntry(const KeyTreeItem& i, CSwordKey* k) { +{} +QString CHTMLExportRendering::renderEntry(KeyTreeItem const & i, CSwordKey * k) +{ if (i.hasAlternativeContent()) { QString ret = i.settings().highlight ? "<div class=\"currententry\">" : "<div class=\"entry\">"; ret.append(i.getAlternativeContent()); - // Q_ASSERT(i.hasChildItems()); - if (!i.childList()->isEmpty()) { - const KeyTree & tree = *i.childList(); + KeyTree const & tree = *i.childList(); - const QList<const CSwordModuleInfo*> modules = collectModules(tree); + BtConstModuleList const modules(collectModules(tree)); - if (modules.count() == 1) { //insert the direction into the surrounding div - ret.insert( 5, QString("dir=\"%1\" ").arg((modules.first()->textDirection() == CSwordModuleInfo::LeftToRight) ? "ltr" : "rtl" )); - } + if (modules.count() == 1) + // insert the direction into the surrounding div: + ret.insert(5, + QString("dir=\"%1\" ") + .arg(modules.first()->textDirectionAsHtml())); - Q_FOREACH (const KeyTreeItem * const item, tree) { + Q_FOREACH (KeyTreeItem const * const item, tree) ret.append(renderEntry(*item)); - } } ret.append("</div>"); - return ret; //WARNING: Return already here! + return ret; // WARNING: Return already here! } - const QList<const CSwordModuleInfo*> &modules(i.modules()); - if (modules.isEmpty()) { - return ""; //no module present for rendering - } + BtConstModuleList const & modules(i.modules()); + if (modules.isEmpty()) + return ""; // no module present for rendering - QSharedPointer<CSwordKey> scoped_key( !k ? CSwordKey::createInstance(modules.first()) : 0 ); - CSwordKey* key = k ? k : scoped_key.data(); - Q_ASSERT(key); + std::unique_ptr<CSwordKey> scoped_key( + !k ? CSwordKey::createInstance(modules.first()) : nullptr); + CSwordKey * const key = k ? k : scoped_key.get(); + BT_ASSERT(key); - CSwordVerseKey* myVK = dynamic_cast<CSwordVerseKey*>(key); - - if (myVK) { + CSwordVerseKey * const myVK = dynamic_cast<CSwordVerseKey *>(key); + if (myVK) myVK->setIntros(true); - } - QString renderedText( (modules.count() > 1) ? "\n\t\t<tr>\n" : "\n" ); + QString renderedText((modules.count() > 1) ? "\n\t\t<tr>\n" : "\n"); // Only insert the table stuff if we are displaying parallel. //declarations out of the loop for optimization @@ -110,113 +80,145 @@ QString CHTMLExportRendering::renderEntry(const KeyTreeItem& i, CSwordKey* k) { QString langAttr; QString key_renderedText; - QList<const CSwordModuleInfo*>::const_iterator end_modItr = modules.end(); + BtConstModuleList::const_iterator end_modItr = modules.end(); + + for (BtConstModuleList::const_iterator mod_Itr(modules.begin()); mod_Itr != end_modItr; ++mod_Itr) { + if (myVK) { + key->setModule(*modules.begin()); + key->setKey(i.key()); + + // this would change key position due to v11n translation + key->setModule(*mod_Itr); + } else { + key->setModule(*mod_Itr); + key->setKey(i.key()); + } + + // indicate that key was changed + i.setMappedKey(key->key() != i.key() ? key : nullptr); - for (QList<const CSwordModuleInfo*>::const_iterator mod_Itr(modules.begin()); mod_Itr != end_modItr; ++mod_Itr) { - key->setModule(*mod_Itr); - key->setKey(i.key()); isRTL = ((*mod_Itr)->textDirection() == CSwordModuleInfo::RightToLeft); entry = QString::null; + auto & swModule = (*mod_Itr)->module(); if ((*mod_Itr)->language()->isValid()) { langAttr = QString("xml:lang=\"") .append((*mod_Itr)->language()->abbrev()) .append("\" lang=\"") .append((*mod_Itr)->language()->abbrev()) .append("\""); - } - else { + } else { langAttr = QString("xml:lang=\"") - .append((*mod_Itr)->module()->getLanguage()) + .append(swModule.getLanguage()) .append("\" lang=\"") - .append((*mod_Itr)->module()->getLanguage()) + .append(swModule.getLanguage()) .append("\""); } - key_renderedText = key->renderedText(); + if (key->isValid()) { + key_renderedText = key->renderedText(); + + // if key was expanded + if (CSwordVerseKey const * const vk = + dynamic_cast<CSwordVerseKey *>(key)) + { + if (vk->isBoundSet()) { + CSwordVerseKey pk(*vk); + for (int i = vk->getLowerBound().getIndex() + 1; + i <= vk->getUpperBound().getIndex(); + ++i) + { + key_renderedText += " "; + pk.setIndex(i); + key_renderedText += pk.renderedText(); + } + } + } + } else { + key_renderedText = "<span class=\"inactive\">—</span>"; + } if (m_filterOptions.headings) { // only process EntryAttributes, do not render, this might destroy the EntryAttributes again - (*mod_Itr)->module()->renderText(0, -1, 0); + swModule.renderText(nullptr, -1, 0); sword::AttributeValue::const_iterator it = - (*mod_Itr)->module()->getEntryAttributes()["Heading"]["Preverse"].begin(); - const sword::AttributeValue::const_iterator end = - (*mod_Itr)->module()->getEntryAttributes()["Heading"]["Preverse"].end(); + swModule.getEntryAttributes()["Heading"]["Preverse"].begin(); + sword::AttributeValue::const_iterator const end = + swModule.getEntryAttributes()["Heading"]["Preverse"].end(); for (; it != end; ++it) { - QString unfiltered = QString::fromUtf8(it->second.c_str()); + QString unfiltered(QString::fromUtf8(it->second.c_str())); /// \todo This is only a preliminary workaround to strip the tags: - QRegExp filter("(.*)<title[^>]*>(.*)</title>(.*)"); - while(filter.indexIn(unfiltered) >= 0) { - unfiltered = filter.cap(1) + filter.cap(2) + filter.cap(3); + { + static QRegExp const staticFilter( + "(.*)<title[^>]*>(.*)</title>(.*)"); + QRegExp filter(staticFilter); + while (filter.indexIn(unfiltered) >= 0) + unfiltered = filter.cap(1) + filter.cap(2) + filter.cap(3); } - // Fiter out offending self-closing div tags, which are bad HTML - QRegExp ofilter("(.*)<div[^>]*/>(.*)"); - while(ofilter.indexIn(unfiltered) >= 0) { - unfiltered = ofilter.cap(1) + ofilter.cap(2); + + // Filter out offending self-closing div tags, which are bad HTML + { + static QRegExp const staticFilter("(.*)<div[^>]*/>(.*)"); + QRegExp filter(staticFilter); + while (filter.indexIn(unfiltered) >= 0) + unfiltered = filter.cap(1) + filter.cap(2); } + preverseHeading = unfiltered; /// \todo Take care of the heading type! if (!preverseHeading.isEmpty()) { entry.append("<div ") - .append(langAttr) - .append(" class=\"sectiontitle\">") - .append(preverseHeading) - .append("</div>"); + .append(langAttr) + .append(" class=\"sectiontitle\">") + .append(preverseHeading) + .append("</div>"); } } } - entry.append(m_displayOptions.lineBreaks ? "<div " : "<div style=\"display: inline;\" "); - - if (modules.count() == 1) { //insert only the class if we're not in a td - entry.append( i.settings().highlight ? "class=\"currententry\" " : "class=\"entry\" " ); - } + entry.append(m_displayOptions.lineBreaks ? "<div class=\"" : "<div class=\"inline "); + if (modules.count() == 1) //insert only the class if we're not in a td + entry.append( i.settings().highlight ? "currententry " : "entry " ); + entry.append("\""); entry.append(langAttr).append(isRTL ? " dir=\"rtl\">" : " dir=\"ltr\">"); //keys should normally be left-to-right, but this doesn't apply in all cases - entry.append("<span class=\"entryname\" dir=\"ltr\">").append(entryLink(i, *mod_Itr)).append("</span>"); + if(key->isValid()) + entry.append("<span class=\"entryname\" dir=\"ltr\">").append(entryLink(i, *mod_Itr)).append("</span>"); - if (m_addText) { - //entry.append( QString::fromLatin1("<span %1>%2</span>").arg(langAttr).arg(key_renderedText) ); - entry.append( key_renderedText ); - } + if (m_addText) + entry.append(key_renderedText); - if (!i.childList()->isEmpty()) { - KeyTree* tree(i.childList()); - - Q_FOREACH (const KeyTreeItem * const c, *tree) { - entry.append( renderEntry(*c) ); - } - } + if (!i.childList()->isEmpty()) + Q_FOREACH (KeyTreeItem const * const c, *(i.childList())) + entry.append(renderEntry(*c)); entry.append("</div>"); if (modules.count() == 1) { - renderedText.append( "\t\t" ).append( entry ).append("\n"); - } - else { + renderedText.append("\t\t").append(entry).append("\n"); + } else { renderedText.append("\t\t<td class=\"") - .append(i.settings().highlight ? "currententry" : "entry") - .append("\" ") - .append(langAttr) - .append(" dir=\"") - .append(isRTL ? "rtl" : "ltr") - .append("\">\n") - .append( "\t\t\t" ).append( entry ).append("\n") - .append("\t\t</td>\n"); + .append(i.settings().highlight ? "currententry" : "entry") + .append("\" ") + .append(langAttr) + .append(" dir=\"") + .append(isRTL ? "rtl" : "ltr") + .append("\">\n") + .append( "\t\t\t" ).append( entry ).append("\n") + .append("\t\t</td>\n"); } } - if (modules.count() > 1) { + if (modules.count() > 1) renderedText.append("\t\t</tr>\n"); - } // qDebug("CHTMLExportRendering: %s", renderedText.latin1()); return renderedText; @@ -224,37 +226,34 @@ QString CHTMLExportRendering::renderEntry(const KeyTreeItem& i, CSwordKey* k) { void CHTMLExportRendering::initRendering() { //CSwordBackend::instance()()->setDisplayOptions( m_displayOptions ); - CSwordBackend::instance()->setFilterOptions( m_filterOptions ); + CSwordBackend::instance()->setFilterOptions(m_filterOptions); } -QString CHTMLExportRendering::finishText(const QString &text, const KeyTree &tree) { - typedef CDisplayTemplateMgr CDTM; - - CDTM::Settings settings; +QString CHTMLExportRendering::finishText(QString const & text, + KeyTree const & tree) +{ + CDisplayTemplateMgr::Settings settings; settings.modules = collectModules(tree); if (settings.modules.count() == 1) { - const CSwordModuleInfo * const firstModule = settings.modules.first(); - const CLanguageMgr::Language * const lang = firstModule->language(); + CSwordModuleInfo const * const firstModule = settings.modules.first(); + CLanguageMgr::Language const * const lang = firstModule->language(); settings.langAbbrev = lang->isValid() ? lang->abbrev() : "unknown"; settings.textDirection = firstModule->textDirection(); } else { settings.langAbbrev = "unknown"; } - return CDTM::instance()->fillTemplate(CDisplayTemplateMgr::activeTemplateName(), - text, - settings); + return CDisplayTemplateMgr::instance()->fillTemplate( + CDisplayTemplateMgr::activeTemplateName(), + text, + settings); } /*! \fn CHTMLExportRendering::entryLink( KeyTreeItem& item ) */ -QString CHTMLExportRendering::entryLink(const KeyTreeItem &item, - const CSwordModuleInfo * module) -{ - Q_UNUSED(module); - - return item.key(); -} +QString CHTMLExportRendering::entryLink(KeyTreeItem const & item, + CSwordModuleInfo const *) +{ return item.key(); } }//end of namespace "Rendering" diff --git a/src/backend/rendering/chtmlexportrendering.h b/src/backend/rendering/chtmlexportrendering.h index 51041a3..58a280b 100644 --- a/src/backend/rendering/chtmlexportrendering.h +++ b/src/backend/rendering/chtmlexportrendering.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -12,45 +12,45 @@ #ifndef RENDERINGCHTMLEXPORTRENDERING_H #define RENDERINGCHTMLEXPORTRENDERING_H -#include "backend/rendering/ctextrendering.h" +#include "ctextrendering.h" -#include "backend/config/btconfig.h" -#include "backend/managers/cswordbackend.h" -#include "btglobal.h" +#include "../btglobal.h" +#include "../config/btconfig.h" +#include "../managers/cswordbackend.h" namespace Rendering { /** - * This CTextRenerding implementation - * creates HTML specially made for export as HTML files. - * @short HTML rendering for export. - * @author The BibleTime team - */ + \brief Provides HTML rendering for export. + This CTextRenerding implementation creates HTML specially made for export as + HTML files. +*/ class CHTMLExportRendering: public CTextRendering { - public: /* Methods: */ +public: /* Methods: */ - CHTMLExportRendering( - bool addText, - const DisplayOptions &displayOptions = btConfig().getDisplayOptions(), - const FilterOptions &filterOptions = btConfig().getFilterOptions()); + CHTMLExportRendering( + bool addText, + DisplayOptions const & displayOptions = + btConfig().getDisplayOptions(), + FilterOptions const & filterOptions = + btConfig().getFilterOptions()); - ~CHTMLExportRendering() {}; +protected: /* Methods: */ - protected: /* Methods: */ + QString renderEntry(KeyTreeItem const & item, + CSwordKey * key = nullptr) override; + QString finishText(QString const & text, KeyTree const & tree) override; + virtual QString entryLink(KeyTreeItem const & item, + CSwordModuleInfo const * module); + void initRendering() override; - virtual QString renderEntry(const KeyTreeItem &item, CSwordKey * key = 0); - virtual QString finishText(const QString &text, const KeyTree &tree); - virtual QString entryLink(const KeyTreeItem &item, - const CSwordModuleInfo *module); - virtual void initRendering(); +protected: /* Fields: */ - protected: /* Fields: */ - - DisplayOptions m_displayOptions; - FilterOptions m_filterOptions; - bool m_addText; + DisplayOptions const m_displayOptions; + FilterOptions const m_filterOptions; + bool const m_addText; }; /* class CHTMLExportRendering */ diff --git a/src/backend/rendering/cplaintextexportrendering.cpp b/src/backend/rendering/cplaintextexportrendering.cpp index e462e53..f065503 100644 --- a/src/backend/rendering/cplaintextexportrendering.cpp +++ b/src/backend/rendering/cplaintextexportrendering.cpp @@ -2,15 +2,14 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ -#include "backend/rendering/cplaintextexportrendering.h" +#include "cplaintextexportrendering.h" -#include <QSharedPointer> -#include "backend/keys/cswordkey.h" +#include "../keys/cswordkey.h" namespace Rendering { @@ -32,12 +31,12 @@ QString CPlainTextExportRendering::renderEntry(const KeyTreeItem &i, if (!m_addText) return QString(i.key()).append("\n"); - const QList<const CSwordModuleInfo*> modules = i.modules(); + const BtConstModuleList modules = i.modules(); CSwordKey * key = CSwordKey::createInstance(modules.first()); QString renderedText = QString(i.key()).append(":\n"); QString entry; - Q_FOREACH(const CSwordModuleInfo * module, modules) { + Q_FOREACH(CSwordModuleInfo const * const module, modules) { key->setModule(module); key->setKey(i.key()); diff --git a/src/backend/rendering/cplaintextexportrendering.h b/src/backend/rendering/cplaintextexportrendering.h index 45ad8ac..f16a849 100644 --- a/src/backend/rendering/cplaintextexportrendering.h +++ b/src/backend/rendering/cplaintextexportrendering.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -12,8 +12,8 @@ #ifndef RENDERINGCPLAINTEXTEXPORTRENDERING_H #define RENDERINGCPLAINTEXTEXPORTRENDERING_H -#include "backend/rendering/chtmlexportrendering.h" -#include "backend/config/btconfig.h" +#include "../config/btconfig.h" +#include "chtmlexportrendering.h" namespace Rendering { @@ -34,8 +34,8 @@ class CPlainTextExportRendering: public CHTMLExportRendering { protected: /* Methods: */ - virtual QString renderEntry(const KeyTreeItem &item, CSwordKey * key = 0); - virtual QString finishText(const QString &text, const KeyTree &tree); + QString renderEntry(const KeyTreeItem &item, CSwordKey * key = nullptr) override; + QString finishText(const QString &text, const KeyTree &tree) override; }; /* class CPlainTextExportRendering */ diff --git a/src/backend/rendering/ctextrendering.cpp b/src/backend/rendering/ctextrendering.cpp index 409a601..8045cf3 100644 --- a/src/backend/rendering/ctextrendering.cpp +++ b/src/backend/rendering/ctextrendering.cpp @@ -2,23 +2,22 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ -#include "backend/rendering/ctextrendering.h" - -#include <QSharedPointer> +#include "ctextrendering.h" +#include <memory> #include <QRegExp> #include <QtAlgorithms> - -#include "backend/drivers/cswordmoduleinfo.h" -#include "backend/keys/cswordkey.h" -#include "backend/keys/cswordversekey.h" -#include "backend/managers/cdisplaytemplatemgr.h" -#include "backend/managers/referencemanager.h" +#include "../../util/btassert.h" +#include "../drivers/cswordmoduleinfo.h" +#include "../keys/cswordkey.h" +#include "../keys/cswordversekey.h" +#include "../managers/cdisplaytemplatemgr.h" +#include "../managers/referencemanager.h" // Sword includes: #include <swkey.h> @@ -49,7 +48,7 @@ CTextRendering::KeyTreeItem::KeyTreeItem(const QString &content, } CTextRendering::KeyTreeItem::KeyTreeItem(const QString &key, - const QList<const CSwordModuleInfo*> &mods, + const BtConstModuleList &mods, const Settings &settings) : m_settings( settings ), m_moduleList( mods ), @@ -93,7 +92,7 @@ CTextRendering::KeyTreeItem::KeyTreeItem(const QString &startKey, m_childList(), m_stopKey( stopKey ), m_alternativeContent( QString::null ) { - Q_ASSERT(module); + BT_ASSERT(module); m_moduleList.append(module); //use the start and stop key to ceate our child items @@ -156,12 +155,12 @@ CTextRendering::KeyTreeItem::KeyTreeItem(const QString &startKey, m_alternativeContent.prepend("<div class=\"rangeheading\" dir=\"ltr\">").append("</div>"); //insert the right tags } -QList<const CSwordModuleInfo*> CTextRendering::collectModules(const KeyTree &tree) const { +BtConstModuleList CTextRendering::collectModules(const KeyTree &tree) const { //collect all modules which are available and used by child items - QList<const CSwordModuleInfo*> modules; + BtConstModuleList modules; Q_FOREACH (const KeyTreeItem * const c, tree) { - Q_ASSERT(c != 0); + BT_ASSERT(c); Q_FOREACH (const CSwordModuleInfo * const mod, c->modules()) { if (!modules.contains(mod)) modules.append(mod); @@ -173,18 +172,17 @@ QList<const CSwordModuleInfo*> CTextRendering::collectModules(const KeyTree &tre const QString CTextRendering::renderKeyTree(const KeyTree &tree) { initRendering(); - const QList<const CSwordModuleInfo*> modules = collectModules(tree); + const BtConstModuleList modules = collectModules(tree); QString t; //optimization for entries with the same key - QSharedPointer<CSwordKey> key( - (modules.count() == 1) ? CSwordKey::createInstance(modules.first()) : 0 - ); if (modules.count() == 1) { //this optimizes the rendering, only one key created for all items + std::unique_ptr<CSwordKey> key( + CSwordKey::createInstance(modules.first())); Q_FOREACH (const KeyTreeItem * const c, tree) { key->setKey(c->key()); - t.append( renderEntry( *c, key.data()) ); + t.append(renderEntry(*c, key.get())); } } else { @@ -199,7 +197,7 @@ const QString CTextRendering::renderKeyTree(const KeyTree &tree) { const QString CTextRendering::renderKeyRange( const QString &start, const QString &stop, - const QList<const CSwordModuleInfo*> &modules, + const BtConstModuleList &modules, const QString &highlightKey, const KeyTreeItem::Settings &keySettings) { @@ -207,16 +205,16 @@ const QString CTextRendering::renderKeyRange( const CSwordModuleInfo *module = modules.first(); //qWarning( "renderKeyRange start %s stop %s \n", start.latin1(), stop.latin1() ); - QSharedPointer<CSwordKey> lowerBound( CSwordKey::createInstance(module) ); + std::unique_ptr<CSwordKey> lowerBound( CSwordKey::createInstance(module) ); lowerBound->setKey(start); - QSharedPointer<CSwordKey> upperBound( CSwordKey::createInstance(module) ); + std::unique_ptr<CSwordKey> upperBound( CSwordKey::createInstance(module) ); upperBound->setKey(stop); - sword::SWKey* sw_start = dynamic_cast<sword::SWKey*>(lowerBound.data()); - sword::SWKey* sw_stop = dynamic_cast<sword::SWKey*>(upperBound.data()); + sword::SWKey* sw_start = dynamic_cast<sword::SWKey*>(lowerBound.get()); + sword::SWKey* sw_stop = dynamic_cast<sword::SWKey*>(upperBound.get()); - Q_ASSERT((*sw_start == *sw_stop) || (*sw_start < *sw_stop)); + BT_ASSERT((*sw_start == *sw_stop) || (*sw_start < *sw_stop)); if (*sw_start == *sw_stop) { //same key, render single key return renderSingleKey(lowerBound->key(), modules); @@ -225,11 +223,11 @@ const QString CTextRendering::renderKeyRange( KeyTree tree; KeyTreeItem::Settings settings = keySettings; - CSwordVerseKey* vk_start = dynamic_cast<CSwordVerseKey*>(lowerBound.data()); - Q_ASSERT(vk_start); + CSwordVerseKey* vk_start = dynamic_cast<CSwordVerseKey*>(lowerBound.get()); + BT_ASSERT(vk_start); - CSwordVerseKey* vk_stop = dynamic_cast<CSwordVerseKey*>(upperBound.data()); - Q_ASSERT(vk_stop); + CSwordVerseKey* vk_stop = dynamic_cast<CSwordVerseKey*>(upperBound.get()); + BT_ASSERT(vk_stop); while ((*vk_start < *vk_stop) || (*vk_start == *vk_stop)) { @@ -262,7 +260,7 @@ const QString CTextRendering::renderKeyRange( const QString CTextRendering::renderSingleKey( const QString &key, - const QList<const CSwordModuleInfo*> &modules, + const BtConstModuleList &modules, const KeyTreeItem::Settings &settings) { KeyTree tree; diff --git a/src/backend/rendering/ctextrendering.h b/src/backend/rendering/ctextrendering.h index c62a877..bb38cc9 100644 --- a/src/backend/rendering/ctextrendering.h +++ b/src/backend/rendering/ctextrendering.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -16,9 +16,10 @@ #include <QSharedPointer> #include <QString> +#include "../drivers/btmodulelist.h" + class CSwordKey; -class CSwordModuleInfo; namespace Rendering { @@ -45,7 +46,7 @@ class CTextRendering { inline operator const KeyTreeItem * () const { return data(); } }; - typedef QList<KeyTreeSharedPointer> KeyTree; + using KeyTree = QList<KeyTreeSharedPointer>; class KeyTreeItem { @@ -57,7 +58,9 @@ class CTextRendering { NoKey, //< means no key shown at all SimpleKey, //< means only versenumber or only lexicon entry name CompleteShort, //< means key like "Gen 1:1" - CompleteLong //< means "Genesis 1:1" + CompleteLong, //< means "Genesis 1:1" + ExpandedShort, // means "KJV:Gen 1:1" + ExpandedLong // means "Genesis 1:1 (KJV)" }; Settings(const bool highlight = false, @@ -78,7 +81,7 @@ class CTextRendering { const Settings &settings); KeyTreeItem(const QString &key, - const QList<const CSwordModuleInfo*> &modules, + const BtConstModuleList &modules, const Settings &settings); KeyTreeItem(const QString &startKey, @@ -102,7 +105,7 @@ class CTextRendering { return !m_alternativeContent.isNull(); } - inline const QList<const CSwordModuleInfo*>& modules() const { + inline const BtConstModuleList& modules() const { return m_moduleList; } @@ -118,6 +121,14 @@ class CTextRendering { return &m_childList; } + inline void setMappedKey(CSwordKey const * key) const { + m_mappedKey = key; + } + + inline CSwordKey const * mappedKey() const { + return m_mappedKey; + } + protected: /* Methods: */ KeyTreeItem(); @@ -125,8 +136,9 @@ class CTextRendering { private: /* Fields: */ Settings m_settings; - QList<const CSwordModuleInfo*> m_moduleList; + BtConstModuleList m_moduleList; QString m_key; + mutable CSwordKey const * m_mappedKey; mutable KeyTree m_childList; QString m_stopKey; @@ -143,19 +155,19 @@ class CTextRendering { const QString renderKeyRange( const QString &start, const QString &stop, - const QList<const CSwordModuleInfo*> &modules, + const BtConstModuleList &modules, const QString &hightlightKey = QString::null, const KeyTreeItem::Settings &settings = KeyTreeItem::Settings()); const QString renderSingleKey( const QString &key, - const QList<const CSwordModuleInfo*> &modules, + const BtConstModuleList &modules, const KeyTreeItem::Settings &settings = KeyTreeItem::Settings()); protected: /* Methods: */ - QList<const CSwordModuleInfo*> collectModules(const KeyTree &tree) const; - virtual QString renderEntry(const KeyTreeItem &item, CSwordKey * key = 0) = 0; + BtConstModuleList collectModules(const KeyTree &tree) const; + virtual QString renderEntry(const KeyTreeItem &item, CSwordKey * key = nullptr) = 0; virtual QString finishText(const QString &text, const KeyTree &tree) = 0; virtual void initRendering() = 0; diff --git a/src/bibletime.cpp b/src/bibletime.cpp index 95461e5..2c60cba 100644 --- a/src/bibletime.cpp +++ b/src/bibletime.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -10,6 +10,7 @@ #include "bibletime.h" #include <cstdlib> +#include <exception> #include <QAction> #include <QApplication> #include <QCloseEvent> @@ -31,28 +32,33 @@ #include "frontend/cmdiarea.h" #include "frontend/display/btfindwidget.h" #include "frontend/displaywindow/btactioncollection.h" +#include "frontend/displaywindow/cbiblereadwindow.h" +#include "frontend/displaywindow/cbookreadwindow.h" +#include "frontend/displaywindow/ccommentaryreadwindow.h" #include "frontend/displaywindow/cdisplaywindow.h" -#include "frontend/displaywindow/cdisplaywindowfactory.h" +#include "frontend/displaywindow/chtmlwritewindow.h" +#include "frontend/displaywindow/clexiconreadwindow.h" +#include "frontend/displaywindow/cplainwritewindow.h" #include "frontend/displaywindow/creadwindow.h" #include "frontend/keychooser/ckeychooser.h" #include "frontend/messagedialog.h" #include "frontend/searchdialog/csearchdialog.h" +#include "util/btassert.h" #include "util/cresmgr.h" #include "util/directory.h" -#include "util/geticon.h" -BibleTime *BibleTime::m_instance = 0; +BibleTime *BibleTime::m_instance = nullptr; BibleTime::BibleTime(QWidget *parent, Qt::WindowFlags flags) : QMainWindow(parent, flags) { namespace DU = util::directory; - Q_ASSERT(m_instance == 0); + BT_ASSERT(!m_instance); m_instance = this; - QSplashScreen *splash = 0; + QSplashScreen *splash = nullptr; QString splashHtml; if (btConfig().value<bool>("GUI/showSplashScreen", true)) { @@ -81,14 +87,14 @@ BibleTime::BibleTime(QWidget *parent, Qt::WindowFlags flags) } initBackends(); - if (splash != 0) { + if (splash != nullptr) { splash->showMessage(splashHtml.arg(tr("Creating BibleTime's user interface...")), Qt::AlignCenter); qApp->processEvents(); } initView(); - if (splash != 0) { + if (splash != nullptr) { splash->showMessage(splashHtml.arg(tr("Initializing menu- and toolbars...")), Qt::AlignCenter); qApp->processEvents(); @@ -99,24 +105,46 @@ BibleTime::BibleTime(QWidget *parent, Qt::WindowFlags flags) initConnections(); setWindowTitle("BibleTime " BT_VERSION); - setWindowIcon(util::getIcon(CResMgr::mainWindow::icon)); + setWindowIcon(CResMgr::mainWindow::icon()); retranslateUi(); } BibleTime::~BibleTime() { // delete m_dcopInterface; // The backend is deleted by the BibleTimeApp instance -#ifdef BT_DEBUG +#ifndef NDEBUG deleteDebugWindow(); #endif saveProfile(); } +namespace { + +CReadWindow * createReadInstance(QList<CSwordModuleInfo *> const modules, + CMDIArea * const parent) +{ + switch (modules.first()->type()) { + case CSwordModuleInfo::Bible: + return new CBibleReadWindow(modules, parent); + case CSwordModuleInfo::Commentary: + return new CCommentaryReadWindow(modules, parent); + case CSwordModuleInfo::Lexicon: + return new CLexiconReadWindow(modules, parent); + case CSwordModuleInfo::GenericBook: + return new CBookReadWindow(modules, parent); + default: + qFatal("unknown module type"); + std::terminate(); + } +} + +} // anonymous namespace + /** Creates a new presenter in the MDI area according to the type of the module. */ CDisplayWindow* BibleTime::createReadDisplayWindow(QList<CSwordModuleInfo*> modules, const QString& key) { qApp->setOverrideCursor( QCursor(Qt::WaitCursor) ); // qDebug() << "BibleTime::createReadDisplayWindow(QList<CSwordModuleInfo*> modules, const QString& key)"; - CDisplayWindow* displayWindow = CDisplayWindowFactory::createReadInstance(modules, m_mdi); + CDisplayWindow * const displayWindow = createReadInstance(modules, m_mdi); if ( displayWindow ) { displayWindow->init(); m_mdi->addSubWindow(displayWindow); @@ -136,28 +164,23 @@ CDisplayWindow* BibleTime::createReadDisplayWindow(QList<CSwordModuleInfo*> modu /** Creates a new presenter in the MDI area according to the type of the module. */ CDisplayWindow* BibleTime::createReadDisplayWindow(CSwordModuleInfo* module, const QString& key) { - QList<CSwordModuleInfo*> list; - list.append(module); - - return createReadDisplayWindow(list, key); + return createReadDisplayWindow(QList<CSwordModuleInfo*>() << module, key); } CDisplayWindow * BibleTime::createWriteDisplayWindow(CSwordModuleInfo * module, const QString & key, CPlainWriteWindow::WriteWindowType type) { qApp->setOverrideCursor( QCursor(Qt::WaitCursor) ); - QList<CSwordModuleInfo*> modules; - modules.append(module); - - CDisplayWindow* displayWindow = CDisplayWindowFactory::createWriteInstance(modules, m_mdi, type); - if ( displayWindow ) { - displayWindow->init(); - m_mdi->addSubWindow(displayWindow); - if (m_mdi->subWindowList().isEmpty()) - displayWindow->showMaximized(); - else - displayWindow->show(); - displayWindow->lookupKey(key); - } + CDisplayWindow * const displayWindow = + (type == CPlainWriteWindow::HTMLWindow) + ? new CHTMLWriteWindow(QList<CSwordModuleInfo *>() << module, m_mdi) + : new CPlainWriteWindow(QList<CSwordModuleInfo *>() << module, m_mdi); + displayWindow->init(); + m_mdi->addSubWindow(displayWindow); + if (m_mdi->subWindowList().isEmpty()) + displayWindow->showMaximized(); + else + displayWindow->show(); + displayWindow->lookupKey(key); qApp->restoreOverrideCursor(); return displayWindow; @@ -180,7 +203,7 @@ CDisplayWindow* BibleTime::moduleEditHtml(CSwordModuleInfo *module) { void BibleTime::searchInModule(CSwordModuleInfo *module) { /// \todo Refactor this. - QList<const CSwordModuleInfo *> modules; + BtConstModuleList modules; modules.append(module); Search::CSearchDialog::openDialog(modules, QString::null); } @@ -207,7 +230,7 @@ bool BibleTime::moduleUnlock(CSwordModuleInfo *module, QWidget *parent) { CSwordBackend *backend = CSwordBackend::instance(); backend->reloadModules(CSwordBackend::OtherChange); module = backend->findModuleByName(moduleName); - Q_ASSERT(module != 0); + BT_ASSERT(module); } if (!module->isLocked()) break; @@ -231,16 +254,10 @@ void BibleTime::moduleAbout(CSwordModuleInfo *module) { /** Refreshes all presenters.*/ void BibleTime::refreshDisplayWindows() const { - Q_FOREACH (const QMdiSubWindow * const subWindow, m_mdi->subWindowList()) { - if (CDisplayWindow* window = dynamic_cast<CDisplayWindow*>(subWindow->widget())) { + Q_FOREACH(QMdiSubWindow const * const subWindow, m_mdi->subWindowList()) + if (CDisplayWindow * const window = + dynamic_cast<CDisplayWindow*>(subWindow->widget())) window->reload(CSwordBackend::OtherChange); - } - } -} - -/** Refresh main window accelerators */ -void BibleTime::refreshBibleTimeAccel() { - m_actionCollection->readShortcuts("Application shortcuts"); } void BibleTime::closeEvent(QCloseEvent *event) { @@ -276,7 +293,7 @@ void BibleTime::processCommandline(bool ignoreSession, const QString &bibleKey) if (!bibleKey.isNull()) { CSwordModuleInfo* bible = btConfig().getDefaultSwordModuleByType("standardBible"); if (bibleKey == "random") { - CSwordVerseKey vk(0); + CSwordVerseKey vk(nullptr); const int maxIndex = 31100; int newIndex = rand() % maxIndex; vk.setPosition(sword::TOP); @@ -311,10 +328,10 @@ bool BibleTime::event(QEvent* event) { const CSwordModuleInfo* BibleTime::getCurrentModule() { QMdiSubWindow* activeSubWindow = m_mdi->activeSubWindow(); if (!activeSubWindow) - return 0; + return nullptr; CDisplayWindow* w = dynamic_cast<CDisplayWindow*>(activeSubWindow->widget()); if (!w) - return 0; + return nullptr; return w->modules().first(); } diff --git a/src/bibletime.h b/src/bibletime.h index 5712515..038d58a 100644 --- a/src/bibletime.h +++ b/src/bibletime.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -18,7 +18,7 @@ #include "frontend/displaywindow/cdisplaywindow.h" #include "frontend/displaywindow/cplainwritewindow.h" #include <QSignalMapper> -#ifdef BT_DEBUG +#ifndef NDEBUG #include <QMutex> #endif @@ -128,12 +128,11 @@ class QSignalMapper; */ class BibleTime : public QMainWindow { friend class CDisplayWindow; - friend class BibleTimeDBusAdaptor; Q_OBJECT public: - BibleTime(QWidget *parent = 0, Qt::WindowFlags flags = 0); + BibleTime(QWidget *parent = nullptr, Qt::WindowFlags flags = nullptr); ~BibleTime(); @@ -188,7 +187,7 @@ class BibleTime : public QMainWindow { \param[in] parent The parent widget for the unlock dialogs. \returns whether the module was successfully unlocked. */ - static bool moduleUnlock(CSwordModuleInfo *module, QWidget *parent = 0); + static bool moduleUnlock(CSwordModuleInfo *module, QWidget *parent = nullptr); /** Get a pointer to the module associated with the current window @@ -206,9 +205,9 @@ public slots: */ void slotSettingsOptions(); /** - * Opens the optionsdialog of BibleTime. + * Opens the bookshelf wizard. */ - void slotSwordSetupDialog(); + void slotBookshelfWizard(); /** * Opens the handbook. */ @@ -240,7 +239,7 @@ public slots: /** * Catch QMainWindow events */ - bool event(QEvent* event); + bool event(QEvent* event) override; /** * Create the main window menu and toolbar */ @@ -288,21 +287,17 @@ public slots: /** * Initializes one action object */ - QAction* initAction(QAction* action, QString text, QString icon, QKeySequence accel, + QAction* initAction(QAction* action, QString text, QIcon const & icon, QKeySequence accel, const QString& tooltip, const QString& actionName, const char* slot ); /** * Refreshes all presenter supporting at least in of the features given as parameter. */ void refreshDisplayWindows() const; - /** - * Refresh main window accelerators - */ - void refreshBibleTimeAccel(); /** * Reimplemented from QWidget. */ - void closeEvent(QCloseEvent *event); + void closeEvent(QCloseEvent *event) override; protected slots: /** @@ -483,6 +478,7 @@ public slots: QMenu *m_settingsMenu; QAction *m_setPreferencesAction; QAction *m_bookshelfManagerAction; + QAction *m_bookshelfWizardAction; // Help menu: QMenu *m_helpMenu; @@ -507,7 +503,7 @@ public slots: BtFindWidget* m_findWidget; - protected: //DBUS interface implementation + protected: void closeAllModuleWindows(); void syncAllBibles(const QString& key); void syncAllCommentaries(const QString& key); @@ -531,9 +527,9 @@ public slots: */ void showOrHideToolBars(); -#ifdef BT_DEBUG +#ifndef NDEBUG void deleteDebugWindow(); - private slots: + private: void slotDebugWindowClosing(); void slotDebugTimeout(); void slotShowDebugWindow(bool); diff --git a/src/bibletime_dbus.cpp b/src/bibletime_dbus.cpp deleted file mode 100644 index 6beb7fd..0000000 --- a/src/bibletime_dbus.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/********* -* -* 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 <QList> -#include <QMdiSubWindow> -#include "backend/keys/cswordversekey.h" -#include "frontend/cmdiarea.h" - -// Sword includes: -#include <versekey.h> -#include <listkey.h> - - -//helper function -void BibleTime::syncAllModulesByType(const CSwordModuleInfo::ModuleType type, const QString& key) { - Q_FOREACH (const QMdiSubWindow * const w, m_mdi->usableWindowList()) { - CDisplayWindow * const d = dynamic_cast<CDisplayWindow*>(w->widget()); - if (d != 0 && !d->modules().isEmpty() && d->modules().first()->type() == type) { - d->lookupKey(key); - } - } -} - -void BibleTime::closeAllModuleWindows() { - m_mdi->closeAllSubWindows(); -} -QStringList BibleTime::searchInModule(const QString& moduleName, const QString& searchText) { - QStringList ret; - CSwordModuleInfo* mod = CSwordBackend::instance()->findModuleByName(moduleName); - - if (mod) { - sword::ListKey result; - - //mod->search(searchText, CSwordModuleSearch::multipleWords, sword::ListKey()); - sword::ListKey scope; - mod->searchIndexed(searchText, scope, result); - - const QString lead = QString("[%1] ").arg(moduleName); - - for (int i = 0; i < result.getCount(); i++) { - sword::SWKey* key = result.getElement(i); - Q_ASSERT(key); - - - if (mod->type() == CSwordModuleInfo::Bible || mod->type() == CSwordModuleInfo::Commentary) { - sword::VerseKey vk(key->getText()); - ret << lead + QString::fromUtf8( vk.getOSISRef() ); - } - else { - ret << lead + QString::fromUtf8( key->getText() ); - } - } - } - return ret; -} - -QStringList BibleTime::searchInOpenModules(const QString& searchText) { - QStringList ret; - Q_FOREACH (const QMdiSubWindow * const subWindow, m_mdi->subWindowList()) { - const CDisplayWindow * const w = dynamic_cast<CDisplayWindow*>(subWindow->widget()); - if (w != 0) { - Q_FOREACH (const CSwordModuleInfo * const mi, w->modules()) { - ret += searchInModule(mi->name(), searchText); - } - } - } - return ret; -} - -QString BibleTime::getCurrentReference() { - QString ret = QString::null; - - QMdiSubWindow* activeSubWindow = m_mdi->activeSubWindow(); - if (!activeSubWindow) return ret; - - CDisplayWindow* w = dynamic_cast<CDisplayWindow*>(activeSubWindow->widget()); - - if (w) { - QString modType; - Q_ASSERT(w->modules().first()); - switch (w->modules().first()->type()) { - case CSwordModuleInfo::Bible: - modType = "BIBLE"; - break; - case CSwordModuleInfo::Commentary: - modType = "COMMENTARY"; - break; - case CSwordModuleInfo::GenericBook: - modType = "BOOK"; - break; - case CSwordModuleInfo::Lexicon: - modType = "LEXICON"; - break; - default: - modType = "UNSUPPORTED"; - break; - } - - ret.append("[").append(w->modules().first()->name()).append("] "); - ret.append("[").append(modType).append("] "); - - CSwordVerseKey* vk = dynamic_cast<CSwordVerseKey*>( w->key() ); - if (vk) { - ret.append( vk->getOSISRef() ); - } - else { - ret.append( w->key()->key() ); - } - } - - return ret; -} - -QStringList BibleTime::getModulesOfType(const QString& type) { - QStringList ret; - CSwordModuleInfo::ModuleType modType; - - if (type == "BIBLES") { - modType = CSwordModuleInfo::Bible; - } - else if (type == "COMMENTARIES") { - modType = CSwordModuleInfo::Commentary; - } - else if (type == "LEXICONS") { - modType = CSwordModuleInfo::Lexicon; - } - else if (type == "BOOKS") { - modType = CSwordModuleInfo::GenericBook; - } - else { - modType = CSwordModuleInfo::Unknown; - } - - Q_FOREACH(const CSwordModuleInfo * const mi, CSwordBackend::instance()->moduleList()) { - if (mi->type() == modType) { - ret.append(mi->name()); - } - } - - return ret; -} - diff --git a/src/bibletime_dbus_adaptor.cpp b/src/bibletime_dbus_adaptor.cpp deleted file mode 100644 index b393a11..0000000 --- a/src/bibletime_dbus_adaptor.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/********* -* -* 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 NO_DBUS - -#include "bibletime_dbus_adaptor.h" - -#include <QDebug> -#include "backend/config/btconfig.h" - -BibleTimeDBusAdaptor::BibleTimeDBusAdaptor(BibleTime *pBibleTime) - : QDBusAbstractAdaptor(pBibleTime) - , m_bibletime(pBibleTime) -{ - // Intentionally empty -} - -void BibleTimeDBusAdaptor::syncAllBibles(const QString &key) { - qDebug() << "DBUS: syncing all bibles ..."; - m_bibletime->syncAllModulesByType(CSwordModuleInfo::Bible, key); -} - -void BibleTimeDBusAdaptor::syncAllCommentaries(const QString &key) { - qDebug() << "DBUS: syncing all commentaries ..."; - m_bibletime->syncAllModulesByType(CSwordModuleInfo::Commentary, key); -} -void BibleTimeDBusAdaptor::syncAllLexicons(const QString &key) { - qDebug() << "DBUS: syncing all lexicons ..."; - m_bibletime->syncAllModulesByType(CSwordModuleInfo::Lexicon, key); -} - -void BibleTimeDBusAdaptor::syncAllVerseBasedModules(const QString &key) { - qDebug() << "DBUS: syncing all verse based modules ..."; - m_bibletime->syncAllModulesByType(CSwordModuleInfo::Bible, key); - m_bibletime->syncAllModulesByType(CSwordModuleInfo::Commentary, key); -} - -void BibleTimeDBusAdaptor::openWindow(const QString &moduleName, const QString &key) { - qDebug() << "DBUS: open window for module" << moduleName.toLatin1() << "and key" << key.toLatin1() << " ..."; - CSwordModuleInfo *module = CSwordBackend::instance()->findModuleByName(moduleName); - if (module) - m_bibletime->createReadDisplayWindow(module, key); -} - -void BibleTimeDBusAdaptor::openDefaultBible(const QString &key) { - qDebug() << "DBUS: open default bible ..."; - CSwordModuleInfo *module = btConfig().getDefaultSwordModuleByType("standardBible"); - if (module) - m_bibletime->createReadDisplayWindow(module, key); -} - -void BibleTimeDBusAdaptor::closeAllModuleWindows() { - qDebug() << "DBUS: close all windows now ..."; - m_bibletime->closeAllModuleWindows(); -} - -QString BibleTimeDBusAdaptor::getCurrentReference() { - qDebug() << "DBUS: getCurrentReference ..."; - return m_bibletime->getCurrentReference(); -} - -QStringList BibleTimeDBusAdaptor::searchInModule(const QString &moduleName, const QString &searchText) { - qDebug() << "DBUS: searchInModule" << moduleName.toLatin1() << " ..."; - return m_bibletime->searchInModule(moduleName, searchText); -} - -QStringList BibleTimeDBusAdaptor::searchInOpenModules(const QString &searchText) { - qDebug() << "DBUS: search in open modules ..."; - return m_bibletime->searchInOpenModules(searchText); -} - -QStringList BibleTimeDBusAdaptor::searchInDefaultBible(const QString &searchText) { - qDebug() << "DBUS: search in default bible ..."; - CSwordModuleInfo *bible = btConfig().getDefaultSwordModuleByType("standardBible"); - return m_bibletime->searchInModule(bible->name(), searchText); -} - -QStringList BibleTimeDBusAdaptor::getModulesOfType(const QString &type) { - qDebug() << "DBUS: get modules of type ..."; - return m_bibletime->getModulesOfType(type); -} - -#endif //NO_DBUS diff --git a/src/bibletime_dbus_adaptor.h b/src/bibletime_dbus_adaptor.h deleted file mode 100644 index cf7200c..0000000 --- a/src/bibletime_dbus_adaptor.h +++ /dev/null @@ -1,138 +0,0 @@ -/********* -* -* 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 NO_DBUS - -#ifndef BIBLETIME_DBUS_ADAPTOR_H -#define BIBLETIME_DBUS_ADAPTOR_H - -#include "bibletime.h" - -#ifndef NO_DBUS -#include <QDBusAbstractAdaptor> -#endif -#include <QString> -#include <QStringList> - - -class BibleTimeDBusAdaptor: QDBusAbstractAdaptor { - - Q_OBJECT - Q_CLASSINFO("D-Bus Interface", "info.bibletime.BibleTime") - -public: /* Methods: */ - - BibleTimeDBusAdaptor(BibleTime *pBibleTime); - -public slots: - - /** - Sync all open Bible windows to the key. - \param[in] key The key which is set to all Bible windows. - */ - void syncAllBibles(const QString &key); - - /** - Sync all open commentary windows to the key. - \param[in] key The key which is set to all Commentary windows. - */ - void syncAllCommentaries(const QString &key); - - /** - Sync all open lexicon windows to the key. - \param[in] key The key which is set to all Lexicon windows. - */ - void syncAllLexicons(const QString &key); - - /** - Sync all open verse based (i.e. Bibles and commentaries) windows to the key. - \param key The key which is set to all Bible and Commentary windows. - */ - void syncAllVerseBasedModules(const QString &key); - - /** - Open a new read window for the module moduleName using the given key - \param[in] moduleName The name of the module which is opened in a new module window. - \param[in] key The key to set to the newly opened window. - */ - void openWindow(const QString &moduleName, const QString &key); - - /** - Open a new read window for the default Bible module using the given key - \param[in] key The key to set to the newly opened window. - */ - void openDefaultBible(const QString &key); - - /** - Close all open windows. - */ - void closeAllModuleWindows(); - - /** - Returns the reference used in the current window. - The format of the returned reference is - [Module] [Type] OSIS_Reference, - with type one of BIBLE/COMMENTARY/BOOK/LEXICON/UNSUPPORTED - If the type is BIBLE or COMMENTARY the reference is an OSIS ref - in the other cases it's the key name, for books /Chapter/Subsection - for Lexicons just the plain key, e.g. "ADAM". - e.g. - [KJV] [BIBLE] Gen.1.1 - [MHC] [COMMENTARY] Gen.1.1 - [ISBE] [LEXICON] REDEMPTION - \returns The reference displayed in the currently active module window. - Empty if none is active. - */ - QString getCurrentReference(); - - /** - Search the searchText in the specified module. - \param[in] moduleName The module to search in - \param[in] searchText Search for this in the modules - \returns The search result. It's in the format [modulename] - osis_ref_of_the_found_key. For example "[KJV] Gen.1.1". - */ - QStringList searchInModule(const QString &moduleName, const QString &searchText) ; - - /** - Search in all open modules and return the search result. - The result is in the same format as searchInModule - \param[in] searchText Search for this in the modules - \returns The search result for a searchin all opened module windows - \see searchInModule For the search result format. - */ - QStringList searchInOpenModules(const QString &searchText); - - /** - Search in the default Bible module and return the search result. - The result is in the same format as searchInModule - \param[in] searchText Search for this in the modules - \returns The search result for a search in the default Bible - \see searchInModule - */ - QStringList searchInDefaultBible(const QString &searchText); - - /** - Return a list of modules of the given type. - \param[in] type One of BIBLES, COMMENTARIES, LEXICONS, BOOKS - \returns The list of modules of the given type, may be empty - */ - QStringList getModulesOfType(const QString &type); - -private: /* Fields: */ - - BibleTime *m_bibletime; - -}; /* class BibleTimeDBusAdaptor */ - -#endif /* #ifdef NO_DBUS */ - -#endif /* #ifdef BIBLETIME_DBUS_ADAPTOR_H */ diff --git a/src/bibletime_init.cpp b/src/bibletime_init.cpp index 7a3c5b7..ceb14ff 100644 --- a/src/bibletime_init.cpp +++ b/src/bibletime_init.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -29,20 +29,21 @@ #include "frontend/btopenworkaction.h" #include "frontend/cinfodisplay.h" #include "frontend/cmdiarea.h" -#include "frontend/cprinter.h" #include "frontend/display/btfindwidget.h" #include "frontend/displaywindow/btactioncollection.h" #include "frontend/displaywindow/btmodulechooserbar.h" #include "frontend/bookmarks/cbookmarkindex.h" -#include "frontend/settingsdialogs/btlanguagesettings.h" +#include "frontend/settingsdialogs/cdisplaysettings.h" +#include "util/btassert.h" +#include "util/btconnect.h" #include "util/cresmgr.h" #include "util/directory.h" -#include "util/geticon.h" // Sword includes: #include <swlog.h> +#include <swmgr.h> -#ifdef BT_DEBUG +#ifndef NDEBUG #include <QLabel> #include <QMetaObject> #include <QMutexLocker> @@ -65,7 +66,7 @@ void BibleTime::initView() { m_bookmarksDock = new QDockWidget(this); m_bookmarksDock->setObjectName("BookmarksDock"); - m_bookmarksPage = new CBookmarkIndex(0); + m_bookmarksPage = new CBookmarkIndex(nullptr); m_bookmarksDock->setWidget(m_bookmarksPage); addDockWidget(Qt::LeftDockWidgetArea, m_bookmarksDock); tabifyDockWidget(m_bookmarksDock, m_bookshelfDock); @@ -77,23 +78,24 @@ void BibleTime::initView() { m_magDock->setWidget(m_infoDisplay); addDockWidget(Qt::LeftDockWidgetArea, m_magDock); - connect(m_bookshelfDock, SIGNAL(moduleHovered(CSwordModuleInfo*)), - m_infoDisplay, SLOT(setInfo(CSwordModuleInfo*))); + BT_CONNECT(m_bookshelfDock, SIGNAL(moduleHovered(CSwordModuleInfo *)), + m_infoDisplay, SLOT(setInfo(CSwordModuleInfo *))); m_mdi->setMinimumSize(100, 100); m_mdi->setFocusPolicy(Qt::ClickFocus); } -QAction* BibleTime::initAction(QAction* action, QString text, QString icon, +QAction* BibleTime::initAction(QAction* action, QString text, QIcon const & icon, QKeySequence accel, const QString& tooltip, const QString& actionName, const char* slot) { action->setText(text); - if ( ! icon.isEmpty() ) - action->setIcon(util::getIcon(icon)); + action->setIcon(icon); action->setShortcut(accel); - if (tooltip != QString::null) action->setToolTip(tooltip); + if (tooltip != QString::null) + action->setToolTip(tooltip); m_actionCollection->addAction(actionName, action); - if (slot) QObject::connect( action, SIGNAL(triggered()), this, slot ); + if (slot) + BT_CONNECT(action, SIGNAL(triggered()), this, slot); return action; } @@ -102,14 +104,14 @@ QAction* BibleTime::initAction(QAction* action, QString text, QString icon, void BibleTime::insertKeyboardActions( BtActionCollection* const a ) { QAction* action = new QAction(a); action->setText(tr("&Quit")); - action->setIcon(util::getIcon("exit.svg")); + action->setIcon(CResMgr::mainMenu::window::quit::icon()); action->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q)); action->setToolTip(tr("Quit BibleTime")); a->addAction("quit", action); action = new QAction(a); action->setText(tr("&Fullscreen mode")); - action->setIcon(util::getIcon(CResMgr::mainMenu::window::showFullscreen::icon)); + action->setIcon(CResMgr::mainMenu::window::showFullscreen::icon()); action->setShortcut(QKeySequence(CResMgr::mainMenu::window::showFullscreen::accel)); action->setToolTip(tr("Toggle fullscreen mode of the main window")); a->addAction("toggleFullscreen", action); @@ -121,144 +123,145 @@ void BibleTime::insertKeyboardActions( BtActionCollection* const a ) { action = new QAction(a); action->setText(tr("Search in &open works...")); - action->setIcon(util::getIcon(CResMgr::mainMenu::mainIndex::search::icon)); + action->setIcon(CResMgr::mainMenu::mainIndex::search::icon()); action->setShortcut(QKeySequence(CResMgr::mainMenu::mainIndex::search::accel)); action->setToolTip(tr("Search in all works that are currently open")); a->addAction("searchOpenWorks", action); action = new QAction(a); action->setText(tr("Search in standard &Bible...")); - action->setIcon(util::getIcon(CResMgr::mainMenu::mainIndex::searchdefaultbible::icon)); + action->setIcon(CResMgr::mainMenu::mainIndex::searchdefaultbible::icon()); action->setShortcut(QKeySequence(CResMgr::mainMenu::mainIndex::searchdefaultbible::accel)); action->setToolTip(tr("Search in the standard Bible")); a->addAction("searchStdBible", action); action = new QAction(a); action->setText(tr("Save as &new session...")); - action->setIcon(util::getIcon(CResMgr::mainMenu::window::saveToNewProfile::icon)); + action->setIcon(CResMgr::mainMenu::window::saveToNewProfile::icon()); action->setShortcut(QKeySequence(CResMgr::mainMenu::window::saveToNewProfile::accel)); action->setToolTip(tr("Create and save a new session")); a->addAction("saveNewSession", action); action = new QAction(a); action->setText(tr("&Manual mode")); - action->setIcon(util::getIcon(CResMgr::mainMenu::window::arrangementMode::manual::icon)); + action->setIcon(CResMgr::mainMenu::window::arrangementMode::manual::icon()); action->setShortcut(QKeySequence(CResMgr::mainMenu::window::arrangementMode::manual::accel)); action->setToolTip(tr("Manually arrange the open windows")); a->addAction("manualArrangement", action); action = new QAction(a); action->setText(tr("Auto-tile &vertically")); - action->setIcon(util::getIcon(CResMgr::mainMenu::window::arrangementMode::autoTileVertical::icon)); + action->setIcon(CResMgr::mainMenu::window::arrangementMode::autoTileVertical::icon()); action->setShortcut(QKeySequence(CResMgr::mainMenu::window::arrangementMode::autoTileVertical::accel)); action->setToolTip(tr("Automatically tile the open windows vertically (arrange side by side)")); a->addAction("autoVertical", action); action = new QAction(a); action->setText(tr("Auto-tile &horizontally")); - action->setIcon(util::getIcon(CResMgr::mainMenu::window::arrangementMode::autoTileHorizontal::icon)); + action->setIcon(CResMgr::mainMenu::window::arrangementMode::autoTileHorizontal::icon()); action->setShortcut(QKeySequence(CResMgr::mainMenu::window::arrangementMode::autoTileHorizontal::accel)); action->setToolTip(tr("Automatically tile the open windows horizontally (arrange on top of each other)")); a->addAction("autoHorizontal", action); action = new QAction(a); action->setText(tr("Auto-&tile")); - action->setIcon(util::getIcon(CResMgr::mainMenu::window::arrangementMode::autoTile::icon)); + action->setIcon(CResMgr::mainMenu::window::arrangementMode::autoTile::icon()); action->setShortcut(QKeySequence(CResMgr::mainMenu::window::arrangementMode::autoTile::accel)); action->setToolTip(tr("Automatically tile the open windows")); a->addAction("autoTile", action); action = new QAction(a); action->setText(tr("Ta&bbed")); - action->setIcon(util::getIcon(CResMgr::mainMenu::window::arrangementMode::autoTabbed::icon)); + action->setIcon(CResMgr::mainMenu::window::arrangementMode::autoTabbed::icon()); action->setShortcut(QKeySequence(CResMgr::mainMenu::window::arrangementMode::autoTabbed::accel)); action->setToolTip(tr("Automatically tab the open windows")); a->addAction("autoTabbed", action); action = new QAction(a); action->setText(tr("Auto-&cascade")); - action->setIcon(util::getIcon(CResMgr::mainMenu::window::arrangementMode::autoCascade::icon)); + action->setIcon(CResMgr::mainMenu::window::arrangementMode::autoCascade::icon()); action->setShortcut(QKeySequence(CResMgr::mainMenu::window::arrangementMode::autoCascade::accel)); action->setToolTip(tr("Automatically cascade the open windows")); a->addAction("autoCascade", action); action = new QAction(a); action->setText(tr("&Cascade")); - action->setIcon(util::getIcon(CResMgr::mainMenu::window::cascade::icon)); + action->setIcon(CResMgr::mainMenu::window::cascade::icon()); action->setShortcut(QKeySequence(CResMgr::mainMenu::window::cascade::accel)); action->setToolTip(tr("Cascade the open windows")); a->addAction("cascade", action); action = new QAction(a); action->setText(tr("&Tile")); - action->setIcon(util::getIcon(CResMgr::mainMenu::window::tile::icon)); + action->setIcon(CResMgr::mainMenu::window::tile::icon()); action->setShortcut(QKeySequence(CResMgr::mainMenu::window::tile::accel)); action->setToolTip(tr("Tile the open windows")); a->addAction("tile", action); action = new QAction(a); action->setText(tr("Tile &vertically")); - action->setIcon(util::getIcon(CResMgr::mainMenu::window::tileVertical::icon)); + action->setIcon(CResMgr::mainMenu::window::tileVertical::icon()); action->setShortcut(QKeySequence(CResMgr::mainMenu::window::tileVertical::accel)); action->setToolTip(tr("Vertically tile (arrange side by side) the open windows")); a->addAction("tileVertically", action); action = new QAction(a); action->setText(tr("Tile &horizontally")); - action->setIcon(util::getIcon(CResMgr::mainMenu::window::tileHorizontal::icon)); + action->setIcon(CResMgr::mainMenu::window::tileHorizontal::icon()); action->setShortcut(QKeySequence(CResMgr::mainMenu::window::tileHorizontal::accel)); action->setToolTip(tr("Horizontally tile (arrange on top of each other) the open windows")); a->addAction("tileHorizontally", action); action = new QAction(a); action->setText(tr("Close &window")); - action->setIcon(util::getIcon(CResMgr::mainMenu::window::close::icon)); + action->setIcon(CResMgr::mainMenu::window::close::icon()); action->setShortcut(QKeySequence(CResMgr::mainMenu::window::close::accel)); action->setToolTip(tr("Close the current open window")); a->addAction("closeWindow", action); action = new QAction(a); action->setText(tr("Cl&ose all windows")); - action->setIcon(util::getIcon(CResMgr::mainMenu::window::closeAll::icon)); + action->setIcon(CResMgr::mainMenu::window::closeAll::icon()); action->setShortcut(QKeySequence(CResMgr::mainMenu::window::closeAll::accel)); action->setToolTip(tr("Close all open windows inside BibleTime")); a->addAction("closeAllWindows", action); action = new QAction(a); action->setText(tr("&Configure BibleTime...")); - action->setIcon(util::getIcon("configure.svg")); + action->setIcon(CResMgr::mainMenu::settings::configureDialog::icon()); action->setToolTip(tr("Set BibleTime's preferences")); a->addAction("setPreferences", action); action = new QAction(a); - action->setText(tr("Bookshelf &Manager...")); - action->setIcon(util::getIcon(CResMgr::mainMenu::settings::swordSetupDialog::icon)); + action->setText(tr("Bookshelf Manager...")); + action->setIcon(CResMgr::mainMenu::settings::swordSetupDialog::icon()); action->setShortcut(QKeySequence(CResMgr::mainMenu::settings::swordSetupDialog::accel)); action->setToolTip(tr("Configure your bookshelf and install/update/remove/index works")); - a->addAction("bookshelfManager", action); + a->addAction("bookshelfWizard", action); action = new QAction(a); action->setText(tr("&Handbook")); - action->setIcon(util::getIcon(CResMgr::mainMenu::help::handbook::icon)); + action->setIcon(CResMgr::mainMenu::help::handbook::icon()); action->setShortcut(QKeySequence(CResMgr::mainMenu::help::handbook::accel)); action->setToolTip(tr("Open BibleTime's handbook")); a->addAction("openHandbook", action); action = new QAction(a); action->setText(tr("&Bible Study Howto")); - action->setIcon(util::getIcon(CResMgr::mainMenu::help::bibleStudyHowTo::icon)); + action->setIcon(CResMgr::mainMenu::help::bibleStudyHowTo::icon()); action->setShortcut(QKeySequence(CResMgr::mainMenu::help::bibleStudyHowTo::accel)); action->setToolTip(tr("Open the Bible study HowTo included with BibleTime.<br/>This HowTo is an introduction on how to study the Bible in an efficient way.")); a->addAction("bibleStudyHowto", action); action = new QAction(a); action->setText(tr("&About BibleTime")); + action->setIcon(CResMgr::mainMenu::help::aboutBibleTime::icon()); action->setToolTip(tr("Information about the BibleTime program")); a->addAction("aboutBibleTime", action); action = new QAction(a); action->setText(tr("&Tip of the day...")); - action->setIcon(util::getIcon(CResMgr::mainMenu::help::tipOfTheDay::icon)); + action->setIcon(CResMgr::mainMenu::help::tipOfTheDay::icon()); action->setShortcut(QKeySequence(CResMgr::mainMenu::help::tipOfTheDay::accel)); action->setToolTip(tr("Show tips about BibleTime")); a->addAction("tipOfTheDay", action); @@ -343,6 +346,8 @@ void BibleTime::createCentralWidget() m_findWidget->setVisible(false); QVBoxLayout* layout = new QVBoxLayout(); + QMargins margins(0, 0, 0, 0); + layout->setContentsMargins(margins); layout->addWidget(m_mdi); layout->addWidget(m_findWidget); @@ -350,20 +355,18 @@ void BibleTime::createCentralWidget() widget->setLayout(layout); setCentralWidget(widget); - bool ok = connect(m_findWidget, SIGNAL(findNext(const QString&,bool)), - m_mdi, SLOT(findNextTextInActiveWindow(const QString &, bool))); - Q_ASSERT(ok); + BT_CONNECT(m_findWidget, SIGNAL(findNext(QString const &,bool)), + m_mdi, SLOT(findNextTextInActiveWindow(QString const &, bool))); - ok = connect(m_findWidget, SIGNAL(findPrevious(const QString&,bool)), - m_mdi, SLOT(findPreviousTextInActiveWindow(const QString &, bool))); - Q_ASSERT(ok); - ok = connect(m_findWidget, SIGNAL(highlightText(const QString&,bool)), - m_mdi, SLOT(highlightTextInActiveWindow(const QString &, bool))); - Q_ASSERT(ok); + BT_CONNECT(m_findWidget, SIGNAL(findPrevious(QString const &,bool)), + m_mdi, + SLOT(findPreviousTextInActiveWindow(QString const &, bool))); - ok = connect(m_mdi, SIGNAL(subWindowActivated(QMdiSubWindow*)), - this, SLOT(slotActiveWindowChanged(QMdiSubWindow*))); - Q_ASSERT(ok); + BT_CONNECT(m_findWidget, SIGNAL(highlightText(QString const &,bool)), + m_mdi, SLOT(highlightTextInActiveWindow(QString const &, bool))); + + BT_CONNECT(m_mdi, SIGNAL(subWindowActivated(QMdiSubWindow *)), + this, SLOT(slotActiveWindowChanged(QMdiSubWindow *))); } /** Initializes the action objects of the GUI */ @@ -373,162 +376,147 @@ void BibleTime::initActions() { // Create the window to signal mapper and connect it up: m_windowMapper = new QSignalMapper(this); - connect(m_windowMapper, SIGNAL(mapped(QWidget*)), - this, SLOT(slotSetActiveSubWindow(QWidget*))); + BT_CONNECT(m_windowMapper, SIGNAL(mapped(QWidget *)), + this, SLOT(slotSetActiveSubWindow(QWidget *))); // File menu actions: m_openWorkAction = new BtOpenWorkAction("GUI/mainWindow/openWorkAction/grouping", this); - Q_ASSERT(m_openWorkAction != 0); - connect(m_openWorkAction, SIGNAL(triggered(CSwordModuleInfo*)), - this, SLOT(createReadDisplayWindow(CSwordModuleInfo*))); + BT_CONNECT(m_openWorkAction, SIGNAL(triggered(CSwordModuleInfo *)), + this, SLOT(createReadDisplayWindow(CSwordModuleInfo *))); - m_quitAction = m_actionCollection->action("quit"); + m_quitAction = &m_actionCollection->action("quit"); m_quitAction->setMenuRole(QAction::QuitRole); - Q_ASSERT(m_quitAction != 0); - connect(m_quitAction, SIGNAL(triggered()), - this, SLOT(quit())); + BT_CONNECT(m_quitAction, SIGNAL(triggered()), + this, SLOT(quit())); // View menu actions: - m_windowFullscreenAction = m_actionCollection->action("toggleFullscreen"); - Q_ASSERT(m_windowFullscreenAction != 0); + m_windowFullscreenAction = &m_actionCollection->action("toggleFullscreen"); m_windowFullscreenAction->setCheckable(true); - connect(m_windowFullscreenAction, SIGNAL(triggered()), - this, SLOT(toggleFullscreen())); + BT_CONNECT(m_windowFullscreenAction, SIGNAL(triggered()), + this, SLOT(toggleFullscreen())); // Special case these actions, overwrite those already in collection m_showBookshelfAction = m_bookshelfDock->toggleViewAction(); - m_showBookshelfAction->setIcon(util::getIcon(CResMgr::mainMenu::view::showBookshelf::icon)); + m_showBookshelfAction->setIcon(CResMgr::mainMenu::view::showBookshelf::icon()); m_showBookshelfAction->setToolTip(tr("Toggle visibility of the bookshelf window")); + m_actionCollection->removeAction("showBookshelf"); m_actionCollection->addAction("showBookshelf", m_showBookshelfAction); m_showBookmarksAction = m_bookmarksDock->toggleViewAction(); - m_showBookmarksAction->setIcon(util::getIcon(CResMgr::mainMenu::view::showBookmarks::icon)); + m_showBookmarksAction->setIcon(CResMgr::mainMenu::view::showBookmarks::icon()); m_showBookmarksAction->setToolTip(tr("Toggle visibility of the bookmarks window")); + m_actionCollection->removeAction("showBookmarks"); m_actionCollection->addAction("showBookmarks", m_showBookmarksAction); m_showMagAction = m_magDock->toggleViewAction(); - m_showMagAction->setIcon(util::getIcon(CResMgr::mainMenu::view::showMag::icon)); + m_showMagAction->setIcon(CResMgr::mainMenu::view::showMag::icon()); m_showMagAction->setToolTip(tr("Toggle visibility of the mag window")); + m_actionCollection->removeAction("showMag"); m_actionCollection->addAction("showMag", m_showMagAction); - m_showTextAreaHeadersAction = m_actionCollection->action("showParallelTextHeaders"); - Q_ASSERT(m_showTextAreaHeadersAction != 0); + m_showTextAreaHeadersAction = + &m_actionCollection->action("showParallelTextHeaders"); m_showTextAreaHeadersAction->setCheckable(true); m_showTextAreaHeadersAction->setChecked(btConfig().sessionValue<bool>("GUI/showTextWindowHeaders", true)); - connect(m_showTextAreaHeadersAction, SIGNAL(toggled(bool)), - this, SLOT(slotToggleTextWindowHeader())); + BT_CONNECT(m_showTextAreaHeadersAction, SIGNAL(toggled(bool)), + this, SLOT(slotToggleTextWindowHeader())); - m_showMainWindowToolbarAction = m_actionCollection->action("showToolbar"); - Q_ASSERT(m_showMainWindowToolbarAction != 0); + m_showMainWindowToolbarAction = &m_actionCollection->action("showToolbar"); m_showMainWindowToolbarAction->setCheckable(true); m_showMainWindowToolbarAction->setChecked(btConfig().sessionValue<bool>("GUI/showMainToolbar", true)); - connect( m_showMainWindowToolbarAction, SIGNAL(triggered()), - this, SLOT(slotToggleMainToolbar())); + BT_CONNECT(m_showMainWindowToolbarAction, SIGNAL(triggered()), + this, SLOT(slotToggleMainToolbar())); - m_showTextWindowNavigationAction = m_actionCollection->action("showNavigation"); - Q_ASSERT(m_showTextWindowNavigationAction != 0); + m_showTextWindowNavigationAction = + &m_actionCollection->action("showNavigation"); m_showTextWindowNavigationAction->setCheckable(true); m_showTextWindowNavigationAction->setChecked(btConfig().sessionValue<bool>("GUI/showTextWindowNavigator", true)); - connect(m_showTextWindowNavigationAction, SIGNAL(toggled(bool)), - this, SLOT(slotToggleNavigatorToolbar())); + BT_CONNECT(m_showTextWindowNavigationAction, SIGNAL(toggled(bool)), + this, SLOT(slotToggleNavigatorToolbar())); - m_showTextWindowModuleChooserAction = m_actionCollection->action("showWorks"); - Q_ASSERT(m_showTextWindowModuleChooserAction != 0); + m_showTextWindowModuleChooserAction = + &m_actionCollection->action("showWorks"); m_showTextWindowModuleChooserAction->setCheckable(true); m_showTextWindowModuleChooserAction->setChecked(btConfig().sessionValue<bool>("GUI/showTextWindowModuleSelectorButtons", true)); - connect(m_showTextWindowModuleChooserAction, SIGNAL(toggled(bool)), - this, SLOT(slotToggleWorksToolbar())); + BT_CONNECT(m_showTextWindowModuleChooserAction, SIGNAL(toggled(bool)), + this, SLOT(slotToggleWorksToolbar())); - m_showTextWindowToolButtonsAction = m_actionCollection->action("showTools"); - Q_ASSERT(m_showTextWindowToolButtonsAction != 0); + m_showTextWindowToolButtonsAction = + &m_actionCollection->action("showTools"); m_showTextWindowToolButtonsAction->setCheckable(true); m_showTextWindowToolButtonsAction->setChecked(btConfig().sessionValue<bool>("GUI/showTextWindowToolButtons", true)); - connect(m_showTextWindowToolButtonsAction, SIGNAL(toggled(bool)), - this, SLOT(slotToggleToolsToolbar())); + BT_CONNECT(m_showTextWindowToolButtonsAction, SIGNAL(toggled(bool)), + this, SLOT(slotToggleToolsToolbar())); - m_showFormatToolbarAction = m_actionCollection->action("showFormat"); - Q_ASSERT(m_showFormatToolbarAction != 0); + m_showFormatToolbarAction = &m_actionCollection->action("showFormat"); m_showFormatToolbarAction->setCheckable(true); m_showFormatToolbarAction->setChecked(btConfig().sessionValue<bool>("GUI/showFormatToolbarButtons", true)); - bool ok = connect(m_showFormatToolbarAction, SIGNAL(toggled(bool)), - this, SLOT(slotToggleFormatToolbar())); - Q_ASSERT(ok); + BT_CONNECT(m_showFormatToolbarAction, SIGNAL(toggled(bool)), + this, SLOT(slotToggleFormatToolbar())); - m_toolbarsInEachWindow = m_actionCollection->action("showToolbarsInTextWindows"); - Q_ASSERT(m_toolbarsInEachWindow != 0); + m_toolbarsInEachWindow = + &m_actionCollection->action("showToolbarsInTextWindows"); m_toolbarsInEachWindow->setCheckable(true); m_toolbarsInEachWindow->setChecked(btConfig().sessionValue<bool>("GUI/showToolbarsInEachWindow", true)); - ok = connect(m_toolbarsInEachWindow, SIGNAL(toggled(bool)), - this, SLOT(slotToggleToolBarsInEachWindow())); - Q_ASSERT(ok); + BT_CONNECT(m_toolbarsInEachWindow, SIGNAL(toggled(bool)), + this, SLOT(slotToggleToolBarsInEachWindow())); // Search menu actions: - m_searchOpenWorksAction = m_actionCollection->action("searchOpenWorks"); - Q_ASSERT(m_searchOpenWorksAction != 0); - connect(m_searchOpenWorksAction, SIGNAL(triggered()), - this, SLOT(slotSearchModules())); + m_searchOpenWorksAction = &m_actionCollection->action("searchOpenWorks"); + BT_CONNECT(m_searchOpenWorksAction, SIGNAL(triggered()), + this, SLOT(slotSearchModules())); - m_searchStandardBibleAction = m_actionCollection->action("searchStdBible"); - Q_ASSERT(m_searchStandardBibleAction != 0); - connect(m_searchStandardBibleAction, SIGNAL(triggered()), - this, SLOT(slotSearchDefaultBible())); + m_searchStandardBibleAction = &m_actionCollection->action("searchStdBible"); + BT_CONNECT(m_searchStandardBibleAction, SIGNAL(triggered()), + this, SLOT(slotSearchDefaultBible())); // Window menu actions: - m_windowCloseAction = m_actionCollection->action("closeWindow"); - Q_ASSERT(m_windowCloseAction != 0); - connect(m_windowCloseAction, SIGNAL(triggered()), - m_mdi, SLOT(closeActiveSubWindow())); - - m_windowCloseAllAction = m_actionCollection->action("closeAllWindows"); - Q_ASSERT(m_windowCloseAllAction != 0); - connect(m_windowCloseAllAction, SIGNAL(triggered()), - m_mdi, SLOT(closeAllSubWindows())); - - m_windowCascadeAction = m_actionCollection->action("cascade"); - Q_ASSERT(m_windowCascadeAction != 0); - connect(m_windowCascadeAction, SIGNAL(triggered()), - this, SLOT(slotCascade())); - - m_windowTileAction = m_actionCollection->action("tile"); - Q_ASSERT(m_windowTileAction != 0); - connect(m_windowTileAction, SIGNAL(triggered()), - this, SLOT(slotTile())); - - m_windowTileVerticalAction = m_actionCollection->action("tileVertically"); - Q_ASSERT(m_windowTileVerticalAction != 0); - connect(m_windowTileVerticalAction, SIGNAL(triggered()), - this, SLOT(slotTileVertical())); - - m_windowTileHorizontalAction = m_actionCollection->action("tileHorizontally"); - Q_ASSERT(m_windowTileHorizontalAction != 0); - connect(m_windowTileHorizontalAction, SIGNAL(triggered()), - this, SLOT(slotTileHorizontal())); + m_windowCloseAction = &m_actionCollection->action("closeWindow"); + BT_CONNECT(m_windowCloseAction, SIGNAL(triggered()), + m_mdi, SLOT(closeActiveSubWindow())); + + m_windowCloseAllAction = &m_actionCollection->action("closeAllWindows"); + BT_CONNECT(m_windowCloseAllAction, SIGNAL(triggered()), + m_mdi, SLOT(closeAllSubWindows())); + + m_windowCascadeAction = &m_actionCollection->action("cascade"); + BT_CONNECT(m_windowCascadeAction, SIGNAL(triggered()), + this, SLOT(slotCascade())); + + m_windowTileAction = &m_actionCollection->action("tile"); + BT_CONNECT(m_windowTileAction, SIGNAL(triggered()), + this, SLOT(slotTile())); + + m_windowTileVerticalAction = &m_actionCollection->action("tileVertically"); + BT_CONNECT(m_windowTileVerticalAction, SIGNAL(triggered()), + this, SLOT(slotTileVertical())); + + m_windowTileHorizontalAction = + &m_actionCollection->action("tileHorizontally"); + BT_CONNECT(m_windowTileHorizontalAction, SIGNAL(triggered()), + this, SLOT(slotTileHorizontal())); alignmentMode alignment = btConfig().sessionValue<alignmentMode>("GUI/alignmentMode", autoTileVertical); - m_windowManualModeAction = m_actionCollection->action("manualArrangement"); - Q_ASSERT(m_windowManualModeAction != 0); + m_windowManualModeAction = &m_actionCollection->action("manualArrangement"); m_windowManualModeAction->setCheckable(true); - m_windowAutoTabbedAction = m_actionCollection->action("autoTabbed"); - Q_ASSERT(m_windowAutoTabbedAction != 0); + m_windowAutoTabbedAction = &m_actionCollection->action("autoTabbed"); m_windowAutoTabbedAction->setCheckable(true); //: Vertical tiling means that windows are vertical, placed side by side - m_windowAutoTileVerticalAction = m_actionCollection->action("autoVertical"); - Q_ASSERT(m_windowAutoTileVerticalAction != 0); + m_windowAutoTileVerticalAction = + &m_actionCollection->action("autoVertical"); m_windowAutoTileVerticalAction->setCheckable(true); //: Horizontal tiling means that windows are horizontal, placed on top of each other - m_windowAutoTileHorizontalAction = m_actionCollection->action("autoHorizontal"); - Q_ASSERT(m_windowAutoTileHorizontalAction != 0); + m_windowAutoTileHorizontalAction = + &m_actionCollection->action("autoHorizontal"); m_windowAutoTileHorizontalAction->setCheckable(true); - m_windowAutoTileAction = m_actionCollection->action("autoTile"); - Q_ASSERT(m_windowAutoTileAction != 0); + m_windowAutoTileAction = &m_actionCollection->action("autoTile"); m_windowAutoTileAction->setCheckable(true); - m_windowAutoCascadeAction = m_actionCollection->action("autoCascade"); - Q_ASSERT(m_windowAutoCascadeAction != 0); + m_windowAutoCascadeAction = &m_actionCollection->action("autoCascade"); m_windowAutoCascadeAction->setCheckable(true); /* @@ -554,49 +542,43 @@ void BibleTime::initActions() { alignmentAction->setChecked(true); slotUpdateWindowArrangementActions(alignmentAction); - m_windowSaveToNewProfileAction = m_actionCollection->action("saveNewSession"); - Q_ASSERT(m_windowSaveToNewProfileAction != 0); - connect(m_windowSaveToNewProfileAction, SIGNAL(triggered()), - this, SLOT(saveToNewProfile())); + m_windowSaveToNewProfileAction = + &m_actionCollection->action("saveNewSession"); + BT_CONNECT(m_windowSaveToNewProfileAction, SIGNAL(triggered()), + this, SLOT(saveToNewProfile())); - m_setPreferencesAction = m_actionCollection->action("setPreferences"); - Q_ASSERT(m_setPreferencesAction != 0); + m_setPreferencesAction = &m_actionCollection->action("setPreferences"); m_setPreferencesAction->setMenuRole( QAction::PreferencesRole ); - connect(m_setPreferencesAction, SIGNAL(triggered()), - this, SLOT(slotSettingsOptions())); - - m_bookshelfManagerAction = m_actionCollection->action("bookshelfManager"); - Q_ASSERT(m_bookshelfManagerAction != 0); - m_bookshelfManagerAction->setMenuRole( QAction::ApplicationSpecificRole ); - connect(m_bookshelfManagerAction, SIGNAL(triggered()), - this, SLOT(slotSwordSetupDialog())); - - m_openHandbookAction = m_actionCollection->action("openHandbook"); - Q_ASSERT(m_openHandbookAction != 0); - connect(m_openHandbookAction, SIGNAL(triggered()), - this, SLOT(openOnlineHelp_Handbook())); - - m_bibleStudyHowtoAction = m_actionCollection->action("bibleStudyHowto"); - Q_ASSERT(m_bibleStudyHowtoAction != 0); - connect(m_bibleStudyHowtoAction, SIGNAL(triggered()), - this, SLOT(openOnlineHelp_Howto())); - - m_aboutBibleTimeAction = m_actionCollection->action("aboutBibleTime"); - Q_ASSERT(m_aboutBibleTimeAction != 0); + BT_CONNECT(m_setPreferencesAction, SIGNAL(triggered()), + this, SLOT(slotSettingsOptions())); + + m_bookshelfWizardAction = &m_actionCollection->action("bookshelfWizard"); + m_bookshelfWizardAction->setMenuRole( QAction::ApplicationSpecificRole ); + BT_CONNECT(m_bookshelfWizardAction, SIGNAL(triggered()), + this, SLOT(slotBookshelfWizard())); + + m_openHandbookAction = &m_actionCollection->action("openHandbook"); + BT_CONNECT(m_openHandbookAction, SIGNAL(triggered()), + this, SLOT(openOnlineHelp_Handbook())); + + m_bibleStudyHowtoAction = &m_actionCollection->action("bibleStudyHowto"); + BT_CONNECT(m_bibleStudyHowtoAction, SIGNAL(triggered()), + this, SLOT(openOnlineHelp_Howto())); + + m_aboutBibleTimeAction = &m_actionCollection->action("aboutBibleTime"); m_aboutBibleTimeAction->setMenuRole( QAction::AboutRole ); - connect(m_aboutBibleTimeAction, SIGNAL(triggered()), - this, SLOT(slotOpenAboutDialog()) ); + BT_CONNECT(m_aboutBibleTimeAction, SIGNAL(triggered()), + this, SLOT(slotOpenAboutDialog()) ); - m_tipOfTheDayAction = m_actionCollection->action("tipOfTheDay"); - Q_ASSERT(m_tipOfTheDayAction != 0); - connect(m_tipOfTheDayAction, SIGNAL(triggered()), - this, SLOT(slotOpenTipDialog()) ); + m_tipOfTheDayAction = &m_actionCollection->action("tipOfTheDay"); + BT_CONNECT(m_tipOfTheDayAction, SIGNAL(triggered()), + this, SLOT(slotOpenTipDialog()) ); - #ifdef BT_DEBUG + #ifndef NDEBUG m_debugWidgetAction = new QAction(this); m_debugWidgetAction->setCheckable(true); - connect(m_debugWidgetAction, SIGNAL(triggered(bool)), - this, SLOT(slotShowDebugWindow(bool))); + BT_CONNECT(m_debugWidgetAction, &QAction::triggered, + this, &BibleTime::slotShowDebugWindow); #endif retranslateUiActions(m_actionCollection); @@ -638,8 +620,8 @@ void BibleTime::initMenubar() { // Window menu: m_windowMenu = new QMenu(this); m_openWindowsMenu = new QMenu(this); - QObject::connect(m_openWindowsMenu, SIGNAL(aboutToShow()), - this, SLOT(slotOpenWindowsMenuAboutToShow())); + BT_CONNECT(m_openWindowsMenu, SIGNAL(aboutToShow()), + this, SLOT(slotOpenWindowsMenuAboutToShow())); m_windowMenu->addMenu(m_openWindowsMenu); m_windowMenu->addAction(m_windowCloseAction); m_windowMenu->addAction(m_windowCloseAllAction); @@ -662,8 +644,8 @@ void BibleTime::initMenubar() { m_windowArrangementActionGroup->addAction(m_windowAutoTileAction); m_windowArrangementMenu->addAction(m_windowAutoCascadeAction); m_windowArrangementActionGroup->addAction(m_windowAutoCascadeAction); - connect(m_windowArrangementActionGroup, SIGNAL(triggered(QAction *)), - this, SLOT(slotUpdateWindowArrangementActions(QAction *))); + BT_CONNECT(m_windowArrangementActionGroup, SIGNAL(triggered(QAction *)), + this, SLOT(slotUpdateWindowArrangementActions(QAction *))); m_windowMenu->addMenu(m_windowArrangementMenu); m_windowMenu->addSeparator(); @@ -673,26 +655,26 @@ void BibleTime::initMenubar() { m_windowMenu->addMenu(m_windowLoadProfileMenu); m_windowDeleteProfileMenu = new QMenu(this); m_windowMenu->addMenu(m_windowDeleteProfileMenu); - connect(m_windowLoadProfileMenu, SIGNAL(triggered(QAction*)), - this, SLOT(loadProfile(QAction*))); - connect(m_windowDeleteProfileMenu, SIGNAL(triggered(QAction*)), - this, SLOT(deleteProfile(QAction*))); + BT_CONNECT(m_windowLoadProfileMenu, SIGNAL(triggered(QAction *)), + this, SLOT(loadProfile(QAction *))); + BT_CONNECT(m_windowDeleteProfileMenu, SIGNAL(triggered(QAction *)), + this, SLOT(deleteProfile(QAction *))); refreshProfileMenus(); menuBar()->addMenu(m_windowMenu); - connect(m_windowMenu, SIGNAL(aboutToShow()), - this, SLOT(slotWindowMenuAboutToShow())); + BT_CONNECT(m_windowMenu, SIGNAL(aboutToShow()), + this, SLOT(slotWindowMenuAboutToShow())); #ifndef Q_OS_MAC m_settingsMenu = new QMenu(this); m_settingsMenu->addAction(m_setPreferencesAction); m_settingsMenu->addSeparator(); - m_settingsMenu->addAction(m_bookshelfManagerAction); + m_settingsMenu->addAction(m_bookshelfWizardAction); menuBar()->addMenu(m_settingsMenu); #else // On MAC OS, the settings actions will be moved to a system menu item. // Therefore the settings menu would be empty, so we do not show it. m_fileMenu->addAction(m_setPreferencesAction); - m_fileMenu->addAction(m_bookshelfManagerAction); + m_fileMenu->addAction(m_bookshelfWizardAction); #endif // Help menu: @@ -702,7 +684,7 @@ void BibleTime::initMenubar() { m_helpMenu->addAction(m_tipOfTheDayAction); m_helpMenu->addSeparator(); m_helpMenu->addAction(m_aboutBibleTimeAction); - #ifdef BT_DEBUG + #ifndef NDEBUG m_helpMenu->addSeparator(); m_helpMenu->addAction(m_debugWidgetAction); #endif @@ -716,15 +698,9 @@ void BibleTime::initToolbars() { m_mainToolBar->addWidget(openWorkButton); m_mainToolBar->addAction(m_windowFullscreenAction); - QAction *a = m_actionCollection->action("showBookshelf"); - Q_ASSERT(a != 0); - m_mainToolBar->addAction(a); - a = m_actionCollection->action("showBookmarks"); - Q_ASSERT(a != 0); - m_mainToolBar->addAction(a); - a = m_actionCollection->action("showMag"); - Q_ASSERT(a != 0); - m_mainToolBar->addAction(a); + m_mainToolBar->addAction(&m_actionCollection->action("showBookshelf")); + m_mainToolBar->addAction(&m_actionCollection->action("showBookmarks")); + m_mainToolBar->addAction(&m_actionCollection->action("showMag")); m_mainToolBar->addAction(m_searchOpenWorksAction); m_mainToolBar->addAction(m_openHandbookAction); } @@ -756,7 +732,7 @@ void BibleTime::retranslateUi() { m_helpMenu->setTitle(tr("&Help")); - #ifdef BT_DEBUG + #ifndef NDEBUG m_debugWidgetAction->setText(tr("Show \"Whats this widget\" dialog")); #endif @@ -769,57 +745,48 @@ void BibleTime::retranslateUi() { * The second is used during the use of the configuration shortcut editor */ void BibleTime::retranslateUiActions(BtActionCollection* ac) { - QAction *a = ac->action("showToolbarsInTextWindows"); - Q_ASSERT(a != 0); - a->setText(tr("Show toolbars in text windows")); - a = ac->action("showToolbar"); - Q_ASSERT(a != 0); - a->setText(tr("Show main toolbar")); - a = ac->action("showNavigation"); - Q_ASSERT(a != 0); - a->setText(tr("Show navigation bar")); - a = ac->action("showWorks"); - Q_ASSERT(a != 0); - a->setText(tr("Show works toolbar")); - a = ac->action("showTools"); - Q_ASSERT(a != 0); - a->setText(tr("Show tools toolbar")); - a = ac->action("showFormat"); - Q_ASSERT(a != 0); - a->setText(tr("Show formatting toolbar")); - a = ac->action("showBookshelf"); - Q_ASSERT(a != 0); - a->setText(tr("Show bookshelf")); - a = ac->action("showBookmarks"); - Q_ASSERT(a != 0); - a->setText(tr("Show bookmarks")); - a = ac->action("showMag"); - Q_ASSERT(a != 0); - a->setText(tr("Show mag")); - a = ac->action("showParallelTextHeaders"); - Q_ASSERT(a != 0); - a->setText(tr("Show parallel text headers")); + ac->action("showToolbarsInTextWindows") + .setText(tr("Show toolbars in text windows")); + ac->action("showToolbar").setText(tr("Show main toolbar")); + ac->action("showNavigation").setText(tr("Show navigation bar")); + ac->action("showWorks").setText(tr("Show works toolbar")); + ac->action("showTools").setText(tr("Show tools toolbar")); + ac->action("showFormat").setText(tr("Show formatting toolbar")); + ac->action("showBookshelf").setText(tr("Show bookshelf")); + ac->action("showBookmarks").setText(tr("Show bookmarks")); + ac->action("showMag").setText(tr("Show mag")); + ac->action("showParallelTextHeaders") + .setText(tr("Show parallel text headers")); } /** Initializes the SIGNAL / SLOT connections */ void BibleTime::initConnections() { // Bookmarks page connections: - connect(m_bookmarksPage, SIGNAL(createReadDisplayWindow(QList<CSwordModuleInfo*>, const QString&)), - this, SLOT(createReadDisplayWindow(QList<CSwordModuleInfo*>, const QString&))); + BT_CONNECT(m_bookmarksPage, + SIGNAL(createReadDisplayWindow(QList<CSwordModuleInfo *>, + QString const &)), + this, + SLOT(createReadDisplayWindow(QList<CSwordModuleInfo *>, + QString const &))); // Bookshelf dock connections: - connect(m_bookshelfDock, SIGNAL(moduleOpenTriggered(CSwordModuleInfo*)), - this, SLOT(createReadDisplayWindow(CSwordModuleInfo*))); - connect(m_bookshelfDock, SIGNAL(moduleSearchTriggered(CSwordModuleInfo*)), - this, SLOT(searchInModule(CSwordModuleInfo*))); - connect(m_bookshelfDock, SIGNAL(moduleEditPlainTriggered(CSwordModuleInfo*)), - this, SLOT(moduleEditPlain(CSwordModuleInfo*))); - connect(m_bookshelfDock, SIGNAL(moduleEditHtmlTriggered(CSwordModuleInfo*)), - this, SLOT(moduleEditHtml(CSwordModuleInfo*))); - connect(m_bookshelfDock, SIGNAL(moduleUnlockTriggered(CSwordModuleInfo*)), - this, SLOT(slotModuleUnlock(CSwordModuleInfo*))); - connect(m_bookshelfDock, SIGNAL(moduleAboutTriggered(CSwordModuleInfo*)), - this, SLOT(moduleAbout(CSwordModuleInfo*))); + BT_CONNECT(m_bookshelfDock, SIGNAL(moduleOpenTriggered(CSwordModuleInfo *)), + this, SLOT(createReadDisplayWindow(CSwordModuleInfo *))); + BT_CONNECT(m_bookshelfDock, + SIGNAL(moduleSearchTriggered(CSwordModuleInfo *)), + this, SLOT(searchInModule(CSwordModuleInfo *))); + BT_CONNECT(m_bookshelfDock, + SIGNAL(moduleEditPlainTriggered(CSwordModuleInfo *)), + this, SLOT(moduleEditPlain(CSwordModuleInfo *))); + BT_CONNECT(m_bookshelfDock, + SIGNAL(moduleEditHtmlTriggered(CSwordModuleInfo *)), + this, SLOT(moduleEditHtml(CSwordModuleInfo *))); + BT_CONNECT(m_bookshelfDock, + SIGNAL(moduleUnlockTriggered(CSwordModuleInfo *)), + this, SLOT(slotModuleUnlock(CSwordModuleInfo *))); + BT_CONNECT(m_bookshelfDock, + SIGNAL(moduleAboutTriggered(CSwordModuleInfo *)), + this, SLOT(moduleAbout(CSwordModuleInfo *))); } void BibleTime::initSwordConfigFile() { @@ -867,12 +834,12 @@ void BibleTime::initSwordConfigFile() { void BibleTime::initBackends() { initSwordConfigFile(); - sword::StringMgr::setSystemStringMgr( new BtStringMgr() ); - sword::SWLog::getSystemLog()->setLogLevel(sword::SWLog::LOG_ERROR); + if (!sword::SWMgr::isICU) + sword::StringMgr::setSystemStringMgr(new BtStringMgr()); - if (qApp->property("--debug").toBool()) { - sword::SWLog::getSystemLog()->setLogLevel(sword::SWLog::LOG_DEBUG); - } + sword::SWLog::getSystemLog()->setLogLevel(btApp->debugMode() + ? sword::SWLog::LOG_DEBUG + : sword::SWLog::LOG_ERROR); #ifdef Q_OS_MAC // set a LocaleMgr with a fixed path to the locales.d of the DMG image on MacOS @@ -887,49 +854,13 @@ void BibleTime::initBackends() { sync with the language of the book names displayed, so that both would always use the same setting. */ - BtLanguageSettingsPage::resetLanguage(); /// \todo refactor this hack + CDisplaySettingsPage::resetLanguage(); /// \todo refactor this hack CSwordBackend *backend = CSwordBackend::createInstance(); - backend->booknameLanguage(btConfig().value<QString>("language", QLocale::system().name())); - - const CSwordBackend::LoadError errorCode = CSwordBackend::instance()->initModules(CSwordBackend::OtherChange); - - if (errorCode != CSwordBackend::NoError) { - //show error message that initBackend failed - /// \todo -// switch (errorCode) { -// case CSwordBackend::NoSwordConfig: //mods.d or mods.conf missing -// { -// KStartupLogo::hideSplash(); -// qDebug() << "case CSwordBackend::NoSwordConfig"; -// BookshelfManager::CSwordSetupDialog dlg; -// dlg.showPart( BookshelfManager::CSwordSetupDialog::Sword ); -// dlg.exec(); -// break; -// } -// -// case CSwordBackend::NoModules: //no modules installed, but config exists -// { -// KStartupLogo::hideSplash(); -// qDebug() << "case CSwordBackend::NoModules"; -// BookshelfManager::CSwordSetupDialog dlg; -// dlg.showPart( BookshelfManager::CSwordSetupDialog::Install ); -// dlg.exec(); -// break; -// } -// -// default: //unknown error -// { -// KStartupLogo::hideSplash(); -// qDebug() << "unknown error"; -// BookshelfManager::CSwordSetupDialog dlg; -// dlg.showPart( BookshelfManager::CSwordSetupDialog::Sword ); -// dlg.exec(); -// break; -// } -// } - } + backend->booknameLanguage(btConfig().value<QString>("GUI/booknameLanguage", QLocale::system().name())); + + CSwordBackend::instance()->initModules(CSwordBackend::OtherChange); // This function will // - delete all orphaned indexes (no module present) if autoDeleteOrphanedIndices is true @@ -938,25 +869,30 @@ void BibleTime::initBackends() { } -#if BT_DEBUG +#ifndef NDEBUG -QLabel *BibleTime::m_debugWindow = 0; +QLabel *BibleTime::m_debugWindow = nullptr; QMutex BibleTime::m_debugWindowLock; void BibleTime::slotShowDebugWindow(bool show) { if (show) { QMutexLocker lock(&m_debugWindowLock); - if (m_debugWindow == 0) { - m_debugWindow = new QLabel(0, Qt::Dialog); + if (m_debugWindow == nullptr) { + m_debugWindow = new QLabel(nullptr, Qt::Dialog); m_debugWindow->setAttribute(Qt::WA_DeleteOnClose); m_debugWindow->setTextFormat(Qt::RichText); m_debugWindow->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); m_debugWindow->setWindowTitle(tr("Whats this widget?")); } m_debugWindow->show(); - connect(m_debugWindow, SIGNAL(destroyed()), - this, SLOT(slotDebugWindowClosing()), Qt::DirectConnection); + BT_CONNECT(m_debugWindow, &QObject::destroyed, + this, &BibleTime::slotDebugWindowClosing, + Qt::DirectConnection); + #if QT_VERSION < 0x050400 QTimer::singleShot(0, this, SLOT(slotDebugTimeout())); + #else + QTimer::singleShot(0, this, &BibleTime::slotDebugTimeout); + #endif } else { deleteDebugWindow(); } @@ -964,36 +900,40 @@ void BibleTime::slotShowDebugWindow(bool show) { void BibleTime::deleteDebugWindow() { QMutexLocker lock(&m_debugWindowLock); - if (m_debugWindow != 0) { - m_debugWindow->disconnect(SIGNAL(destroyed()), this, SLOT(slotDebugWindowClosing())); + if (m_debugWindow != nullptr) { + disconnect(m_debugWindow, &QObject::destroyed, + this, &BibleTime::slotDebugWindowClosing); delete m_debugWindow; - m_debugWindow = 0; + m_debugWindow = nullptr; } } void BibleTime::slotDebugWindowClosing() { QMutexLocker lock(&m_debugWindowLock); - m_debugWindow = 0; + m_debugWindow = nullptr; m_debugWidgetAction->setChecked(false); } void BibleTime::slotDebugTimeout() { QMutexLocker lock(&m_debugWindowLock); - if (m_debugWindow == 0 || m_debugWindow->isVisible() == false) return; - + if (!m_debugWindow || m_debugWindow->isVisible() == false) + return; + #if QT_VERSION < 0x050400 QTimer::singleShot(0, this, SLOT(slotDebugTimeout())); - QObject *w = QApplication::widgetAt(QCursor::pos()); - if (w != 0) { + #else + QTimer::singleShot(0, this, &BibleTime::slotDebugTimeout); + #endif + if (QObject const * w = QApplication::widgetAt(QCursor::pos())) { QString objectHierarchy; do { - const QMetaObject *m = w->metaObject(); + QMetaObject const * m = w->metaObject(); QString classHierarchy; do { - if (!classHierarchy.isEmpty()) classHierarchy += ": "; + if (!classHierarchy.isEmpty()) + classHierarchy += ": "; classHierarchy += m->className(); - m = m->superClass(); - } while (m != 0); + } while (m); if (!objectHierarchy.isEmpty()) { objectHierarchy += "<br/><b>child of:</b> "; } else { @@ -1001,7 +941,7 @@ void BibleTime::slotDebugTimeout() { } objectHierarchy += classHierarchy; w = w->parent(); - } while (w != 0); + } while (w); m_debugWindow->setText(objectHierarchy); } else { m_debugWindow->setText("No widget"); diff --git a/src/bibletime_slots.cpp b/src/bibletime_slots.cpp index 0572f73..d28c9b6 100644 --- a/src/bibletime_slots.cpp +++ b/src/bibletime_slots.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -27,7 +27,7 @@ #include "frontend/btaboutdialog.h" #include "frontend/cinfodisplay.h" #include "frontend/cmdiarea.h" -#include "frontend/bookshelfmanager/btmodulemanagerdialog.h" +#include "frontend/bookshelfwizard/btbookshelfwizard.h" #include "frontend/display/btfindwidget.h" #include "frontend/displaywindow/btmodulechooserbar.h" #include "frontend/displaywindow/cdisplaywindow.h" @@ -35,6 +35,8 @@ #include "frontend/searchdialog/csearchdialog.h" #include "frontend/settingsdialogs/cconfigurationdialog.h" #include "frontend/tips/bttipdialog.h" +#include "util/btassert.h" +#include "util/btconnect.h" #include "util/directory.h" @@ -42,14 +44,15 @@ void BibleTime::slotSettingsOptions() { qDebug() << "BibleTime::slotSettingsOptions"; CConfigurationDialog *dlg = new CConfigurationDialog(this, m_actionCollection); - QObject::connect(dlg, SIGNAL(signalSettingsChanged()), this, SLOT(slotSettingsChanged()) ); + BT_CONNECT(dlg, SIGNAL(signalSettingsChanged()), + this, SLOT(slotSettingsChanged()) ); dlg->show(); } /** Save the settings, used when no settings have been saved before **/ void BibleTime::saveConfigSettings() { - CConfigurationDialog* dlg = new CConfigurationDialog(this, 0); + CConfigurationDialog* dlg = new CConfigurationDialog(this, nullptr); dlg->save(); delete dlg; } @@ -57,7 +60,7 @@ void BibleTime::saveConfigSettings() { /** Is called when settings in the optionsdialog were changed (ok or apply) */ void BibleTime::slotSettingsChanged() { qDebug() << "BibleTime::slotSettingsChanged"; - const QString language = btConfig().value<QString>("language", QLocale::system().name()); + const QString language = btConfig().value<QString>("GUI/booknameLanguage", QLocale::system().name()); CSwordBackend::instance()->booknameLanguage(language); // \todo update the bookmarks after Bible bookname language has been changed @@ -70,25 +73,21 @@ void BibleTime::slotSettingsChanged() { // ++it; // } - refreshBibleTimeAccel(); + m_actionCollection->readShortcuts("Application shortcuts"); refreshDisplayWindows(); refreshProfileMenus(); qDebug() << "BibleTime::slotSettingsChanged"; } -/** Opens the sword setup dialog of BibleTime. */ -void BibleTime::slotSwordSetupDialog() { - BtModuleManagerDialog *dlg = BtModuleManagerDialog::getInstance(this); - - dlg->showNormal(); - dlg->show(); - dlg->raise(); - dlg->activateWindow(); +/** Opens the bookshelf wizard. */ +void BibleTime::slotBookshelfWizard() { + BtBookshelfWizard dlg(BibleTime::instance()); + dlg.exec(); } /** Is called just before the window menu is shown. */ void BibleTime::slotWindowMenuAboutToShow() { - Q_ASSERT(m_windowMenu); + BT_ASSERT(m_windowMenu); const int numSubWindows = m_mdi->subWindowList().count(); m_windowCloseAction->setEnabled(numSubWindows); @@ -104,21 +103,22 @@ void BibleTime::slotWindowMenuAboutToShow() { /** Is called just before the open windows menu is shown. */ void BibleTime::slotOpenWindowsMenuAboutToShow() { - Q_ASSERT(m_openWindowsMenu); + BT_ASSERT(m_openWindowsMenu); m_openWindowsMenu->clear(); Q_FOREACH (QMdiSubWindow * const window, m_mdi->usableWindowList()) { QAction *openWindowAction = m_openWindowsMenu->addAction(window->windowTitle()); openWindowAction->setCheckable(true); openWindowAction->setChecked(window == m_mdi->activeSubWindow()); - connect(openWindowAction, SIGNAL(triggered()), m_windowMapper, SLOT(map())); + BT_CONNECT(openWindowAction, SIGNAL(triggered()), + m_windowMapper, SLOT(map())); m_windowMapper->setMapping(openWindowAction, window); } } /** This slot is connected with the windowAutoTileAction object */ void BibleTime::slotUpdateWindowArrangementActions(QAction * trigerredAction) { - Q_ASSERT(trigerredAction); + BT_ASSERT(trigerredAction); if (trigerredAction == m_windowAutoTileVerticalAction) { m_mdi->setMDIArrangementMode(CMDIArea::ArrangementModeTileVertical); @@ -141,7 +141,7 @@ void BibleTime::slotUpdateWindowArrangementActions(QAction * trigerredAction) { btConfig().setSessionValue("GUI/alignmentMode", autoCascade); } else { - Q_ASSERT(trigerredAction == m_windowManualModeAction + BT_ASSERT(trigerredAction == m_windowManualModeAction || trigerredAction == m_windowTileAction || trigerredAction == m_windowCascadeAction || trigerredAction == m_windowTileVerticalAction @@ -187,7 +187,7 @@ void BibleTime::slotTileHorizontal() { /** Shows/hides the toolbar */ void BibleTime::slotToggleMainToolbar() { - Q_ASSERT(m_mainToolBar); + BT_ASSERT(m_mainToolBar); bool currentState = btConfig().sessionValue<bool>("GUI/showMainToolbar", true); btConfig().setSessionValue("GUI/showMainToolbar", !currentState); if ( m_showMainWindowToolbarAction->isChecked()) { @@ -282,11 +282,11 @@ void BibleTime::slotSetActiveSubWindow(QWidget* window) { void BibleTime::slotSearchModules() { //get the modules of the open windows - QList<const CSwordModuleInfo*> modules; + BtConstModuleList modules; Q_FOREACH (const QMdiSubWindow * const subWindow, m_mdi->subWindowList()) { const CDisplayWindow * const w = dynamic_cast<CDisplayWindow*>(subWindow->widget()); - if (w != 0) { + if (w != nullptr) { modules << w->modules(); } } @@ -295,7 +295,7 @@ void BibleTime::slotSearchModules() { void BibleTime::slotActiveWindowChanged(QMdiSubWindow* window) { - if (window == 0) + if (window == nullptr) m_findWidget->setVisible(false); } @@ -303,7 +303,7 @@ void BibleTime::slotActiveWindowChanged(QMdiSubWindow* window) * Call CSearchDialog::openDialog with only the default bible module */ void BibleTime::slotSearchDefaultBible() { - QList<const CSwordModuleInfo*> module; + BtConstModuleList module; CSwordModuleInfo* bible = btConfig().getDefaultSwordModuleByType("standardBible"); if (bible) { module.append(bible); @@ -357,15 +357,15 @@ void BibleTime::saveProfile() { } void BibleTime::loadProfile(QAction * action) { - Q_ASSERT(action); + BT_ASSERT(action); QVariant keyProperty = action->property("ProfileKey"); - Q_ASSERT(keyProperty.type() == QVariant::String); - Q_ASSERT(btConfig().sessionNames().contains(keyProperty.toString())); + BT_ASSERT(keyProperty.type() == QVariant::String); + BT_ASSERT(btConfig().sessionNames().contains(keyProperty.toString())); loadProfile(keyProperty.toString()); } void BibleTime::loadProfile(const QString & profileKey) { - Q_ASSERT(btConfig().sessionNames().contains(profileKey)); + BT_ASSERT(btConfig().sessionNames().contains(profileKey)); // do nothing if requested session is the current session if (profileKey == btConfig().currentSessionKey()) @@ -387,7 +387,7 @@ namespace { /// Helper object for reloadProfile() struct WindowLoadStatus { - inline WindowLoadStatus() : window(0) {} + inline WindowLoadStatus() : window(nullptr) {} QStringList failedModules; QList<CSwordModuleInfo*> okModules; CDisplayWindow * window; @@ -396,8 +396,8 @@ struct WindowLoadStatus { } // anonymous namespace void BibleTime::reloadProfile() { - typedef CMDIArea::MDIArrangementMode MAM; - typedef CPlainWriteWindow::WriteWindowType WWT; + using MAM = CMDIArea::MDIArrangementMode; + using WWT = CPlainWriteWindow::WriteWindowType; using message::setQActionCheckedNoTrigger; // Cache pointer to config: @@ -427,11 +427,12 @@ void BibleTime::reloadProfile() { setQActionCheckedNoTrigger(m_showFormatToolbarAction, conf.sessionValue<bool>("GUI/showFormatToolbarButtons", true)); setQActionCheckedNoTrigger(m_toolbarsInEachWindow, conf.sessionValue<bool>("GUI/showToolbarsInEachWindow", true)); - m_mdi->setMDIArrangementMode(static_cast<MAM>(conf.sessionValue<int>("MainWindow/MDIArrangementMode"))); + m_mdi->setMDIArrangementMode(static_cast<MAM>( + conf.sessionValue<int>("MainWindow/MDIArrangementMode",CMDIArea::ArrangementModeTile))); m_findWidget->setVisible(conf.sessionValue<bool>("FindIsVisible", false)); - QWidget * focusWindow = 0; + QWidget * focusWindow = nullptr; QMap<QString, WindowLoadStatus> failedWindows; Q_FOREACH (const QString & w, conf.sessionValue<QStringList>("windowsList")) @@ -462,7 +463,7 @@ void BibleTime::reloadProfile() { failedWindows.insert(w, wls); // Try to respawn the window: - Q_ASSERT(!wls.window); + BT_ASSERT(!wls.window); const QString key = conf.sessionValue<QString>(windowGroup + "key"); WWT wwt = static_cast<WWT>(conf.sessionValue<int>(windowGroup + "writeWindowType", 0)); if (wwt > 0) { @@ -505,10 +506,10 @@ void BibleTime::reloadProfile() { } void BibleTime::deleteProfile(QAction* action) { - Q_ASSERT(action); + BT_ASSERT(action); QVariant keyProperty = action->property("ProfileKey"); - Q_ASSERT(keyProperty.type() == QVariant::String); - Q_ASSERT(btConfig().sessionNames().contains(keyProperty.toString())); + BT_ASSERT(keyProperty.type() == QVariant::String); + BT_ASSERT(btConfig().sessionNames().contains(keyProperty.toString())); /// \todo Ask for confirmation btConfig().deleteSession(keyProperty.toString()); @@ -561,8 +562,8 @@ void BibleTime::saveToNewProfile() { /** Slot to refresh the saved profile and load profile menus. */ void BibleTime::refreshProfileMenus() { - typedef BtConfig::SessionNamesHashMap SNHM; - typedef SNHM::const_iterator SNHMCI; + using SNHM = BtConfig::SessionNamesHashMap; + using SNHMCI = SNHM::const_iterator; m_windowLoadProfileMenu->clear(); m_windowDeleteProfileMenu->clear(); diff --git a/src/bibletimeapp.cpp b/src/bibletimeapp.cpp index c8e4274..9871570 100644 --- a/src/bibletimeapp.cpp +++ b/src/bibletimeapp.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -10,25 +10,34 @@ #include "bibletimeapp.h" #include <QDebug> -#include <QFile> +#include <QPainter> +#include <QtGlobal> #include "frontend/messagedialog.h" #include "backend/config/btconfig.h" #include "backend/managers/cswordbackend.h" #include "backend/managers/cdisplaytemplatemgr.h" -#include "util/geticon.h" +#include "util/btassert.h" +#include "util/bticons.h" BibleTimeApp::BibleTimeApp(int &argc, char **argv) : QApplication(argc, argv) , m_init(false) + , m_debugMode(false) + , m_icons(nullptr) { setApplicationName("bibletime"); setApplicationVersion(BT_VERSION); + + // Support for retina displays + #if QT_VERSION >= 0x050200 + this->setAttribute(Qt::AA_UseHighDpiPixmaps); + #endif } BibleTimeApp::~BibleTimeApp() { // Prevent writing to the log file before the directory cache is init: - if (!m_init || BtConfig::m_instance == 0) + if (!m_init || BtConfig::m_instance == nullptr) return; //we can set this safely now because we close now (hopyfully without crash) @@ -38,25 +47,61 @@ BibleTimeApp::~BibleTimeApp() { delete CDisplayTemplateMgr::instance(); CLanguageMgr::destroyInstance(); CSwordBackend::destroyInstance(); - util::clearIconCache(); + delete m_icons; BtConfig::destroyInstance(); } bool BibleTimeApp::initBtConfig() { - Q_ASSERT(m_init); + BT_ASSERT(m_init); - return BtConfig::initBtConfig(); + BtConfig::InitState const r = BtConfig::initBtConfig(); + if (r == BtConfig::INIT_OK) + return true; + if (r == BtConfig::INIT_NEED_UNIMPLEMENTED_FORWARD_MIGRATE) { + /// \todo Migrate from btConfigOldApi to BTCONFIG_API_VERSION + qWarning() << "BibleTime configuration migration is not yet implemented!!!"; + if (message::showWarning( + nullptr, + tr("Warning!"), + tr("Migration to the new configuration system is not yet " + "implemented. Proceeding might result in <b>loss of data" + "</b>. Please backup your configuration files before " + "you continue!<br/><br/>Do you want to continue? Press " + "\"No\" to quit BibleTime immediately."), + QMessageBox::Yes | QMessageBox::No, + QMessageBox::No) == QMessageBox::No) + return false; + } else { + BT_ASSERT(r == BtConfig::INIT_NEED_UNIMPLEMENTED_BACKWARD_MIGRATE); + if (message::showWarning( + nullptr, + tr("Error loading configuration!"), + tr("Failed to load BibleTime's configuration, because it " + "appears that the configuration file corresponds to a " + "newer version of BibleTime. This is likely caused by " + "BibleTime being downgraded. Loading the new " + "configuration file may result in <b>loss of data</b>." + "<br/><br/>Do you still want to try to load the new " + "configuration file? Press \"No\" to quit BibleTime " + "immediately."), + QMessageBox::Yes | QMessageBox::No, + QMessageBox::No) == QMessageBox::No) + return false; + } + BtConfig::forceMigrate(); + return true; } bool BibleTimeApp::initDisplayTemplateManager() { - Q_ASSERT(m_init); + BT_ASSERT(m_init); QString errorMessage; new CDisplayTemplateMgr(errorMessage); if (errorMessage.isNull()) return true; - message::showCritical(0, tr("Fatal error!"), errorMessage); + message::showCritical(nullptr, tr("Fatal error!"), errorMessage); return false; } +void BibleTimeApp::initIcons() { m_icons = new BtIcons(); } diff --git a/src/bibletimeapp.h b/src/bibletimeapp.h index 23a1ce8..428ec2a 100644 --- a/src/bibletimeapp.h +++ b/src/bibletimeapp.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -15,6 +15,8 @@ #include <QApplication> +class BtIcons; + /** The BibleTimeApp class is used to clean up all instances of the backend and to delete all created module objects. @@ -28,16 +30,25 @@ class BibleTimeApp : public QApplication { BibleTimeApp(int &argc, char **argv); ~BibleTimeApp(); - inline void startInit() { m_init = true; } + inline void startInit(bool const debugMode = false) { + m_init = true; + m_debugMode = debugMode; + } + bool initBtConfig(); bool initDisplayTemplateManager(); + void initIcons(); + + bool debugMode() const { return m_debugMode; } private: /* Fields: */ bool m_init; + bool m_debugMode; + BtIcons * m_icons; }; -#define bApp (static_cast<BibleTimeApp *>(QCoreApplication::instance())) +#define btApp (static_cast<BibleTimeApp *>(BibleTimeApp::instance())) #endif diff --git a/src/btglobal.cpp b/src/btglobal.cpp deleted file mode 100644 index 53c274c..0000000 --- a/src/btglobal.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include "btglobal.h" - -#include <QDataStream> - - -QDataStream &operator<<(QDataStream &out, const alignmentMode &mode) { - out << (qint8) mode; - return out; -} - -QDataStream &operator>>(QDataStream &in, alignmentMode &mode) { - qint8 i; - in >> i; - mode = (alignmentMode) i; - return in; -} diff --git a/src/display-templates/Basic-mobile.tmpl b/src/display-templates/Basic-mobile.tmpl new file mode 100644 index 0000000..1c66661 --- /dev/null +++ b/src/display-templates/Basic-mobile.tmpl @@ -0,0 +1,43 @@ +<html> +<head> + <title>#TITLE#</title> + <style type="text/css"> + +a:link { + color: #LINK_COLOR#; + text-decoration: none +} + +.chaptertitle { + font-weight: bold; + font-size: x-large +} + +.sectiontitle { + font-weight: bold; + font-size: medium +} + +.highlightwords { + color: #HIGHLIGHT_COLOR#; + font-weight: bold; + background-color: #FFEECC; +} + +.jesuswords { + color: #JESUS_WORDS_COLOR#; + font-size: 0.9em; +} + +.entry + .sectiontitle { + margin-top:35px; +} + +</style> +</head> + +<body id="#DISPLAYTYPE#" class="#MODTYPE# #MODTYPE#_#MODNAME#"> + <div class="chaptertitle"><center>#CHAPTERTITLE#</center></div> + <div id="content" lang="#LANG_ABBREV#" xml:lang="#LANG_ABBREV#" dir="#PAGE_DIRECTION#">#CONTENT#</div> +</body> +</html> diff --git a/src/display-templates/Blue.css b/src/display-templates/Blue.css index eafe85b..148eb37 100644 --- a/src/display-templates/Blue.css +++ b/src/display-templates/Blue.css @@ -33,6 +33,9 @@ a:hover { padding:0 2px; } +.inline { + display: inline; +} /* Settings which apply to all entries in all modules */ .entry { @@ -65,6 +68,9 @@ td.entry, td.currententry { .currententry[dir=rtl] { text-align:right !important; } +.currententry.inline { + line-height:1.4em; +} div.currententry { } span.currententry { @@ -318,3 +324,7 @@ td.entry + td.entry { border-bottom:1px solid black; color:black; } + +.highlightwords { + background-color: #ffff66; +} diff --git a/src/display-templates/Christmastide.css b/src/display-templates/Christmastide.css index bc65e76..d7b55a4 100644 --- a/src/display-templates/Christmastide.css +++ b/src/display-templates/Christmastide.css @@ -32,6 +32,10 @@ a { padding:2px; } +.inline { + display: inline; +} + td.entry, div.entry { padding: 5px; vertical-align: top; @@ -40,7 +44,6 @@ td.entry, div.entry { div.entry { padding: 5px; } - td.currententry, div.currententry { padding: 5px; vertical-align: top; @@ -131,3 +134,7 @@ div.currententry { .italic { font-style: italic; } + +.highlightwords { + background-color: #ffff66; +} diff --git a/src/display-templates/Crazy.css b/src/display-templates/Crazy.css index e404fc3..1cb5145 100644 --- a/src/display-templates/Crazy.css +++ b/src/display-templates/Crazy.css @@ -41,6 +41,10 @@ body { a { color:#FF0004; padding:0; } a:hover { } +.inline { + display: inline; +} + /* An entry is the generic element used for all content items. In Bibles an entry contains a verse, in commentaries the comment to a verse range, in lexicons an simple item and in book the text of an item with other .entry elements as childs. @@ -76,12 +80,13 @@ td.entry, td.currententry { */ .currententry { padding:0.3em; - line-height:1.6em; background-color:#D3E5FF; /*border: thin solid black;*/ } - +.currententry.inline { + line-height:1.6em; +} table .currententry:nth-child(1) { margin-left:0; border-left:10px solid #99B4FF; @@ -298,3 +303,7 @@ so something like .alternative:before { content:"'"attr(alternative); } is possi #printer .rangeheading {} *[dir=rtl] { text-align:right !important; } + +.highlightwords { + background-color: #ffff66; +} diff --git a/src/display-templates/Green.css b/src/display-templates/Green.css index 4be46b9..aaf7ef6 100644 --- a/src/display-templates/Green.css +++ b/src/display-templates/Green.css @@ -35,6 +35,10 @@ a:hover { padding:0 2px; } +.inline { + display: inline; +} + /* Settings which apply to all entries in all modules */ .entry { @@ -64,6 +68,9 @@ td.entry, td.currententry { .currententry[dir=rtl] { text-align:right !important; } +.currententry.inline { + line-height:1.4em; +} div.currententry { } span.currententry { @@ -298,3 +305,7 @@ td.entry + td.entry { border-bottom:1px solid black; color:black; } + +.highlightwords { + background-color: #ffff66; +} diff --git a/src/display-templates/HighContrast.css b/src/display-templates/HighContrast.css index 0dd1053..eea4faa 100644 --- a/src/display-templates/HighContrast.css +++ b/src/display-templates/HighContrast.css @@ -39,6 +39,10 @@ a:hover { text-decoration:underline; } +.inline { + display: inline; +} + /* Settings which apply to all entries in all modules */ .entry { padding: 2px; @@ -67,6 +71,9 @@ div.entry, td.entry, td.currententry { .currententry[dir=rtl] { text-align: right; } +.currententry.inline { + line-height:1.4em; +} div.currententry { } span.currententry { @@ -310,3 +317,7 @@ td.entry + td.entry { border-bottom: 1px solid black; color: black; } + +.highlightwords { + background-color: #ffff66; +} diff --git a/src/display-templates/Simple.css b/src/display-templates/Simple.css index 32ec57f..1482c95 100644 --- a/src/display-templates/Simple.css +++ b/src/display-templates/Simple.css @@ -29,6 +29,10 @@ a { padding:2px; } +.inline { + display: inline; +} + td.entry, div.entry { padding: 5px; vertical-align: top; @@ -116,3 +120,7 @@ div.currententry { .italic { font-style: italic; } + +.highlightwords { + background-color: #ffff66; +} diff --git a/src/display-templates/basic_template.txt b/src/display-templates/basic_template.txt index dc98ab6..39f69fc 100644 --- a/src/display-templates/basic_template.txt +++ b/src/display-templates/basic_template.txt @@ -9,6 +9,10 @@ a { } a:hover { } +.inline { + display: inline; +} + /* An entry is the generic element used for all content items. In Bibles an entry contains a verse, in commentaries the comment to a verse range, in lexicons an simple item and in book the text of an item with other .entry elements as childs. @@ -175,4 +179,4 @@ so something like .alternative:before { content:"'"attr(alternative); } is possi #infodisplay .entryname { } #infodisplay .rangeheading {} -#printer .rangeheading {}
\ No newline at end of file +#printer .rangeheading {} diff --git a/src/frontend/bookmarks/btbookmarkfolder.cpp b/src/frontend/bookmarks/btbookmarkfolder.cpp deleted file mode 100644 index 3088e99..0000000 --- a/src/frontend/bookmarks/btbookmarkfolder.cpp +++ /dev/null @@ -1,122 +0,0 @@ -/********* -* -* 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 "frontend/bookmarks/btbookmarkfolder.h" - -#include <QFileDialog> -#include "bibletimeapp.h" -#include "frontend/bookmarks/btbookmarkitembase.h" -#include "frontend/bookmarks/btbookmarkitem.h" -#include "frontend/bookmarks/btbookmarkloader.h" -#include "util/cresmgr.h" -#include "util/geticon.h" - - -BtBookmarkFolder::BtBookmarkFolder(const QString &name, QTreeWidgetItem *parent) - : BtBookmarkItemBase(parent) { - setText(0, name); - setFlags(Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsEnabled); -} - -bool BtBookmarkFolder::enableAction(MenuAction action) { - if (action == ChangeFolder || action == NewFolder || action == DeleteEntries || action == ImportBookmarks ) - return true; - if (action == SortFolderBookmarks || action == ExportBookmarks || action == ImportBookmarks ) - return true; - if ((action == PrintBookmarks) && childCount()) - return true; - return false; -} - -void BtBookmarkFolder::exportBookmarks() { - QString filter = QObject::tr("BibleTime bookmark files") + QString(" (*.btb);;") + QObject::tr("All files") + QString(" (*.*)"); - QString fileName = QFileDialog::getSaveFileName(0, QObject::tr("Export Bookmarks"), "", filter); - - if (!fileName.isEmpty()) { - BtBookmarkLoader loader; - loader.saveTreeFromRootItem(this, fileName, false ); //false: don't overwrite without asking - }; - -} - -void BtBookmarkFolder::importBookmarks() { - QString filter = QObject::tr("BibleTime bookmark files") + QString(" (*.btb);;") + QObject::tr("All files") + QString(" (*.*)"); - QString fileName = QFileDialog::getOpenFileName(0, QObject::tr("Import bookmarks"), "", filter); - if (!fileName.isEmpty()) { - BtBookmarkLoader loader; - QList<QTreeWidgetItem*> itemList = loader.loadTree(fileName); - this->insertChildren(0, itemList); - }; -} - -void BtBookmarkFolder::newSubFolder() { - if (dynamic_cast<BtBookmarkFolder*>(this)) { - BtBookmarkFolder* f = new BtBookmarkFolder(QObject::tr("New folder"), this); - - treeWidget()->setCurrentItem(f); - f->update(); - f->rename(); - } -} - -QList<QTreeWidgetItem*> BtBookmarkFolder::getChildList() const { - QList<QTreeWidgetItem*> list; - for (int i = 0; i < childCount(); i++) { - list.append(child(i)); - } - return list; -} - -void BtBookmarkFolder::rename() { - treeWidget()->editItem(this); -} - -void BtBookmarkFolder::update() { - setIcon(0, util::getIcon(isExpanded() && childCount() - ? CResMgr::mainIndex::openedFolder::icon - : CResMgr::mainIndex::closedFolder::icon)); -} - -bool BtBookmarkFolder::hasDescendant(QTreeWidgetItem* item) const { - if (this == item) { - return true; - } - if (getChildList().indexOf(item) > -1) { - return true; - } - foreach(QTreeWidgetItem* childItem, getChildList()) { - bool subresult = false; - BtBookmarkFolder* folder = 0; - if ( (folder = dynamic_cast<BtBookmarkFolder*>(childItem)) ) { - subresult = folder->hasDescendant(childItem); - } - - if (subresult == true) { - return true; - } - } - return false; -} - -BtBookmarkFolder* BtBookmarkFolder::deepCopy() { - BtBookmarkFolder* newFolder = new BtBookmarkFolder(this->text(0)); - foreach(QTreeWidgetItem* subitem, getChildList()) { - if (BtBookmarkItem* bmItem = dynamic_cast<BtBookmarkItem*>(subitem)) { - newFolder->addChild(new BtBookmarkItem(*bmItem)); - } - else { - if (BtBookmarkFolder* bmFolder = dynamic_cast<BtBookmarkFolder*>(subitem)) { - newFolder->addChild(bmFolder->deepCopy()); - } - } - } - newFolder->update(); - return newFolder; -} - diff --git a/src/frontend/bookmarks/btbookmarkfolder.h b/src/frontend/bookmarks/btbookmarkfolder.h deleted file mode 100644 index 4f7c80c..0000000 --- a/src/frontend/bookmarks/btbookmarkfolder.h +++ /dev/null @@ -1,50 +0,0 @@ -/********* -* -* 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 BTBOOKMARKFOLDER_H -#define BTBOOKMARKFOLDER_H - -#include "frontend/bookmarks/btbookmarkitembase.h" - - -#define CURRENT_SYNTAX_VERSION 1 - -class BtBookmarkFolder : public BtBookmarkItemBase { - public: - - BtBookmarkFolder(const QString &name, QTreeWidgetItem *parent = 0); - - /** See the base class. */ - virtual bool enableAction(const MenuAction action); - - /** User gives a file from which to load items into this folder. */ - virtual void exportBookmarks(); - /** User gives a file to which items from this folder are saved. */ - virtual void importBookmarks(); - - /** Creates a new folder under this. */ - void newSubFolder(); - - /** Returns a list of direct childs of this item. */ - QList<QTreeWidgetItem*> getChildList() const; - - /** Returns true if the given item is this or a direct or indirect subitem of this. */ - bool hasDescendant(QTreeWidgetItem* item) const; - - /** Creates a deep copy of this item. */ - BtBookmarkFolder* deepCopy(); - - void rename(); - void update(); - -}; - -#endif diff --git a/src/frontend/bookmarks/btbookmarkitem.cpp b/src/frontend/bookmarks/btbookmarkitem.cpp deleted file mode 100644 index 952be22..0000000 --- a/src/frontend/bookmarks/btbookmarkitem.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/********* -* -* 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 "frontend/bookmarks/btbookmarkitem.h" - -#include <QSharedPointer> -#include "backend/config/btconfig.h" -#include "backend/managers/cswordbackend.h" -#include "backend/drivers/cswordmoduleinfo.h" -#include "backend/keys/cswordversekey.h" -#include "bibletimeapp.h" -#include "btglobal.h" -#include "frontend/bookmarks/btbookmarkfolder.h" -#include "frontend/bookmarks/bteditbookmarkdialog.h" -#include "util/cresmgr.h" -#include "util/geticon.h" - - -BtBookmarkItem::BtBookmarkItem(const CSwordModuleInfo *module, - const QString &key, - const QString &description, - const QString &title) - : m_description(description), - m_moduleName(module ? module->name() : QString::null), - m_title(title) -{ - if (((module && (module->type() == CSwordModuleInfo::Bible)) || (module->type() == CSwordModuleInfo::Commentary)) ) { - CSwordVerseKey vk(0); - vk.setKey(key); - vk.setLocale("en"); - m_key = vk.key(); //the m_key member is always the english key! - } - else { - m_key = key; - }; - - update(); -} - -BtBookmarkItem::BtBookmarkItem(QTreeWidgetItem* parent) - : BtBookmarkItemBase(parent) {} - -BtBookmarkItem::BtBookmarkItem(const BtBookmarkItem& other) - : BtBookmarkItemBase(0), - m_key(other.m_key), - m_description(other.m_description), - m_moduleName(other.m_moduleName), - m_title(other.m_title) -{ - update(); -} - -CSwordModuleInfo *BtBookmarkItem::module() const { - return CSwordBackend::instance()->findModuleByName(m_moduleName); -} - -QString BtBookmarkItem::key() const { - const QString englishKeyName = englishKey(); - if (!module()) { - return englishKeyName; - } - - QString returnKeyName = englishKeyName; - if ((module()->type() == CSwordModuleInfo::Bible) || (module()->type() == CSwordModuleInfo::Commentary)) { - CSwordVerseKey vk(0); - vk.setKey(englishKeyName); - vk.setLocale(CSwordBackend::instance()->booknameLanguage().toLatin1() ); - - returnKeyName = vk.key(); //the returned key is always in the currently set bookname language - } - - return returnKeyName; -} - -QString BtBookmarkItem::toolTip() const { - if (!module()) { - return QString::null; - } - - FilterOptions filterOptions = btConfig().getFilterOptions(); - filterOptions.footnotes = false; - filterOptions.scriptureReferences = false; - CSwordBackend::instance()->setFilterOptions(filterOptions); - - QString ret; - QSharedPointer<CSwordKey> k( CSwordKey::createInstance(module()) ); - k->setKey(key()); - - // const CLanguageMgr::Language* lang = module()->language(); - // BtConfig::FontSettingsPair fontPair = getBtConfig().getFontForLanguage(lang); - - Q_ASSERT(k.data()); - QString header = QString::fromLatin1("%1 (%2)") - .arg(key()) - .arg(module()->name()); - if (title() != header) { - ret = QString::fromLatin1("<b>%1</b><br>%2<hr>%3") - .arg(header) - .arg(title()) - .arg(description()) - ; - } - else { - ret = QString::fromLatin1("<b>%1</b><hr>%2") - .arg(header) - .arg(description()) - ; - } - - return ret; -} - -bool BtBookmarkItem::enableAction(MenuAction action) { - if (action == EditBookmark || (module() && (action == PrintBookmarks)) || action == DeleteEntries) - return true; - - return false; -} - -void BtBookmarkItem::rename() { - BtEditBookmarkDialog d(QString::fromLatin1("%1 (%2)").arg(key()).arg(module() ? module()->name() : QObject::tr("unknown")), - m_title, - m_description, treeWidget()); - - if (d.exec() == QDialog::Accepted) { - m_title = d.titleText(); - m_description = d.descriptionText(); - update(); - } -} - -void BtBookmarkItem::update() { - setIcon(0, util::getIcon(CResMgr::mainIndex::bookmark::icon)); - - if (m_title.isEmpty()) { - m_title = QString::fromLatin1("%1 (%2)").arg(key()).arg(module() ? module()->name() : QObject::tr("unknown")); - } - setText(0,m_title); - setToolTip(0, toolTip()); -} - diff --git a/src/frontend/bookmarks/btbookmarkitem.h b/src/frontend/bookmarks/btbookmarkitem.h deleted file mode 100644 index 932d4e0..0000000 --- a/src/frontend/bookmarks/btbookmarkitem.h +++ /dev/null @@ -1,77 +0,0 @@ -/********* -* -* 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 BTBOOKMARKITEM_H -#define BTBOOKMARKITEM_H - -#include "frontend/bookmarks/btbookmarkitembase.h" - -#include <QString> - - -class BtBookmarkFolder; -class CSwordModuleInfo; - -class BtBookmarkItem : public BtBookmarkItemBase { - public: - friend class BtBookmarkLoader; - - BtBookmarkItem(QTreeWidgetItem* parent); - - /** Creates a bookmark with module, key and description. */ - BtBookmarkItem(const CSwordModuleInfo *module, const QString &key, - const QString &description, const QString &title); - - /** Creates a copy. */ - BtBookmarkItem(const BtBookmarkItem& other); - - /** Returns the used module, 0 if there is no such module. */ - CSwordModuleInfo *module() const; - - /** Returns the used key. */ - QString key() const; - - /** Returns the used description. */ - inline const QString &description() const { - return m_description; - } - - /** Returns the title. */ - inline const QString &title() const { - return m_title; - } - - /** Returns whether the action is supported by this item. */ - virtual bool enableAction(MenuAction action); - - /** Changes this bookmark. */ - virtual void rename(); - - virtual void update(); - - private: - - /** Returns a tooltip for this bookmark. */ - QString toolTip() const; - - /** Returns the english key.*/ - inline const QString &englishKey() const { - return m_key; - } - - private: - QString m_key; - QString m_description; - QString m_moduleName; - QString m_title; -}; - -#endif diff --git a/src/frontend/bookmarks/btbookmarkitembase.h b/src/frontend/bookmarks/btbookmarkitembase.h deleted file mode 100644 index 630d018..0000000 --- a/src/frontend/bookmarks/btbookmarkitembase.h +++ /dev/null @@ -1,56 +0,0 @@ -/********* -* -* 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 BTBOOKMARKITEMBASE_H -#define BTBOOKMARKITEMBASE_H - -#include <QTreeWidgetItem> - - -class BtBookmarkItemBase: public QTreeWidgetItem { - - public: /* Types: */ - - enum MenuAction { - NewFolder = 0, - ChangeFolder, - - EditBookmark, - SortFolderBookmarks, - SortAllBookmarks, - ImportBookmarks, - ExportBookmarks, - PrintBookmarks, - - DeleteEntries, - - ActionBegin = NewFolder, - ActionEnd = DeleteEntries - }; - - public: /* Methods: */ - - inline BtBookmarkItemBase(QTreeWidgetItem *parent = 0) - : QTreeWidgetItem(parent) {} - - /** Returns true if the given action should be enabled in the popup menu. */ - virtual bool enableAction(MenuAction action) = 0; - - /** Rename the item. */ - virtual void rename() = 0; - - /** Update the item (icon etc.) after creating or changing it. */ - virtual void update() = 0; - -}; - -#endif - diff --git a/src/frontend/bookmarks/btbookmarkloader.cpp b/src/frontend/bookmarks/btbookmarkloader.cpp deleted file mode 100644 index 63e0797..0000000 --- a/src/frontend/bookmarks/btbookmarkloader.cpp +++ /dev/null @@ -1,173 +0,0 @@ -/********* -* -* 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 "frontend/bookmarks/btbookmarkloader.h" - -#include <QDomElement> -#include <QDomNode> -#include <QDomDocument> -#include <QFile> -#include <QIODevice> -#include <QTextCodec> -#include <QTextStream> -#include <QTreeWidgetItem> -#include "backend/drivers/cswordmoduleinfo.h" -#include "frontend/bookmarks/btbookmarkitem.h" -#include "frontend/bookmarks/btbookmarkfolder.h" -#include "util/tool.h" - - -#define CURRENT_SYNTAX_VERSION 1 - -QList<QTreeWidgetItem*> BtBookmarkLoader::loadTree(QString fileName) { - QList<QTreeWidgetItem*> itemList; - - QDomDocument doc; - doc.setContent(loadXmlFromFile(fileName)); - - //bookmarkfolder::loadBookmarksFromXML() - - QDomElement document = doc.documentElement(); - if ( document.tagName() != "SwordBookmarks" ) { - qWarning("Not a BibleTime Bookmark XML file"); - return QList<QTreeWidgetItem*>(); - } - - QDomElement child = document.firstChild().toElement(); - - while ( !child.isNull() && child.parentNode() == document) { - QTreeWidgetItem* i = handleXmlElement(child, 0); - itemList.append(i); - if (!child.nextSibling().isNull()) { - child = child.nextSibling().toElement(); - } - else { - child = QDomElement(); //null - } - - } - - return itemList; -} - -QTreeWidgetItem* BtBookmarkLoader::handleXmlElement(QDomElement& element, QTreeWidgetItem* parent) { - QTreeWidgetItem* newItem = 0; - if (element.tagName() == "Folder") { - BtBookmarkFolder* newFolder = new BtBookmarkFolder(QString::null, parent); - if (element.hasAttribute("caption")) { - newFolder->setText(0, element.attribute("caption")); - } - QDomNodeList childList = element.childNodes(); -#if QT_VERSION < 0x050000 - for (unsigned int i = 0; i < childList.length(); i++) { -#else - for (int i = 0; i < childList.length(); i++) { -#endif - QDomElement newElement = childList.at(i).toElement(); - QTreeWidgetItem* newChildItem = handleXmlElement(newElement, newFolder); - newFolder->addChild(newChildItem); - } - newFolder->update(); - newItem = newFolder; - } - else if (element.tagName() == "Bookmark") { - BtBookmarkItem* newBookmarkItem = new BtBookmarkItem(parent); - if (element.hasAttribute("modulename")) { - //we use the name in all cases, even if the module isn't installed anymore - newBookmarkItem->m_moduleName = element.attribute("modulename"); - } - if (element.hasAttribute("key")) { - newBookmarkItem->m_key = element.attribute("key"); - } - if (element.hasAttribute("description")) { - newBookmarkItem->m_description = element.attribute("description"); - } - if (element.hasAttribute("title")) { - newBookmarkItem->m_title = element.attribute("title"); - } - newBookmarkItem->update(); - newItem = newBookmarkItem; - } - return newItem; -} - - -QString BtBookmarkLoader::loadXmlFromFile(QString fileName) { - namespace DU = util::directory; - - if (fileName.isNull()) { - fileName = DU::getUserBaseDir().absolutePath() + "/bookmarks.xml"; - } - QFile file(fileName); - if (!file.exists()) - return QString::null; - - QString xml; - if (file.open(QIODevice::ReadOnly)) { - QTextStream t; - t.setAutoDetectUnicode(false); - t.setCodec(QTextCodec::codecForName("UTF-8")); - t.setDevice(&file); - xml = t.readAll(); - file.close(); - } - return xml; -} - -void BtBookmarkLoader::saveTreeFromRootItem(QTreeWidgetItem* rootItem, QString fileName, bool forceOverwrite) { - namespace DU = util::directory; - - Q_ASSERT(rootItem); - if (fileName.isNull()) { - fileName = DU::getUserBaseDir().absolutePath() + "/bookmarks.xml"; - } - - QDomDocument doc("DOC"); - doc.appendChild( doc.createProcessingInstruction( "xml", "version=\"1.0\" encoding=\"UTF-8\"" ) ); - - QDomElement content = doc.createElement("SwordBookmarks"); - content.setAttribute("syntaxVersion", CURRENT_SYNTAX_VERSION); - doc.appendChild(content); - - //append the XML nodes of all child items - - for (int i = 0; i < rootItem->childCount(); i++) { - saveItem(rootItem->child(i), content); - } - util::tool::savePlainFile(fileName, doc.toString(), forceOverwrite, QTextCodec::codecForName("UTF-8")); - -} - -void BtBookmarkLoader::saveItem(QTreeWidgetItem* item, QDomElement& parentElement) { - BtBookmarkFolder* folderItem = 0; - BtBookmarkItem* bookmarkItem = 0; - - if ((folderItem = dynamic_cast<BtBookmarkFolder*>(item))) { - QDomElement elem = parentElement.ownerDocument().createElement("Folder"); - elem.setAttribute("caption", folderItem->text(0)); - - parentElement.appendChild(elem); - - for (int i = 0; i < folderItem->childCount(); i++) { - saveItem(folderItem->child(i), elem); - } - } - else if ((bookmarkItem = dynamic_cast<BtBookmarkItem*>(item))) { - QDomElement elem = parentElement.ownerDocument().createElement("Bookmark"); - - elem.setAttribute("key", bookmarkItem->englishKey()); - elem.setAttribute("description", bookmarkItem->description()); - elem.setAttribute("modulename", bookmarkItem->m_moduleName); - elem.setAttribute("moduledescription", bookmarkItem->module() ? bookmarkItem->module()->config(CSwordModuleInfo::Description) : QString::null); - if ( ! bookmarkItem->title().isEmpty()) { - elem.setAttribute("title", bookmarkItem->m_title); - } - parentElement.appendChild(elem); - } -} diff --git a/src/frontend/bookmarks/btbookmarkloader.h b/src/frontend/bookmarks/btbookmarkloader.h deleted file mode 100644 index 25b56b8..0000000 --- a/src/frontend/bookmarks/btbookmarkloader.h +++ /dev/null @@ -1,48 +0,0 @@ -/********* -* -* 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 BTBOOKMARKLOADER_H -#define BTBOOKMARKLOADER_H - -#include "util/directory.h" - -#include <QDomElement> -#include <QList> -#include <QString> - - -class QTreeWidgetItem; - -/** -* Class for loading and saving bookmarks. -*/ -class BtBookmarkLoader { - public: - /** Loads a list of items (with subitem trees) from a named file - * or from the default bookmarks file. */ - QList<QTreeWidgetItem*> loadTree(QString fileName = QString::null); - - /** Takes one item and saves the tree which is under it to a named file - * or to the default bookmarks file, asking the user about overwriting if necessary. */ - void saveTreeFromRootItem(QTreeWidgetItem* rootItem, QString fileName = QString::null, bool forceOverwrite = true); - - private: - /** Create a new item from a document element. */ - QTreeWidgetItem* handleXmlElement(QDomElement& element, QTreeWidgetItem* parent); - - /** Writes one item to a document element. */ - void saveItem(QTreeWidgetItem* item, QDomElement& parentElement); - - /** Loads a bookmark XML document from a named file or from the default bookmarks file. */ - QString loadXmlFromFile(QString fileName = QString::null); -}; - -#endif diff --git a/src/frontend/bookmarks/bteditbookmarkdialog.cpp b/src/frontend/bookmarks/bteditbookmarkdialog.cpp index 1291f56..f27b501 100644 --- a/src/frontend/bookmarks/bteditbookmarkdialog.cpp +++ b/src/frontend/bookmarks/bteditbookmarkdialog.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -10,16 +10,16 @@ #include "bteditbookmarkdialog.h" #include <QDialogButtonBox> -#include <QVBoxLayout> #include <QFormLayout> #include <QLabel> #include <QLineEdit> #include <QTextEdit> +#include <QVBoxLayout> #include <QWidget> #include "bibletimeapp.h" -#include "util/cresmgr.h" #include "frontend/messagedialog.h" -#include "util/geticon.h" +#include "util/btconnect.h" +#include "util/cresmgr.h" BtEditBookmarkDialog::BtEditBookmarkDialog(const QString &key, @@ -32,7 +32,7 @@ BtEditBookmarkDialog::BtEditBookmarkDialog(const QString &key, QVBoxLayout *mainLayout = new QVBoxLayout(this); resize(400, 300); - setWindowIcon(util::getIcon(CResMgr::mainIndex::bookmark::icon)); + setWindowIcon(CResMgr::mainIndex::bookmark::icon()); m_layout = new QFormLayout; @@ -59,8 +59,8 @@ BtEditBookmarkDialog::BtEditBookmarkDialog(const QString &key, message::prepareDialogBox(m_buttonBox); mainLayout->addWidget(m_buttonBox); - QObject::connect(m_buttonBox, SIGNAL(accepted()), this, SLOT(accept())); - QObject::connect(m_buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + BT_CONNECT(m_buttonBox, SIGNAL(accepted()), this, SLOT(accept())); + BT_CONNECT(m_buttonBox, SIGNAL(rejected()), this, SLOT(reject())); retranslateUi(); diff --git a/src/frontend/bookmarks/bteditbookmarkdialog.h b/src/frontend/bookmarks/bteditbookmarkdialog.h index 674ccdf..1093842 100644 --- a/src/frontend/bookmarks/bteditbookmarkdialog.h +++ b/src/frontend/bookmarks/bteditbookmarkdialog.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -31,7 +31,7 @@ class BtEditBookmarkDialog : public QDialog { BtEditBookmarkDialog(const QString &key, const QString &title, const QString &description, - QWidget *parent = 0, + QWidget *parent = nullptr, Qt::WindowFlags wflags = Qt::Dialog); /** diff --git a/src/frontend/bookmarks/cbookmarkindex.cpp b/src/frontend/bookmarks/cbookmarkindex.cpp index 1b697d0..30b6855 100644 --- a/src/frontend/bookmarks/cbookmarkindex.cpp +++ b/src/frontend/bookmarks/cbookmarkindex.cpp @@ -2,79 +2,69 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ -#include "frontend/bookmarks/cbookmarkindex.h" - -#include <QSharedPointer> +#include <memory> #include <QAction> #include <QApplication> #include <QCursor> -#include <QDebug> #include <QDrag> #include <QDragLeaveEvent> #include <QDragMoveEvent> #include <QDropEvent> -#include <QInputDialog> -#include <QList> +#include <QFileDialog> #include <QMenu> #include <QMouseEvent> #include <QPainter> #include <QPaintEvent> #include <QTimer> -#include <QTreeWidget> -#include <QTreeWidgetItem> #include <QToolTip> #include "backend/config/btconfig.h" #include "backend/drivers/cswordmoduleinfo.h" +#include "backend/btbookmarksmodel.h" #include "backend/managers/referencemanager.h" +#include "bibletime.h" #include "bibletimeapp.h" +#include "frontend/btprinter.h" #include "frontend/cdragdrop.h" #include "frontend/cinfodisplay.h" -#include "frontend/cprinter.h" -#include "frontend/bookmarks/btbookmarkitembase.h" -#include "frontend/bookmarks/btbookmarkitem.h" -#include "frontend/bookmarks/btbookmarkfolder.h" -#include "frontend/bookmarks/btbookmarkloader.h" #include "frontend/messagedialog.h" #include "frontend/searchdialog/csearchdialog.h" +#include "frontend/bookmarks/bteditbookmarkdialog.h" +#include "frontend/bookmarks/cbookmarkindex.h" +#include "util/btassert.h" +#include "util/btconnect.h" +#include "util/bticons.h" +#include "util/btscopeexit.h" #include "util/cresmgr.h" #include "util/tool.h" #include "util/directory.h" -#include "util/geticon.h" -#include "bibletime.h" -CBookmarkIndex::CBookmarkIndex(QWidget *parent) - : QTreeWidget(parent), - m_magTimer(this), - m_previousEventItem(0) { +CBookmarkIndex::CBookmarkIndex(QWidget * const parent) + : QTreeView{parent} + , m_magTimer{this} + , m_bookmarksModel{nullptr} +{ setMouseTracking(true); m_magTimer.setSingleShot(true); m_magTimer.setInterval(btConfig().value<int>("GUI/magDelay", 400)); setContextMenuPolicy(Qt::CustomContextMenu); - initView(); - initConnections(); - initTree(); -} - -CBookmarkIndex::~CBookmarkIndex() { - saveBookmarks(); -} + setHeaderHidden(true); + //-------------------------------------------------------------------------- + // Initialize view: -/** Initializes the view. */ -void CBookmarkIndex::initView() { setHeaderHidden(true); setFocusPolicy(Qt::WheelFocus); //d'n'd related settings - setDragEnabled( true ); - setAcceptDrops( true ); + setDragEnabled(true); + setAcceptDrops(true); setDragDropMode(QAbstractItemView::DragDrop); viewport()->setAcceptDrops(true); setAutoScroll(true); @@ -85,168 +75,169 @@ void CBookmarkIndex::initView() { setAllColumnsShowFocus(true); setSelectionMode(QAbstractItemView::ExtendedSelection); + //setExpandsOnDoubleClick(true); + setEditTriggers(editTriggers() ^ QAbstractItemView::DoubleClicked); + //setup the popup menu - m_popup = new QMenu(viewport()); + m_popup = new QMenu{viewport()}; m_popup->setTitle(tr("Bookmarks")); - m_actions.newFolder = newQAction(tr("New folder"), CResMgr::mainIndex::newFolder::icon, 0, this, SLOT(createNewFolder()), this); - m_actions.changeFolder = newQAction(tr("Rename folder"), CResMgr::mainIndex::changeFolder::icon, 0, this, SLOT(changeFolder()), this); - - m_actions.editBookmark = newQAction(tr("Edit bookmark..."), CResMgr::mainIndex::editBookmark::icon, 0, this, SLOT(editBookmark()), this); + auto const newQAction = [this](QString const & text, + QIcon const & pix, + char const * const slot) + { + QAction * const action = new QAction{pix, text, this}; + BT_CONNECT(action, SIGNAL(triggered()), this, slot); + return action; + }; + + namespace MI = CResMgr::mainIndex; + m_actions[NewFolder] = newQAction(tr("New folder"), + MI::newFolder::icon(), + SLOT(createNewFolder())); + m_actions[ChangeFolder] = newQAction(tr("Rename folder"), + MI::changeFolder::icon(), + SLOT(changeFolder())); + m_actions[EditBookmark] = newQAction(tr("Edit bookmark..."), + MI::editBookmark::icon(), + SLOT(editBookmark())); /// \todo Add icons for sorting bookmarks - m_actions.sortFolderBookmarks = newQAction(tr("Sort folder bookmarks..."), QString::null, 0, this, SLOT(sortFolderBookmarks()), this); - m_actions.sortAllBookmarks = newQAction(tr("Sort all bookmarks..."), QString::null, 0, this, SLOT(sortAllBookmarks()), this); - m_actions.importBookmarks = newQAction(tr("Import to folder..."), CResMgr::mainIndex::importBookmarks::icon, 0, this, SLOT(importBookmarks()), this); - m_actions.exportBookmarks = newQAction(tr("Export from folder..."), CResMgr::mainIndex::exportBookmarks::icon, 0, this, SLOT(exportBookmarks()), this); - m_actions.printBookmarks = newQAction(tr("Print bookmarks..."), CResMgr::mainIndex::printBookmarks::icon, 0, this, SLOT(printBookmarks()), this); - - m_actions.deleteEntries = newQAction(tr("Remove selected items..."), CResMgr::mainIndex::deleteItems::icon, 0, this, SLOT(deleteEntries()), this); - - - //fill the popup menu itself - m_popup->addAction(m_actions.newFolder); - m_popup->addAction(m_actions.changeFolder); - QAction* separator = new QAction(this); - separator->setSeparator(true); - m_popup->addAction(separator); - m_popup->addAction(m_actions.editBookmark); - m_popup->addAction(m_actions.sortFolderBookmarks); - m_popup->addAction(m_actions.sortAllBookmarks); - m_popup->addAction(m_actions.importBookmarks); - m_popup->addAction(m_actions.exportBookmarks); - m_popup->addAction(m_actions.printBookmarks); - separator = new QAction(this); - separator->setSeparator(true); - m_popup->addAction(separator); - m_popup->addAction(m_actions.deleteEntries); - - m_bookmarksModified = false; -} + m_actions[SortFolderBookmarks] = newQAction(tr("Sort folder bookmarks..."), + MI::sortFolderBookmarks::icon(), + SLOT(sortFolderBookmarks())); + m_actions[SortAllBookmarks] = newQAction(tr("Sort all bookmarks..."), + MI::sortAllBookmarks::icon(), + SLOT(sortAllBookmarks())); + m_actions[ImportBookmarks] = newQAction(tr("Import to folder..."), + MI::importBookmarks::icon(), + SLOT(importBookmarks())); + m_actions[ExportBookmarks] = newQAction(tr("Export from folder..."), + MI::exportBookmarks::icon(), + SLOT(exportBookmarks())); + m_actions[PrintBookmarks] = newQAction(tr("Print bookmarks..."), + MI::printBookmarks::icon(), + SLOT(printBookmarks())); + + m_actions[DeleteEntries] = newQAction(tr("Remove selected items..."), + MI::deleteItems::icon(), + SLOT(confirmDeleteEntries())); + + // Fill the popup menu: + auto const createSeparator = [this]{ + QAction * const separator = new QAction{this}; + separator->setSeparator(true); + return separator; + }; + m_popup->addAction(m_actions[NewFolder]); + m_popup->addAction(m_actions[ChangeFolder]); + m_popup->addAction(createSeparator()); + m_popup->addAction(m_actions[EditBookmark]); + m_popup->addAction(m_actions[SortFolderBookmarks]); + m_popup->addAction(m_actions[SortAllBookmarks]); + m_popup->addAction(m_actions[ImportBookmarks]); + m_popup->addAction(m_actions[ExportBookmarks]); + m_popup->addAction(m_actions[PrintBookmarks]); + m_popup->addAction(createSeparator()); + m_popup->addAction(m_actions[DeleteEntries]); + + + //-------------------------------------------------------------------------- + // Initialize connections: + + BT_CONNECT(this, SIGNAL(activated(QModelIndex const &)), + this, SLOT(slotExecuted(QModelIndex const &))); + BT_CONNECT(this, SIGNAL(customContextMenuRequested(QPoint const &)), + this, SLOT(contextMenu(QPoint const &))); + BT_CONNECT(&m_magTimer, SIGNAL(timeout()), this, SLOT(magTimeout())); + + //-------------------------------------------------------------------------- + // Initialize tree: + + m_bookmarksModel = new BtBookmarksModel{this}; + setModel(m_bookmarksModel); -/** Convenience function for creating a new QAction. -* Should be replaced with something better; it was easier to make a new function -* than to modify all QAction constructors. -*/ -QAction* CBookmarkIndex::newQAction(const QString& text, const QString& pix, const int /*shortcut*/, const QObject* receiver, const char* slot, QObject* parent) { - QAction *action; - if (pix.isEmpty()) { - action = new QAction(text, parent); - } else { - action = new QAction(util::getIcon(pix), text, parent); - } - QObject::connect(action, SIGNAL(triggered()), receiver, slot); - return action; -} - -/** Initialize the SIGNAL<->SLOT connections */ -void CBookmarkIndex::initConnections() { - bool ok; - ok = connect(this, SIGNAL(itemActivated(QTreeWidgetItem*, int)), this, SLOT(slotExecuted(QTreeWidgetItem*))); - Q_ASSERT(ok); - ok = connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), - SLOT(contextMenu(const QPoint&))); - Q_ASSERT(ok); - ok = connect(&m_magTimer, SIGNAL(timeout()), this, SLOT(magTimeout())); - Q_ASSERT(ok); - ok = connect(this, SIGNAL(itemEntered(QTreeWidgetItem*, int)), this, SLOT(slotItemEntered(QTreeWidgetItem*, int)) ); - Q_ASSERT(ok); - - // Connection to detect changes in the items themselves (e.g. renames, - // description changes) so that we can consider saving the bookmarks. - connect(this, SIGNAL(itemChanged(QTreeWidgetItem*, int)), this, SLOT(needToSaveBookmarks(QTreeWidgetItem*)) ); - - // Connect the bookmark saving timer. - bookmarkSaveTimer.setSingleShot(true); - connect(&bookmarkSaveTimer, SIGNAL(timeout()), this, SLOT(considerSavingBookmarks()) ); + // add the invisible extra item at the end + if(m_bookmarksModel->insertRows(m_bookmarksModel->rowCount(), 1)) + m_extraItem = m_bookmarksModel->index(m_bookmarksModel->rowCount() - 1, 0); + showExtraItem(); } - -/** -* Hack to get single click and selection working. See slotExecuted. -*/ +/** \note Hack to get single click and selection working. See slotExecuted. */ void CBookmarkIndex::mouseReleaseEvent(QMouseEvent* event) { m_mouseReleaseEventModifiers = event->modifiers(); - QTreeWidget::mouseReleaseEvent(event); + QTreeView::mouseReleaseEvent(event); } /** Called when an item is clicked with mouse or activated with keyboard. */ -void CBookmarkIndex::slotExecuted( QTreeWidgetItem* i ) { - //HACK: checking the modifier keys from the last mouseReleaseEvent - //depends on executing order: mouseReleaseEvent first, then itemClicked signal - int modifiers = m_mouseReleaseEventModifiers; +void CBookmarkIndex::slotExecuted( const QModelIndex &index ) { + /** \note HACK: checking the modifier keys from the last mouseReleaseEvent + depends on executing order: mouseReleaseEvent first, then + itemClicked signal. */ + auto const modifiers = m_mouseReleaseEventModifiers; m_mouseReleaseEventModifiers = Qt::NoModifier; - if (modifiers != Qt::NoModifier) { - return; - } - - BtBookmarkItemBase* btItem = dynamic_cast<BtBookmarkItemBase*>(i); - if (!btItem) { + if (modifiers != Qt::NoModifier || !index.isValid()) return; - } - BtBookmarkFolder* folderItem = 0; - BtBookmarkItem* bookmarkItem = 0; - if ((folderItem = dynamic_cast<BtBookmarkFolder*>(btItem))) { - i->setExpanded( !i->isExpanded() ); - } - else if (( bookmarkItem = dynamic_cast<BtBookmarkItem*>(btItem) )) { //clicked on a bookmark - if (CSwordModuleInfo* mod = bookmarkItem->module()) { - QList<CSwordModuleInfo*> modules; - modules.append(mod); - emit createReadDisplayWindow(modules, bookmarkItem->key()); - } - } + // Clicked on a bookmark: + if (m_bookmarksModel->isBookmark(index)) + if (CSwordModuleInfo * const mod = m_bookmarksModel->module(index)) + emit createReadDisplayWindow(QList<CSwordModuleInfo *>() << mod, + m_bookmarksModel->key(index)); } /** Creates a drag mime data object for the current selection. */ -QMimeData* CBookmarkIndex::dragObject() { - BTMimeData::ItemList dndItems; - BTMimeData* mimeData = new BTMimeData; +QMimeData * CBookmarkIndex::dragObject() { + BTMimeData * const mimeData = new BTMimeData{}; - foreach( QTreeWidgetItem* widgetItem, selectedItems() ) { - if (!widgetItem) + Q_FOREACH(QModelIndex const & widgetItem, selectedIndexes()) { + if (!widgetItem.isValid()) break; - if (dynamic_cast<BtBookmarkItemBase*>(widgetItem)) { - if (BtBookmarkItem* bookmark = dynamic_cast<BtBookmarkItem*>( widgetItem )) { - //take care of bookmarks which have no valid module any more, e.g. if it was uninstalled - const QString moduleName = bookmark->module() ? bookmark->module()->name() : QString::null; - mimeData->appendBookmark(moduleName, bookmark->key(), bookmark->description()); - } + if (m_bookmarksModel->isBookmark(widgetItem)) { + /* Take care of bookmarks which have no valid module any more, e.g. + if these were uninstalled: */ + CSwordModuleInfo * const module = + m_bookmarksModel->module(widgetItem); + const QString moduleName = module ? module->name() : QString::null; + mimeData->appendBookmark(moduleName, m_bookmarksModel->key(widgetItem), + m_bookmarksModel->description(widgetItem)); } } return mimeData; } -void CBookmarkIndex::dragEnterEvent( QDragEnterEvent* event ) { - setState(QAbstractItemView::DraggingState); - QTreeWidget::dragEnterEvent(event); - if (event->source() == this || event->mimeData()->hasFormat("BibleTime/Bookmark")) { +void CBookmarkIndex::dragEnterEvent(QDragEnterEvent * event) { + if (event->mimeData()->hasFormat("BibleTime/Bookmark")) { event->acceptProposedAction(); + setState(DraggingState); + } else { + QAbstractItemView::dragEnterEvent(event); } } - -void CBookmarkIndex::dragMoveEvent( QDragMoveEvent* event ) { - // do this first, otherwise the event may be ignored - QTreeWidget::dragMoveEvent(event); +void CBookmarkIndex::dragMoveEvent(QDragMoveEvent * event) { + // Do this first, otherwise the event may be ignored: + QTreeView::dragMoveEvent(event); event->acceptProposedAction(); event->accept(); - // do this to paint the arrow + // Do this to paint the arrow: m_dragMovementPosition = event->pos(); viewport()->update(); - } -void CBookmarkIndex::dragLeaveEvent( QDragLeaveEvent* ) { - setState(QAbstractItemView::NoState); // not dragging anymore - viewport()->update(); // clear the arrow +void CBookmarkIndex::dragLeaveEvent(QDragLeaveEvent *) { + setState(QAbstractItemView::NoState); // Not dragging anymore + viewport()->update(); // Clear the arrow } +void CBookmarkIndex::paintEvent(QPaintEvent * event) { + // Do the normal painting first + QTreeView::paintEvent(event); -void CBookmarkIndex::paintEvent(QPaintEvent* event) { - namespace DU = util::directory; + // Don't paint the arrow if not dragging: + if (state() != QAbstractItemView::DraggingState) + return; static QPixmap pix; static int halfPixHeight; @@ -255,467 +246,383 @@ void CBookmarkIndex::paintEvent(QPaintEvent* event) { // Initialize the static variables, including the arrow pixmap if (!arrowInitialized) { arrowInitialized = true; - int arrowSize = util::tool::mWidth(this, 1); - QString fileName; - if (DU::getIconDir().exists("pointing_arrow.svg")) { - fileName = DU::getIconDir().filePath("pointing_arrow.svg"); - } - else { - if (DU::getIconDir().exists("pointing_arrow.png")) { - fileName = DU::getIconDir().filePath("pointing_arrow.png"); - } - else { - qWarning() << "Picture file pointing_arrow.svg or .png not found!"; - } - } - - pix = QPixmap(fileName); - pix = pix.scaled(arrowSize, arrowSize, Qt::KeepAspectRatioByExpanding); + pix = BtIcons::instance().icon_pointing_arrow.pixmap(util::tool::mWidth(this, 1)); halfPixHeight = pix.height() / 2; } - // Do the normal painting first - QTreeWidget::paintEvent(event); - - // Paint the arrow if the drag is going on - if (QAbstractItemView::DraggingState == state()) { - bool rtol = QApplication::isRightToLeft(); - - QPainter painter(this->viewport()); - QTreeWidgetItem* item = itemAt(m_dragMovementPosition); - bool isFolder = dynamic_cast<BtBookmarkFolder*>(item); - bool isBookmark = dynamic_cast<BtBookmarkItem*>(item); - - // Find the place for the arrow - QRect rect = visualItemRect(item); - int xCoord = rtol ? rect.right() : rect.left(); - int yCoord; - if (isFolder) { - if (m_dragMovementPosition.y() > rect.bottom() - (2* rect.height() / 3) ) { + // Find the place for the arrow: + QModelIndex const index = indexAt(m_dragMovementPosition); + int xCoord, yCoord; + if (m_bookmarksModel->isBookmark(index)) { + QRect const rect = visualRect(index); + xCoord = QApplication::isRightToLeft() ? rect.right() : rect.left(); + if (m_dragMovementPosition.y() > rect.bottom() - rect.height() / 2) { + yCoord = rect.bottom() - halfPixHeight; // bottom + } else { + yCoord = rect.top() - halfPixHeight - 1; // top + } + } else { + if (m_bookmarksModel->isFolder(index)) { + QRect const rect = visualRect(index); + if (m_dragMovementPosition.y() + > rect.bottom() - (2 * rect.height() / 3)) + { yCoord = rect.bottom() - halfPixHeight; // bottom - xCoord = rtol ? (xCoord - indentation()) : (xCoord + indentation()); - } - else { + xCoord = QApplication::isRightToLeft() + ? (rect.right() - indentation()) + : (rect.left() + indentation()); + } else { yCoord = rect.top() - halfPixHeight - 1; // top + xCoord = QApplication::isRightToLeft() + ? rect.right() + : rect.left(); } - + } else if (index.isValid()) { // the extra item + QRect const rect = visualRect(index); + xCoord = QApplication::isRightToLeft() ? rect.right() : rect.left(); + yCoord = rect.top() - halfPixHeight - 1; + } else { // empty area + QRect const rect = visualRect(m_extraItem); + yCoord = rect.top() - halfPixHeight - 1; + xCoord = QApplication::isRightToLeft() ? rect.right() : rect.left(); } - else { - if (isBookmark) { - if (m_dragMovementPosition.y() > rect.bottom() - rect.height() / 2) { - yCoord = rect.bottom() - halfPixHeight; // bottom - } - else { - yCoord = rect.top() - halfPixHeight - 1; // top - } - } - else { - if (item) { // the extra item - yCoord = rect.top() - halfPixHeight - 1; - } - else { // empty area - rect = visualItemRect(m_extraItem); - yCoord = rect.top() - halfPixHeight - 1; - xCoord = rtol ? rect.right() : rect.left(); - } - } - } - - painter.drawPixmap(xCoord, yCoord, pix); } + QPainter{this->viewport()}.drawPixmap(xCoord, yCoord, pix); } -void CBookmarkIndex::dropEvent( QDropEvent* event ) { - - //setState(QAbstractItemView::NoState); - // Try to prevent annoying timed autocollapsing. Remember to disconnect before return. - QObject::connect(this, SIGNAL(itemCollapsed(QTreeWidgetItem*)), this, SLOT(expandAutoCollapsedItem(QTreeWidgetItem*))); - QTreeWidgetItem* item = itemAt(event->pos()); - QTreeWidgetItem* parentItem = 0; +void CBookmarkIndex::dropEvent(QDropEvent * event) { + // Try to prevent annoying timed autocollapsing: + BT_CONNECT(this, SIGNAL(collapsed(QModelIndex const &)), + this, SLOT(expandAutoCollapsedItem(QModelIndex const &))); + BT_SCOPE_EXIT( + QObject::disconnect( + this, SIGNAL(collapsed(QModelIndex const &)), + this, SLOT(expandAutoCollapsedItem(QModelIndex const &))); + ); + QModelIndex const index = indexAt(event->pos()); + QModelIndex parentIndex; int indexUnderParent = 0; // Find the place where the drag is dropped - if (item) { - QRect rect = visualItemRect(item); - bool isFolder = dynamic_cast<BtBookmarkFolder*>(item); - bool isBookmark = dynamic_cast<BtBookmarkItem*>(item); - - if (isFolder) { // item is a folder + if (index.isValid()) { + if (m_bookmarksModel->isFolder(index)) { + QRect const rect = visualRect(index); if (event->pos().y() > rect.bottom() - (2* rect.height() / 3) ) { - parentItem = item; + parentIndex = index; + } else { + parentIndex = index.parent(); + indexUnderParent = index.row(); // before the current folder } - else { - parentItem = item->parent(); - if (!parentItem) { - parentItem = invisibleRootItem(); - } - indexUnderParent = parentItem->indexOfChild(item); // before the current folder - } - } - else { - if (isBookmark) { // item is a bookmark - parentItem = item->parent(); - if (!parentItem) { - parentItem = invisibleRootItem(); - } - indexUnderParent = parentItem->indexOfChild(item); // before the current bookmark - if (event->pos().y() > rect.bottom() - rect.height() / 2) { + } else { + if (m_bookmarksModel->isBookmark(index)) { + parentIndex = index.parent(); + indexUnderParent = index.row(); // before the current bookmark + QRect const rect = visualRect(index); + if (event->pos().y() > rect.bottom() - rect.height() / 2) indexUnderParent++; // after the current bookmark - } - } - else { // item is the extra item - parentItem = item->parent(); - if (!parentItem) { - parentItem = invisibleRootItem(); - } - indexUnderParent = parentItem->indexOfChild(item); // before the current bookmark + } else { // item is the extra item + parentIndex = index.parent(); + indexUnderParent = index.row(); // before the current bookmark } } - - } - else { // no item under event point: drop to the end - parentItem = invisibleRootItem(); - indexUnderParent = parentItem->childCount() - 1; - } - - - if ( event->source() == this ) { + } else { // no item under event point: drop to the end + indexUnderParent = m_bookmarksModel->rowCount() - 1; + } + + if (event->source() != this) { + // Take the bookmark data from the mime source + if (BTMimeData const * const mdata = + dynamic_cast<BTMimeData const *>(event->mimeData())) + { + //create the new bookmark + QString const moduleName(mdata->bookmark().module()); + QString const keyText(mdata->bookmark().key()); + QString const description(mdata->bookmark().description()); + CSwordModuleInfo * minfo = + CSwordBackend::instance()->findModuleByName(moduleName); + BT_ASSERT(minfo); + + /// \todo add title + m_bookmarksModel->addBookmark(indexUnderParent, + parentIndex, + *minfo, + keyText, + description); + } + } else { event->accept(); bool bookmarksOnly = true; bool targetIncluded = false; bool moreThanOneFolder = false; - QList<QTreeWidgetItem*> newItems = addItemsToDropTree(parentItem, bookmarksOnly, targetIncluded, moreThanOneFolder); + QModelIndexList const list = selectedIndexes(); + QModelIndexList newList; + + Q_FOREACH(QModelIndex const & index, list) { + if (m_bookmarksModel->isFolder(index)) { + bookmarksOnly = false; + // Only one item allowed if a folder is selected: + if (list.count() > 1) { + moreThanOneFolder = true; + break; + } + // Dropping to self or descendand not allowed: + if (m_bookmarksModel->hasDescendant(index, parentIndex)) { + targetIncluded = true; + break; + } + } else { + newList.append(index); + } + } + + if (!bookmarksOnly && list.count() == 1) { + newList.append(list[0]); // list contain only one folder item + } else if (!bookmarksOnly && list.count() > 1) { + moreThanOneFolder = true; // wrong amount of items + } if (moreThanOneFolder) { QToolTip::showText(QCursor::pos(), tr("Can drop only bookmarks or one folder")); - QObject::disconnect(this, SIGNAL(itemCollapsed(QTreeWidgetItem*)), this, SLOT(expandAutoCollapsedItem(QTreeWidgetItem*))); return; } if (targetIncluded) { QToolTip::showText(QCursor::pos(), tr("Can't drop folder into the folder itself or into its subfolder")); - QObject::disconnect(this, SIGNAL(itemCollapsed(QTreeWidgetItem*)), this, SLOT(expandAutoCollapsedItem(QTreeWidgetItem*))); return; } + // Ask whether to copy or move with a popup menu + std::unique_ptr<QMenu> dropPopupMenu{new QMenu{this}}; + dropPopupMenu->setEnabled(!newList.empty()); + QAction * const copy = dropPopupMenu->addAction(tr("Copy")); + QAction * const move = dropPopupMenu->addAction(tr("Move")); + QAction * const dropAction = dropPopupMenu->exec(QCursor::pos()); + dropPopupMenu.reset(); - QMenu* dropPopupMenu = new QMenu(this); - QAction* copy = dropPopupMenu->addAction(tr("Copy")); - QAction* move = dropPopupMenu->addAction(tr("Move")); - QAction* dropAction = dropPopupMenu->exec(QCursor::pos()); if (dropAction == copy) { - parentItem->insertChildren(indexUnderParent, newItems); - // Need this here because the "move" case goes through - // "deleteEntries" which has a save call. - needToSaveBookmarks(); - } - else { - if (dropAction == move) { - parentItem->insertChildren(indexUnderParent, newItems); - deleteEntries(false); - } - else { - QObject::disconnect(this, SIGNAL(itemCollapsed(QTreeWidgetItem*)), - this, SLOT(expandAutoCollapsedItem(QTreeWidgetItem*))); - return; // user canceled - } + m_bookmarksModel->copyItems(indexUnderParent, parentIndex, newList); + } else if (dropAction == move) { + m_bookmarksModel->copyItems(indexUnderParent, parentIndex, newList); + deleteEntries(); + } else { // user canceled + return; } } - else { - createBookmarkFromDrop(event, parentItem, indexUnderParent); - } - QObject::disconnect(this, SIGNAL(itemCollapsed(QTreeWidgetItem*)), this, SLOT(expandAutoCollapsedItem(QTreeWidgetItem*))); setState(QAbstractItemView::NoState); } - -void CBookmarkIndex::createBookmarkFromDrop(QDropEvent* event, QTreeWidgetItem* parentItem, int indexInParent) { - //take the bookmark data from the mime source - const BTMimeData* mdata = dynamic_cast<const BTMimeData*>(event->mimeData()); - if (mdata) { - //create the new bookmark - QString moduleName = mdata->bookmark().module(); - QString keyText = mdata->bookmark().key(); - QString description = mdata->bookmark().description(); - CSwordModuleInfo *minfo = CSwordBackend::instance()->findModuleByName(moduleName); - QString title; /// \todo - - QTreeWidgetItem* newItem = new BtBookmarkItem(minfo, keyText, description, title); - // connect(newItem, SIGNAL(bookmarkModified()), this, SLOT(needToSaveBookmarks()) ); - parentItem->insertChild(indexInParent, newItem); - - needToSaveBookmarks(); +bool CBookmarkIndex::enableAction(QModelIndex const & index, + CBookmarkIndex::MenuAction const type) const +{ + switch (type) { + case NewFolder: + case ChangeFolder: + case SortFolderBookmarks: + case ImportBookmarks: + case ExportBookmarks: + return m_bookmarksModel->isFolder(index); + case DeleteEntries: + return true; + case PrintBookmarks: + return hasBookmarksRecursively(QModelIndexList{} << index); + case EditBookmark: + return m_bookmarksModel->isBookmark(index); + default: + return false; } } - -/** Load the tree from file */ -void CBookmarkIndex::initTree() { - BtBookmarkLoader loader; - addTopLevelItems(loader.loadTree()); - - // add the invisible extra item at the end - m_extraItem = new QTreeWidgetItem(); - m_extraItem->setFlags(Qt::ItemIsDropEnabled); - addTopLevelItem(m_extraItem); -} - -void CBookmarkIndex::slotItemEntered(QTreeWidgetItem* item, int) { - if (item == m_extraItem) { - m_extraItem->setText(0, tr("Drag references from text views to this view")); - } - else { - m_extraItem->setText(0, QString::null); +bool CBookmarkIndex::hasBookmarksRecursively(QModelIndexList items) const { + while (!items.empty()) { + QModelIndex const index = items.takeFirst(); + if (m_bookmarksModel->isBookmark(index)) + return true; + if (m_bookmarksModel->isFolder(index)) { + int const numChildren = m_bookmarksModel->rowCount(index); + for (int i = 0; i < numChildren; i++) + items.append(index.child(i, 0)); + } } + return false; } +void CBookmarkIndex::showExtraItem() { + model()->setData(m_extraItem, + tr("Drag references from text views to this view")); +} -/** Returns the correct QAction object for the given type of action. */ -QAction* CBookmarkIndex::action( BtBookmarkItemBase::MenuAction type ) const { - switch (type) { - case BtBookmarkItemBase::NewFolder: - return m_actions.newFolder; - case BtBookmarkItemBase::ChangeFolder: - return m_actions.changeFolder; - - case BtBookmarkItemBase::EditBookmark: - return m_actions.editBookmark; - case BtBookmarkItemBase::SortFolderBookmarks: - return m_actions.sortFolderBookmarks; - case BtBookmarkItemBase::SortAllBookmarks: - return m_actions.sortAllBookmarks; - case BtBookmarkItemBase::ImportBookmarks: - return m_actions.importBookmarks; - case BtBookmarkItemBase::ExportBookmarks: - return m_actions.exportBookmarks; - case BtBookmarkItemBase::PrintBookmarks: - return m_actions.printBookmarks; - - case BtBookmarkItemBase::DeleteEntries: - return m_actions.deleteEntries; +void CBookmarkIndex::hideExtraItem() +{ model()->setData(m_extraItem, QVariant()); } - default: - return 0; - } +void CBookmarkIndex::leaveEvent(QEvent * event) { + showExtraItem(); + update(); + QTreeView::leaveEvent(event); } /** Shows the context menu at the given position. */ -void CBookmarkIndex::contextMenu(const QPoint& p) { - //setup menu entries depending on current selection - QTreeWidgetItem* i = itemAt(p); - QList<QTreeWidgetItem *> items = selectedItems(); - //The item which was clicked may not be selected - if (i && !items.contains(i) && i != m_extraItem) - items.append(i); - - if (items.isEmpty()) { - //special handling for no selection - BtBookmarkItemBase::MenuAction actionType; - for (int index = BtBookmarkItemBase::ActionBegin; index <= BtBookmarkItemBase::ActionEnd; ++index) { - actionType = static_cast<BtBookmarkItemBase::MenuAction>(index); - if (QAction* a = action(actionType)) { - switch (index) { - //case BtBookmarkItemBase::ExportBookmarks: - //case BtBookmarkItemBase::ImportBookmarks: - case BtBookmarkItemBase::NewFolder: - case BtBookmarkItemBase::SortAllBookmarks: - //case BtBookmarkItemBase::PrintBookmarks: - a->setEnabled(true); - break; - default: - a->setEnabled(false); - } - } - } - } - else if (items.count() == 1) { - //special handling for one selected item - - BtBookmarkItemBase* item = dynamic_cast<BtBookmarkItemBase*>(items.at(0)); - BtBookmarkItemBase::MenuAction actionType; - for (int index = BtBookmarkItemBase::ActionBegin; index <= BtBookmarkItemBase::ActionEnd; ++index) { - actionType = static_cast<BtBookmarkItemBase::MenuAction>(index); - if (QAction* a = action(actionType)) - a->setEnabled( item->enableAction(actionType) ); - } - } - else { - //first disable all actions - BtBookmarkItemBase::MenuAction actionType; - for (int index = BtBookmarkItemBase::ActionBegin; index <= BtBookmarkItemBase::ActionEnd; ++index) { - actionType = static_cast<BtBookmarkItemBase::MenuAction>(index); - if (QAction* a = action(actionType)) - a->setEnabled(false); - } - //enable the menu items depending on the types of the selected items. - for (int index = BtBookmarkItemBase::ActionBegin; index <= BtBookmarkItemBase::ActionEnd; ++index) { - actionType = static_cast<BtBookmarkItemBase::MenuAction>(index); - bool enableAction = isMultiAction(actionType); - QListIterator<QTreeWidgetItem *> it(items); - while (it.hasNext()) { - BtBookmarkItemBase* i = dynamic_cast<BtBookmarkItemBase*>(it.next()); - enableAction = enableAction && i->enableAction(actionType); - } - if (enableAction) { - QAction* a = action(actionType) ; - if (i && a) - a->setEnabled(enableAction); - } - } +void CBookmarkIndex::contextMenu(QPoint const & p) { + // Enable actions based on the selected items (if any): + QModelIndex const i = indexAt(p); + QModelIndexList const items = selectedIndexes(); + if (items.isEmpty()) { // Special handling for no selection: + for (int index = ActionBegin; index < ActionEnd; ++index) + m_actions[index]->setEnabled((index == NewFolder) + || (index == SortAllBookmarks)); + } else if (items.count() == 1) { // Special handling for one selected item: + for (int index = ActionBegin; index < ActionEnd; ++index) + m_actions[index]->setEnabled( + enableAction(items.at(0), static_cast<MenuAction>(index))); + } else if (!i.isValid()) { // Disable all actions for invalid index: + for (int index = ActionBegin; index < ActionEnd; ++index) + m_actions[index]->setEnabled(false); + } else { // Enable actions depending on the the selected items: + for (int index = ActionBegin; index < ActionEnd; ++index) + m_actions[index]->setEnabled( + (index == DeleteEntries) + || ((index == PrintBookmarks) + && hasBookmarksRecursively(items))); } - //finally, open the popup m_popup->exec(mapToGlobal(p)); } /** Adds a new subfolder to the current item. */ void CBookmarkIndex::createNewFolder() { - QList<QTreeWidgetItem*> selected = selectedItems(); - if (selected.count() > 0) { - BtBookmarkFolder* i = dynamic_cast<BtBookmarkFolder*>(currentItem()); - if (i) { - i->newSubFolder(); - } - } - else { - // create a top level folder - BtBookmarkFolder* newFolder = new BtBookmarkFolder(tr("New folder")); - //parentFolder->addChild(newFolder); - insertTopLevelItem(topLevelItemCount() - 1, newFolder); - newFolder->update(); - newFolder->rename(); + if (!selectedIndexes().empty()) { + if (m_bookmarksModel->isFolder(currentIndex())) + setCurrentIndex(m_bookmarksModel->addFolder( + m_bookmarksModel->rowCount(currentIndex()), + currentIndex())); + } else { // create a top level folder + setCurrentIndex( + m_bookmarksModel->addFolder(m_bookmarksModel->rowCount() - 1, + QModelIndex{})); } - needToSaveBookmarks(); } /** Opens a dialog to change the current folder. */ void CBookmarkIndex::changeFolder() { - BtBookmarkFolder* i = dynamic_cast<BtBookmarkFolder*>(currentItem()); - Q_ASSERT(i); - if (i) { - i->rename(); - } + BT_ASSERT(m_bookmarksModel->isFolder(currentIndex())); + edit(currentIndex()); } /** Edits the current bookmark. */ void CBookmarkIndex::editBookmark() { - BtBookmarkItem* i = dynamic_cast<BtBookmarkItem*>(currentItem()); - Q_ASSERT(i); - - if (i) { - i->rename(); + QModelIndex const index = currentIndex(); + BT_ASSERT(m_bookmarksModel->isBookmark(index)); + CSwordModuleInfo * const module = m_bookmarksModel->module(index); + BtEditBookmarkDialog d{ + QString::fromLatin1("%1 (%2)").arg(m_bookmarksModel->key(index)) + .arg(module + ? module->name() + : QObject::tr("unknown")), + index.data().toString(), + m_bookmarksModel->description(index), + this}; + if (d.exec() == QDialog::Accepted) { + m_bookmarksModel->setData(index, d.titleText()); + m_bookmarksModel->setDescription(index, d.descriptionText()); } } /** Sorts the current folder bookmarks. */ void CBookmarkIndex::sortFolderBookmarks() { - BtBookmarkFolder* i = dynamic_cast<BtBookmarkFolder*>(currentItem()); - Q_ASSERT(i); - - if (i) { - i->sortChildren(0, Qt::AscendingOrder); - } + BT_ASSERT(m_bookmarksModel->isFolder(currentIndex())); + m_bookmarksModel->sortItems(currentIndex()); } /** Sorts all bookmarks. */ void CBookmarkIndex::sortAllBookmarks() { - sortItems(0, Qt::AscendingOrder); - int index = indexOfTopLevelItem(m_extraItem); - if (index >= 0) { - QTreeWidgetItem* item = takeTopLevelItem(index); - if (item != 0) { - addTopLevelItem(m_extraItem); - } + m_bookmarksModel->sortItems(); + if (m_extraItem.row() != m_bookmarksModel->rowCount() - 1) { + m_bookmarksModel->removeRow(m_extraItem.row(), m_extraItem.parent()); + if (m_bookmarksModel->insertRows(m_bookmarksModel->rowCount(), 1)) + m_extraItem = m_bookmarksModel->index(m_bookmarksModel->rowCount() - 1, 0); } } /** Exports the bookmarks being in the selected folder. */ void CBookmarkIndex::exportBookmarks() { - BtBookmarkFolder* i = dynamic_cast<BtBookmarkFolder*>(currentItem()); - Q_ASSERT(i); - - if (i) { - i->exportBookmarks(); - } + BT_ASSERT(m_bookmarksModel->isFolder(currentIndex())); + QString const fileName = + QFileDialog::getSaveFileName( + nullptr, + QObject::tr("Export Bookmarks"), + "", + QObject::tr("BibleTime bookmark files") + QString(" (*.btb);;") + + QObject::tr("All files") + QString(" (*.*)")); + if (!fileName.isEmpty()) + m_bookmarksModel->save(fileName, currentIndex()); } /** Import bookmarks from a file and add them to the selected folder. */ void CBookmarkIndex::importBookmarks() { - BtBookmarkFolder* i = dynamic_cast<BtBookmarkFolder*>(currentItem()); - Q_ASSERT(i); - - if (i) { - i->importBookmarks(); - } - needToSaveBookmarks(); + BT_ASSERT(m_bookmarksModel->isFolder(currentIndex())); + QString const fileName = + QFileDialog::getOpenFileName( + nullptr, + QObject::tr("Import bookmarks"), + "", + QObject::tr("BibleTime bookmark files") + + QString(" (*.btb);;") + + QObject::tr("All files") + QString(" (*.*)")); + if (!fileName.isEmpty()) + m_bookmarksModel->load(fileName, currentIndex()); } /** Prints the selected bookmarks. */ void CBookmarkIndex::printBookmarks() { - Printing::CPrinter::KeyTree tree; - Printing::CPrinter::KeyTreeItem::Settings settings; - settings.keyRenderingFace = Printing::CPrinter::KeyTreeItem::Settings::CompleteShort; - - QList<QTreeWidgetItem*> items; - BtBookmarkFolder* bf = dynamic_cast<BtBookmarkFolder*>(currentItem()); - - if (bf) { - items = bf->getChildList(); - } - else { - items = selectedItems(); - } - - //create a tree of keytreeitems using the bookmark hierarchy. - QListIterator<QTreeWidgetItem*> it(items); - while (it.hasNext()) { - BtBookmarkItem* i = dynamic_cast<BtBookmarkItem*>(it.next()); - if (i) { - qDebug() << "printBookmarks: add to list" << i->key(); - tree.append( new Printing::CPrinter::KeyTreeItem( i->key(), i->module(), settings ) ); + BT_ASSERT(hasBookmarksRecursively(selectedIndexes())); + BtPrinter::KeyTree tree; + { + BtPrinter::KeyTreeItem::Settings const settings{ + false, + BtPrinter::KeyTreeItem::Settings::CompleteShort}; + QModelIndexList items(selectedIndexes()); + while (!items.empty()) { + QModelIndex const index(items.takeFirst()); + if (m_bookmarksModel->isBookmark(index)) { + tree.append( + new BtPrinter::KeyTreeItem{ + m_bookmarksModel->key(index), + m_bookmarksModel->module(index), + settings}); + } else if (m_bookmarksModel->isFolder(index)) { + int const numChildren = m_bookmarksModel->rowCount(index); + for (int i = 0; i < numChildren; i++) + items.append(index.child(i, 0)); + } } } + BT_ASSERT(!tree.isEmpty()); - if (items.isEmpty()) { - qWarning("Tried to print empty bookmark list."); - return; - } - QSharedPointer<Printing::CPrinter> printer( - new Printing::CPrinter( this, btConfig().getDisplayOptions(), btConfig().getFilterOptions() ) - ); - printer->printKeyTree(tree); + BtPrinter{btConfig().getDisplayOptions(), + btConfig().getFilterOptions(), + this}.printKeyTree(tree); } -/** Deletes the selected entries. */ -void CBookmarkIndex::deleteEntries(bool confirm) { - if (confirm) { - if (!selectedItems().count()) { - BtBookmarkItemBase* f = dynamic_cast<BtBookmarkItemBase*>(currentItem()); - if (f) { - currentItem()->setSelected(true); - } - else { - return; - } - } +void CBookmarkIndex::confirmDeleteEntries() { + if (message::showQuestion( + this, + tr("Delete Items"), + tr("Do you really want to delete the selected items and folders?"), + QMessageBox::Yes | QMessageBox::No, + QMessageBox::No) == QMessageBox::Yes) + deleteEntries(); +} - if (message::showQuestion(this, tr("Delete Items"), - tr("Do you really want to delete the selected items and child-items?"), - QMessageBox::Yes | QMessageBox::No, QMessageBox::No ) - != QMessageBox::Yes) { - return; - } - } +void CBookmarkIndex::deleteEntries() { + /* We need to use QPersistentModelIndex because after removeRows QModelIndex + will be invalidated. Need to delete per index because selected indexes + might be under different parents. */ + QList<QPersistentModelIndex> list; + Q_FOREACH(QModelIndex const & i, selectedIndexes()) + list.append(i); - while (selectedItems().size() > 0) { - delete selectedItems().at(0); // deleting all does not work because it may cause double deletion - } - // Save the bookmarks. One way would be to signal that the bookmarks have - // changed emit a signal so that a number of changes may be saved at once. - // Another way is to simply save the bookmarks after each change, which can - // be inefficient. - needToSaveBookmarks(); + Q_FOREACH(QModelIndex const & i, list) + model()->removeRows(i.row(), 1, i.parent()); } @@ -727,164 +634,59 @@ a BibleTime mimedata object. It can be dragged and dropped to a text view or som The internal drag is handled differently, it doesn't use the mimedata (see dropEvent()). */ void CBookmarkIndex::startDrag(Qt::DropActions) { - - QMimeData* mData = dragObject(); // create the data which can be used in other widgets - QDrag* drag = new QDrag(this); + // Create the data which can be used in other widgets: + QMimeData * const mData = dragObject(); + QDrag * const drag = new QDrag{this}; drag->setMimeData(mData); drag->exec(); viewport()->update(); // because of the arrow } - - - - - -/* Returns true if more than one entry is supported by this action type. Returns false for actions which support only one entry, e.g. about module etc. */ -bool CBookmarkIndex::isMultiAction( const BtBookmarkItemBase::MenuAction type ) const { - switch (type) { - case BtBookmarkItemBase::NewFolder: - return false; - case BtBookmarkItemBase::ChangeFolder: - return false; - - case BtBookmarkItemBase::EditBookmark: - return false; - case BtBookmarkItemBase::SortFolderBookmarks: - return false; - case BtBookmarkItemBase::SortAllBookmarks: - return false; - case BtBookmarkItemBase::ImportBookmarks: - return false; - case BtBookmarkItemBase::ExportBookmarks: - return false; - case BtBookmarkItemBase::PrintBookmarks: - return true; - - case BtBookmarkItemBase::DeleteEntries: - return true; - } - - return false; -} - -/* Saves the bookmarks to the default bookmarks file. */ -void CBookmarkIndex::saveBookmarks() { - BtBookmarkLoader loader; - loader.saveTreeFromRootItem(invisibleRootItem()); -} - -void CBookmarkIndex::mouseMoveEvent(QMouseEvent* event) { - - // Restart the mag timer if we have moved to another item and shift was not pressed. - QTreeWidgetItem* itemUnderPointer = itemAt(event->pos()); - if (itemUnderPointer && (itemUnderPointer != m_previousEventItem) ) { - if ( !(event->modifiers() & Qt::ShiftModifier)) { - m_magTimer.start(); // see the ctor for the timer properties - } - } +void CBookmarkIndex::mouseMoveEvent(QMouseEvent * event) { + /* Restart the mag timer if we have moved to another item and shift was not + pressed: */ + QModelIndex const itemUnderPointer = indexAt(event->pos()); + if (itemUnderPointer.isValid() + && (itemUnderPointer != m_previousEventItem) + && !(event->modifiers() & Qt::ShiftModifier)) + m_magTimer.start(); m_previousEventItem = itemUnderPointer; - // Clear the extra item text unless we are on top of it - if ( (itemUnderPointer != m_extraItem) && !m_extraItem->text(0).isNull()) { - m_extraItem->setText(0, QString::null); + if (!itemUnderPointer.isValid() || itemUnderPointer == m_extraItem) { + showExtraItem(); + } else { + hideExtraItem(); } + update(); - QTreeWidget::mouseMoveEvent(event); + QTreeView::mouseMoveEvent(event); } void CBookmarkIndex::magTimeout() { - QTreeWidgetItem* itemUnderPointer = 0; - if (underMouse()) { - itemUnderPointer = itemAt(mapFromGlobal(QCursor::pos())); - } - // if the mouse pointer have been over the same item since the timer was started - if (itemUnderPointer && (m_previousEventItem == itemUnderPointer)) { - BtBookmarkItem* bitem = dynamic_cast<BtBookmarkItem*>(itemUnderPointer); - if (bitem) { - // Update the mag - if (bitem->module()) { - (BibleTime::instance()->infoDisplay())->setInfo( - InfoDisplay::CInfoDisplay::CrossReference, - bitem->module()->name() + ":" + bitem->key() - ); - } - else { - (BibleTime::instance()->infoDisplay())->setInfo(InfoDisplay::CInfoDisplay::Text, tr("The work to which the bookmark points to is not installed.")); - } + if (!underMouse()) + return; + /* Update the Mag only if the mouse pointer have been over the same item + since the timer was started. */ + QModelIndex const itemUnderPointer{indexAt(mapFromGlobal(QCursor::pos()))}; + if (itemUnderPointer.isValid() + && m_previousEventItem == itemUnderPointer + && m_bookmarksModel->isBookmark(itemUnderPointer)) + { + BT_ASSERT(BibleTime::instance()->infoDisplay()); + InfoDisplay::CInfoDisplay & infoDisplay = + *(BibleTime::instance()->infoDisplay()); + if (CSwordModuleInfo const * const module = + m_bookmarksModel->module(itemUnderPointer)) + { + infoDisplay.setInfo( + Rendering::CrossReference, + module->name() + ":" + m_bookmarksModel->key(itemUnderPointer)); + } else { + infoDisplay.setInfo(Rendering::Text, + tr("The work to which the bookmark points to " + "is not installed.")); } } } - -/* -Creates a list of new items based on the current selection. -If there are only bookmarks in the selection they are all included. -If there is one folder it's included as a deep copy. -Sets bookmarksOnly=false if it finds a folder. -Sets targetIncluded=true if the target is in the list. -Sets moreThanOneFolder=true if selection includes one folder and something more. -If moreThanOneFolder or targetIncluded is detected the creation of list is stopped -and the list is incomplete. -*/ -QList<QTreeWidgetItem*> CBookmarkIndex::addItemsToDropTree( - QTreeWidgetItem* target, bool& bookmarksOnly, bool& targetIncluded, bool& moreThanOneFolder) { - QList<QTreeWidgetItem*> selectedList = selectedItems(); - QList<QTreeWidgetItem*> newList; - - foreach(QTreeWidgetItem* item, selectedList) { - if ( BtBookmarkFolder* folder = dynamic_cast<BtBookmarkFolder*>(item)) { - bookmarksOnly = false; - if (selectedList.count() > 1) { // only one item allowed if a folder is selected - moreThanOneFolder = true; - break; - } - if (folder->hasDescendant(target)) { // dropping to self or descendand not allowed - targetIncluded = true; - break; - } - } - else { - newList.append(new BtBookmarkItem( *(dynamic_cast<BtBookmarkItem*>(item)) )); - } - } - if (!bookmarksOnly && selectedList.count() == 1) { - BtBookmarkFolder* folder = dynamic_cast<BtBookmarkFolder*>(selectedList.value(0)); - BtBookmarkFolder* copy = folder->deepCopy(); - newList.append(copy); - } - if (!bookmarksOnly && selectedList.count() > 1) { - // wrong amount of items - moreThanOneFolder = true; - } - return newList; -} - -/// Bookmark saving code. To avoid many saves during a short period of time, -/// bookmark modification is first noted. Then, after a wait (1.5s), if no more -/// modifications are made, the bookmarks are saved. The timer is reset when a -/// new modification is made. The timer bookmarkSaveTimer is set to be oneshot. -void CBookmarkIndex::needToSaveBookmarks() { - m_bookmarksModified = true; - bookmarkSaveTimer.start(1500); // Only save after 1.5s. -} -void CBookmarkIndex::needToSaveBookmarks(QTreeWidgetItem* treeItem) { - // Need to test whether the item that changed is not just a display item, - // but actually a folder or bookmark. - BtBookmarkItemBase* bookmark = dynamic_cast<BtBookmarkItemBase*>(treeItem); - if (bookmark) { - m_bookmarksModified = true; - bookmarkSaveTimer.start(1500); // Only save after 1.5s. - } -} - -/// Considers saving bookmarks only if they have been modified. This procedure -/// should be called by the qtimer bookmarkTimer. -void CBookmarkIndex::considerSavingBookmarks() { - if (m_bookmarksModified) { - saveBookmarks(); - m_bookmarksModified = false; - } -} - diff --git a/src/frontend/bookmarks/cbookmarkindex.h b/src/frontend/bookmarks/cbookmarkindex.h index df4a1c6..4ae3c0e 100644 --- a/src/frontend/bookmarks/cbookmarkindex.h +++ b/src/frontend/bookmarks/cbookmarkindex.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -12,18 +12,13 @@ #ifndef CBOOKMARKINDEX_H #define CBOOKMARKINDEX_H -#include "frontend/bookmarks/btbookmarkitembase.h" - -#include <QList> #include <QTimer> -#include <QTreeWidget> -#include <QTreeWidgetItem> #include <QToolTip> -#include "frontend/displaywindow/cdisplaywindow.h" +#include <QTreeView> class BTMimeData; -class CSearchDialog; +class BtBookmarksModel; class CSwordModuleInfo; class QAction; class QDragLeaveEvent; @@ -32,185 +27,128 @@ class QDropEvent; class QMenu; class QMouseEvent; class QPaintEvent; -class QWidget; /** * The widget which manages all bookmarks. -* @author The BibleTime team +* +* \author The BibleTime team */ -class CBookmarkIndex : public QTreeWidget { - Q_OBJECT - public: - CBookmarkIndex(QWidget *parent); - virtual ~CBookmarkIndex(); - - void initTree(); - - /** - * Saves the bookmarks to disk - */ - void saveBookmarks(); - - signals: - /** - * Is emitted when a module should be opened, - */ - void createReadDisplayWindow( QList<CSwordModuleInfo*>, const QString& ); - - public slots: - - /** - * Indicates a need to save the bookmarks. - * This is needed to provide a way for a bookmarkitem stored in the - * treeWidget to inform us that it has been modified, namely its - * description text. It only sets a dirty-bit so we don't execute many - * consecutive saves. - */ - void needToSaveBookmarks(); - void needToSaveBookmarks(QTreeWidgetItem* treeItem); - - - protected: // Protected methods - - /** A hack to get the modifiers. */ - virtual void mouseReleaseEvent(QMouseEvent* event); +class CBookmarkIndex: public QTreeView { - /** Needed to paint an drag pointer arrow. */ - virtual void paintEvent(QPaintEvent* event); + Q_OBJECT - /** Initialize the SIGNAL<->SLOT connections. */ - void initConnections(); +public: /* Types: */ - /** Returns the drag object for the current selection. */ - virtual QMimeData* dragObject(); + enum MenuAction { + NewFolder = 0, + ChangeFolder, - /** - * D'n'd methods are reimplementations from QTreeWidget or its ancestors. - * In these we handle creating, moving and copying bookmarks with d'n'd. - */ - virtual void dragEnterEvent( QDragEnterEvent* event ); - virtual void dragMoveEvent( QDragMoveEvent* event ); - virtual void dropEvent( QDropEvent* event ); - virtual void dragLeaveEvent( QDragLeaveEvent* event ); + EditBookmark, + SortFolderBookmarks, + SortAllBookmarks, + ImportBookmarks, + ExportBookmarks, + PrintBookmarks, - /** Returns the correct action object for the given type of action. */ - QAction* action( BtBookmarkItemBase::MenuAction type ) const; + DeleteEntries, - /** Reimplementation from QAbstractItemView. Takes care of movable items. */ - virtual void startDrag(Qt::DropActions supportedActions); + ActionCount, + ActionBegin = NewFolder, + ActionEnd = ActionCount + }; +public: /* Methods: */ - /** Handle mouse moving (mag updates) */ - virtual void mouseMoveEvent(QMouseEvent* event); + CBookmarkIndex(QWidget * const parent = nullptr); +signals: - protected slots: + /** \brief Emitted when a module should be opened. */ + void createReadDisplayWindow(QList<CSwordModuleInfo *>, QString const &); - /** Prevents annoying folder collapsing while dropping. */ - void expandAutoCollapsedItem(QTreeWidgetItem* i) { - expandItem(i); - } +protected: /* Methods: */ - /** Is called when an item was clicked or activated. */ - void slotExecuted( QTreeWidgetItem* ); + QMimeData * dragObject(); - /** Shows the context menu at the given position. */ - void contextMenu(const QPoint&); + void mouseReleaseEvent(QMouseEvent * event) override; + void paintEvent(QPaintEvent * event) override; + void dragEnterEvent(QDragEnterEvent * event) override; + void dragMoveEvent(QDragMoveEvent * event) override; + void dropEvent(QDropEvent * event) override; + void dragLeaveEvent(QDragLeaveEvent * event) override; + void startDrag(Qt::DropActions supportedActions) override; + void mouseMoveEvent(QMouseEvent * event) override; + void leaveEvent(QEvent * event) override; - /** Adds a new subfolder to the current item. */ - void createNewFolder(); +protected slots: - /** Opens a dialog to change the current folder. */ - void changeFolder(); + /** Prevents annoying folder collapsing while dropping. */ + void expandAutoCollapsedItem(QModelIndex const & index) { expand(index); } - /** Exports the bookmarks from the selected folder. */ - void exportBookmarks(); + /** Is called when an item was clicked or activated. */ + void slotExecuted(QModelIndex const & index); - /** Changes the current bookmark. */ - void editBookmark(); + /** Shows the context menu at the given position. */ + void contextMenu(QPoint const & p); - /** Sorts the current folder bookmarks. */ - void sortFolderBookmarks(); + /** Adds a new subfolder to the current item. */ + void createNewFolder(); - /** Sorts all bookmarks. */ - void sortAllBookmarks(); + /** Opens a dialog to change the current folder. */ + void changeFolder(); - /** Helps with the extra item. */ - void slotItemEntered(QTreeWidgetItem*, int); + /** Exports the bookmarks from the selected folder. */ + void exportBookmarks(); - /** Import bookmarks from a file and add them to the selected folder. */ - void importBookmarks(); + /** Changes the current bookmark. */ + void editBookmark(); - /** Deletes the selected entries. */ - void deleteEntries(bool confirm = true); + /** Sorts the current folder bookmarks. */ + void sortFolderBookmarks(); - /** Prints the selected bookmarks. */ - void printBookmarks(); + /** Sorts all bookmarks. */ + void sortAllBookmarks(); - /** Slot for the mag update timer. */ - void magTimeout(); + /** Import bookmarks from a file and add them to the selected folder. */ + void importBookmarks(); - private: + /** Deletes the selected entries after user confirmation. */ + void confirmDeleteEntries(); - /** Initializes the view. */ - void initView(); + /** Deletes the selected entries. */ + void deleteEntries(); - /** Convenience function for creating a new action. */ - QAction* newQAction(const QString& text, const QString& pix, int shortcut, const QObject* receiver, const char* slot, QObject* parent); + /** Prints the selected bookmarks. */ + void printBookmarks(); - /** - * Returns true if more than one entry is supported by this action type. - * Returns false for actions which support only one entry. - */ - bool isMultiAction( const BtBookmarkItemBase::MenuAction type ) const; + /** Slot for the mag update timer. */ + void magTimeout(); - /** A helper function for d'n'd which creates a new bookmark item when drop happens. */ - void createBookmarkFromDrop(QDropEvent* event, QTreeWidgetItem* parentItem, int indexInParent); +private: /* Methods: */ - /** - * Returns a list of new items created from the selection. - * Sets flags which indicate whether the selection was legal for dropping. - */ - QList<QTreeWidgetItem*> addItemsToDropTree(QTreeWidgetItem* target, bool& bookmarksOnly, bool& targetIncluded, bool& moreThanOneFolder); + bool enableAction(QModelIndex const & index, + MenuAction const type) const; - struct Actions { - QAction* newFolder; - QAction* changeFolder; + bool hasBookmarksRecursively(QModelIndexList selected) const; - QAction* editBookmark; - QAction* sortFolderBookmarks; - QAction* sortAllBookmarks; - QAction* importBookmarks; - QAction* exportBookmarks; - QAction* printBookmarks; + void showExtraItem(); + void hideExtraItem(); - QAction* deleteEntries; - } - m_actions; +private: /* Fields: */ - QMenu* m_popup; - QTimer m_magTimer; - int m_mouseReleaseEventModifiers; - QTreeWidgetItem* m_previousEventItem; - QPoint m_dragMovementPosition; - QPoint m_dragStartPosition; - QTreeWidgetItem* m_extraItem; + QAction * m_actions[ActionCount]; - // The following is for managing saving bookmarks. It uses a QTimer to - // determine whether the bookmarks should be saved. This may seem like - // a hassle, but it is to prevent many saves from being executed at a - // time. + QMenu * m_popup; + QTimer m_magTimer; + int m_mouseReleaseEventModifiers; + QModelIndex m_previousEventItem; + QPoint m_dragMovementPosition; + QPoint m_dragStartPosition; + QPersistentModelIndex m_extraItem; - /** Flag indicating that bookmarks have been modified. */ - bool m_bookmarksModified; - QTimer bookmarkSaveTimer; + /** Pointer to bookmarks model, added for convenience. */ + BtBookmarksModel * m_bookmarksModel; - private slots: - /** - * Saves the bookmarks. - * It checks m_bookmarksModified and resets it at the end. It should be - * connected to a timer that periodically calls this. */ - void considerSavingBookmarks(); }; #endif diff --git a/src/frontend/bookshelfmanager/btconfigdialog.cpp b/src/frontend/bookshelfmanager/btconfigdialog.cpp deleted file mode 100644 index e5d0fd1..0000000 --- a/src/frontend/bookshelfmanager/btconfigdialog.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/********* -* -* 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 "frontend/bookshelfmanager/btconfigdialog.h" - -#include <QDialog> -#include <QDialogButtonBox> -#include <QEvent> -#include <QFrame> -#include <QHBoxLayout> -#include <QLabel> -#include <QListWidget> -#include <QListView> -#include <QStackedWidget> -#include <QVBoxLayout> - - -BtConfigDialog::BtConfigDialog(QWidget* parent, Qt::WindowFlags flags) - : QDialog(parent, flags) - , m_buttonBoxRuler(0) - , m_buttonBox(0) - , m_maxItemWidth(0) - , m_previousPageIndex(-2) -{ - m_contentsList = new QListWidget(this); - m_contentsList->setViewMode(QListView::IconMode); - m_contentsList->setMovement(QListView::Static); - - m_pageWidget = new QStackedWidget(this); - m_pageWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); - - m_pageLayout = new QVBoxLayout; - m_pageLayout->addWidget(m_pageWidget); - - QHBoxLayout *mainLayout = new QHBoxLayout(this); - mainLayout->addWidget(m_contentsList); - mainLayout->addLayout(m_pageLayout); - - connect(m_contentsList, SIGNAL(currentRowChanged(int)), - this, SLOT(slotChangePage(int))); -} - -void BtConfigDialog::addPage(Page* pageWidget) { - - m_pageWidget->addWidget(pageWidget); - - QListWidgetItem* item = new QListWidgetItem(m_contentsList); - item->setIcon(pageWidget->icon()); - item->setText(pageWidget->headerText()); - item->setTextAlignment(Qt::AlignHCenter); - item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); - pageWidget->setListWidgetItem(item); - - //set the list width - it may bee too wide (if there were no pages) or too narrow - if (m_maxItemWidth < m_contentsList->visualItemRect(item).width()) { - m_maxItemWidth = m_contentsList->visualItemRect(item).width(); - m_contentsList->setFixedWidth( m_maxItemWidth + (m_contentsList->frameWidth()*2) ); - } - // all items should has the same width - for (int i = 0; i < m_contentsList->count(); ++i) { - m_contentsList->item(i)->setSizeHint(QSize(m_maxItemWidth, m_contentsList->visualItemRect(m_contentsList->item(i)).height()) ); - } - - setCurrentPage(m_contentsList->row(item)); -} - -void BtConfigDialog::setButtonBox(QDialogButtonBox *box) { - Q_ASSERT(box != 0); - Q_ASSERT(m_buttonBox == 0); - Q_ASSERT(m_buttonBoxRuler == 0); - - m_buttonBox = box; - - // First add a horizontal ruler: - m_buttonBoxRuler = new QFrame(this); - m_buttonBoxRuler->setGeometry(QRect(1, 1, 1, 3)); - m_buttonBoxRuler->setFrameShape(QFrame::HLine); - m_buttonBoxRuler->setFrameShadow(QFrame::Sunken); - m_buttonBoxRuler->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); - m_pageLayout->addWidget(m_buttonBoxRuler); - - // Add button box: - m_pageLayout->addWidget(box); -} - -void BtConfigDialog::setCurrentPage(int newIndex) { - if (m_previousPageIndex != newIndex) { - m_previousPageIndex = newIndex; - m_contentsList->setCurrentRow(newIndex); - m_pageWidget->setCurrentIndex(newIndex); - } -} - -void BtConfigDialog::slotChangePage(int newIndex) { - /* - This check is in place here because this slot is indirectly called by the - setCurrentPage method. - */ - if (m_previousPageIndex != newIndex) { - m_previousPageIndex = newIndex; - m_pageWidget->setCurrentIndex(newIndex); - } -} diff --git a/src/frontend/bookshelfmanager/btconfigdialog.h b/src/frontend/bookshelfmanager/btconfigdialog.h deleted file mode 100644 index 2525bd8..0000000 --- a/src/frontend/bookshelfmanager/btconfigdialog.h +++ /dev/null @@ -1,110 +0,0 @@ -/********* -* -* 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 BTCONFIGDIALOG_H -#define BTCONFIGDIALOG_H - -#include <QDialog> - -#include <QIcon> -#include <QListWidgetItem> - - -class BtConfigPage; -class QDialogButtonBox; -class QFrame; -class QStackedWidget; -class QVBoxLayout; - -/** -* Base class for configuration dialogs. A dialog which has a page chooser (icons -* + text) at the left, widget pages and a buttonbox. -* -* Usage: add BtConfigPage pages with addPage(), add a button box with addButtonBox(). -* Connect the button box signals. Use setAttribute(Qt::WA_DeleteOnClose) if you want -* an auto-destroying window. -*/ -class BtConfigDialog : public QDialog { - - Q_OBJECT - - public: /* Types: */ - - /** Base class for configuration dialog pages. */ - class Page : public QWidget { - - friend class BtConfigDialog; - - public: /* Methods: */ - - inline Page(BtConfigDialog *parent) - : QWidget(parent), m_listWidgetItem(0) {} - inline Page(const QIcon &icon, BtConfigDialog *parent) - : QWidget(parent), m_icon(icon), m_listWidgetItem(0) {} - - inline const QIcon &icon() const { return m_icon; } - inline void setIcon(const QIcon &icon) { - m_icon = icon; - if (m_listWidgetItem != 0) - m_listWidgetItem->setIcon(icon); - } - - inline const QString &headerText() const { return m_headerText; } - inline void setHeaderText(const QString &headerText) { - m_headerText = headerText; - if (m_listWidgetItem != 0) - m_listWidgetItem->setText(headerText); - } - - private: /* Methods: */ - - void setListWidgetItem(QListWidgetItem *item) { - m_listWidgetItem = item; - } - - private: /* Fields: */ - - QIcon m_icon; - QString m_headerText; - QListWidgetItem *m_listWidgetItem; - - }; - - public: /* Methods: */ - - BtConfigDialog(QWidget *parent = 0, Qt::WindowFlags flags = 0); - - /** Adds a BtConfigPage to the paged widget stack. The new page will be the current page.*/ - void addPage(Page *pageWidget); - - /** Adds a button box to the lower edge of the dialog. */ - void setButtonBox(QDialogButtonBox* buttonBox); - - /** Changes the current page using the given index number. */ - void setCurrentPage(int newIndex); - - private slots: - - void slotChangePage(int newIndex); - - private: /* Fields: */ - - QListWidget* m_contentsList; - QStackedWidget* m_pageWidget; - QVBoxLayout* m_pageLayout; - QFrame *m_buttonBoxRuler; - QDialogButtonBox *m_buttonBox; - int m_maxItemWidth; - int m_previousPageIndex; - -}; - -#endif diff --git a/src/frontend/bookshelfmanager/btmodulemanagerdialog.cpp b/src/frontend/bookshelfmanager/btmodulemanagerdialog.cpp deleted file mode 100644 index 8eebde6..0000000 --- a/src/frontend/bookshelfmanager/btmodulemanagerdialog.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/********* -* -* 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 "frontend/bookshelfmanager/btmodulemanagerdialog.h" - -#include "backend/config/btconfig.h" -#include "backend/managers/cswordbackend.h" -#include "frontend/bookshelfmanager/indexpage/btindexpage.h" -#include "frontend/bookshelfmanager/installpage/btinstallpage.h" -#include "frontend/bookshelfmanager/removepage/btremovepage.h" - - -namespace { -const QString GeometryKey = "GUI/BookshelfManager/ModuleManagerDialog/geometry"; -} // anonymous namespace - -static BtModuleManagerDialog *m_staticModuleManagerDialog = 0; - -BtModuleManagerDialog* BtModuleManagerDialog::getInstance(QWidget *parent, - Qt::WindowFlags flags) -{ - if (m_staticModuleManagerDialog) { - m_staticModuleManagerDialog->setParent(parent, flags); - } else { - m_staticModuleManagerDialog = new BtModuleManagerDialog(parent, flags); - } - Q_ASSERT(m_staticModuleManagerDialog); - return m_staticModuleManagerDialog; -} - -BtModuleManagerDialog::BtModuleManagerDialog(QWidget *parent, - Qt::WindowFlags flags) - : BtConfigDialog(parent, - flags | Qt::CustomizeWindowHint | Qt::WindowTitleHint - | Qt::WindowCloseButtonHint | Qt::WindowMaximizeButtonHint) -{ - setAttribute(Qt::WA_DeleteOnClose); - - addPage(new BtInstallPage()); - addPage(new BtRemovePage()); - addPage(new BtIndexPage()); - - retranslateUi(); - - loadDialogSettings(); - setCurrentPage(0); - -} - -void BtModuleManagerDialog::retranslateUi() { - setWindowTitle(tr("Bookshelf Manager")); -} - -BtModuleManagerDialog::~BtModuleManagerDialog() { - saveDialogSettings(); - m_staticModuleManagerDialog = 0; -} - -void BtModuleManagerDialog::loadDialogSettings() { - restoreGeometry(btConfig().value<QByteArray>(GeometryKey, QByteArray())); -} - -void BtModuleManagerDialog::saveDialogSettings() const { - btConfig().setValue(GeometryKey, saveGeometry()); -} diff --git a/src/frontend/bookshelfmanager/btmodulemanagerdialog.h b/src/frontend/bookshelfmanager/btmodulemanagerdialog.h deleted file mode 100644 index 4d94026..0000000 --- a/src/frontend/bookshelfmanager/btmodulemanagerdialog.h +++ /dev/null @@ -1,46 +0,0 @@ -/********* -* -* 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 BTMODULEMANAGERDIALOG_H -#define BTMODULEMANAGERDIALOG_H - -#include "frontend/bookshelfmanager/btconfigdialog.h" - - -/** -* The Bookshelf Manager dialog. Includes pages for Install, Remove, Indexes. -*/ -class BtModuleManagerDialog: public BtConfigDialog { - - Q_OBJECT - - public: - - static BtModuleManagerDialog *getInstance(QWidget *parent = 0, - Qt::WindowFlags flags = 0); - ~BtModuleManagerDialog(); - - private: - - BtModuleManagerDialog(QWidget *parent = 0, Qt::WindowFlags flags = 0); - - void retranslateUi(); - - /** Loads the settings from the resource file. */ - void loadDialogSettings(); - - /** Saves the settings to the resource file. */ - void saveDialogSettings() const; - -}; - - -#endif diff --git a/src/frontend/bookshelfmanager/indexpage/btindexpage.cpp b/src/frontend/bookshelfmanager/indexpage/btindexpage.cpp deleted file mode 100644 index b117f80..0000000 --- a/src/frontend/bookshelfmanager/indexpage/btindexpage.cpp +++ /dev/null @@ -1,181 +0,0 @@ -/********* -* -* 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 "frontend/bookshelfmanager/indexpage/btindexpage.h" - -#include <QCheckBox> -#include <QDir> -#include <QHBoxLayout> -#include <QPushButton> -#include <QTreeWidget> -#include <QTreeWidgetItem> -#include <QVBoxLayout> -#include "backend/config/btconfig.h" -#include "backend/drivers/cswordmoduleinfo.h" -#include "backend/managers/cswordbackend.h" -#include "bibletimeapp.h" -#include "frontend/bookshelfmanager/btmodulemanagerdialog.h" -#include "frontend/btmoduleindexdialog.h" -#include "util/cresmgr.h" -#include "util/geticon.h" -#include "util/tool.h" - - -BtIndexPage::BtIndexPage(BtModuleManagerDialog *parent) - : BtConfigDialog::Page(util::getIcon(CResMgr::bookshelfmgr::indexpage::icon), parent) -{ - QVBoxLayout *vboxLayout = new QVBoxLayout(this); - QHBoxLayout *hboxLayout; - - m_autoDeleteOrphanedIndicesBox = new QCheckBox(this); - vboxLayout->addWidget(m_autoDeleteOrphanedIndicesBox); - - m_moduleList = new QTreeWidget(this); - vboxLayout->addWidget(m_moduleList); - - hboxLayout = new QHBoxLayout(); - - QSpacerItem *spacerItem = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); - hboxLayout->addItem(spacerItem); - - m_deleteButton = new QPushButton(this); - hboxLayout->addWidget(m_deleteButton); - - m_createButton = new QPushButton(this); - hboxLayout->addWidget(m_createButton); - - vboxLayout->addLayout(hboxLayout); - - // configure the list view - m_moduleList->setHeaderLabels( (QStringList(tr("Work")) << tr("Index size")) ); /// \todo Move to retranslateUi() - m_moduleList->setRootIsDecorated(true); - m_moduleList->setColumnWidth(0, util::tool::mWidth(m_moduleList, 20) ); - //m_moduleList->setTextAlignment(1, Qt::AlignRight); see doc... - m_moduleList->setSortingEnabled(false); - - m_autoDeleteOrphanedIndicesBox->setChecked( btConfig().value<bool>("settings/behaviour/autoDeleteOrphanedIndices", true) ); - - // icons for our buttons - m_createButton->setIcon(util::getIcon(CResMgr::bookshelfmgr::indexpage::create_icon)); - m_deleteButton->setIcon(util::getIcon(CResMgr::bookshelfmgr::indexpage::delete_icon)); - - // connect our signals/slots - connect(m_createButton, SIGNAL(clicked()), - this, SLOT(createIndices())); - connect(m_deleteButton, SIGNAL(clicked()), - this, SLOT(deleteIndices())); - connect(CSwordBackend::instance(), SIGNAL(sigSwordSetupChanged(CSwordBackend::SetupChangedReason)), - this, SLOT(slotSwordSetupChanged())); - - retranslateUi(); // also calls populateModuleList(); -} - -BtIndexPage::~BtIndexPage() { - btConfig().setValue("settings/behaviour/autoDeleteOrphanedIndices", m_autoDeleteOrphanedIndicesBox->isChecked() ); -} - -/** Populates the module list with installed modules and orphaned indices */ -void BtIndexPage::populateModuleList() { - typedef QList<CSwordModuleInfo*>::const_iterator MLCI; - - m_moduleList->clear(); - - // populate installed modules - m_modsWithIndices = new QTreeWidgetItem(m_moduleList); - m_modsWithIndices->setText(0, tr("Indexed Works")); - m_modsWithIndices->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsTristate); - m_modsWithIndices->setExpanded(true); - - m_modsWithoutIndices = new QTreeWidgetItem(m_moduleList); - m_modsWithoutIndices->setText(0, tr("Unindexed Works")); - m_modsWithoutIndices->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsTristate); - m_modsWithoutIndices->setExpanded(true); - - const QList<CSwordModuleInfo*> &modules(CSwordBackend::instance()->moduleList()); - for (MLCI it(modules.begin()); it != modules.end(); ++it) { - QTreeWidgetItem* item = 0; - - if ((*it)->hasIndex()) { - item = new QTreeWidgetItem(m_modsWithIndices); - item->setText(0, (*it)->name()); - item->setText(1, tr("%1 KiB").arg((*it)->indexSize() / 1024)); - item->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); - item->setCheckState(0, Qt::Unchecked); - } - else { - item = new QTreeWidgetItem(m_modsWithoutIndices); - item->setText(0, (*it)->name()); - item->setText(1, tr("0 KiB")); - item->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); - item->setCheckState(0, Qt::Checked); - } - } -} - -void BtIndexPage::retranslateUi() { - setHeaderText(tr("Search Indexes")); - - m_autoDeleteOrphanedIndicesBox->setToolTip(tr("If selected, those indexes which have no corresponding work will be deleted when BibleTime starts")); - m_autoDeleteOrphanedIndicesBox->setText(tr("Automatically delete orphaned indexes when BibleTime starts")); - - m_deleteButton->setToolTip(tr("Delete the selected indexes")); - m_deleteButton->setText(tr("Delete")); - - m_createButton->setToolTip(tr("Create new indexes for the selected works")); - m_createButton->setText(tr("Create...")); - - populateModuleList(); -} - -/** Creates indices for selected modules if no index currently exists */ -void BtIndexPage::createIndices() { - bool indicesCreated = false; - QList<const CSwordModuleInfo*> moduleList; - - for (int i = 0; i < m_modsWithoutIndices->childCount(); i++) { - if (m_modsWithoutIndices->child(i)->checkState(0) == Qt::Checked) { - CSwordModuleInfo* module = CSwordBackend::instance()->findModuleByName(m_modsWithoutIndices->child(i)->text(0).toUtf8()); - if (module) { - moduleList.append( module ); - indicesCreated = true; - } - } - } - - //Shows the progress dialog - if (indicesCreated) { - BtModuleIndexDialog::indexAllModules(moduleList); - populateModuleList(); - } -} - -/** Deletes indices for selected modules */ -void BtIndexPage::deleteIndices() { - bool indicesDeleted = false; - - for (int i = 0; i < m_modsWithIndices->childCount(); i++) { - if (m_modsWithIndices->child(i)->checkState(0) == Qt::Checked) { - CSwordModuleInfo* module = CSwordBackend::instance()->findModuleByName(m_modsWithIndices->child(i)->text(0).toUtf8()); - if (module) { - module->deleteIndex(); - indicesDeleted = true; - } - } - } - - // repopulate the list if an action was taken - if (indicesDeleted) { - populateModuleList(); - } -} - -void BtIndexPage::slotSwordSetupChanged() { - populateModuleList(); -} - diff --git a/src/frontend/bookshelfmanager/indexpage/btindexpage.h b/src/frontend/bookshelfmanager/indexpage/btindexpage.h deleted file mode 100644 index 100de17..0000000 --- a/src/frontend/bookshelfmanager/indexpage/btindexpage.h +++ /dev/null @@ -1,74 +0,0 @@ -/********* -* -* 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 BTINDEXPAGE_H -#define BTINDEXPAGE_H - -#include "frontend/bookshelfmanager/btconfigdialog.h" - - -class BtModuleManagerDialog; -class QCheckBox; -class QTreeWidget; -class QTreeWidgetItem; - -/** \todo add void retranslateUi(); */ - -/** -* This class encapsulates the "Manage search indices" page of the Bookshelf -* Manager. It allows for creation and deletion of search indicies for each -* installed module. It also allows for deletion of orphaned indices. -*/ -class BtIndexPage: public BtConfigDialog::Page { - - Q_OBJECT - - public: - - BtIndexPage(BtModuleManagerDialog *parent = 0); - ~BtIndexPage(); - - public slots: - void slotSwordSetupChanged(); - - protected: - - /** - * Populates the module list with installed modules and orphaned indices - */ - void populateModuleList(); - - void retranslateUi(); - - public slots: - /** - * Creates indices for selected modules if no index currently exists - */ - void createIndices(); - /** - * Deletes indices for selected modules - */ - void deleteIndices(); - - private: - - QCheckBox *m_autoDeleteOrphanedIndicesBox; - QTreeWidget *m_moduleList; - QPushButton *m_deleteButton; - QPushButton *m_createButton; - - QTreeWidgetItem* m_modsWithIndices; - QTreeWidgetItem* m_modsWithoutIndices; - -}; - - -#endif diff --git a/src/frontend/bookshelfmanager/installpage/btinstallmodulechooserdialog.cpp b/src/frontend/bookshelfmanager/installpage/btinstallmodulechooserdialog.cpp deleted file mode 100644 index a689c05..0000000 --- a/src/frontend/bookshelfmanager/installpage/btinstallmodulechooserdialog.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/********* -* -* 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 "frontend/bookshelfmanager/installpage/btinstallmodulechooserdialog.h" - -#include <QAction> -#include <QHeaderView> -#include <QToolButton> -#include "backend/bookshelfmodel/btbookshelffiltermodel.h" -#include "frontend/btbookshelfview.h" -#include "util/tool.h" - - -namespace { -const QString groupingOrderKey("GUI/BookshelfManager/InstallConfirmDialog/grouping"); -} - -BtInstallModuleChooserDialog::BtInstallModuleChooserDialog(const BtBookshelfTreeModel::Grouping &g, - QWidget *parent, - Qt::WindowFlags flags) - : BtModuleChooserDialog(parent, flags), m_shown(false) -{ - resize(550, 340); - - // Read grouping order from settings or the default from argument: - BtBookshelfTreeModel::Grouping groupingOrder(false); - if (!groupingOrder.loadFrom(groupingOrderKey)) { - groupingOrder = g; - } - - BtInstallModuleChooserDialogModel *treeModel; - treeModel = new BtInstallModuleChooserDialogModel(groupingOrder, this); - connect(treeModel, SIGNAL(groupingOrderChanged(BtBookshelfTreeModel::Grouping)), - this, SLOT(slotGroupingOrderChanged(const BtBookshelfTreeModel::Grouping&))); - - m_bookshelfModel = new BtBookshelfModel(this); - bookshelfWidget()->postFilterModel()->setShowShown(true); - bookshelfWidget()->setTreeModel(treeModel); - bookshelfWidget()->setSourceModel(m_bookshelfModel); - bookshelfWidget()->showHideAction()->setVisible(false); - bookshelfWidget()->showHideButton()->hide(); - bookshelfWidget()->treeView()->header()->show(); - - retranslateUi(); -} - -void BtInstallModuleChooserDialog::addModuleItem(CSwordModuleInfo *module, - const QString &sourceName) -{ - module->setProperty("installSourceName", sourceName); - m_bookshelfModel->addModule(module); -} - -void BtInstallModuleChooserDialog::retranslateUi() { - setWindowTitle(tr("Install/Update works?")); - util::tool::initExplanationLabel( - label(), QString::null, - tr("Do you really want to install these works?") + "<br/><br/><small>" + - tr("Only one version of a work can be installed at the same time. Select only " - "one if there are items marked with red.") + "</small>"); -} - -void BtInstallModuleChooserDialog::showEvent(QShowEvent *event) { - Q_UNUSED(event); - - if (m_shown) return; - bookshelfWidget()->treeView()->expandAll(); - bookshelfWidget()->treeView()->header()->resizeSections(QHeaderView::ResizeToContents); - m_shown = true; -} - -void BtInstallModuleChooserDialog::slotGroupingOrderChanged(const BtBookshelfTreeModel::Grouping &g) { - g.saveTo(groupingOrderKey); -} diff --git a/src/frontend/bookshelfmanager/installpage/btinstallmodulechooserdialog.h b/src/frontend/bookshelfmanager/installpage/btinstallmodulechooserdialog.h deleted file mode 100644 index 49f1978..0000000 --- a/src/frontend/bookshelfmanager/installpage/btinstallmodulechooserdialog.h +++ /dev/null @@ -1,55 +0,0 @@ -/********* -* -* 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 BTINSTALLMODULECHOOSERDIALOG_H -#define BTINSTALLMODULECHOOSERDIALOG_H - -#include "frontend/btmodulechooserdialog.h" - -#include "frontend/bookshelfmanager/installpage/btinstallmodulechooserdialogmodel.h" - - -class BtBookshelfModel; -class BtInstallModuleChooserDialogModel; -class CSwordModuleInfo; - -/** -* Confirmation dialog for installation. Lets the user -* uncheck modules from the list. -*/ -class BtInstallModuleChooserDialog: public BtModuleChooserDialog { - Q_OBJECT - public: - BtInstallModuleChooserDialog(const BtBookshelfTreeModel::Grouping &g, - QWidget *parent = 0, - Qt::WindowFlags flags = 0); - - inline const QSet<CSwordModuleInfo*> &checkedModules() const { - return bookshelfWidget()->treeModel()->checkedModules(); - } - - void addModuleItem(CSwordModuleInfo *module, const QString &sourceName); - - protected: - void retranslateUi(); - void showEvent(QShowEvent *event); - - protected slots: - void slotGroupingOrderChanged(const BtBookshelfTreeModel::Grouping &g); - - private: - BtBookshelfModel *m_bookshelfModel; - - bool m_shown; -}; - -#endif // BTINSTALLMODULECHOOSERDIALOG_H diff --git a/src/frontend/bookshelfmanager/installpage/btinstallmodulechooserdialogmodel.cpp b/src/frontend/bookshelfmanager/installpage/btinstallmodulechooserdialogmodel.cpp deleted file mode 100644 index 6f0fc9b..0000000 --- a/src/frontend/bookshelfmanager/installpage/btinstallmodulechooserdialogmodel.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/********* -* -* 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 "frontend/bookshelfmanager/installpage/btinstallmodulechooserdialogmodel.h" - -#include <QBrush> -#include "backend/drivers/cswordmoduleinfo.h" -#include "backend/managers/cswordbackend.h" - - -#define MODULEPOINTERFORINDEX(i) static_cast<CSwordModuleInfo *>(\ - BtBookshelfTreeModel::data((i), BtBookshelfModel::ModulePointerRole).value<void*>()) - -BtInstallModuleChooserDialogModel::BtInstallModuleChooserDialogModel( - const Grouping &grouping, - QObject *parent) - : BtBookshelfTreeModel(grouping, parent), m_dataChangedFired(false) -{ - setDefaultChecked(BtBookshelfTreeModel::CHECKED); - setCheckable(true); - connect(this, SIGNAL(dataChanged(QModelIndex,QModelIndex)), - this, SLOT(parentDataChanged(QModelIndex,QModelIndex)), - Qt::DirectConnection); -} - -QVariant BtInstallModuleChooserDialogModel::data(const QModelIndex &i, int role) const { - switch (role) { - case Qt::BackgroundRole: - if (isMulti(i)) return QBrush(Qt::red); - return BtBookshelfTreeModel::data(i, role); - case Qt::ForegroundRole: - if (isMulti(i)) return QBrush(Qt::white); - return BtBookshelfTreeModel::data(i, role); - case Qt::DisplayRole: - switch (i.column()) { - case 0: - return BtBookshelfTreeModel::data(i, role); - case 1: - { - CSwordModuleInfo *module = MODULEPOINTERFORINDEX(index(i.row(), 0, i.parent())); - if (module != 0) return module->property("installSourceName"); - break; - } - case 2: - { - CSwordModuleInfo *module = MODULEPOINTERFORINDEX(index(i.row(), 0, i.parent())); - if (module == 0) break; - CSwordBackend *b = CSwordBackend::instance(); - CSwordModuleInfo *imodule = b->findModuleByName(module->name()); - if (imodule == 0) { - return module->config(CSwordModuleInfo::ModuleVersion); - } else { - return imodule->config(CSwordModuleInfo::ModuleVersion) - + " => " - + module->config(CSwordModuleInfo::ModuleVersion); - } - } - default: break; - } - default: - if (i.column() == 0) return BtBookshelfTreeModel::data(i, role); - } - - return QVariant(); -} - -int BtInstallModuleChooserDialogModel::columnCount(const QModelIndex &parent) const { - Q_UNUSED(parent); - - return 3; -} - -QVariant BtInstallModuleChooserDialogModel::headerData(int section, - Qt::Orientation orientation, - int role) const -{ - if (role == Qt::DisplayRole && orientation == Qt::Horizontal) { - switch (section) { - case 0: return tr("Work"); - case 1: return tr("Installation source"); - case 2: return tr("Version"); - default: break; - } - } - - return QVariant(); -} - -void BtInstallModuleChooserDialogModel::parentDataChanged(const QModelIndex &topLeft, - const QModelIndex &bottomRight) -{ - Q_UNUSED(topLeft); - Q_UNUSED(bottomRight); - - if (m_dataChangedFired) return; - m_dataChangedFired = true; - resetData(); - m_dataChangedFired = false; -} - -bool BtInstallModuleChooserDialogModel::isMulti(CSwordModuleInfo * m1) const { - if (m1 != 0 && checkedModules().contains(m1)) - Q_FOREACH (CSwordModuleInfo * m2, modules()) - if (m1 != m2 && checkedModules().contains(m2) && m1->name() == m2->name()) - return true; - return false; -} - -bool BtInstallModuleChooserDialogModel::isMulti(const QModelIndex &i) const { - if (!i.isValid()) return false; - - if (!hasChildren(i)) { - return isMulti(MODULEPOINTERFORINDEX(index(i.row(), 0, i.parent()))); - } else { - for (int row = 0; row < rowCount(i); row++) { - if (isMulti(i.child(row, 0))) return true; - } - } - return false; -} diff --git a/src/frontend/bookshelfmanager/installpage/btinstallmodulechooserdialogmodel.h b/src/frontend/bookshelfmanager/installpage/btinstallmodulechooserdialogmodel.h deleted file mode 100644 index 406b89c..0000000 --- a/src/frontend/bookshelfmanager/installpage/btinstallmodulechooserdialogmodel.h +++ /dev/null @@ -1,43 +0,0 @@ -/********* -* -* 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 BTINSTALLMODULECHOOSERDIALOGMODEL_H -#define BTINSTALLMODULECHOOSERDIALOGMODEL_H - -#include "backend/bookshelfmodel/btbookshelftreemodel.h" - -#include <QMap> - - -class BtInstallModuleChooserDialogModel: public BtBookshelfTreeModel { - Q_OBJECT - public: - BtInstallModuleChooserDialogModel(const Grouping &grouping, QObject *parent = 0); - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - QVariant headerData(int section, Qt::Orientation orientation, - int role = Qt::DisplayRole) const; - - private slots: - void parentDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); - - private: - bool isMulti(CSwordModuleInfo *module) const; - bool isMulti(const QModelIndex &index) const; - - private: - QMap<QString, int> m_nameCounts; - bool m_dataChangedFired; -}; - -#endif // BTINSTALLMODULECHOOSERDIALOGMODEL_H diff --git a/src/frontend/bookshelfmanager/installpage/btinstallpage.cpp b/src/frontend/bookshelfmanager/installpage/btinstallpage.cpp deleted file mode 100644 index 5f8bfb8..0000000 --- a/src/frontend/bookshelfmanager/installpage/btinstallpage.cpp +++ /dev/null @@ -1,447 +0,0 @@ -/********* -* -* 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 "frontend/bookshelfmanager/installpage/btinstallpage.h" - -#include <QApplication> -#include <QComboBox> -#include <QGroupBox> -#include <QHBoxLayout> -#include <QHeaderView> -#include <QLabel> -#include <QPushButton> -#include <QSharedPointer> -#include <QStackedLayout> -#include <QToolButton> -#include "backend/config/btconfig.h" -#include "backend/btinstallbackend.h" -#include "bibletimeapp.h" -#include "frontend/bookshelfmanager/btmodulemanagerdialog.h" -#include "frontend/bookshelfmanager/cswordsetupinstallsourcesdialog.h" -#include "frontend/bookshelfmanager/installpage/btinstallmodulechooserdialog.h" -#include "frontend/bookshelfmanager/installpage/btinstallpageworkswidget.h" -#include "frontend/bookshelfmanager/installpage/btinstallpathdialog.h" -#include "frontend/bookshelfmanager/installpage/btinstallprogressdialog.h" -#include "frontend/btbookshelfview.h" -#include "frontend/messagedialog.h" -#include "util/cresmgr.h" -#include "util/directory.h" -#include "util/geticon.h" -#include "util/tool.h" - - -namespace { -const QString groupingOrderKey ("GUI/BookshelfManager/InstallPage/grouping"); -const QString headerStateKey ("GUI/BookshelfManager/InstallPage/headerState"); -const QString selectedModuleKey("GUI/BookshelfManager/InstallPage/selectedModule"); -const QString installPathKey ("GUI/BookshelfManager/InstallPage/installPathIndex"); -} // anonymous namespace - - -// ********************************************************* -// *********** Config dialog page: Install/Update ********** -// ********************************************************* - -BtInstallPage::BtInstallPage(BtModuleManagerDialog *parent) - : BtConfigDialog::Page(util::getIcon(CResMgr::bookshelfmgr::installpage::icon), parent) - , m_groupingOrder(groupingOrderKey) - , m_modulesSelected(0) - , m_modulesSelectedSources(0) -{ - // Read settings: - m_headerState = btConfig().value<QByteArray>(headerStateKey, QByteArray()); - - // Initialize widgets: - initView(); - initConnections(); - - retranslateUi(); -} - -void BtInstallPage::setInstallEnabled(bool b) { - m_installButton->setEnabled(b); -} - -QString BtInstallPage::selectedInstallPath() { - return m_pathCombo->currentText(); -} - -void BtInstallPage::initView() { - // Warning label: - m_warningLabel = new QLabel(this); - - // Source chooser: - m_sourceGroupBox = new QGroupBox(this); - m_sourceGroupBox->setFlat(true); - - m_sourceComboBox = new QComboBox(this); - m_sourceComboBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); - initSourcesCombo(); - - m_sourceAddButton = new QPushButton(this); - m_sourceAddButton->setIcon(util::getIcon(CResMgr::bookshelfmgr::installpage::add_icon)); - - m_sourceDeleteButton = new QPushButton(this); - m_sourceDeleteButton->setIcon(util::getIcon(CResMgr::bookshelfmgr::installpage::delete_icon)); - - QHBoxLayout *sourceChooserLayout = new QHBoxLayout(); - sourceChooserLayout->setContentsMargins(0, 8, 0, 0); - sourceChooserLayout->addWidget(m_sourceComboBox, 1); - sourceChooserLayout->addWidget(m_sourceAddButton); - sourceChooserLayout->addWidget(m_sourceDeleteButton); - m_sourceGroupBox->setLayout(sourceChooserLayout); - - // Works chooser: - m_worksGroupBox = new QGroupBox(this); - m_worksGroupBox->setFlat(true); - m_worksLayout = new QStackedLayout(); - m_worksGroupBox->setLayout(m_worksLayout); - slotSourceIndexChanged(m_sourceComboBox->currentIndex()); - - // Installation path chooser: - m_installGroupBox = new QGroupBox(this); - m_installGroupBox->setFlat(true); - retranslateInstallGroupBox(); - - m_pathLabel = new QLabel(this); - m_pathCombo = new QComboBox(this); - m_pathCombo->setMinimumContentsLength(20); - m_pathCombo->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon); - m_pathCombo->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); - m_pathCombo->view()->setTextElideMode(Qt::ElideMiddle); - m_pathLabel->setBuddy(m_pathCombo); - initPathCombo(); - - m_configurePathButton = new QToolButton(this); - m_configurePathButton->setIcon(util::getIcon(CResMgr::bookshelfmgr::installpage::path_icon)); - - m_installButton = new QPushButton(this); - m_installButton->setIcon(util::getIcon(CResMgr::bookshelfmgr::installpage::install_icon)); - m_installButton->setEnabled(false); - - QHBoxLayout *pathLayout = new QHBoxLayout(); - pathLayout->setContentsMargins(0, 8, 0, 0); - pathLayout->addWidget(m_pathLabel); - pathLayout->addWidget(m_pathCombo); - pathLayout->addWidget(m_configurePathButton); - pathLayout->addWidget(m_installButton); - m_installGroupBox->setLayout(pathLayout); - - QVBoxLayout *mainLayout = new QVBoxLayout(this); - mainLayout->addWidget(m_warningLabel); - mainLayout->addWidget(m_sourceGroupBox); - mainLayout->addWidget(m_worksGroupBox, 1); - mainLayout->addWidget(m_installGroupBox); -} - -void BtInstallPage::initConnections() { - connect(m_sourceComboBox, SIGNAL(currentIndexChanged(int)), - this, SLOT(slotSourceIndexChanged(int))); - connect(m_sourceAddButton, SIGNAL(clicked()), - this, SLOT(slotSourceAdd())); - connect(m_sourceDeleteButton, SIGNAL(clicked()), - this, SLOT(slotSourceDelete())); - connect(m_installButton, SIGNAL(clicked()), - this, SLOT(slotInstall())); - connect(m_pathCombo, SIGNAL(activated(const QString&)), - this , SLOT(slotPathChanged(const QString&))); - connect(m_configurePathButton, SIGNAL(clicked()), - this, SLOT(slotEditPaths())); - connect(CSwordBackend::instance(), - SIGNAL(sigSwordSetupChanged(CSwordBackend::SetupChangedReason)), - this, SLOT(slotSwordSetupChanged())); -} - -void BtInstallPage::initPathCombo() { - //populate the combo list - m_pathCombo->clear(); - - QStringList targets = BtInstallBackend::targetList(); - for (QStringList::iterator it = targets.begin(); it != targets.end(); ++it) { - // Add the path only if it's writable - if ((*it).isEmpty()) continue; - QDir dir(*it); - if (!dir.exists()) continue; - if (!dir.isReadable()) continue; - QFileInfo fi( dir.canonicalPath()); - if (!fi.isWritable()) continue; - m_pathCombo->addItem(util::directory::convertDirSeparators(*it)); - } - - // choose the current value from config but check whether we have so many items - int configValue = btConfig().value<int>(installPathKey, 0); - int index = configValue > (m_pathCombo->count() - 1) ? m_pathCombo->count() - 1 : configValue; - m_pathCombo->setCurrentIndex(index); -} - -void BtInstallPage::initSourcesCombo() { - /// \todo Implement a proper model for this - - m_sourceComboBox->clear(); - QStringList sourceList = BtInstallBackend::sourceNameList(); - - // Add a default entry, the Crosswire main repository - if (sourceList.empty()) { - /// \todo Open a dialog which asks whether to get list from server and add sources - sword::InstallSource is("FTP"); //default return value - is.caption = "CrossWire Bible Society"; - is.source = "ftp.crosswire.org"; - is.directory = "/pub/sword/raw"; - // passive ftp is not needed here, it's the default - - BtInstallBackend::addSource(is); - - sourceList = BtInstallBackend::sourceNameList(); - Q_ASSERT(!sourceList.empty()); - } - - // Read selected module from config: - const QString selected = btConfig().value<QString>(selectedModuleKey, QString()); - - // Populate combo box - bool selectionOk = false; - for (int i = 0; i < sourceList.size(); i++) { - m_sourceComboBox->addItem(sourceList.at(i)); - - // Select configured item: - if (!selectionOk && sourceList.at(i) == selected) { - m_sourceComboBox->setCurrentIndex(i); - selectionOk = true; - } - } - - // Set selection, if it wasn't properly configured: - if (!selectionOk) { - m_sourceComboBox->setCurrentIndex(0); - btConfig().setValue(selectedModuleKey, sourceList.at(0)); - } -} - -void BtInstallPage::activateSource(const sword::InstallSource &src) { - qApp->setOverrideCursor(Qt::WaitCursor); - BtInstallPageWorksWidget *w = m_sourceMap.value(QString(src.caption), 0); - if (w == 0) { - window()->setEnabled(false); - qApp->processEvents(); - w = new BtInstallPageWorksWidget(src, m_groupingOrder, this); - m_sourceMap.insert(QString(src.caption), w); - m_worksLayout->addWidget(w); - connect(w->treeModel(), SIGNAL(groupingOrderChanged(BtBookshelfTreeModel::Grouping)), - this, SLOT(slotGroupingOrderChanged(const BtBookshelfTreeModel::Grouping&))); - connect(w->treeModel(), SIGNAL(moduleChecked(CSwordModuleInfo*,bool)), - this, SLOT(slotSelectedModulesChanged())); - window()->setEnabled(true); - } else { - disconnect(w->treeView()->header(), SIGNAL(geometriesChanged()), - this, SLOT(slotHeaderChanged())); - } - m_worksLayout->setCurrentWidget(w); - w->treeModel()->setGroupingOrder(m_groupingOrder); - w->treeView()->header()->restoreState(m_headerState); - connect(w->treeView()->header(), SIGNAL(geometriesChanged()), - this, SLOT(slotHeaderChanged())); - qApp->restoreOverrideCursor(); -} - -void BtInstallPage::retranslateInstallGroupBox() { - if (m_modulesSelected > 0) { - m_installGroupBox->setTitle(tr("Start installation of %1 works from %2 sources:") - .arg(m_modulesSelected) - .arg(m_modulesSelectedSources)); - } else { - m_installGroupBox->setTitle(tr("Start installation:")); - } -} - -void BtInstallPage::retranslateUi() { - setHeaderText(tr("Install/Update")); - - util::tool::initExplanationLabel(m_warningLabel, tr("WARNING!!!"), - tr("If you live in a persecuted country and don't want to risk " - "detection don't use remote sources.")); - - m_sourceGroupBox->setTitle(tr("Select installation &source:")); - m_sourceAddButton->setText(tr("&Add...")); - m_sourceAddButton->setToolTip(tr("Add new source")); - m_sourceDeleteButton->setText(tr("&Delete...")); - m_sourceDeleteButton->setToolTip(tr("Delete this source")); - - m_worksGroupBox->setTitle(tr("Select &works to install:")); - - m_pathLabel->setText(tr("Install &folder:")); - m_pathCombo->setToolTip(tr("The folder where the new works will be installed")); - m_configurePathButton->setToolTip(tr("Configure folders where works are installed and found")); - m_installButton->setText(tr("&Install...")); - m_installButton->setToolTip(tr("Install or update selected works")); - - retranslateInstallGroupBox(); -} - -void BtInstallPage::slotGroupingOrderChanged(const BtBookshelfTreeModel::Grouping &g) { - m_groupingOrder = g; - m_groupingOrder.saveTo(groupingOrderKey); -} - -void BtInstallPage::slotHeaderChanged() { - typedef BtInstallPageWorksWidget IPWW; - Q_ASSERT(qobject_cast<IPWW*>(m_worksLayout->currentWidget()) != 0); - IPWW *w = static_cast<IPWW*>(m_worksLayout->currentWidget()); - m_headerState = w->treeView()->header()->saveState(); - btConfig().setValue(headerStateKey, m_headerState); -} - -void BtInstallPage::slotInstall() { - // check that the destination path is writable, do nothing if not and user doesn't want to continue - QDir dir = selectedInstallPath(); - bool canWrite = true; - if (dir.isReadable()) { - const QFileInfo fi( dir.canonicalPath() ); - if (!fi.exists() || !fi.isWritable()) { - canWrite = false; - } - } - else { - canWrite = false; - } - if (!canWrite) { - const int result = message::showWarning(this, tr("Warning"), tr("The destination directory is not writable or does not exist. Installation will fail unless this has first been fixed."), QMessageBox::Ignore | QMessageBox::Cancel, QMessageBox::Cancel); - if (result != QMessageBox::Ignore) { - return; - } - } - - // create the confirmation dialog - BtInstallModuleChooserDialog *dlg = new BtInstallModuleChooserDialog(m_groupingOrder, this); - - // Add all checked modules from all tabs: - Q_FOREACH (BtInstallPageWorksWidget *w, m_sourceMap.values()) { - Q_FOREACH (CSwordModuleInfo *module, w->treeModel()->checkedModules()) { - dlg->addModuleItem(module, QString(w->installSource().caption)); - } - } - - if (dlg->exec() == QDialog::Accepted) { - QList<CSwordModuleInfo *> modules(dlg->checkedModules().toList()); - if (modules.empty()) - return; - - /// \todo first remove all modules which will be updated from the module list - // but what modules? all with the same real name? (there may be _n modules...) - - // progressDialog is WA_DeleteOnClose - typedef BtInstallProgressDialog BIPD; - BIPD * const progressDialog = new BIPD(modules, selectedInstallPath(), this); - m_installButton->setEnabled(false); - // the progress dialog is now modal, it can be made modeless later. - progressDialog->exec(); - - } - delete dlg; -} - -void BtInstallPage::slotPathChanged(const QString& /*pathText*/) { - btConfig().setValue(installPathKey, m_pathCombo->currentIndex()); -} - -void BtInstallPage::slotEditPaths() { - BtInstallPathDialog* dlg = new BtInstallPathDialog(); - int result = dlg->exec(); - if (result == QDialog::Accepted) { - //dynamic_cast<BtModuleManagerDialog*>(parentDialog())->slotSwordSetupChanged(); - CSwordBackend::instance()->reloadModules(CSwordBackend::PathChanged); - } -} - -void BtInstallPage::slotSourceAdd() { - typedef CSwordSetupInstallSourcesDialog SSISD; - - QSharedPointer<SSISD> dlg(new SSISD()); - if (dlg->exec() == QDialog::Accepted) { - if (dlg->wasRemoteListAdded()) { - initSourcesCombo(); - } - else { - sword::InstallSource newSource = dlg->getSource(); - if ( !((QString)newSource.type.c_str()).isEmpty() ) { // we have a valid source to add - BtInstallBackend::addSource(newSource); - } - initSourcesCombo(); - for (int i = 0; i < m_sourceComboBox->count(); i++) { - if (m_sourceComboBox->itemText(i) == newSource.caption) { - m_sourceComboBox->setCurrentIndex(i); - break; - } - } - } - } -} - -void BtInstallPage::slotSourceDelete() { - typedef BtInstallPageWorksWidget IPWW; - - int ret = message::showWarning(this, tr("Delete Source?"), - tr("Do you really want to delete this source?"), - QMessageBox::Yes | QMessageBox::No); - - if (ret == QMessageBox::Yes) { - qApp->setOverrideCursor(Qt::WaitCursor); - window()->setEnabled(false); - Q_ASSERT(qobject_cast<IPWW*>(m_worksLayout->currentWidget())); - IPWW *w = static_cast<IPWW*>(m_worksLayout->currentWidget()); - m_sourceMap.remove(QString(w->installSource().caption)); - w->deleteSource(); - initSourcesCombo(); - slotSourceIndexChanged(m_sourceComboBox->currentIndex()); - delete w; - window()->setEnabled(true); - qApp->restoreOverrideCursor(); - } -} - -void BtInstallPage::slotSourceIndexChanged(int index) { - if (index < 0) { - if(!m_sourceComboBox->count()) - return; - index = 0; - } - - /// \todo use pointers instead of text - QString moduleName = m_sourceComboBox->itemText(index); - btConfig().setValue(selectedModuleKey, moduleName); - activateSource(BtInstallBackend::source(moduleName)); -} - -void BtInstallPage::slotSelectedModulesChanged() { - m_modulesSelected = 0; - m_modulesSelectedSources = 0; - Q_FOREACH (BtInstallPageWorksWidget *w, m_sourceMap.values()) { - int selected = w->treeModel()->checkedModules().size(); - if (selected > 0) { - m_modulesSelectedSources++; - m_modulesSelected += selected; - } - } - - m_installButton->setEnabled(m_modulesSelected > 0); - retranslateInstallGroupBox(); -} - -void BtInstallPage::slotSwordSetupChanged() { - QString moduleName = m_sourceComboBox->currentText(); - - // clean m_sourceMap before initSourcesCombo() make too much work - qDeleteAll(m_sourceMap.values()); - m_sourceMap.clear(); - initSourcesCombo(); - m_sourceComboBox->setCurrentIndex(m_sourceComboBox->findText(moduleName)); - initPathCombo(); - m_modulesSelected = 0; - m_modulesSelectedSources = 0; - retranslateInstallGroupBox(); -} diff --git a/src/frontend/bookshelfmanager/installpage/btinstallpage.h b/src/frontend/bookshelfmanager/installpage/btinstallpage.h deleted file mode 100644 index fe791cf..0000000 --- a/src/frontend/bookshelfmanager/installpage/btinstallpage.h +++ /dev/null @@ -1,101 +0,0 @@ -/********* -* -* 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 BTINSTALLPAGE_H -#define BTINSTALLPAGE_H - -#include "frontend/bookshelfmanager/btconfigdialog.h" - -#include "backend/bookshelfmodel/btbookshelftreemodel.h" - - -namespace sword { -class InstallSource; -} - -class BtInstallPageWorksWidget; -class BtModuleManagerDialog; -class QComboBox; -class QGroupBox; -class QLabel; -class QPushButton; -class QStackedLayout; -class QToolButton; - -/** -* The Install page includes module path chooser, source/module handler and install button. -*/ -class BtInstallPage: public BtConfigDialog::Page { - - Q_OBJECT - - public: - - BtInstallPage(BtModuleManagerDialog *parent = 0); - - void setInstallEnabled(bool b); - - QString selectedInstallPath(); - - public slots: - void slotSwordSetupChanged(); - - protected: - - void retranslateUi(); - - private: - void initView(); - void initConnections(); - void initPathCombo(); - void initSourcesCombo(); - - void activateSource(const sword::InstallSource &src); - void retranslateInstallGroupBox(); - - private slots: - void slotGroupingOrderChanged(const BtBookshelfTreeModel::Grouping &g); - void slotHeaderChanged(); - void slotInstall(); - void slotPathChanged(const QString& pathText); - void slotEditPaths(); - void slotSourceAdd(); - void slotSourceDelete(); - void slotSourceIndexChanged(int index); - void slotSelectedModulesChanged(); - - private: - BtBookshelfTreeModel::Grouping m_groupingOrder; - QByteArray m_headerState; - - QMap<QString, BtInstallPageWorksWidget*> m_sourceMap; - - QLabel *m_warningLabel; - - QGroupBox *m_sourceGroupBox; - QComboBox *m_sourceComboBox; - QPushButton *m_sourceAddButton; - QPushButton *m_sourceDeleteButton; - - QGroupBox *m_worksGroupBox; - QStackedLayout *m_worksLayout; - - QGroupBox *m_installGroupBox; - QLabel *m_pathLabel; - QComboBox *m_pathCombo; - QToolButton *m_configurePathButton; - QPushButton *m_installButton; - - unsigned m_modulesSelected; - unsigned m_modulesSelectedSources; -}; - -#endif diff --git a/src/frontend/bookshelfmanager/installpage/btinstallpagemodel.cpp b/src/frontend/bookshelfmanager/installpage/btinstallpagemodel.cpp deleted file mode 100644 index 06e97f8..0000000 --- a/src/frontend/bookshelfmanager/installpage/btinstallpagemodel.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/********* -* -* 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 "frontend/bookshelfmanager/installpage/btinstallpagemodel.h" - - -#include "backend/drivers/cswordmoduleinfo.h" -#include "backend/managers/cswordbackend.h" - - -#define MODULEPOINTERFORINDEX(i) static_cast<CSwordModuleInfo *>(\ - BtBookshelfTreeModel::data((i), BtBookshelfModel::ModulePointerRole).value<void*>()) - -BtInstallPageModel::BtInstallPageModel(const Grouping &grouping, QObject *parent) - : BtBookshelfTreeModel(grouping, parent) -{ - setDefaultChecked(BtBookshelfTreeModel::UNCHECKED); - setCheckable(true); -} - -QVariant BtInstallPageModel::data(const QModelIndex &i, int role) const { - switch (role) { - case Qt::DisplayRole: - switch (i.column()) { - case 0: - return BtBookshelfTreeModel::data(i, role); - case 1: - { - CSwordModuleInfo *module = MODULEPOINTERFORINDEX(index(i.row(), 0, i.parent())); - if (module == 0) break; - CSwordBackend *b = CSwordBackend::instance(); - CSwordModuleInfo *imodule = b->findModuleByName(module->name()); - if (imodule == 0) { - return module->config(CSwordModuleInfo::ModuleVersion); - } else { - return imodule->config(CSwordModuleInfo::ModuleVersion) - + " => " - + module->config(CSwordModuleInfo::ModuleVersion); - } - } - case 2: - { - CSwordModuleInfo *module = MODULEPOINTERFORINDEX(index(i.row(), 0, i.parent())); - if (module != 0) return module->config(CSwordModuleInfo::Description); - } - default: break; - } - default: - if (i.column() == 0) return BtBookshelfTreeModel::data(i, role); - } - - return QVariant(); -} - -int BtInstallPageModel::columnCount(const QModelIndex &parent) const { - Q_UNUSED(parent); - - return 3; -} - -QVariant BtInstallPageModel::headerData(int section, Qt::Orientation orientation, - int role) const -{ - if (role == Qt::DisplayRole && orientation == Qt::Horizontal) { - switch (section) { - case 0: return tr("Work"); - case 1: return tr("Version"); - case 2: return tr("Description"); - default: break; - } - } - - return QVariant(); -} diff --git a/src/frontend/bookshelfmanager/installpage/btinstallpagemodel.h b/src/frontend/bookshelfmanager/installpage/btinstallpagemodel.h deleted file mode 100644 index 009aa15..0000000 --- a/src/frontend/bookshelfmanager/installpage/btinstallpagemodel.h +++ /dev/null @@ -1,32 +0,0 @@ -/********* -* -* 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 BTINSTALLPAGEMODEL_H -#define BTINSTALLPAGEMODEL_H - -#include "backend/bookshelfmodel/btbookshelftreemodel.h" - -#include <QMap> - - -class BtInstallPageModel: public BtBookshelfTreeModel { - Q_OBJECT - public: - BtInstallPageModel(const Grouping &grouping, QObject *parent = 0); - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - QVariant headerData(int section, Qt::Orientation orientation, - int role = Qt::DisplayRole) const; -}; - -#endif // BTINSTALLPAGEMODEL_H diff --git a/src/frontend/bookshelfmanager/installpage/btinstallpageworkswidget.cpp b/src/frontend/bookshelfmanager/installpage/btinstallpageworkswidget.cpp deleted file mode 100644 index 629a69c..0000000 --- a/src/frontend/bookshelfmanager/installpage/btinstallpageworkswidget.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/********* -* -* 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 "frontend/bookshelfmanager/installpage/btinstallpageworkswidget.h" - -#include <QApplication> -#include <QAction> -#include <QDebug> -#include <QTimer> -#include <QToolButton> -#include "backend/btinstallbackend.h" -#include "backend/managers/cswordbackend.h" -#include "bibletimeapp.h" -#include "frontend/bookshelfmanager/installpage/btinstallpage.h" -#include "frontend/bookshelfmanager/installpage/btinstallpagemodel.h" -#include "frontend/bookshelfmanager/installpage/btrefreshprogressdialog.h" -#include "frontend/btbookshelfview.h" -#include "util/cresmgr.h" -#include "util/geticon.h" - - -namespace { - -/** Filters out already installed modules which can't be updated right now. */ -bool filter(CSwordModuleInfo *mInfo) { - typedef CSwordModuleInfo CSMI; - typedef sword::SWVersion SV; - - const CSMI *installedModule = CSwordBackend::instance()->findModuleByName(mInfo->name()); - if (installedModule) { - // Already installed, check if it's an update: - const SV curVersion(installedModule->config(CSMI::ModuleVersion).toLatin1()); - const SV newVersion(mInfo->config(CSMI::ModuleVersion).toLatin1()); - if (curVersion >= newVersion) { - return false; - } - } - return true; -} - -} - -BtInstallPageWorksWidget::BtInstallPageWorksWidget( - const sword::InstallSource &source, - const BtBookshelfTreeModel::Grouping &g, - BtInstallPage *parent, Qt::WindowFlags flags) - : BtBookshelfWidget(parent, flags) - , m_source(source) - , m_parent(parent) - , m_backend(0) - , m_myModel(0) -{ - - setTreeModel(new BtInstallPageModel(g, this)); - - treeView()->setHeaderHidden(false); - showHideButton()->hide(); - showHideAction()->setVisible(false); - - m_sourceRefreshButton = new QToolButton(this); - m_sourceRefreshButton->setAutoRaise(true); - m_sourceRefreshButton->setToolTip(tr("Refresh the list of works from this source")); - m_sourceRefreshButton->setIcon(util::getIcon(CResMgr::bookshelfmgr::installpage::refresh_icon)); - setRightCornerWidget(m_sourceRefreshButton); - - connect(m_sourceRefreshButton, SIGNAL(clicked()), - this, SLOT(slotSourceRefresh())); - - m_backend = BtInstallBackend::backend(m_source); - Q_ASSERT(m_backend != 0); - m_myModel = new BtBookshelfModel(this); - Q_FOREACH(CSwordModuleInfo *module, m_backend->moduleList()) { - if (filter(module)) m_myModel->addModule(module); - } - setSourceModel(m_myModel); -} - -BtInstallPageWorksWidget::~BtInstallPageWorksWidget() { - delete m_backend; -} - -void BtInstallPageWorksWidget::deleteSource() { - qDebug() << "Deleting source" << m_source.caption; - - m_myModel->clear(); - BtInstallBackend::deleteSource(QString(m_source.caption)); -} - -void BtInstallPageWorksWidget::updateTree() { - qDebug() << "Updating BtInstallPageWorksWidget tree for source" << m_source.caption; - - m_myModel->clear(); - - // Is this necessary? - m_source = BtInstallBackend::source(QString(m_source.caption)); - m_backend = BtInstallBackend::backend(m_source); - - // Repopulate model: - Q_FOREACH(CSwordModuleInfo *module, m_backend->moduleList()) { - if (filter(module)) m_myModel->addModule(module); - } -} - -void BtInstallPageWorksWidget::slotSourceRefresh() { - qDebug() << "Refreshing source" << m_source.caption; - - if (BtInstallBackend::isRemote(m_source)) { - BtRefreshProgressDialog d(m_source, this); - if (!d.runAndDelete()) return; - } - updateTree(); -} diff --git a/src/frontend/bookshelfmanager/installpage/btinstallpageworkswidget.h b/src/frontend/bookshelfmanager/installpage/btinstallpageworkswidget.h deleted file mode 100644 index d02e99e..0000000 --- a/src/frontend/bookshelfmanager/installpage/btinstallpageworkswidget.h +++ /dev/null @@ -1,57 +0,0 @@ -/********* -* -* 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 BTINSTALLPAGEWORKSWIDGET_H -#define BTINSTALLPAGEWORKSWIDGET_H - - -#include "frontend/btbookshelfwidget.h" - -// Sword includes -#include <installmgr.h> - - -class BtInstallPage; - -class BtInstallPageWorksWidget: public BtBookshelfWidget { - Q_OBJECT - - public: /* Methods: */ - - BtInstallPageWorksWidget(const sword::InstallSource &source, - const BtBookshelfTreeModel::Grouping &g, - BtInstallPage *parent, Qt::WindowFlags f = 0); - - ~BtInstallPageWorksWidget(); - - inline const sword::InstallSource &installSource() const { - return m_source; - } - void deleteSource(); - - private: /* Methods: */ - - void updateTree(); - - private slots: - - void slotSourceRefresh(); - - private: /* Fields: */ - - sword::InstallSource m_source; - BtInstallPage *m_parent; - QToolButton *m_sourceRefreshButton; - CSwordBackend *m_backend; - BtBookshelfModel *m_myModel; -}; - -#endif // BTINSTALLPAGEWORKSWIDGET_H diff --git a/src/frontend/bookshelfmanager/installpage/btinstallpathdialog.cpp b/src/frontend/bookshelfmanager/installpage/btinstallpathdialog.cpp deleted file mode 100644 index 109bbd9..0000000 --- a/src/frontend/bookshelfmanager/installpage/btinstallpathdialog.cpp +++ /dev/null @@ -1,236 +0,0 @@ -/********* -* -* 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 "frontend/bookshelfmanager/installpage/btinstallpathdialog.h" - -#include <QDebug> -#include <QDialog> -#include <QDialogButtonBox> -#include <QDir> -#include <QFileDialog> -#include <QGridLayout> -#include <QLabel> -#include <QPushButton> -#include <QString> -#include <QTreeWidget> -#include <QTreeWidgetItem> -#include "backend/btinstallbackend.h" -#include "bibletimeapp.h" -#include "frontend/messagedialog.h" -#include "util/directory.h" -#include "util/cresmgr.h" -#include "util/geticon.h" -#include "util/tool.h" - - -BtInstallPathDialog::BtInstallPathDialog() { - namespace DU = util::directory; - - setWindowTitle(tr("Bookshelf Folders")); - - QVBoxLayout *mainLayout; - QHBoxLayout *viewLayout; - - mainLayout = new QVBoxLayout(this); - viewLayout = new QHBoxLayout(); - - QString l1 = tr("Works can be installed in one or more folders. After setting up folders here you can choose one of them in Install page."); - /// \bug The following string has an extra space character: - QString l2 = tr("BibleTime and the SWORD library find the works from all of these folders. If a folder is removed here it still exists in the system with all the works in it."); - - QLabel* mainLabel = util::tool::explanationLabel(this, - tr("Configure bookshelf folders"), l1 + QString("<small><br/><br/>") + l2 + QString("</small>")); - mainLayout->addWidget(mainLabel); - - QString swordConfPath = BtInstallBackend::swordConfigFilename(); - /// \todo After releasing 2.4, change the following line to: QLabel *confPathLabel = new QLabel(tr("Configuration file for the folders is: <b>%1</b>").arg(swordConfPath), this); - QLabel* confPathLabel = new QLabel(tr("Configuration file for the folders is: ").append("<b>%1</b>").arg(swordConfPath), this); - confPathLabel->setWordWrap(true); - mainLayout->addWidget(confPathLabel); - - - m_swordPathListBox = new QTreeWidget(this); - m_swordPathListBox->setHeaderHidden(true); - - QString rwfolderitem(tr("Folders where new works can be installed")); - m_writableItem = new QTreeWidgetItem(m_swordPathListBox, QStringList(rwfolderitem));; - m_writableItem->setFlags(Qt::ItemIsEnabled); - m_readableItem = new QTreeWidgetItem(m_swordPathListBox, QStringList(tr("Read-only folders")));; - m_readableItem->setFlags(Qt::ItemIsEnabled); - m_nonexistingItem = new QTreeWidgetItem(m_swordPathListBox, QStringList(tr("Nonexistent folders")));; - m_nonexistingItem->setFlags(Qt::ItemIsEnabled); - - QStringList targets = BtInstallBackend::targetList(); - - foreach (QString pathname, targets) { - addPathToList(pathname); - } - updateTopLevelItems(); - - viewLayout->addWidget(m_swordPathListBox); - - QVBoxLayout* buttonLayout = new QVBoxLayout(); - - m_addButton = new QPushButton(tr("&Add..."), this); - m_addButton->setToolTip(tr("Add new folder")); - m_addButton->setIcon(util::getIcon(CResMgr::bookshelfmgr::paths::add_icon)); - connect(m_addButton, SIGNAL(clicked()), this, SLOT(slotAddClicked())); - buttonLayout->addWidget(m_addButton); - - m_editButton = new QPushButton(tr("&Edit..."), this); - m_editButton->setToolTip(tr("Edit the selected folder")); - m_editButton->setIcon(util::getIcon(CResMgr::bookshelfmgr::paths::edit_icon)); - connect(m_editButton, SIGNAL(clicked()), this, SLOT(slotEditClicked())); - buttonLayout->addWidget(m_editButton); - - m_removeButton = new QPushButton(tr("&Remove"), this); - m_removeButton->setToolTip(tr("Remove the selected folder")); - m_removeButton->setIcon(util::getIcon(CResMgr::bookshelfmgr::paths::remove_icon)); - connect(m_removeButton, SIGNAL(clicked()), this, SLOT(slotRemoveClicked())); - buttonLayout->addWidget(m_removeButton); - - QSpacerItem* spacerItem = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding); - buttonLayout->addItem(spacerItem); - - viewLayout->addLayout(buttonLayout); - mainLayout->addLayout(viewLayout); - - QDialogButtonBox* buttonBox = new QDialogButtonBox(this); - buttonBox->setOrientation(Qt::Horizontal); - buttonBox->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::NoButton | QDialogButtonBox::Ok); - message::prepareDialogBox(buttonBox); - mainLayout->addWidget(buttonBox); - connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); - connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); - //clumsy way to set width. Could someone please fix Qt to have an easy way to set widget sizes? - int textWidth = fontMetrics().width(rwfolderitem.append("MMMMMMMMMM")); - int buttonWidth = m_addButton->width(); - resize(textWidth + buttonWidth, size().height()); -} - -BtInstallPathDialog::~BtInstallPathDialog() { - m_swordPathListBox->invisibleRootItem()->takeChildren(); - delete m_readableItem; - delete m_writableItem; - delete m_nonexistingItem; -} - -void BtInstallPathDialog::updateTopLevelItems() { - if (m_writableItem->childCount()) { - m_writableItem->setHidden(false); - m_swordPathListBox->expandItem(m_writableItem); - } - else { - m_writableItem->setHidden(true); - } - if (m_readableItem->childCount()) { - m_readableItem->setHidden(false); - m_swordPathListBox->expandItem(m_readableItem); - } - else { - m_readableItem->setHidden(true); - } - if (m_nonexistingItem->childCount()) { - m_nonexistingItem->setHidden(false); - m_swordPathListBox->expandItem(m_nonexistingItem); - } - else { - m_nonexistingItem->setHidden(true); - } -} - - -void BtInstallPathDialog::addPathToList(QString pathname) { - if (pathname.isEmpty()) return; - QTreeWidgetItem* i = 0; - QDir dir(pathname); - if (!dir.exists()) { - i = new QTreeWidgetItem(m_nonexistingItem, QStringList(pathname) ); - } - else if (dir.isReadable()) { - const QFileInfo fi( dir.canonicalPath() ); - if (fi.isWritable()) { - i = new QTreeWidgetItem(m_writableItem, QStringList(pathname) ); - } - else { - i = new QTreeWidgetItem(m_readableItem, QStringList(pathname) ); - } - } - if (i && QDir(pathname) == BtInstallBackend::swordDir()) { - i->setFlags(Qt::NoItemFlags); - i->setToolTip(0, tr("This default folder in your home directory can't be removed")); - } -} - -void BtInstallPathDialog::slotEditClicked() { - if (QTreeWidgetItem* i = m_swordPathListBox->currentItem()) { - QString dirname = QFileDialog::getExistingDirectory(this, tr("Choose Folder"), i->text(0), QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); - - if (dirname.isEmpty()) { // if user cancelled the dialog - return; - } - QDir dir = QDir(dirname); - if (dir.isReadable()) { - const QFileInfo fi( dir.canonicalPath() ); - if (!fi.exists() || !fi.isWritable()) { - const int result = message::showWarning(this, tr("Use Folder?"), tr("This folder is not writable, so works can not be installed here using BibleTime. Do you want to use this folder instead of the previous value?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No); - if (result != QMessageBox::Yes) return; - } - //i->setText(0, dir.absolutePath()); // absolute, not canonical - addPathToList(dir.absolutePath()); - delete i; - updateTopLevelItems(); - } - } -} - -void BtInstallPathDialog::slotAddClicked() { - QString dirname = QFileDialog::getExistingDirectory(this, tr("Choose Folder"), "", QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); - if (dirname.isEmpty()) { // if user cancelled the dialog - return; - } - QDir dir = QDir(dirname); - if (dir.isReadable()) { - const QFileInfo fi( dir.canonicalPath() ); - if (!fi.exists() || !fi.isWritable()) { - const int result = message::showWarning(this, tr("Use Folder?"), tr("This folder is not writable, so works can not be installed here using BibleTime. Do you still want to add it to the list of bookshelf folders?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No); - if (result != QMessageBox::Yes) { - return; - } - } - addPathToList(util::directory::convertDirSeparators(dir.canonicalPath())); - updateTopLevelItems(); - } -} - -void BtInstallPathDialog::slotRemoveClicked() { - QTreeWidgetItem* i = m_swordPathListBox->selectedItems().value(0); - if (i && i->parent() != m_swordPathListBox->invisibleRootItem()) { - delete i; - } - updateTopLevelItems(); -} - -void BtInstallPathDialog::writeSwordConfig() { - QStringList targets; - QTreeWidgetItemIterator it(m_swordPathListBox, QTreeWidgetItemIterator::NoChildren | QTreeWidgetItemIterator::Enabled | QTreeWidgetItemIterator::NotHidden); - while (*it) { - if (!(*it)->text(0).isEmpty()) { - targets << (*it)->text(0); - } - ++it; - } - qDebug() << "save the target list" << targets; - BtInstallBackend::setTargetList(targets); //creates new Sword config -} - -void BtInstallPathDialog::accept() { - writeSwordConfig(); - QDialog::accept(); -} diff --git a/src/frontend/bookshelfmanager/installpage/btinstallpathdialog.h b/src/frontend/bookshelfmanager/installpage/btinstallpathdialog.h deleted file mode 100644 index de4c69a..0000000 --- a/src/frontend/bookshelfmanager/installpage/btinstallpathdialog.h +++ /dev/null @@ -1,51 +0,0 @@ -/********* -* -* 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 BTINSTALLPATHDIALOG_H -#define BTINSTALLPATHDIALOG_H - -#include <QDialog> - - -class QPushButton; -class QTreeWidget; -class QTreeWidgetItem; - -class BtInstallPathDialog : public QDialog { - Q_OBJECT - public: - BtInstallPathDialog(); - ~BtInstallPathDialog(); - - public slots: - virtual void accept(); - - private slots: - void slotAddClicked(); - void slotRemoveClicked(); - void slotEditClicked(); - - private: - void writeSwordConfig(); - void updateTopLevelItems(); - void addPathToList(QString path); - - private: - QPushButton* m_editButton; - QPushButton* m_addButton; - QPushButton* m_removeButton; - QTreeWidget* m_swordPathListBox; - QTreeWidgetItem* m_writableItem; - QTreeWidgetItem* m_readableItem; - QTreeWidgetItem* m_nonexistingItem; -}; - -#endif diff --git a/src/frontend/bookshelfmanager/installpage/btinstallprogressdialog.cpp b/src/frontend/bookshelfmanager/installpage/btinstallprogressdialog.cpp deleted file mode 100644 index 53fd274..0000000 --- a/src/frontend/bookshelfmanager/installpage/btinstallprogressdialog.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/********* -* -* 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 "frontend/bookshelfmanager/installpage/btinstallprogressdialog.h" - -#include <QApplication> -#include <QCloseEvent> -#include <QDebug> -#include <QDialog> -#include <QHeaderView> -#include <QMultiMap> -#include <QProgressBar> -#include <QPushButton> -#include <QTreeWidget> -#include <QTreeWidgetItem> -#include <QVBoxLayout> -#include "backend/managers/cswordbackend.h" -#include "backend/btinstallthread.h" - - -BtInstallProgressDialog::BtInstallProgressDialog(const QList<CSwordModuleInfo *> & modules, - const QString & destination, - QWidget * parent, - Qt::WindowFlags flags) - : QDialog(parent, flags) - , m_nextInstallIndex(0) -{ - // we want this dialog to be deleted when user closes it or the downloads are completed - setAttribute(Qt::WA_DeleteOnClose, true); - - setWindowTitle(tr("Install Progress")); - - m_statusWidget = new QTreeWidget(); - m_statusWidget->setRootIsDecorated(false); - m_statusWidget->setHeaderLabels(QStringList(tr("Work")) << tr("Progress")); - m_statusWidget->header()->setStretchLastSection(false); -#if QT_VERSION < 0x050000 - m_statusWidget->header()->setResizeMode(1, QHeaderView::Stretch); - m_statusWidget->header()->setMovable(false); -#else - m_statusWidget->header()->setSectionResizeMode(1, QHeaderView::Stretch); - m_statusWidget->header()->setSectionsMovable(false); -#endif - - Q_FOREACH(const CSwordModuleInfo * module, modules) { - QTreeWidgetItem * progressItem = new QTreeWidgetItem(m_statusWidget); - progressItem->setText(0, module->name()); - progressItem->setIcon(0, module->moduleIcon()); - progressItem->setText(1, tr("Waiting for turn...")); - progressItem->setFlags(Qt::ItemIsEnabled); - } - - m_statusWidget->setMinimumWidth(m_statusWidget->size().width()); - m_stopAllButton = new QPushButton(tr("Stop All"), this); - - QVBoxLayout * layout = new QVBoxLayout(this); - layout->addWidget(m_statusWidget); - layout->addWidget(m_stopAllButton); - - connect(m_stopAllButton, SIGNAL(clicked()), - this, SLOT(slotStopInstall())); - - m_thread = new BtInstallThread(modules, destination, this); - // Connect the signals between the dialog, items and threads - connect(m_thread, SIGNAL(preparingInstall(int)), - this, SLOT(slotInstallStarted(int)), - Qt::QueuedConnection); - connect(m_thread, SIGNAL(downloadStarted(int)), - this, SLOT(slotDownloadStarted(int)), - Qt::QueuedConnection); - connect(m_thread, SIGNAL(statusUpdated(int, int)), - this, SLOT(slotStatusUpdated(int, int)), - Qt::QueuedConnection); - connect(m_thread, SIGNAL(installCompleted(int, bool)), - this, SLOT(slotOneItemCompleted(int, bool)), - Qt::QueuedConnection); - connect(m_thread, SIGNAL(finished()), - this, SLOT(slotThreadFinished()), - Qt::QueuedConnection); - #if QT_VERSION < 0x050000 - connect(m_thread, SIGNAL(terminated()), - this, SLOT(slotThreadFinished()), - Qt::QueuedConnection); - #endif - m_thread->start(); -} - -BtInstallProgressDialog::~BtInstallProgressDialog() { - m_thread->wait(); - delete m_thread; -} - -void BtInstallProgressDialog::slotStopInstall() { - m_stopAllButton->setDisabled(true); - m_thread->stopInstall(); - for (int i = m_nextInstallIndex; i < m_statusWidget->topLevelItemCount(); i++) { - QTreeWidgetItem * const item = m_statusWidget->topLevelItem(i); - item->setText(1, QString::null); - item->setDisabled(true); - } -} - -void BtInstallProgressDialog::slotInstallStarted(int moduleIndex) { - Q_ASSERT(moduleIndex == m_nextInstallIndex); - m_nextInstallIndex++; - QTreeWidgetItem * const item = m_statusWidget->topLevelItem(moduleIndex); - item->setText(1, tr("Preparing install...")); - m_statusWidget->scrollToItem(item); -} - -void BtInstallProgressDialog::slotDownloadStarted(int moduleIndex) { - QTreeWidgetItem * const item = m_statusWidget->topLevelItem(moduleIndex); - item->setText(1, QString::null); - getOrCreateProgressBar(item)->setValue(0); -} - -void BtInstallProgressDialog::slotStatusUpdated(int moduleIndex, int status) { - // find the progress bar for this module and update the value - getOrCreateProgressBar(moduleIndex)->setValue(status); -} - -void BtInstallProgressDialog::slotOneItemCompleted(int moduleIndex, bool successful) { -QTreeWidgetItem * const item = m_statusWidget->topLevelItem(moduleIndex); - // update the list item - m_statusWidget->setItemWidget(item, 1, NULL); - item->setText(1, successful ? tr("Completed") : tr("Failed")); - item->setDisabled(true); -} - -void BtInstallProgressDialog::slotThreadFinished() { - close(); -} - -void BtInstallProgressDialog::closeEvent(QCloseEvent * event) { - if (event->spontaneous()) { - event->ignore(); - slotStopInstall(); - return; - } - // other parts of the UI/engine must be updated - CSwordBackend::instance()->reloadModules(CSwordBackend::AddedModules); -} - -QProgressBar * BtInstallProgressDialog::getOrCreateProgressBar(int moduleIndex) { - return getOrCreateProgressBar(m_statusWidget->topLevelItem(moduleIndex)); -} - -QProgressBar * BtInstallProgressDialog::getOrCreateProgressBar(QTreeWidgetItem * item) { - QWidget * const itemWidget = m_statusWidget->itemWidget(item, 1); - QProgressBar * progressBar = dynamic_cast<QProgressBar *>(itemWidget); - if (!progressBar) { - progressBar = new QProgressBar(m_statusWidget); - progressBar->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); - m_statusWidget->setItemWidget(item, 1, progressBar); - } - return progressBar; -} diff --git a/src/frontend/bookshelfmanager/installpage/btinstallprogressdialog.h b/src/frontend/bookshelfmanager/installpage/btinstallprogressdialog.h deleted file mode 100644 index e6add1c..0000000 --- a/src/frontend/bookshelfmanager/installpage/btinstallprogressdialog.h +++ /dev/null @@ -1,69 +0,0 @@ -/********* -* -* 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 BTINSTALLPROGRESSDIALOG_H -#define BTINSTALLPROGRESSDIALOG_H - -#include <QDialog> - -#include <QString> - - -class BtInstallThread; -class CSwordModuleInfo; -class QProgressBar; -class QTreeWidget; -class QTreeWidgetItem; - -class BtInstallProgressDialog: public QDialog { - - Q_OBJECT - -public: /* Methods: */ - - BtInstallProgressDialog(const QList<CSwordModuleInfo *> & modules, - const QString & destination, - QWidget * parent = 0, - Qt::WindowFlags flags = 0); - ~BtInstallProgressDialog(); - -public slots: - - void slotStopInstall(); - void slotInstallStarted(int moduleIndex); - void slotDownloadStarted(int moduleIndex); - void slotStatusUpdated(int moduleIndex, int status); - void slotOneItemCompleted(int moduleIndex, bool status); - void slotThreadFinished(); - -protected: /* Methods: */ - - /** - Handles closing by the window close button, Cancel (Stop) All button, or - completing the downloads. - */ - virtual void closeEvent(QCloseEvent * event); - -private: /* Methods: */ - - QProgressBar * getOrCreateProgressBar(int moduleIndex); - QProgressBar * getOrCreateProgressBar(QTreeWidgetItem * item); - -private: /* Fields: */ - - QTreeWidget * m_statusWidget; - QPushButton * m_stopAllButton; - BtInstallThread * m_thread; - int m_nextInstallIndex; - -}; - -#endif diff --git a/src/frontend/bookshelfmanager/installpage/btrefreshprogressdialog.cpp b/src/frontend/bookshelfmanager/installpage/btrefreshprogressdialog.cpp deleted file mode 100644 index 856f58b..0000000 --- a/src/frontend/bookshelfmanager/installpage/btrefreshprogressdialog.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include "frontend/bookshelfmanager/installpage/btrefreshprogressdialog.h" - -#include <QApplication> -#include "backend/btinstallbackend.h" -#include "frontend/messagedialog.h" - - -BtRefreshProgressDialog::BtRefreshProgressDialog(sword::InstallSource &source, - QWidget *parent, - Qt::WindowFlags flags) - : QProgressDialog(parent, flags) - , m_source(source) -{ - Q_ASSERT(BtInstallBackend::isRemote(source)); - setWindowTitle(tr("Refreshing source %1").arg(QString(source.caption))); - setCancelButtonText(tr("&Cancel")); - setLabelText(tr("Connecting...")); - Q_ASSERT(minimum() == 0); - setMaximum(100); - setValue(0); - setWindowModality(Qt::ApplicationModal); - setMinimumDuration(1000); - - connect(this, SIGNAL(canceled()), - this, SLOT(slotCanceled())); - connect(&m_installMgr, SIGNAL(percentCompleted(int,int)), - this, SLOT(slotPercentCompleted(int,int))); -} - -void BtRefreshProgressDialog::slotPercentCompleted(int, int current) { - setValue(current); - qApp->processEvents(); -} - -void BtRefreshProgressDialog::slotCanceled() { - m_installMgr.terminate(); -} - -bool BtRefreshProgressDialog::runAndDelete() { - show(); - qApp->processEvents(); - bool r = (m_installMgr.refreshRemoteSource(&m_source) == 0); - if (r) { - setValue(100); - qApp->processEvents(); - } else { - message::showWarning(this, tr("Warning"), - tr("Failed to refresh source %1") - .arg(QString(m_source.caption))); - } - deleteLater(); - return r; -} diff --git a/src/frontend/bookshelfmanager/installpage/btrefreshprogressdialog.h b/src/frontend/bookshelfmanager/installpage/btrefreshprogressdialog.h deleted file mode 100644 index 03f82c9..0000000 --- a/src/frontend/bookshelfmanager/installpage/btrefreshprogressdialog.h +++ /dev/null @@ -1,40 +0,0 @@ -/********* -* -* 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 BTREFRESHPROGRESSDIALOG_H -#define BTREFRESHPROGRESSDIALOG_H - -#include <QProgressDialog> - -#include "backend/btinstallmgr.h" - - -class BtRefreshProgressDialog: public QProgressDialog { - Q_OBJECT - - public: /* Methods: */ - BtRefreshProgressDialog(sword::InstallSource &source, - QWidget *parent = 0, Qt::WindowFlags f = 0); - - bool runAndDelete(); - - private slots: - - void slotPercentCompleted(int, int); - void slotCanceled(); - - private: /* Fields: */ - - sword::InstallSource m_source; - BtInstallMgr m_installMgr; -}; - -#endif // BTREFRESHPROGRESSDIALOG_H diff --git a/src/frontend/bookshelfmanager/removepage/btremovepage.cpp b/src/frontend/bookshelfmanager/removepage/btremovepage.cpp deleted file mode 100644 index 57879ea..0000000 --- a/src/frontend/bookshelfmanager/removepage/btremovepage.cpp +++ /dev/null @@ -1,194 +0,0 @@ -/********* -* -* 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 "frontend/bookshelfmanager/removepage/btremovepage.h" - -#include <QAction> -#include <QDebug> -#include <QGroupBox> -#include <QHBoxLayout> -#include <QHeaderView> -#include <QPushButton> -#include <QToolButton> -#include <QVBoxLayout> -#include "backend/bookshelfmodel/btbookshelffiltermodel.h" -#include "backend/managers/cswordbackend.h" -#include "bibletimeapp.h" -#include "frontend/bookshelfmanager/btmodulemanagerdialog.h" -#include "frontend/btbookshelfview.h" -#include "frontend/btbookshelfwidget.h" -#include "frontend/messagedialog.h" -#include "util/cresmgr.h" -#include "util/directory.h" -#include "util/geticon.h" - -// Sword includes: -#include <swmgr.h> -#include <installmgr.h> - - -namespace { -const QString groupingOrderKey("GUI/BookshelfManager/RemovePage/grouping"); -} - -BtRemovePage::BtRemovePage(BtModuleManagerDialog *parent) - : BtConfigDialog::Page(util::getIcon(CResMgr::bookshelfmgr::removepage::icon), parent) -{ - m_worksGroupBox = new QGroupBox(this); - m_worksGroupBox->setFlat(true); - QVBoxLayout *wLayout = new QVBoxLayout; - wLayout->setContentsMargins(0, 0, 0, 0); - m_worksGroupBox->setLayout(wLayout); - - BtRemovePageTreeModel *treeModel = new BtRemovePageTreeModel(groupingOrderKey, - this); - connect(treeModel, SIGNAL(groupingOrderChanged(BtBookshelfTreeModel::Grouping)), - this, SLOT(slotGroupingOrderChanged(const BtBookshelfTreeModel::Grouping&))); - - m_bookshelfWidget = new BtBookshelfWidget(this); - m_bookshelfWidget->postFilterModel()->setShowHidden(true); - m_bookshelfWidget->setTreeModel(treeModel); - m_bookshelfWidget->setSourceModel(CSwordBackend::instance()->model()); - m_bookshelfWidget->showHideAction()->setVisible(false); - m_bookshelfWidget->showHideButton()->hide(); - m_bookshelfWidget->treeView()->header()->show(); -#if QT_VERSION < 0x050000 - m_bookshelfWidget->treeView()->header()->setResizeMode(QHeaderView::ResizeToContents); -#else - m_bookshelfWidget->treeView()->header()->setSectionResizeMode(QHeaderView::ResizeToContents); -#endif - wLayout->addWidget(m_bookshelfWidget); - - m_uninstallGroupBox = new QGroupBox(this); - m_uninstallGroupBox->setFlat(true); - QHBoxLayout *uLayout = new QHBoxLayout; - uLayout->setContentsMargins(0, 0, 0, 0); - m_uninstallGroupBox->setLayout(uLayout); - uLayout->addStretch(1); - - m_removeButton = new QPushButton(this); - m_removeButton->setIcon(util::getIcon(CResMgr::bookshelfmgr::removepage::remove_icon)); - m_removeButton->setEnabled(false); - uLayout->addWidget(m_removeButton, 0, Qt::AlignRight); - - QVBoxLayout *mainLayout = new QVBoxLayout(this); - mainLayout->addWidget(m_worksGroupBox, 1); - mainLayout->addWidget(m_uninstallGroupBox); - - connect(m_removeButton, SIGNAL(clicked()), - this, SLOT(slotRemoveModules())); - connect(m_bookshelfWidget->treeModel(), SIGNAL(moduleChecked(CSwordModuleInfo*,bool)), - this, SLOT(slotResetRemoveButton())); - connect(m_bookshelfWidget->treeModel(), SIGNAL(rowsRemoved(const QModelIndex&,int,int)), - this, SLOT(slotResetRemoveButton())); - - retranslateUi(); -} - -void BtRemovePage::retranslateUi() { - setHeaderText(tr("Remove")); - - m_worksGroupBox->setTitle(tr("Select &works to uninstall:")); - - m_removeButton->setText(tr("&Remove...")); - m_removeButton->setToolTip(tr("Remove the selected works")); - - retranslateUninstallGroupBox(); -} - -void BtRemovePage::retranslateUninstallGroupBox() { - int count = m_bookshelfWidget->treeModel()->checkedModules().count(); - if (count > 0) { - m_uninstallGroupBox->setTitle(tr("Start removal of %1 works:") - .arg(count)); - } else { - m_uninstallGroupBox->setTitle(tr("Start removal:")); - } -} - -void BtRemovePage::slotResetRemoveButton() { - retranslateUninstallGroupBox(); - m_removeButton->setEnabled(!m_bookshelfWidget->treeModel()->checkedModules().empty()); -} - -void BtRemovePage::slotRemoveModules() { - // Do nothing when this signal fires without anything selected to remove: - if (m_bookshelfWidget->treeModel()->checkedModules().empty()) return; - - QStringList moduleNames; - QStringList prettyModuleNames; - const int textHeight = fontMetrics().height(); - /// \bug <nobr> is not working, Qt bug - const QString moduleString("<nobr><img src=\"%1\" width=\"%2\" height=\"%3\"/> %4</nobr>"); - const QString iconDir = util::directory::getIconDir().canonicalPath() + '/'; - Q_FOREACH(const CSwordModuleInfo * m, - m_bookshelfWidget->treeModel()->checkedModules()) - { - const QIcon icon = CSwordModuleInfo::moduleIcon(*m); - const QSize iconSize = icon.actualSize(QSize(textHeight, textHeight)); - prettyModuleNames.append(moduleString - .arg(iconDir + CSwordModuleInfo::moduleIconFilename(*m)) - .arg(iconSize.width()) - .arg(iconSize.height()) - .arg(m->name())); - moduleNames.append(m->name()); - } - const QString message = tr("You selected the following work(s): ") - .append("<br/><br/> ") - .append(prettyModuleNames.join(", ")) - .append("<br/><br/>") - .append(tr("Do you really want to remove them from your system?")); - - if ((message::showQuestion(this, tr("Remove Works?"), message, QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::Yes)) { //Yes was pressed. - - // Update the module list before really removing. Remember deleting the pointers later. - QList<CSwordModuleInfo*> toBeDeleted = CSwordBackend::instance()->takeModulesFromList(moduleNames); - Q_ASSERT(toBeDeleted.size() == moduleNames.size()); - - 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(toBeDeleted); - //delete all mgrs which were created above - qDeleteAll(mgrDict); - mgrDict.clear(); - } -} - -void BtRemovePage::slotGroupingOrderChanged(const BtBookshelfTreeModel::Grouping &g) { - g.saveTo(groupingOrderKey); -} diff --git a/src/frontend/bookshelfmanager/removepage/btremovepage.h b/src/frontend/bookshelfmanager/removepage/btremovepage.h deleted file mode 100644 index a9600d8..0000000 --- a/src/frontend/bookshelfmanager/removepage/btremovepage.h +++ /dev/null @@ -1,61 +0,0 @@ -/********* -* -* 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 BTREMOVEPAGE_H -#define BTREMOVEPAGE_H - -#include "frontend/bookshelfmanager/btconfigdialog.h" - -#include <QMultiMap> -#include <QString> -#include "backend/btmoduletreeitem.h" -#include "frontend/bookshelfmanager/removepage/btremovepagetreemodel.h" - - -class BtBookshelfWidget; -class BtModuleManagerDialog; -class QGroupBox; -class QPushButton; - -class BtRemovePage: public BtConfigDialog::Page { - - Q_OBJECT - - public: /* Methods: */ - - BtRemovePage(BtModuleManagerDialog *parent = 0); - - public: /* Methods: */ - - void retranslateUi(); - - private: /* Methods: */ - - void retranslateUninstallGroupBox(); - - private slots: - - void slotRemoveModules(); - void slotResetRemoveButton(); - void slotGroupingOrderChanged(const BtBookshelfTreeModel::Grouping &g); - - private: /* Fields: */ - - QGroupBox *m_worksGroupBox; - BtBookshelfWidget *m_bookshelfWidget; - - QGroupBox *m_uninstallGroupBox; - QPushButton *m_removeButton; - -}; - -#endif diff --git a/src/frontend/bookshelfmanager/removepage/btremovepagetreemodel.cpp b/src/frontend/bookshelfmanager/removepage/btremovepagetreemodel.cpp deleted file mode 100644 index 9fce7ab..0000000 --- a/src/frontend/bookshelfmanager/removepage/btremovepagetreemodel.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/********* -* -* 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 "frontend/bookshelfmanager/removepage/btremovepagetreemodel.h" - - -BtRemovePageTreeModel::BtRemovePageTreeModel(const QString &configKey, QObject *parent) - : BtBookshelfTreeModel(configKey, parent) -{ - setCheckable(true); - setDefaultChecked(BtBookshelfTreeModel::UNCHECKED); -} - -int BtRemovePageTreeModel::columnCount(const QModelIndex &parent) const { - Q_UNUSED(parent); - - return 2; -} - -QVariant BtRemovePageTreeModel::data(const QModelIndex &i, int role) const { - if (i.column() == 1) { - QModelIndex realIndex(index(i.row(), 0, i.parent())); - switch (role) { - case Qt::DisplayRole: - case Qt::ToolTipRole: - return BtBookshelfTreeModel::data(realIndex, BtBookshelfModel::ModuleInstallPathRole); - default: - break; - } - } - else { - return BtBookshelfTreeModel::data(i, role); - } - - return QVariant(); -} - -QVariant BtRemovePageTreeModel::headerData(int section, - Qt::Orientation orientation, - int role) const { - if (role == Qt::DisplayRole && orientation == Qt::Horizontal) { - if (section == 0) { - return tr("Work"); - } - else if (section == 1) { - return tr("Install path"); - } - } - - return QVariant(); -} diff --git a/src/frontend/bookshelfmanager/removepage/btremovepagetreemodel.h b/src/frontend/bookshelfmanager/removepage/btremovepagetreemodel.h deleted file mode 100644 index 50da32b..0000000 --- a/src/frontend/bookshelfmanager/removepage/btremovepagetreemodel.h +++ /dev/null @@ -1,30 +0,0 @@ -/********* -* -* 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 BTREMOVEPAGETREEMODEL_H -#define BTREMOVEPAGETREEMODEL_H - -#include "backend/bookshelfmodel/btbookshelftreemodel.h" - -class BtRemovePageTreeModel: public BtBookshelfTreeModel { - Q_OBJECT - - public: - BtRemovePageTreeModel(const QString &configKey, QObject *parent = 0); - - int columnCount(const QModelIndex &parent = QModelIndex()) const; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - QVariant headerData(int section, Qt::Orientation orientation, - int role = Qt::DisplayRole) const; -}; - -#endif // BTREMOVEPAGETREEMODEL_H diff --git a/src/frontend/bookshelfwizard/btbookshelfinstallfinalpage.cpp b/src/frontend/bookshelfwizard/btbookshelfinstallfinalpage.cpp new file mode 100644 index 0000000..b91a732 --- /dev/null +++ b/src/frontend/bookshelfwizard/btbookshelfinstallfinalpage.cpp @@ -0,0 +1,189 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#include "frontend/bookshelfwizard/btbookshelfinstallfinalpage.h" + +#include <QApplication> +#include <QHBoxLayout> +#include <QLabel> +#include <QProgressBar> +#include <QPushButton> +#include <QVBoxLayout> +#include "backend/btinstallbackend.h" +#include "backend/btinstallthread.h" +#include "frontend/bookshelfwizard/btbookshelfwizard.h" +#include "frontend/bookshelfwizard/btbookshelfwizardenums.h" +#include "util/btconnect.h" + + +namespace { +QString const groupingOrderKey = "GUI/BookshelfWizard/InstallPage/grouping"; +QString const installPathKey = + "GUI/BookshelfWizard/InstallPage/installPathIndex"; +} // anonymous namespace + +BtBookshelfInstallFinalPage::BtBookshelfInstallFinalPage(QWidget * parent) + : BtBookshelfWizardPage(parent) +{ + // Setup UI: + m_verticalLayout = new QVBoxLayout(this); + m_verticalLayout->setObjectName(QStringLiteral("verticalLayout")); + + m_verticalLayout->addItem(new QSpacerItem(20, + 40, + QSizePolicy::Minimum, + QSizePolicy::Expanding)); + + m_msgLabel = new QLabel(this); + m_msgLabel->setAlignment(Qt::AlignCenter); + m_msgLabel->setWordWrap(true); + m_verticalLayout->addWidget(m_msgLabel); + + m_msgLabel2 = new QLabel(this); + m_msgLabel2->setAlignment(Qt::AlignCenter); + m_msgLabel2->setWordWrap(true); + m_verticalLayout->addWidget(m_msgLabel2); + + m_progressBar = new QProgressBar(this); + m_progressBar->setObjectName("progressBar"); + m_progressBar->setMinimum(0); + m_progressBar->setMaximum(100); + m_verticalLayout->addWidget(m_progressBar,Qt::AlignCenter); + + QHBoxLayout * const horizontalLayout = new QHBoxLayout(); + m_stopButton = new QPushButton(this); + horizontalLayout->addSpacerItem( + new QSpacerItem(1, 1, QSizePolicy::Expanding)); + horizontalLayout->addWidget(m_stopButton); + horizontalLayout->addSpacerItem( + new QSpacerItem(1, 1, QSizePolicy::Expanding)); + m_verticalLayout->addLayout(horizontalLayout); + + m_verticalLayout->addItem(new QSpacerItem(20, + 40, + QSizePolicy::Minimum, + QSizePolicy::Expanding)); + + // Initialize connections: + BT_CONNECT(m_stopButton, &QPushButton::clicked, + this, &BtBookshelfInstallFinalPage::slotStopInstall); +} + +void BtBookshelfInstallFinalPage::destroyThread() noexcept { + if (m_thread) { + m_thread->stopInstall(); + while (!m_thread->wait()) /* join */; + delete m_thread; + m_thread = nullptr; + } +} + +void BtBookshelfInstallFinalPage::retranslateUi() { + m_stopButton->setText(tr("Stop")); + + if (btWizard().taskType() == WizardTaskType::updateWorks) { + setTitle(QApplication::translate( + "BookshelfWizard", "Updating Works")); + setSubTitle(QApplication::translate( + "BookshelfWizard", + "The selected works are being updated.")); + } else { + setTitle(QApplication::translate( + "BookshelfWizard", "Installing Works")); + setSubTitle(QApplication::translate( + "BookshelfWizard", + "The selected works are being installed.")); + } +} + +int BtBookshelfInstallFinalPage::nextId() const { return -1; } + +void BtBookshelfInstallFinalPage::initializePage() { + destroyThread(); + retranslateUi(); + + // Install works: + auto & btWiz = btWizard(); + m_modules = btWiz.selectedWorks().toList(); + m_thread = new BtInstallThread(m_modules, btWiz.installPath(), this); + BT_CONNECT(m_thread, &BtInstallThread::preparingInstall, + this, &BtBookshelfInstallFinalPage::slotInstallStarted, + Qt::QueuedConnection); + BT_CONNECT(m_thread, &BtInstallThread::statusUpdated, + this, &BtBookshelfInstallFinalPage::slotStatusUpdated, + Qt::QueuedConnection); + BT_CONNECT(m_thread, &BtInstallThread::installCompleted, + this, &BtBookshelfInstallFinalPage::slotOneItemCompleted, + Qt::QueuedConnection); + BT_CONNECT(m_thread, &BtInstallThread::finished, + this, &BtBookshelfInstallFinalPage::slotThreadFinished, + Qt::QueuedConnection); + m_progressBar->setValue(0); + m_stopButton->setEnabled(true); + m_installFailed = false; + m_installCompleted = false; + m_thread->start(); + btWiz.downloadStarted(); +} + +bool BtBookshelfInstallFinalPage::isComplete() const +{ return m_installCompleted; } + +void BtBookshelfInstallFinalPage::slotStopInstall() { + m_stopButton->setDisabled(true); + m_thread->stopInstall(); + m_installFailed = true; +} + +void BtBookshelfInstallFinalPage::slotInstallStarted(int moduleIndex) { + m_msgLabel->setText( + tr("Installing \"%1\"").arg(m_modules.at(moduleIndex)->name())); + m_msgLabel2->setText(m_modules.at(moduleIndex)->config(CSwordModuleInfo::Description)); + m_lastStatus = -1; +} + +void BtBookshelfInstallFinalPage::slotStatusUpdated(int moduleIndex, int status) +{ + // Skip initial high value sent by sword + if ((m_lastStatus == -1 && status > 80) || (m_lastStatus == status)) + return; + + m_lastStatus = status; + + int const perModuleIncrement = 100 / m_modules.count(); + m_progressBar->setValue((moduleIndex * perModuleIncrement) + + (status * perModuleIncrement / 100)); +} + +void BtBookshelfInstallFinalPage::slotOneItemCompleted(int moduleIndex, + bool successful) +{ + m_progressBar->setValue((moduleIndex + 1) * (100 / m_modules.count())); + if (!successful) + m_installFailed = true; +} + +void BtBookshelfInstallFinalPage::slotThreadFinished() { + m_progressBar->setValue(100); + m_stopButton->setEnabled(false); + if (m_installFailed) { + m_msgLabel->setText(tr("Some of the selected works were not " + "installed.")); + m_msgLabel->setStyleSheet("QLabel{color:red}"); + } else { + m_msgLabel->setText(tr("The selected works have been installed.")); + } + m_msgLabel2->setText(""); + + CSwordBackend::instance()->reloadModules(CSwordBackend::AddedModules); + + m_installCompleted = true; + emit QWizardPage::completeChanged(); + btWizard().downloadFinished(); +} diff --git a/src/frontend/bookshelfwizard/btbookshelfinstallfinalpage.h b/src/frontend/bookshelfwizard/btbookshelfinstallfinalpage.h new file mode 100644 index 0000000..6938384 --- /dev/null +++ b/src/frontend/bookshelfwizard/btbookshelfinstallfinalpage.h @@ -0,0 +1,77 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef BTBOOKSHELFINSTALLFINALPAGE +#define BTBOOKSHELFINSTALLFINALPAGE + +#include "btbookshelfwizardpage.h" + +#include <QList> +#include "backend/drivers/btmoduleset.h" + + +class BtBookshelfWizard; +class BtInstallThread; +class QLabel; +class QProgressBar; +class QPushButton; +class QSwordModuleInfo; +class QVBoxLayout; + +class BtBookshelfInstallFinalPage final: public BtBookshelfWizardPage { + + Q_OBJECT + +public: /* Methods: */ + + BtBookshelfInstallFinalPage(QWidget * parent = 0); + inline ~BtBookshelfInstallFinalPage() noexcept final override + { destroyThread(); } + + void destroyThread() noexcept; + + void initializePage() final override; + bool isComplete() const final override; + int nextId() const final override; + BtModuleSet selectedWorks() const; + +public slots: + void slotStopInstall(); + +private slots: + + void slotInstallStarted(int moduleIndex); + void slotOneItemCompleted(int moduleIndex, bool status); + void slotStatusUpdated(int moduleIndex, int status); + void slotThreadFinished(); + +private: /* Methods: */ + + void retranslateUi(); + +private: /* Fields: */ + + QLabel * m_msgLabel; + QLabel * m_msgLabel2; + QProgressBar * m_progressBar; + QPushButton * m_stopButton; + BtInstallThread * m_thread = nullptr; + QVBoxLayout * m_verticalLayout; + + bool m_installFailed; + bool m_installCompleted; + + QList<CSwordModuleInfo *> m_modules; + int m_lastStatus; + +}; /* class BtBookshelfInstallFinalPage */ + +#endif diff --git a/src/frontend/bookshelfwizard/btbookshelflanguagespage.cpp b/src/frontend/bookshelfwizard/btbookshelflanguagespage.cpp new file mode 100644 index 0000000..b422172 --- /dev/null +++ b/src/frontend/bookshelfwizard/btbookshelflanguagespage.cpp @@ -0,0 +1,122 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#include "frontend/bookshelfwizard/btbookshelflanguagespage.h" + +#include <QApplication> +#include <QHBoxLayout> +#include <QListView> +#include <QPushButton> +#include <QVBoxLayout> +#include <set> +#include "backend/btinstallbackend.h" +#include "backend/config/btconfig.h" +#include "backend/managers/clanguagemgr.h" +#include "backend/models/btlistmodel.h" +#include "frontend/bookshelfwizard/btbookshelfwizard.h" +#include "frontend/bookshelfwizard/btbookshelfwizardenums.h" +#include "util/btconnect.h" + + +namespace { +QString const LanguagesKey = "GUI/BookshelfWizard/languages"; +} // anonymous namespace + +BtBookshelfLanguagesPage::BtBookshelfLanguagesPage(QWidget * parent) + : BtBookshelfWizardPage(parent) +{ + // Setup UI: + m_verticalLayout = new QVBoxLayout(this); + m_verticalLayout->setObjectName(QStringLiteral("verticalLayout")); + m_languagesListView = new QListView(this); + m_languagesListView->setObjectName(QStringLiteral("languagesListView")); + m_verticalLayout->addWidget(m_languagesListView); + + // Create languages Model: + m_model = new BtListModel(true, this); + m_languagesListView->setModel(m_model); + BT_CONNECT(m_model, &QStandardItemModel::dataChanged, + this, &BtBookshelfLanguagesPage::slotDataChanged); +} + +void BtBookshelfLanguagesPage::retranslateUi() { + setTitle(QApplication::translate("BookshelfWizard", "Choose Languages")); + setSubTitle(QApplication::translate("BookshelfWizard", + "Choose one or more languages to " + "install works from.")); +} + +int BtBookshelfLanguagesPage::nextId() const +{ return WizardPage::installWorksPage; } + +void BtBookshelfLanguagesPage::initializePage() { + + { // Select languages: + QStringList languages; + if (m_firstTimeInit) { + languages << btConfig().value<QStringList>(LanguagesKey, + QStringList{}); + if (languages.isEmpty()) + languages << tr("English"); + m_firstTimeInit = false; + } else { + languages << selectedLanguages(); + } + + bool scrolledToFirstSelected = false; + for (int row = 0; row < m_model->rowCount(); ++row) { + QStandardItem * const item = m_model->item(row, 0); + if (languages.contains(item->text())) { + item->setCheckState(Qt::Checked); + // Scroll to first selected item: + if (!scrolledToFirstSelected) { + m_languagesListView->scrollTo(m_model->indexFromItem(item)); + scrolledToFirstSelected = true; + } + } + } + } + + retranslateUi(); +} + +void BtBookshelfLanguagesPage::initializeLanguages() { + // Get languages from sources: + std::set<QString> languages; + for (auto const & sourceName : btWizard().selectedSources()) + for (auto const * module : + BtInstallBackend::backend( + BtInstallBackend::source(sourceName))->moduleList()) + languages.insert(module->language()->translatedName()); + + // Update languages model: + m_model->clear(); + for (auto const & lang : languages) + m_model->appendItem(lang); + if (languages.size() == 1u) + m_model->item(0, 0)->setCheckState(Qt::Checked); +} + +bool BtBookshelfLanguagesPage::skipPage() const noexcept +{ return m_model->rowCount() == 1; } + +void BtBookshelfLanguagesPage::slotDataChanged() { emit completeChanged(); } + +bool BtBookshelfLanguagesPage::isComplete() const +{ return selectedLanguages().count() > 0; } + +QStringList BtBookshelfLanguagesPage::selectedLanguages() const { + QStringList languages; + for (int row = 0; row < m_model->rowCount(); ++row) { + QStandardItem * const item = m_model->item(row,0); + if (item->checkState() == Qt::Checked) + languages << item->text(); + } + return languages; +} diff --git a/src/frontend/bookshelfwizard/btbookshelflanguagespage.h b/src/frontend/bookshelfwizard/btbookshelflanguagespage.h new file mode 100644 index 0000000..12b1a30 --- /dev/null +++ b/src/frontend/bookshelfwizard/btbookshelflanguagespage.h @@ -0,0 +1,57 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef BTBOOKSHELFLANGUAGESPAGE +#define BTBOOKSHELFLANGUAGESPAGE + +#include "frontend/bookshelfwizard/btbookshelfwizardpage.h" + +#include <QStringList> + + +class BtBookshelfWizard; +class BtListModel; +class QListView; +class QVBoxLayout; + +class BtBookshelfLanguagesPage final: public BtBookshelfWizardPage { + + Q_OBJECT + +public: /* Methods: */ + + BtBookshelfLanguagesPage(QWidget * parent = 0); + + void initializeLanguages(); + void initializePage() final override; + bool isComplete() const final override; + int nextId() const final override; + QStringList selectedLanguages() const; + bool skipPage() const noexcept; + +private slots: + + void slotDataChanged(); + +private: /* Methods: */ + + void retranslateUi(); + +private: /* Fields: */ + + bool m_firstTimeInit = true; + QListView * m_languagesListView; + QVBoxLayout * m_verticalLayout; + BtListModel * m_model; + +}; /* class BtBookshelfLanguagesPage */ + +#endif diff --git a/src/frontend/bookshelfwizard/btbookshelfremovefinalpage.cpp b/src/frontend/bookshelfwizard/btbookshelfremovefinalpage.cpp new file mode 100644 index 0000000..1c4eb36 --- /dev/null +++ b/src/frontend/bookshelfwizard/btbookshelfremovefinalpage.cpp @@ -0,0 +1,61 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#include "frontend/bookshelfwizard/btbookshelfremovefinalpage.h" + +#include <QDebug> +#include <QLabel> +#include <QSpacerItem> +#include <QVBoxLayout> +#include "backend/managers/cswordbackend.h" +#include "frontend/bookshelfwizard/btbookshelfwizard.h" +#include "util/btconnect.h" + + +namespace { +const QString groupingOrderKey ("GUI/BookshelfWizard/InstallPage/grouping"); +const QString installPathKey ("GUI/BookshelfWizard/InstallPage/installPathIndex"); +} // anonymous namespace + +BtBookshelfRemoveFinalPage::BtBookshelfRemoveFinalPage(QWidget * parent) + : BtBookshelfWizardPage(parent) +{ + m_verticalLayout = new QVBoxLayout(this); + m_verticalLayout->setObjectName(QStringLiteral("verticalLayout")); + + m_verticalLayout->addItem(new QSpacerItem(20, + 40, + QSizePolicy::Minimum, + QSizePolicy::Expanding)); + + m_msgLabel = new QLabel(this); + m_msgLabel->setAlignment(Qt::AlignCenter); + m_msgLabel->setObjectName(QStringLiteral("msgLabel")); + m_msgLabel->setWordWrap(true); + m_verticalLayout->addWidget(m_msgLabel); + + m_verticalLayout->addItem(new QSpacerItem(20, + 40, + QSizePolicy::Minimum, + QSizePolicy::Expanding)); +} + +void BtBookshelfRemoveFinalPage::retranslateUi() +{ m_msgLabel->setText(tr("The selected works have been removed.")); } + +void BtBookshelfRemoveFinalPage::initializePage() { + retranslateUi(); + + // Remove works: + CSwordBackend::instance()->uninstallModules(btWizard().selectedWorks()); +} + +bool BtBookshelfRemoveFinalPage::isComplete() const { return true; } + +int BtBookshelfRemoveFinalPage::nextId() const { return -1; } diff --git a/src/frontend/bookshelfwizard/btbookshelfremovefinalpage.h b/src/frontend/bookshelfwizard/btbookshelfremovefinalpage.h new file mode 100644 index 0000000..a081fba --- /dev/null +++ b/src/frontend/bookshelfwizard/btbookshelfremovefinalpage.h @@ -0,0 +1,48 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef BTBOOKSHELFREMOVEFINALPAGE +#define BTBOOKSHELFREMOVEFINALPAGE + +#include "frontend/bookshelfwizard/btbookshelfwizardpage.h" + +#include "backend/bookshelfmodel/btbookshelftreemodel.h" +#include "backend/drivers/btmoduleset.h" + + +class BtBookshelfWizard; +class QLabel; +class QVBoxLayout; + +class BtBookshelfRemoveFinalPage final: public BtBookshelfWizardPage { + + Q_OBJECT + +public: /* Methods: */ + + BtBookshelfRemoveFinalPage(QWidget * parent = 0); + + bool isComplete() const final override; + void initializePage() final override; + int nextId() const final override; + +private: /* Methods: */ + + void retranslateUi(); + +private: /* Fields: */ + + QLabel * m_msgLabel; + QVBoxLayout * m_verticalLayout; + +}; /* class BtBookshelfRemoveFinalPage */ + +#endif diff --git a/src/frontend/bookshelfwizard/btbookshelfsourcespage.cpp b/src/frontend/bookshelfwizard/btbookshelfsourcespage.cpp new file mode 100644 index 0000000..c0af1a3 --- /dev/null +++ b/src/frontend/bookshelfwizard/btbookshelfsourcespage.cpp @@ -0,0 +1,208 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#include "frontend/bookshelfwizard/btbookshelfsourcespage.h" + +#include <QAbstractItemView> +#include <QApplication> +#include <QDate> +#include <QHBoxLayout> +#include <QHeaderView> +#include <QMessageBox> +#include <QModelIndex> +#include <QProgressDialog> +#include <QPushButton> +#include <QSignalMapper> +#include <QTableView> +#include <QtGlobal> +#include <QVBoxLayout> +#include "backend/config/btconfig.h" +#include "backend/btinstallbackend.h" +#include "backend/btinstallmgr.h" +#include "backend/models/btlistmodel.h" +#include "frontend/bookshelfwizard/cswordsetupinstallsourcesdialog.h" +#include "frontend/bookshelfwizard/btbookshelflanguagespage.h" +#include "frontend/bookshelfwizard/btbookshelfwizard.h" +#include "frontend/bookshelfwizard/btbookshelfwizardenums.h" +#include "util/btconnect.h" + + +namespace { +char const buttonPropertyName[] = "BtBookshelfSourcesPageButtonProperty"; +constexpr bool const ButtonTagAdd = true; +constexpr bool const ButtonTagRemove = false; +QString const SourcesKey = "GUI/BookshelfWizard/sources"; +QString const lastUpdate = "GUI/BookshelfWizard/lastUpdate"; +QStringList const initialSelection{"CrossWire", "Bible.org", "Xiphos"}; +} // anonymous namespace + + +BtBookshelfSourcesPage::BtBookshelfSourcesPage(QWidget * parent) + : BtBookshelfWizardPage(parent) +{ + // Setup UI: + m_verticalLayout = new QVBoxLayout(this); + m_verticalLayout->setObjectName(QStringLiteral("m_verticalLayout")); + m_sourcesTableView = new QTableView(this); + m_sourcesTableView->setObjectName(QStringLiteral("sourcesListView")); + m_sourcesTableView->horizontalHeader()->setVisible(false); + m_sourcesTableView->verticalHeader()->setVisible(false); + m_verticalLayout->addWidget(m_sourcesTableView); + + // Create sources model: + m_model = new BtListModel(true, this, 2); + m_sourcesTableView->setModel(m_model); + BT_CONNECT(m_model, &QStandardItemModel::dataChanged, + this, &QWizardPage::completeChanged); +} + +void BtBookshelfSourcesPage::retranslateUi() { + setTitle(QApplication::translate("BookshelfWizard", + "Choose Remote Libraries")); + setSubTitle(QApplication::translate( + "BookshelfWizard", + "Choose one or more remote libraries to install works from.")); +} + +int BtBookshelfSourcesPage::nextId() const { + auto & languagesPage = btWizard().languagesPage(); + languagesPage.initializeLanguages(); + return languagesPage.skipPage() + ? WizardPage::installWorksPage + : WizardPage::languagesPage; +} + +void BtBookshelfSourcesPage::initializePage() { + QStringList saveSources; + if (m_firstTimeInit) { + saveSources << btConfig().value<QStringList>(SourcesKey, QStringList{}); + if (saveSources.empty()) + saveSources << initialSelection; + m_firstTimeInit = false; + } else { + saveSources << selectedSources(); + } + + // Do before updating models to get correct + // column width for buttons + retranslateUi(); + + updateSourcesModel(); + selectSourcesInModel(saveSources); +} + +void BtBookshelfSourcesPage::selectSourcesInModel(const QStringList& sources) { + for (int row = 0; row < m_model->rowCount(); ++row) { + QStandardItem * const item = m_model->item(row,0); + if (sources.contains(item->text())) + item->setCheckState(Qt::Checked); + } +} + +void BtBookshelfSourcesPage::updateSourcesModel() { + QStringList sourceList = BtInstallBackend::sourceNameList(); + m_model->clear(); + m_model->setColumnCount(2); + + m_signalMapper = new QSignalMapper(this); + + auto const addButton = [this](int row, int column, + QString const & text, bool const tag) { + QPushButton * const button = new QPushButton(text, this); + button->setProperty(buttonPropertyName, tag); + m_sourcesTableView->setIndexWidget(m_model->index(row, column), button); + return button; + }; + + constexpr auto const smMap = + static_cast<void (QSignalMapper::*)()>(&QSignalMapper::map); + QString const removeText = tr("Remove"); + for (QString source : sourceList) { + m_model->appendItem(source); + int const row = m_model->rowCount() - 1; + QPushButton * button = addButton(row, 1, removeText, ButtonTagRemove); + BT_CONNECT(button, &QPushButton::clicked, + m_signalMapper, smMap); + m_signalMapper->setMapping(button, row); + } + + m_model->appendRow(new QStandardItem(tr("< Add new remote library >"))); + int const row = m_model->rowCount() - 1; + QString const addText = tr("Add"); + QPushButton * const button = addButton(row, 1, addText, ButtonTagAdd); + BT_CONNECT(button, &QPushButton::clicked, m_signalMapper,smMap); + m_signalMapper->setMapping(button, row); + + BT_CONNECT(m_signalMapper, + static_cast<void (QSignalMapper::*)(int)>( + &QSignalMapper::mapped), + this, &BtBookshelfSourcesPage::slotButtonClicked); + + m_sourcesTableView->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Fixed); + m_sourcesTableView->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); + m_sourcesTableView->setShowGrid(false); + + // Calculate button column width: + QFontMetrics const fontMetrics = m_sourcesTableView->fontMetrics(); + m_sourcesTableView->setColumnWidth(1, + qMax(fontMetrics.width(removeText), + fontMetrics.width(addText)) + 60); +} + +bool BtBookshelfSourcesPage::isComplete() const { + for (int row = 0; row < m_model->rowCount(); ++row) + if (m_model->item(row, 0)->checkState() == Qt::Checked) + return true; + return false; +} + +QStringList BtBookshelfSourcesPage::selectedSources() const { + QStringList sources; + for (int row = 0; row < m_model->rowCount(); ++row) { + QStandardItem * const item = m_model->item(row, 0); + if (item->checkState() == Qt::Checked) + sources << item->text(); + } + return sources; +} + +void BtBookshelfSourcesPage::slotButtonClicked(int row) { + QModelIndex const index = m_model->index(row, 1); + if (static_cast<QPushButton *>( + m_sourcesTableView->indexWidget(index))->property( + buttonPropertyName).toBool() == ButtonTagRemove) + { + if (QMessageBox::warning( + this, + tr("Delete Source"), + tr("Do you really want to delete this source?"), + QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) + BtInstallBackend::deleteSource( + m_model->item(index.row(), 0)->text()); + QStringList const saveSources = selectedSources(); + updateSourcesModel(); + selectSourcesInModel(saveSources); + return; + } + + CSwordSetupInstallSourcesDialog dlg; + QStringList const saveSources = selectedSources(); + if (dlg.exec() != QDialog::Accepted) + return; + if (dlg.wasRemoteListAdded()) { + updateSourcesModel(); + selectSourcesInModel(saveSources); + return; + } + sword::InstallSource newSource = dlg.getSource(); + if (*(newSource.type.c_str()) != '\0') // we have a valid source to add + BtInstallBackend::addSource(newSource); + updateSourcesModel(); + selectSourcesInModel(saveSources); +} diff --git a/src/frontend/bookshelfwizard/btbookshelfsourcespage.h b/src/frontend/bookshelfwizard/btbookshelfsourcespage.h new file mode 100644 index 0000000..8f5ef73 --- /dev/null +++ b/src/frontend/bookshelfwizard/btbookshelfsourcespage.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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef BTBOOKSHELFSOURCESPAGE +#define BTBOOKSHELFSOURCESPAGE + +#include "frontend/bookshelfwizard/btbookshelfwizardpage.h" + +#include <QStringList> + + +class BtInstallMgr; +class BtListModel; +class QPushButton; +class QSignalMapper; +class QTableView; +class QVBoxLayout; + +class BtBookshelfSourcesPage final: public BtBookshelfWizardPage { + + Q_OBJECT + +public: /* Methods: */ + + BtBookshelfSourcesPage(QWidget * parent = 0); + + bool isComplete() const final override; + void initializePage() final override; + int nextId() const final override; + QStringList selectedSources() const; + +private slots: + + void slotButtonClicked(int row); + +private: /* Methods: */ + + void retranslateUi(); + void selectSourcesInModel(QStringList const & sources); + void updateSourcesModel(); + +private: /* Fields: */ + + bool m_firstTimeInit = true; + QTableView * m_sourcesTableView; + QVBoxLayout * m_verticalLayout; + BtListModel * m_model; + BtInstallMgr * m_currentInstallMgr; + QSignalMapper * m_signalMapper; + +}; /* class BtBookshelfSourcesPage */ + +#endif diff --git a/src/frontend/bookshelfwizard/btbookshelfsourcesprogresspage.cpp b/src/frontend/bookshelfwizard/btbookshelfsourcesprogresspage.cpp new file mode 100644 index 0000000..b26e4cb --- /dev/null +++ b/src/frontend/bookshelfwizard/btbookshelfsourcesprogresspage.cpp @@ -0,0 +1,134 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#include "frontend/bookshelfwizard/btbookshelfsourcesprogresspage.h" + +#include <QApplication> +#include <QDate> +#include <QHBoxLayout> +#include <QLabel> +#include <QProgressBar> +#include <QPushButton> +#include <QVBoxLayout> +#include "backend/btinstallbackend.h" +#include "backend/btsourcesthread.h" +#include "backend/config/btconfig.h" +#include "frontend/bookshelfwizard/btbookshelfwizardenums.h" +#include "frontend/bookshelfwizard/btbookshelfwizard.h" +#include "util/btconnect.h" + + +namespace { +QString const lastUpdate = "GUI/BookshelfWizard/lastUpdate"; +} + +BtBookshelfSourcesProgressPage::BtBookshelfSourcesProgressPage(QWidget * parent) + : BtBookshelfWizardPage(parent) +{ + // Setup UI: + QVBoxLayout * const vLayout = new QVBoxLayout(this); + vLayout->setObjectName(QStringLiteral("verticalLayout")); + + vLayout->addItem(new QSpacerItem(20, + 40, + QSizePolicy::Minimum, + QSizePolicy::Expanding)); + + m_msgLabel = new QLabel(this); + m_msgLabel->setAlignment(Qt::AlignCenter); + m_msgLabel->setObjectName(QStringLiteral("msgLabel")); + m_msgLabel->setWordWrap(true); + vLayout->addWidget(m_msgLabel); + + m_progressBar = new QProgressBar(this); + m_progressBar->setObjectName("progressBar"); + m_progressBar->setMinimum(0); + m_progressBar->setMaximum(100); + vLayout->addWidget(m_progressBar, Qt::AlignCenter); + + QHBoxLayout * const horizontalLayout = new QHBoxLayout(); + m_stopButton = new QPushButton(this); + horizontalLayout->addSpacerItem( + new QSpacerItem(1, 1, QSizePolicy::Expanding)); + horizontalLayout->addWidget(m_stopButton); + horizontalLayout->addSpacerItem( + new QSpacerItem(1, 1, QSizePolicy::Expanding)); + vLayout->addLayout(horizontalLayout); + + vLayout->addItem(new QSpacerItem(20, + 40, + QSizePolicy::Minimum, + QSizePolicy::Expanding)); + + // Initialize connections: + BT_CONNECT(m_stopButton, &QPushButton::clicked, + this, &BtBookshelfSourcesProgressPage::slotStopInstall); +} + +void BtBookshelfSourcesProgressPage::destroyThread() noexcept { + if (m_thread) { + m_thread->stop(); + while (!m_thread->wait()) /* join */; + delete m_thread; + m_thread = nullptr; + } +} + +void BtBookshelfSourcesProgressPage::retranslateUi() { + m_stopButton->setText(tr("Stop")); + + setTitle(QApplication::translate( + "BookshelfWizard", "Updating Remote Libraries")); + setSubTitle(QApplication::translate( + "BookshelfWizard", + "Updating information from remote libraries.")); +} + +int BtBookshelfSourcesProgressPage::nextId() const { + if (btWizard().taskType() == WizardTaskType::updateWorks) + return WizardPage::updateWorksPage; + return WizardPage::sourcesPage; +} + +void BtBookshelfSourcesProgressPage::initializePage() { + destroyThread(); + + m_installCompleted = false; + m_thread = new BtSourcesThread(this); + BT_CONNECT(m_thread, &BtSourcesThread::percentComplete, + m_progressBar, &QProgressBar::setValue, + Qt::QueuedConnection); + BT_CONNECT(m_thread, &BtSourcesThread::showMessage, + m_msgLabel, &QLabel::setText, + Qt::QueuedConnection); + BT_CONNECT(m_thread, &BtSourcesThread::finished, + this, &BtBookshelfSourcesProgressPage::slotThreadFinished, + Qt::QueuedConnection); + m_thread->start(); + m_stopButton->setEnabled(true); + btWizard().downloadStarted(); + retranslateUi(); +} + +bool BtBookshelfSourcesProgressPage::isComplete() const +{ return m_installCompleted; } + +void BtBookshelfSourcesProgressPage::slotThreadFinished() { + m_stopButton->setDisabled(true); + if (m_thread->finishedSuccessfully()) + btConfig().setValue<QDate>(lastUpdate, QDate::currentDate()); + m_installCompleted = true; + emit QWizardPage::completeChanged(); + btWizard().downloadFinished(); +} + +void BtBookshelfSourcesProgressPage::slotStopInstall() { + m_stopButton->setDisabled(true); + m_thread->stop(); +} diff --git a/src/frontend/bookshelfwizard/btbookshelfsourcesprogresspage.h b/src/frontend/bookshelfwizard/btbookshelfsourcesprogresspage.h new file mode 100644 index 0000000..459167e --- /dev/null +++ b/src/frontend/bookshelfwizard/btbookshelfsourcesprogresspage.h @@ -0,0 +1,60 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef BTBOOKSHELFSOURCESPROGRESSPAGE +#define BTBOOKSHELFSOURCESPROGRESSPAGE + +#include "frontend/bookshelfwizard/btbookshelfwizardpage.h" + + +class BtSourcesThread; +class QLabel; +class QProgressBar; +class QPushButton; + +class BtBookshelfSourcesProgressPage final: public BtBookshelfWizardPage { + + Q_OBJECT + +public: /* Methods: */ + + BtBookshelfSourcesProgressPage(QWidget * parent = 0); + inline ~BtBookshelfSourcesProgressPage() noexcept override + { destroyThread(); } + + void destroyThread() noexcept; + + void initializePage() final override; + bool isComplete() const final override; + int nextId() const final override; + +public slots: + void slotStopInstall(); + +private slots: + + void slotThreadFinished(); + +private: /* Methods: */ + + void retranslateUi(); + +private: /* Methods: */ + + bool m_installCompleted = false; + QLabel * m_msgLabel; + QProgressBar * m_progressBar; + QPushButton * m_stopButton; + BtSourcesThread * m_thread = nullptr; + +}; + +#endif diff --git a/src/frontend/bookshelfwizard/btbookshelftaskpage.cpp b/src/frontend/bookshelfwizard/btbookshelftaskpage.cpp new file mode 100644 index 0000000..ca9c936 --- /dev/null +++ b/src/frontend/bookshelfwizard/btbookshelftaskpage.cpp @@ -0,0 +1,137 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#include "backend/config/btconfig.h" +#include "frontend/bookshelfwizard/btbookshelftaskpage.h" + +#include <QApplication> +#include <QDate> +#include <QGroupBox> +#include <QLabel> +#include <QRadioButton> +#include <QVBoxLayout> + + +namespace { +QString const lastUpdate = "GUI/BookshelfWizard/lastUpdate"; +} // anonymous namespace + + +BtBookshelfTaskPage::BtBookshelfTaskPage(QWidget * parent) + : BtBookshelfWizardPage(parent) +{ + m_verticalLayout = new QVBoxLayout(this); + m_verticalLayout->setObjectName(QStringLiteral("verticalLayout")); + + m_warningLabel = new QLabel(this); + m_warningLabel->setObjectName(QStringLiteral("warningLabel")); + m_warningLabel->setWordWrap(true); + + m_verticalLayout->addWidget(m_warningLabel); + m_verticalLayout->addItem( + new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding)); + + m_groupBox = new QGroupBox(this); + { // Setup radio buttons: + QVBoxLayout * const vLayout = new QVBoxLayout(m_groupBox); + vLayout->setObjectName(QStringLiteral("verticalLayout2")); + + m_installRadioButton = new QRadioButton(m_groupBox); + m_installRadioButton->setObjectName( + QStringLiteral("installRadioButton")); + QSizePolicy sizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred); + sizePolicy.setHorizontalStretch(0); + sizePolicy.setVerticalStretch(0); + sizePolicy.setHeightForWidth( + m_installRadioButton->sizePolicy().hasHeightForWidth()); + m_installRadioButton->setSizePolicy(sizePolicy); + m_installRadioButton->setChecked(true); + vLayout->addWidget(m_installRadioButton); + + m_updateRadioButton = new QRadioButton(m_groupBox); + m_updateRadioButton->setObjectName(QStringLiteral("updateRadioButton")); + sizePolicy.setHeightForWidth( + m_updateRadioButton->sizePolicy().hasHeightForWidth()); + m_updateRadioButton->setSizePolicy(sizePolicy); + vLayout->addWidget(m_updateRadioButton); + + m_removeRadioButton = new QRadioButton(m_groupBox); + m_removeRadioButton->setObjectName(QStringLiteral("removeRadioButton")); + vLayout->addWidget(m_removeRadioButton); + } + m_verticalLayout->addWidget(m_groupBox); + + m_verticalLayout->addItem( + new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding)); + m_verticalLayout->setStretch(0, 1); + m_verticalLayout->setStretch(1, 1); + m_verticalLayout->setStretch(2, 1); + m_verticalLayout->setStretch(3, 3); + + retranslateUi(); +} + +void BtBookshelfTaskPage::retranslateUi() { + setTitle(QApplication::translate("BookshelfWizard", + "Bookshelf Manager")); + setSubTitle(QApplication::translate("BookshelfWizard", + "Install, update, or remove works on your bookshelf.")); + m_warningLabel->setText( + QApplication::translate( + "BookshelfWizard", + "<html><head/><body><p><span style=\" font-weight:600;\">" + "WARNING</span>: Installing or updating works uses the " + "internet. If you live in a persecuted country you may not " + "want to do this.</p></body></html>")); + m_groupBox->setTitle(QApplication::translate("BookshelfWizard", + "Bookshelf task")); + m_installRadioButton->setText( + QApplication::translate( + "BookshelfWizard", + "Install additional works (uses internet)")); + m_updateRadioButton->setText( + QApplication::translate("BookshelfWizard", + "Update installed works (uses internet)")); + m_removeRadioButton->setText( + QApplication::translate("BookshelfWizard", + "Remove installed works")); +} + +static bool timeToUpdate() { + QDate const lastDate = btConfig().value<QDate>(lastUpdate); + if (!lastDate.isValid()) + return true; + if (QDate::currentDate().toJulianDay() - lastDate.toJulianDay() > 7) + return true; + return false; +} + +int BtBookshelfTaskPage::nextId() const { + if (m_installRadioButton->isChecked()) { + if (timeToUpdate()) + return WizardPage::sourcesProgressPage; + return WizardPage::sourcesPage; + } else if (m_updateRadioButton->isChecked()) { + if (timeToUpdate()) + return WizardPage::sourcesProgressPage; + return WizardPage::updateWorksPage; + } else if (m_removeRadioButton->isChecked()) { + return WizardPage::removeWorksPage; + } else { + return -1; + } +} + +WizardTaskType BtBookshelfTaskPage::taskType() const { + if (m_installRadioButton->isChecked()) + return WizardTaskType::installWorks; + if (m_updateRadioButton->isChecked()) + return WizardTaskType::updateWorks; + return WizardTaskType::removeWorks; +} diff --git a/src/frontend/bookshelfwizard/btbookshelftaskpage.h b/src/frontend/bookshelfwizard/btbookshelftaskpage.h new file mode 100644 index 0000000..8118f89 --- /dev/null +++ b/src/frontend/bookshelfwizard/btbookshelftaskpage.h @@ -0,0 +1,51 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef BTBOOKSHELFTASKPAGE +#define BTBOOKSHELFTASKPAGE + +#include "frontend/bookshelfwizard/btbookshelfwizardpage.h" + +#include "frontend/bookshelfwizard/btbookshelfwizardenums.h" + + +class QGroupBox; +class QLabel; +class QRadioButton; +class QVBoxLayout; + +class BtBookshelfTaskPage final: public BtBookshelfWizardPage { + + Q_OBJECT + +public: /* Methods: */ + + BtBookshelfTaskPage(QWidget * parent = 0); + + int nextId() const final override; + WizardTaskType taskType() const; + +private: /* Methods: */ + + void retranslateUi(); + +private: /* Fields: */ + + QLabel * m_warningLabel; + QGroupBox * m_groupBox; + QVBoxLayout * m_verticalLayout; + QRadioButton * m_installRadioButton; + QRadioButton * m_updateRadioButton; + QRadioButton * m_removeRadioButton; + +}; + +#endif diff --git a/src/frontend/bookshelfwizard/btbookshelfwizard.cpp b/src/frontend/bookshelfwizard/btbookshelfwizard.cpp new file mode 100644 index 0000000..a5db6d4 --- /dev/null +++ b/src/frontend/bookshelfwizard/btbookshelfwizard.cpp @@ -0,0 +1,169 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#include "frontend/bookshelfwizard/btbookshelfwizard.h" + +#include <QAbstractButton> +#include <QApplication> +#include <QByteArray> +#include <QKeyEvent> +#include <QMessageBox> +#include <QPushButton> +#include "backend/config/btconfig.h" +#include "frontend/bookshelfwizard/btbookshelfinstallfinalpage.h" +#include "frontend/bookshelfwizard/btbookshelflanguagespage.h" +#include "frontend/bookshelfwizard/btbookshelfremovefinalpage.h" +#include "frontend/bookshelfwizard/btbookshelfsourcespage.h" +#include "frontend/bookshelfwizard/btbookshelfsourcesprogresspage.h" +#include "frontend/bookshelfwizard/btbookshelftaskpage.h" +#include "frontend/bookshelfwizard/btbookshelfwizardenums.h" +#include "frontend/bookshelfwizard/btbookshelfworkspage.h" + + +namespace { +QString const GeometryKey = "GUI/BookshelfWizard/geometry"; +QString const SourcesKey = "GUI/BookshelfWizard/sources"; +QString const LanguagesKey = "GUI/BookshelfWizard/languages"; +} // anonymous namespace + +BtBookshelfWizard::BtBookshelfWizard(QWidget * parent, Qt::WindowFlags flags) + : QWizard(parent, flags) + , m_downloadInProgress(false) + , m_closeRequested(false) + , m_closeMessageBox(new QMessageBox(this)) + , m_taskPage(new BtBookshelfTaskPage(this)) + , m_sourcesPage(new BtBookshelfSourcesPage(this)) + , m_sourcesProgressPage(new BtBookshelfSourcesProgressPage(this)) + , m_languagesPage(new BtBookshelfLanguagesPage(this)) + , m_installWorksPage(new BtBookshelfWorksPage(WizardTaskType::installWorks, this)) + , m_updateWorksPage(new BtBookshelfWorksPage(WizardTaskType::updateWorks, this)) + , m_removeWorksPage(new BtBookshelfWorksPage(WizardTaskType::removeWorks, this)) + , m_installFinalPage(new BtBookshelfInstallFinalPage(this)) // For install and update +{ + setPage(WizardPage::taskPage, m_taskPage); + setPage(WizardPage::sourcesProgressPage,m_sourcesProgressPage); + setPage(WizardPage::sourcesPage, m_sourcesPage); + setPage(WizardPage::languagesPage, m_languagesPage); + setPage(WizardPage::installWorksPage, m_installWorksPage); + setPage(WizardPage::updateWorksPage, m_updateWorksPage); + setPage(WizardPage::removeWorksPage, m_removeWorksPage); + setPage(WizardPage::removeFinalPage, new BtBookshelfRemoveFinalPage(this)); + setPage(WizardPage::installFinalPage, m_installFinalPage); + setStartId(WizardPage::taskPage); + + QRect rect = geometry(); + rect.setWidth(780); + rect.setHeight(600); + setGeometry(rect); + setOption(QWizard::NoBackButtonOnLastPage); + + retranslateUi(); + + // Load wizard geometry: + restoreGeometry(btConfig().value<QByteArray>(GeometryKey, QByteArray())); +} + +static void replaceButtonText(QWizard * wizard, QWizard::WizardButton which, const QString& text) { + QAbstractButton * button = wizard->button(which); + if (button != nullptr) + button->setText(text); +} + +// This function can be used by other QWizard's in the future +void translateQWizardStandardButtons(QWizard * wizard) { + replaceButtonText(wizard, QWizard::BackButton, QPushButton::tr("Back" ,"Dialog Button")); + replaceButtonText(wizard, QWizard::NextButton, QPushButton::tr("Next" ,"Dialog Button")); + replaceButtonText(wizard, QWizard::CommitButton, QPushButton::tr("Commit","Dialog Button")); + replaceButtonText(wizard, QWizard::FinishButton, QPushButton::tr("Finish","Dialog Button")); + replaceButtonText(wizard, QWizard::CancelButton, QPushButton::tr("Cancel","Dialog Button")); + replaceButtonText(wizard, QWizard::HelpButton, QPushButton::tr("Help" ,"Dialog Button")); +} + +void BtBookshelfWizard::retranslateUi() { + translateQWizardStandardButtons(this); + setWindowTitle(QApplication::translate("BookshelfWizard", + "Bookshelf Manager")); + m_closeMessageBox->setWindowTitle(QApplication::translate( + "BookshelfWizard", + "Canceling Downloads")); + m_closeMessageBox->setText(QApplication::translate( + "BookshelfWizard", + "The Bookshelf Manager will close when the current download finishes.")); +} + +QStringList BtBookshelfWizard::selectedSources() const +{ return m_sourcesPage->selectedSources(); } + +QStringList BtBookshelfWizard::selectedLanguages() const +{ return m_languagesPage->selectedLanguages(); } + +void BtBookshelfWizard::accept() { + if (currentPage() == m_installFinalPage) { + // Save settings: + btConfig().setValue(SourcesKey, selectedSources()); + btConfig().setValue(LanguagesKey, selectedLanguages()); + } + + btConfig().setValue(GeometryKey, saveGeometry()); // Save wizard geometry + QDialog::accept(); +} + +BtModuleSet BtBookshelfWizard::selectedWorks() const { + WizardTaskType const iType = m_taskPage->taskType(); + if (iType == WizardTaskType::installWorks) + return m_installWorksPage->checkedModules(); + if (iType == WizardTaskType::updateWorks) + return m_updateWorksPage->checkedModules(); + BT_ASSERT(iType == WizardTaskType::removeWorks); + return m_removeWorksPage->checkedModules(); +} + +WizardTaskType BtBookshelfWizard::taskType() const +{ return m_taskPage->taskType(); } + +QString BtBookshelfWizard::installPath() const { + WizardTaskType const iType = m_taskPage->taskType(); + if (iType == WizardTaskType::installWorks) + return m_installWorksPage->installPath(); + BT_ASSERT(iType == WizardTaskType::updateWorks); + return m_updateWorksPage->installPath(); +} + +void BtBookshelfWizard::stopDownload() { + if (currentPage() == m_installFinalPage) { + m_installFinalPage->slotStopInstall(); + } + if (currentPage() == m_sourcesProgressPage) { + m_sourcesProgressPage->slotStopInstall(); + } +} + +void BtBookshelfWizard::keyPressEvent(QKeyEvent * event) { + if(event->key() == Qt::Key_Escape) { + if (m_downloadInProgress) { + m_closeRequested = true; + m_closeMessageBox->show(); + stopDownload(); + return; + } + } + QWizard::keyPressEvent(event); +} + +void BtBookshelfWizard::downloadStarted() { + m_downloadInProgress = true; +} + +void BtBookshelfWizard::downloadFinished() { + m_downloadInProgress = false; + if (m_closeRequested) { + m_closeMessageBox->hide(); + accept(); + } +} diff --git a/src/frontend/bookshelfwizard/btbookshelfwizard.h b/src/frontend/bookshelfwizard/btbookshelfwizard.h new file mode 100644 index 0000000..44219c1 --- /dev/null +++ b/src/frontend/bookshelfwizard/btbookshelfwizard.h @@ -0,0 +1,84 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef BTBOOKSHELFWIZARD_H +#define BTBOOKSHELFWIZARD_H + +#include <QWizard> + +#include <QStringList> +#include "frontend/bookshelfwizard/btbookshelfwizardenums.h" +#include "util/btassert.h" + + +class BtBookshelfWorksPage; +class BtBookshelfInstallFinalPage; +class BtBookshelfLanguagesPage; +class BtBookshelfSourcesPage; +class BtBookshelfSourcesProgressPage; +class BtBookshelfTaskPage; +class BtBookshelfUpdatePage; +class BtModuleSet; +class QKeyEvent; +class QMessageBox; + +/** \brief The Bookshelf Manager wizard. */ +class BtBookshelfWizard final: public QWizard { + + Q_OBJECT + +public: /* Methods: */ + + BtBookshelfWizard(QWidget * parent = nullptr, Qt::WindowFlags flags = 0); + + QStringList selectedSources() const; + QStringList selectedLanguages() const; + BtModuleSet selectedWorks() const; + WizardTaskType taskType() const; + QString installPath() const; + + BtBookshelfLanguagesPage & languagesPage() const noexcept { + return *m_languagesPage; + } + + void downloadStarted(); + void downloadFinished(); + +public slots: + + void accept() final override; + +protected: + virtual void keyPressEvent(QKeyEvent * event) override; + +private: /* Methods: */ + + void retranslateUi(); + void stopDownload(); + +private: /* Fields: */ + + bool m_downloadInProgress; + bool m_closeRequested; + QMessageBox * m_closeMessageBox; + + BtBookshelfTaskPage * const m_taskPage; + BtBookshelfSourcesPage * const m_sourcesPage; + BtBookshelfSourcesProgressPage * const m_sourcesProgressPage; + BtBookshelfLanguagesPage * const m_languagesPage; + BtBookshelfWorksPage * const m_installWorksPage; + BtBookshelfWorksPage * const m_updateWorksPage; + BtBookshelfWorksPage * const m_removeWorksPage; + BtBookshelfInstallFinalPage * const m_installFinalPage; + +}; /* class BtBookshelfWizard */ + +#endif diff --git a/src/frontend/bookshelfwizard/btbookshelfwizardenums.h b/src/frontend/bookshelfwizard/btbookshelfwizardenums.h new file mode 100644 index 0000000..410961a --- /dev/null +++ b/src/frontend/bookshelfwizard/btbookshelfwizardenums.h @@ -0,0 +1,33 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef BTBOOKSHELFWIZARDENUM_H +#define BTBOOKSHELFWIZARDENUM_H + +enum WizardPage: int { + taskPage, + sourcesProgressPage, + sourcesPage, + languagesPage, + installWorksPage, + updateWorksPage, + removeWorksPage, + removeFinalPage, + installFinalPage +}; + +enum WizardTaskType { + installWorks, + updateWorks, + removeWorks +}; + +#endif diff --git a/src/frontend/bookshelfwizard/btbookshelfwizardpage.h b/src/frontend/bookshelfwizard/btbookshelfwizardpage.h new file mode 100644 index 0000000..0a00606 --- /dev/null +++ b/src/frontend/bookshelfwizard/btbookshelfwizardpage.h @@ -0,0 +1,42 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef BTBOOKSHELFWIZARDPAGE_H +#define BTBOOKSHELFWIZARDPAGE_H + +#include <QWizardPage> + +#include <utility> +#include "frontend/bookshelfwizard/btbookshelfwizard.h" +#include "util/btassert.h" + + +class BtBookshelfWizardPage: public QWizardPage { + + Q_OBJECT + +public: /* Methods: */ + + template <typename ... Args> + BtBookshelfWizardPage(Args && ... args) + : QWizardPage(std::forward<Args>(args)...) + {} + + inline BtBookshelfWizard & btWizard() const noexcept { + BtBookshelfWizard * const w = + qobject_cast<BtBookshelfWizard *>(wizard()); + BT_ASSERT(w); + return *w; + } + +}; /* class BtBookshelfWizardPage */ + +#endif diff --git a/src/frontend/bookshelfwizard/btbookshelfworkspage.cpp b/src/frontend/bookshelfwizard/btbookshelfworkspage.cpp new file mode 100644 index 0000000..2b7808a --- /dev/null +++ b/src/frontend/bookshelfwizard/btbookshelfworkspage.cpp @@ -0,0 +1,320 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#include "frontend/bookshelfwizard/btbookshelfworkspage.h" + +#include <QApplication> +#include <QComboBox> +#include <QHBoxLayout> +#include <QHeaderView> +#include <QLabel> +#include <QSet> +#include <QToolButton> +#include <QVBoxLayout> +#include "backend/btinstallbackend.h" +#include "backend/bookshelfmodel/btbookshelffiltermodel.h" +#include "backend/config/btconfig.h" +#include "backend/managers/cswordbackend.h" +#include "frontend/bookshelfwizard/btinstallpagemodel.h" +#include "frontend/btbookshelfgroupingmenu.h" +#include "frontend/btbookshelfview.h" +#include "util/btassert.h" +#include "util/btconnect.h" +#include "util/directory.h" + + +namespace { +QString const groupingOrderKey("GUI/BookshelfWizard/InstallPage/grouping"); +QString const installPathKey( + "GUI/BookshelfWizard/InstallPage/installPathIndex"); + +inline bool filter(WizardTaskType const taskType, + QStringList const & languages, + CSwordModuleInfo const * const mInfo) +{ + if (taskType == WizardTaskType::installWorks) { + return !CSwordBackend::instance()->findModuleByName(mInfo->name()) + && languages.contains(mInfo->language()->translatedName()); + } else if (taskType == WizardTaskType::updateWorks) { + using CSMI = CSwordModuleInfo; + using CSV = sword::SWVersion const; + CSMI const * const installedModule = + CSwordBackend::instance()->findModuleByName(mInfo->name()); + return installedModule + && (CSV(installedModule->config(CSMI::ModuleVersion).toLatin1()) + < CSV(mInfo->config(CSMI::ModuleVersion).toLatin1())); + } else { + BT_ASSERT(taskType == WizardTaskType::removeWorks); + return CSwordBackend::instance()->findModuleByName(mInfo->name()); + } +} + +} // anonymous namespace + +BtBookshelfWorksPage::BtBookshelfWorksPage(WizardTaskType iType, + QWidget * parent) + : BtBookshelfWizardPage(parent) + , m_taskType(iType) + , m_groupingOrder(groupingOrderKey) +{ + // Initialize menus: + m_groupingMenu = new BtBookshelfGroupingMenu(this); + m_contextMenu = new QMenu(this); + m_contextMenu->addMenu(m_groupingMenu); + m_itemContextMenu = m_contextMenu; + + // Setup UI: + QVBoxLayout * const verticalLayout = new QVBoxLayout(this); + verticalLayout->setObjectName(QStringLiteral("verticalLayout")); + + m_bookshelfView = new BtBookshelfView(this); + m_bookshelfView->setObjectName(QStringLiteral("worksTreeView")); + m_bookshelfView->setHeaderHidden(false); + m_bookshelfView->header()->setSectionResizeMode( + QHeaderView::ResizeToContents); + verticalLayout->addWidget(m_bookshelfView); + + m_msgLabel = new QLabel(this); + m_msgLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + m_msgLabel->setWordWrap(true); + verticalLayout->addWidget(m_msgLabel); + + QHBoxLayout * const pathLayout = new QHBoxLayout(); + if (m_taskType != WizardTaskType::removeWorks) { + m_pathCombo = new QComboBox(this); + m_pathCombo->setMinimumContentsLength(20); + m_pathCombo->setSizeAdjustPolicy( + QComboBox::AdjustToMinimumContentsLengthWithIcon); + m_pathCombo->setSizePolicy(QSizePolicy::Expanding, + QSizePolicy::Minimum); + m_pathCombo->view()->setTextElideMode(Qt::ElideMiddle); + + m_pathLabel = new QLabel(this); + m_pathLabel->setBuddy(m_pathCombo); + slotInitPathCombo(); + + pathLayout->setContentsMargins(0, 8, 0, 0); + pathLayout->addWidget(m_pathLabel); + pathLayout->addWidget(m_pathCombo); + } + pathLayout->addStretch(); + + m_groupingLabel = new QLabel(this); + pathLayout->addWidget(m_groupingLabel); + + m_groupingButton = new QToolButton(this); + m_groupingButton->setPopupMode(QToolButton::InstantPopup); + m_groupingButton->setMenu(m_groupingMenu); + m_groupingButton->setIcon(m_groupingMenu->icon()); + m_groupingButton->setAutoRaise(true); + pathLayout->addWidget(m_groupingButton); + + verticalLayout->addLayout(pathLayout); + + // Setup models: + BtBookshelfFilterModel * const filterModel = + new BtBookshelfFilterModel(this); + m_bookshelfView->setModel(filterModel); + + m_installPageModel = new BtInstallPageModel(m_groupingOrder, this); + if (m_taskType == WizardTaskType::updateWorks) + m_installPageModel->setDefaultChecked(BtBookshelfTreeModel::CHECKED); + filterModel->setSourceModel(m_installPageModel); + + m_bookshelfModel = new BtBookshelfModel(this); + if (m_taskType == WizardTaskType::removeWorks) { + m_installPageModel->setSourceModel(CSwordBackend::instance()->model()); + } else { + m_installPageModel->setSourceModel(m_bookshelfModel); + } + if (m_taskType == WizardTaskType::removeWorks) + m_bookshelfView->setColumnHidden(1, true); + + // Initialize connections: + BT_CONNECT(m_groupingMenu, + &BtBookshelfGroupingMenu::signalGroupingOrderChanged, + this, + &BtBookshelfWorksPage::slotGroupingActionTriggered); + if (m_taskType != WizardTaskType::removeWorks) { + BT_CONNECT(m_pathCombo, + static_cast<void (QComboBox::*)(int)>( + &QComboBox::currentIndexChanged), + this, &BtBookshelfWorksPage::slotPathChanged); + BT_CONNECT( + CSwordBackend::instance(), &CSwordBackend::sigSwordSetupChanged, + this, &BtBookshelfWorksPage::slotInitPathCombo); + } + BT_CONNECT(m_installPageModel, &BtBookshelfTreeModel::moduleChecked, + this, &BtBookshelfWorksPage::completeChanged); + BT_CONNECT(m_installPageModel, &BtInstallPageModel::groupingOrderChanged, + this, &BtBookshelfWorksPage::slotGroupingOrderChanged); + + retranslateUi(); +} + +void BtBookshelfWorksPage::retranslateUi() { + if (m_taskType == installWorks) { + setTitle(QApplication::translate("BookshelfWizard", "Install Works")); + setSubTitle(QApplication::translate("BookshelfWizard", + "Choose one or more works to " + "install.")); + setButtonText(QWizard::NextButton,tr("Install Works >")); + } else if (m_taskType == WizardTaskType::updateWorks) { + setTitle(QApplication::translate("BookshelfWizard", "Update Works")); + setSubTitle(QApplication::translate("BookshelfWizard", + "Choose one or more works to " + "update.")); + setButtonText(QWizard::NextButton,tr("Update Works >")); + } else { + BT_ASSERT(m_taskType == WizardTaskType::removeWorks); + setTitle(QApplication::translate("BookshelfWizard", "Remove Works")); + setSubTitle(QApplication::translate("BookshelfWizard", + "Choose one or more works to " + "remove.")); + setButtonText(QWizard::NextButton,tr("Remove Works >")); + } + + if (m_taskType != WizardTaskType::removeWorks) { + m_pathLabel->setText(tr("Install &folder:")); + m_pathCombo->setToolTip(tr("The folder where the new works will be " + "installed")); + } + + if (m_taskType == WizardTaskType::updateWorks) { + m_msgLabel->setText(tr("There are no works to update.")); + } else if (m_taskType == WizardTaskType::removeWorks) { + m_msgLabel->setText(tr("No works are currently installed so they " + "cannot be removed.")); + } else { + BT_ASSERT(m_taskType == WizardTaskType::installWorks); + m_msgLabel->setText( + tr("No works can be installed with the current selection of " + "remote libraries and languages. Please go back and make a " + "different selection.")); + } + + m_groupingLabel->setText(tr("Grouping:")); + m_groupingButton->setText(tr("Grouping")); + m_groupingButton->setToolTip( + tr("Change the grouping of items in the bookshelf.")); +} + +int BtBookshelfWorksPage::nextId() const { + if (btWizard().taskType() == WizardTaskType::removeWorks) + return WizardPage::removeFinalPage; + return WizardPage::installFinalPage; +} + +void BtBookshelfWorksPage::initializePage() { + // Update models: + QStringList sources; + QStringList languages; + if (m_taskType == installWorks) { + sources = btWizard().selectedSources(); + languages = btWizard().selectedLanguages(); + } else { + sources = BtInstallBackend::sourceNameList(); + } + + { + QSet<QString> addedModuleNames; + m_bookshelfModel->clear(); + for (auto const & sourceName : sources) { + sword::InstallSource const source = + BtInstallBackend::source(sourceName); + CSwordBackend * const backend = BtInstallBackend::backend(source); + for (auto * const module : backend->moduleList()) { + if (filter(m_taskType, languages, module)) { + QString const & moduleName = module->name(); + if (addedModuleNames.contains(moduleName)) + continue; + addedModuleNames.insert(moduleName); + m_bookshelfModel->addModule(module); + module->setProperty("installSourceName", + QString(source.caption.c_str())); + } + } + } + if (m_taskType != WizardTaskType::installWorks) + m_bookshelfView->expandAll(); + + bool const noWorks = (addedModuleNames.count() == 0); + m_msgLabel->setVisible(noWorks); + m_bookshelfView->setVisible(!noWorks); + m_groupingButton->setVisible(!noWorks); + m_groupingLabel->setVisible(!noWorks); + } + + // Set grouping: + static BtBookshelfTreeModel::Grouping const cat( + BtBookshelfTreeModel::GROUP_CATEGORY); + static BtBookshelfTreeModel::Grouping const catLang; // No grouping + if (languages.count() == 1) { + slotGroupingActionTriggered(cat); + } else if (languages.count() > 1 && m_groupingOrder == cat) { + slotGroupingActionTriggered(catLang); + } +} + +void BtBookshelfWorksPage::slotGroupingActionTriggered( + BtBookshelfTreeModel::Grouping const & grouping) +{ + m_installPageModel->setGroupingOrder(grouping); + m_bookshelfView->setRootIsDecorated(!grouping.isEmpty()); +} + +bool BtBookshelfWorksPage::isComplete() const +{ return checkedModules().count() > 0; } + +void BtBookshelfWorksPage::slotGroupingOrderChanged( + BtBookshelfTreeModel::Grouping const & g) +{ + m_groupingOrder = g; + m_groupingOrder.saveTo(groupingOrderKey); +} + +BtModuleSet const & BtBookshelfWorksPage::checkedModules() const +{ return m_installPageModel->checkedModules(); } + +QString BtBookshelfWorksPage::installPath() const +{ return m_pathCombo->currentText(); } + +void BtBookshelfWorksPage::slotPathChanged(int const index) +{ btConfig().setValue(installPathKey, index); } + +static bool installPathIsUsable(QString const & path) { + if (path.isEmpty()) + return false; + QDir const dir(path); + if (!dir.exists() || !dir.isReadable()) + return false; + return QFileInfo(dir.canonicalPath()).isWritable(); +} + +void BtBookshelfWorksPage::slotInitPathCombo() { + m_pathCombo->clear(); + QStringList const targets(BtInstallBackend::targetList()); + bool haveUsableTargets = false; + for (auto const & target : targets) { + if (installPathIsUsable(target)) { + m_pathCombo->addItem(util::directory::convertDirSeparators(target)); + haveUsableTargets = true; + } + } + + m_pathCombo->setVisible(haveUsableTargets); + m_pathLabel->setVisible(haveUsableTargets); + if (haveUsableTargets) { + /* Choose the current value from config but check whether we have so + many items: */ + int const cfgValue = btConfig().value<int>(installPathKey, 0); + int const lastIdx = m_pathCombo->count() - 1; + m_pathCombo->setCurrentIndex(cfgValue > lastIdx ? lastIdx : cfgValue); + } +} diff --git a/src/frontend/bookshelfwizard/btbookshelfworkspage.h b/src/frontend/bookshelfwizard/btbookshelfworkspage.h new file mode 100644 index 0000000..5ed385d --- /dev/null +++ b/src/frontend/bookshelfwizard/btbookshelfworkspage.h @@ -0,0 +1,78 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef BTBOOKSHELFWORKSPAGE +#define BTBOOKSHELFWORKSPAGE + +#include "frontend/bookshelfwizard/btbookshelfwizardpage.h" + +#include "backend/bookshelfmodel/btbookshelftreemodel.h" +#include "backend/drivers/btmoduleset.h" +#include "frontend/bookshelfwizard/btbookshelfwizardenums.h" + + +class BtBookshelfGroupingMenu; +class BtBookshelfModel; +class BtBookshelfView; +class BtInstallPageModel; +class QComboBox; +class QLabel; +class QMenu; +class QToolButton; + +class BtBookshelfWorksPage final: public BtBookshelfWizardPage { + + Q_OBJECT + +public: /* Methods: */ + + BtBookshelfWorksPage(WizardTaskType iType, QWidget * parent = nullptr); + + BtModuleSet const & checkedModules() const; + bool isComplete() const final override; + void initializePage() final override; + QString installPath() const; + int nextId() const final override; + +private slots: + + void slotGroupingActionTriggered( + BtBookshelfTreeModel::Grouping const & grouping); + void slotGroupingOrderChanged(BtBookshelfTreeModel::Grouping const & g); + void slotPathChanged(int const index); + void slotInitPathCombo(); + +private: /* Methods: */ + + void retranslateUi(); + +private: /* Fields: */ + + WizardTaskType const m_taskType; + BtBookshelfTreeModel::Grouping m_groupingOrder; + + QToolButton * m_groupingButton; + BtBookshelfView * m_bookshelfView; + QLabel * m_msgLabel; + QLabel * m_pathLabel; + QLabel * m_groupingLabel; + QComboBox * m_pathCombo; + + BtInstallPageModel * m_installPageModel; + BtBookshelfModel * m_bookshelfModel; + + QMenu * m_contextMenu; + BtBookshelfGroupingMenu * m_groupingMenu; + QMenu * m_itemContextMenu; + +}; /* class BtBookshelfWorksPage */ + +#endif diff --git a/src/frontend/bookshelfwizard/btinstallpagemodel.cpp b/src/frontend/bookshelfwizard/btinstallpagemodel.cpp new file mode 100644 index 0000000..25b6e1d --- /dev/null +++ b/src/frontend/bookshelfwizard/btinstallpagemodel.cpp @@ -0,0 +1,83 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +#include "btinstallpagemodel.h" + +#include "backend/drivers/cswordmoduleinfo.h" +#include "backend/managers/cswordbackend.h" + + +BtInstallPageModel::BtInstallPageModel(Grouping const & grouping, + QObject * const parent) + : BtBookshelfTreeModel(grouping, parent) +{ + setDefaultChecked(BtBookshelfTreeModel::UNCHECKED); + setCheckable(true); +} + +QVariant BtInstallPageModel::data(QModelIndex const & i, int role) const { + switch (role) { + case Qt::DisplayRole: + switch (i.column()) { + case 0: + return BtBookshelfTreeModel::data(i, role); + case 1: + if (CSwordModuleInfo * const m = + module(index(i.row(), 0, i.parent()))) + { + if (CSwordModuleInfo * imodule = + CSwordBackend::instance()->findModuleByName( + m->name())) + return imodule->config( + CSwordModuleInfo::ModuleVersion) + + " => " + + m->config(CSwordModuleInfo::ModuleVersion); + return m->config(CSwordModuleInfo::ModuleVersion); + } + break; + case 2: + if (CSwordModuleInfo * const m = + module(index(i.row(), 0, i.parent()))) + return m->config(CSwordModuleInfo::Description); + break; + default: + break; + } + break; + default: + if (i.column() == 0) + return BtBookshelfTreeModel::data(i, role); + break; + } + + return QVariant(); +} + +int BtInstallPageModel::columnCount(QModelIndex const & parent) const { + Q_UNUSED(parent); + return 3; +} + +QVariant BtInstallPageModel::headerData(int section, + Qt::Orientation orientation, + int role) const +{ + if (role == Qt::DisplayRole && orientation == Qt::Horizontal) { + switch (section) { + case 0: return tr("Work"); + case 1: return tr("Version"); + case 2: return tr("Description"); + default: break; + } + } + return QVariant(); +} diff --git a/src/frontend/bookshelfwizard/btinstallpagemodel.h b/src/frontend/bookshelfwizard/btinstallpagemodel.h new file mode 100644 index 0000000..6003c9b --- /dev/null +++ b/src/frontend/bookshelfwizard/btinstallpagemodel.h @@ -0,0 +1,38 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +#ifndef BTINSTALLPAGEMODEL_H +#define BTINSTALLPAGEMODEL_H + +#include "backend/bookshelfmodel/btbookshelftreemodel.h" + + +class BtInstallPageModel: public BtBookshelfTreeModel { + + Q_OBJECT + +public: /* Methods: */ + + BtInstallPageModel(Grouping const & grouping, + QObject * const parent = nullptr); + + QVariant data(QModelIndex const & index, + int role = Qt::DisplayRole) const final override; + int columnCount(QModelIndex const & parent = QModelIndex()) + const final override; + QVariant headerData(int section, + Qt::Orientation orientation, + int role = Qt::DisplayRole) const final override; + +}; /* class BtInstallPageModel */ + +#endif /* BTINSTALLPAGEMODEL_H */ diff --git a/src/frontend/bookshelfmanager/cswordsetupinstallsourcesdialog.cpp b/src/frontend/bookshelfwizard/cswordsetupinstallsourcesdialog.cpp index 646efab..c183cfa 100644 --- a/src/frontend/bookshelfmanager/cswordsetupinstallsourcesdialog.cpp +++ b/src/frontend/bookshelfwizard/cswordsetupinstallsourcesdialog.cpp @@ -2,14 +2,13 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ -#include "frontend/bookshelfmanager/cswordsetupinstallsourcesdialog.h" +#include "frontend/bookshelfwizard/cswordsetupinstallsourcesdialog.h" -#include <QSharedPointer> #include <QComboBox> #include <QDir> #include <QFileInfo> @@ -26,6 +25,9 @@ #include <QApplication> #include "backend/btinstallbackend.h" #include "frontend/messagedialog.h" +#include "util/btassert.h" +#include "util/btconnect.h" + const QString PROTO_FILE( QObject::tr("Local") ); //Local path const QString PROTO_FTP( QObject::tr("Remote FTP") ); //Remote path @@ -91,11 +93,12 @@ CSwordSetupInstallSourcesDialog::CSwordSetupInstallSourcesDialog(/*QWidget *pare QPushButton* getListButton = new QPushButton(tr("Get list..."), this); getListButton->setToolTip(tr("Download a list of sources from CrossWire server and add sources")); buttonBox->addButton(getListButton, QDialogButtonBox::ActionRole); - connect(getListButton, SIGNAL(clicked()), SLOT(slotGetListClicked())); + BT_CONNECT(getListButton, SIGNAL(clicked()), SLOT(slotGetListClicked())); mainLayout->addWidget(buttonBox); - connect(buttonBox, SIGNAL(accepted()), SLOT(slotOk())); - connect(buttonBox, SIGNAL(rejected()), SLOT(reject())); - connect( m_protocolCombo, SIGNAL( activated(int) ), this, SLOT( slotProtocolChanged() ) ); + BT_CONNECT(buttonBox, SIGNAL(accepted()), SLOT(slotOk())); + BT_CONNECT(buttonBox, SIGNAL(rejected()), SLOT(reject())); + BT_CONNECT(m_protocolCombo, SIGNAL(activated(int)), + this, SLOT(slotProtocolChanged())); } void CSwordSetupInstallSourcesDialog::slotOk() { @@ -108,7 +111,7 @@ void CSwordSetupInstallSourcesDialog::slotOk() { //BTInstallMgr iMgr; //sword::InstallSource is = BTInstallMgr::Tool::RemoteConfig::source( &iMgr, m_captionEdit->text() ); sword::InstallSource is = BtInstallBackend::source(m_captionEdit->text()); - if ( (QString)is.caption.c_str() == m_captionEdit->text() ) { //source already exists + if (is.caption.c_str() == m_captionEdit->text()) { // source already exists message::showInformation( this, tr( "Error" ), tr("A source with this caption already exists. Please provide a different caption.")); return; @@ -167,10 +170,12 @@ void CSwordSetupInstallSourcesDialog::slotGetListClicked() { m_progressDialog = new QProgressDialog("", tr("Cancel"), 0 , 100, this); m_progressDialog->setWindowTitle(tr("Downloading List")); m_progressDialog->setMinimumDuration(0); - connect(m_progressDialog, SIGNAL(canceled()), SLOT(slotRefreshCanceled())); + BT_CONNECT(m_progressDialog, SIGNAL(canceled()), + SLOT(slotRefreshCanceled())); m_currentInstallMgr = &iMgr; //for the progress dialog // connect this directly to the dialog setValue(int) if possible - connect(&iMgr, SIGNAL(percentCompleted(const int, const int)), SLOT(slotRefreshProgress(const int, const int))); + BT_CONNECT(&iMgr, SIGNAL(percentCompleted(const int, const int)), + SLOT(slotRefreshProgress(const int, const int))); m_progressDialog->show(); qApp->processEvents(); @@ -189,7 +194,7 @@ void CSwordSetupInstallSourcesDialog::slotGetListClicked() { qWarning("InstallMgr: getting remote list returned an error."); } delete m_progressDialog; - m_progressDialog = 0; + m_progressDialog = nullptr; } void CSwordSetupInstallSourcesDialog::slotRefreshProgress(const int, const int current) { @@ -203,7 +208,7 @@ void CSwordSetupInstallSourcesDialog::slotRefreshProgress(const int, const int c } void CSwordSetupInstallSourcesDialog::slotRefreshCanceled() { - Q_ASSERT(m_currentInstallMgr); + BT_ASSERT(m_currentInstallMgr); if (m_currentInstallMgr) { m_currentInstallMgr->terminate(); } diff --git a/src/frontend/bookshelfmanager/cswordsetupinstallsourcesdialog.h b/src/frontend/bookshelfwizard/cswordsetupinstallsourcesdialog.h index 20bf461..ed763e7 100644 --- a/src/frontend/bookshelfmanager/cswordsetupinstallsourcesdialog.h +++ b/src/frontend/bookshelfwizard/cswordsetupinstallsourcesdialog.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -25,7 +25,7 @@ class QLabel; class QLineEdit; class QProgressDialog; -class CSwordSetupInstallSourcesDialog : public QDialog { +class CSwordSetupInstallSourcesDialog final: public QDialog { Q_OBJECT public: diff --git a/src/frontend/btaboutdialog.cpp b/src/frontend/btaboutdialog.cpp index fd0a3c9..65d9b34 100644 --- a/src/frontend/btaboutdialog.cpp +++ b/src/frontend/btaboutdialog.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -18,7 +18,9 @@ #include <QTabWidget> #include <QTextStream> #include <QVBoxLayout> -#include <QWebView> +#include "frontend/btwebengineview.h" +#include "util/btconnect.h" +#include "util/bticons.h" #include "util/directory.h" // Sword includes: @@ -58,7 +60,7 @@ BtAboutDialog::BtAboutDialog(QWidget *parent, Qt::WindowFlags wflags) QWidget *top = new QWidget(this); QHBoxLayout *topLayout = new QHBoxLayout; m_iconLabel = new QLabel(this); - m_iconLabel->setPixmap(QIcon(util::directory::getIconDir().path() + "/bibletime.svg").pixmap(48)); + m_iconLabel->setPixmap(BtIcons::instance().icon_bibletime.pixmap(48)); topLayout->addWidget(m_iconLabel); m_versionLabel = new QLabel(this); QFont font = m_versionLabel->font(); @@ -82,8 +84,7 @@ BtAboutDialog::BtAboutDialog(QWidget *parent, Qt::WindowFlags wflags) mainLayout->addWidget(m_buttonBox); setLayout(mainLayout); - connect(m_buttonBox, SIGNAL(rejected()), - this, SLOT(reject())); + BT_CONNECT(m_buttonBox, SIGNAL(rejected()), this, SLOT(reject())); retranslateUi(); } @@ -98,11 +99,12 @@ void BtAboutDialog::resizeEvent(QResizeEvent* event) { } -void BtAboutDialog::initTab(QWebView *&tab) { - tab = new QWebView(this); +void BtAboutDialog::initTab(BtWebEngineView *&tab) { + tab = new BtWebEngineView(this); + BtWebEnginePage * page = new BtWebEnginePage(this); + tab->setPage(page); m_tabWidget->addTab(tab, ""); - tab->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks); - connect(tab, SIGNAL(linkClicked(QUrl)), this, SLOT(linkClicked(QUrl))); + BT_CONNECT(tab->btPage(), SIGNAL(linkClicked(QUrl)), this, SLOT(linkClicked(QUrl))); } void BtAboutDialog::retranslateUi() { @@ -123,11 +125,7 @@ void BtAboutDialog::retranslateBtTab() { QString content("<p>"); content += tr("BibleTime is an easy to use but powerful Bible study tool."); content += "</p><p>"; - content += tr("We are looking for developers and translators. If you would like to join " - "our team, please send an email to %1.") - .arg(MAKE_LINK_STATIC("mailto:info@bibletime.info", "info@bibletime.info")); - content += "</p><p>"; - content += tr("(c)1999-2014, The BibleTime Team"); + content += tr("(c)1999-2016, The BibleTime Team"); content += "</p><p>" MAKE_LINK_STATIC("http://www.bibletime.info", "www.bibletime.info") "</p>"; m_bibletimeTab->setHtml(MAKE_HTML(m_bibletimeTab, content)); @@ -171,6 +169,7 @@ void BtAboutDialog::retranslateContributorsTab() { MAKE_CONTR(content, "Andrus Raag", artist) MAKE_CONTR2(content, "Jaak Ristioja", tr("project manager"), developer) MAKE_CONTR(content, "Fred Saalbach", tr("documentation")) + MAKE_CONTR(content, "Erik Schanze", tr("documentation")) MAKE_CONTR(content, "Gary Sims", developer) MAKE_CONTR2(content, "Wolfgang Stradner", tr("tester"), tr("usability expert")) MAKE_CONTR(content, "Kang Sun", developer) @@ -217,10 +216,10 @@ void BtAboutDialog::retranslateContributorsTab() { "<li>Dmitry Yurevich</li>" "<li>Esteban Zeller</li>" "</ul><p>"; - content += tr("Some names may be missing, please email %1 if you notice errors or " - "omissions.").arg(MAKE_LINK_STATIC( - "mailto:bibletime-translations@lists.sourceforge.net", - "bibletime-translations@lists.sourceforge.net")); + content += tr("Some names may be missing, please file an issue at %1 if " + "you notice errors or omissions.").arg(MAKE_LINK_STATIC( + "https://github.com/bibletime/bibletime/issues", + "https://github.com/bibletime/bibletime/issues")); content += "</p>"; m_contributorsTab->setHtml(MAKE_HTML(m_contributorsTab, content)); diff --git a/src/frontend/btaboutdialog.h b/src/frontend/btaboutdialog.h index 132074a..b26409a 100644 --- a/src/frontend/btaboutdialog.h +++ b/src/frontend/btaboutdialog.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -15,21 +15,21 @@ #include <QDialog> class QDialogButtonBox; +class QLabel; class QTabWidget; class QUrl; -class QWebView; -class QLabel; +class BtWebEngineView; class BtAboutDialog: public QDialog { Q_OBJECT public: - BtAboutDialog(QWidget *parent = 0, Qt::WindowFlags wflags = Qt::Dialog); + BtAboutDialog(QWidget *parent = nullptr, Qt::WindowFlags wflags = Qt::Dialog); protected: - virtual void resizeEvent(QResizeEvent* event); + void resizeEvent(QResizeEvent* event) override; private: - void initTab(QWebView *&tab); + void initTab(BtWebEngineView *&tab); void retranslateUi(); void retranslateBtTab(); @@ -43,11 +43,11 @@ class BtAboutDialog: public QDialog { private: QTabWidget *m_tabWidget; - QWebView *m_bibletimeTab; - QWebView *m_contributorsTab; - QWebView *m_swordTab; - QWebView *m_qtTab; - QWebView *m_licenceTab; + BtWebEngineView *m_bibletimeTab; + BtWebEngineView *m_contributorsTab; + BtWebEngineView *m_swordTab; + BtWebEngineView *m_qtTab; + BtWebEngineView *m_licenceTab; QDialogButtonBox *m_buttonBox; QLabel *m_iconLabel; QLabel *m_versionLabel; diff --git a/src/frontend/btaboutmoduledialog.cpp b/src/frontend/btaboutmoduledialog.cpp index b8603b5..3d7cde3 100644 --- a/src/frontend/btaboutmoduledialog.cpp +++ b/src/frontend/btaboutmoduledialog.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -15,6 +15,7 @@ #include "backend/drivers/cswordmoduleinfo.h" #include "frontend/btaboutmoduledialog.h" #include "frontend/messagedialog.h" +#include "util/btconnect.h" BTAboutModuleDialog::BTAboutModuleDialog(const CSwordModuleInfo *moduleInfo, @@ -32,13 +33,12 @@ BTAboutModuleDialog::BTAboutModuleDialog(const CSwordModuleInfo *moduleInfo, vboxLayout->addWidget(m_textEdit); m_buttons = new QDialogButtonBox(QDialogButtonBox::Close, Qt::Horizontal, this); - QObject::connect(m_buttons, SIGNAL(rejected()), this, SLOT(reject())); + BT_CONNECT(m_buttons, SIGNAL(rejected()), this, SLOT(reject())); vboxLayout->addWidget(m_buttons); retranslateUi(); - connect(moduleInfo, SIGNAL(destroyed()), - this, SLOT(close())); + BT_CONNECT(moduleInfo, SIGNAL(destroyed()), this, SLOT(close())); } void BTAboutModuleDialog::retranslateUi() { diff --git a/src/frontend/btaboutmoduledialog.h b/src/frontend/btaboutmoduledialog.h index 05f78d1..e7a3f62 100644 --- a/src/frontend/btaboutmoduledialog.h +++ b/src/frontend/btaboutmoduledialog.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -29,8 +29,8 @@ class BTAboutModuleDialog: public QDialog { public: /* Methods: */ BTAboutModuleDialog(const CSwordModuleInfo *moduleInfo, - QWidget *parent = 0, - Qt::WindowFlags flags = 0); + QWidget *parent = nullptr, + Qt::WindowFlags flags = nullptr); protected: /* Methods: */ diff --git a/src/frontend/btbookshelfdockwidget.cpp b/src/frontend/btbookshelfdockwidget.cpp index 46ee023..78f3b42 100644 --- a/src/frontend/btbookshelfdockwidget.cpp +++ b/src/frontend/btbookshelfdockwidget.cpp @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -25,20 +25,21 @@ #include "frontend/btbookshelfview.h" #include "frontend/btbookshelfwidget.h" #include "frontend/messagedialog.h" +#include "util/btassert.h" +#include "util/btconnect.h" #include "util/cresmgr.h" -#include "util/geticon.h" namespace { const QString groupingOrderKey("GUI/MainWindow/Docks/Bookshelf/grouping"); } -BtBookshelfDockWidget *BtBookshelfDockWidget::m_instance = 0; +BtBookshelfDockWidget *BtBookshelfDockWidget::m_instance = nullptr; BtBookshelfDockWidget::BtBookshelfDockWidget(QWidget *parent, Qt::WindowFlags f) : QDockWidget(parent, f) { - Q_ASSERT(m_instance == 0); + BT_ASSERT(!m_instance); m_instance = this; setObjectName("BookshelfDock"); @@ -82,22 +83,29 @@ BtBookshelfDockWidget::BtBookshelfDockWidget(QWidget *parent, Qt::WindowFlags f) setWidget(m_stackedWidget); // Connect signals: - connect(m_bookshelfWidget->treeView(), SIGNAL(moduleActivated(CSwordModuleInfo*)), - this, SLOT(slotModuleActivated(CSwordModuleInfo*))); - connect(m_bookshelfWidget->treeView(), SIGNAL(moduleHovered(CSwordModuleInfo*)), - this, SIGNAL(moduleHovered(CSwordModuleInfo*))); - connect(m_treeModel, SIGNAL(moduleChecked(CSwordModuleInfo*, bool)), - this, SLOT(slotModuleChecked(CSwordModuleInfo*, bool))); - connect(m_treeModel, SIGNAL(groupingOrderChanged(BtBookshelfTreeModel::Grouping)), - this, SLOT(slotGroupingOrderChanged(const BtBookshelfTreeModel::Grouping&))); - connect(m_bookshelfWidget->showHideAction(), SIGNAL(toggled(bool)), - m_treeModel, SLOT(setCheckable(bool))); - connect(bookshelfModel, SIGNAL(rowsInserted(const QModelIndex&,int,int)), - this, SLOT(slotModulesChanged())); - connect(bookshelfModel, SIGNAL(rowsRemoved(const QModelIndex&,int,int)), - this, SLOT(slotModulesChanged())); - connect(m_installButton, SIGNAL(clicked()), - BibleTime::instance(), SLOT(slotSwordSetupDialog())); + BT_CONNECT(m_bookshelfWidget->treeView(), + SIGNAL(moduleActivated(CSwordModuleInfo *)), + this, SLOT(slotModuleActivated(CSwordModuleInfo *))); + BT_CONNECT(m_bookshelfWidget->treeView(), + SIGNAL(moduleHovered(CSwordModuleInfo *)), + this, SIGNAL(moduleHovered(CSwordModuleInfo *))); + BT_CONNECT(m_treeModel, SIGNAL(moduleChecked(CSwordModuleInfo *, bool)), + this, SLOT(slotModuleChecked(CSwordModuleInfo *, bool))); + BT_CONNECT(m_treeModel, + SIGNAL(groupingOrderChanged(BtBookshelfTreeModel::Grouping)), + this, + SLOT(slotGroupingOrderChanged( + BtBookshelfTreeModel::Grouping const &))); + BT_CONNECT(m_bookshelfWidget->showHideAction(), SIGNAL(toggled(bool)), + m_treeModel, SLOT(setCheckable(bool))); + BT_CONNECT(bookshelfModel, + SIGNAL(rowsInserted(QModelIndex const &, int, int)), + this, SLOT(slotModulesChanged())); + BT_CONNECT(bookshelfModel, + SIGNAL(rowsRemoved(QModelIndex const &, int, int)), + this, SLOT(slotModulesChanged())); + BT_CONNECT(m_installButton, SIGNAL(clicked()), + BibleTime::instance(), SLOT(slotBookshelfWizard())); retranslateUi(); } @@ -107,43 +115,43 @@ void BtBookshelfDockWidget::initMenus() { m_itemContextMenu = new QMenu(this); m_itemActionGroup = new QActionGroup(this); - connect(m_itemActionGroup, SIGNAL(triggered(QAction*)), - this, SLOT(slotItemActionTriggered(QAction*))); + BT_CONNECT(m_itemActionGroup, SIGNAL(triggered(QAction *)), + this, SLOT(slotItemActionTriggered(QAction *))); m_itemOpenAction = new QAction(this); m_itemActionGroup->addAction(m_itemOpenAction); m_itemContextMenu->addAction(m_itemOpenAction); m_itemSearchAction = new QAction(this); - m_itemSearchAction->setIcon(util::getIcon(RM::search::icon)); + m_itemSearchAction->setIcon(RM::search::icon()); m_itemActionGroup->addAction(m_itemSearchAction); m_itemContextMenu->addAction(m_itemSearchAction); m_itemEditMenu = new QMenu(this); - m_itemEditMenu->setIcon(util::getIcon(RM::editModuleMenu::icon)); + m_itemEditMenu->setIcon(RM::editModuleMenu::icon()); m_itemContextMenu->addMenu(m_itemEditMenu); m_itemEditPlainAction = new QAction(this); - m_itemEditPlainAction->setIcon(util::getIcon(RM::editModulePlain::icon)); + m_itemEditPlainAction->setIcon(RM::editModulePlain::icon()); m_itemActionGroup->addAction(m_itemEditPlainAction); m_itemEditMenu->addAction(m_itemEditPlainAction); m_itemEditHtmlAction = new QAction(this); - m_itemEditHtmlAction->setIcon(util::getIcon(RM::editModuleHTML::icon)); + m_itemEditHtmlAction->setIcon(RM::editModuleHTML::icon()); m_itemActionGroup->addAction(m_itemEditHtmlAction); m_itemEditMenu->addAction(m_itemEditHtmlAction); m_itemUnlockAction = new QAction(this); - m_itemUnlockAction->setIcon(util::getIcon(RM::unlockModule::icon)); + m_itemUnlockAction->setIcon(RM::unlockModule::icon()); m_itemActionGroup->addAction(m_itemUnlockAction); m_itemContextMenu->addAction(m_itemUnlockAction); m_itemAboutAction = new QAction(this); - m_itemAboutAction->setIcon(util::getIcon(RM::aboutModule::icon)); + m_itemAboutAction->setIcon(RM::aboutModule::icon()); m_itemActionGroup->addAction(m_itemAboutAction); m_itemContextMenu->addAction(m_itemAboutAction); - connect(m_itemContextMenu, SIGNAL(aboutToShow()), - this, SLOT(slotPrepareItemContextMenu())); + BT_CONNECT(m_itemContextMenu, SIGNAL(aboutToShow()), + this, SLOT(slotPrepareItemContextMenu())); } void BtBookshelfDockWidget::retranslateUi() { @@ -181,7 +189,7 @@ void BtBookshelfDockWidget::slotModuleActivated(CSwordModuleInfo *module) { if (BibleTime::moduleUnlock(module)) { // Re-initialize module pointer: module = CSwordBackend::instance()->findModuleByName(moduleName); - Q_ASSERT(module != 0); + BT_ASSERT(module); emit moduleOpenTriggered(module); } @@ -193,8 +201,10 @@ void BtBookshelfDockWidget::slotModuleChecked(CSwordModuleInfo *module, bool c) } void BtBookshelfDockWidget::slotItemActionTriggered(QAction *action) { - CSwordModuleInfo *module((CSwordModuleInfo*) m_itemContextMenu->property("BtModule").value<void*>()); - if (module == 0) return; + CSwordModuleInfo * const module = + static_cast<CSwordModuleInfo *>( + m_itemContextMenu->property("BtModule").value<void *>()); + if (module == nullptr) return; if (action == m_itemOpenAction) { emit moduleOpenTriggered(module); diff --git a/src/frontend/btbookshelfdockwidget.h b/src/frontend/btbookshelfdockwidget.h index fe415d7..a18b0a3 100644 --- a/src/frontend/btbookshelfdockwidget.h +++ b/src/frontend/btbookshelfdockwidget.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -29,7 +29,7 @@ class QStackedWidget; class BtBookshelfDockWidget: public QDockWidget { Q_OBJECT public: - BtBookshelfDockWidget(QWidget *parent = 0, Qt::WindowFlags f = 0); + BtBookshelfDockWidget(QWidget *parent = nullptr, Qt::WindowFlags f = nullptr); static inline BtBookshelfDockWidget *getInstance() { return m_instance; } diff --git a/src/frontend/btbookshelfgroupingmenu.cpp b/src/frontend/btbookshelfgroupingmenu.cpp index c456f80..e182990 100644 --- a/src/frontend/btbookshelfgroupingmenu.cpp +++ b/src/frontend/btbookshelfgroupingmenu.cpp @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -13,9 +13,10 @@ #include "frontend/btbookshelfgroupingmenu.h" #include "bibletimeapp.h" +#include "util/btassert.h" +#include "util/btconnect.h" #include "util/cresmgr.h" #include "util/directory.h" -#include "util/geticon.h" namespace { @@ -27,11 +28,11 @@ BtBookshelfTreeModel::Grouping groupingLang(true); BtBookshelfTreeModel::Grouping groupingLangCat(true); inline void initializeGroups() { - Q_ASSERT(groupingNone.empty()); + BT_ASSERT(groupingNone.empty()); groupingCat.append(BtBookshelfTreeModel::GROUP_CATEGORY); - Q_ASSERT(groupingCatLang.size() == 2); - Q_ASSERT(groupingCatLang.at(0) == BtBookshelfTreeModel::GROUP_CATEGORY); - Q_ASSERT(groupingCatLang.at(1) == BtBookshelfTreeModel::GROUP_LANGUAGE); + BT_ASSERT(groupingCatLang.size() == 2); + BT_ASSERT(groupingCatLang.at(0) == BtBookshelfTreeModel::GROUP_CATEGORY); + BT_ASSERT(groupingCatLang.at(1) == BtBookshelfTreeModel::GROUP_LANGUAGE); groupingLang.append(BtBookshelfTreeModel::GROUP_LANGUAGE); groupingLangCat.append(BtBookshelfTreeModel::GROUP_LANGUAGE); groupingLangCat.append(BtBookshelfTreeModel::GROUP_CATEGORY); @@ -39,27 +40,28 @@ inline void initializeGroups() { } inline void setActionRef(QAction *a, const BtBookshelfTreeModel::Grouping &g) { - a->setProperty("groupingPointer", QVariant::fromValue((void*) &g)); + a->setProperty("groupingPointer", + QVariant::fromValue( + const_cast<void *>(static_cast<void const *>(&g)))); } inline const BtBookshelfTreeModel::Grouping &getActionRef(const QAction *a) { - return *((const BtBookshelfTreeModel::Grouping*) a->property("groupingPointer").value<void*>()); + return *static_cast<BtBookshelfTreeModel::Grouping const *>( + a->property("groupingPointer").value<void *>()); } } // anonymous namespace void BtBookshelfGroupingMenu::initMenu(bool showNoGrouping) { - namespace RM = CResMgr::mainIndex; - if (!groupsInitialized) initializeGroups(); - setIcon(util::getIcon(RM::grouping::icon)); + setIcon(CResMgr::mainIndex::grouping::icon()); m_groupingActionGroup = new QActionGroup(this); m_groupingActionGroup->setExclusive(true); - connect(m_groupingActionGroup, SIGNAL(triggered(QAction*)), - this, SLOT(slotGroupingActionTriggered(QAction*))); + BT_CONNECT(m_groupingActionGroup, SIGNAL(triggered(QAction *)), + this, SLOT(slotGroupingActionTriggered(QAction *))); m_groupingCatLangAction = new QAction(this); m_groupingCatLangAction->setCheckable(true); @@ -92,7 +94,7 @@ void BtBookshelfGroupingMenu::initMenu(bool showNoGrouping) { m_groupingActionGroup->addAction(m_groupingNoneAction); addAction(m_groupingNoneAction); } else { - m_groupingNoneAction = 0; + m_groupingNoneAction = nullptr; } retranslateUi(); @@ -104,7 +106,7 @@ void BtBookshelfGroupingMenu::retranslateUi() { m_groupingLangCatAction->setText(tr("Language/Category")); m_groupingLangAction->setText(tr("Language")); - if (m_groupingNoneAction != 0) { + if (m_groupingNoneAction != nullptr) { m_groupingNoneAction->setText(tr("No grouping")); } } diff --git a/src/frontend/btbookshelfgroupingmenu.h b/src/frontend/btbookshelfgroupingmenu.h index f49c3c0..40e35f9 100644 --- a/src/frontend/btbookshelfgroupingmenu.h +++ b/src/frontend/btbookshelfgroupingmenu.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -24,11 +24,11 @@ class QActionGroup; class BtBookshelfGroupingMenu: public QMenu { Q_OBJECT public: - explicit inline BtBookshelfGroupingMenu(QWidget *parent = 0) + explicit inline BtBookshelfGroupingMenu(QWidget *parent = nullptr) : QMenu(parent) { initMenu(true); } explicit inline BtBookshelfGroupingMenu(bool showNoGrouping, - QWidget *parent = 0) + QWidget *parent = nullptr) : QMenu(parent) { initMenu(showNoGrouping); } signals: diff --git a/src/frontend/btbookshelfview.cpp b/src/frontend/btbookshelfview.cpp index 1a04eff..f6d3585 100644 --- a/src/frontend/btbookshelfview.cpp +++ b/src/frontend/btbookshelfview.cpp @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -16,6 +16,7 @@ #include <QMouseEvent> #include "backend/bookshelfmodel/btbookshelftreemodel.h" #include "backend/drivers/cswordmoduleinfo.h" +#include "util/btconnect.h" BtBookshelfView::BtBookshelfView(QWidget *parent) @@ -31,10 +32,10 @@ BtBookshelfView::BtBookshelfView(QWidget *parent) */ // setRootIsDecorated(false); - connect(this, SIGNAL(activated(QModelIndex)), - this, SLOT(slotItemActivated(QModelIndex))); - connect(this, SIGNAL(entered(QModelIndex)), - this, SLOT(slotItemHovered(QModelIndex))); + BT_CONNECT(this, SIGNAL(activated(QModelIndex)), + this, SLOT(slotItemActivated(QModelIndex))); + BT_CONNECT(this, SIGNAL(entered(QModelIndex)), + this, SLOT(slotItemHovered(QModelIndex))); } CSwordModuleInfo * BtBookshelfView::getModule(const QModelIndex & index) const { @@ -51,7 +52,7 @@ void BtBookshelfView::keyPressEvent(QKeyEvent *event) { CSwordModuleInfo *i(getModule(currentIndex())); QRect itemRect(visualRect(currentIndex())); QPoint p(viewport()->mapToGlobal(itemRect.bottomLeft())); - if (i == 0) { + if (i == nullptr) { emit contextMenuActivated(p); } else { @@ -64,7 +65,7 @@ void BtBookshelfView::keyPressEvent(QKeyEvent *event) { case Qt::Key_Enter: { QModelIndex i(currentIndex()); CSwordModuleInfo *m(getModule(i)); - if (m != 0) { + if (m != nullptr) { emit moduleActivated(m); } else { @@ -86,7 +87,7 @@ void BtBookshelfView::mousePressEvent(QMouseEvent *event) { setCurrentIndex(clickedItemIndex); } CSwordModuleInfo *i(getModule(clickedItemIndex)); - if (i == 0) { + if (i == nullptr) { emit contextMenuActivated(mapToGlobal(event->pos())); } else { @@ -101,7 +102,7 @@ void BtBookshelfView::mousePressEvent(QMouseEvent *event) { void BtBookshelfView::slotItemActivated(const QModelIndex &index) { CSwordModuleInfo *i(getModule(index)); - if (i != 0) { + if (i != nullptr) { emit moduleActivated(i); } } diff --git a/src/frontend/btbookshelfview.h b/src/frontend/btbookshelfview.h index f957785..a9c5dd7 100644 --- a/src/frontend/btbookshelfview.h +++ b/src/frontend/btbookshelfview.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -21,7 +21,7 @@ class CSwordModuleInfo; class BtBookshelfView: public QTreeView { Q_OBJECT public: - BtBookshelfView(QWidget *parent = 0); + BtBookshelfView(QWidget *parent = nullptr); CSwordModuleInfo *getModule(const QModelIndex &index) const; @@ -33,8 +33,8 @@ class BtBookshelfView: public QTreeView { void moduleHovered(CSwordModuleInfo *item); protected: - void keyPressEvent(QKeyEvent *event); - void mousePressEvent(QMouseEvent *event); + void keyPressEvent(QKeyEvent *event) override; + void mousePressEvent(QMouseEvent *event) override; protected slots: void slotItemActivated(const QModelIndex &index); diff --git a/src/frontend/btbookshelfwidget.cpp b/src/frontend/btbookshelfwidget.cpp index 2ce812e..819cabe 100644 --- a/src/frontend/btbookshelfwidget.cpp +++ b/src/frontend/btbookshelfwidget.cpp @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -25,22 +25,21 @@ #include <QVBoxLayout> #include "backend/bookshelfmodel/btbookshelffiltermodel.h" #include "bibletimeapp.h" -#include "frontend/bookshelfmanager/installpage/btinstallmodulechooserdialogmodel.h" -#include "frontend/bookshelfmanager/removepage/btremovepagetreemodel.h" #include "frontend/btbookshelfdockwidget.h" #include "frontend/btbookshelfgroupingmenu.h" #include "frontend/btbookshelfview.h" +#include "util/btassert.h" +#include "util/btconnect.h" #include "util/cresmgr.h" #include "util/directory.h" -#include "util/geticon.h" BtBookshelfWidget::BtBookshelfWidget(QWidget *parent, Qt::WindowFlags flags) : QWidget(parent, flags) - , m_sourceModel(0) - , m_treeModel(0) - , m_leftCornerWidget(0) - , m_rightCornerWidget(0) + , m_sourceModel(nullptr) + , m_treeModel(nullptr) + , m_leftCornerWidget(nullptr) + , m_rightCornerWidget(nullptr) { // Setup post-filter: m_postFilterModel = new BtBookshelfFilterModel(this); @@ -55,27 +54,28 @@ BtBookshelfWidget::BtBookshelfWidget(QWidget *parent, Qt::WindowFlags flags) retranslateUi(); - connect(m_nameFilterEdit, SIGNAL(textEdited(QString)), - m_postFilterModel, SLOT(setNameFilterFixedString(QString))); - connect(m_treeView, SIGNAL(contextMenuActivated(QPoint)), - this, SLOT(slotShowContextMenu(QPoint))); - connect(m_treeView, SIGNAL(moduleContextMenuActivated(CSwordModuleInfo*, QPoint)), - this, SLOT(slotShowItemContextMenu(CSwordModuleInfo*, QPoint))); + BT_CONNECT(m_nameFilterEdit, SIGNAL(textEdited(QString)), + m_postFilterModel, SLOT(setNameFilterFixedString(QString))); + BT_CONNECT(m_treeView, SIGNAL(contextMenuActivated(QPoint)), + this, SLOT(slotShowContextMenu(QPoint))); + BT_CONNECT(m_treeView, + SIGNAL(moduleContextMenuActivated(CSwordModuleInfo *, QPoint)), + this, SLOT(slotShowItemContextMenu(CSwordModuleInfo *, QPoint))); } void BtBookshelfWidget::setSourceModel(QAbstractItemModel *model) { - Q_ASSERT(model != 0); + BT_ASSERT(model); m_sourceModel = model; - if (m_treeModel != 0) { + if (m_treeModel != nullptr) { m_treeModel->setSourceModel(model); } } void BtBookshelfWidget::setTreeModel(BtBookshelfTreeModel *model) { - Q_ASSERT(model != 0); - Q_ASSERT(m_treeModel == 0); + BT_ASSERT(model); + BT_ASSERT(!m_treeModel); m_treeModel = model; - if (m_sourceModel != 0) { + if (m_sourceModel != nullptr) { model->setSourceModel(m_sourceModel); } m_postFilterModel->setSourceModel(model); @@ -94,23 +94,22 @@ void BtBookshelfWidget::setRightCornerWidget(QWidget *w) { } void BtBookshelfWidget::initActions() { - namespace RM = CResMgr::mainIndex; - m_showHideAction = new QAction(this); - m_showHideAction->setIcon(util::getIcon("layer-visible-on.svg")); + m_showHideAction->setIcon(CResMgr::mainIndex::showHide::icon()); m_showHideAction->setCheckable(true); - connect(m_showHideAction, SIGNAL(toggled(bool)), - m_postFilterModel, SLOT(setShowHidden(bool))); + BT_CONNECT(m_showHideAction, SIGNAL(toggled(bool)), + m_postFilterModel, SLOT(setShowHidden(bool))); } void BtBookshelfWidget::initMenus() { - namespace DU = util::directory; - namespace RM = CResMgr::mainIndex; - // Grouping menu: m_groupingMenu = new BtBookshelfGroupingMenu(this); - connect(m_groupingMenu, SIGNAL(signalGroupingOrderChanged(BtBookshelfTreeModel::Grouping)), - this, SLOT(slotGroupingActionTriggered(BtBookshelfTreeModel::Grouping))); + BT_CONNECT(m_groupingMenu, + SIGNAL(signalGroupingOrderChanged( + BtBookshelfTreeModel::Grouping)), + this, + SLOT(slotGroupingActionTriggered( + BtBookshelfTreeModel::Grouping))); // Context menu m_contextMenu = new QMenu(this); @@ -162,7 +161,7 @@ void BtBookshelfWidget::retranslateUi() { } bool BtBookshelfWidget::eventFilter(QObject *object, QEvent *event) { - Q_ASSERT(object == m_nameFilterEdit); + BT_ASSERT(object == m_nameFilterEdit); if (event->type() == QEvent::KeyPress) { QKeyEvent *e = static_cast<QKeyEvent*>(event); switch (e->key()) { @@ -190,8 +189,10 @@ void BtBookshelfWidget::slotShowContextMenu(const QPoint &pos) { void BtBookshelfWidget::slotShowItemContextMenu(CSwordModuleInfo *module, const QPoint &pos) { - if (m_itemContextMenu != 0) { - m_itemContextMenu->setProperty("BtModule", qVariantFromValue((void*) module)); + if (m_itemContextMenu != nullptr) { + m_itemContextMenu->setProperty("BtModule", + qVariantFromValue( + static_cast<void *>(module))); m_itemContextMenu->popup(pos); } else { m_itemContextMenu = m_contextMenu; diff --git a/src/frontend/btbookshelfwidget.h b/src/frontend/btbookshelfwidget.h index 7811b5c..09ab5aa 100644 --- a/src/frontend/btbookshelfwidget.h +++ b/src/frontend/btbookshelfwidget.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -34,7 +34,7 @@ class QToolButton; class BtBookshelfWidget: public QWidget { Q_OBJECT public: - explicit BtBookshelfWidget(QWidget *parent = 0, Qt::WindowFlags flags = 0); + explicit BtBookshelfWidget(QWidget *parent = nullptr, Qt::WindowFlags flags = nullptr); void setSourceModel(QAbstractItemModel *model); @@ -68,7 +68,7 @@ class BtBookshelfWidget: public QWidget { inline void setContextMenu(QMenu *newMenu) { m_contextMenu = newMenu; } inline void setItemContextMenu(QMenu *newMenu) { m_itemContextMenu = newMenu; } - bool eventFilter(QObject *object, QEvent *event); + bool eventFilter(QObject *object, QEvent *event) override; protected: void initActions(); diff --git a/src/frontend/btcentralwidget.cpp b/src/frontend/btcentralwidget.cpp index 04615c3..e812ad5 100644 --- a/src/frontend/btcentralwidget.cpp +++ b/src/frontend/btcentralwidget.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ diff --git a/src/frontend/btcentralwidget.h b/src/frontend/btcentralwidget.h index 3ef9002..a136b4c 100644 --- a/src/frontend/btcentralwidget.h +++ b/src/frontend/btcentralwidget.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ diff --git a/src/frontend/btmenuview.cpp b/src/frontend/btmenuview.cpp index 919602b..d422de2 100644 --- a/src/frontend/btmenuview.cpp +++ b/src/frontend/btmenuview.cpp @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -13,15 +13,17 @@ #include "frontend/btmenuview.h" #include <QActionGroup> +#include "util/btassert.h" +#include "util/btconnect.h" BtMenuView::BtMenuView(QWidget *parent) - : QMenu(parent), m_model(0), m_parentIndex(QModelIndex()), m_actions(0) + : QMenu(parent), m_model(nullptr), m_parentIndex(QModelIndex()), m_actions(nullptr) { - connect(this, SIGNAL(aboutToShow()), - this, SLOT(slotAboutToShow())); - connect(this, SIGNAL(triggered(QAction*)), - this, SLOT(slotActionTriggered(QAction*))); + BT_CONNECT(this, SIGNAL(aboutToShow()), + this, SLOT(slotAboutToShow())); + BT_CONNECT(this, SIGNAL(triggered(QAction*)), + this, SLOT(slotActionTriggered(QAction*))); } BtMenuView::~BtMenuView() { @@ -31,7 +33,7 @@ BtMenuView::~BtMenuView() { void BtMenuView::setModel(QAbstractItemModel *model) { m_model = model; delete m_actions; - m_actions = 0; + m_actions = nullptr; m_indexMap.clear(); m_parentIndex = QModelIndex(); } @@ -91,10 +93,10 @@ QAction *BtMenuView::newAction(QMenu *parentMenu, const QModelIndex &itemIndex) // Set checked: QVariant checkData(m_model->data(itemIndex, Qt::CheckStateRole)); bool ok; - Qt::CheckState state = (Qt::CheckState) checkData.toInt(&ok); - if (ok) { + Qt::CheckState const state = + static_cast<Qt::CheckState>(checkData.toInt(&ok)); + if (ok) childAction->setChecked(state == Qt::Checked); - } return childAction; } @@ -137,8 +139,8 @@ QMenu *BtMenuView::newMenu(QMenu *parentMenu, const QModelIndex &itemIndex) { } void BtMenuView::buildMenu(QMenu *parentMenu, const QModelIndex &parentIndex) { - Q_ASSERT(m_model != 0); - Q_ASSERT(m_actions != 0); + BT_ASSERT(m_model); + BT_ASSERT(m_actions); int children = m_model->rowCount(parentIndex); for (int i = 0; i < children; i++) { @@ -147,7 +149,7 @@ void BtMenuView::buildMenu(QMenu *parentMenu, const QModelIndex &parentIndex) { if (m_model->rowCount(childIndex) > 0) { QMenu *childMenu = newMenu(parentMenu, childIndex); - if (childMenu != 0) { + if (childMenu != nullptr) { // Add the child menu and populate it: parentMenu->addMenu(childMenu); buildMenu(childMenu, childIndex); @@ -155,7 +157,7 @@ void BtMenuView::buildMenu(QMenu *parentMenu, const QModelIndex &parentIndex) { } else { QAction *childAction = newAction(parentMenu, childIndex); - if (childAction != 0) { + if (childAction != nullptr) { // Map index m_indexMap.insert(childAction, childIndex); @@ -175,12 +177,12 @@ void BtMenuView::slotAboutToShow() { // to remove the menus here. removeMenus(); delete m_actions; - m_actions = 0; + m_actions = nullptr; m_indexMap.clear(); preBuildMenu(); - if (m_model != 0) { + if (m_model != nullptr) { m_actions = new QActionGroup(this); buildMenu(this, m_parentIndex); diff --git a/src/frontend/btmenuview.h b/src/frontend/btmenuview.h index 39b56f6..d2e1100 100644 --- a/src/frontend/btmenuview.h +++ b/src/frontend/btmenuview.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -44,7 +44,7 @@ class QActionGroup; class BtMenuView: public QMenu { Q_OBJECT public: - BtMenuView(QWidget *parent = 0); + BtMenuView(QWidget *parent = nullptr); virtual ~BtMenuView(); /** diff --git a/src/frontend/btmodulechooserdialog.cpp b/src/frontend/btmodulechooserdialog.cpp index e6ed79f..bc7a63a 100644 --- a/src/frontend/btmodulechooserdialog.cpp +++ b/src/frontend/btmodulechooserdialog.cpp @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -20,6 +20,7 @@ #include "frontend/btbookshelfview.h" #include "frontend/btbookshelfwidget.h" #include "frontend/messagedialog.h" +#include "util/btconnect.h" #include "util/tool.h" @@ -32,16 +33,15 @@ BtModuleChooserDialog::BtModuleChooserDialog(QWidget *parent, Qt::WindowFlags fl mainLayout->addWidget(m_captionLabel); m_bookshelfWidget = new BtBookshelfWidget(this); - connect(m_bookshelfWidget->treeView(), SIGNAL(moduleActivated(CSwordModuleInfo*)), - this, SLOT(slotModuleAbout(CSwordModuleInfo*))); + BT_CONNECT(m_bookshelfWidget->treeView(), + SIGNAL(moduleActivated(CSwordModuleInfo *)), + this, SLOT(slotModuleAbout(CSwordModuleInfo *))); mainLayout->addWidget(m_bookshelfWidget); m_buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok, Qt::Horizontal, this); - connect(m_buttonBox, SIGNAL(accepted()), - this, SLOT(accept())); - connect(m_buttonBox, SIGNAL(rejected()), - this, SLOT(reject())); + BT_CONNECT(m_buttonBox, SIGNAL(accepted()), this, SLOT(accept())); + BT_CONNECT(m_buttonBox, SIGNAL(rejected()), this, SLOT(reject())); mainLayout->addWidget(m_buttonBox); setLayout(mainLayout); diff --git a/src/frontend/btmodulechooserdialog.h b/src/frontend/btmodulechooserdialog.h index 685ac48..f2ab06b 100644 --- a/src/frontend/btmodulechooserdialog.h +++ b/src/frontend/btmodulechooserdialog.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -26,7 +26,7 @@ class BtModuleChooserDialog : public QDialog { Q_OBJECT protected: - explicit BtModuleChooserDialog(QWidget *parent = 0, Qt::WindowFlags flags = 0); + explicit BtModuleChooserDialog(QWidget *parent = nullptr, Qt::WindowFlags flags = nullptr); void retranslateUi(); diff --git a/src/frontend/btmoduleindexdialog.cpp b/src/frontend/btmoduleindexdialog.cpp index 2714ea7..8b70541 100644 --- a/src/frontend/btmoduleindexdialog.cpp +++ b/src/frontend/btmoduleindexdialog.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -12,43 +12,40 @@ #include <QApplication> #include <QMutexLocker> #include "backend/managers/cswordbackend.h" +#include "frontend/messagedialog.h" +#include "util/btassert.h" +#include "util/btconnect.h" -QMutex BtModuleIndexDialog::m_singleInstanceMutex; - -bool BtModuleIndexDialog::indexAllModules( - const QList<const CSwordModuleInfo*> &modules) +bool BtModuleIndexDialog::indexAllModules(const QList<CSwordModuleInfo *> &modules) { - QMutexLocker lock(&m_singleInstanceMutex); + static QMutex mutex; + QMutexLocker lock(&mutex); if (modules.empty()) return true; BtModuleIndexDialog d(modules.size()); d.show(); d.raise(); - return d.indexAllModules2(modules); + return d.indexAllModulesPrivate(modules); } BtModuleIndexDialog::BtModuleIndexDialog(int numModules) : QProgressDialog(tr("Preparing to index modules..."), tr("Cancel"), 0, - numModules * 100, 0), + numModules * 100, nullptr), m_currentModuleIndex(0) { setWindowTitle(tr("Creating indices")); setModal(true); } -bool BtModuleIndexDialog::indexAllModules2( - const QList<const CSwordModuleInfo*> &modules) +bool BtModuleIndexDialog::indexAllModulesPrivate(const QList<CSwordModuleInfo*> &modules) { bool success = true; - QList<CSwordModuleInfo *> indexedModules; - Q_FOREACH(const CSwordModuleInfo *cm, modules) { - Q_ASSERT(!cm->hasIndex()); - - /// \warning const_cast - CSwordModuleInfo *m = const_cast<CSwordModuleInfo*>(cm); + QList <CSwordModuleInfo*> indexedModules; + Q_FOREACH(CSwordModuleInfo * const m, modules) { + BT_ASSERT(!m->hasIndex()); /* Keep track of created indices to delete them on failure or @@ -56,17 +53,23 @@ bool BtModuleIndexDialog::indexAllModules2( */ indexedModules.append(m); - connect(this, SIGNAL(canceled()), - m, SLOT(cancelIndexing())); - connect(m, SIGNAL(indexingFinished()), - this, SLOT(slotFinished())); - connect(m, SIGNAL(indexingProgress(int)), - this, SLOT(slotModuleProgress(int))); + BT_CONNECT(this, SIGNAL(canceled()), m, SLOT(cancelIndexing())); + BT_CONNECT(m, SIGNAL(indexingFinished()), this, SLOT(slotFinished())); + BT_CONNECT(m, SIGNAL(indexingProgress(int)), + this, SLOT(slotModuleProgress(int))); // Single module indexing blocks until finished: setLabelText(tr("Creating index for work: %1").arg(m->name())); - if (!m->buildIndex()) success = false; + try { + m->buildIndex(); + } catch (...) { + message::showWarning(this, + tr("Indexing aborted"), + tr("An internal error occurred while building " + "the index.")); + success = false; + } m_currentModuleIndex++; @@ -82,14 +85,11 @@ bool BtModuleIndexDialog::indexAllModules2( if (!success) break; } - if (!success) { + if (!success) // Delete already created indices: - Q_FOREACH(CSwordModuleInfo *m, indexedModules) { - if (m->hasIndex()) { + Q_FOREACH(CSwordModuleInfo * const m, indexedModules) + if (m->hasIndex()) m->deleteIndex(); - } - } - } return success; } diff --git a/src/frontend/btmoduleindexdialog.h b/src/frontend/btmoduleindexdialog.h index 8b794f9..581a838 100644 --- a/src/frontend/btmoduleindexdialog.h +++ b/src/frontend/btmoduleindexdialog.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -14,8 +14,6 @@ #include <QProgressDialog> -#include <QMutex> - class CSwordModuleInfo; @@ -26,7 +24,6 @@ class CSwordModuleInfo; */ class BtModuleIndexDialog: public QProgressDialog { Q_OBJECT - Q_DISABLE_COPY(BtModuleIndexDialog) public: /* Methods: */ /** @@ -39,7 +36,7 @@ class BtModuleIndexDialog: public QProgressDialog { \pre all given modules are unindexed \returns whether the indexing was finished successfully. */ - static bool indexAllModules(const QList<const CSwordModuleInfo*> &modules); + static bool indexAllModules(const QList<CSwordModuleInfo*> &modules); private: /* Methods: */ BtModuleIndexDialog(int numModules); @@ -53,14 +50,13 @@ class BtModuleIndexDialog: public QProgressDialog { \pre all given modules are unindexed \returns whether the indexing was finished successfully. */ - bool indexAllModules2(const QList<const CSwordModuleInfo*> &modules); + bool indexAllModulesPrivate(const QList<CSwordModuleInfo*> &modules); private slots: void slotModuleProgress(int percentage); void slotFinished(); private: /* Fields: */ - static QMutex m_singleInstanceMutex; int m_currentModuleIndex; }; diff --git a/src/frontend/btopenworkaction.cpp b/src/frontend/btopenworkaction.cpp index a398412..2a5aae3 100644 --- a/src/frontend/btopenworkaction.cpp +++ b/src/frontend/btopenworkaction.cpp @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -16,13 +16,17 @@ #include "backend/managers/cswordbackend.h" #include "bibletimeapp.h" #include "frontend/btbookshelfgroupingmenu.h" -#include "util/geticon.h" +#include "util/btconnect.h" +#include "util/cresmgr.h" BtOpenWorkActionMenu::BtOpenWorkActionMenu(const QString &groupingConfigKey, QWidget *parent) - : BtMenuView(parent), m_treeModel(0), m_postFilterModel(0), - m_groupingConfigKey(groupingConfigKey) + : BtMenuView(parent) + , m_treeModel(nullptr) + , m_postFilterModel(nullptr) + , m_groupingMenu(nullptr) + , m_groupingConfigKey(groupingConfigKey) { // Setup models: m_treeModel = new BtBookshelfTreeModel(groupingConfigKey, this); @@ -30,8 +34,8 @@ BtOpenWorkActionMenu::BtOpenWorkActionMenu(const QString &groupingConfigKey, m_postFilterModel->setSourceModel(m_treeModel); setModel(m_postFilterModel); - connect(this, SIGNAL(triggered(QModelIndex)), - this, SLOT(slotIndexTriggered(QModelIndex))); + BT_CONNECT(this, SIGNAL(triggered(QModelIndex)), + this, SLOT(slotIndexTriggered(QModelIndex))); } void BtOpenWorkActionMenu::setSourceModel(QAbstractItemModel *model) { @@ -39,6 +43,8 @@ void BtOpenWorkActionMenu::setSourceModel(QAbstractItemModel *model) { } void BtOpenWorkActionMenu::retranslateUi() { + if (!m_groupingMenu) + return; m_groupingMenu->setTitle(tr("&Grouping order")); m_groupingMenu->setStatusTip(tr("Sets the grouping order for the items in " "this menu.")); @@ -48,8 +54,12 @@ void BtOpenWorkActionMenu::postBuildMenu() { addSeparator(); m_groupingMenu = new BtBookshelfGroupingMenu(false, this); - connect(m_groupingMenu, SIGNAL(signalGroupingOrderChanged(BtBookshelfTreeModel::Grouping)), - this, SLOT(slotGroupingActionTriggered(BtBookshelfTreeModel::Grouping))); + BT_CONNECT(m_groupingMenu, + SIGNAL(signalGroupingOrderChanged( + BtBookshelfTreeModel::Grouping)), + this, + SLOT(slotGroupingActionTriggered( + BtBookshelfTreeModel::Grouping))); retranslateUi(); addMenu(m_groupingMenu); @@ -60,7 +70,7 @@ void BtOpenWorkActionMenu::slotIndexTriggered(const QModelIndex &index) { CSwordModuleInfo *i; i = static_cast<CSwordModuleInfo *>(model()->data(index, MPR).value<void*>()); - if (i != 0) { + if (i != nullptr) { emit triggered(i); } } @@ -78,21 +88,21 @@ BtOpenWorkAction::BtOpenWorkAction(const QString &groupingConfigKey, m_menu->setSourceModel(CSwordBackend::instance()->model()); setMenu(m_menu); - setIcon(util::getIcon("folder-open.svg")); + setIcon(CResMgr::mainWindow::icon_openAction()); retranslateUi(); slotModelChanged(); BtBookshelfFilterModel *filterModel = m_menu->postFilterModel(); - connect(m_menu, SIGNAL(triggered(CSwordModuleInfo*)), - this, SIGNAL(triggered(CSwordModuleInfo*))); - connect(filterModel, SIGNAL(layoutChanged()), - this, SLOT(slotModelChanged())); - connect(filterModel, SIGNAL(modelReset()), - this, SLOT(slotModelChanged())); - connect(filterModel, SIGNAL(rowsInserted(QModelIndex, int, int)), - this, SLOT(slotModelChanged())); - connect(filterModel, SIGNAL(rowsRemoved(QModelIndex, int, int)), - this, SLOT(slotModelChanged())); + BT_CONNECT(m_menu, SIGNAL(triggered(CSwordModuleInfo *)), + this, SIGNAL(triggered(CSwordModuleInfo *))); + BT_CONNECT(filterModel, SIGNAL(layoutChanged()), + this, SLOT(slotModelChanged())); + BT_CONNECT(filterModel, SIGNAL(modelReset()), + this, SLOT(slotModelChanged())); + BT_CONNECT(filterModel, SIGNAL(rowsInserted(QModelIndex, int, int)), + this, SLOT(slotModelChanged())); + BT_CONNECT(filterModel, SIGNAL(rowsRemoved(QModelIndex, int, int)), + this, SLOT(slotModelChanged())); } BtOpenWorkAction::~BtOpenWorkAction() { diff --git a/src/frontend/btopenworkaction.h b/src/frontend/btopenworkaction.h index 1ca8379..0e6b38a 100644 --- a/src/frontend/btopenworkaction.h +++ b/src/frontend/btopenworkaction.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -28,7 +28,7 @@ class BtOpenWorkActionMenu: public BtMenuView { Q_OBJECT public: BtOpenWorkActionMenu(const QString &groupingConfigKey, - QWidget *parent = 0); + QWidget *parent = nullptr); void setSourceModel(QAbstractItemModel *model); inline QAbstractItemModel *sourceModel() const { return m_treeModel->sourceModel(); } @@ -41,8 +41,7 @@ class BtOpenWorkActionMenu: public BtMenuView { private: void retranslateUi(); - /* Reimplemented from BtMenuView. */ - virtual void postBuildMenu(); + void postBuildMenu() override; private slots: void slotIndexTriggered(const QModelIndex &index); @@ -62,7 +61,7 @@ class BtOpenWorkAction: public QAction { Q_OBJECT public: explicit BtOpenWorkAction(const QString &groupingConfigKey, - QObject *parent = 0); + QObject *parent = nullptr); ~BtOpenWorkAction(); signals: diff --git a/src/frontend/btprinter.cpp b/src/frontend/btprinter.cpp new file mode 100644 index 0000000..ae718e6 --- /dev/null +++ b/src/frontend/btprinter.cpp @@ -0,0 +1,116 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#include "btprinter.h" +#include "bibletime.h" +#include <QPrintDialog> +#include <QPrinter> +#include <QTextEdit> +#include "../util/btassert.h" +#include "backend/config/btconfig.h" +#include "backend/keys/cswordversekey.h" +#include "backend/managers/cdisplaytemplatemgr.h" + + +namespace { + +inline FilterOptions mangleFilterOptions(FilterOptions fo) { + fo.footnotes = false; + fo.scriptureReferences = false; + fo.strongNumbers = false; + fo.morphTags = false; + fo.headings = false; + return fo; +} + +} // anonymous namespace + +BtPrinter::BtPrinter(DisplayOptions const & displayOptions, + FilterOptions const & filterOptions, + QObject * const parent) + : QObject{parent} + , CDisplayRendering{displayOptions, mangleFilterOptions(filterOptions)} +{} + +void BtPrinter::printKeyTree(KeyTree const & tree) { + QTextEdit htmlPage; + htmlPage.setHtml(renderKeyTree(tree)); + + QPrinter printer; + QPrintDialog printDialog(&printer); + if (printDialog.exec() == QDialog::Accepted) + htmlPage.print(&printer); +} + +QString BtPrinter::entryLink(KeyTreeItem const & item, + CSwordModuleInfo const * module) +{ + BT_ASSERT(module); + if (module->type() != CSwordModuleInfo::Bible) + return item.key(); + + CSwordVerseKey vk(module); + vk.setKey(item.key()); + switch (item.settings().keyRenderingFace) { + case KeyTreeItem::Settings::CompleteShort: + return QString::fromUtf8(vk.getShortText()); + + case KeyTreeItem::Settings::CompleteLong: + return vk.key(); + + case KeyTreeItem::Settings::NoKey: + return QString::null; + + case KeyTreeItem::Settings::SimpleKey: // fall through: + default: + return QString::number(vk.getVerse()); + } +} + +QString BtPrinter::renderEntry(KeyTreeItem const & i, CSwordKey * key) { + Q_UNUSED(key); + BT_ASSERT(dynamic_cast<BtPrinter::KeyTreeItem const *>(&i)); + BtPrinter::KeyTreeItem const * const printItem = + static_cast<BtPrinter::KeyTreeItem const *>(&i); + + if (printItem->hasAlternativeContent()) { + QString ret = + QString::fromLatin1("<div class=\"entry\"><div class=\"" + "rangeheading\">%1</div>").arg( + printItem->getAlternativeContent()); + if (!i.childList()->isEmpty()) + Q_FOREACH (const KeyTreeItem * const c, *i.childList()) + ret.append(CDisplayRendering::renderEntry(*c)); + ret.append("</div>"); + return ret; + } + return CDisplayRendering::renderEntry(i); +} + +QString BtPrinter::finishText(QString const & text, KeyTree const & tree) { + BtConstModuleList const modules = collectModules(tree); + BT_ASSERT(!modules.empty()); + + CLanguageMgr::Language const * const lang = modules.first()->language(); + BT_ASSERT(lang); + + CDisplayTemplateMgr::Settings settings; + //settings.modules = modules; + settings.pageCSS_ID = "printer"; + if (modules.count() == 1 && lang->isValid()) + settings.langAbbrev = lang->abbrev(); + + if (modules.count() == 1) + settings.textDirection = modules.first()->textDirection(); + + return CDisplayTemplateMgr::instance()->fillTemplate( + CDisplayTemplateMgr::activeTemplateName(), + text, + settings); +} diff --git a/src/frontend/btprinter.h b/src/frontend/btprinter.h new file mode 100644 index 0000000..8307881 --- /dev/null +++ b/src/frontend/btprinter.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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef BTPRINTER_H +#define BTPRINTER_H + +#include <QObject> +#include "backend/rendering/cdisplayrendering.h" + +#include "backend/managers/cswordbackend.h" + + +/** \brief Manages the print item queue and printing. */ +class BtPrinter final: public QObject, public Rendering::CDisplayRendering { + + Q_OBJECT + +public: /* Methods: */ + + BtPrinter(DisplayOptions const & displayOptions, + FilterOptions const & filterOptions, + QObject * const parent = nullptr); + + void printKeyTree(KeyTree const &); + +private: /* Methods: */ + + QString entryLink(KeyTreeItem const & item, + CSwordModuleInfo const * module) override; + + QString renderEntry(KeyTreeItem const & item, + CSwordKey * const key = nullptr) override; + QString finishText(QString const & text, KeyTree const & tree) override; + +}; + +#endif /* BTPRINTER_H */ diff --git a/src/frontend/btwebenginepage.cpp b/src/frontend/btwebenginepage.cpp new file mode 100644 index 0000000..e2fd666 --- /dev/null +++ b/src/frontend/btwebenginepage.cpp @@ -0,0 +1,95 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +// This class encapsulates most differences between QWebPage and QWebEnginePage +// Javascript issues are handled in BtHtmlReadDisplay + +#include "btwebenginepage.h" +#include "btwebengineview.h" + +#include "frontend/display/bthtmljsobject.h" +#include "util/directory.h" + +#include <QDebug> +#include <QPainter> +#include <QPrinter> +#ifdef USEWEBENGINE +#include <QWebChannel> +#else +#include <QWebPage> +#endif + +#ifdef USEWEBENGINE + +BtWebEnginePage::BtWebEnginePage(QObject *parent) + :QWebEnginePage(parent), + m_webChannel(new QWebChannel(this)) { + + setWebChannel(m_webChannel); +} + +bool BtWebEnginePage::acceptNavigationRequest( + const QUrl& url, NavigationType /*type*/, bool /*isMainFrame*/) { + emit linkClicked(url); + return false; +} + +void BtWebEnginePage::addJavaScriptObject(const QString &name, QObject *object) { + object->setObjectName(name); + m_webChannel->registerObject(name, object); +} + +void BtWebEnginePage::selectAll() { + triggerAction(QWebEnginePage::SelectAll); +} + +void BtWebEnginePage::print(QPrinter *printer) { + QPainter painter; + painter.begin(printer); + BtWebEngineView *btWebEngineView = btView(); + btWebEngineView->render(&painter); + painter.end(); +} + +void BtWebEnginePage::javaScriptConsoleMessage( + JavaScriptConsoleMessageLevel /*level*/, + const QString & message, int /*lineNumber*/, + const QString & /*sourceID*/) { + qWarning() << "javascript console :" << message; +} + +#else + +BtWebEnginePage::BtWebEnginePage(QObject *parent) + :QWebPage(parent) { + settings()->setAttribute(QWebSettings::JavascriptEnabled, true); +} + +void BtWebEnginePage::addJavaScriptObject(const QString &name, QObject *object) { + object->setObjectName(name); + mainFrame()->addToJavaScriptWindowObject(object->objectName(), object); +} + +void BtWebEnginePage::selectAll() { + triggerAction(QWebPage::SelectAll); +} + +void BtWebEnginePage::print(QPrinter *printer) { + mainFrame()->print(printer); +} + +void BtWebEnginePage::setHtml(const QString& text) { + // TODO - test +} + +#endif + +BtWebEngineView * BtWebEnginePage::btView() const { + return qobject_cast<BtWebEngineView*>(view()); +} diff --git a/src/frontend/btwebenginepage.h b/src/frontend/btwebenginepage.h new file mode 100644 index 0000000..ad2a9f8 --- /dev/null +++ b/src/frontend/btwebenginepage.h @@ -0,0 +1,69 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef BTWEBENGINEPAGE_H +#define BTWEBENGINEPAGE_H + +#ifdef USEWEBENGINE +#include <QWebEnginePage> +#else +#include <QWebPage> +#include <QWebFrame> +#endif +#include <QUrl> +#include <QObject> + +class QPrinter; +class QWidget; +class QWebChannel; +class BtWebEngineView; + + +#ifdef USEWEBENGINE +class BtWebEnginePage : public QWebEnginePage { +#else +class BtWebEnginePage : public QWebPage { +#endif + + Q_OBJECT + +public: + BtWebEnginePage(QObject *parent = 0); + + void addJavaScriptObject(const QString &name, QObject *object); + BtWebEngineView * btView() const; + void print(QPrinter* printer); + void selectAll(); + +#ifdef USEWEBENGINE +signals: + void linkClicked(const QUrl& url); + +protected: + virtual bool acceptNavigationRequest( + const QUrl& url, NavigationType type, bool isMainFrame); + + void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, + const QString & message, int lineNumber, + const QString & sourceID); + +private: + + QWebChannel *m_webChannel; + +#else + + void setHtml(const QString& text); + +#endif +}; + +#endif diff --git a/src/frontend/btwebengineview.cpp b/src/frontend/btwebengineview.cpp new file mode 100644 index 0000000..57d0f8f --- /dev/null +++ b/src/frontend/btwebengineview.cpp @@ -0,0 +1,62 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#include "btwebengineview.h" +#include "btwebenginepage.h" + +// This class encapsulates differences between QWebView and QWebEngineView + +#ifdef USEWEBENGINE +BtWebEngineView::BtWebEngineView(QWidget *parent) + : QWebEngineView(parent) { +} +#else +BtWebEngineView::BtWebEngineView(QWidget *parent) + : QWebView(parent) { +} +#endif + +BtWebEnginePage * BtWebEngineView::btPage() const { + return qobject_cast<BtWebEnginePage*>(page()); +} + +void BtWebEngineView::findTextHighlight(const QString& text, bool caseSensitive) { +#ifdef USEWEBENGINE + QWebEnginePage::FindFlags options; + if (caseSensitive) + options |= QWebEnginePage::FindCaseSensitively; + QWebEngineView::findText("", options); // clear old highlight + QWebEngineView::findText(text, options); +#else + QWebPage::FindFlags options = QWebPage::HighlightAllOccurrences; + if (caseSensitive) + options |= QWebPage::FindCaseSensitively; + QWebView::findText("", options); // clear old highlight + QWebView::findText(text, options); + +#endif +} + +void BtWebEngineView::findText(const QString& text, bool caseSensitive, bool backward) { +#ifdef USEWEBENGINE + QWebEnginePage::FindFlags options; + if (backward) + options |= QWebEnginePage::FindBackward; + if (caseSensitive) + options |= QWebEnginePage::FindCaseSensitively; + QWebEngineView::findText(text, options); +#else + QWebPage::FindFlags options = QWebPage::FindWrapsAroundDocument; + if (backward) + options |= QWebPage::FindBackward; + if (caseSensitive) + options |= QWebPage::FindCaseSensitively; + QWebView::findText(text, options); +#endif +} diff --git a/src/frontend/btwebengineview.h b/src/frontend/btwebengineview.h new file mode 100644 index 0000000..75f52b5 --- /dev/null +++ b/src/frontend/btwebengineview.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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef BTWEBENGINEVIEW_H +#define BTWEBENGINEVIEW_H + +#include "frontend/btwebenginepage.h" + +#ifdef USEWEBENGINE +#include <QWebEngineView> +#else +#include <QWebView> +#endif + +class BtWebEnginePage; + +#ifdef USEWEBENGINE +class BtWebEngineView : public QWebEngineView { +#else +class BtWebEngineView : public QWebView { +#endif + + Q_OBJECT + +public: + BtWebEngineView(QWidget *parent = 0); + + BtWebEnginePage * btPage() const; + + void findTextHighlight(const QString& text, bool caseSensitive); + void findText(const QString& text, bool caseSensitive, bool backwards); +}; + +#endif + + + diff --git a/src/frontend/cdragdrop.h b/src/frontend/cdragdrop.h index 869d2fb..296373c 100644 --- a/src/frontend/cdragdrop.h +++ b/src/frontend/cdragdrop.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -72,7 +72,7 @@ class BTMimeData: public QMimeData { public: /* Types: */ /** Type for bookmark item list. Usage: BTMimeData::ItemList. */ - typedef QList<BookmarkItem> ItemList; + using ItemList = QList<BookmarkItem>; public: /* Methods: */ diff --git a/src/frontend/cexportmanager.cpp b/src/frontend/cexportmanager.cpp index e7546ba..5d00ca7 100644 --- a/src/frontend/cexportmanager.cpp +++ b/src/frontend/cexportmanager.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -23,7 +23,8 @@ #include "backend/rendering/centrydisplay.h" #include "backend/rendering/chtmlexportrendering.h" #include "backend/rendering/cplaintextexportrendering.h" -#include "frontend/cprinter.h" +#include "frontend/btprinter.h" +#include "util/btassert.h" #include "util/tool.h" // Sword includes: @@ -32,22 +33,34 @@ using namespace Rendering; -using namespace Printing; -CExportManager::CExportManager(const bool showProgress, - const QString &progressLabel, - const FilterOptions &filterOptions, - const DisplayOptions &displayOptions) +using KTI = CTextRendering::KeyTreeItem; + + +namespace { + +QTextCodec * getCodec(CExportManager::Format const format) { + if (format == CExportManager::HTML) + return QTextCodec::codecForName("UTF-8"); + return QTextCodec::codecForLocale(); +} + +} // anonymous namespace + +CExportManager::CExportManager(bool const showProgress, + QString const & progressLabel, + FilterOptions const & filterOptions, + DisplayOptions const & displayOptions) { m_filterOptions = filterOptions; m_displayOptions = displayOptions; if (showProgress) { - m_progressDialog = new QProgressDialog(0, Qt::Dialog); + m_progressDialog = new QProgressDialog{nullptr, Qt::Dialog}; m_progressDialog->setWindowTitle("BibleTime"); m_progressDialog->setLabelText(progressLabel); } else { - m_progressDialog = 0; + m_progressDialog = nullptr; } } @@ -55,396 +68,367 @@ CExportManager::~CExportManager() { delete m_progressDialog; } -bool CExportManager::saveKey(CSwordKey* key, const Format format, const bool addText) { - if (!key) { - return false; - } - if (!key->module()) { +bool CExportManager::saveKey(CSwordKey const * const key, + Format const format, + bool const addText) +{ + if (!key || !key->module()) return false; - } - const QString filename = getSaveFileName(format); - if (filename.isEmpty()) { + QString const filename = getSaveFileName(format); + if (filename.isEmpty()) return false; - } - - CTextRendering * render = newRenderer(format, addText); QString text; - - QList<const CSwordModuleInfo*> modules; - modules.append(key->module()); - - CSwordVerseKey *vk = dynamic_cast<CSwordVerseKey*>(key); - if (vk && vk->isBoundSet()) { - text = render->renderKeyRange( QString::fromUtf8(vk->getLowerBound()), QString::fromUtf8(vk->getUpperBound()), modules ); - } - else { //no range supported - text = render->renderSingleKey(key->key(), modules); + { + BtConstModuleList modules; + modules.append(key->module()); + CSwordVerseKey const * const vk = + dynamic_cast<CSwordVerseKey const *>(key); + auto const render = newRenderer(format, addText); + if (vk && vk->isBoundSet()) { + text = render->renderKeyRange( + QString::fromUtf8(vk->getLowerBound()), + QString::fromUtf8(vk->getUpperBound()), + modules); + } else { // no range supported + text = render->renderSingleKey(key->key(), modules); + } } - delete render; - - util::tool::savePlainFile(filename, text, false, - (format == HTML) - ? QTextCodec::codecForName("UTF-8") - : QTextCodec::codecForLocale()); + util::tool::savePlainFile(filename, text, false, getCodec(format)); return true; } -bool CExportManager::saveKeyList(const sword::ListKey & l, - const CSwordModuleInfo *module, - Format format, - bool addText) +bool CExportManager::saveKeyList(sword::ListKey const & l, + CSwordModuleInfo const * module, + Format const format, + bool const addText) { if (!l.getCount()) return false; - const QString filename = getSaveFileName(format); - if (filename.isEmpty()) { + QString const filename = getSaveFileName(format); + if (filename.isEmpty()) return false; - } CTextRendering::KeyTree tree; /// \todo Verify that items in tree are properly freed. setProgressRange(l.getCount()); - CTextRendering::KeyTreeItem::Settings itemSettings; + KTI::Settings itemSettings; itemSettings.highlight = false; sword::ListKey list(l); list.setPosition(sword::TOP); - while (!list.popError() && !progressWasCancelled()) { - tree.append( new CTextRendering::KeyTreeItem(QString::fromLocal8Bit((const char*)list) , module, itemSettings) ); + while (!list.popError()) { + if (progressWasCancelled()) + return false; + tree.append(new KTI(QString::fromLocal8Bit(list.getText()), + module, + itemSettings)); incProgress(); - list.increment(); } - CTextRendering * render = newRenderer(format, addText); - const QString text = render->renderKeyTree(tree); - delete render; - - if (!progressWasCancelled()) { - util::tool::savePlainFile(filename, text, false, (format == HTML) ? QTextCodec::codecForName("UTF-8") : QTextCodec::codecForLocale() ); - closeProgressDialog(); - return true; - } - return false; + QString const text = newRenderer(format, addText)->renderKeyTree(tree); + util::tool::savePlainFile(filename, text, false, getCodec(format)); + closeProgressDialog(); + return true; } -bool CExportManager::saveKeyList(const QList<CSwordKey*> &list, - Format format, - bool addText) +bool CExportManager::saveKeyList(QList<CSwordKey *> const & list, + Format const format, + bool const addText) { - if (!list.count()) + if (list.empty()) return false; const QString filename = getSaveFileName(format); - if (filename.isEmpty()) { + if (filename.isEmpty()) return false; - } CTextRendering::KeyTree tree; /// \todo Verify that items in tree are properly freed. - setProgressRange(list.count()); - CTextRendering::KeyTreeItem::Settings itemSettings; + KTI::Settings itemSettings; itemSettings.highlight = false; - QListIterator<CSwordKey*> it(list); - while (it.hasNext() && !progressWasCancelled()) { - CSwordKey* k = it.next(); - tree.append( new CTextRendering::KeyTreeItem(k->key(), k->module(), itemSettings) ); + setProgressRange(list.count()); + for (CSwordKey const * const k : list) { + if (progressWasCancelled()) + return false; + tree.append(new KTI(k->key(), k->module(), itemSettings)); incProgress(); }; - CTextRendering * render = newRenderer(format, addText); - const QString text = render->renderKeyTree(tree); - delete render; - - if (!progressWasCancelled()) { - util::tool::savePlainFile(filename, text, false, (format == HTML) ? QTextCodec::codecForName("UTF-8") : QTextCodec::codecForLocale() ); - closeProgressDialog(); - return true; - } - return false; + QString const text = newRenderer(format, addText)->renderKeyTree(tree); + util::tool::savePlainFile(filename, text, false, getCodec(format)); + closeProgressDialog(); + return true; } -bool CExportManager::copyKey(CSwordKey* key, const Format format, const bool addText) { +namespace { + +template <typename Arg> inline void copyToClipboard(Arg && arg) +{ QApplication::clipboard()->setText(std::forward<Arg>(arg)); } + +} // anonymous namespace + +bool CExportManager::copyKey(CSwordKey const * const key, + Format const format, + bool const addText) +{ if (!key || !key->module()) return false; QString text; - QList<const CSwordModuleInfo*> modules; + BtConstModuleList modules; modules.append(key->module()); - CTextRendering * render = newRenderer(format, addText); - CSwordVerseKey * vk = dynamic_cast<CSwordVerseKey*>(key); - if (vk && vk->isBoundSet()) { - text = render->renderKeyRange( - QString::fromUtf8(vk->getLowerBound()), - QString::fromUtf8(vk->getUpperBound()), - modules - ); - } - else { //no range supported - text = render->renderSingleKey(key->key(), modules); + { + auto const render = newRenderer(format, addText); + CSwordVerseKey const * const vk = + dynamic_cast<CSwordVerseKey const *>(key); + if (vk && vk->isBoundSet()) { + text = render->renderKeyRange( + QString::fromUtf8(vk->getLowerBound()), + QString::fromUtf8(vk->getUpperBound()), + modules + ); + } else { // no range supported + text = render->renderSingleKey(key->key(), modules); + } } - delete render; - - QApplication::clipboard()->setText(text); + copyToClipboard(text); return true; } -bool CExportManager::copyKeyList(const sword::ListKey &l, - const CSwordModuleInfo *module, - Format format, - bool addText) +bool CExportManager::copyKeyList(sword::ListKey const & l, + CSwordModuleInfo const * const module, + Format const format, + bool const addText) { sword::ListKey list = l; if (!list.getCount()) return false; CTextRendering::KeyTree tree; /// \todo Verify that items in tree are properly freed. - CTextRendering::KeyTreeItem::Settings itemSettings; + KTI::Settings itemSettings; itemSettings.highlight = false; list.setPosition(sword::TOP); - while (!list.popError() && !progressWasCancelled()) { - tree.append( new CTextRendering::KeyTreeItem(QString::fromLocal8Bit((const char*)list) , module, itemSettings) ); - + while (!list.popError()) { + if (progressWasCancelled()) + return false; + tree.append(new KTI(QString::fromLocal8Bit(list.getText()), + module, + itemSettings)); list.increment(); } - CTextRendering * render = newRenderer(format, addText); - const QString text = render->renderKeyTree(tree); - delete render; - QApplication::clipboard()->setText(text); + copyToClipboard(newRenderer(format, addText)->renderKeyTree(tree)); + closeProgressDialog(); return true; } -bool CExportManager::copyKeyList(const QList<CSwordKey*> &list, - Format format, - bool addText) +bool CExportManager::copyKeyList(QList<CSwordKey *> const & list, + Format const format, + bool const addText) { - if (!list.count()) + if (list.empty()) return false; - CTextRendering::KeyTree tree; /// \todo Verify that items in tree are properly freed. - - CTextRendering::KeyTreeItem::Settings itemSettings; + KTI::Settings itemSettings; itemSettings.highlight = false; - QListIterator<CSwordKey*> it(list); - while (it.hasNext() && !progressWasCancelled()) { - CSwordKey* k = it.next(); - tree.append( new CTextRendering::KeyTreeItem(k->key(), k->module(), itemSettings) ); + setProgressRange(list.count()); + for (CSwordKey const * const k : list) { + if (progressWasCancelled()) + return false; + tree.append(new KTI(k->key(), k->module(), itemSettings)); incProgress(); }; - CTextRendering * render = newRenderer(format, addText); - const QString text = render->renderKeyTree(tree); - delete render; - - QApplication::clipboard()->setText(text); - if (!progressWasCancelled()) { - closeProgressDialog(); - } + copyToClipboard(newRenderer(format, addText)->renderKeyTree(tree)); + closeProgressDialog(); return true; } -bool CExportManager::printKeyList(const sword::ListKey & list, - const CSwordModuleInfo *module, - const DisplayOptions &displayOptions, - const FilterOptions &filterOptions) -{ - CPrinter::KeyTreeItem::Settings settings; - CPrinter::KeyTree tree; /// \todo Verify that items in tree are properly freed. +namespace { - setProgressRange(list.getCount()); - for (int i=0; i< list.getCount(); i++) { - const sword::SWKey* swKey = list.getElement(i); - const sword::VerseKey* vKey = dynamic_cast<const sword::VerseKey*>(swKey); - if (vKey != 0) { - QString startKey = vKey->getText(); - tree.append(new CTextRendering::KeyTreeItem(startKey, - startKey, - module, - settings)); - } - else { - QString key = swKey->getText(); - tree.append(new CTextRendering::KeyTreeItem(key, - key, - module, - settings)); - } - incProgress(); - if (progressWasCancelled()) - break; - } +struct PrintSettings: BtPrinter::KeyTreeItem::Settings { + PrintSettings(DisplayOptions const & displayOptions) + : BtPrinter::KeyTreeItem::Settings{ + false, + displayOptions.verseNumbers ? Settings::SimpleKey : Settings::NoKey} + {} - if (!progressWasCancelled()) { - CPrinter * printer = new CPrinter(0, displayOptions, filterOptions); - printer->printKeyTree(tree); - delete printer; - closeProgressDialog(); - return true; - } +}; - return false; -} +} // anonymous namespace -bool CExportManager::printKey(const CSwordModuleInfo *module, - const QString &startKey, - const QString &stopKey, - const DisplayOptions &displayOptions, - const FilterOptions &filterOptions) +bool CExportManager::printKey(CSwordKey const * const key, + DisplayOptions const & displayOptions, + FilterOptions const & filterOptions) { - CPrinter::KeyTreeItem::Settings settings; - settings.keyRenderingFace = - displayOptions.verseNumbers - ? CPrinter::KeyTreeItem::Settings::SimpleKey - : CPrinter::KeyTreeItem::Settings::NoKey; - - CPrinter::KeyTree tree; /// \todo Verify that items in tree are properly freed. - if (startKey != stopKey) { - tree.append( new CPrinter::KeyTreeItem(startKey, stopKey, module, settings) ); - } - else { - tree.append( new CPrinter::KeyTreeItem(startKey, module, settings) ); - } - - CPrinter * printer = new CPrinter(0, displayOptions, filterOptions); - printer->printKeyTree(tree); - delete printer; + PrintSettings settings{displayOptions}; + BtPrinter::KeyTree tree; /// \todo Verify that items in tree are properly freed. + tree.append(new BtPrinter::KeyTreeItem(key->key(), key->module(), settings)); + BtPrinter{displayOptions, filterOptions}.printKeyTree(tree); return true; } -bool CExportManager::printKey(const CSwordKey *key, - const DisplayOptions &displayOptions, - const FilterOptions &filterOptions) +bool CExportManager::printKey(CSwordModuleInfo const * const module, + QString const & startKey, + QString const & stopKey, + DisplayOptions const & displayOptions, + FilterOptions const & filterOptions) { - CPrinter::KeyTreeItem::Settings settings; - settings.keyRenderingFace = - displayOptions.verseNumbers - ? CPrinter::KeyTreeItem::Settings::SimpleKey - : CPrinter::KeyTreeItem::Settings::NoKey; - - CPrinter::KeyTree tree; /// \todo Verify that items in tree are properly freed. - tree.append( new CPrinter::KeyTreeItem(key->key(), key->module(), settings) ); - - CPrinter * printer = new CPrinter(0, displayOptions, filterOptions); - printer->printKeyTree(tree); - delete printer; + PrintSettings settings{displayOptions}; + BtPrinter::KeyTree tree; /// \todo Verify that items in tree are properly freed. + if (startKey != stopKey) { + tree.append(new BtPrinter::KeyTreeItem(startKey, stopKey, module, settings)); + } else { + tree.append(new BtPrinter::KeyTreeItem(startKey, module, settings)); + } + BtPrinter{displayOptions, filterOptions}.printKeyTree(tree); return true; } -bool CExportManager::printByHyperlink(const QString &hyperlink, - const DisplayOptions &displayOptions, - const FilterOptions &filterOptions) +bool CExportManager::printByHyperlink(QString const & hyperlink, + DisplayOptions const & displayOptions, + FilterOptions const & filterOptions) { QString moduleName; QString keyName; ReferenceManager::Type type; - ReferenceManager::decodeHyperlink(hyperlink, moduleName, keyName, type); - if (moduleName.isEmpty()) { + if (moduleName.isEmpty()) moduleName = ReferenceManager::preferredModule(type); - } - CPrinter::KeyTree tree; /// \todo Verify that items in tree are properly freed. - CPrinter::KeyTreeItem::Settings settings; - settings.keyRenderingFace = - displayOptions.verseNumbers - ? CPrinter::KeyTreeItem::Settings::SimpleKey - : CPrinter::KeyTreeItem::Settings::NoKey; - - CSwordModuleInfo* module = CSwordBackend::instance()->findModuleByName(moduleName); - Q_ASSERT(module); - - if (module) { - //check if we have a range of entries or a single one - if ((module->type() == CSwordModuleInfo::Bible) || (module->type() == CSwordModuleInfo::Commentary)) { - sword::ListKey verses = sword::VerseKey().parseVerseList((const char*)keyName.toUtf8(), "Genesis 1:1", true); - - for (int i = 0; i < verses.getCount(); i++) { - sword::VerseKey* element = dynamic_cast<sword::VerseKey*>(verses.getElement(i)); - if (element) { - const QString startKey = QString::fromUtf8(element->getLowerBound().getText()); - const QString stopKey = QString::fromUtf8(element->getUpperBound().getText()); - - tree.append( new CPrinter::KeyTreeItem(startKey, stopKey, module, settings) ); - } - else if (verses.getElement(i)) { - const QString key = QString::fromUtf8(verses.getElement(i)->getText()); - - tree.append( new CPrinter::KeyTreeItem(key, module, settings) ); - } + BtPrinter::KeyTree tree; /// \todo Verify that items in tree are properly freed. + PrintSettings settings{displayOptions}; + CSwordModuleInfo const * module = + CSwordBackend::instance()->findModuleByName(moduleName); + BT_ASSERT(module); + //check if we have a range of entries or a single one + if ((module->type() == CSwordModuleInfo::Bible) + || (module->type() == CSwordModuleInfo::Commentary)) + { + sword::ListKey const verses = + sword::VerseKey().parseVerseList( + keyName.toUtf8().constData(), + "Genesis 1:1", + true); + + for (int i = 0; i < verses.getCount(); i++) { + if (sword::VerseKey const * const element = + dynamic_cast<sword::VerseKey const *>(verses.getElement(i))) + { + tree.append( + new BtPrinter::KeyTreeItem( + QString::fromUtf8( + element->getLowerBound().getText()), + QString::fromUtf8( + element->getUpperBound().getText()), + module, + settings) ); + } else if (verses.getElement(i)) { + tree.append( + new BtPrinter::KeyTreeItem( + QString::fromUtf8(verses.getElement(i)->getText()), + module, + settings) ); } } - else { - tree.append( new CPrinter::KeyTreeItem(keyName, module, settings) ); - } + } else { + tree.append(new BtPrinter::KeyTreeItem(keyName, module, settings)); } - - CPrinter * printer = new CPrinter(0, displayOptions, filterOptions); - printer->printKeyTree(tree); - delete printer; + BtPrinter{displayOptions, filterOptions}.printKeyTree(tree); return true; } -bool CExportManager::printKeyList(const QStringList &list, - const CSwordModuleInfo *module, - const DisplayOptions &displayOptions, - const FilterOptions &filterOptions) +bool CExportManager::printKeyList(sword::ListKey const & list, + CSwordModuleInfo const * const module, + DisplayOptions const & displayOptions, + FilterOptions const & filterOptions) { - CPrinter::KeyTreeItem::Settings settings; - settings.keyRenderingFace = - displayOptions.verseNumbers - ? CPrinter::KeyTreeItem::Settings::SimpleKey - : CPrinter::KeyTreeItem::Settings::NoKey; - - CPrinter::KeyTree tree; /// \todo Verify that items in tree are properly freed. - setProgressRange(list.count()); + if (!list.getCount()) + return false; + PrintSettings settings{displayOptions}; + BtPrinter::KeyTree tree; /// \todo Verify that items in tree are properly freed. - const QStringList::const_iterator end = list.constEnd(); - for (QStringList::const_iterator it = list.constBegin(); (it != end) && !progressWasCancelled(); ++it) { - tree.append( new CPrinter::KeyTreeItem(*it, module, settings) ); + setProgressRange(list.getCount()); + for (int i = 0; i < list.getCount(); i++) { + if (progressWasCancelled()) + return false; + sword::SWKey const * const swKey = list.getElement(i); + if (sword::VerseKey const * const vKey = + dynamic_cast<const sword::VerseKey*>(swKey)) + { + QString const startKey = vKey->getText(); + tree.append(new KTI(startKey, startKey, module, settings)); + } else { + QString const key = swKey->getText(); + tree.append(new KTI(key, key, module, settings)); + } incProgress(); } + BtPrinter{displayOptions, filterOptions}.printKeyTree(tree); + closeProgressDialog(); + return true; +} +bool CExportManager::printKeyList(QStringList const & list, + CSwordModuleInfo const * const module, + DisplayOptions const & displayOptions, + FilterOptions const & filterOptions) +{ + if (list.empty()) + return false; - if (!progressWasCancelled()) { - CPrinter * printer = new CPrinter(0, displayOptions, filterOptions); - printer->printKeyTree(tree); - delete printer; - closeProgressDialog(); - return true; - } + PrintSettings settings{displayOptions}; + BtPrinter::KeyTree tree; /// \todo Verify that items in tree are properly freed. - return false; + setProgressRange(list.count()); + for (QString const & key: list) { + if (progressWasCancelled()) + return false; + tree.append(new BtPrinter::KeyTreeItem(key, module, settings)); + incProgress(); + } + BtPrinter{displayOptions, filterOptions}.printKeyTree(tree); + closeProgressDialog(); + return true; } /** Returns the string for the filedialogs to show the correct files. */ const QString CExportManager::filterString( const Format format ) { + QString const allFiles = QObject::tr("All files") + QString(" (*.*)"); switch (format) { case HTML: - return QObject::tr("HTML files") + QString(" (*.html *.htm);;") + QObject::tr("All files") + QString(" (*.*)"); + return allFiles + QObject::tr("HTML files") + + QString(" (*.html *.htm);;"); case Text: - return QObject::tr("Text files") + QString(" (*.txt);;") + QObject::tr("All files") + QString(" (*.*)"); + return allFiles + QObject::tr("Text files") + QString(" (*.txt);;"); default: - return QObject::tr("All files") + QString(" (*.*)"); + return allFiles; } } /** Returns a filename to save a file. */ const QString CExportManager::getSaveFileName(const Format format) { - return QFileDialog::getSaveFileName(0, QObject::tr("Save file"), "", filterString(format), 0); + return QFileDialog::getSaveFileName(nullptr, + QObject::tr("Save file"), + "", + filterString(format), + nullptr); } -CTextRendering * CExportManager::newRenderer(const Format format, bool addText) { +std::unique_ptr<CTextRendering> CExportManager::newRenderer(Format const format, + bool const addText) +{ FilterOptions filterOptions = m_filterOptions; filterOptions.footnotes = false; filterOptions.strongNumbers = false; @@ -453,15 +437,18 @@ CTextRendering * CExportManager::newRenderer(const Format format, bool addText) filterOptions.scriptureReferences = false; filterOptions.textualVariants = false; - if (format == HTML) { - return new CHTMLExportRendering(addText, m_displayOptions, filterOptions); - } else { - Q_ASSERT(format == Text); - return new CPlainTextExportRendering(addText, m_displayOptions, filterOptions); - } + using R = std::unique_ptr<CTextRendering>; + BT_ASSERT((format == Text) || (format == HTML)); + if (format == HTML) + return R{new CHTMLExportRendering(addText, + m_displayOptions, + filterOptions)}; + return R{new CPlainTextExportRendering(addText, + m_displayOptions, + filterOptions)}; } -void CExportManager::setProgressRange( const int items ) { +void CExportManager::setProgressRange(int const items) { if (!m_progressDialog) return; @@ -480,10 +467,7 @@ void CExportManager::incProgress() { } bool CExportManager::progressWasCancelled() { - if (m_progressDialog) - return m_progressDialog->wasCanceled(); - - return false; + return m_progressDialog ? m_progressDialog->wasCanceled() : false; } /** Closes the progress dialog immediatly. */ @@ -492,6 +476,5 @@ void CExportManager::closeProgressDialog() { m_progressDialog->close(); m_progressDialog->reset(); } - qApp->processEvents(); //do not lock the GUI! } diff --git a/src/frontend/cexportmanager.h b/src/frontend/cexportmanager.h index a222ac8..5286477 100644 --- a/src/frontend/cexportmanager.h +++ b/src/frontend/cexportmanager.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -12,10 +12,12 @@ #ifndef CEXPORTMANAGER_H #define CEXPORTMANAGER_H +#include <memory> #include <QList> #include <QString> +#include "backend/btglobal.h" #include "backend/config/btconfig.h" -#include "btglobal.h" + class CSwordKey; class CSwordModuleInfo; @@ -25,111 +27,108 @@ namespace Rendering { class CTextRendering; } -/** Contains the functions to export text to disk, clipboard or printer. - * @author The BibleTime team - */ class CExportManager { - public: - /** The format the export actions should have - */ - enum Format { - HTML, - Text - }; - - CExportManager(const bool showProgress = true, - const QString &progressLabel = QString::null, - const FilterOptions &filterOptions = btConfig().getFilterOptions(), - const DisplayOptions &displayOptions = btConfig().getDisplayOptions()); - ~CExportManager(); - - bool saveKey(CSwordKey* key, const Format format, const bool addText); - - bool saveKeyList(const sword::ListKey &list, - const CSwordModuleInfo *module, - Format format, - bool addText); - - bool saveKeyList(const QList<CSwordKey*> &list, - Format format, - const bool addText ); - - bool copyKey(CSwordKey* key, const Format format, const bool addText); - - bool copyKeyList(const sword::ListKey &list, - const CSwordModuleInfo *module, - Format format, - bool addText); - - bool copyKeyList(const QList<CSwordKey*> &list, - Format format, - bool addText); - - bool printKey(const CSwordKey *key, - const DisplayOptions &displayOptions, - const FilterOptions &filterOptions); - - bool printKey(const CSwordModuleInfo *module, - const QString &startKey, - const QString &stopKey, - const DisplayOptions &displayOptions, - const FilterOptions &filterOptions); - - /** - Prints a key using the hyperlink created by CReferenceManager. - */ - bool printByHyperlink(const QString &hyperlink, - const DisplayOptions &displayOptions, - const FilterOptions &filterOptions); - - bool printKeyList(const sword::ListKey &list, - const CSwordModuleInfo *module, - const DisplayOptions &displayOptions, - const FilterOptions &filterOptions); - - bool printKeyList(const QStringList &list, - const CSwordModuleInfo *module, - const DisplayOptions &displayOptions, - const FilterOptions &filterOptions); - - protected: // Protected methods - /** - * Returns the string for the filedialogs to show the correct files. - */ - const QString filterString( const Format format ); - /** - * Returns a filename to save a file. - */ - const QString getSaveFileName(const Format format); - - private: /* Methods: */ - - Rendering::CTextRendering * newRenderer(const Format format, - bool addText); - - /** - * Returns the CSS string used in HTML pages. - */ - void setProgressRange( const int item ); - - /** - * Increments the progress by one item. - */ - inline void incProgress(); - - bool progressWasCancelled(); - - /** - * Closes the progress dialog immediately. - */ - void closeProgressDialog(); - - private: - - FilterOptions m_filterOptions; - DisplayOptions m_displayOptions; - - QProgressDialog* m_progressDialog; + +public: /* Types: */ + + /** The format the export actions should have. */ + enum Format { + HTML, + Text + }; + +public: /* Methods: */ + + CExportManager(const bool showProgress = true, + const QString &progressLabel = QString::null, + const FilterOptions &filterOptions = btConfig().getFilterOptions(), + const DisplayOptions &displayOptions = btConfig().getDisplayOptions()); + ~CExportManager(); + + bool saveKey(CSwordKey const * const key, + Format const format, + bool const addText); + + bool saveKeyList(sword::ListKey const & list, + CSwordModuleInfo const * const module, + Format const format, + bool const addText); + + bool saveKeyList(QList<CSwordKey *> const & list, + Format const format, + bool const addText); + + bool copyKey(CSwordKey const * const key, + Format const format, + bool const addText); + + bool copyKeyList(sword::ListKey const & list, + CSwordModuleInfo const * const module, + Format const format, + bool const addText); + + bool copyKeyList(QList<CSwordKey *> const & list, + Format const format, + bool const addText); + + bool printKey(CSwordKey const * const key, + DisplayOptions const & displayOptions, + FilterOptions const & filterOptions); + + bool printKey(CSwordModuleInfo const * const module, + QString const & startKey, + QString const & stopKey, + DisplayOptions const & displayOptions, + FilterOptions const & filterOptions); + + /** + \brief Prints a key using the hyperlink created by CReferenceManager. + */ + bool printByHyperlink(QString const & hyperlink, + DisplayOptions const & displayOptions, + FilterOptions const & filterOptions); + + bool printKeyList(sword::ListKey const & list, + CSwordModuleInfo const * const module, + DisplayOptions const & displayOptions, + FilterOptions const & filterOptions); + + bool printKeyList(QStringList const & list, + CSwordModuleInfo const * const module, + DisplayOptions const & displayOptions, + FilterOptions const & filterOptions); + +protected: /* Methods: */ + + /** \returns the string for the filedialogs to show the correct files.*/ + const QString filterString(Format const format); + + /** \returns a filename to save a file. */ + const QString getSaveFileName(Format const format); + +private: /* Methods: */ + + std::unique_ptr<Rendering::CTextRendering> newRenderer(Format const format, + bool const addText); + + /** \returns the CSS string used in HTML pages. */ + void setProgressRange(int const items); + + /** \brief Increments the progress by one item. */ + void incProgress(); + + bool progressWasCancelled(); + + /** \brief Closes the progress dialog immediately. */ + void closeProgressDialog(); + +private: /* Fields: */ + + FilterOptions m_filterOptions; + DisplayOptions m_displayOptions; + + QProgressDialog * m_progressDialog; + }; #endif diff --git a/src/frontend/cinfodisplay.cpp b/src/frontend/cinfodisplay.cpp index 202eb48..a9e6227 100644 --- a/src/frontend/cinfodisplay.cpp +++ b/src/frontend/cinfodisplay.cpp @@ -2,14 +2,14 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ #include "frontend/cinfodisplay.h" -#include <QSharedPointer> +#include <memory> #include <QAction> #include <QDebug> #include <QLabel> @@ -19,7 +19,6 @@ #include <QVBoxLayout> #include <QtAlgorithms> #include <QMenu> - #include "backend/config/btconfig.h" #include "backend/drivers/cswordmoduleinfo.h" #include "backend/keys/cswordkey.h" @@ -29,10 +28,8 @@ #include "bibletime.h" #include "frontend/crossrefrendering.h" #include "frontend/display/bthtmlreaddisplay.h" -#include "util/htmlescape.h" - -// Sword includes: -#include <listkey.h> +#include "util/btassert.h" +#include "util/btconnect.h" using namespace Rendering; @@ -48,28 +45,28 @@ CInfoDisplay::CInfoDisplay(BibleTime * parent) layout->setContentsMargins(2, 2, 2, 2); // Leave small border setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); - m_htmlPart = new BtHtmlReadDisplay(0, this); + m_htmlPart = new BtHtmlReadDisplay(nullptr, this); m_htmlPart->setMouseTracking(false); // We don't want strong/lemma/note mouse infos m_htmlPart->view()->setAcceptDrops(false); QAction * const selectAllAction = new QAction(QIcon(), tr("Select all"), this); selectAllAction->setShortcut(QKeySequence::SelectAll); - QObject::connect(selectAllAction, SIGNAL(triggered()), - this, SLOT(selectAll())); + BT_CONNECT(selectAllAction, SIGNAL(triggered()), + this, SLOT(selectAll())); QAction * const copyAction = new QAction(tr("Copy"), this); copyAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_C)); - QObject::connect(copyAction, SIGNAL(triggered()), - m_htmlPart->connectionsProxy(), SLOT(copySelection())); + BT_CONNECT(copyAction, SIGNAL(triggered()), + m_htmlPart->connectionsProxy(), SLOT(copySelection())); QMenu * const menu = new QMenu(this); menu->addAction(selectAllAction); menu->addAction(copyAction); m_htmlPart->installPopup(menu); - QObject::connect(m_htmlPart->connectionsProxy(), - SIGNAL(referenceClicked(const QString &, const QString &)), - SLOT(lookupInfo(const QString &, const QString &))); + BT_CONNECT(m_htmlPart->connectionsProxy(), + SIGNAL(referenceClicked(QString const &, QString const &)), + SLOT(lookupInfo(QString const &, QString const &))); layout->addWidget(m_htmlPart->view()); @@ -85,22 +82,7 @@ void CInfoDisplay::unsetInfo() { } void CInfoDisplay::setInfo(const QString & renderedData, const QString & lang) { - CDisplayTemplateMgr * const mgr = CDisplayTemplateMgr::instance(); - Q_ASSERT(mgr != 0); - - CDisplayTemplateMgr::Settings settings; - settings.pageCSS_ID = "infodisplay"; - - QString div = "<div class=\"infodisplay\""; - if (!lang.isEmpty()) - div.append(" lang=\"").append(lang).append("\""); - - div.append(">"); - - QString content(mgr->fillTemplate(CDisplayTemplateMgr::activeTemplateName(), - div + renderedData + "</div>", - settings)); - m_htmlPart->setText(content); + m_htmlPart->setText(Rendering::formatInfo(renderedData, lang)); } void CInfoDisplay::lookupInfo(const QString & mod_name, @@ -109,23 +91,19 @@ void CInfoDisplay::lookupInfo(const QString & mod_name, qDebug() << "CInfoDisplay::lookup"; qDebug() << mod_name << key_text; CSwordModuleInfo * const m = CSwordBackend::instance()->findModuleByName(mod_name); - Q_ASSERT(m); - if (!m) - return; - QSharedPointer<CSwordKey> key(CSwordKey::createInstance(m)); + BT_ASSERT(m); + std::unique_ptr<CSwordKey> key(CSwordKey::createInstance(m)); key->setKey(key_text); setInfo(key->renderedText(), m->language()->abbrev()); } -void CInfoDisplay::setInfo(const InfoType type, const QString & data) { - ListInfoData list; - list.append(qMakePair(type, data)); - setInfo(list); +void CInfoDisplay::setInfo(const Rendering::InfoType type, const QString & data) { + setInfo(Rendering::ListInfoData() << qMakePair(type, data)); } -void CInfoDisplay::setInfo(const ListInfoData & list) { +void CInfoDisplay::setInfo(const Rendering::ListInfoData & list) { // If the widget is hidden it would be inefficient to render and display the data if (!isVisible()) return; @@ -135,50 +113,19 @@ void CInfoDisplay::setInfo(const ListInfoData & list) { return; } - QString renderedText; - - ListInfoData::const_iterator end = list.end(); - for (ListInfoData::const_iterator it = list.begin(); it != end; ++it) { - switch ((*it).first) { - case Lemma: - renderedText.append(decodeStrongs((*it).second)); - continue; - case Morph: - renderedText.append(decodeMorph((*it).second)); - continue; - case CrossReference: - renderedText.append(decodeCrossReference((*it).second)); - continue; - case Footnote: - renderedText.append(decodeFootnote((*it).second)); - continue; - case WordTranslation: - renderedText.append(getWordTranslation((*it).second)); - continue; - case WordGloss: - //text.append(getWordTranslation((*it).second)); - continue; - case Abbreviation: - renderedText.append(decodeAbbreviation((*it).second)); - continue; - case Text: - renderedText.append((*it).second); - continue; - default: - continue; - }; - } - setInfo(renderedText); + BtConstModuleList l; + const CSwordModuleInfo * m(m_mainWindow->getCurrentModule()); + if(m != nullptr) + l.append(m); + setInfo(Rendering::formatInfo(list, l)); } void CInfoDisplay::setInfo(CSwordModuleInfo * const module) { - using util::htmlEscape; - if (module) { setInfo(tr("<div class=\"moduleinfo\"><h3>%1</h3><p>%2</p><p>Version: %3</p></div>") - .arg(htmlEscape(module->name())) - .arg(htmlEscape(module->config(CSwordModuleInfo::Description))) - .arg(htmlEscape(module->config(CSwordModuleInfo::ModuleVersion)))); + .arg(module->name().toHtmlEscaped()) + .arg(module->config(CSwordModuleInfo::Description).toHtmlEscaped()) + .arg(module->config(CSwordModuleInfo::ModuleVersion).toHtmlEscaped())); } else { unsetInfo(); } @@ -188,292 +135,6 @@ void CInfoDisplay::selectAll() { m_htmlPart->selectAll(); } -const QString CInfoDisplay::decodeAbbreviation(const QString & data) { - // QStringList strongs = QStringList::split("|", data); - return QString("<div class=\"abbreviation\"><h3>%1: %2</h3><p>%3</p></div>") - .arg(tr("Abbreviation")) - .arg("text") - .arg(data); -} - -const QString CInfoDisplay::decodeCrossReference(const QString & data) { - Q_ASSERT(!data.isEmpty()); - if (data.isEmpty()) - return QString("<div class=\"crossrefinfo\"><h3>%1</h3></div>") - .arg(tr("Cross references")); - - // qWarning("setting crossref %s", data.latin1()); - - DisplayOptions dispOpts; - dispOpts.lineBreaks = false; - dispOpts.verseNumbers = true; - - FilterOptions filterOpts; - filterOpts.headings = false; - filterOpts.strongNumbers = false; - filterOpts.morphTags = false; - filterOpts.lemmas = false; - filterOpts.footnotes = false; - filterOpts.scriptureReferences = false; - - CrossRefRendering renderer(dispOpts, filterOpts); - CTextRendering::KeyTree tree; - - // const bool isBible = true; - const CSwordModuleInfo * module = btConfig().getDefaultSwordModuleByType("standardBible"); - if (!module) - module = m_mainWindow->getCurrentModule(); - - // a prefixed module gives the module to look into - QRegExp re("^[^ ]+:"); - // re.setMinimal(true); - int pos = re.indexIn(data); - if (pos != -1) - pos += re.matchedLength() - 1; - - if (pos > 0) { - const QString moduleName = data.left(pos); - // qWarning("found module %s", moduleName.latin1()); - module = CSwordBackend::instance()->findModuleByName(moduleName); - if (!module) - module = btConfig().getDefaultSwordModuleByType("standardBible"); - // Q_ASSERT(module); - } - - // Q_ASSERT(module); // why? the existense of the module is tested later - CTextRendering::KeyTreeItem::Settings settings( - false, - CTextRendering::KeyTreeItem::Settings::CompleteShort - ); - - if (module && (module->type() == CSwordModuleInfo::Bible)) { - VerseKey vk; - sword::ListKey refs = vk.parseVerseList((const char*) data.mid((pos == -1) ? 0 : pos + 1).toUtf8(), "Gen 1:1", true); - - for (int i = 0; i < refs.getCount(); i++) { - SWKey * const key = refs.getElement(i); - Q_ASSERT(key); - VerseKey * const vk = dynamic_cast<VerseKey*>(key); - - if (vk && vk->isBoundSet()) { // render a range of keys - tree.append(new CTextRendering::KeyTreeItem( - QString::fromUtf8(vk->getLowerBound().getText()), - QString::fromUtf8(vk->getUpperBound().getText()), - module, - settings - )); - } else { - tree.append(new CTextRendering::KeyTreeItem( - QString::fromUtf8(key->getText()), - QString::fromUtf8(key->getText()), - module, - settings - )); - } - } - } else if (module) { - tree.append(new CTextRendering::KeyTreeItem(data.mid((pos == -1) - ? 0 - : pos + 1), - module, - settings)); - } - - // qWarning("rendered the tree: %s", renderer.renderKeyTree(tree).latin1()); - // spanns containing rtl text need dir=rtl on their parent tag to be aligned properly - QString lang = "en"; // default english - if (module) - lang = module->language()->abbrev(); - - return QString("<div class=\"crossrefinfo\" lang=\"%1\"><h3>%2</h3><div class=\"para\" dir=\"%3\">%4</div></div>") - .arg(lang) - .arg(tr("Cross references")) - .arg(module ? ((module->textDirection() == CSwordModuleInfo::LeftToRight) ? "ltr" : "rtl") : "") - .arg(renderer.renderKeyTree(tree)); -} - -/*! - \fn CInfoDisplay::decodeFootnote(const QString & data) - */ -const QString CInfoDisplay::decodeFootnote(const QString & data) { - QStringList list = data.split("/"); - Q_ASSERT(list.count() >= 3); - if (!list.count()) - return QString::null; - - FilterOptions filterOpts; - filterOpts.headings = false; - filterOpts.strongNumbers = false; - filterOpts.morphTags = false; - filterOpts.lemmas = false; - filterOpts.footnotes = true; - // turn scripRefs off, so that they do not show up as footnotes in the OSIS filter's EntryAttributes - filterOpts.scriptureReferences = false; - - CSwordBackend::instance()->setFilterOptions(filterOpts); - - const QString modulename = list.first(); - const QString swordFootnote = list.last(); - - // remove the first and the last and then rejoin it to get a key - list.pop_back(); - list.pop_front(); - const QString keyname = list.join("/"); - - CSwordModuleInfo * const module = CSwordBackend::instance()->findModuleByName(modulename); - if (!module) - return QString::null; - - QSharedPointer<CSwordKey> key(CSwordKey::createInstance(module)); - key->setKey(keyname); - key->renderedText(CSwordKey::ProcessEntryAttributesOnly); // force entryAttributes - - const char * const note = - module->module()->getEntryAttributes() - ["Footnote"][swordFootnote.toLatin1().data()]["body"].c_str(); - - QString text = module->isUnicode() ? QString::fromUtf8(note) : QString(note); - text = QString::fromUtf8(module->module()->renderText( - module->isUnicode() - ? static_cast<const char *>(text.toUtf8()) - : static_cast<const char *>(text.toLatin1()))); - - return QString("<div class=\"footnoteinfo\" lang=\"%1\"><h3>%2</h3><p>%3</p></div>") - .arg(module->language()->abbrev()) - .arg(tr("Footnote")) - .arg(text); -} - -const QString CInfoDisplay::decodeStrongs(const QString & data) { - QStringList strongs = data.split("|"); - QString ret; - - QStringList::const_iterator end = strongs.end(); - for (QStringList::const_iterator it = strongs.begin(); it != end; ++it) { - CSwordModuleInfo * const module = btConfig().getDefaultSwordModuleByType - ( - ((*it).left(1) == QString("H")) ? - "standardHebrewStrongsLexicon" : - "standardGreekStrongsLexicon" - ); - - QString text; - if (module) { - QSharedPointer<CSwordKey> key(CSwordKey::createInstance(module)); - key->setKey((*it).mid(1)); // skip H or G (language sign), will have to change later if we have better modules - text = key->renderedText(); - } - //if the module could not be found just display an empty lemma info - - QString lang = "en"; // default english - if (module) - lang = module->language()->abbrev(); - ret.append( - QString("<div class=\"strongsinfo\" lang=\"%1\"><h3>%2: %3</h3><p>%4</p></div>") - .arg(lang) - .arg(tr("Strongs")) - .arg(*it) - .arg(text) - ); - } - - return ret; -} - -const QString CInfoDisplay::decodeMorph(const QString & data) { - QStringList morphs = data.split("|"); - QString ret; - - Q_FOREACH (QString morph, morphs) { - //qDebug() << "CInfoDisplay::decodeMorph, morph: " << morph; - CSwordModuleInfo * module = 0; - bool skipFirstChar = false; - QString value = ""; - QString valueClass = ""; - - int valStart = morph.indexOf(':'); - if (valStart > -1) { - valueClass = morph.mid(0, valStart); - // qDebug() << "valueClass: " << valueClass; - module = CSwordBackend::instance()->findModuleByName(valueClass); - } - value = morph.mid(valStart + 1); //works for prepended module and without (-1 +1 == 0). - - // if we don't have a class assigned or desired one isn't installed... - if (!module) { - // Morphs usually don't have [GH] prepended, but some old OLB - // codes do. We should check if we're digit after first char - // to better guess this. - if (value.size() > 1 && value.at(1).isDigit()) { - switch (value.at(0).toLatin1()) { - case 'G': - module = btConfig().getDefaultSwordModuleByType("standardGreekMorphLexicon"); - skipFirstChar = true; - break; - case 'H': - module = btConfig().getDefaultSwordModuleByType("standardHebrewMorphLexicon"); - skipFirstChar = true; - break; - default: - skipFirstChar = false; - /// \todo we can't tell here if it's a greek or hebrew moprh code, that's a problem we have to solve - // module = getBtConfig().getDefaultSwordModuleByType("standardGreekMorphLexicon"); - break; - } - } - //if it is still not set use the default - if (!module) - module = btConfig().getDefaultSwordModuleByType("standardGreekMorphLexicon"); - } - - QString text; - // Q_ASSERT(module); - if (module) { - QSharedPointer<CSwordKey> key(CSwordKey::createInstance(module)); - - // skip H or G (language sign) if we have to skip it - const bool isOk = key->setKey(skipFirstChar ? value.mid(1) : value); - // Q_ASSERT(isOk); - if (!isOk) { // try to use the other morph lexicon, because this one failed with the current morph code - key->setModule(btConfig().getDefaultSwordModuleByType("standardHebrewMorphLexicon")); /// \todo: what if the module doesn't exist? - key->setKey(skipFirstChar ? value.mid(1) : value); - } - - text = key->renderedText(); - } - - // if the module wasn't found just display an empty morph info - QString lang = "en"; // default to english - if (module) - lang = module->language()->abbrev(); - ret.append(QString("<div class=\"morphinfo\" lang=\"%1\"><h3>%2: %3</h3><p>%4</p></div>") - .arg(lang) - .arg(tr("Morphology")) - .arg(value) - .arg(text) - ); - } - - return ret; -} - -const QString CInfoDisplay::getWordTranslation(const QString & data) { - CSwordModuleInfo * const module = btConfig().getDefaultSwordModuleByType("standardLexicon"); - if (!module) - return QString::null; - - QSharedPointer<CSwordKey> key(CSwordKey::createInstance(module)); - key->setKey(data); - if (key->key().toUpper() != data.toUpper()) //key not present in the lexicon - return QString::null; - - return QString("<div class=\"translationinfo\" lang=\"%1\"><h3>%2: %3</h3><p>%4</p></div>") - .arg(module->language()->abbrev()) - .arg(tr("Word lookup")) - .arg(data) - .arg(key->renderedText()); -} - QSize CInfoDisplay::sizeHint() const { return QSize(100, 150); } diff --git a/src/frontend/cinfodisplay.h b/src/frontend/cinfodisplay.h index 46623ba..a7e18b1 100644 --- a/src/frontend/cinfodisplay.h +++ b/src/frontend/cinfodisplay.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -16,7 +16,7 @@ #include <QList> #include <QPair> -#include "backend/rendering/ctextrendering.h" +#include "backend/rendering/btinforendering.h" class CReadDisplay; @@ -31,46 +31,21 @@ class CInfoDisplay: public QWidget { Q_OBJECT -public: /* Types: */ - - enum InfoType { - Abbreviation, - CrossReference, - Footnote, - Lemma, - Morph, - WordTranslation, - WordGloss, - Text - }; - - typedef QPair<InfoType, QString> InfoData; - typedef QList<InfoData> ListInfoData; - public: /* Methods: */ - CInfoDisplay(BibleTime * parent = NULL); + CInfoDisplay(BibleTime * parent = nullptr); void unsetInfo(); void setInfo(const QString & renderedData, const QString & lang = QString()); - void setInfo(const InfoType, const QString & data); - void setInfo(const ListInfoData &); - QSize sizeHint() const; + void setInfo(Rendering::InfoType const, QString const & data); + void setInfo(Rendering::ListInfoData const &); + QSize sizeHint() const override; public slots: void setInfo(CSwordModuleInfo * module); -private: /* Methods: */ - - const QString decodeAbbreviation(const QString & data); - const QString decodeCrossReference(const QString & data); - const QString decodeFootnote(const QString & data); - const QString decodeStrongs(const QString & data); - const QString decodeMorph(const QString & data); - const QString getWordTranslation(const QString & data); - private slots: void lookupInfo(const QString &, const QString &); diff --git a/src/frontend/cmdiarea.cpp b/src/frontend/cmdiarea.cpp index d879dfa..0e01cc8 100644 --- a/src/frontend/cmdiarea.cpp +++ b/src/frontend/cmdiarea.cpp @@ -2,15 +2,13 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ -#include "bibletime.h" #include "frontend/cmdiarea.h" -#include "frontend/displaywindow/btmodulechooserbar.h" -#include "frontend/display/cdisplay.h" + #include <QEvent> #include <QMdiSubWindow> #include <QMenu> @@ -18,8 +16,13 @@ #include <QTabBar> #include <QTimer> #include <QToolBar> -#include <QWebView> +#include "frontend/btwebenginepage.h" +#include "frontend/btwebengineview.h" #include <QWindowStateChangeEvent> +#include "bibletime.h" +#include "frontend/displaywindow/btmodulechooserbar.h" +#include "frontend/display/cdisplay.h" +#include "util/btconnect.h" namespace { @@ -28,30 +31,26 @@ inline CDisplayWindow * getDisplayWindow(const QMdiSubWindow * const mdiWindow) return qobject_cast<CDisplayWindow *>(mdiWindow->widget()); } -inline QWebView * getWebViewFromDisplayWindow(const CDisplayWindow * const displayWindow) { +inline BtWebEngineView * getWebViewFromDisplayWindow(const CDisplayWindow * const displayWindow) { if (!displayWindow) - return NULL; + return nullptr; CDisplay * const display = displayWindow->displayWidget(); if (!display) - return NULL; - return qobject_cast<QWebView *>(display->view()); + return nullptr; + return qobject_cast<BtWebEngineView *>(display->view()); } } // anonymous namespace -CMDIArea::CMDIArea(BibleTime *parent) - : QMdiArea(parent) +CMDIArea::CMDIArea(BibleTime * parent) + : QMdiArea((BT_ASSERT(parent), parent)) , m_mdiArrangementMode(ArrangementModeManual) - , m_activeWindow(0) + , m_activeWindow(nullptr) , m_bibleTime(parent) { - Q_ASSERT(parent != 0); - - #if QT_VERSION >= 0x040500 // Set document-style tabs (for Mac): setDocumentMode(true); - #endif /* Activate windows based on the history of activation, e.g. when one has window A @@ -63,8 +62,8 @@ CMDIArea::CMDIArea(BibleTime *parent) setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); - connect(this, SIGNAL(subWindowActivated(QMdiSubWindow*)), - this, SLOT(slotSubWindowActivated(QMdiSubWindow*))); + BT_CONNECT(this, SIGNAL(subWindowActivated(QMdiSubWindow *)), + this, SLOT(slotSubWindowActivated(QMdiSubWindow *))); } void CMDIArea::fixSystemMenu(QMdiSubWindow* subWindow) { @@ -129,22 +128,18 @@ void CMDIArea::setMDIArrangementMode( const MDIArrangementMode newArrangementMod break; case ArrangementModeTabbed: setViewMode(QMdiArea::TabbedView); + for (auto win : subWindowList()) + win->showMaximized(); break; default: setViewMode(QMdiArea::SubWindowView); triggerWindowUpdate(); break; } - Q_FOREACH (QTabBar* tab, findChildren<QTabBar *>()) { + Q_FOREACH(QTabBar * const tab, findChildren<QTabBar *>()) { QObject* parent = tab->parent(); - if (parent == this) { + if (parent == this) tab->setTabsClosable(true); -// As of version 4.8, Qt does the close for us. -#if QT_VERSION < 0x040800 - disconnect(tab, SIGNAL(tabCloseRequested(int)), this, SLOT(closeTab(int))); - connect(tab, SIGNAL(tabCloseRequested(int)), this, SLOT(closeTab(int))); -#endif - } } } @@ -182,7 +177,7 @@ void CMDIArea::myTileVertical() { x += actWidth; } - if (active != 0) { + if (active != nullptr) { active->setFocus(); } @@ -215,7 +210,7 @@ void CMDIArea::myTileHorizontal() { y += actHeight; } - if (active != 0) { + if (active != nullptr) { active->setFocus(); } @@ -292,19 +287,17 @@ QList<QMdiSubWindow*> CMDIArea::usableWindowList() const { //Take care: when new windows are added, they will not appear //in subWindowList() when their ChildAdded-Event is triggered QList<QMdiSubWindow*> ret; - Q_FOREACH (QMdiSubWindow * const w, subWindowList()) { - if (!w->isHidden()) { + Q_FOREACH(QMdiSubWindow * const w, subWindowList()) + if (!w->isHidden()) ret.append(w); - } - } return ret; } -QWebView* CMDIArea::getActiveWebView() +BtWebEngineView* CMDIArea::getActiveWebView() { QMdiSubWindow* activeMdiWindow = activeSubWindow(); CDisplayWindow* const activeWindow = getDisplayWindow(activeMdiWindow); - QWebView* webView = getWebViewFromDisplayWindow(activeWindow); + BtWebEngineView* webView = getWebViewFromDisplayWindow(activeWindow); return webView; } @@ -312,48 +305,39 @@ void CMDIArea::slotSubWindowActivated(QMdiSubWindow* client) { if (subWindowList().isEmpty()) m_bibleTime->clearMdiToolBars(); - if (client == 0) { + if (client == nullptr) { return; } emit sigSetToplevelCaption( client->windowTitle().trimmed() ); // Notify child window it is active CDisplayWindow* const activeWindow = getDisplayWindow(client); - if (activeWindow != 0 && activeWindow != m_activeWindow) { + if (activeWindow != nullptr && activeWindow != m_activeWindow) { m_activeWindow = activeWindow; activeWindow->windowActivated(); } } -void CMDIArea::findNextTextInActiveWindow(const QString& text, bool caseSensitive) { - QWebView* activeWebView = getActiveWebView(); - if (activeWebView == 0) - return; - QWebPage::FindFlags options = QWebPage::FindWrapsAroundDocument; - if (caseSensitive) - options |= QWebPage::FindCaseSensitively; - activeWebView->findText(text, options); -} +void CMDIArea::findNextTextInActiveWindow(QString const & text, bool cs) +{ findTextInActiveWindow(text, cs, false); } -void CMDIArea::findPreviousTextInActiveWindow(const QString& text, bool caseSensitive) { - QWebView* activeWebView = getActiveWebView(); - if (activeWebView == 0) - return; - QWebPage::FindFlags options = QWebPage::FindWrapsAroundDocument; - if (caseSensitive) - options |= QWebPage::FindCaseSensitively; - activeWebView->findText(text, options); -} +void CMDIArea::findPreviousTextInActiveWindow(QString const & text, bool cs) +{ findTextInActiveWindow(text, cs, true); } void CMDIArea::highlightTextInActiveWindow(const QString& text, bool caseSensitive) { - QWebView* activeWebView = getActiveWebView(); - if (activeWebView == 0) + BtWebEngineView* activeWebView = getActiveWebView(); + if (activeWebView == nullptr) return; - QWebPage::FindFlags options = QWebPage::HighlightAllOccurrences; - if (caseSensitive) - options |= QWebPage::FindCaseSensitively; - activeWebView->findText("", options); // clear old highlight - activeWebView->findText(text, options); + activeWebView->findTextHighlight(text, caseSensitive); +} + +void CMDIArea::findTextInActiveWindow(QString const & text, + bool caseSensitive, + bool backward) +{ + if (BtWebEngineView * const activeWebView = getActiveWebView()) { + activeWebView->findText(text, caseSensitive, backward); + } } void CMDIArea::resizeEvent(QResizeEvent* e) { @@ -377,13 +361,14 @@ bool CMDIArea::eventFilter(QObject *o, QEvent *e) { const QMdiSubWindow * const w = qobject_cast<QMdiSubWindow*>(o); // Let the event be handled by other filters: - if (w == 0) + if (w == nullptr) return QMdiArea::eventFilter(o, e); switch (e->type()) { case QEvent::WindowStateChange: { - Qt::WindowStates newState(w->windowState()); - Qt::WindowStates oldState(((QWindowStateChangeEvent*)e)->oldState()); + Qt::WindowStates const newState(w->windowState()); + Qt::WindowStates const oldState( + static_cast<QWindowStateChangeEvent *>(e)->oldState()); /* Do not handle window activation or deactivation here, it will diff --git a/src/frontend/cmdiarea.h b/src/frontend/cmdiarea.h index 6245d94..56afce4 100644 --- a/src/frontend/cmdiarea.h +++ b/src/frontend/cmdiarea.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -20,7 +20,7 @@ class BibleTime; class CSwordModuleInfo; class CDisplayWindow; -class QWebView; +class BtWebEngineView; /** A custom MDI area widget. @@ -55,7 +55,7 @@ class CMDIArea: public QMdiArea { Reimplementation of QMdiArea::addSubWindow(). */ QMdiSubWindow * addSubWindow(QWidget * widget, - Qt::WindowFlags windowFlags = 0); + Qt::WindowFlags windowFlags = nullptr); /** Returns the BibleTime main window @@ -144,23 +144,27 @@ class CMDIArea: public QMdiArea { protected: /* Methods: */ + void findTextInActiveWindow(QString const & text, + bool caseSensitive, + bool backward); + /** Reimplementation of QWidget::resizeEvent() to handle our automatic tiling properly. */ - void resizeEvent(QResizeEvent *e); + void resizeEvent(QResizeEvent *e) override; /** Reimplementation of QObject::eventFilter() used to handle some MDI subwindow events. */ - bool eventFilter(QObject *o, QEvent *e); + bool eventFilter(QObject *o, QEvent *e) override; void emitWindowCaptionChanged(); void fixSystemMenu(QMdiSubWindow* subWindow); - QWebView* getActiveWebView(); + BtWebEngineView *getActiveWebView(); protected slots: diff --git a/src/frontend/cprinter.cpp b/src/frontend/cprinter.cpp deleted file mode 100644 index b10d614..0000000 --- a/src/frontend/cprinter.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/********* -* -* 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 "frontend/cprinter.h" - -#include <QPrintDialog> -#include <QPrinter> -#include <QWebFrame> -#include <QWebPage> -#include "backend/keys/cswordversekey.h" -#include "backend/managers/cdisplaytemplatemgr.h" -#include "backend/config/btconfig.h" - - -namespace Printing { - -/// \todo WHY IS parent NOT USED!? -CPrinter::CPrinter(QObject *, - const DisplayOptions &displayOptions, - const FilterOptions &filterOptions) - : QObject(0), - CDisplayRendering(displayOptions, filterOptions), - m_htmlPage(new QWebPage()) -{ - m_htmlPage->setParent(this); - - //override the filteroptions set in the c-tor of CDisplayRendering - m_filterOptions.footnotes = false; - m_filterOptions.scriptureReferences = false; - m_filterOptions.strongNumbers = false; - m_filterOptions.morphTags = false; - m_filterOptions.headings = false; -} - -CPrinter::~CPrinter() { - delete m_htmlPage; - m_htmlPage = 0; -} - -void CPrinter::printKeyTree( KeyTree& tree ) { - m_htmlPage->mainFrame()->setHtml(renderKeyTree(tree)); - - QPrinter printer; - QPrintDialog printDialog(&printer); - if (printDialog.exec() == QDialog::Accepted) { - m_htmlPage->mainFrame()->print(&printer); - } -} - -QString CPrinter::entryLink(const KeyTreeItem &item, - const CSwordModuleInfo * module) -{ - Q_ASSERT(module); - if (module->type() == CSwordModuleInfo::Bible) { - CSwordVerseKey vk(module); - vk.setKey(item.key()); - switch (item.settings().keyRenderingFace) { - case KeyTreeItem::Settings::CompleteShort: - return QString::fromUtf8(vk.getShortText()); - - case KeyTreeItem::Settings::CompleteLong: - return vk.key(); - - case KeyTreeItem::Settings::NoKey: - return QString::null; - - case KeyTreeItem::Settings::SimpleKey: //fall through - default: - return QString::number(vk.getVerse()); - } - } - return item.key(); -} - -QString CPrinter::renderEntry(const KeyTreeItem &i, CSwordKey * key) { - Q_UNUSED(key); - - const CPrinter::KeyTreeItem* printItem = dynamic_cast<const CPrinter::KeyTreeItem*>(&i); - Q_ASSERT(printItem); - - if (printItem && printItem->hasAlternativeContent()) { - QString ret = QString::fromLatin1("<div class=\"entry\"><div class=\"rangeheading\">%1</div>").arg(printItem->getAlternativeContent()); - - if (!i.childList()->isEmpty()) { - KeyTree const * tree = i.childList(); - - Q_FOREACH (const KeyTreeItem * const c, *tree) { - ret.append( CDisplayRendering::renderEntry( *c ) ); - } - } - - ret.append("</div>"); - return ret; - } - return CDisplayRendering::renderEntry(i); -} - -QString CPrinter::finishText(const QString &text, const KeyTree &tree) { - QList<const CSwordModuleInfo*> modules = collectModules(tree); - Q_ASSERT(modules.count() > 0); - - const CLanguageMgr::Language* const lang = modules.first()->language(); - Q_ASSERT(lang); - - CDisplayTemplateMgr::Settings settings; - //settings.modules = modules; - settings.pageCSS_ID = "printer"; - if (modules.count() == 1 && lang->isValid()) - settings.langAbbrev = lang->abbrev(); - - if (modules.count() == 1) - settings.textDirection = modules.first()->textDirection(); - - CDisplayTemplateMgr *tMgr = CDisplayTemplateMgr::instance(); - return tMgr->fillTemplate(CDisplayTemplateMgr::activeTemplateName(), text, settings); -} - -} //end of namespace diff --git a/src/frontend/cprinter.h b/src/frontend/cprinter.h deleted file mode 100644 index 48001a1..0000000 --- a/src/frontend/cprinter.h +++ /dev/null @@ -1,50 +0,0 @@ -/********* -* -* 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 CPRINTER_H -#define CPRINTER_H - -#include <QObject> -#include "backend/rendering/cdisplayrendering.h" - -#include "backend/managers/cswordbackend.h" - - -class QWebPage; - -namespace Printing { - -// The CPrinter class manages the print item queue and the printing of them to the printer. - -class CPrinter : public QObject, public Rendering::CDisplayRendering { - Q_OBJECT - public: - CPrinter(QObject *parent, - const DisplayOptions &displayOptions, - const FilterOptions &filterOptions); - - virtual ~CPrinter(); - void printKeyTree( KeyTree& ); - - protected: - virtual QString entryLink(const KeyTreeItem &item, - const CSwordModuleInfo * module); - - virtual QString renderEntry(const KeyTreeItem &item, CSwordKey * key = 0); - virtual QString finishText(const QString &text, const KeyTree &tree); - - private: - QWebPage* m_htmlPage; -}; - -} //namespace Printing - -#endif diff --git a/src/frontend/crossrefrendering.cpp b/src/frontend/crossrefrendering.cpp index 868b6ce..d81c326 100644 --- a/src/frontend/crossrefrendering.cpp +++ b/src/frontend/crossrefrendering.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -12,6 +12,7 @@ #include "backend/drivers/cswordmoduleinfo.h" #include "backend/keys/cswordversekey.h" #include "backend/managers/referencemanager.h" +#include "util/btassert.h" namespace InfoDisplay { @@ -31,9 +32,10 @@ QString CrossRefRendering::finishText(const QString &text, const KeyTree &tree) QString CrossRefRendering::entryLink(const KeyTreeItem &item, const CSwordModuleInfo *module) { + BT_ASSERT(module); QString linkText; - const bool isBible = module && (module->type() == CSwordModuleInfo::Bible); + const bool isBible = (module->type() == CSwordModuleInfo::Bible); CSwordVerseKey vk(module); //only valid for bible modules, i.e. isBible == true if (isBible) { vk.setKey(item.key()); diff --git a/src/frontend/crossrefrendering.h b/src/frontend/crossrefrendering.h index fb22aa2..0dbf233 100644 --- a/src/frontend/crossrefrendering.h +++ b/src/frontend/crossrefrendering.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -27,10 +27,10 @@ class CrossRefRendering : public Rendering::CHTMLExportRendering { const FilterOptions &filterOptions = btConfig().getFilterOptions() ); - virtual QString entryLink(const KeyTreeItem &item, - const CSwordModuleInfo *module); + QString entryLink(const KeyTreeItem &item, + const CSwordModuleInfo *module) override; - virtual QString finishText(const QString &text, const KeyTree &tree); + QString finishText(const QString &text, const KeyTree &tree) override; }; diff --git a/src/frontend/display/btcolorwidget.cpp b/src/frontend/display/btcolorwidget.cpp index 579e461..908037b 100644 --- a/src/frontend/display/btcolorwidget.cpp +++ b/src/frontend/display/btcolorwidget.cpp @@ -2,58 +2,46 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ #include "frontend/display/btcolorwidget.h" -#include <QColor> #include <QColorDialog> #include <QMouseEvent> #include <QPalette> -BtColorWidget::BtColorWidget(QWidget* parent) - : QFrame(parent) { +BtColorWidget::BtColorWidget(QWidget * parent) + : QFrame(parent) +{ setFrameShadow(QFrame::Sunken); setFrameShape(QFrame::StyledPanel); setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); setAutoFillBackground(true); + setBackgroundRole(QPalette::Window); } -BtColorWidget::~BtColorWidget() { -} - -QSize BtColorWidget::sizeHint() const { - return QSize(35, 18); -} +QSize BtColorWidget::sizeHint() const { return QSize(35, 18); } -void BtColorWidget::setColor(const QColor& color) { - QPalette p = palette(); +void BtColorWidget::setColor(QColor const & color) { + QPalette p(palette()); p.setColor(QPalette::Normal, QPalette::Window, color); setPalette(p); - - if (color.isValid()) - m_color = color; - else - m_color = QColor(0, 0, 0); update(); } -void BtColorWidget::mouseReleaseEvent(QMouseEvent* event) { +void BtColorWidget::mouseReleaseEvent(QMouseEvent * event) { if (event->button() == Qt::LeftButton) { event->accept(); - showColorDialog(); - return; - } -} - -void BtColorWidget::showColorDialog() { - QColor color = QColorDialog::getColor(m_color, this); - if (color.isValid()) { - m_color = color; - emit changed(m_color); + QColor const color(QColorDialog::getColor( + palette().color(QPalette::Normal, QPalette::Window), + this)); + if (color.isValid()) { + setColor(color); + emit changed(color); + } } } diff --git a/src/frontend/display/btcolorwidget.h b/src/frontend/display/btcolorwidget.h index 9dd2e97..ab8d9c4 100644 --- a/src/frontend/display/btcolorwidget.h +++ b/src/frontend/display/btcolorwidget.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -15,29 +15,28 @@ #include <QFrame> -class QPaintEvent; +class BtColorWidget: public QFrame { -class BtColorWidget : public QFrame { - Q_OBJECT + Q_OBJECT - public: - BtColorWidget(QWidget* parent = 0); - ~BtColorWidget(); - QSize sizeHint() const; +public: - public slots: - void setColor(const QColor& color); + BtColorWidget(QWidget * parent = nullptr); - protected: - void mouseReleaseEvent(QMouseEvent* event); + QSize sizeHint() const override; - private: - void showColorDialog(); +public slots: - QColor m_color; + void setColor(QColor const & color); + +protected: /* Methods: */ + + void mouseReleaseEvent(QMouseEvent * event) override; + +signals: + + void changed(QColor const & color); - signals: - void changed(const QColor& color); }; #endif diff --git a/src/frontend/display/btfindwidget.cpp b/src/frontend/display/btfindwidget.cpp index 1ada629..d60c290 100644 --- a/src/frontend/display/btfindwidget.cpp +++ b/src/frontend/display/btfindwidget.cpp @@ -2,117 +2,99 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ #include "frontend/display/btfindwidget.h" -#include "QApplication" #include "QCheckBox" #include "QHBoxLayout" #include "QLineEdit" #include "QSpacerItem" #include "QToolButton" -#include "bibletimeapp.h" +#include "util/btconnect.h" #include "util/cresmgr.h" -#include "util/geticon.h" - - -BtFindWidget::BtFindWidget(QWidget* parent) - : QWidget(parent) { - createLayout(); - createToolButton(CResMgr::findWidget::close_icon, "", SLOT(hide())); - createTextEditor(); - createToolButton(CResMgr::findWidget::previous_icon, tr("Previous"), SLOT(findPrevious())); - createToolButton(CResMgr::findWidget::next_icon, tr("Next"), SLOT(findNext())); - createCaseCheckBox(); - createSpacer(); - setFocusProxy(m_textEditor); -} -BtFindWidget::~BtFindWidget() { + +namespace { +inline QToolButton * newToolButton(QIcon const & icon, + char const * const slot, + QWidget * const parent, + QHBoxLayout * const layout) +{ + QToolButton * const button = new QToolButton(parent); + button->setIcon(icon); + button->setIconSize(QSize(16, 16)); + button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + button->setAutoRaise(true); + layout->addWidget(button); + BT_CONNECT_QOBJECT(button, SIGNAL(released()), parent, slot); + return button; } +} // anonymous namespace -void BtFindWidget::createLayout() { +BtFindWidget::BtFindWidget(QWidget * parent) + : QWidget(parent) +{ + // Overall layout: m_layout = new QHBoxLayout(this); m_layout->setMargin(0); m_layout->setSpacing(8); -} -void BtFindWidget::createToolButton(const QString& iconName, const QString& text, const char* slot) { - QToolButton* button = new QToolButton(this); - button->setIcon(util::getIcon(iconName)); - button->setIconSize(QSize(16,16)); - button->setText(text); - button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); - button->setAutoRaise(true); - m_layout->addWidget(button); - bool ok = connect(button, SIGNAL(released()), this, slot); - Q_ASSERT(ok); -} + // Buttons and text editor: + #define newButton(...) newToolButton(__VA_ARGS__, this, m_layout) + + // Close button: + newButton(CResMgr::findWidget::icon_close(), SLOT(hide())); -void BtFindWidget::createTextEditor() { + // Text editor: m_textEditor = new QLineEdit(this); -#if QT_VERSION < 0x050000 - m_textEditor->setToolTip(QApplication::translate("findWidget", - "The text you want to search for", 0, QApplication::UnicodeUTF8)); -#else - m_textEditor->setToolTip(QApplication::translate("findWidget", - "The text you want to search for", 0)); -#endif m_layout->addWidget(m_textEditor); - bool ok = connect(m_textEditor, SIGNAL(textChanged(const QString&)), - this, SLOT(textChanged(const QString&))); - Q_ASSERT(ok); - ok = connect(m_textEditor,SIGNAL(returnPressed()), this, SLOT(returnPressed())); - Q_ASSERT(ok); -} - -void BtFindWidget::createCaseCheckBox() { - m_caseCheckBox = new QCheckBox(tr("Match case"), this); + BT_CONNECT(m_textEditor, SIGNAL(textChanged(QString const &)), + this, SLOT(textChanged(QString const &))); + BT_CONNECT(m_textEditor, SIGNAL(returnPressed()), + this, SLOT(returnPressed())); + + // Next and Previous buttons: + m_previousButton = newButton(CResMgr::findWidget::icon_previous(), + SLOT(findPrevious())); + m_nextButton = newButton(CResMgr::findWidget::icon_next(), + SLOT(findNext())); + + // Case checkbox: + m_caseCheckBox = new QCheckBox(this); + BT_CONNECT(m_caseCheckBox, SIGNAL(stateChanged(int)), + this, SLOT(caseStateChanged(int))); m_layout->addWidget(m_caseCheckBox); -} - -void BtFindWidget::createSpacer() { - QSpacerItem* spacer = new QSpacerItem(0,0,QSizePolicy::Expanding, QSizePolicy::Minimum); - m_layout->addItem(spacer); -} -void BtFindWidget::highlightText(const QString& text) { - bool caseSensitive = m_caseCheckBox->checkState() == Qt::Checked; - emit highlightText(text, caseSensitive); -} + // Spacer: + m_layout->addItem(new QSpacerItem(0, + 0, + QSizePolicy::Expanding, + QSizePolicy::Minimum)); + setFocusProxy(m_textEditor); -void BtFindWidget::returnPressed() { - bool caseSensitive = m_caseCheckBox->checkState() == Qt::Checked; - QString text = m_textEditor->text(); - emit highlightText(text, caseSensitive); - emit findNext(text, caseSensitive); + retranslateUi(); } -void BtFindWidget::textChanged(const QString& text) { - bool caseSensitive = m_caseCheckBox->checkState() == Qt::Checked; - emit highlightText(text, caseSensitive); - emit findNext(text, caseSensitive); +void BtFindWidget::retranslateUi() { + m_textEditor->setToolTip(tr("The text you want to search for", + "findWidget")); + m_previousButton->setText(tr("Previous")); + m_nextButton->setText(tr("Next")); + m_caseCheckBox->setText(tr("Match case")); } -void BtFindWidget::findNext() { - bool caseSensitive = m_caseCheckBox->checkState() == Qt::Checked; - QString text = m_textEditor->text(); - emit findNext(text, caseSensitive); -} +bool BtFindWidget::caseSensitive() const +{ return m_caseCheckBox->checkState() == Qt::Checked; } -void BtFindWidget::findPrevious() { - bool caseSensitive = m_caseCheckBox->checkState() == Qt::Checked; - QString text = m_textEditor->text(); - emit findPrevious(text, caseSensitive); -} +QString BtFindWidget::text() const { return m_textEditor->text(); } -void BtFindWidget::showAndSelect(){ +void BtFindWidget::showAndSelect() { setVisible(true); - QWidget::show(); + show(); m_textEditor->selectAll(); m_textEditor->setFocus(Qt::ShortcutFocusReason); } diff --git a/src/frontend/display/btfindwidget.h b/src/frontend/display/btfindwidget.h index 52a879a..bd32cb7 100644 --- a/src/frontend/display/btfindwidget.h +++ b/src/frontend/display/btfindwidget.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -13,44 +13,61 @@ #define BTFINDIDGET_H #include <QWidget> -#include <QWebPage> + + class QCheckBox; -class QLineEdit; class QHBoxLayout; +class QLineEdit; class QString; +class QToolButton; -class BtFindWidget : public QWidget { - Q_OBJECT - - public: - BtFindWidget(QWidget* parent = 0); - ~BtFindWidget(); - void showAndSelect(); - - private slots: - void findNext(); - void findPrevious(); - void returnPressed(); - void textChanged(const QString& text); - - private: - void createCaseCheckBox(); - void createLayout(); - void createSpacer(); - void createTextEditor(); - void createToolButton(const QString& iconName, const QString& text, const char* slot); - void highlightText(const QString& searchText); - - QHBoxLayout* m_layout; - QLineEdit* m_textEditor; - QCheckBox* m_caseCheckBox; - - signals: - void findPrevious(const QString & text, bool caseSensitive); - void findNext(const QString & text, bool caseSensitive); - void highlightText(const QString & text, bool caseSensitive); -}; +class BtFindWidget: public QWidget { -#endif + Q_OBJECT + +public: /* Methods: */ + + BtFindWidget(QWidget * parent = nullptr); + + void showAndSelect(); + +private slots: + + void findNext() { emit findNext(text(), caseSensitive()); } + void findPrevious() { emit findPrevious(text(), caseSensitive()); } + void returnPressed() { emitChange(text(), caseSensitive()); } + void textChanged(QString const & txt) { emitChange(txt, caseSensitive()); } + void caseStateChanged(int st) { emitChange(text(), st == Qt::Checked); } + +private: /* Methods: */ + void retranslateUi(); + void highlightText(QString const & text) + { emit highlightText(text, caseSensitive()); } + + bool caseSensitive() const; + + QString text() const; + + void emitChange(QString const & text, bool const caseSensitive) { + emit highlightText(text, caseSensitive); + } + +signals: + + void findPrevious(QString const & text, bool caseSensitive); + void findNext(QString const & text, bool caseSensitive); + void highlightText(QString const & text, bool caseSensitive); + +private: /* Fields: */ + + QHBoxLayout * m_layout; + QLineEdit * m_textEditor; + QToolButton * m_nextButton; + QToolButton * m_previousButton; + QCheckBox * m_caseCheckBox; + +}; + +#endif diff --git a/src/frontend/display/btfontsizewidget.cpp b/src/frontend/display/btfontsizewidget.cpp index 82fdd08..eccacd3 100644 --- a/src/frontend/display/btfontsizewidget.cpp +++ b/src/frontend/display/btfontsizewidget.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -11,36 +11,36 @@ #include <QCompleter> #include <QFontDatabase> +#include <QValidator> +#include "util/btconnect.h" -BtFontSizeWidget::BtFontSizeWidget(QWidget* parent) - : QComboBox(parent) { +BtFontSizeWidget::BtFontSizeWidget(QWidget * parent) + : QComboBox(parent) + , m_validator(new QIntValidator(1, 99, this)) +{ setEditable(true); + setValidator(m_validator); completer()->setCompletionMode(QCompleter::PopupCompletion); - QFontDatabase database; - const QList<int> sizes = database.standardSizes(); - QStringList list; - for ( QList<int>::ConstIterator it = sizes.begin(); it != sizes.end(); ++it ) - list.append( QString::number( *it ) ); - addItems(list); + Q_FOREACH (int const size, QFontDatabase().standardSizes()) { + if (size > m_validator->top()) + m_validator->setTop(size); + addItem(QString::number(size), QVariant(size)); + } - bool ok = connect(this, SIGNAL(currentIndexChanged(const QString&)), - this, SLOT(changed(const QString&))); - Q_ASSERT(ok); + BT_CONNECT(this, SIGNAL(currentIndexChanged(QString const &)), + this, SLOT(changed(QString const &))); } -BtFontSizeWidget::~BtFontSizeWidget() { -} - -void BtFontSizeWidget::changed(const QString& text) { +void BtFontSizeWidget::changed(QString const & text) { emit fontSizeChanged(text.toInt()); } void BtFontSizeWidget::setFontSize(int size) { - int index = findText(QString::number(size)); - if (index >= 0) - setCurrentIndex(index); + if ((size < 1) || (size > m_validator->top())) + size = 12; + setCurrentText(QString::number(size)); } int BtFontSizeWidget::fontSize() const { diff --git a/src/frontend/display/btfontsizewidget.h b/src/frontend/display/btfontsizewidget.h index 40b94a1..7cd7e43 100644 --- a/src/frontend/display/btfontsizewidget.h +++ b/src/frontend/display/btfontsizewidget.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -15,22 +15,34 @@ #include <QComboBox> -class BtFontSizeWidget : public QComboBox { - Q_OBJECT +class QIntValidator; - public: - BtFontSizeWidget(QWidget* parent = 0); - ~BtFontSizeWidget(); - int fontSize() const; +class BtFontSizeWidget: public QComboBox { - public slots: - void setFontSize(int size); + Q_OBJECT - private slots: - virtual void changed(const QString& text); +public: /* Methods: */ - signals: - void fontSizeChanged( int ); -}; + BtFontSizeWidget(QWidget * parent = nullptr); + + int fontSize() const; + +public slots: + + void setFontSize(int size); + +private slots: + + virtual void changed(QString const & text); + +signals: + + void fontSizeChanged(int); + +private: /* Fields: */ + + QIntValidator * const m_validator; + +}; /* class BtFontSizeWidget { */ #endif diff --git a/src/frontend/display/bthtml.js b/src/frontend/display/bthtml.js index d56318f..79bffde 100644 --- a/src/frontend/display/bthtml.js +++ b/src/frontend/display/bthtml.js @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ diff --git a/src/frontend/display/bthtmljsobject.cpp b/src/frontend/display/bthtmljsobject.cpp index cb395cc..b2407e3 100644 --- a/src/frontend/display/bthtmljsobject.cpp +++ b/src/frontend/display/bthtmljsobject.cpp @@ -2,15 +2,15 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ #include "frontend/display/bthtmljsobject.h" +#include <memory> #include <QDrag> -#include <QSharedPointer> #include "backend/config/btconfig.h" #include "backend/keys/cswordkey.h" #include "backend/managers/referencemanager.h" @@ -76,7 +76,7 @@ void BtHtmlJsObject::mouseMoveEvent(const QString& attributes, const int& x, con // If we have not started dragging, but the mouse button is down, create a the mime data QPoint current(x, y); if ((current - m_dndData.startPos).manhattanLength() > 4 /*qApp->startDragDistance()*/ ) { - QDrag* drag = 0; + QDrag* drag = nullptr; if (!m_dndData.url.isEmpty()) { // create a new bookmark drag! QString moduleName = QString::null; @@ -89,7 +89,7 @@ void BtHtmlJsObject::mouseMoveEvent(const QString& attributes, const int& x, con drag->setMimeData(mimedata); //add real Bible text from module/key if (CSwordModuleInfo *module = CSwordBackend::instance()->findModuleByName(moduleName)) { - QSharedPointer<CSwordKey> key( CSwordKey::createInstance(module) ); + std::unique_ptr<CSwordKey> key(CSwordKey::createInstance(module)); key->setKey(keyName); mimedata->setText(key->strippedText()); // This works across applications! } @@ -118,24 +118,9 @@ void BtHtmlJsObject::timeOutEvent(const QString & attributes) { return; m_prev_attributes = ""; - CInfoDisplay::ListInfoData infoList; - const QStringList attrList = attributes.split("||"); - for (int i = 0; i < attrList.count(); i++) { - const QStringList attr(attrList[i].split('=')); - if (attr.count() == 2) { - if (attr[0] == "note") { - infoList.append(qMakePair(CInfoDisplay::Footnote, attr[1])); - } else if (attr[0] == "lemma") { - infoList.append(qMakePair(CInfoDisplay::Lemma, attr[1])); - } else if (attr[0] == "morph") { - infoList.append(qMakePair(CInfoDisplay::Morph, attr[1])); - } else if (attr[0] == "expansion") { - infoList.append(qMakePair(CInfoDisplay::Abbreviation, attr[1])); - } else if (attr[0] == "crossrefs") { - infoList.append(qMakePair(CInfoDisplay::CrossReference, attr[1])); - } - } - } + + Rendering::ListInfoData infoList(Rendering::detectInfo(attributes)); + // Update the mag if valid attributes were found if (!(infoList.isEmpty())) BibleTime::instance()->infoDisplay()->setInfo(infoList); diff --git a/src/frontend/display/bthtmljsobject.h b/src/frontend/display/bthtmljsobject.h index 3bf37f5..3e34d1d 100644 --- a/src/frontend/display/bthtmljsobject.h +++ b/src/frontend/display/bthtmljsobject.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ diff --git a/src/frontend/display/bthtmlreaddisplay.cpp b/src/frontend/display/bthtmlreaddisplay.cpp index 7b303e7..eace51f 100644 --- a/src/frontend/display/bthtmlreaddisplay.cpp +++ b/src/frontend/display/bthtmlreaddisplay.cpp @@ -2,16 +2,18 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ #include "frontend/display/bthtmlreaddisplay.h" -#include <QSharedPointer> +#include <memory> #include <QMenu> +#include <QDebug> #include <QString> +#include <QTimer> #include "backend/keys/cswordkey.h" #include "backend/managers/referencemanager.h" #include "bibletime.h" @@ -20,78 +22,115 @@ #include "frontend/cmdiarea.h" #include "frontend/display/bthtmljsobject.h" #include "frontend/displaywindow/cdisplaywindow.h" -#include "frontend/displaywindow/cdisplaywindowfactory.h" #include "frontend/displaywindow/creadwindow.h" +#include "util/btassert.h" +#include "util/btconnect.h" #include "util/directory.h" +#ifdef USEWEBENGINE +#include <QWebEngineScript> +#include <QWebEngineScriptCollection> +#endif using namespace InfoDisplay; -static QString javascript; // Initialized from file bthtml.js +#ifdef USEWEBENGINE +static QString javascriptFile = "btwebengine.js"; +#else +static QString javascriptFile = "bthtml.js"; +#endif + +static QString s_javascript; // Initialized from javascript file + +// This is s work around for Qt bug 51565 +// It is also documented in BibleTime bug #53 +static void clearChildFocusWidget(QWidget * widget) { + QWidget * childFocusedWidget = widget->focusWidget(); + if (childFocusedWidget) + childFocusedWidget->clearFocus(); +} BtHtmlReadDisplay::BtHtmlReadDisplay(CReadWindow* readWindow, QWidget* parentWidget) - : QWebPage(parentWidget), CReadDisplay(readWindow), m_magTimerId(0), m_view(0), m_jsObject(0) + : BtWebEnginePage(parentWidget), CReadDisplay(readWindow), m_magTimerId(0), m_view(nullptr), m_jsObject(nullptr) { - settings()->setAttribute(QWebSettings::JavascriptEnabled, true); m_view = new BtHtmlReadDisplayView(this, parentWidget ? parentWidget : readWindow, readWindow); m_view->setAcceptDrops(true); m_view->setPage(this); setParent(m_view); m_view->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - m_view->setHtml(""); - initJavascript(); - bool ok = connect(this, SIGNAL(loadFinished(bool)), this, SLOT(slotLoadFinished(bool))); - Q_ASSERT(ok); + loadJSObject(); + loadScripts(); + m_view->setHtml(""); // This sets focus on a child widget + clearChildFocusWidget(m_view); + + BT_CONNECT(this, SIGNAL(loadFinished(bool)), + this, SLOT(slotLoadFinished(bool))); } BtHtmlReadDisplay::~BtHtmlReadDisplay() { - setView(0); + setView(nullptr); } -// Read javascript into memory once and create the c++ javascript object -void BtHtmlReadDisplay::initJavascript() { +void BtHtmlReadDisplay::loadScripts() { namespace DU = util::directory; - // read bthtml.js javascript file once - if (javascript.isEmpty()) { - QString jsFile = DU::getJavascriptDir().canonicalPath() + "/bthtml.js"; - QFile file(jsFile); - if (file.open(QFile::ReadOnly)) { - while (!file.atEnd()) { - QByteArray line = file.readLine(); - javascript = javascript + line; - } - file.close(); + QString jScript; +#ifdef USEWEBENGINE + jScript = readJavascript(":/qtwebchannel/qwebchannel.js"); +#endif + QString jsFile = DU::getJavascriptDir().canonicalPath() + "/" + javascriptFile; + jScript += readJavascript(jsFile); + +#ifdef USEWEBENGINE + // Directly load javascript into QWebEngine + QWebEngineScript script; + script.setInjectionPoint(QWebEngineScript::DocumentReady); + script.setWorldId(QWebEngineScript::MainWorld); + script.setSourceCode(jScript); + script.setName("script1"); + scripts().insert(script); +#else + // Save javascript and load each time the document is loaded (setHtml) + s_javascript = jScript; +#endif +} + +QString BtHtmlReadDisplay::readJavascript(const QString& jsFileName) { + QString javascript; + QFile file(jsFileName); + if (file.open(QFile::ReadOnly)) { + while (!file.atEnd()) { + QString line = file.readLine(); + javascript = javascript + line; } + file.close(); + } else { + qWarning() << objectName() << ": Missing " +jsFileName; } - - // Setup BtHtmlJsObject which will be called from javascript - m_jsObject = new BtHtmlJsObject(this); - m_jsObject->setObjectName("btHtmlJsObject"); + return javascript; } // When the QWebFrame is cleared, this function is called to install the -// javascript object (BtHtmlJsObject class) into the Javascript model +// javascript object (BtHtmlJsObject class) into the Javascript model. +// It is called only once with QWebEngine. void BtHtmlReadDisplay::loadJSObject() { // Starting with Qt 4.7.4 with QtWebKit 2.2 stronger security checking occurs. // The BtHtmlJsObject that is associated with a given load of a page is rejected // as causing a cross site security problem when a new page is loaded. Deleting // the object and creating it new for each page loaded allows the object to access // javascript variables without this security issue. - if (m_jsObject != 0) + if (m_jsObject != nullptr) delete m_jsObject; m_jsObject = new BtHtmlJsObject(this); - m_jsObject->setObjectName("btHtmlJsObject"); - - mainFrame()->addToJavaScriptWindowObject(m_jsObject->objectName(), m_jsObject); + addJavaScriptObject("btHtmlJsObject", m_jsObject); } const QString BtHtmlReadDisplay::text( const CDisplay::TextType format, const CDisplay::TextPart part) { switch (part) { case Document: { if (format == HTMLText) { - return mainFrame()->toHtml(); + return getCurrentSource(); } else { CDisplayWindow* window = parentWindow(); @@ -100,21 +139,14 @@ const QString BtHtmlReadDisplay::text( const CDisplay::TextType format, const CD //This is never used for Bibles, so it is not implemented for //them. If it should be, see CReadDisplay::print() for example //code. - Q_ASSERT(module->type() == CSwordModuleInfo::Lexicon || + BT_ASSERT(module->type() == CSwordModuleInfo::Lexicon || module->type() == CSwordModuleInfo::Commentary || module->type() == CSwordModuleInfo::GenericBook); if (module->type() == CSwordModuleInfo::Lexicon || module->type() == CSwordModuleInfo::Commentary || module->type() == CSwordModuleInfo::GenericBook) { - /// \todo This is a BAD HACK, we have to fnd a better solution to manage the settings now - FilterOptions filterOptions; - filterOptions.footnotes = false; - filterOptions.strongNumbers = false; - filterOptions.morphTags = false; - filterOptions.lemmas = false; - filterOptions.scriptureReferences = false; - filterOptions.textualVariants = false; + FilterOptions filterOptions; CSwordBackend::instance()->setFilterOptions(filterOptions); return QString(key->strippedText()).append("\n(") @@ -154,7 +186,7 @@ const QString BtHtmlReadDisplay::text( const CDisplay::TextType format, const CD ReferenceManager::decodeHyperlink(activeAnchor(), moduleName, keyName, type); if (CSwordModuleInfo *module = CSwordBackend::instance()->findModuleByName(moduleName)) { - QSharedPointer<CSwordKey> key( CSwordKey::createInstance(module) ); + std::unique_ptr<CSwordKey> key(CSwordKey::createInstance(module)); key->setKey(keyName); return key->strippedText(); @@ -169,18 +201,10 @@ const QString BtHtmlReadDisplay::text( const CDisplay::TextType format, const CD ReferenceManager::decodeHyperlink(activeAnchor(), moduleName, keyName, type); if (CSwordModuleInfo *module = CSwordBackend::instance()->findModuleByName(moduleName)) { - QSharedPointer<CSwordKey> key( CSwordKey::createInstance(module) ); + std::unique_ptr<CSwordKey> key(CSwordKey::createInstance(module)); key->setKey(keyName); - /// \todo This is a BAD HACK, we have to fnd a better solution to manage the settings now FilterOptions filterOptions; - filterOptions.footnotes = false; - filterOptions.strongNumbers = false; - filterOptions.morphTags = false; - filterOptions.lemmas = false; - filterOptions.scriptureReferences = false; - filterOptions.textualVariants = false; - CSwordBackend::instance()->setFilterOptions(filterOptions); return QString(key->strippedText()).append("\n(") @@ -201,21 +225,23 @@ const QString BtHtmlReadDisplay::text( const CDisplay::TextType format, const CD return QString::null; } -// Puts html text and javascript into QWebView +// Puts html text and javascript into BtWebEngineView void BtHtmlReadDisplay::setText( const QString& newText ) { - QString jsText = newText; +#ifndef USEWEBENGINE + // Inject javascript into the document jsText.replace( QString("</body>"), - QString("<script type=\"text/javascript\">").append(javascript).append("</script></body>") + QString("<script type=\"text/javascript\">").append(s_javascript).append("</script></body>") ); // Disconnect any previous connections and connect to slot that loads the javascript object QWebFrame* frame = mainFrame(); - disconnect(frame, SIGNAL(javaScriptWindowObjectCleared()), 0, 0); - bool ok = connect(frame, SIGNAL(javaScriptWindowObjectCleared()), this, SLOT(loadJSObject())); - Q_ASSERT(ok); + disconnect(frame, SIGNAL(javaScriptWindowObjectCleared()), nullptr, nullptr); + BT_CONNECT(frame, SIGNAL(javaScriptWindowObjectCleared()), + this, SLOT(loadJSObject())); +#endif // Send text to the html viewer m_view->setHtml(jsText); @@ -228,10 +254,8 @@ QString BtHtmlReadDisplay::getCurrentSource( ) { } // See if any text is selected -bool BtHtmlReadDisplay::hasSelection() { - if (selectedText().isEmpty()) - return false; - return true; +bool BtHtmlReadDisplay::hasSelection() const { + return !selectedText().isEmpty(); } // Reimplementation @@ -242,19 +266,26 @@ QWidget* BtHtmlReadDisplay::view() { // Select all text in the viewer void BtHtmlReadDisplay::selectAll() { - m_view->triggerPageAction( QWebPage::SelectAll, true ); + BtWebEnginePage::selectAll(); } -// Scroll QWebView to the correct location as specified by the anchor +// Scroll BtWebEngineView to the correct location as specified by the anchor void BtHtmlReadDisplay::moveToAnchor( const QString& anchor ) { -#if QT_VERSION >= 0x040700 - mainFrame()->scrollToAnchor(anchor); +#ifdef USEWEBENGINE + // Rendering in QWebEngine is asynchronous, must delay before scroll to anchor + // TODO - find a better solution + m_currentAnchorCache = anchor; + QTimer::singleShot(180, this, SLOT(slotDelayedMoveToAnchor())); #else - slotGoToAnchor(anchor); + mainFrame()->scrollToAnchor(anchor); #endif } -// Scroll the QWebView to the correct location specified by anchor +void BtHtmlReadDisplay::slotDelayedMoveToAnchor() { + m_jsObject->moveToAnchor(m_currentAnchorCache); +} + +// Scroll the BtWebEngineView to the correct location specified by anchor void BtHtmlReadDisplay::slotGoToAnchor(const QString& anchor) { m_jsObject->moveToAnchor(anchor); } @@ -287,11 +318,11 @@ void BtHtmlReadDisplay::javaScriptConsoleMessage (const QString& message, int li // ----------------- BtHtmlReadDisplayView ------------------------------------- BtHtmlReadDisplayView::BtHtmlReadDisplayView(BtHtmlReadDisplay* displayWidget, QWidget* parent, CReadWindow* readWindow) - : QWebView(parent), m_display(displayWidget), m_readWindow(readWindow) { + : BtWebEngineView(parent), m_display(displayWidget), m_readWindow(readWindow) { } BtHtmlReadDisplayView::~BtHtmlReadDisplayView() { - setPage(0); + setPage(nullptr); } // Create the right mouse context menus @@ -306,9 +337,9 @@ void BtHtmlReadDisplayView::dropEvent( QDropEvent* e ) { if (e->mimeData()->hasFormat("BibleTime/Bookmark")) { //see docs for BTMimeData and QMimeData const QMimeData* mimedata = e->mimeData(); - if (mimedata != 0) { + if (mimedata != nullptr) { const BTMimeData* btmimedata = qobject_cast<const BTMimeData*>(mimedata); - if (btmimedata != 0) { + if (btmimedata != nullptr) { BookmarkItem item = (qobject_cast<const BTMimeData*>(e->mimeData()))->bookmark(); m_display->connectionsProxy()->emitReferenceDropped(item.key()); e->acceptProposedAction(); @@ -320,28 +351,28 @@ void BtHtmlReadDisplayView::dropEvent( QDropEvent* e ) { // e->ignore(); } -// Reimplementation from QWebView +// Reimplementation from BtWebEngineView void BtHtmlReadDisplayView::dragEnterEvent( QDragEnterEvent* e ) { if ( ! e->mimeData()->hasFormat("BibleTime/Bookmark")) return; const QMimeData* mimedata = e->mimeData(); - if (mimedata == 0) + if (mimedata == nullptr) return; const BTMimeData* btmimedata = qobject_cast<const BTMimeData*>(mimedata); - if (btmimedata == 0) + if (btmimedata == nullptr) return; BookmarkItem item = (qobject_cast<const BTMimeData*>(e->mimeData()))->bookmark(); QString moduleName = item.module(); CSwordModuleInfo *m = CSwordBackend::instance()->findModuleByName(moduleName); - Q_ASSERT(m); - if (m == 0) - return; + BT_ASSERT(m); CSwordModuleInfo::ModuleType bookmarkType = m->type(); - CSwordModuleInfo::ModuleType windowType = CDisplayWindowFactory::getModuleType(m_readWindow); + CSwordModuleInfo::ModuleType windowType = CSwordModuleInfo::Unknown; + if (m_readWindow) + windowType = m_readWindow->moduleType(); // Is bible reference bookmark compatible with the window type? if ((bookmarkType == CSwordModuleInfo::Bible || @@ -349,19 +380,25 @@ void BtHtmlReadDisplayView::dragEnterEvent( QDragEnterEvent* e ) { if (windowType == CSwordModuleInfo::Bible || windowType == CSwordModuleInfo::Commentary) e->acceptProposedAction(); +#ifdef USEWEBENGINE + BtWebEngineView::dragEnterEvent(e); // Fix crash, QTBUG-54896, BT bug #70 +#endif return; } // Is reference type compatible with window type if (bookmarkType == windowType) { e->acceptProposedAction(); +#ifdef USEWEBENGINE + BtWebEngineView::dragEnterEvent(e); // Fix crash, QTBUG-54896, BT bug #70 +#endif return; } return; } -// Reimplementation from QWebView +// Reimplementation from BtWebEngineView void BtHtmlReadDisplayView::dragMoveEvent( QDragMoveEvent* e ) { if (e->mimeData()->hasFormat("BibleTime/Bookmark")) { e->acceptProposedAction(); diff --git a/src/frontend/display/bthtmlreaddisplay.h b/src/frontend/display/bthtmlreaddisplay.h index 0a703d3..21fcd67 100644 --- a/src/frontend/display/bthtmlreaddisplay.h +++ b/src/frontend/display/bthtmlreaddisplay.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -12,15 +12,14 @@ #ifndef BTHTMLREADDISPLAY_H #define BTHTMLREADDISPLAY_H +#include "frontend/btwebengineview.h" +#include "frontend/btwebenginepage.h" #include "frontend/display/creaddisplay.h" -#include <QWebPage> #include <QDragEnterEvent> #include <QDropEvent> #include <QPoint> #include <QTimerEvent> -#include <QWebView> -#include <QWebFrame> #include "frontend/display/bthtmljsobject.h" @@ -29,36 +28,35 @@ class BtHtmlReadDisplayView; /** The implementation for the HTML read display. * @author The BibleTime team */ -class BtHtmlReadDisplay : public QWebPage, public CReadDisplay { +class BtHtmlReadDisplay : public BtWebEnginePage, public CReadDisplay { Q_OBJECT friend class BtHtmlReadDisplayView; public: - BtHtmlReadDisplay( CReadWindow* readWindow, QWidget* parent = 0 ); - virtual ~BtHtmlReadDisplay(); + BtHtmlReadDisplay( CReadWindow* readWindow, QWidget* parent = nullptr ); + ~BtHtmlReadDisplay() override; //reimplemented functions from CDisplay // Returns the right text part in the specified format. - virtual const QString text( const CDisplay::TextType format = CDisplay::HTMLText, - const CDisplay::TextPart part = CDisplay::Document ); + const QString text(const CDisplay::TextType format = CDisplay::HTMLText, + const CDisplay::TextPart part = CDisplay::Document) + override; - // Sets the new text for this display widget. - virtual void setText( const QString& newText ); - // Get the current source - virtual QString getCurrentSource(); + void setText( const QString& newText ) override; - virtual bool hasSelection(); + QString getCurrentSource(); - // Reimplementation. - virtual void selectAll(); - virtual void moveToAnchor( const QString& anchor ); - virtual void openFindTextDialog(); - inline virtual QString getCurrentNodeInfo() const { + bool hasSelection() const override; + + void selectAll() override; + void moveToAnchor( const QString& anchor ) override; + void openFindTextDialog() override; + inline QString getCurrentNodeInfo() const override { return m_nodeInfo; } - QWidget* view(); + QWidget* view() override; void setLemma(const QString& lemma); public slots: @@ -94,8 +92,14 @@ class BtHtmlReadDisplay : public QWebPage, public CReadDisplay { void javaScriptConsoleMessage (const QString & message, int lineNumber, const QString & sourceID ); #endif + private slots: + void slotDelayedMoveToAnchor(); + private: void initJavascript(); + void loadScripts(); + QString readJavascript(const QString& jsFileName); + BtHtmlReadDisplayView* m_view; BtHtmlJsObject* m_jsObject; QString m_currentAnchorCache; @@ -103,21 +107,21 @@ class BtHtmlReadDisplay : public QWebPage, public CReadDisplay { }; -class BtHtmlReadDisplayView : public QWebView { +class BtHtmlReadDisplayView : public BtWebEngineView { Q_OBJECT protected: friend class BtHtmlReadDisplay; - void contextMenuEvent(QContextMenuEvent* event); + void contextMenuEvent(QContextMenuEvent* event) override; BtHtmlReadDisplayView(BtHtmlReadDisplay* display, QWidget* parent, CReadWindow* readWindow); ~BtHtmlReadDisplayView(); - bool event(QEvent* e); + bool event(QEvent* e) override; private: BtHtmlReadDisplay* m_display; CReadWindow* m_readWindow; - void dropEvent( QDropEvent* e ); - void dragEnterEvent( QDragEnterEvent* e ); - void dragMoveEvent( QDragMoveEvent* e ); + void dropEvent( QDropEvent* e ) override; + void dragEnterEvent( QDragEnterEvent* e ) override; + void dragMoveEvent( QDragMoveEvent* e ) override; }; #endif diff --git a/src/frontend/display/btwebengine.js b/src/frontend/display/btwebengine.js new file mode 100644 index 0000000..f0bdfb3 --- /dev/null +++ b/src/frontend/display/btwebengine.js @@ -0,0 +1,140 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +var X = 0; +var Y = 0; +var attribs = []; +var eventType = ""; +var prevNode = 0; +var currentNode = 0; +var timeOutId = -1; + +// Scroll window to html anchor +function gotoAnchor(anchor) +{ + document.location=document.location + "#" + anchor; +} + +// Mouse button clicked handler +function mouseClickHandler (mEvent) +{ + var mTarget = mEvent.target; + if (mTarget) + { + var url = ""; + var tmpUrl = mEvent.target.getAttribute("href"); + if (tmpUrl) + url = tmpUrl; + btHtmlJsObject.mouseClick(url); + } +} + +// Mouse button pressed down handler +function mouseDownHandler (mEvent) +{ + var node; + var url = ""; + var lemma = ""; + var mTarget = mEvent.target; + if (mTarget) + { + var tmpUrl = mEvent.target.getAttribute("href"); + if (tmpUrl) + url = tmpUrl; + var tmpLemma = mEvent.target.getAttribute("lemma"); + if (tmpLemma) + lemma = tmpLemma; + } + + if (mEvent.button === 2) // Right mouse button + { + btHtmlJsObject.mouseDownRight(url, lemma); + } + if (mEvent.button === 0) // Left mouse button + { + if (!(mEvent.target === undefined)) + { + var X = mEvent.clientX; + var Y = mEvent.clientY; + btHtmlJsObject.mouseDownLeft(url, X, Y); + } + } +} + +// Mouse moved event handler +function mouseMoveHandler (mEvent) +{ + currentNode = mEvent.target; + var shiftKey = mEvent.shiftKey; + var x = mEvent.clientX; + var y = mEvent.clientY; + var node = mEvent.target; + if ( node != undefined && node != prevNode ) + { + prevNode = node; + var attribList; + if (node.attributes.length > 0) + { + attribList = getNodeAttributes(node); + btHtmlJsObject.mouseMoveEvent(attribList, x, y, shiftKey); + } + } +} + +// Get attributes of a DOM node and put into a single string +function getNodeAttributes(node) +{ + var attribList = ''; + if (node.attributes.length > 0) + { + var i; + for (i = 0; i < node.attributes.length; i++) + { + attribList = attribList + node.attributes[i].nodeName + '=' + node.attributes[i].value + '||'; + } + } + return attribList; +} + +// Start a timer event +function startTimer(time) +{ + clearTimeout(timeOutId); + timeOutId = setTimeout("timerEvent()",time); +} + +// Handles a timer event +function timerEvent() +{ + timeOutId = -1; + if (currentNode != 0 && currentNode == prevNode) + { + var attributes = getNodeAttributes(currentNode); + btHtmlJsObject.timeOutEvent(attributes); + } +} + +function selectAll () { + console.log("select all"); +} + +document.getElementsByTagName("body")[0].addEventListener ('mousedown', function (eve) { mouseDownHandler (eve); }, true); +document.getElementsByTagName("body")[0].addEventListener ('mousemove', function (eve) { mouseMoveHandler (eve); }, true); +document.getElementsByTagName("body")[0].addEventListener ('click', function (eve) { mouseClickHandler (eve); }, true); + +var btHtmlJsObject = 0; + +new QWebChannel(qt.webChannelTransport, function (channel) { + btHtmlJsObject = channel.objects.btHtmlJsObject; + btHtmlJsObject.startTimer.connect(startTimer); + btHtmlJsObject.gotoAnchor.connect(gotoAnchor); + btHtmlJsObject.selectAll.connect(selectAll); + }); + + diff --git a/src/frontend/display/cdisplay.cpp b/src/frontend/display/cdisplay.cpp index a5c5bc8..b53d080 100644 --- a/src/frontend/display/cdisplay.cpp +++ b/src/frontend/display/cdisplay.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -102,7 +102,7 @@ void CDisplayConnections::openFindTextDialog() { CDisplay::CDisplay(CDisplayWindow* parent) : m_parentWindow(parent), m_connections( new CDisplayConnections( this ) ), - m_popup(0) {} + m_popup(nullptr) {} CDisplay::~CDisplay() { delete m_connections; @@ -127,7 +127,7 @@ bool CDisplay::save( const CDisplay::TextType format, const CDisplay::TextPart p break; } - const QString filename = QFileDialog::getSaveFileName(0, QObject::tr("Save document ..."), "", filter); + const QString filename = QFileDialog::getSaveFileName(nullptr, QObject::tr("Save document ..."), "", filter); if (!filename.isEmpty()) { util::tool::savePlainFile(filename, content); diff --git a/src/frontend/display/cdisplay.h b/src/frontend/display/cdisplay.h index de971d5..6650322 100644 --- a/src/frontend/display/cdisplay.h +++ b/src/frontend/display/cdisplay.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -61,7 +61,7 @@ class CDisplay { /** * Returns true if the display widget has a selection. Otherwise false. */ - virtual bool hasSelection() = 0; + virtual bool hasSelection() const = 0; /** * Returns the view of this display widget. */ @@ -157,10 +157,6 @@ class CDisplayConnections : public QObject { private: CDisplay* m_display; - struct { - QString module; - QString key; - } m_referenceClickedCache; }; #endif diff --git a/src/frontend/display/chtmlwritedisplay.cpp b/src/frontend/display/chtmlwritedisplay.cpp index 829f607..709f10f 100644 --- a/src/frontend/display/chtmlwritedisplay.cpp +++ b/src/frontend/display/chtmlwritedisplay.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -20,8 +20,9 @@ #include "frontend/display/btfontsizewidget.h" #include "frontend/displaywindow/btactioncollection.h" #include "frontend/displaywindow/chtmlwritewindow.h" +#include "util/btassert.h" +#include "util/btconnect.h" #include "util/cresmgr.h" -#include "util/geticon.h" class BtActionCollection; @@ -44,76 +45,83 @@ CHTMLWriteDisplay::CHTMLWriteDisplay(CHTMLWriteWindow * parentWindow, QWidget* p //--------------------bold toggle------------------------- m_actions.bold = new QAction( - util::getIcon(CResMgr::displaywindows::writeWindow::boldText::icon), + CResMgr::displaywindows::writeWindow::boldText::icon(), tr("Bold"), this); m_actions.bold->setCheckable(true); m_actions.bold->setChecked(f.bold()); m_actions.bold->setShortcut(CResMgr::displaywindows::writeWindow::boldText::accel); m_actions.bold->setToolTip( tr("Bold") ); - connect(m_actions.bold, SIGNAL(toggled(bool)), - this, SLOT(toggleBold(bool)), Qt::DirectConnection); + BT_CONNECT(m_actions.bold, SIGNAL(toggled(bool)), + this, SLOT(toggleBold(bool)), + Qt::DirectConnection); //--------------------italic toggle------------------------- m_actions.italic = new QAction( - util::getIcon(CResMgr::displaywindows::writeWindow::italicText::icon), + CResMgr::displaywindows::writeWindow::italicText::icon(), tr("Italic"), this ); m_actions.italic->setCheckable(true); m_actions.italic->setChecked(f.italic()); m_actions.bold->setShortcut(CResMgr::displaywindows::writeWindow::italicText::accel); - connect(m_actions.italic, SIGNAL(toggled(bool)), - this, SLOT(toggleItalic(bool)), Qt::DirectConnection); + BT_CONNECT(m_actions.italic, SIGNAL(toggled(bool)), + this, SLOT(toggleItalic(bool)), + Qt::DirectConnection); m_actions.italic->setToolTip( tr("Italic") ); //--------------------underline toggle------------------------- m_actions.underline = new QAction( - util::getIcon(CResMgr::displaywindows::writeWindow::underlinedText::icon), + CResMgr::displaywindows::writeWindow::underlinedText::icon(), tr("Underline"), this ); m_actions.underline->setCheckable(true); m_actions.underline->setChecked(f.underline()); m_actions.underline->setShortcut(CResMgr::displaywindows::writeWindow::underlinedText::accel); - connect(m_actions.underline, SIGNAL(toggled(bool)), - this, SLOT(toggleUnderline(bool)), Qt::DirectConnection); + BT_CONNECT(m_actions.underline, SIGNAL(toggled(bool)), + this, SLOT(toggleUnderline(bool)), + Qt::DirectConnection); m_actions.underline->setToolTip( tr("Underline") ); //--------------------align left toggle------------------------- m_actions.alignLeft = new QAction( - util::getIcon(CResMgr::displaywindows::writeWindow::alignLeft::icon), + CResMgr::displaywindows::writeWindow::alignLeft::icon(), tr("Left"), this); m_actions.alignLeft->setCheckable(true); m_actions.alignLeft->setShortcut(CResMgr::displaywindows::writeWindow::alignLeft::accel); - connect(m_actions.alignLeft, SIGNAL(toggled(bool)), - this, SLOT(alignLeft(bool)), Qt::DirectConnection); + BT_CONNECT(m_actions.alignLeft, SIGNAL(toggled(bool)), + this, SLOT(alignLeft(bool)), + Qt::DirectConnection); m_actions.alignLeft->setToolTip( tr("Align left") ); //--------------------align center toggle------------------------- m_actions.alignCenter = new QAction( - util::getIcon(CResMgr::displaywindows::writeWindow::alignCenter::icon), + CResMgr::displaywindows::writeWindow::alignCenter::icon(), tr("Center"), this); m_actions.alignCenter->setCheckable(true); m_actions.alignCenter->setShortcut(CResMgr::displaywindows::writeWindow::alignCenter::accel); - connect(m_actions.alignCenter, SIGNAL(toggled(bool)), - this, SLOT(alignCenter(bool)), Qt::DirectConnection); + BT_CONNECT(m_actions.alignCenter, SIGNAL(toggled(bool)), + this, SLOT(alignCenter(bool)), + Qt::DirectConnection); m_actions.alignCenter->setToolTip( tr("Center") ); //--------------------align right toggle------------------------- m_actions.alignRight = new QAction( - util::getIcon(CResMgr::displaywindows::writeWindow::alignRight::icon), + CResMgr::displaywindows::writeWindow::alignRight::icon(), tr("Right"), this); m_actions.alignRight->setCheckable(true); m_actions.alignRight->setShortcut(CResMgr::displaywindows::writeWindow::alignRight::accel); - connect(m_actions.alignRight, SIGNAL(toggled(bool)), - this, SLOT(alignRight(bool)), Qt::DirectConnection); + BT_CONNECT(m_actions.alignRight, SIGNAL(toggled(bool)), + this, SLOT(alignRight(bool)), + Qt::DirectConnection); m_actions.alignRight->setToolTip( tr("Align right") ); setAcceptRichText(true); setAcceptDrops(true); viewport()->setAcceptDrops(true); - connect(this, SIGNAL(currentCharFormatChanged(QTextCharFormat)), - this, SLOT(slotCurrentCharFormatChanged(QTextCharFormat)), Qt::DirectConnection); + BT_CONNECT(this, SIGNAL(currentCharFormatChanged(QTextCharFormat)), + this, SLOT(slotCurrentCharFormatChanged(QTextCharFormat)), + Qt::DirectConnection); } void CHTMLWriteDisplay::setText(const QString & newText) { @@ -162,7 +170,7 @@ void CHTMLWriteDisplay::alignRight(bool set) { /** The text's alignment changed. Enable the right buttons. */ void CHTMLWriteDisplay::alignmentChanged( int a ) { - Q_ASSERT(!m_handingFormatChangeFromEditor); + BT_ASSERT(!m_handingFormatChangeFromEditor); bool alignLeft = false; bool alignCenter = false; bool alignRight = false; @@ -187,7 +195,7 @@ void CHTMLWriteDisplay::alignmentChanged( int a ) { } void CHTMLWriteDisplay::slotCurrentCharFormatChanged(const QTextCharFormat &) { - Q_ASSERT(!m_handingFormatChangeFromEditor); + BT_ASSERT(!m_handingFormatChangeFromEditor); m_handingFormatChangeFromEditor = true; QFont f = currentFont(); emit signalFontChanged(f); @@ -206,13 +214,7 @@ void CHTMLWriteDisplay::slotCurrentCharFormatChanged(const QTextCharFormat &) { void CHTMLWriteDisplay::slotFontSizeChosen(int newSize) { if (!m_handingFormatChangeFromEditor) - setFontPointSize((qreal)newSize); -} - -/** Is called when a new color was selected. */ -void CHTMLWriteDisplay::slotFontColorChosen( const QColor& c) { - if (!m_handingFormatChangeFromEditor) - setTextColor( c ); + setFontPointSize(static_cast<qreal>(newSize)); } void CHTMLWriteDisplay::slotFontFamilyChosen(const QFont& font) { @@ -230,36 +232,34 @@ void CHTMLWriteDisplay::setupToolbar(QToolBar * bar, BtActionCollection * action fontFamilyCombo->setCurrentFont(f); fontFamilyCombo->setToolTip( tr("Font") ); bar->addWidget(fontFamilyCombo); - bool ok = connect(fontFamilyCombo, SIGNAL(currentFontChanged(const QFont&)), - this, SLOT(slotFontFamilyChosen(const QFont&)), Qt::DirectConnection); - Q_ASSERT(ok); - ok = connect(this, SIGNAL(signalFontChanged(const QFont&)), - fontFamilyCombo, SLOT(setCurrentFont(const QFont&)), Qt::DirectConnection); - Q_ASSERT(ok); + BT_CONNECT(fontFamilyCombo, SIGNAL(currentFontChanged(QFont const &)), + this, SLOT(slotFontFamilyChosen(QFont const &)), + Qt::DirectConnection); + BT_CONNECT(this, SIGNAL(signalFontChanged(QFont const &)), + fontFamilyCombo, SLOT(setCurrentFont(QFont const &)), + Qt::DirectConnection); //--------------------font size chooser------------------------- BtFontSizeWidget* fontSizeChooser = new BtFontSizeWidget(this); fontSizeChooser->setFontSize(f.pointSize()); fontSizeChooser->setToolTip( tr("Font size") ); bar->addWidget(fontSizeChooser); - ok = connect(fontSizeChooser, SIGNAL(fontSizeChanged(int)), - this, SLOT(slotFontSizeChosen(int)), Qt::DirectConnection); - Q_ASSERT(ok); - ok = connect(this, SIGNAL(signalFontSizeChanged(int)), - fontSizeChooser, SLOT(setFontSize(int)), Qt::DirectConnection); - Q_ASSERT(ok); + BT_CONNECT(fontSizeChooser, SIGNAL(fontSizeChanged(int)), + this, SLOT(slotFontSizeChosen(int)), + Qt::DirectConnection); + BT_CONNECT(this, SIGNAL(signalFontSizeChanged(int)), + fontSizeChooser, SLOT(setFontSize(int)), Qt::DirectConnection); //--------------------color button------------------------- BtColorWidget* fontColorChooser = new BtColorWidget(); fontColorChooser->setColor(textColor()); fontColorChooser->setToolTip(tr("Font color")); bar->addWidget(fontColorChooser); - ok = connect(fontColorChooser, SIGNAL(changed(const QColor&)), - this, SLOT(slotFontColorChosen(const QColor&)), Qt::DirectConnection); - Q_ASSERT(ok); - ok = connect(this, SIGNAL(signalFontColorChanged(const QColor&)), - fontColorChooser, SLOT(setColor(QColor)), Qt::DirectConnection); - Q_ASSERT(ok); + BT_CONNECT(fontColorChooser, SIGNAL(changed(QColor const &)), + this, SLOT(setTextColor(QColor const &)), + Qt::DirectConnection); + BT_CONNECT(this, SIGNAL(signalFontColorChanged(QColor const &)), + fontColorChooser, SLOT(setColor(QColor)), Qt::DirectConnection); bar->addSeparator(); diff --git a/src/frontend/display/chtmlwritedisplay.h b/src/frontend/display/chtmlwritedisplay.h index 1bc9dd0..f94516d 100644 --- a/src/frontend/display/chtmlwritedisplay.h +++ b/src/frontend/display/chtmlwritedisplay.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -32,22 +32,13 @@ class CHTMLWriteDisplay : public CPlainWriteDisplay { Q_OBJECT public: - CHTMLWriteDisplay(CHTMLWriteWindow * parentWindow, QWidget * parent = 0); + CHTMLWriteDisplay(CHTMLWriteWindow * parentWindow, QWidget * parent = nullptr); - /** - * Sets the new text for this display widget. (CPlainWriteDisplay). - */ - virtual void setText( const QString& newText ); - /** - * Returns the text of this edit widget. (CPlainWriteDisplay). - */ - virtual const QString plainText(); + void setText( const QString& newText ) override; - /** - * Creates the necessary action objects and puts them on the toolbar. - * (CPlainWriteDisplay) - */ - virtual void setupToolbar(QToolBar * bar, BtActionCollection * actionCollection); + const QString plainText() override; + + void setupToolbar(QToolBar * bar, BtActionCollection * actionCollection) override; protected: @@ -64,7 +55,6 @@ class CHTMLWriteDisplay : public CPlainWriteDisplay { void slotFontFamilyChosen(const QFont&); void slotFontSizeChosen(int); - void slotFontColorChosen( const QColor& ); void slotCurrentCharFormatChanged(const QTextCharFormat &); diff --git a/src/frontend/display/cplainwritedisplay.cpp b/src/frontend/display/cplainwritedisplay.cpp index e4b22d5..5d04067 100644 --- a/src/frontend/display/cplainwritedisplay.cpp +++ b/src/frontend/display/cplainwritedisplay.cpp @@ -2,24 +2,24 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ #include "frontend/display/cplainwritedisplay.h" -#include <QSharedPointer> +#include <memory> #include <QDragEnterEvent> #include <QDragMoveEvent> #include <QDropEvent> #include <QMenu> - #include "backend/keys/cswordkey.h" #include "frontend/cdragdrop.h" #include "frontend/displaywindow/btactioncollection.h" #include "frontend/displaywindow/cdisplaywindow.h" #include "frontend/displaywindow/cplainwritewindow.h" +#include "util/btconnect.h" CPlainWriteDisplay::CPlainWriteDisplay(CPlainWriteWindow * parentWindow, QWidget * parent) @@ -30,8 +30,8 @@ CPlainWriteDisplay::CPlainWriteDisplay(CPlainWriteWindow * parentWindow, QWidget setAcceptDrops(true); viewport()->setAcceptDrops(true); - connect(this, SIGNAL(textChanged()), - connectionsProxy(), SLOT(emitTextChanged())); + BT_CONNECT(this, SIGNAL(textChanged()), + connectionsProxy(), SLOT(emitTextChanged())); } /** Reimplementation. */ @@ -48,7 +48,7 @@ void CPlainWriteDisplay::setText( const QString& newText ) { QTextEdit::setText(text); } -bool CPlainWriteDisplay::hasSelection() { +bool CPlainWriteDisplay::hasSelection() const { /// \todo test this return textCursor().hasSelection(); } @@ -123,7 +123,7 @@ void CPlainWriteDisplay::dropEvent( QDropEvent* e ) { for (it = items.begin(); it != items.end(); ++it) { CSwordModuleInfo *module = CSwordBackend::instance()->findModuleByName((*it).module()); - QSharedPointer<CSwordKey> key( CSwordKey::createInstance(module) ); + std::unique_ptr<CSwordKey> key(CSwordKey::createInstance(module)); key->setKey((*it).key()); QString moduleText = key->strippedText(); diff --git a/src/frontend/display/cplainwritedisplay.h b/src/frontend/display/cplainwritedisplay.h index dad57a1..8ff095b 100644 --- a/src/frontend/display/cplainwritedisplay.h +++ b/src/frontend/display/cplainwritedisplay.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -26,32 +26,23 @@ class QToolBar; class CPlainWriteDisplay : public QTextEdit, public CDisplay { public: - CPlainWriteDisplay(CPlainWriteWindow * parentWindow, QWidget * parent = 0); + CPlainWriteDisplay(CPlainWriteWindow * parentWindow, QWidget * parent = nullptr); - /** - * Reimplementation. - */ - virtual void selectAll(); - /** - * Sets the new text for this display widget. - */ - virtual void setText( const QString& newText ); - /** - * Returns true if the display widget has a selection. Otherwise false. - */ - virtual bool hasSelection(); - /** - * Returns the view of this display widget. - */ - virtual QWidget* view(); - virtual const QString text( const CDisplay::TextType format = CDisplay::HTMLText, const CDisplay::TextPart part = CDisplay::Document ); + void selectAll() override; - /** - Reimplemented from CDisplay. - */ - virtual inline void print(const CDisplay::TextPart, - const DisplayOptions &, - const FilterOptions &) {} + void setText(const QString & newText) override; + + bool hasSelection() const override; + + QWidget* view() override; + + const QString text(const CDisplay::TextType format = CDisplay::HTMLText, + const CDisplay::TextPart part = CDisplay::Document ) + override; + + inline void print(const CDisplay::TextPart, + const DisplayOptions &, + const FilterOptions &) override {} virtual bool isModified() const; /** @@ -69,18 +60,11 @@ class CPlainWriteDisplay : public QTextEdit, public CDisplay { protected: - /** - * Reimplementation from QTextEdit to manage drops of our drag and drop objects. - */ - virtual void dropEvent( QDropEvent* e ); - /** - * Reimplementation from QTextEdit to insert the text of a dragged reference into the edit view. - */ - virtual void dragEnterEvent( QDragEnterEvent* e ); - /** - * Reimplementation from QTextEdit to insert the text of a dragged reference into the edit view. - */ - virtual void dragMoveEvent( QDragMoveEvent* e ); + void dropEvent(QDropEvent * e) override; + + void dragEnterEvent(QDragEnterEvent * e) override; + + void dragMoveEvent(QDragMoveEvent * e) override; }; diff --git a/src/frontend/display/creaddisplay.cpp b/src/frontend/display/creaddisplay.cpp index f5c3459..cf4374c 100644 --- a/src/frontend/display/creaddisplay.cpp +++ b/src/frontend/display/creaddisplay.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -28,7 +28,7 @@ CReadDisplay::CReadDisplay(CReadWindow* readWindow) : m_useMouseTracking(true) {} /** Returns the current active anchor. */ -const QString& CReadDisplay::activeAnchor() { +const QString& CReadDisplay::activeAnchor() const { return m_activeAnchor; } @@ -39,7 +39,7 @@ void CReadDisplay::setActiveAnchor( const QString& anchor ) { /** Returns true if the display has an active anchor. */ -bool CReadDisplay::hasActiveAnchor() { +bool CReadDisplay::hasActiveAnchor() const { return !activeAnchor().isEmpty(); } @@ -48,7 +48,7 @@ void CReadDisplay::print(const CDisplay::TextPart type, const DisplayOptions &displayOptions, const FilterOptions &filterOptions) { - typedef CSwordBibleModuleInfo CSBiMI; + using CSBiMI = CSwordBibleModuleInfo; CDisplayWindow* window = parentWindow(); CSwordKey* const key = window->key(); const CSwordModuleInfo *module = key->module(); diff --git a/src/frontend/display/creaddisplay.h b/src/frontend/display/creaddisplay.h index dd25a76..4ae0ec6 100644 --- a/src/frontend/display/creaddisplay.h +++ b/src/frontend/display/creaddisplay.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -28,19 +28,19 @@ class CReadDisplay : public CDisplay { /** * Returns true if the display has an active anchor. */ - bool hasActiveAnchor(); + bool hasActiveAnchor() const; /** * Returns the current active anchor. */ - const QString& activeAnchor(); + QString const & activeAnchor() const; /** * Moves the widget to the given anchor. */ virtual void moveToAnchor( const QString& ) = 0; - virtual void print(const CDisplay::TextPart, - const DisplayOptions &displayOptions, - const FilterOptions &filterOptions); + void print(const CDisplay::TextPart, + const DisplayOptions &displayOptions, + const FilterOptions &filterOptions) override; void setMouseTracking(const bool trackingEnabled) { m_useMouseTracking = trackingEnabled; diff --git a/src/frontend/displaywindow/btactioncollection.cpp b/src/frontend/displaywindow/btactioncollection.cpp index f25b972..b150e8c 100644 --- a/src/frontend/displaywindow/btactioncollection.cpp +++ b/src/frontend/displaywindow/btactioncollection.cpp @@ -2,110 +2,85 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ #include "frontend/displaywindow/btactioncollection.h" -#include <QAction> -#include <QDebug> -#include <QKeySequence> -#include <QString> -#include <QStringList> +#include "util/btconnect.h" #include "util/directory.h" -class BtActionItem: public QObject { - - public: /* Methods: */ - - BtActionItem(QAction *action, QObject *parent = 0) - : QObject(parent), defaultKeys(action->shortcut()), action(action) - { - // Intentionally empty - } - - public: /* Fields: */ - - QKeySequence defaultKeys; - QAction* action; - -}; +QAction & BtActionCollection::action(QString const & name) const { + Item const * const foundItem = findActionItem(name); + BT_ASSERT(foundItem); + return *(foundItem->m_action); +} -QList<QAction*> BtActionCollection::actions() { - QList<QAction*> actionList; - for (ActionMap::const_iterator iter = m_actions.constBegin(); - iter != m_actions.constEnd(); - ++iter) - { - actionList.append(iter.value()->action); +void BtActionCollection::addAction(QString const & name, + QAction * const action) +{ + BT_ASSERT(action); + BT_ASSERT(m_actions.find(name) == m_actions.end()); + Item * const item = new Item{action, this}; + try { + m_actions.insert(name, item); + } catch (...) { + delete item; + throw; } - return actionList; } -QAction *BtActionCollection::action(const QString &name) const { - ActionMap::const_iterator it = m_actions.find(name); - if (it != m_actions.constEnd()) - return (*it)->action; - - qWarning() << "A QAction for a shortcut named" << name << "was requested but it is not defined."; - return 0; +void BtActionCollection::addAction(QString const & name, + QObject const * const receiver, + char const * const member) +{ + QAction * const action = new QAction{name, this}; + try { + if (receiver && member) + BT_CONNECT(action, SIGNAL(triggered()), + receiver, SLOT(triggered())); + return addAction(name, action); + } catch (...) { + delete action; + throw; + } } -QAction* BtActionCollection::addAction(const QString& name, QAction* action) { - Q_ASSERT(action != 0); - ActionMap::iterator it = m_actions.find(name); - if (it != m_actions.constEnd()) - delete *it; - - m_actions.insert(name, new BtActionItem(action, this)); - return action; +void BtActionCollection::removeAction(QString const & name) { + #ifndef NDEBUG + int const r = + #endif + m_actions.remove(name); + BT_ASSERT(r > 0); } -QAction* BtActionCollection::addAction(const QString &name, const QObject *receiver, const char* member) { - QAction* action = new QAction(name, this); - if (receiver && member) { - bool ok = connect(action, SIGNAL(triggered()), - receiver, SLOT(triggered())); - Q_ASSERT(ok); - } - return addAction(name, action); +QKeySequence BtActionCollection::getDefaultShortcut(QAction * action) const { + for (Item * const item : m_actions) + if (item->m_action == action) + return item->m_defaultKeys; + return QKeySequence{}; } -QKeySequence BtActionCollection::getDefaultShortcut(QAction* action) { - for (ActionMap::const_iterator iter = m_actions.constBegin(); - iter != m_actions.constEnd(); - ++iter) - { - if (iter.value()->action == action) { - return iter.value()->defaultKeys; - } - } - return QKeySequence(); +void BtActionCollection::readShortcuts(QString const & group) { + BtConfig::ShortcutsMap shortcuts = btConfig().getShortcuts(group); + for (auto it = shortcuts.begin(); it != shortcuts.end(); ++it) + if (Item const * const foundItem = findActionItem(it.key())) + foundItem->m_action->setShortcuts(it.value()); } -void BtActionCollection::readShortcuts(const QString &group) { - QHash<QString, QList <QKeySequence > > shortcuts = btConfig().getShortcuts(group); - for(QHash<QString, QList <QKeySequence> >::const_iterator iter = shortcuts.begin(); - iter != shortcuts.end(); - ++iter) - { - QAction *a = action(iter.key()); - if (a == 0) - continue; - action(iter.key())->setShortcuts(iter.value()); - } +void BtActionCollection::writeShortcuts(QString const & group) const { + BtConfig::ShortcutsMap shortcuts; + for (auto it = m_actions.begin(); it != m_actions.end(); ++it) + shortcuts.insert(it.key(), it.value()->m_action->shortcuts()); + btConfig().setShortcuts(group, shortcuts); } -void BtActionCollection::writeShortcuts(const QString &group) { - QHash< QString, QList<QKeySequence> > shortcuts; - for (ActionMap::const_iterator iter = m_actions.constBegin(); - iter != m_actions.constEnd(); - ++iter) - { - shortcuts.insert(iter.key(), iter.value()->action->shortcuts()); - } - btConfig().setShortcuts(group, shortcuts); +BtActionCollection::Item * BtActionCollection::findActionItem( + QString const & name) const +{ + ActionMap::const_iterator const it = m_actions.find(name); + return (it != m_actions.constEnd()) ? *it : nullptr; } diff --git a/src/frontend/displaywindow/btactioncollection.h b/src/frontend/displaywindow/btactioncollection.h index a4d062f..a5f2fc8 100644 --- a/src/frontend/displaywindow/btactioncollection.h +++ b/src/frontend/displaywindow/btactioncollection.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -14,61 +14,97 @@ #include <QObject> -#include <QList> +#include <QAction> +#include <QKeySequence> #include <QMap> - +#include <QString> #include "backend/config/btconfig.h" +#include "util/btassert.h" -class BtActionItem; -class QAction; -class QKeySequence; -class QString; class BtActionCollection: public QObject { - Q_OBJECT + Q_OBJECT - private: /* Types: */ +private: /* Types: */ - typedef QMap<QString, BtActionItem*> ActionMap; + class Item: public QObject { public: /* Methods: */ - inline BtActionCollection(QObject *parent = 0) : QObject(parent) {} + Item(QAction * const action, QObject * const parent) + : QObject{parent} + , m_defaultKeys{action->shortcut()} + , m_action{action} + {} + + public: /* Fields: */ + + QKeySequence const m_defaultKeys; + QAction * const m_action; + + }; + using ActionMap = QMap<QString, Item *>; + +public: /* Methods: */ + + inline BtActionCollection(QObject * const parent = nullptr) + : QObject{parent} + {} + + void addAction(QString const & name, QAction * const action); + + void addAction(QString const & name, + QObject const * const receiver, + const char * const member = nullptr); + + void removeAction(QString const & name); + + QAction & action(QString const & name) const; + + template <typename T> + inline T & actionAs(QString const & name) const { + QAction & a = action(name); + BT_ASSERT(dynamic_cast<T *>(&a)); + return static_cast<T &>(a); + } - QAction* addAction(const QString& name, QAction* action); + template <typename F> + inline void foreachQAction(F && f) const { + for (Item const * const item : m_actions) + f(*(item->m_action), item->m_defaultKeys); + } - QAction* addAction(const QString &name, const QObject *receiver, const char* member = 0); + /*! + * \brief Read shortcuts from config. + * + * Read the shortcuts for the given group + * from the configuration and add them to + * this action collection. + * + * \param[in] group Shortcut group to read actions from. + */ + void readShortcuts(QString const & group); - QList<QAction*> actions(); + /*! + * \brief Write shortcuts to config. + * + * Write the shortcuts of this action collection + * to the given group in the configuration. + * + * \param[in] group Shortcut group to write actions to. + */ + void writeShortcuts(QString const & group) const; - QAction *action(const QString &name) const; + QKeySequence getDefaultShortcut(QAction * const action) const; - /*! - * \brief Read shortcuts from config. - * - * Read the shortcuts for the given group - * from the configuration and add them to - * this action collection. - * - * \param[in] group Shortcut group to read actions from. - */ - void readShortcuts(const QString &group); +private: /* Methods: */ - /*! - * \brief Write shortcuts to config. - * - * Write the shortcuts of this action collection - * to the given group in the configuration. - * - * \param[in] group Shortcut group to write actions to. - */ - void writeShortcuts(const QString& group); - QKeySequence getDefaultShortcut(QAction* action); + Item * findActionItem(QString const & name) const; - private: /* Fields: */ +private: /* Fields: */ - ActionMap m_actions; + ActionMap m_actions; }; diff --git a/src/frontend/displaywindow/btdisplaysettingsbutton.cpp b/src/frontend/displaywindow/btdisplaysettingsbutton.cpp index bca9334..2e99e48 100644 --- a/src/frontend/displaywindow/btdisplaysettingsbutton.cpp +++ b/src/frontend/displaywindow/btdisplaysettingsbutton.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -15,23 +15,24 @@ #include <QToolTip> #include <QToolButton> #include "bibletimeapp.h" +#include "util/btassert.h" +#include "util/btconnect.h" #include "util/cresmgr.h" -#include "util/geticon.h" BtDisplaySettingsButton::BtDisplaySettingsButton(QWidget *parent) : QToolButton(parent) { initMenu(); - setIcon(util::getIcon(CResMgr::displaywindows::displaySettings::icon)); + setIcon(CResMgr::displaywindows::displaySettings::icon()); setPopupMode(QToolButton::InstantPopup); setEnabled(false); initMenu(); retranslateUi(); - connect(m_popup, SIGNAL(triggered(QAction*)), - this, SLOT(slotOptionToggled(QAction*))); + BT_CONNECT(m_popup, SIGNAL(triggered(QAction *)), + this, SLOT(slotOptionToggled(QAction *))); } void BtDisplaySettingsButton::setDisplayOptions( @@ -55,7 +56,7 @@ void BtDisplaySettingsButton::setFilterOptions( } void BtDisplaySettingsButton::setModules( - const QList<const CSwordModuleInfo*> &modules) + const BtConstModuleList &modules) { m_modules = modules; repopulateMenu(); @@ -161,7 +162,7 @@ void BtDisplaySettingsButton::slotOptionToggled(QAction *action) { m_filterOptions.redLetterWords = checked; emit sigFilterOptionsChanged(m_filterOptions); } else { - Q_ASSERT(false); + BT_ASSERT(false && "Shouldn't happen!"); return; } @@ -238,8 +239,8 @@ void BtDisplaySettingsButton::addMenuEntry(QAction *action, bool checked) { } bool BtDisplaySettingsButton::isOptionAvailable(const CSwordModuleInfo::FilterTypes option) { - Q_FOREACH (const CSwordModuleInfo *module, m_modules) { - if (module->has(option)) return true; - } + Q_FOREACH(CSwordModuleInfo const * const module, m_modules) + if (module->has(option)) + return true; return false; } diff --git a/src/frontend/displaywindow/btdisplaysettingsbutton.h b/src/frontend/displaywindow/btdisplaysettingsbutton.h index f82f682..39cdcc3 100644 --- a/src/frontend/displaywindow/btdisplaysettingsbutton.h +++ b/src/frontend/displaywindow/btdisplaysettingsbutton.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -14,8 +14,8 @@ #include <QToolButton> +#include "backend/btglobal.h" #include "backend/managers/cswordbackend.h" -#include "btglobal.h" class CSwordModuleInfo; @@ -28,7 +28,7 @@ class BtDisplaySettingsButton: public QToolButton { Q_OBJECT public: - BtDisplaySettingsButton(QWidget *parent = 0); + BtDisplaySettingsButton(QWidget *parent = nullptr); public slots: void setDisplayOptions(const DisplayOptions &displaySettings, @@ -36,13 +36,13 @@ class BtDisplaySettingsButton: public QToolButton { void setFilterOptions(const FilterOptions &moduleSettings, bool repopulate = true); - void setModules(const QList<const CSwordModuleInfo*> &modules); + void setModules(const BtConstModuleList &modules); signals: void sigFilterOptionsChanged(FilterOptions filterOptions); void sigDisplayOptionsChanged(DisplayOptions displayOptions); - void sigModulesChanged(const QList<CSwordModuleInfo*> &modules); - void sigChanged(void); + void sigModulesChanged(const BtConstModuleList &modules); + void sigChanged(); protected slots: void slotOptionToggled(QAction *action); @@ -59,7 +59,7 @@ class BtDisplaySettingsButton: public QToolButton { private: FilterOptions m_filterOptions; DisplayOptions m_displayOptions; - QList<const CSwordModuleInfo*> m_modules; + BtConstModuleList m_modules; QMenu *m_popup; QAction *m_lineBreakAction; diff --git a/src/frontend/displaywindow/btmodulechooserbar.cpp b/src/frontend/displaywindow/btmodulechooserbar.cpp index e8d80cb..5e830d2 100644 --- a/src/frontend/displaywindow/btmodulechooserbar.cpp +++ b/src/frontend/displaywindow/btmodulechooserbar.cpp @@ -2,44 +2,45 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ #include "frontend/displaywindow/btmodulechooserbar.h" -#include "frontend/displaywindow/btmodulechooserbutton.h" -#include "creadwindow.h" -#include "util/btmodules.h" #include <QAction> #include <QDebug> #include <QList> #include <QToolBar> +#include "frontend/displaywindow/btmodulechooserbutton.h" +#include "creadwindow.h" +#include "util/btconnect.h" +#include "util/btmodules.h" BtModuleChooserBar::BtModuleChooserBar(QWidget *parent) : QToolBar(parent), - BtWindowModuleChooser(CSwordModuleInfo::Unknown, 0), + BtWindowModuleChooser(CSwordModuleInfo::Unknown, nullptr), m_idCounter(0), - m_window(0) { + m_window(nullptr) { setAllowedAreas(Qt::TopToolBarArea); setFloatable(false); } void BtModuleChooserBar::slotBackendModulesChanged() { m_modules = m_window->getModuleList(); - adjustButtonCount(); - //recreate all menus from scratch - for (int i = 0; i < m_buttonList.count(); i++) { - BtModuleChooserButton* button = m_buttonList.at(i); - QString moduleName = (i >= m_modules.count()) ? QString::null : m_modules.at(i); - qDebug() << "refresh button's menu:" << moduleName << i; - int leftLikeModules = leftLikeParallelModules(m_modules); - button->recreateMenu(m_modules, moduleName, i, leftLikeModules); - } + // Recreate all menus from scratch: + int const leftLikeModules = leftLikeParallelModules(m_modules); + for (int i = 0; i < m_buttonList.count(); i++) + m_buttonList.at(i)->recreateMenu(m_modules, + (i >= m_modules.count()) + ? QString::null + : m_modules.at(i), + i, + leftLikeModules); } void BtModuleChooserBar::adjustButtonCount(bool adjustToZero) { @@ -80,9 +81,12 @@ BtModuleChooserButton* BtModuleChooserBar::addButton() { // the button sends signals directly to the window which then signals back when the module // list has changed - connect(b, SIGNAL(sigModuleAdd(int, QString)), m_window, SLOT(slotAddModule(int, QString))); - connect(b, SIGNAL(sigModuleReplace(int, QString)), m_window, SLOT(slotReplaceModule(int, QString))); - connect(b, SIGNAL(sigModuleRemove(int)), m_window, SLOT(slotRemoveModule(int))); + BT_CONNECT(b, &BtModuleChooserButton::sigModuleAdd, + m_window, &CReadWindow::slotAddModule); + BT_CONNECT(b, &BtModuleChooserButton::sigModuleReplace, + m_window, &CReadWindow::slotReplaceModule); + BT_CONNECT(b, &BtModuleChooserButton::sigModuleRemove, + m_window, &CReadWindow::slotRemoveModule); a->setVisible(true); return b; @@ -108,15 +112,19 @@ void BtModuleChooserBar::setModules( QStringList useModules,CSwordModuleInfo::Mo } updateButtonMenus(); - connect(m_window, SIGNAL(sigModuleListSet(QStringList)), SLOT(slotBackendModulesChanged())); - connect(m_window, SIGNAL(sigModuleListChanged()), SLOT(slotWindowModulesChanged())); + BT_CONNECT(m_window, &CReadWindow::sigModuleListSet, + this, &BtModuleChooserBar::slotBackendModulesChanged); + BT_CONNECT(m_window, &CReadWindow::sigModuleListChanged, + this, &BtModuleChooserBar::slotWindowModulesChanged); } void BtModuleChooserBar::updateButtonMenus() { - int leftLikeModules = leftLikeParallelModules(m_modules); - for (int i = 0; i < m_buttonList.count(); i++) { - BtModuleChooserButton* button = m_buttonList.at(i); - QString moduleName = (i >= m_modules.count()) ? QString::null : m_modules.at(i); - button->updateMenu(m_modules, moduleName, i, leftLikeModules); - } + int const leftLikeModules = leftLikeParallelModules(m_modules); + for (int i = 0; i < m_buttonList.count(); i++) + m_buttonList.at(i)->updateMenu(m_modules, + (i >= m_modules.count()) + ? QString::null + : m_modules.at(i), + i, + leftLikeModules); } diff --git a/src/frontend/displaywindow/btmodulechooserbar.h b/src/frontend/displaywindow/btmodulechooserbar.h index 024bc08..2e09627 100644 --- a/src/frontend/displaywindow/btmodulechooserbar.h +++ b/src/frontend/displaywindow/btmodulechooserbar.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -33,12 +33,12 @@ class BtModuleChooserBar: public QToolBar, public BtWindowModuleChooser { * The signal comes from the window, not from the backend. The new list can * be shorter but not longer than the old list. */ - void slotBackendModulesChanged(); + void slotBackendModulesChanged() override; /** * The window module list was changed, i.e. 1 module added, removed or replaced. */ - void slotWindowModulesChanged(); + void slotWindowModulesChanged() override; private: /** Adds an empty button to the toolbar.*/ diff --git a/src/frontend/displaywindow/btmodulechooserbutton.cpp b/src/frontend/displaywindow/btmodulechooserbutton.cpp index 4e0a5fc..5e6eea1 100644 --- a/src/frontend/displaywindow/btmodulechooserbutton.cpp +++ b/src/frontend/displaywindow/btmodulechooserbutton.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -19,14 +19,14 @@ #include "backend/managers/cswordbackend.h" #include "bibletimeapp.h" #include "frontend/displaywindow/btmodulechooserbar.h" +#include "util/btconnect.h" #include "util/cresmgr.h" -#include "util/geticon.h" BtModuleChooserButton::BtModuleChooserButton(BtModuleChooserBar *parent, CSwordModuleInfo::ModuleType mtype) : QToolButton(parent), m_moduleType(mtype), - m_popup(0) { + m_popup(nullptr) { setPopupMode(QToolButton::InstantPopup); } @@ -35,18 +35,26 @@ void BtModuleChooserButton::recreateMenu(QStringList newModulesToUse, QString th updateMenu(newModulesToUse, thisModule, newIndex, leftLikeModules); } -const QString BtModuleChooserButton::iconName() { +QIcon const & BtModuleChooserButton::icon() { switch (m_moduleType) { case CSwordModuleInfo::Bible: - return (m_hasModule) ? CResMgr::modules::bible::icon_unlocked : CResMgr::modules::bible::icon_add; + return m_hasModule + ? CResMgr::modules::bible::icon_unlocked() + : CResMgr::modules::bible::icon_add(); case CSwordModuleInfo::Commentary: - return (m_hasModule) ? CResMgr::modules::commentary::icon_unlocked : CResMgr::modules::commentary::icon_add; + return m_hasModule + ? CResMgr::modules::commentary::icon_unlocked() + : CResMgr::modules::commentary::icon_add(); case CSwordModuleInfo::Lexicon: - return m_hasModule ? CResMgr::modules::lexicon::icon_unlocked : CResMgr::modules::lexicon::icon_add; + return m_hasModule + ? CResMgr::modules::lexicon::icon_unlocked() + : CResMgr::modules::lexicon::icon_add(); case CSwordModuleInfo::GenericBook: - return m_hasModule ? CResMgr::modules::book::icon_unlocked : CResMgr::modules::book::icon_add; + return m_hasModule + ? CResMgr::modules::book::icon_unlocked() + : CResMgr::modules::book::icon_add(); default: //return as default the bible icon - return CResMgr::modules::bible::icon_unlocked; + return CResMgr::modules::bible::icon_unlocked(); } } @@ -58,19 +66,20 @@ void BtModuleChooserButton::updateMenu(QStringList newModulesToUse, QString this populateMenu(); m_module = thisModule; - m_hasModule = thisModule.isEmpty() ? false : true; + m_hasModule = !thisModule.isEmpty(); //All items are iterated and the state is changed properly QListIterator<QMenu*> it(m_submenus); while (it.hasNext()) { QMenu* popup = it.next(); - foreach (QAction* a, popup->actions()) { - a->setChecked( (a->text() == thisModule) ? true : false ); - a->setDisabled( newModulesToUse.contains(a->text()) ? true : false ); + Q_FOREACH(QAction * const a, popup->actions()) { + auto const moduleName(a->property("BibleTimeModule").toString()); + a->setChecked(moduleName == thisModule); + a->setDisabled(newModulesToUse.contains(moduleName)); } } - m_noneAction->setChecked(m_hasModule ? false : true); - setIcon(util::getIcon(iconName())); + m_noneAction->setChecked(!m_hasModule); + setIcon(icon()); if (m_hasModule) { setToolTip( QString(tr("Select a work [%1]")).arg(m_module) ); @@ -99,7 +108,8 @@ void BtModuleChooserButton::updateMenu(QStringList newModulesToUse, QString this /** Is called after a module was selected in the popup */ void BtModuleChooserButton::moduleChosen( QAction* action ) { - if (action->text() == tr("NONE")) { // note: this is for m_popup, the toplevel! + auto modProperty(action->property("BibleTimeModule")); + if (!modProperty.isValid()) { // note: this is for m_popup, the toplevel! if (m_hasModule) { qDebug() << "remove module" << m_id; emit sigModuleRemove(m_id); @@ -113,10 +123,10 @@ void BtModuleChooserButton::moduleChosen( QAction* action ) { } else { if (!m_hasModule) { - emit sigModuleAdd(m_id + 1, action->text()); + emit sigModuleAdd(m_id + 1, modProperty.toString()); return; } - emit sigModuleReplace(m_id, action->text()); + emit sigModuleReplace(m_id, modProperty.toString()); } } @@ -132,7 +142,8 @@ void BtModuleChooserButton::populateMenu() { if (m_module.isEmpty()) m_noneAction->setChecked(true); m_popup->addSeparator(); - connect(m_popup, SIGNAL(triggered(QAction*)), this, SLOT(moduleChosen(QAction*))); + BT_CONNECT(m_popup, &QMenu::triggered, + this, &BtModuleChooserButton::moduleChosen); setMenu(m_popup); @@ -166,8 +177,7 @@ void BtModuleChooserButton::populateMenu() { } void BtModuleChooserButton::addItemToMenu(BTModuleTreeItem* item, QMenu* menu) { - foreach (BTModuleTreeItem* i, item->children()) { - + Q_FOREACH(BTModuleTreeItem * const i, item->children()) { if (i->type() == BTModuleTreeItem::Language || i->type() == BTModuleTreeItem::Category ) { // argument menu was m_popup, create and add a new lang menu to it @@ -181,6 +191,7 @@ void BtModuleChooserButton::addItemToMenu(BTModuleTreeItem* item, QMenu* menu) { // item must be module, create and add it to the lang menu QString name(i->text()); QAction* modItem = new QAction(name, menu); + modItem->setProperty("BibleTimeModule", name); modItem->setCheckable(true); menu->addAction(modItem); } diff --git a/src/frontend/displaywindow/btmodulechooserbutton.h b/src/frontend/displaywindow/btmodulechooserbutton.h index 03c2b9b..2d33b9a 100644 --- a/src/frontend/displaywindow/btmodulechooserbutton.h +++ b/src/frontend/displaywindow/btmodulechooserbutton.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -36,9 +36,8 @@ class BtModuleChooserButton : public QToolButton { TypeFilter(CSwordModuleInfo::ModuleType t) { m_mType = t; } - bool filter(CSwordModuleInfo* mi) { - return ((mi->type() == m_mType) && !mi->isLocked()); - } + bool filter(CSwordModuleInfo const & mi) const override + { return ((mi.type() == m_mType) && !mi.isLocked()); } CSwordModuleInfo::ModuleType m_mType; }; @@ -79,8 +78,9 @@ class BtModuleChooserButton : public QToolButton { void moduleChosen(QAction* action ); private: + /** Returns the icon used for the current status.*/ - const QString iconName(); + QIcon const & icon(); /** * Populates the menu with language submenus and module items without setting diff --git a/src/frontend/displaywindow/bttextwindowheader.cpp b/src/frontend/displaywindow/bttextwindowheader.cpp index 6f108d7..3a1c546 100644 --- a/src/frontend/displaywindow/bttextwindowheader.cpp +++ b/src/frontend/displaywindow/bttextwindowheader.cpp @@ -2,26 +2,27 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ #include "bttextwindowheader.h" -#include "bttextwindowheaderwidget.h" -#include "clexiconreadwindow.h" -#include "util/btmodules.h" - -#include <QStringList> -#include <QWidget> +#include <QAction> +#include <QDebug> +#include <QFrame> #include <QHBoxLayout> #include <QLabel> #include <QSizePolicy> +#include <QStringList> #include <QToolButton> -#include <QFrame> -#include <QAction> -#include <QDebug> +#include <QWidget> +#include "bttextwindowheaderwidget.h" +#include "clexiconreadwindow.h" +#include "util/btconnect.h" +#include "util/btmodules.h" + BtTextWindowHeader::BtTextWindowHeader(CSwordModuleInfo::ModuleType modtype, QStringList modules, @@ -34,8 +35,10 @@ BtTextWindowHeader::BtTextWindowHeader(CSwordModuleInfo::ModuleType modtype, setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); setLayoutDirection(Qt::LeftToRight); setModules(modules); - connect(window, SIGNAL(sigModuleListSet(QStringList)), SLOT(slotBackendModulesChanged())); - connect(window, SIGNAL(sigModuleListChanged()), SLOT(slotWindowModulesChanged())); + BT_CONNECT(window, SIGNAL(sigModuleListSet(QStringList)), + SLOT(slotBackendModulesChanged())); + BT_CONNECT(window, SIGNAL(sigModuleListChanged()), + SLOT(slotWindowModulesChanged())); } void BtTextWindowHeader::slotBackendModulesChanged() { @@ -44,13 +47,12 @@ void BtTextWindowHeader::slotBackendModulesChanged() { adjustWidgetCount(); //recreate all widgets from scratch - for (int i = 0; i < m_widgetList.count(); i++) { - BtTextWindowHeaderWidget* widgt = m_widgetList.at(i); - QString moduleName = m_modules.at(i); - qDebug() << "refresh button's menu:" << moduleName << i; - int leftLikeModules = leftLikeParallelModules(m_modules); - widgt->recreateWidget(m_modules, moduleName, i, leftLikeModules); - } + int const leftLikeModules = leftLikeParallelModules(m_modules); + for (int i = 0; i < m_widgetList.count(); i++) + m_widgetList.at(i)->recreateWidget(m_modules, + m_modules.at(i), + i, + leftLikeModules); } void BtTextWindowHeader::slotWindowModulesChanged() { @@ -75,7 +77,7 @@ void BtTextWindowHeader::adjustWidgetCount(bool adjustToZero) { while (widgetCountDifference) { // it should be safe to delete the button later BtTextWindowHeaderWidget* w = m_widgetList.takeFirst(); - w->setParent(0); + w->setParent(nullptr); w->deleteLater(); widgetCountDifference--; } @@ -96,9 +98,12 @@ BtTextWindowHeaderWidget* BtTextWindowHeader::addWidget() { // the button sends signals directly to the window which then signals back when the module // list has changed - connect(w, SIGNAL(sigModuleAdd(int, QString)), m_window, SLOT(slotAddModule(int, QString))); - connect(w, SIGNAL(sigModuleReplace(int, QString)), m_window, SLOT(slotReplaceModule(int, QString))); - connect(w, SIGNAL(sigModuleRemove(int)), m_window, SLOT(slotRemoveModule(int))); + BT_CONNECT(w, SIGNAL(sigModuleAdd(int, QString)), + m_window, SLOT(slotAddModule(int, QString))); + BT_CONNECT(w, SIGNAL(sigModuleReplace(int, QString)), + m_window, SLOT(slotReplaceModule(int, QString))); + BT_CONNECT(w, SIGNAL(sigModuleRemove(int)), + m_window, SLOT(slotRemoveModule(int))); return w; } @@ -115,10 +120,10 @@ void BtTextWindowHeader::setModules( QStringList useModules ) { } void BtTextWindowHeader::updateWidgets() { - int leftLikeModules = leftLikeParallelModules(m_modules); - for (int i = 0; i < m_widgetList.count(); i++) { - BtTextWindowHeaderWidget* w = m_widgetList.at(i); - //QString moduleName = m_modules.at(i); - w->updateWidget(m_modules, m_modules.at(i), i, leftLikeModules); - } + int const leftLikeModules = leftLikeParallelModules(m_modules); + for (int i = 0; i < m_widgetList.count(); i++) + m_widgetList.at(i)->updateWidget(m_modules, + m_modules.at(i), + i, + leftLikeModules); } diff --git a/src/frontend/displaywindow/bttextwindowheader.h b/src/frontend/displaywindow/bttextwindowheader.h index 2673d78..fdd587d 100644 --- a/src/frontend/displaywindow/bttextwindowheader.h +++ b/src/frontend/displaywindow/bttextwindowheader.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -31,12 +31,12 @@ class BtTextWindowHeader: public QWidget, public BtWindowModuleChooser { The backend module list was updated, module list and widgets must be updated from scratch. */ - void slotBackendModulesChanged(); + void slotBackendModulesChanged() override; /** The window module list was updated, module list and widgets must be updated. */ - void slotWindowModulesChanged(); + void slotWindowModulesChanged() override; signals: /** User selected a module from menu to replace another module*/ diff --git a/src/frontend/displaywindow/bttextwindowheaderwidget.cpp b/src/frontend/displaywindow/bttextwindowheaderwidget.cpp index a974c2c..b8201ad 100644 --- a/src/frontend/displaywindow/bttextwindowheaderwidget.cpp +++ b/src/frontend/displaywindow/bttextwindowheaderwidget.cpp @@ -2,27 +2,26 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ #include "frontend/displaywindow/bttextwindowheaderwidget.h" +#include <QHBoxLayout> +#include <QLabel> #include <QMenu> -#include <QString> #include <QToolButton> #include <QToolTip> -#include <QHBoxLayout> #include <QSizePolicy> -#include <QLabel> - +#include <QString> #include "backend/config/btconfig.h" #include "backend/managers/cswordbackend.h" #include "bibletimeapp.h" #include "frontend/displaywindow/bttextwindowheader.h" +#include "util/btconnect.h" #include "util/cresmgr.h" -#include "util/geticon.h" namespace { @@ -30,11 +29,12 @@ const QString BookshelfShowHiddenKey = "GUI/bookshelfShowHidden"; } // anonymous namespace const char* ActionType = "ActionType"; +const char * ModuleName = "ModuleName"; BtTextWindowHeaderWidget::BtTextWindowHeaderWidget(BtTextWindowHeader *parent, CSwordModuleInfo::ModuleType mtype) : QWidget(parent), m_moduleType(mtype), - m_popup(0) { + m_popup(nullptr) { QHBoxLayout* layout = new QHBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); @@ -92,9 +92,11 @@ void BtTextWindowHeaderWidget::updateWidget(QStringList newModulesToUse, QString QListIterator<QMenu*> it(m_submenus); while (it.hasNext()) { QMenu* popup = it.next(); - foreach (QAction* a, popup->actions()) { - a->setChecked( (a->text() == thisModule) ? true : false ); - a->setDisabled( newModulesToUse.contains(a->text()) ? true : false ); + Q_FOREACH(QAction * const a, popup->actions()) { + a->setChecked(a->property(ModuleName).toString() == thisModule); + a->setDisabled( + newModulesToUse.contains( + a->property(ModuleName).toString())); } } @@ -113,7 +115,7 @@ void BtTextWindowHeaderWidget::updateWidget(QStringList newModulesToUse, QString if (typeText != QObject::tr("Replace")) continue; QMenu* menuType = actionType->menu(); - if (menuType == 0) + if (menuType == nullptr) continue; QList<QAction*> actions = menuType->actions(); for (int i=0; i<actions.count(); i++) { @@ -134,11 +136,11 @@ void BtTextWindowHeaderWidget::moduleChosen( QAction* action ) { return; } if (action->property(ActionType).toInt() == AddAction) { - emit sigModuleAdd(m_id + 1, action->text()); + emit sigModuleAdd(m_id + 1, action->property(ModuleName).toString()); return; } if (action->property(ActionType).toInt() == ReplaceAction) { - emit sigModuleReplace(m_id, action->text()); + emit sigModuleReplace(m_id, action->property(ModuleName).toString()); } } @@ -147,30 +149,31 @@ void BtTextWindowHeaderWidget::populateMenu() { delete m_popup; m_popup = new QMenu(m_button); - connect(m_popup, SIGNAL(triggered(QAction*)), this, SLOT(moduleChosen(QAction*))); + BT_CONNECT(m_popup, SIGNAL(triggered(QAction *)), + this, SLOT(moduleChosen(QAction *))); m_button->setMenu(m_popup); m_removeAction = new QAction(tr("Remove"), m_popup); m_removeAction->setProperty(ActionType, RemoveAction); - m_removeAction->setIcon(util::getIcon(CResMgr::displaywindows::general::removemoduleicon)); + m_removeAction->setIcon(CResMgr::displaywindows::general::icon_removeModule()); m_popup->addAction(m_removeAction); // Add Replace and Add menus, both have all modules in them QMenu* replaceItem = new QMenu(tr("Replace"), m_popup); - replaceItem->setIcon(util::getIcon(CResMgr::displaywindows::general::replacemoduleicon)); + replaceItem->setIcon(CResMgr::displaywindows::general::icon_replaceModule()); replaceItem->setProperty(ActionType, ReplaceAction); m_popup->addMenu(replaceItem); QMenu* addItem = new QMenu(tr("Add"), m_popup); addItem->setProperty(ActionType, AddAction); - addItem->setIcon(util::getIcon(CResMgr::displaywindows::general::addmoduleicon)); + addItem->setIcon(CResMgr::displaywindows::general::icon_addModule()); m_popup->addMenu(addItem); QList<QMenu*> toplevelMenus; toplevelMenus.append(replaceItem); toplevelMenus.append(addItem); - foreach(QMenu* menu, toplevelMenus) { + Q_FOREACH(QMenu * const menu, toplevelMenus) { // ******* Add categories, languages and modules ******** // Filters: add only non-hidden, non-locked and correct type BTModuleTreeItem::HiddenOff hiddenFilter; @@ -181,6 +184,8 @@ void BtTextWindowHeaderWidget::populateMenu() { TypeFilter typeFilter(m_moduleType); filters.append(&typeFilter); + TypeOfAction const typeOfAction = + static_cast<TypeOfAction>(menu->property(ActionType).toInt()); if (m_moduleType == CSwordModuleInfo::Bible) { BTModuleTreeItem root(filters, BTModuleTreeItem::CatLangMod); QList<BTModuleTreeItem::Filter*> filters2; @@ -192,18 +197,17 @@ void BtTextWindowHeaderWidget::populateMenu() { filters2.append(&typeFilter2); root.add_items(filters2); } - addItemToMenu(&root, menu, (TypeOfAction)menu->property(ActionType).toInt()); + addItemToMenu(&root, menu, typeOfAction); } else { BTModuleTreeItem root(filters, BTModuleTreeItem::LangMod); - addItemToMenu(&root, menu, (TypeOfAction)menu->property(ActionType).toInt()); + addItemToMenu(&root, menu, typeOfAction); } } } void BtTextWindowHeaderWidget::addItemToMenu(BTModuleTreeItem* item, QMenu* menu, TypeOfAction actionType) { - foreach (BTModuleTreeItem* i, item->children()) { - + Q_FOREACH(BTModuleTreeItem * const i, item->children()) { if (i->type() == BTModuleTreeItem::Language || i->type() == BTModuleTreeItem::Category) { // argument menu was m_popup, create and add a new lang menu to it @@ -219,6 +223,7 @@ void BtTextWindowHeaderWidget::addItemToMenu(BTModuleTreeItem* item, QMenu* menu QAction* modItem = new QAction(name, menu); modItem->setCheckable(true); modItem->setProperty(ActionType, actionType); + modItem->setProperty(ModuleName, name); menu->addAction(modItem); } } diff --git a/src/frontend/displaywindow/bttextwindowheaderwidget.h b/src/frontend/displaywindow/bttextwindowheaderwidget.h index c69bf11..033cd64 100644 --- a/src/frontend/displaywindow/bttextwindowheaderwidget.h +++ b/src/frontend/displaywindow/bttextwindowheaderwidget.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -46,9 +46,8 @@ class BtTextWindowHeaderWidget : public QWidget { TypeFilter(CSwordModuleInfo::ModuleType t) { m_mType = t; } - bool filter(CSwordModuleInfo* mi) { - return ((mi->type() == m_mType) && !mi->isLocked()); - } + bool filter(CSwordModuleInfo const & mi) const override + { return ((mi.type() == m_mType) && !mi.isLocked()); } CSwordModuleInfo::ModuleType m_mType; }; diff --git a/src/frontend/displaywindow/bttoolbarpopupaction.cpp b/src/frontend/displaywindow/bttoolbarpopupaction.cpp index e443f8a..da52c92 100644 --- a/src/frontend/displaywindow/bttoolbarpopupaction.cpp +++ b/src/frontend/displaywindow/bttoolbarpopupaction.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -13,16 +13,17 @@ #include <QEvent> #include <QMenu> #include <QToolButton> +#include "util/btconnect.h" namespace { class BtToolButton: public QToolButton { public: - inline BtToolButton(QWidget *parent = 0) + inline BtToolButton(QWidget *parent = nullptr) : QToolButton(parent) {} private: - virtual inline void nextCheckState() {} + inline void nextCheckState() override {} }; } // anonymous namespace @@ -53,8 +54,7 @@ QWidget* BtToolBarPopupAction::createWidget(QWidget* parent) { m_button->setDefaultAction(this); m_button->setPopupMode(QToolButton::MenuButtonPopup); m_button->setMenu(m_menu); - bool ok = connect(m_button, SIGNAL(pressed()), this, SLOT(buttonPressed())); - Q_ASSERT(ok);; + BT_CONNECT(m_button, SIGNAL(pressed()), this, SLOT(buttonPressed())); return m_button; } diff --git a/src/frontend/displaywindow/bttoolbarpopupaction.h b/src/frontend/displaywindow/bttoolbarpopupaction.h index 4999098..23bd688 100644 --- a/src/frontend/displaywindow/bttoolbarpopupaction.h +++ b/src/frontend/displaywindow/bttoolbarpopupaction.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -31,11 +31,10 @@ class BtToolBarPopupAction : public QWidgetAction { // return the QMenu object so a popup menu can be constructed QMenu* popupMenu() const; -// Function to catch the Shortcut event and emit the triggered signal - virtual bool event(QEvent* e); + bool event(QEvent* e) override; protected: - QWidget* createWidget(QWidget* parent); + QWidget* createWidget(QWidget* parent) override; private slots: diff --git a/src/frontend/displaywindow/btwindowmodulechooser.h b/src/frontend/displaywindow/btwindowmodulechooser.h index 40ffcf0..be34ee7 100644 --- a/src/frontend/displaywindow/btwindowmodulechooser.h +++ b/src/frontend/displaywindow/btwindowmodulechooser.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ diff --git a/src/frontend/displaywindow/cbiblereadwindow.cpp b/src/frontend/displaywindow/cbiblereadwindow.cpp index 4d88f13..7789953 100644 --- a/src/frontend/displaywindow/cbiblereadwindow.cpp +++ b/src/frontend/displaywindow/cbiblereadwindow.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -10,7 +10,6 @@ #include "frontend/displaywindow/cbiblereadwindow.h" #include <QAction> -#include <QApplication> #include <QEvent> #include <QMdiSubWindow> #include <QMenu> @@ -18,6 +17,7 @@ #include <QWidget> #include "backend/drivers/cswordbiblemoduleinfo.h" #include "backend/keys/cswordversekey.h" +#include "bibletimeapp.h" #include "frontend/cexportmanager.h" #include "frontend/cmdiarea.h" #include "frontend/display/creaddisplay.h" @@ -25,6 +25,8 @@ #include "frontend/displaywindow/ccommentaryreadwindow.h" #include "frontend/displaywindow/btdisplaysettingsbutton.h" #include "frontend/keychooser/ckeychooser.h" +#include "util/btassert.h" +#include "util/btconnect.h" #include "util/directory.h" #include "util/cresmgr.h" #include "util/tool.h" @@ -46,7 +48,7 @@ void CBibleReadWindow::applyProfileSettings(const QString & windowGroup) { lookup(); } -void CBibleReadWindow::storeProfileSettings(const QString & windowGroup) { +void CBibleReadWindow::storeProfileSettings(QString const & windowGroup) const { BtConfig & conf = btConfig(); conf.beginGroup(windowGroup); conf.setFilterOptions(filterOptions()); @@ -127,109 +129,60 @@ void CBibleReadWindow::initActions() { CBibleReadWindow::insertKeyboardActions(ac); - QAction * qaction; - - //cleanup, not a clean oo-solution - qaction = ac->action("nextEntry"); - Q_ASSERT(qaction != 0); - qaction->setEnabled(false); - qaction = ac->action("previousEntry"); - Q_ASSERT(qaction != 0); - qaction->setEnabled(false); - - - qaction = m_actionCollection->action("nextBook"); - Q_ASSERT(qaction != 0); - QObject::connect(qaction, SIGNAL(triggered()), this, SLOT(nextBook()) ); - addAction(qaction); - - qaction = m_actionCollection->action("previousBook"); - Q_ASSERT(qaction != 0); - QObject::connect(qaction, SIGNAL(triggered()), this, SLOT(previousBook()) ); - addAction(qaction); - - qaction = m_actionCollection->action("nextChapter"); - Q_ASSERT(qaction != 0); - QObject::connect(qaction, SIGNAL(triggered()), this, SLOT(nextChapter()) ); - addAction(qaction); - - qaction = m_actionCollection->action("previousChapter"); - Q_ASSERT(qaction != 0); - QObject::connect(qaction, SIGNAL(triggered()), this, SLOT(previousChapter()) ); - addAction(qaction); - - qaction = m_actionCollection->action("nextVerse"); - Q_ASSERT(qaction != 0); - QObject::connect(qaction, SIGNAL(triggered()), this, SLOT(nextVerse()) ); - addAction(qaction); - - qaction = m_actionCollection->action("previousVerse"); - Q_ASSERT(qaction != 0); - QObject::connect(qaction, SIGNAL(triggered()), this, SLOT(previousVerse()) ); - addAction(qaction); - - m_actions.selectAll = ac->action("selectAll"); - Q_ASSERT(m_actions.selectAll != 0); - - m_actions.findText = ac->action("findText"); - Q_ASSERT(m_actions.findText != 0); - - m_actions.findStrongs = m_actionCollection->action(CResMgr::displaywindows::general::findStrongs::actionName); - Q_ASSERT(m_actions.findStrongs != 0); - - m_actions.copy.referenceOnly = m_actionCollection->action("copyReferenceOnly"); - Q_ASSERT(m_actions.copy.referenceOnly != 0); - - m_actions.copy.referenceTextOnly = m_actionCollection->action("copyTextOfReference"); - Q_ASSERT(m_actions.copy.referenceTextOnly != 0); - QObject::connect(m_actions.copy.referenceTextOnly, SIGNAL(triggered()), - displayWidget()->connectionsProxy(), SLOT(copyAnchorTextOnly())); - addAction(m_actions.copy.referenceTextOnly); - - m_actions.copy.referenceAndText = m_actionCollection->action("copyReferenceWithText"); - Q_ASSERT(m_actions.copy.referenceAndText != 0); - QObject::connect(m_actions.copy.referenceAndText, SIGNAL(triggered()), - displayWidget()->connectionsProxy(), SLOT(copyAnchorWithText())); - addAction(m_actions.copy.referenceAndText); - - m_actions.copy.chapter = m_actionCollection->action("copyChapter"); - Q_ASSERT(m_actions.copy.chapter != 0); - QObject::connect(m_actions.copy.chapter, SIGNAL(triggered()), - this, SLOT(copyDisplayedText())); - addAction(m_actions.copy.chapter); - - m_actions.copy.selectedText = ac->action("copySelectedText"); - Q_ASSERT(m_actions.copy.selectedText != 0); - - m_actions.save.referenceAndText = m_actionCollection->action("saveReferenceWithText"); - Q_ASSERT(m_actions.save.referenceAndText != 0); - QObject::connect(m_actions.save.referenceAndText, SIGNAL(triggered()), - displayWidget()->connectionsProxy(), SLOT(saveAnchorWithText())); - addAction(m_actions.copy.chapter); - - m_actions.save.chapterAsPlain = m_actionCollection->action("saveChapterAsPlainText"); - Q_ASSERT(m_actions.save.chapterAsPlain != 0); - QObject::connect(m_actions.save.chapterAsPlain, SIGNAL(triggered()), - this, SLOT(saveChapterPlain())); - addAction(m_actions.save.referenceAndText); - - m_actions.save.chapterAsHTML = m_actionCollection->action("saveChapterAsHTML"); - Q_ASSERT(m_actions.save.chapterAsHTML != 0); - QObject::connect(m_actions.save.chapterAsHTML, SIGNAL(triggered()), - this, SLOT(saveChapterHTML())); - addAction(m_actions.save.chapterAsHTML); - - m_actions.print.reference = m_actionCollection->action("printReferenceWithText"); - Q_ASSERT(m_actions.print.reference != 0); - QObject::connect(m_actions.print.reference, SIGNAL(triggered()), - this, SLOT(printAnchorWithText())); - addAction(m_actions.print.reference); - - m_actions.print.chapter = m_actionCollection->action("printChapter"); - Q_ASSERT(m_actions.print.chapter != 0); - QObject::connect(m_actions.print.chapter, SIGNAL(triggered()), - this, SLOT(printAll())); - addAction(m_actions.print.chapter); + ac->action("nextEntry").setEnabled(false); + ac->action("previousEntry").setEnabled(false); + + initAction("nextBook", this, &CBibleReadWindow::nextBook); + initAction("previousBook", this, &CBibleReadWindow::previousBook); + initAction("nextChapter", this, &CBibleReadWindow::nextChapter); + initAction("previousChapter", this, &CBibleReadWindow::previousChapter); + initAction("nextVerse", this, &CBibleReadWindow::nextVerse); + initAction("previousVerse", this, &CBibleReadWindow::previousVerse); + + m_actions.selectAll = &ac->action("selectAll"); + m_actions.findText = &ac->action("findText"); + m_actions.findStrongs = &ac->action(CResMgr::displaywindows::general::findStrongs::actionName); + m_actions.copy.referenceOnly = &ac->action("copyReferenceOnly"); + + m_actions.copy.referenceTextOnly = + &initAction("copyTextOfReference", + displayWidget()->connectionsProxy(), + &CDisplayConnections::copyAnchorTextOnly); + + m_actions.copy.referenceAndText = + &initAction("copyReferenceWithText", + displayWidget()->connectionsProxy(), + &CDisplayConnections::copyAnchorWithText); + + m_actions.copy.chapter = + &initAction("copyChapter", + this, + &CBibleReadWindow::copyDisplayedText); + + m_actions.copy.selectedText = &ac->action("copySelectedText"); + + m_actions.save.referenceAndText = + &initAction("saveReferenceWithText", + displayWidget()->connectionsProxy(), + &CDisplayConnections::saveAnchorWithText); + + m_actions.save.chapterAsPlain = + &initAction("saveChapterAsPlainText", + this, + &CBibleReadWindow::saveChapterPlain); + + m_actions.save.chapterAsHTML = + &initAction("saveChapterAsHTML", + this, + &CBibleReadWindow::saveChapterHTML); + + m_actions.print.reference = + &initAction("printReferenceWithText", + this, + &CBibleReadWindow::printAnchorWithText); + + m_actions.print.chapter = + &initAction("printChapter", this, &CBibleReadWindow::printAll); ac->readShortcuts("Bible shortcuts"); } @@ -277,9 +230,9 @@ void CBibleReadWindow::setupPopupMenu() { m_actions.saveMenu->addAction(m_actions.save.chapterAsHTML); // Save raw HTML action for debugging purposes - if (qApp->property("--debug").toBool()) { + if (btApp->debugMode()) { QAction* debugAction = new QAction("Raw HTML", this); - QObject::connect(debugAction, SIGNAL(triggered()), this, SLOT(saveRawHTML())); + BT_CONNECT(debugAction, SIGNAL(triggered()), this, SLOT(saveRawHTML())); m_actions.saveMenu->addAction(debugAction); } // end of Save Raw HTML popup()->addMenu(m_actions.saveMenu); @@ -294,16 +247,19 @@ void CBibleReadWindow::setupPopupMenu() { void CBibleReadWindow::updatePopupMenu() { qWarning("CBibleReadWindow::updatePopupMenu()"); - m_actions.findStrongs->setEnabled(!displayWidget()->getCurrentNodeInfo().isNull()); + CReadDisplay const & display = + *static_cast<CReadDisplay *>(displayWidget()); + m_actions.findStrongs->setEnabled(!display.getCurrentNodeInfo().isNull()); - m_actions.copy.referenceOnly->setEnabled( ((CReadDisplay*)displayWidget())->hasActiveAnchor() ); - m_actions.copy.referenceTextOnly->setEnabled( ((CReadDisplay*)displayWidget())->hasActiveAnchor() ); - m_actions.copy.referenceAndText->setEnabled( ((CReadDisplay*)displayWidget())->hasActiveAnchor() ); - m_actions.copy.selectedText->setEnabled( ((CReadDisplay*)displayWidget())->hasSelection() ); + bool const hasActiveAnchor = display.hasActiveAnchor(); + m_actions.copy.referenceOnly->setEnabled(hasActiveAnchor); + m_actions.copy.referenceTextOnly->setEnabled(hasActiveAnchor); + m_actions.copy.referenceAndText->setEnabled(hasActiveAnchor); + m_actions.copy.selectedText->setEnabled(display.hasSelection()); - m_actions.save.referenceAndText->setEnabled( ((CReadDisplay*)displayWidget())->hasActiveAnchor() ); + m_actions.save.referenceAndText->setEnabled(hasActiveAnchor); - m_actions.print.reference->setEnabled( ((CReadDisplay*)displayWidget())->hasActiveAnchor() ); + m_actions.print.reference->setEnabled(hasActiveAnchor); } /** Moves to the next book. */ @@ -351,7 +307,7 @@ void CBibleReadWindow::previousVerse() { /** wrapper around key() to return the right type of key. */ CSwordVerseKey* CBibleReadWindow::verseKey() { CSwordVerseKey* k = dynamic_cast<CSwordVerseKey*>(CDisplayWindow::key()); - Q_ASSERT(k); + BT_ASSERT(k); return k; } @@ -375,7 +331,7 @@ void CBibleReadWindow::copyDisplayedText() { /** Saves the chapter as valid HTML page. */ void CBibleReadWindow::saveChapterHTML() { //saves the complete chapter to disk - Q_ASSERT(dynamic_cast<const CSwordBibleModuleInfo*>(modules().first()) != 0); + BT_ASSERT(dynamic_cast<CSwordBibleModuleInfo const *>(modules().first())); const CSwordBibleModuleInfo *bible = static_cast<const CSwordBibleModuleInfo*>(modules().first()); CSwordVerseKey dummy(*verseKey()); @@ -428,7 +384,7 @@ void CBibleReadWindow::reload(CSwordBackend::SetupChangedReason reason) { bool CBibleReadWindow::eventFilter( QObject* o, QEvent* e) { const bool ret = CLexiconReadWindow::eventFilter(o, e); - // Q_ASSERT(o->inherits("CDisplayWindow")); + // BT_ASSERT(o->inherits("CDisplayWindow")); // qWarning("class: %s", o->className()); if (e && (e->type() == QEvent::FocusIn)) { //sync other windows to this active @@ -452,7 +408,7 @@ void CBibleReadWindow::lookupSwordKey( CSwordKey* newKey ) { } void CBibleReadWindow::syncWindows() { - foreach (QMdiSubWindow* subWindow, mdi()->subWindowList()) { + Q_FOREACH(QMdiSubWindow * const subWindow, mdi()->subWindowList()) { CDisplayWindow* w = dynamic_cast<CDisplayWindow*>(subWindow->widget()); if (w && w->syncAllowed()) { w->lookupKey( key()->key() ); diff --git a/src/frontend/displaywindow/cbiblereadwindow.h b/src/frontend/displaywindow/cbiblereadwindow.h index 99c98fb..0be8c6d 100644 --- a/src/frontend/displaywindow/cbiblereadwindow.h +++ b/src/frontend/displaywindow/cbiblereadwindow.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -14,8 +14,11 @@ #include "frontend/displaywindow/clexiconreadwindow.h" +#include <QAction> +#include "frontend/displaywindow/btactioncollection.h" +#include "util/btconnect.h" + -class BtActionCollection; class CSwordKey; class CSwordVerseKey; class CTransliterationButton; @@ -33,30 +36,33 @@ class CBibleReadWindow: public CLexiconReadWindow { inline CBibleReadWindow(const QList<CSwordModuleInfo*> & modules, CMDIArea* parent) : CLexiconReadWindow(modules, parent) {} - virtual void storeProfileSettings(const QString & windowGroup); - virtual void applyProfileSettings(const QString & windowGroup); + CSwordModuleInfo::ModuleType moduleType() const override + { return CSwordModuleInfo::Bible; } + + void storeProfileSettings(QString const & windowGroup) const override; + void applyProfileSettings(const QString & windowGroup) override; static void insertKeyboardActions( BtActionCollection* const a ); protected: /* Methods: */ - virtual void initActions(); - virtual void initToolbars(); - virtual void initConnections(); - virtual void initView(); - /** Called to add actions to mainWindow toolbars */ - virtual void setupMainWindowToolBars(); - /** - * Reimplementation. - */ - virtual void setupPopupMenu(); - /** - * Reimplemented. - */ - virtual void updatePopupMenu(); - /** Event filter. - * Reimplementation of the event filter to filter out events like focus in. - */ - virtual bool eventFilter( QObject* o, QEvent* e); + template <typename ... Args> + QAction & initAction(QString actionName, Args && ... args) { + QAction & action = m_actionCollection->action(std::move(actionName)); + BT_CONNECT(&action, + &QAction::triggered, + std::forward<Args>(args)...); + addAction(&action); + return action; + } + + void initActions() override; + void initToolbars() override; + void initConnections() override; + void initView() override; + void setupMainWindowToolBars() override; + void setupPopupMenu() override; + void updatePopupMenu() override; + bool eventFilter( QObject* o, QEvent* e) override; struct { QAction* selectAll; @@ -99,17 +105,15 @@ class CBibleReadWindow: public CLexiconReadWindow { void previousChapter(); void nextVerse(); void previousVerse(); - /** - * Refreshes the content of this display window and the content of the keychooser. - */ - virtual void reload(CSwordBackend::SetupChangedReason reason); + + void reload(CSwordBackend::SetupChangedReason reason) override; protected slots: /** * Copies the current chapter into the clipboard. */ - void copyDisplayedText(); + void copyDisplayedText() override; /** * Saves the chapter as valid HTML page. */ @@ -118,7 +122,7 @@ class CBibleReadWindow: public CLexiconReadWindow { * Saves the chapter as valid HTML page. */ void saveChapterPlain(); - virtual void lookupSwordKey( CSwordKey* newKey ); + void lookupSwordKey(CSwordKey * newKey) override; void syncWindows(); private: /* Methods: */ diff --git a/src/frontend/displaywindow/cbookreadwindow.cpp b/src/frontend/displaywindow/cbookreadwindow.cpp index fade4d5..6c68264 100644 --- a/src/frontend/displaywindow/cbookreadwindow.cpp +++ b/src/frontend/displaywindow/cbookreadwindow.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -21,6 +21,8 @@ #include "frontend/displaywindow/btmodulechooserbar.h" #include "frontend/displaywindow/btdisplaysettingsbutton.h" #include "frontend/keychooser/cbooktreechooser.h" +#include "util/btassert.h" +#include "util/btconnect.h" #include "util/cresmgr.h" #include "util/tool.h" @@ -28,16 +30,16 @@ void CBookReadWindow::applyProfileSettings(const QString & windowGroup) { CLexiconReadWindow::applyProfileSettings(windowGroup); - Q_ASSERT(m_treeAction); - Q_ASSERT(windowGroup.endsWith('/')); + BT_ASSERT(m_treeAction); + BT_ASSERT(windowGroup.endsWith('/')); if (btConfig().sessionValue<bool>(windowGroup + "treeShown", true) != m_treeAction->isChecked()) m_treeAction->activate(QAction::Trigger); } -void CBookReadWindow::storeProfileSettings(const QString & windowGroup) { +void CBookReadWindow::storeProfileSettings(QString const & windowGroup) const { CLexiconReadWindow::storeProfileSettings(windowGroup); - Q_ASSERT(windowGroup.endsWith('/')); + BT_ASSERT(windowGroup.endsWith('/')); btConfig().setSessionValue(windowGroup + "treeShown", m_treeAction->isChecked()); } @@ -47,17 +49,12 @@ void CBookReadWindow::initActions() { insertKeyboardActions(ac); //cleanup, not a clean oo-solution - QAction *a = ac->action("nextEntry"); - Q_ASSERT(a != 0); - a->setEnabled(false); - a = ac->action("previousEntry"); - Q_ASSERT(a != 0); - a->setEnabled(false); - - m_treeAction = ac->action("toggleTree"); - Q_ASSERT(m_treeAction != 0); - QObject::connect(m_treeAction, SIGNAL(triggered()), - this, SLOT(treeToggled())); + ac->action("nextEntry").setEnabled(false); + ac->action("previousEntry").setEnabled(false); + + m_treeAction = &ac->action("toggleTree"); + BT_ASSERT(m_treeAction); + BT_CONNECT(m_treeAction, SIGNAL(triggered()), this, SLOT(treeToggled())); addAction(m_treeAction); ac->readShortcuts("Book shortcuts"); @@ -69,7 +66,7 @@ void CBookReadWindow::insertKeyboardActions( BtActionCollection* const a ) { qaction = new QAction( /* QIcon(CResMgr::displaywindows::bookWindow::toggleTree::icon), */ tr("Toggle tree view"), a); qaction->setCheckable(true); - qaction->setShortcut(CResMgr::displaywindows::bookWindow::toggleTree::accel); + // qaction->setShortcut(CResMgr::displaywindows::bookWindow::toggleTree::accel); a->addAction("toggleTree", qaction); } @@ -77,9 +74,12 @@ void CBookReadWindow::insertKeyboardActions( BtActionCollection* const a ) { void CBookReadWindow::initConnections() { CLexiconReadWindow::initConnections(); - connect(m_treeChooser, SIGNAL(keyChanged(CSwordKey*)), this, SLOT(lookupSwordKey(CSwordKey*))); - connect(m_treeChooser, SIGNAL(keyChanged(CSwordKey*)), keyChooser(), SLOT(updateKey(CSwordKey*))); - connect(keyChooser(), SIGNAL(keyChanged(CSwordKey*)), m_treeChooser, SLOT(updateKey(CSwordKey*))); + BT_CONNECT(m_treeChooser, SIGNAL(keyChanged(CSwordKey *)), + this, SLOT(lookupSwordKey(CSwordKey *))); + BT_CONNECT(m_treeChooser, SIGNAL(keyChanged(CSwordKey *)), + keyChooser(), SLOT(updateKey(CSwordKey *))); + BT_CONNECT(keyChooser(), SIGNAL(keyChanged(CSwordKey *)), + m_treeChooser, SLOT(updateKey(CSwordKey *))); } /** Init the view */ @@ -112,8 +112,8 @@ void CBookReadWindow::initView() { } void CBookReadWindow::initToolbars() { - Q_ASSERT(m_treeAction); - Q_ASSERT(m_actions.backInHistory); + BT_ASSERT(m_treeAction); + BT_ASSERT(m_actions.backInHistory); mainToolBar()->addAction(m_actions.backInHistory); mainToolBar()->addAction(m_actions.forwardInHistory); @@ -125,10 +125,10 @@ void CBookReadWindow::initToolbars() { BtDisplaySettingsButton* button = new BtDisplaySettingsButton(buttonsToolBar()); setDisplaySettingsButton(button); buttonsToolBar()->addWidget(button); // Display settings - QAction *action = actionCollection()->action(CResMgr::displaywindows::general::search::actionName); - if (action != 0) { - buttonsToolBar()->addAction(action); // Search - } + // Search: + buttonsToolBar()->addAction( + &actionCollection()->action( + CResMgr::displaywindows::general::search::actionName)); } void CBookReadWindow::setupMainWindowToolBars() { @@ -137,10 +137,10 @@ void CBookReadWindow::setupMainWindowToolBars() { btMainWindow()->navToolBar()->addAction(m_actions.forwardInHistory); //2nd button CKeyChooser* keyChooser = CKeyChooser::createInstance(modules(), history(), key(), btMainWindow()->navToolBar() ); btMainWindow()->navToolBar()->addWidget(keyChooser); - bool ok = connect(keyChooser, SIGNAL(keyChanged(CSwordKey*)), this, SLOT(lookupSwordKey(CSwordKey*))); - Q_ASSERT(ok); - ok = connect(this, SIGNAL(sigKeyChanged(CSwordKey*)), keyChooser, SLOT(updateKey(CSwordKey*)) ); - Q_ASSERT(ok); + BT_CONNECT(keyChooser, SIGNAL(keyChanged(CSwordKey *)), + this, SLOT(lookupSwordKey(CSwordKey *))); + BT_CONNECT(this, SIGNAL(sigKeyChanged(CSwordKey *)), + keyChooser, SLOT(updateKey(CSwordKey *))); // Works toolbar btMainWindow()->worksToolBar()->setModules(getModuleList(), modules().first()->type(), this); @@ -150,16 +150,16 @@ void CBookReadWindow::setupMainWindowToolBars() { BtDisplaySettingsButton* button = new BtDisplaySettingsButton(buttonsToolBar()); setDisplaySettingsButton(button); btMainWindow()->toolsToolBar()->addWidget(button); // Display settings - QAction *action = actionCollection()->action(CResMgr::displaywindows::general::search::actionName); - if (action != 0) { - btMainWindow()->toolsToolBar()->addAction(action); // Search - } + // Search: + btMainWindow()->toolsToolBar()->addAction( + &actionCollection()->action( + CResMgr::displaywindows::general::search::actionName)); } /** Is called when the action was executed to toggle the tree view. */ void CBookReadWindow::treeToggled() { if (m_treeAction->isChecked()) { - m_treeChooser->show(); + m_treeChooser->doShow(); } else { m_treeChooser->hide(); diff --git a/src/frontend/displaywindow/cbookreadwindow.h b/src/frontend/displaywindow/cbookreadwindow.h index 63f3922..e11ab12 100644 --- a/src/frontend/displaywindow/cbookreadwindow.h +++ b/src/frontend/displaywindow/cbookreadwindow.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's BtActionCollection code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime BtActionCollection code is licensed under the GNU General Public License version 2.0. * **********/ @@ -25,37 +25,33 @@ class CBookReadWindow: public CLexiconReadWindow { inline CBookReadWindow(const QList<CSwordModuleInfo *> & modules, CMDIArea * parent) : CLexiconReadWindow(modules, parent) - , m_treeAction(0) - , m_treeChooser(0) {} + , m_treeAction(nullptr) + , m_treeChooser(nullptr) {} - virtual void storeProfileSettings(const QString & windowGroup); - virtual void applyProfileSettings(const QString & windowGroup); + CSwordModuleInfo::ModuleType moduleType() const override + { return CSwordModuleInfo::GenericBook; } + + void storeProfileSettings(QString const & windowGroup) const override; + void applyProfileSettings(const QString & windowGroup) override; static void insertKeyboardActions(BtActionCollection * const a); public slots: - /** - * Refreshes the content of this display window and the content of the keychooser. - */ - virtual void reload(CSwordBackend::SetupChangedReason reason); + void reload(CSwordBackend::SetupChangedReason reason) override; protected: /* Methods: */ - virtual void initActions(); - virtual void initToolbars(); - virtual void initConnections(); - virtual void initView(); - /** Called to add actions to mainWindow toolbars */ - virtual void setupMainWindowToolBars(); + void initActions() override; + void initToolbars() override; + void initConnections() override; + void initView() override; + void setupMainWindowToolBars() override; - virtual void setupPopupMenu(); + void setupPopupMenu() override; protected slots: - /** - * Reimplementation to take care of the tree chooser. - */ - virtual void modulesChanged(); + void modulesChanged() override; private slots: diff --git a/src/frontend/displaywindow/ccommentaryreadwindow.cpp b/src/frontend/displaywindow/ccommentaryreadwindow.cpp index 1beb5c5..86313dc 100644 --- a/src/frontend/displaywindow/ccommentaryreadwindow.cpp +++ b/src/frontend/displaywindow/ccommentaryreadwindow.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -21,8 +21,8 @@ #include "frontend/displaywindow/btactioncollection.h" #include "frontend/displaywindow/btmodulechooserbar.h" #include "frontend/keychooser/ckeychooser.h" +#include "util/btconnect.h" #include "util/cresmgr.h" -#include "util/geticon.h" void CCommentaryReadWindow::insertKeyboardActions(BtActionCollection* const a) { @@ -52,7 +52,7 @@ void CCommentaryReadWindow::insertKeyboardActions(BtActionCollection* const a) { qaction->setShortcut(CResMgr::displaywindows::bibleWindow::previousVerse::accel); a->addAction("previousVerse", qaction); - qaction = new QAction(QIcon(util::getIcon(CResMgr::displaywindows::commentaryWindow::syncWindow::icon)), + qaction = new QAction(CResMgr::displaywindows::commentaryWindow::syncWindow::icon(), tr("Synchronize"), a); qaction->setCheckable(true); qaction->setShortcut(CResMgr::displaywindows::commentaryWindow::syncWindow::accel); @@ -65,54 +65,27 @@ void CCommentaryReadWindow::initActions() { BtActionCollection* ac = actionCollection(); insertKeyboardActions(ac); - //cleanup, not a clean oo-solution - QAction *qaction = ac->action("nextEntry"); - Q_ASSERT(qaction != 0); - qaction->setEnabled(false); - qaction = ac->action("previousEntry"); - Q_ASSERT(qaction != 0); - qaction->setEnabled(false); - - qaction = ac->action("nextBook"); - Q_ASSERT(qaction != 0); - QObject::connect(qaction, SIGNAL(triggered()), - this, SLOT(nextBook())); - addAction(qaction); - - qaction = ac->action("previousBook"); - Q_ASSERT(qaction != 0); - QObject::connect(qaction, SIGNAL(triggered()), - this, SLOT(previousBook())); - addAction(qaction); - - qaction = ac->action("nextChapter"); - Q_ASSERT(qaction != 0); - QObject::connect(qaction, SIGNAL(triggered()), - this, SLOT(nextChapter())); - addAction(qaction); - - qaction = ac->action("previousChapter"); - Q_ASSERT(qaction != 0); - QObject::connect(qaction, SIGNAL(triggered()), - this, SLOT(previousChapter())); - addAction(qaction); - - qaction = ac->action("nextVerse"); - Q_ASSERT(qaction != 0); - QObject::connect(qaction, SIGNAL(triggered()), - this, SLOT(nextVerse())); - addAction(qaction); - - qaction = ac->action("previousVerse"); - Q_ASSERT(qaction != 0); - QObject::connect(qaction, SIGNAL(triggered()), - this, SLOT(previousVerse())); - addAction(qaction); - - qaction = ac->action(CResMgr::displaywindows::commentaryWindow::syncWindow::actionName); - Q_ASSERT(qaction != 0); - m_syncButton = qaction; - addAction(qaction); + ac->action("nextEntry").setEnabled(false); + ac->action("previousEntry").setEnabled(false); + + auto const initAction = [this, ac](QString actionName, + void (CCommentaryReadWindow::* slot)()) + { + QAction & action = ac->action(std::move(actionName)); + BT_CONNECT(&action, &QAction::triggered, this, slot); + addAction(&action); + }; + + initAction("nextBook", &CCommentaryReadWindow::nextBook); + initAction("previousBook", &CCommentaryReadWindow::previousBook); + initAction("nextChapter", &CCommentaryReadWindow::nextChapter); + initAction("previousChapter", &CCommentaryReadWindow::previousChapter); + initAction("nextVerse", &CCommentaryReadWindow::nextVerse); + initAction("previousVerse", &CCommentaryReadWindow::previousVerse); + + QAction & qaction = ac->action(CResMgr::displaywindows::commentaryWindow::syncWindow::actionName); + m_syncButton = &qaction; + addAction(&qaction); actionCollection()->readShortcuts("Commentary shortcuts"); } @@ -120,16 +93,18 @@ void CCommentaryReadWindow::initActions() { void CCommentaryReadWindow::applyProfileSettings(const QString & windowGroup) { CLexiconReadWindow::applyProfileSettings(windowGroup); - Q_ASSERT(windowGroup.endsWith('/')); - Q_ASSERT(m_syncButton); + BT_ASSERT(windowGroup.endsWith('/')); + BT_ASSERT(m_syncButton); m_syncButton->setChecked(btConfig().sessionValue<bool>(windowGroup + "syncEnabled", false)); } -void CCommentaryReadWindow::storeProfileSettings(const QString & windowGroup) { +void CCommentaryReadWindow::storeProfileSettings(QString const & windowGroup) + const +{ CLexiconReadWindow::storeProfileSettings(windowGroup); - Q_ASSERT(windowGroup.endsWith('/')); - Q_ASSERT(m_syncButton); + BT_ASSERT(windowGroup.endsWith('/')); + BT_ASSERT(m_syncButton); btConfig().setSessionValue(windowGroup + "syncEnabled", m_syncButton->isChecked()); } @@ -157,7 +132,7 @@ void CCommentaryReadWindow::reload(CSwordBackend::SetupChangedReason reason) { /** rapper around key() to return the right type of key. */ CSwordVerseKey* CCommentaryReadWindow::verseKey() { CSwordVerseKey* k = dynamic_cast<CSwordVerseKey*>(CDisplayWindow::key()); - Q_ASSERT(k); + BT_ASSERT(k); return k; } diff --git a/src/frontend/displaywindow/ccommentaryreadwindow.h b/src/frontend/displaywindow/ccommentaryreadwindow.h index 06cbd93..3dc7029 100644 --- a/src/frontend/displaywindow/ccommentaryreadwindow.h +++ b/src/frontend/displaywindow/ccommentaryreadwindow.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -33,33 +33,32 @@ class CCommentaryReadWindow : public CLexiconReadWindow { inline CCommentaryReadWindow(const QList<CSwordModuleInfo *> & modules, CMDIArea * parent) : CLexiconReadWindow(modules, parent) {} - virtual void storeProfileSettings(const QString & windowGroup); - virtual void applyProfileSettings(const QString & windowGroup); - virtual bool syncAllowed() const; + CSwordModuleInfo::ModuleType moduleType() const override + { return CSwordModuleInfo::Commentary; } - public slots: // Public slots + void storeProfileSettings(QString const & windowGroup) const override; + void applyProfileSettings(const QString & windowGroup) override; + bool syncAllowed() const override; + + public slots: void nextBook(); void previousBook(); void nextChapter(); void previousChapter(); void nextVerse(); void previousVerse(); - /** - * Reimplementation to handle the keychooser refresh. - */ - virtual void reload(CSwordBackend::SetupChangedReason); + void reload(CSwordBackend::SetupChangedReason) override; protected: - virtual void initActions(); - virtual void initToolbars(); - /** Called to add actions to mainWindow toolbars */ - virtual void setupMainWindowToolBars(); + void initActions() override; + void initToolbars() override; + void setupMainWindowToolBars() override; private: QAction* m_syncButton; CSwordVerseKey* verseKey(); protected: - virtual void setupPopupMenu(); + void setupPopupMenu() override; }; #endif diff --git a/src/frontend/displaywindow/cdisplaywindow.cpp b/src/frontend/displaywindow/cdisplaywindow.cpp index a584d6e..1285205 100644 --- a/src/frontend/displaywindow/cdisplaywindow.cpp +++ b/src/frontend/displaywindow/cdisplaywindow.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -22,59 +22,65 @@ #include "frontend/cmdiarea.h" #include "frontend/display/cdisplay.h" #include "frontend/displaywindow/bttoolbarpopupaction.h" -#include "frontend/displaywindow/btactioncollection.h" #include "frontend/displaywindow/btmodulechooserbar.h" #include "frontend/displaywindow/btdisplaysettingsbutton.h" #include "frontend/keychooser/ckeychooser.h" #include "frontend/keychooser/bthistory.h" #include "frontend/searchdialog/csearchdialog.h" #include "util/cresmgr.h" -#include "util/geticon.h" + + +namespace { + +inline QWidget * getProfileWindow(QWidget * w) { + for (; w; w = w->parentWidget()) + if (QMdiSubWindow * const sw = qobject_cast<QMdiSubWindow *>(w)) + return sw; + return nullptr; +} + +} CDisplayWindow::CDisplayWindow(const QList<CSwordModuleInfo *> & modules, CMDIArea * parent) : QMainWindow(parent), - m_actionCollection(0), + m_actionCollection(nullptr), m_mdi(parent), - m_keyChooser(0), - m_swordKey(0), + m_keyChooser(nullptr), + m_swordKey(nullptr), m_isReady(false), - m_moduleChooserBar(0), - m_mainToolBar(0), - m_buttonsToolBar(0), - m_formatToolBar(0), - m_headerBar(0), - m_popupMenu(0), - m_displayWidget(0), - m_history(0) { + m_moduleChooserBar(nullptr), + m_mainToolBar(nullptr), + m_buttonsToolBar(nullptr), + m_formatToolBar(nullptr), + m_headerBar(nullptr), + m_popupMenu(nullptr), + m_displayWidget(nullptr), + m_history(nullptr) { setAttribute(Qt::WA_DeleteOnClose); //we want to destroy this window when it is closed m_actionCollection = new BtActionCollection(this); setModules(modules); // Connect this to the backend module list changes - connect(CSwordBackend::instance(), - SIGNAL(sigSwordSetupChanged(CSwordBackend::SetupChangedReason)), - SLOT(reload(CSwordBackend::SetupChangedReason))); + BT_CONNECT(CSwordBackend::instance(), + SIGNAL(sigSwordSetupChanged(CSwordBackend::SetupChangedReason)), + SLOT(reload(CSwordBackend::SetupChangedReason))); BibleTime* mainwindow = btMainWindow(); - connect(mainwindow, SIGNAL(toggledTextWindowHeader(bool)), SLOT(slotShowHeader(bool)) ); - connect(mainwindow, SIGNAL(toggledTextWindowNavigator(bool)), SLOT(slotShowNavigator(bool)) ); - connect(mainwindow, SIGNAL(toggledTextWindowToolButtons(bool)), SLOT(slotShowToolButtons(bool)) ); - connect(mainwindow, SIGNAL(toggledTextWindowModuleChooser(bool)), SLOT(slotShowModuleChooser(bool)) ); - connect(mainwindow, SIGNAL(toggledTextWindowFormatToolbar(bool)), SLOT(slotShowFormatToolBar(bool)) ); + BT_CONNECT(mainwindow, SIGNAL(toggledTextWindowHeader(bool)), + SLOT(slotShowHeader(bool))); + BT_CONNECT(mainwindow, SIGNAL(toggledTextWindowNavigator(bool)), + SLOT(slotShowNavigator(bool))); + BT_CONNECT(mainwindow, SIGNAL(toggledTextWindowToolButtons(bool)), + SLOT(slotShowToolButtons(bool))); + BT_CONNECT(mainwindow, SIGNAL(toggledTextWindowModuleChooser(bool)), + SLOT(slotShowModuleChooser(bool))); + BT_CONNECT(mainwindow, SIGNAL(toggledTextWindowFormatToolbar(bool)), + SLOT(slotShowFormatToolBar(bool))); } CDisplayWindow::~CDisplayWindow() { delete m_swordKey; - m_swordKey = 0; -} - -QWidget * CDisplayWindow::getProfileWindow() const { - for (QWidget * w = parentWidget(); w; w = w->parentWidget()) { - QMdiSubWindow * sw = qobject_cast<QMdiSubWindow *>(w); - if (sw) - return sw; - } - return const_cast<CDisplayWindow *>(this); + m_swordKey = nullptr; } BibleTime* CDisplayWindow::btMainWindow() { @@ -83,14 +89,14 @@ BibleTime* CDisplayWindow::btMainWindow() { void CDisplayWindow::setToolBarsHidden() { // Hide current window toolbars - if (mainToolBar()) - mainToolBar()->setHidden(true); - if (buttonsToolBar()) - buttonsToolBar()->setHidden(true); - if (moduleChooserBar()) - moduleChooserBar()->setHidden(true); - if (formatToolBar()) - formatToolBar()->setHidden(true); + if (m_mainToolBar) + m_mainToolBar->setHidden(true); + if (m_buttonsToolBar) + m_buttonsToolBar->setHidden(true); + if (m_moduleChooserBar) + m_moduleChooserBar->setHidden(true); + if (m_formatToolBar) + m_formatToolBar->setHidden(true); } void CDisplayWindow::clearMainWindowToolBars() { // Clear main window toolbars, except for works toolbar @@ -114,17 +120,18 @@ const QString CDisplayWindow::windowCaption() { } /** Returns the used modules as a pointer list */ -const QList<const CSwordModuleInfo*> CDisplayWindow::modules() const { +const BtConstModuleList CDisplayWindow::modules() const { return CSwordBackend::instance()->getConstPointerList(m_modules); } /** Store the settings of this window in the given CProfileWindow object. */ -void CDisplayWindow::storeProfileSettings(const QString & windowGroup) { +void CDisplayWindow::storeProfileSettings(QString const & windowGroup) const { BtConfig & conf = btConfig(); conf.beginGroup(windowGroup); - QWidget * w = getProfileWindow(); + QWidget const * const w = getProfileWindow(parentWidget()); + BT_ASSERT(w); /** \note We don't use saveGeometry/restoreGeometry for MDI subwindows, @@ -133,7 +140,10 @@ void CDisplayWindow::storeProfileSettings(const QString & windowGroup) { */ const QRect rect(w->x(), w->y(), w->width(), w->height()); conf.setSessionValue<QRect>("windowRect", rect); - + conf.setSessionValue<bool>("staysOnTop", + w->windowFlags() & Qt::WindowStaysOnTopHint); + conf.setSessionValue<bool>("staysOnBottom", + w->windowFlags() & Qt::WindowStaysOnBottomHint); conf.setSessionValue("maximized", w->isMaximized()); bool hasFocus = (w == dynamic_cast<CDisplayWindow *>(mdi()->activeSubWindow())); @@ -141,11 +151,8 @@ void CDisplayWindow::storeProfileSettings(const QString & windowGroup) { // conf.setSessionValue("type", static_cast<int>(modules().first()->type())); // Save current key: - if (key()) { - CSwordKey * k = key(); - sword::VerseKey * vk = dynamic_cast<sword::VerseKey*>(k); - QString oldLang; - if (vk) { + if (CSwordKey * const k = key()) { + if (sword::VerseKey * const vk = dynamic_cast<sword::VerseKey *>(k)) { // Save keys in english only: const QString oldLang = QString::fromLatin1(vk->getLocale()); vk->setLocale("en"); @@ -157,10 +164,10 @@ void CDisplayWindow::storeProfileSettings(const QString & windowGroup) { } // Save list of modules: - QStringList mods; - Q_FOREACH (const CSwordModuleInfo * module, modules()) - mods.append(module->name()); - conf.setSessionValue("modules", mods); + conf.setSessionValue("modules", m_modules); + + // Default for "not a write window": + conf.setSessionValue("writeWindowType", int(0)); conf.endGroup(); } @@ -170,7 +177,8 @@ void CDisplayWindow::applyProfileSettings(const QString & windowGroup) { conf.beginGroup(windowGroup); setUpdatesEnabled(false); - QWidget * w = getProfileWindow(); + QWidget * const w = getProfileWindow(parentWidget()); + BT_ASSERT(w); /** \note We don't use restoreGeometry/saveGeometry for MDI subwindows, @@ -180,7 +188,10 @@ void CDisplayWindow::applyProfileSettings(const QString & windowGroup) { const QRect rect = conf.sessionValue<QRect>("windowRect"); w->resize(rect.width(), rect.height()); w->move(rect.x(), rect.y()); - + if (conf.sessionValue<bool>("staysOnTop", false)) + w->setWindowFlags(w->windowFlags() | Qt::WindowStaysOnTopHint); + if (conf.sessionValue<bool>("staysOnBottom", false)) + w->setWindowFlags(w->windowFlags() | Qt::WindowStaysOnBottomHint); if (conf.sessionValue<bool>("maximized")) w->showMaximized(); @@ -205,13 +216,13 @@ void CDisplayWindow::insertKeyboardActions( BtActionCollection* a ) { actn->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_L)); a->addAction("openLocation", actn); - actn = new QAction(QIcon(util::getIcon(CResMgr::displaywindows::general::search::icon)), + actn = new QAction(CResMgr::displaywindows::general::search::icon(), tr("Search with works of this window"), a); actn->setShortcut(CResMgr::displaywindows::general::search::accel); a->addAction(CResMgr::displaywindows::general::search::actionName, actn); BtToolBarPopupAction* action = new BtToolBarPopupAction( - QIcon(util::getIcon(CResMgr::displaywindows::general::backInHistory::icon)), + CResMgr::displaywindows::general::backInHistory::icon(), tr("Back in history"), a ); @@ -219,7 +230,7 @@ void CDisplayWindow::insertKeyboardActions( BtActionCollection* a ) { a->addAction(CResMgr::displaywindows::general::backInHistory::actionName, action); action = new BtToolBarPopupAction( - QIcon(util::getIcon(CResMgr::displaywindows::general::forwardInHistory::icon)), + CResMgr::displaywindows::general::forwardInHistory::icon(), tr("Forward in history"), a ); @@ -232,62 +243,39 @@ void CDisplayWindow::initActions() { CDisplayWindow::insertKeyboardActions(ac); - QAction* actn = ac->action(CResMgr::displaywindows::general::search::actionName); - Q_ASSERT(actn != 0); - QObject::connect(actn, SIGNAL(triggered()), - this, SLOT(slotSearchInModules())); - - CDisplayConnections* conn = displayWidget()->connectionsProxy(); - - actn = ac->action("openLocation"); - Q_ASSERT(actn != 0); - QObject::connect(actn, SIGNAL(triggered()), - this, SLOT(setFocusKeyChooser())); - addAction(actn); - - actn = ac->action("selectAll"); - Q_ASSERT(actn != 0); - QObject::connect(actn, SIGNAL(triggered()), - conn, SLOT(selectAll())); - addAction(actn); - - actn = ac->action("copySelectedText"); - Q_ASSERT(actn != 0); - QObject::connect(actn, SIGNAL(triggered()), - conn, SLOT(copySelection())); - addAction(actn); - - actn = ac->action("findText"); - Q_ASSERT(actn != 0); - QObject::connect(actn, SIGNAL(triggered()), - conn, SLOT(openFindTextDialog())); - addAction(actn); - - actn = ac->action(CResMgr::displaywindows::general::backInHistory::actionName); - Q_ASSERT(actn != 0); - bool ok = QObject::connect(actn, SIGNAL(triggered()), - keyChooser()->history(), SLOT(back())); - Q_ASSERT(ok); - addAction(actn); - - actn = ac->action(CResMgr::displaywindows::general::forwardInHistory::actionName); - Q_ASSERT(actn != 0); - ok = QObject::connect(actn, SIGNAL(triggered()), - keyChooser()->history(), SLOT(fw())); - Q_ASSERT(ok); - addAction(actn); + namespace DWG = CResMgr::displaywindows::general; + initAction(DWG::search::actionName, + this, + &CDisplayWindow::slotSearchInModules); + initAddAction("openLocation", this, &CDisplayWindow::setFocusKeyChooser); + CDisplayConnections * const conn = displayWidget()->connectionsProxy(); + initAddAction("selectAll", + conn, + &CDisplayConnections::selectAll); + initAddAction("copySelectedText", + conn, + &CDisplayConnections::copySelection); + initAddAction("findText", + conn, + &CDisplayConnections::openFindTextDialog); + initAddAction(DWG::backInHistory::actionName, + keyChooser()->history(), + &BTHistory::back); + initAddAction(DWG::forwardInHistory::actionName, + keyChooser()->history(), + &BTHistory::fw); ac->readShortcuts("Displaywindow shortcuts"); } /** Refresh the settings of this window. */ void CDisplayWindow::reload(CSwordBackend::SetupChangedReason) { - //first make sure all used Sword modules are still present - QMutableStringListIterator it(m_modules); - while (it.hasNext()) { - if (!CSwordBackend::instance()->findModuleByName(it.next())) { - it.remove(); - } + { // First make sure all used Sword modules are still present: + CSwordBackend & backend = *(CSwordBackend::instance()); + QMutableStringListIterator it(m_modules); + while (it.hasNext()) + if (!backend.findModuleByName(it.next())) + it.remove(); } if (m_modules.isEmpty()) { @@ -295,12 +283,13 @@ void CDisplayWindow::reload(CSwordBackend::SetupChangedReason) { return; } - if (keyChooser()) keyChooser()->setModules( modules(), false ); + if (CKeyChooser * const kc = keyChooser()) + kc->setModules(modules(), false); lookup(); - actionCollection()->readShortcuts("DisplayWindow shortcuts"); - actionCollection()->readShortcuts("Readwindow shortcuts"); + m_actionCollection->readShortcuts("DisplayWindow shortcuts"); + m_actionCollection->readShortcuts("Readwindow shortcuts"); emit sigModuleListSet(m_modules); } @@ -339,11 +328,6 @@ void CDisplayWindow::setFilterOptions(const FilterOptions &filterOptions) { emit sigFilterOptionsChanged(m_filterOptions); } -/** Set the ready status */ -void CDisplayWindow::setReady(bool ready) { - m_isReady = ready; -} - /** Returns true if the window may be closed. */ bool CDisplayWindow::queryClose() { return true; @@ -356,12 +340,12 @@ void CDisplayWindow::setKeyChooser( CKeyChooser* ck ) { /** Sets the new sword key. */ void CDisplayWindow::setKey( CSwordKey* key ) { - Q_ASSERT( key ); + BT_ASSERT(key); m_swordKey = key; } BTHistory* CDisplayWindow::history() { - if (m_history == 0) + if (m_history == nullptr) m_history = new BTHistory(this); return m_history; } @@ -408,9 +392,8 @@ void CDisplayWindow::setHeaderBar( QToolBar* header ) { void CDisplayWindow::setModules( const QList<CSwordModuleInfo*>& newModules ) { m_modules.clear(); - foreach (CSwordModuleInfo* mod, newModules) { + Q_FOREACH(CSwordModuleInfo const * const mod, newModules) m_modules.append(mod->name()); - } } /** Initialize the window. Call this method from the outside, because calling this in the constructor is not possible! */ @@ -437,7 +420,7 @@ bool CDisplayWindow::init() { emit sigFilterOptionsChanged(m_filterOptions); emit sigModulesChanged(modules()); - setReady(true); + m_isReady = true; return true; } @@ -468,23 +451,23 @@ void CDisplayWindow::setFormatToolBar( QToolBar* bar ) { /** Sets the display settings button. */ void CDisplayWindow::setDisplaySettingsButton(BtDisplaySettingsButton *button) { - connect(this, SIGNAL(sigDisplayOptionsChanged(const DisplayOptions&)), - button, SLOT(setDisplayOptions(const DisplayOptions&))); - connect(this, SIGNAL(sigFilterOptionsChanged(const FilterOptions&)), - button, SLOT(setFilterOptions(const FilterOptions&))); - connect(this, SIGNAL(sigModulesChanged(const QList<const CSwordModuleInfo*>&)), - button, SLOT(setModules(const QList<const CSwordModuleInfo*>&))); + BT_CONNECT(this, SIGNAL(sigDisplayOptionsChanged(DisplayOptions const &)), + button, SLOT(setDisplayOptions(DisplayOptions const &))); + BT_CONNECT(this, SIGNAL(sigFilterOptionsChanged(FilterOptions const &)), + button, SLOT(setFilterOptions(FilterOptions const &))); + BT_CONNECT(this, SIGNAL(sigModulesChanged(BtConstModuleList const &)), + button, SLOT(setModules(BtConstModuleList const &))); button->setDisplayOptions(displayOptions(), false); button->setFilterOptions(filterOptions(), false); button->setModules(modules()); - connect(button, SIGNAL(sigFilterOptionsChanged(const FilterOptions&)), - this, SLOT(setFilterOptions(const FilterOptions&))); - connect(button, SIGNAL(sigDisplayOptionsChanged(const DisplayOptions&)), - this, SLOT(setDisplayOptions(const DisplayOptions&))); - connect(button, SIGNAL(sigChanged()), - this, SLOT(lookup())); + BT_CONNECT(button, SIGNAL(sigFilterOptionsChanged(FilterOptions const &)), + this, SLOT(setFilterOptions(FilterOptions const &))); + BT_CONNECT(button, SIGNAL(sigDisplayOptionsChanged(DisplayOptions const &)), + this, SLOT(setDisplayOptions(DisplayOptions const &))); + BT_CONNECT(button, SIGNAL(sigChanged()), + this, SLOT(lookup())); } void CDisplayWindow::slotShowHeader(bool show) { @@ -536,19 +519,16 @@ void CDisplayWindow::lookupModKey( const QString& moduleName, const QString& key else { //given module not displayed in this window //if the module is displayed in another display window we assume a wrong drop //create a new window for the given module - QList<CSwordModuleInfo*> mList; - mList.append(m); - BibleTime *mainWindow = btMainWindow(); - Q_ASSERT(mainWindow != 0); - mainWindow->createReadDisplayWindow(mList, keyName); + BT_ASSERT(mainWindow); + mainWindow->createReadDisplayWindow(m, keyName); } } void CDisplayWindow::lookupKey( const QString& keyName ) { /* This function is called for example after a bookmark was dropped on this window */ - Q_ASSERT(modules().first()); + BT_ASSERT(modules().first()); lookupModKey(modules().first()->name(), keyName); } @@ -564,7 +544,8 @@ QMenu* CDisplayWindow::popup() { // qWarning("CReadWindow::popup()"); if (!m_popupMenu) { m_popupMenu = new QMenu(this); - connect(m_popupMenu, SIGNAL(aboutToShow()), this, SLOT(updatePopupMenu())); + BT_CONNECT(m_popupMenu, SIGNAL(aboutToShow()), + this, SLOT(updatePopupMenu())); if (displayWidget()) { displayWidget()->installPopup(m_popupMenu); } diff --git a/src/frontend/displaywindow/cdisplaywindow.h b/src/frontend/displaywindow/cdisplaywindow.h index 72199d1..6728d95 100644 --- a/src/frontend/displaywindow/cdisplaywindow.h +++ b/src/frontend/displaywindow/cdisplaywindow.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -14,12 +14,15 @@ #include <QMainWindow> +#include <QAction> #include <QStringList> +#include "backend/btglobal.h" #include "backend/managers/cswordbackend.h" -#include "btglobal.h" +#include "frontend/displaywindow/btactioncollection.h" +#include "util/btassert.h" +#include "util/btconnect.h" -class BtActionCollection; class CDisplay; class BtDisplaySettingsButton; class CKeyChooser; @@ -46,9 +49,6 @@ class CDisplayWindow : public QMainWindow { /** Insert the keyboard accelerators of this window into the given actioncollection.*/ static void insertKeyboardActions( BtActionCollection* const a ); - /** Returns a pointer to the parent widget of type QMdiSubWindow or pointer to self if none found. */ - QWidget * getProfileWindow() const; - /** Returns pointer to the mdi area object.*/ inline CMDIArea *mdi() const { return m_mdi; @@ -58,7 +58,7 @@ class CDisplayWindow : public QMainWindow { const QString windowCaption(); /** Returns the used modules as a pointer list.*/ - const QList<const CSwordModuleInfo*> modules() const; + const BtConstModuleList modules() const; /** Returns the used modules as a string list. */ inline const QStringList &getModuleList() const { @@ -66,7 +66,7 @@ class CDisplayWindow : public QMainWindow { } /** Store the settings of this window in the given CProfileWindow object.*/ - virtual void storeProfileSettings(const QString & windowGroup); + virtual void storeProfileSettings(QString const & windowGroup) const; /** Load the settings the given CProfileWindow object into this window.*/ virtual void applyProfileSettings(const QString & windowGroup); @@ -81,9 +81,6 @@ class CDisplayWindow : public QMainWindow { return m_filterOptions; } - /** Set the ready status. */ - void setReady(bool ready); - /** Returns true if the widget is ready for use. */ inline bool isReady() const { return m_isReady; @@ -105,7 +102,7 @@ class CDisplayWindow : public QMainWindow { /** Returns the key of this display window. */ inline CSwordKey *key() const { - Q_ASSERT(m_swordKey != 0); + BT_ASSERT(m_swordKey); return m_swordKey; } @@ -113,7 +110,7 @@ class CDisplayWindow : public QMainWindow { * Initialize the window. Call this method from the outside, * because calling this in the constructor is not possible! */ - virtual bool init(); + bool init(); /** Sets and inits the properties of the main navigation toolbar.*/ void setMainToolBar( QToolBar* bar ); @@ -149,7 +146,7 @@ class CDisplayWindow : public QMainWindow { /** Returns the display widget used by this implementation of CDisplayWindow. */ virtual inline CDisplay *displayWidget() const { - Q_ASSERT(m_displayWidget != 0); + BT_ASSERT(m_displayWidget); return m_displayWidget; } @@ -160,9 +157,7 @@ class CDisplayWindow : public QMainWindow { * Returns whether syncs to the active window are allowed at this time for this display window * @return boolean value whether sync is allowed */ - virtual bool syncAllowed() const { - return false; - }; + virtual bool syncAllowed() const { return false; } /** * Return pointer to the BibleTime main window @@ -198,7 +193,7 @@ class CDisplayWindow : public QMainWindow { void sigFilterOptionsChanged(const FilterOptions &filterOptions); /** signal for change of modules */ - void sigModulesChanged(const QList<const CSwordModuleInfo*> &modules); + void sigModulesChanged(const BtConstModuleList &modules); /** signal for sword key change */ void sigKeyChanged(CSwordKey* key); @@ -232,7 +227,7 @@ class CDisplayWindow : public QMainWindow { friend class CBibleReadWindow; CDisplayWindow(const QList<CSwordModuleInfo *> & modules, CMDIArea * parent); - virtual ~CDisplayWindow(); + ~CDisplayWindow() override; /** \returns the display options used by this display window. @@ -286,7 +281,7 @@ class CDisplayWindow : public QMainWindow { /** Called to add actions to mainWindow toolbars */ virtual void setupMainWindowToolBars() = 0; - virtual void closeEvent(QCloseEvent* e); + void closeEvent(QCloseEvent* e) override; void setToolBarsHidden(); void clearMainWindowToolBars(); @@ -320,6 +315,19 @@ class CDisplayWindow : public QMainWindow { void setFocusKeyChooser(); + private: /* Methods: */ + + template <typename Name, typename ... Args> + inline QAction & initAction(Name && name, Args && ... args) { + QAction & a = m_actionCollection->action(std::forward<Name>(name)); + BT_CONNECT(&a, &QAction::triggered, std::forward<Args>(args)...); + return a; + } + + template <typename ... Args> + inline void initAddAction(Args && ... args) + { addAction(&initAction(std::forward<Args>(args)...)); } + private: BtActionCollection* m_actionCollection; CMDIArea* m_mdi; diff --git a/src/frontend/displaywindow/cdisplaywindowfactory.cpp b/src/frontend/displaywindow/cdisplaywindowfactory.cpp deleted file mode 100644 index 12059d1..0000000 --- a/src/frontend/displaywindow/cdisplaywindowfactory.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/********* -* -* 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 "frontend/displaywindow/cdisplaywindowfactory.h" - -#include "backend/drivers/cswordmoduleinfo.h" -#include "frontend/displaywindow/cbiblereadwindow.h" -#include "frontend/displaywindow/cbookreadwindow.h" -#include "frontend/displaywindow/ccommentaryreadwindow.h" -#include "frontend/displaywindow/chtmlwritewindow.h" -#include "frontend/displaywindow/clexiconreadwindow.h" -#include "frontend/displaywindow/cplainwritewindow.h" -#include "frontend/displaywindow/creadwindow.h" -#include "frontend/cmdiarea.h" - - -CReadWindow* CDisplayWindowFactory::createReadInstance(const QList<CSwordModuleInfo *> & modules, CMDIArea * parent) { - CReadWindow* win = 0; - switch (modules.first()->type()) { - case CSwordModuleInfo::Bible: - win = new CBibleReadWindow(modules, parent); - break; - case CSwordModuleInfo::Commentary: - win = new CCommentaryReadWindow(modules, parent); - break; - case CSwordModuleInfo::Lexicon: - win = new CLexiconReadWindow(modules, parent); - break; - case CSwordModuleInfo::GenericBook: - win = new CBookReadWindow(modules, parent); - break; - default: - qWarning("unknown module type"); - break; - } - return win; -} - -CPlainWriteWindow * CDisplayWindowFactory::createWriteInstance(const QList<CSwordModuleInfo *> & modules, CMDIArea * parent, CPlainWriteWindow::WriteWindowType type) { - if (type == CPlainWriteWindow::HTMLWindow) { - return new CHTMLWriteWindow(modules, parent); - } - else { - return new CPlainWriteWindow(modules, parent); - } - return 0; -} - -CSwordModuleInfo::ModuleType CDisplayWindowFactory::getModuleType(QObject* widget) { - if (qobject_cast<CBibleReadWindow*>(widget) != 0 ) - return CSwordModuleInfo::Bible; - if (qobject_cast<CCommentaryReadWindow*>(widget) != 0 ) - return CSwordModuleInfo::Commentary; - if (qobject_cast<CBookReadWindow*>(widget) != 0 ) - return CSwordModuleInfo::GenericBook; - if (qobject_cast<CLexiconReadWindow*>(widget) != 0 ) - return CSwordModuleInfo::Lexicon; - return CSwordModuleInfo::Unknown; -} diff --git a/src/frontend/displaywindow/cdisplaywindowfactory.h b/src/frontend/displaywindow/cdisplaywindowfactory.h deleted file mode 100644 index e065e50..0000000 --- a/src/frontend/displaywindow/cdisplaywindowfactory.h +++ /dev/null @@ -1,33 +0,0 @@ -/********* -* -* 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 CDISPLAYWINDOWFACTORY_H -#define CDISPLAYWINDOWFACTORY_H - -#include "frontend/displaywindow/cdisplaywindow.h" -#include "frontend/displaywindow/cplainwritewindow.h" - - -class CReadWindow; -class CSwordModuleInfo; - -/// \todo Make CDisplayWindowFactory a namespace instead? -class CDisplayWindowFactory { - public: - static CReadWindow* createReadInstance(const QList<CSwordModuleInfo *> & modules, CMDIArea * parent); - static CPlainWriteWindow* createWriteInstance(const QList<CSwordModuleInfo*> & modules, CMDIArea * parent, CPlainWriteWindow::WriteWindowType type = CPlainWriteWindow::HTMLWindow); - static CSwordModuleInfo::ModuleType getModuleType(QObject* widget); - - private: - CDisplayWindowFactory(); -}; - -#endif diff --git a/src/frontend/displaywindow/chtmlwritewindow.cpp b/src/frontend/displaywindow/chtmlwritewindow.cpp index 20c8323..cff94f4 100644 --- a/src/frontend/displaywindow/chtmlwritewindow.cpp +++ b/src/frontend/displaywindow/chtmlwritewindow.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -18,6 +18,8 @@ #include "frontend/displaywindow/btmodulechooserbar.h" #include "frontend/keychooser/ckeychooser.h" #include "frontend/messagedialog.h" +#include "util/btassert.h" +#include "util/btconnect.h" #include "util/directory.h" #include "util/cresmgr.h" @@ -27,7 +29,7 @@ CHTMLWriteWindow::CHTMLWriteWindow(const QList<CSwordModuleInfo *> & modules, CM void CHTMLWriteWindow::initView() { m_writeDisplay = new CHTMLWriteDisplay(this, this); - Q_ASSERT(m_writeDisplay); + BT_ASSERT(m_writeDisplay); setDisplayWidget(m_writeDisplay); setCentralWidget(m_writeDisplay->view() ); @@ -47,8 +49,10 @@ void CHTMLWriteWindow::initView() { void CHTMLWriteWindow::initConnections() { CPlainWriteWindow::initConnections(); - connect(keyChooser(), SIGNAL(keyChanged(CSwordKey*)), this, SLOT(lookupSwordKey(CSwordKey*))); - connect(m_writeDisplay->connectionsProxy(), SIGNAL(textChanged()), this, SLOT(textChanged()) ); + BT_CONNECT(keyChooser(), SIGNAL(keyChanged(CSwordKey *)), + this, SLOT(lookupSwordKey(CSwordKey *))); + BT_CONNECT(m_writeDisplay->connectionsProxy(), SIGNAL(textChanged()), + this, SLOT(textChanged())); } void CHTMLWriteWindow::initToolbars() { @@ -60,32 +64,33 @@ void CHTMLWriteWindow::initToolbars() { m_writeDisplay->setupToolbar( formatToolBar(), actionCollection() ); } -void CHTMLWriteWindow::storeProfileSettings(const QString & windowGroup) { +void CHTMLWriteWindow::storeProfileSettings(QString const & windowGroup) const { CPlainWriteWindow::storeProfileSettings(windowGroup); - QAction * action = actionCollection()->action(CResMgr::displaywindows::commentaryWindow::syncWindow::actionName); - Q_ASSERT(action != 0); - Q_ASSERT(windowGroup.endsWith('/')); - btConfig().setSessionValue(windowGroup + "syncWindowEnabled", action->isChecked()); + BT_ASSERT(windowGroup.endsWith('/')); + namespace SW = CResMgr::displaywindows::commentaryWindow::syncWindow; + btConfig().setSessionValue( + windowGroup + "syncWindowEnabled", + actionCollection()->action(SW::actionName).isChecked()); } void CHTMLWriteWindow::applyProfileSettings(const QString & windowGroup) { CPlainWriteWindow::applyProfileSettings(windowGroup); - QAction* action = actionCollection()->action(CResMgr::displaywindows::commentaryWindow::syncWindow::actionName); - Q_ASSERT(action != 0); - Q_ASSERT(windowGroup.endsWith('/')); - action->setChecked(btConfig().sessionValue<bool>(windowGroup + "syncWindowEnabled", false)); + namespace SW = CResMgr::displaywindows::commentaryWindow::syncWindow; + BT_ASSERT(windowGroup.endsWith('/')); + actionCollection()->action(SW::actionName).setChecked( + btConfig().sessionValue<bool>(windowGroup + "syncWindowEnabled", + false)); } /** Is called when the current text was changed. */ void CHTMLWriteWindow::textChanged() { - QAction* action = actionCollection()->action(CResMgr::displaywindows::writeWindow::saveText::actionName); - Q_ASSERT(action != 0); - action->setEnabled(m_writeDisplay->isModified()); - action = actionCollection()->action(CResMgr::displaywindows::writeWindow::restoreText::actionName); - Q_ASSERT(action != 0); - action->setEnabled(m_writeDisplay->isModified()); + namespace WW = CResMgr::displaywindows::writeWindow; + actionCollection()->action(WW::saveText::actionName) + .setEnabled(m_writeDisplay->isModified()); + actionCollection()->action(WW::restoreText::actionName) + .setEnabled(m_writeDisplay->isModified()); } /** Loads the original text from the module. */ @@ -96,9 +101,9 @@ void CHTMLWriteWindow::restoreText() { } bool CHTMLWriteWindow::syncAllowed() const { - QAction* action = actionCollection()->action(CResMgr::displaywindows::commentaryWindow::syncWindow::actionName); - Q_ASSERT(action != 0); - return action->isChecked(); + return actionCollection()->action( + CResMgr::displaywindows::commentaryWindow::syncWindow::actionName) + .isChecked(); } /** Saves the text for the current key. Directly writes the changed text into the module. */ diff --git a/src/frontend/displaywindow/chtmlwritewindow.h b/src/frontend/displaywindow/chtmlwritewindow.h index 2d2eee6..6942057 100644 --- a/src/frontend/displaywindow/chtmlwritewindow.h +++ b/src/frontend/displaywindow/chtmlwritewindow.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -27,43 +27,27 @@ class CHTMLWriteWindow : public CPlainWriteWindow { public: CHTMLWriteWindow(const QList<CSwordModuleInfo *> & modules, CMDIArea * parent); - virtual void storeProfileSettings(const QString & windowGroup); - virtual void applyProfileSettings(const QString & windowGroup); + void storeProfileSettings(QString const & windowGroup) const override; + void applyProfileSettings(const QString & windowGroup) override; - /** - * Returns true if the sync toolbar is enabled. - */ - virtual bool syncAllowed() const; + bool syncAllowed() const override; protected: - /** - * Initialize the state of this widget. - */ - virtual void initView(); - virtual void initConnections(); - virtual void initToolbars(); + void initView() override; + void initConnections() override; + void initToolbars() override; - virtual WriteWindowType writeWindowType() const { + WriteWindowType writeWindowType() const override { return HTMLWindow; } - /** - * Called to add actions to mainWindow toolbars - */ - virtual void setupMainWindowToolBars(); + + void setupMainWindowToolBars() override; protected slots: - /** - * Is called when the current text was changed. - */ - virtual void textChanged(); - /** - * Loads the original text from the module. - */ - virtual void restoreText(); - /** - * Saves the text for the current key. Directly writes the changed text into the module. - */ - virtual void saveCurrentText( const QString& ); + + void textChanged() override; + void restoreText() override; + void saveCurrentText(QString const &) override; }; diff --git a/src/frontend/displaywindow/clexiconreadwindow.cpp b/src/frontend/displaywindow/clexiconreadwindow.cpp index 3b76f38..495bddc 100644 --- a/src/frontend/displaywindow/clexiconreadwindow.cpp +++ b/src/frontend/displaywindow/clexiconreadwindow.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -10,15 +10,15 @@ #include "frontend/displaywindow/clexiconreadwindow.h" #include <QAction> -#include <QApplication> #include <QFile> #include <QFileDialog> #include <QMenu> #include <QDebug> -#include "bibletime.h" #include "backend/keys/cswordldkey.h" #include "backend/keys/cswordkey.h" +#include "bibletime.h" +#include "bibletimeapp.h" #include "frontend/cexportmanager.h" #include "frontend/display/bthtmlreaddisplay.h" #include "frontend/displaywindow/btactioncollection.h" @@ -28,6 +28,8 @@ #include "frontend/displaywindow/btmodulechooserbar.h" #include "frontend/keychooser/bthistory.h" #include "frontend/keychooser/ckeychooser.h" +#include "util/btassert.h" +#include "util/btconnect.h" #include "util/directory.h" #include "util/cresmgr.h" #include "util/tool.h" @@ -80,79 +82,56 @@ void CLexiconReadWindow::initActions() { CReadWindow::initActions(); CLexiconReadWindow::insertKeyboardActions(ac); - QAction *qaction = ac->action(CResMgr::displaywindows::general::backInHistory::actionName); - Q_ASSERT(qaction != 0); - m_actions.backInHistory = dynamic_cast<BtToolBarPopupAction*>(qaction); - Q_ASSERT(m_actions.backInHistory); + m_actions.backInHistory = + &ac->actionAs<BtToolBarPopupAction>( + CResMgr::displaywindows::general::backInHistory::actionName); addAction(m_actions.backInHistory); - qaction = ac->action(CResMgr::displaywindows::general::forwardInHistory::actionName); - Q_ASSERT(qaction != 0); - m_actions.forwardInHistory = dynamic_cast<BtToolBarPopupAction*>(qaction); - Q_ASSERT(m_actions.forwardInHistory); + m_actions.forwardInHistory = + &ac->actionAs<BtToolBarPopupAction>( + CResMgr::displaywindows::general::forwardInHistory::actionName); addAction(m_actions.forwardInHistory); - qaction = ac->action("nextEntry"); - Q_ASSERT(qaction != 0); - connect(qaction, SIGNAL(triggered()), - this, SLOT(nextEntry())); - addAction(qaction); - - qaction = ac->action("previousEntry"); - Q_ASSERT(qaction != 0); - connect(qaction, SIGNAL(triggered()), - this, SLOT(previousEntry())); - addAction(qaction); - - m_actions.selectAll = ac->action("selectAll"); - Q_ASSERT(m_actions.selectAll != 0); - - m_actions.findText = ac->action("findText"); - Q_ASSERT(m_actions.findText != 0); - - m_actions.findStrongs = ac->action(CResMgr::displaywindows::general::findStrongs::actionName); - Q_ASSERT(m_actions.findStrongs != 0); - connect(m_actions.findStrongs, SIGNAL(triggered()), - this, SLOT(openSearchStrongsDialog()) ); - addAction(m_actions.findStrongs); - - m_actions.copy.reference = ac->action("copyReferenceOnly"); - Q_ASSERT(m_actions.copy.reference != 0); - connect(m_actions.copy.reference, SIGNAL(triggered()), - displayWidget()->connectionsProxy(), SLOT(copyAnchorOnly())); - addAction(m_actions.copy.reference); - - m_actions.copy.entry = ac->action("copyEntryWithText"); - Q_ASSERT(m_actions.copy.entry != 0); - connect(m_actions.copy.entry, SIGNAL(triggered()), - displayWidget()->connectionsProxy(), SLOT(copyAll())); - addAction(m_actions.copy.entry); - - m_actions.copy.selectedText = ac->action("copySelectedText"); - Q_ASSERT(m_actions.copy.selectedText != 0); - - m_actions.save.entryAsPlain = new QAction(tr("Entry as plain text"), ac ); - connect(m_actions.save.entryAsPlain, SIGNAL(triggered()), - this, SLOT(saveAsPlain())); - addAction(m_actions.save.entryAsPlain); - - m_actions.save.entryAsHTML = ac->action("saveHtml"); - Q_ASSERT(m_actions.save.entryAsHTML != 0); - connect(m_actions.save.entryAsHTML, SIGNAL(triggered()), - this, SLOT(saveAsHTML())); - addAction(m_actions.save.entryAsHTML); - - m_actions.print.reference = ac->action("printReferenceOnly"); - Q_ASSERT(m_actions.print.reference != 0); - connect(m_actions.print.reference, SIGNAL(triggered()), - this, SLOT(printAnchorWithText())); + initAction("nextEntry", this, &CLexiconReadWindow::nextEntry); + initAction("previousEntry", this, &CLexiconReadWindow::previousEntry); + + m_actions.selectAll = &ac->action("selectAll"); + m_actions.findText = &ac->action("findText"); + + m_actions.findStrongs = + &initAction( + CResMgr::displaywindows::general::findStrongs::actionName, + this, + &CLexiconReadWindow::openSearchStrongsDialog); + + m_actions.copy.reference = + &initAction("copyReferenceOnly", + displayWidget()->connectionsProxy(), + &CDisplayConnections::copyAnchorOnly); + + m_actions.copy.entry = &initAction("copyEntryWithText", + displayWidget()->connectionsProxy(), + &CDisplayConnections::copyAll); + + m_actions.copy.selectedText = &ac->action("copySelectedText"); + + m_actions.save.entryAsPlain = &initAction("saveEntryAsPlain", + this, + &CLexiconReadWindow::saveAsPlain); + + m_actions.save.entryAsHTML = &initAction("saveHtml", + this, + &CLexiconReadWindow::saveAsHTML); + + m_actions.print.reference = + &initAction("printReferenceOnly", + this, + &CLexiconReadWindow::printAnchorWithText); addAction(m_actions.print.reference); - m_actions.print.entry = ac->action("printEntryWithText"); - Q_ASSERT(m_actions.print.entry != 0); - connect(m_actions.print.entry, SIGNAL(triggered()), - this, SLOT(printAll())); - addAction(m_actions.print.entry); + m_actions.print.entry = &initAction("printEntryWithText", + this, + &CLexiconReadWindow::printAll); // init with the user defined settings ac->readShortcuts("Lexicon shortcuts"); @@ -160,32 +139,24 @@ void CLexiconReadWindow::initActions() { /** No descriptions */ void CLexiconReadWindow::initConnections() { - Q_ASSERT(keyChooser()); + BT_ASSERT(keyChooser()); - connect(keyChooser(), SIGNAL(keyChanged(CSwordKey*)), this, SLOT(lookupSwordKey(CSwordKey*))); - connect(history(), SIGNAL(historyChanged(bool, bool)), this, SLOT(slotUpdateHistoryButtons(bool, bool))); + BT_CONNECT(keyChooser(), SIGNAL(keyChanged(CSwordKey *)), + this, SLOT(lookupSwordKey(CSwordKey *))); + BT_CONNECT(history(), SIGNAL(historyChanged(bool, bool)), + this, SLOT(slotUpdateHistoryButtons(bool, bool))); //connect the history actions to the right slots - bool ok = connect( - m_actions.backInHistory->popupMenu(), SIGNAL(aboutToShow()), - this, SLOT(slotFillBackHistory()) - ); - Q_ASSERT(ok); - ok = connect( - m_actions.backInHistory->popupMenu(), SIGNAL(triggered(QAction*)), - keyChooser()->history(), SLOT(move(QAction*)) - ); - Q_ASSERT(ok); - ok = connect( - m_actions.forwardInHistory->popupMenu(), SIGNAL(aboutToShow()), - this, SLOT(slotFillForwardHistory()) - ); - Q_ASSERT(ok); - ok = connect( - m_actions.forwardInHistory->popupMenu(), SIGNAL(triggered(QAction*)), - keyChooser()->history(), SLOT(move(QAction*)) - ); - Q_ASSERT(ok); + BT_CONNECT(m_actions.backInHistory->popupMenu(), SIGNAL(aboutToShow()), + this, SLOT(slotFillBackHistory())); + BT_CONNECT(m_actions.backInHistory->popupMenu(), + SIGNAL(triggered(QAction *)), + keyChooser()->history(), SLOT(move(QAction *))); + BT_CONNECT(m_actions.forwardInHistory->popupMenu(), SIGNAL(aboutToShow()), + this, SLOT(slotFillForwardHistory())); + BT_CONNECT(m_actions.forwardInHistory->popupMenu(), + SIGNAL(triggered(QAction *)), + keyChooser()->history(), SLOT(move(QAction *))); } @@ -219,15 +190,15 @@ void CLexiconReadWindow::initView() { void CLexiconReadWindow::initToolbars() { //Navigation toolbar - Q_ASSERT(m_actions.backInHistory); + BT_ASSERT(m_actions.backInHistory); mainToolBar()->addWidget(keyChooser()); mainToolBar()->addAction(m_actions.backInHistory); //1st button mainToolBar()->addAction(m_actions.forwardInHistory); //2nd button //Tools toolbar - QAction *action = actionCollection()->action(CResMgr::displaywindows::general::search::actionName); - Q_ASSERT(action != 0); - buttonsToolBar()->addAction(action); + buttonsToolBar()->addAction( + &actionCollection()->action( + CResMgr::displaywindows::general::search::actionName)); BtDisplaySettingsButton* button = new BtDisplaySettingsButton(buttonsToolBar()); setDisplaySettingsButton(button); @@ -242,10 +213,10 @@ void CLexiconReadWindow::setupMainWindowToolBars() { // Navigation toolbar CKeyChooser* keyChooser = CKeyChooser::createInstance(modules(), history(), key(), btMainWindow()->navToolBar() ); btMainWindow()->navToolBar()->addWidget(keyChooser); - bool ok = connect(keyChooser, SIGNAL(keyChanged(CSwordKey*)), this, SLOT(lookupSwordKey(CSwordKey*))); - Q_ASSERT(ok); - ok = connect(this, SIGNAL(sigKeyChanged(CSwordKey*)), keyChooser, SLOT(updateKey(CSwordKey*)) ); - Q_ASSERT(ok); + BT_CONNECT(keyChooser, SIGNAL(keyChanged(CSwordKey *)), + this, SLOT(lookupSwordKey(CSwordKey *))); + BT_CONNECT(this, SIGNAL(sigKeyChanged(CSwordKey *)), + keyChooser, SLOT(updateKey(CSwordKey *))); btMainWindow()->navToolBar()->addAction(m_actions.backInHistory); //1st button btMainWindow()->navToolBar()->addAction(m_actions.forwardInHistory); //2nd button @@ -253,9 +224,9 @@ void CLexiconReadWindow::setupMainWindowToolBars() { btMainWindow()->worksToolBar()->setModules(getModuleList(), modules().first()->type(), this); // Tools toolbar - QAction *action = actionCollection()->action(CResMgr::displaywindows::general::search::actionName); - Q_ASSERT(action != 0); - btMainWindow()->toolsToolBar()->addAction(action); + btMainWindow()->toolsToolBar()->addAction( + &actionCollection()->action( + CResMgr::displaywindows::general::search::actionName)); BtDisplaySettingsButton* button = new BtDisplaySettingsButton(buttonsToolBar()); setDisplaySettingsButton(button); btMainWindow()->toolsToolBar()->addWidget(button); @@ -285,9 +256,9 @@ void CLexiconReadWindow::setupPopupMenu() { m_actions.saveMenu->addAction(m_actions.save.entryAsHTML); // Save raw HTML action for debugging purposes - if (qApp->property("--debug").toBool()) { + if (btApp->debugMode()) { QAction* debugAction = new QAction("Raw HTML", this); - QObject::connect(debugAction, SIGNAL(triggered()), this, SLOT(saveRawHTML())); + BT_CONNECT(debugAction, SIGNAL(triggered()), this, SLOT(saveRawHTML())); m_actions.saveMenu->addAction(debugAction); } // end of Save Raw HTML @@ -306,12 +277,16 @@ void CLexiconReadWindow::setupPopupMenu() { void CLexiconReadWindow::updatePopupMenu() { //enable the action depending on the supported module features - m_actions.findStrongs->setEnabled(!displayWidget()->getCurrentNodeInfo().isNull()); + CReadDisplay const & display = + *static_cast<CReadDisplay *>(displayWidget()); + + m_actions.findStrongs->setEnabled(!display.getCurrentNodeInfo().isNull()); - m_actions.copy.reference->setEnabled( ((CReadDisplay*)displayWidget())->hasActiveAnchor() ); - m_actions.copy.selectedText->setEnabled( displayWidget()->hasSelection() ); + bool const hasActiveAnchor = display.hasActiveAnchor(); + m_actions.copy.reference->setEnabled(hasActiveAnchor); + m_actions.copy.selectedText->setEnabled(display.hasSelection()); - m_actions.print.reference->setEnabled( ((CReadDisplay*)displayWidget())->hasActiveAnchor() ); + m_actions.print.reference->setEnabled(hasActiveAnchor); } void CLexiconReadWindow::reload(CSwordBackend::SetupChangedReason reason) { @@ -388,8 +363,8 @@ void CLexiconReadWindow::slotFillForwardHistory() { void CLexiconReadWindow::slotUpdateHistoryButtons(bool backEnabled, bool fwEnabled) { - Q_ASSERT(m_actions.backInHistory); - Q_ASSERT(keyChooser()); + BT_ASSERT(m_actions.backInHistory); + BT_ASSERT(keyChooser()); m_actions.backInHistory->setEnabled( backEnabled ); m_actions.forwardInHistory->setEnabled( fwEnabled ); diff --git a/src/frontend/displaywindow/clexiconreadwindow.h b/src/frontend/displaywindow/clexiconreadwindow.h index 6233545..6e939bb 100644 --- a/src/frontend/displaywindow/clexiconreadwindow.h +++ b/src/frontend/displaywindow/clexiconreadwindow.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -36,27 +36,38 @@ class CLexiconReadWindow : public CReadWindow { Q_OBJECT public: CLexiconReadWindow(const QList<CSwordModuleInfo *> & modules, CMDIArea * parent); - virtual ~CLexiconReadWindow(); + ~CLexiconReadWindow() override; + + CSwordModuleInfo::ModuleType moduleType() const override + { return CSwordModuleInfo::Lexicon; } /** Insert the keyboard accelerators of this window into the given actioncollection.*/ static void insertKeyboardActions( BtActionCollection* const a ); public slots: - /** - * Refreshes the content of this display window and the content of the keychooser. - */ - virtual void reload(CSwordBackend::SetupChangedReason reason); + void reload(CSwordBackend::SetupChangedReason reason) override; protected: - virtual void initActions(); - virtual void initToolbars(); - virtual void initConnections(); - virtual void initView(); - virtual void updatePopupMenu(); - virtual void setupPopupMenu(); - - /** Called to add actions to mainWindow toolbars */ - virtual void setupMainWindowToolBars(); + + template <typename ... Args> + QAction & initAction(QString actionName, Args && ... args) { + QAction & action = + actionCollection()->action(std::move(actionName)); + BT_CONNECT(&action, + &QAction::triggered, + std::forward<Args>(args)...); + addAction(&action); + return action; + } + + void initActions() override; + void initToolbars() override; + void initConnections() override; + void initView() override; + void updatePopupMenu() override; + void setupPopupMenu() override; + + void setupMainWindowToolBars() override; struct ActionsStruct { BtToolBarPopupAction* backInHistory; diff --git a/src/frontend/displaywindow/cplainwritewindow.cpp b/src/frontend/displaywindow/cplainwritewindow.cpp index f4b2d0b..b51339e 100644 --- a/src/frontend/displaywindow/cplainwritewindow.cpp +++ b/src/frontend/displaywindow/cplainwritewindow.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -21,20 +21,20 @@ #include "frontend/displaywindow/btmodulechooserbar.h" #include "frontend/keychooser/ckeychooser.h" #include "frontend/messagedialog.h" -#include "util/btsignal.h" +#include "util/btassert.h" +#include "util/btconnect.h" #include "util/cresmgr.h" -#include "util/geticon.h" CPlainWriteWindow::CPlainWriteWindow(const QList<CSwordModuleInfo*> & moduleList, CMDIArea * parent) : CDisplayWindow(moduleList, parent) - , m_writeDisplay(0) + , m_writeDisplay(nullptr) { setKey( CSwordKey::createInstance(moduleList.first()) ); } void CPlainWriteWindow::setDisplayWidget(CDisplay * display) { - Q_ASSERT(dynamic_cast<CPlainWriteDisplay *>(display)); + BT_ASSERT(dynamic_cast<CPlainWriteDisplay *>(display)); CDisplayWindow::setDisplayWidget(static_cast<CPlainWriteDisplay *>(display)); m_writeDisplay = static_cast<CPlainWriteDisplay *>(display); } @@ -80,67 +80,68 @@ void CPlainWriteWindow::initToolbars() { mainToolBar()->addWidget(keyChooser()); // Tools toolbar - QAction* action = actionCollection()->action(CResMgr::displaywindows::commentaryWindow::syncWindow::actionName); - Q_ASSERT(action != 0); - buttonsToolBar()->addAction(action); - action = actionCollection()->action(CResMgr::displaywindows::writeWindow::saveText::actionName); - Q_ASSERT(action != 0); - buttonsToolBar()->addAction(action); - action = actionCollection()->action(CResMgr::displaywindows::writeWindow::deleteEntry::actionName); - Q_ASSERT(action != 0); - buttonsToolBar()->addAction(action); - action = actionCollection()->action(CResMgr::displaywindows::writeWindow::restoreText::actionName); - Q_ASSERT(action != 0); - buttonsToolBar()->addAction(action); + auto const initAction = [this](QString const & actionName) { + buttonsToolBar()->addAction(&actionCollection()->action(actionName)); + }; + using namespace CResMgr::displaywindows; + initAction(commentaryWindow::syncWindow::actionName); + initAction(writeWindow::saveText::actionName); + initAction(writeWindow::deleteEntry::actionName); + initAction(writeWindow::restoreText::actionName); } void CPlainWriteWindow::setupMainWindowToolBars() { // Navigation toolbar CKeyChooser* keyChooser = CKeyChooser::createInstance(modules(), history(), key(), btMainWindow()->navToolBar() ); btMainWindow()->navToolBar()->addWidget(keyChooser); - bool ok = connect(keyChooser, SIGNAL(keyChanged(CSwordKey*)), this, SLOT(lookupSwordKey(CSwordKey*))); - Q_ASSERT(ok); + BT_CONNECT(keyChooser, SIGNAL(keyChanged(CSwordKey *)), + this, SLOT(lookupSwordKey(CSwordKey *))); // Tools toolbar - QAction* action = actionCollection()->action(CResMgr::displaywindows::commentaryWindow::syncWindow::actionName); - Q_ASSERT(action != 0); - btMainWindow()->toolsToolBar()->addAction(action); - action = actionCollection()->action(CResMgr::displaywindows::writeWindow::saveText::actionName); - Q_ASSERT(action != 0); - btMainWindow()->toolsToolBar()->addAction(action); - action = actionCollection()->action(CResMgr::displaywindows::writeWindow::deleteEntry::actionName); - Q_ASSERT(action != 0); - btMainWindow()->toolsToolBar()->addAction(action); - action = actionCollection()->action(CResMgr::displaywindows::writeWindow::restoreText::actionName); - Q_ASSERT(action != 0); - btMainWindow()->toolsToolBar()->addAction(action); + QToolBar & toolsToolbar = *btMainWindow()->toolsToolBar(); + auto const initAction = [this, &toolsToolbar](QString const & actionName) { + toolsToolbar.addAction(&actionCollection()->action(actionName)); + }; + using namespace CResMgr::displaywindows; + initAction(commentaryWindow::syncWindow::actionName); + initAction(writeWindow::saveText::actionName); + initAction(writeWindow::deleteEntry::actionName); + initAction(writeWindow::restoreText::actionName); } void CPlainWriteWindow::initConnections() { - Q_ASSERT(keyChooser()); - QObject::connect(key()->beforeChangedSignaller(), SIGNAL(signal()), this, SLOT(beforeKeyChange())); - QObject::connect(keyChooser(), SIGNAL(keyChanged(CSwordKey*)), this, SLOT(lookupSwordKey(CSwordKey*))); - QObject::connect(displayWidget()->connectionsProxy(), SIGNAL(textChanged()), this, SLOT(textChanged()) ); + BT_ASSERT(keyChooser()); + BT_CONNECT(key()->beforeChangedSignaller(), SIGNAL(signal()), + this, SLOT(beforeKeyChange())); + BT_CONNECT(keyChooser(), SIGNAL(keyChanged(CSwordKey *)), + this, SLOT(lookupSwordKey(CSwordKey *))); + BT_CONNECT(displayWidget()->connectionsProxy(), SIGNAL(textChanged()), + this, SLOT(textChanged())); } -void CPlainWriteWindow::storeProfileSettings(const QString & windowGroup) { +void CPlainWriteWindow::storeProfileSettings(QString const & windowGroup) const { CDisplayWindow::storeProfileSettings(windowGroup); - QAction * action = actionCollection()->action(CResMgr::displaywindows::commentaryWindow::syncWindow::actionName); - Q_ASSERT(action); - Q_ASSERT(windowGroup.endsWith('/')); + BT_ASSERT(windowGroup.endsWith('/')); btConfig().setSessionValue(windowGroup + "writeWindowType", static_cast<int>(writeWindowType())); - btConfig().setSessionValue(windowGroup + "syncWindowEnabled", action->isChecked()); + using namespace CResMgr::displaywindows; + btConfig().setSessionValue( + windowGroup + "syncWindowEnabled", + actionCollection()->action( + commentaryWindow::syncWindow::actionName).isChecked()); } void CPlainWriteWindow::applyProfileSettings(const QString & windowGroup) { CDisplayWindow::applyProfileSettings(windowGroup); - QAction * action = actionCollection()->action(CResMgr::displaywindows::commentaryWindow::syncWindow::actionName); - Q_ASSERT(action != 0); - Q_ASSERT(windowGroup.endsWith('/')); - action->setChecked(btConfig().sessionValue<bool>(windowGroup + "syncWindowEnabled", false)); + BT_ASSERT(windowGroup.endsWith('/')); + using namespace CResMgr::displaywindows; + actionCollection()->action(commentaryWindow::syncWindow::actionName) + .setChecked( + btConfig().sessionValue<bool>( + windowGroup + "syncWindowEnabled", + false)); } /** Saves the text for the current key. Directly writes the changed text into the module. */ @@ -177,12 +178,12 @@ void CPlainWriteWindow::restoreText() { /** Is called when the current text was changed. */ void CPlainWriteWindow::textChanged() { - QAction* action = actionCollection()->action(CResMgr::displaywindows::writeWindow::saveText::actionName); - Q_ASSERT(action != 0); - action->setEnabled(m_writeDisplay->isModified()); - action = actionCollection()->action(CResMgr::displaywindows::writeWindow::restoreText::actionName); - Q_ASSERT(action != 0); - action->setEnabled(m_writeDisplay->isModified()); + namespace WW = CResMgr::displaywindows::writeWindow; + auto const & ac = *actionCollection(); + ac.action(WW::saveText::actionName) + .setEnabled(m_writeDisplay->isModified()); + ac.action(WW::restoreText::actionName) + .setEnabled(m_writeDisplay->isModified()); } /** Deletes the module entry and clears the edit widget, */ @@ -196,42 +197,35 @@ void CPlainWriteWindow::deleteEntry() { void CPlainWriteWindow::setupPopupMenu() {} bool CPlainWriteWindow::syncAllowed() const { - QAction* action = actionCollection()->action(CResMgr::displaywindows::commentaryWindow::syncWindow::actionName); - Q_ASSERT(action != 0); - return action->isChecked(); + return actionCollection()->action( + CResMgr::displaywindows::commentaryWindow::syncWindow::actionName) + .isChecked(); } void CPlainWriteWindow::initActions() { insertKeyboardActions(actionCollection()); - QAction* action = actionCollection()->action(CResMgr::displaywindows::commentaryWindow::syncWindow::actionName); - Q_ASSERT(action != 0); - bool ok = QObject::connect(action, SIGNAL(triggered()), - this, SLOT(saveCurrentText())); - Q_ASSERT(ok); - - action = actionCollection()->action(CResMgr::displaywindows::writeWindow::saveText::actionName); - Q_ASSERT(action != 0); - ok = QObject::connect(action, SIGNAL(triggered()), - this, SLOT(saveCurrentText())); - Q_ASSERT(ok); - - action = actionCollection()->action(CResMgr::displaywindows::writeWindow::deleteEntry::actionName); - Q_ASSERT(action != 0); - ok = QObject::connect(action, SIGNAL(triggered()), - this, SLOT(deleteEntry())); - Q_ASSERT(ok); - - action = actionCollection()->action(CResMgr::displaywindows::writeWindow::restoreText::actionName); - Q_ASSERT(action != 0); - ok = QObject::connect(action, SIGNAL(triggered()), - this, SLOT(restoreText())); - Q_ASSERT(ok); + auto const initAction = [this](QString const & actionName, + void (CPlainWriteWindow:: *slot)()) + { + BT_CONNECT(&actionCollection()->action(actionName), + &QAction::triggered, + this, slot); + }; + namespace DW = CResMgr::displaywindows; + initAction(DW::commentaryWindow::syncWindow::actionName, + &CPlainWriteWindow::saveCurrentText); + initAction(DW::writeWindow::saveText::actionName, + &CPlainWriteWindow::saveCurrentText); + initAction(DW::writeWindow::deleteEntry::actionName, + &CPlainWriteWindow::deleteEntry); + initAction(DW::writeWindow::restoreText::actionName, + &CPlainWriteWindow::restoreText); } void CPlainWriteWindow::insertKeyboardActions( BtActionCollection* const a) { QAction* action = new QAction( - util::getIcon(CResMgr::displaywindows::commentaryWindow::syncWindow::icon), + CResMgr::displaywindows::commentaryWindow::syncWindow::icon(), tr("Sync with active Bible"), a ); @@ -241,7 +235,7 @@ void CPlainWriteWindow::insertKeyboardActions( BtActionCollection* const a) { a->addAction(CResMgr::displaywindows::commentaryWindow::syncWindow::actionName, action); action = new QAction( - util::getIcon(CResMgr::displaywindows::writeWindow::saveText::icon), + CResMgr::displaywindows::writeWindow::saveText::icon(), tr("Save text"), a ); @@ -250,7 +244,7 @@ void CPlainWriteWindow::insertKeyboardActions( BtActionCollection* const a) { a->addAction(CResMgr::displaywindows::writeWindow::saveText::actionName, action); action = new QAction( - util::getIcon(CResMgr::displaywindows::writeWindow::deleteEntry::icon), + CResMgr::displaywindows::writeWindow::deleteEntry::icon(), tr("Delete current entry"), a ); @@ -259,7 +253,7 @@ void CPlainWriteWindow::insertKeyboardActions( BtActionCollection* const a) { a->addAction(CResMgr::displaywindows::writeWindow::deleteEntry::actionName, action); action = new QAction( - util::getIcon(CResMgr::displaywindows::writeWindow::restoreText::icon), + CResMgr::displaywindows::writeWindow::restoreText::icon(), tr("Restore original text"), a ); @@ -292,15 +286,15 @@ bool CPlainWriteWindow::queryClose() { } void CPlainWriteWindow::beforeKeyChange() { - Q_ASSERT(displayWidget()); - Q_ASSERT(keyChooser()); + BT_ASSERT(displayWidget()); + BT_ASSERT(keyChooser()); if (!isReady()) return; // Get current key string for this window QString thisWindowsKey; CSwordKey* oldKey = key(); - if (oldKey == 0) + if (oldKey == nullptr) return; thisWindowsKey = oldKey->key(); diff --git a/src/frontend/displaywindow/cplainwritewindow.h b/src/frontend/displaywindow/cplainwritewindow.h index cf11a46..31cd4c0 100644 --- a/src/frontend/displaywindow/cplainwritewindow.h +++ b/src/frontend/displaywindow/cplainwritewindow.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -38,54 +38,37 @@ class CPlainWriteWindow : public CDisplayWindow { CPlainWriteWindow(const QList<CSwordModuleInfo *> & modules, CMDIArea * parent); /** - * Set the displayWidget which is a subclass of QWebPage. + * Set the displayWidget which is a subclass of BtWebEnginePage. */ - void setDisplayWidget( CDisplay* display ); + void setDisplayWidget( CDisplay* display ) override; - virtual void storeProfileSettings(const QString & windowGroup); - virtual void applyProfileSettings(const QString & windowGroup); + void storeProfileSettings(QString const & windowGroup) const override; + void applyProfileSettings(const QString & windowGroup) override; - /** - * Setups the popup menu of this display widget. - */ - virtual void setupPopupMenu(); + void setupPopupMenu() override; - /** - * Returns true if the sync toolbar is enabled. - */ - virtual bool syncAllowed() const; + bool syncAllowed() const override; public slots: - /** - Look up the given key and display the text. In our case we offer to edit the text. - */ - virtual void lookupSwordKey(CSwordKey * key); + void lookupSwordKey(CSwordKey * key) override; protected: // Protected methods - /** - * Initialize the state of this widget. - */ - virtual void initView(); - virtual void initConnections(); - virtual void initToolbars(); + void initView() override; + void initConnections() override; + void initToolbars() override; virtual WriteWindowType writeWindowType() const { return PlainTextWindow; } - /** Called to add actions to mainWindow toolbars */ - virtual void setupMainWindowToolBars(); - /** - * Initializes the intern keyboard actions. - */ - virtual void initActions(); + void setupMainWindowToolBars() override; + void initActions() override; /** * Insert the keyboard accelerators of this window into the given KAccel object. */ static void insertKeyboardActions( BtActionCollection* const a ); - /** \returns whether the window may be closed.*/ - virtual bool queryClose(); + bool queryClose() override; protected slots: // Protected slots diff --git a/src/frontend/displaywindow/creadwindow.cpp b/src/frontend/displaywindow/creadwindow.cpp index 0d8f2d9..dd6f418 100644 --- a/src/frontend/displaywindow/creadwindow.cpp +++ b/src/frontend/displaywindow/creadwindow.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -20,115 +20,98 @@ #include "frontend/display/bthtmlreaddisplay.h" #include "frontend/displaywindow/btactioncollection.h" #include "frontend/searchdialog/csearchdialog.h" +#include "util/btassert.h" +#include "util/btconnect.h" -CReadWindow::CReadWindow(QList<CSwordModuleInfo*> modules, CMDIArea* parent) - : CDisplayWindow(modules, parent), - m_readDisplayWidget(0) { - // installEventFilter(this); -} +CReadWindow::CReadWindow(QList<CSwordModuleInfo *> modules, CMDIArea * parent) + : CDisplayWindow(modules, parent) + , m_readDisplayWidget(nullptr) +{} -/** Sets the display widget of this display window. */ -void CReadWindow::setDisplayWidget( CDisplay* newDisplay ) { +void CReadWindow::setDisplayWidget(CDisplay * newDisplay) { // Lets be orwellianly paranoid here: - Q_ASSERT(dynamic_cast<CReadDisplay*>(newDisplay) != 0); + BT_ASSERT(dynamic_cast<CReadDisplay *>(newDisplay)); CDisplayWindow::setDisplayWidget(newDisplay); if (m_readDisplayWidget) { - disconnect(m_readDisplayWidget->connectionsProxy(), SIGNAL(referenceClicked(const QString&, const QString&)), - this, SLOT(lookupModKey(const QString&, const QString&))); - disconnect(m_readDisplayWidget->connectionsProxy(), SIGNAL(referenceDropped(const QString&)), - this, SLOT(lookupKey(const QString&))); + disconnect(m_readDisplayWidget->connectionsProxy(), + SIGNAL(referenceClicked(QString const &, QString const &)), + this, + SLOT(lookupModKey(QString const &, QString const &))); + disconnect(m_readDisplayWidget->connectionsProxy(), + SIGNAL(referenceDropped(QString const &)), + this, + SLOT(lookupKey(QString const &))); + + if (BtHtmlReadDisplay * const v = + dynamic_cast<BtHtmlReadDisplay *>(m_readDisplayWidget)) + QObject::disconnect(v, SIGNAL(completed()), + this, SLOT(slotMoveToAnchor())); + } - BtHtmlReadDisplay* v = dynamic_cast<BtHtmlReadDisplay*>(m_readDisplayWidget); - if (v) { - QObject::disconnect(v, SIGNAL(completed()), this, SLOT(slotMoveToAnchor()) ); - } + m_readDisplayWidget = static_cast<CReadDisplay *>(newDisplay); + BT_CONNECT(m_readDisplayWidget->connectionsProxy(), + SIGNAL(referenceClicked(QString const &, QString const &)), + this, + SLOT(lookupModKey(QString const &, QString const &))); - } + BT_CONNECT(m_readDisplayWidget->connectionsProxy(), + SIGNAL(referenceDropped(QString const &)), + this, + SLOT(lookupKey(QString const &))); - m_readDisplayWidget = static_cast<CReadDisplay*>(newDisplay); - connect( - m_readDisplayWidget->connectionsProxy(), - SIGNAL(referenceClicked(const QString&, const QString&)), - this, - SLOT(lookupModKey(const QString&, const QString&)) - ); - - connect( - m_readDisplayWidget->connectionsProxy(), - SIGNAL(referenceDropped(const QString&)), - this, - SLOT(lookupKey(const QString&)) - ); - BtHtmlReadDisplay* v = dynamic_cast<BtHtmlReadDisplay*>(m_readDisplayWidget); - if (v) { - QObject::connect(v, SIGNAL(completed()), this, SLOT(slotMoveToAnchor()) ); - } + if (BtHtmlReadDisplay * const v = + dynamic_cast<BtHtmlReadDisplay *>(m_readDisplayWidget)) + BT_CONNECT(v, SIGNAL(completed()), this, SLOT(slotMoveToAnchor())); } -/** Lookup the given entry. */ -void CReadWindow::lookupSwordKey( CSwordKey* newKey ) { - Q_ASSERT(newKey); +void CReadWindow::lookupSwordKey(CSwordKey * newKey) { + BT_ASSERT(newKey); - using namespace Rendering; - -// Q_ASSERT(isReady() && newKey && modules().first()); - if (!isReady() || !newKey || modules().empty() || !modules().first()) { + if (!isReady() || !newKey || modules().empty() || !modules().first()) return; - } - if (key() != newKey) { + if (key() != newKey) key()->setKey(newKey->key()); - } /// \todo next-TODO how about options? - Q_ASSERT(modules().first()->getDisplay()); - CEntryDisplay* display = modules().first()->getDisplay(); - if (display) { //do we have a display object? - displayWidget()->setText( - display->text( - modules(), - newKey->key(), - displayOptions(), - filterOptions() - ) - ); - } + Rendering::CEntryDisplay * const display = modules().first()->getDisplay(); + BT_ASSERT(display); + displayWidget()->setText(display->text(modules(), + newKey->key(), + displayOptions(), + filterOptions())); setWindowTitle(windowCaption()); - - // moving to anchor happens in slotMoveToAnchor which catches the completed() signal from KHTMLPart + /* Moving to anchor happens in slotMoveToAnchor which catches the + completed() signal from KHTMLPart. */ } void CReadWindow::slotMoveToAnchor() { - ((CReadDisplay*)displayWidget())->moveToAnchor( Rendering::CDisplayRendering::keyToHTMLAnchor(key()->key()) ); + static_cast<CReadDisplay *>(displayWidget())->moveToAnchor( + Rendering::CDisplayRendering::keyToHTMLAnchor(key()->key())); } -void CReadWindow::insertKeyboardActions( BtActionCollection* const ) {} - -/** No descriptions */ -void CReadWindow::copyDisplayedText() { - CExportManager().copyKey(key(), CExportManager::Text, true); -} +void CReadWindow::insertKeyboardActions(BtActionCollection * const) +{} +void CReadWindow::copyDisplayedText() +{ CExportManager().copyKey(key(), CExportManager::Text, true); } -/*! - \fn CReadWindow::resizeEvent(QResizeEvent* e) - */ -void CReadWindow::resizeEvent(QResizeEvent* /*e*/) { - if (displayWidget()) { - ((CReadDisplay*)displayWidget())->moveToAnchor(Rendering::CDisplayRendering::keyToHTMLAnchor(key()->key())); - } +void CReadWindow::resizeEvent(QResizeEvent * e) { + Q_UNUSED(e) + if (displayWidget()) + static_cast<CReadDisplay *>(displayWidget())->moveToAnchor( + Rendering::CDisplayRendering::keyToHTMLAnchor(key()->key())); } void CReadWindow::openSearchStrongsDialog() { QString searchText; - Q_FOREACH (const QString &strongNumber, - displayWidget()->getCurrentNodeInfo().split('|', QString::SkipEmptyParts)) - { + Q_FOREACH(QString const & strongNumber, + displayWidget()->getCurrentNodeInfo().split( + '|', + QString::SkipEmptyParts)) searchText.append("strong:").append(strongNumber).append(' '); - } - - Search::CSearchDialog::openDialog( modules(), searchText, 0 ); + Search::CSearchDialog::openDialog(modules(), searchText, nullptr); } diff --git a/src/frontend/displaywindow/creadwindow.h b/src/frontend/displaywindow/creadwindow.h index 2446e1e..48c0fe1 100644 --- a/src/frontend/displaywindow/creadwindow.h +++ b/src/frontend/displaywindow/creadwindow.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -21,52 +21,49 @@ class BtActionCollection; class QResizeEvent; -/** - \brief The base class for all read-only display windows. -*/ +/** \brief The base class for all read-only display windows. */ class CReadWindow: public CDisplayWindow { - Q_OBJECT - public: - - /** Insert the keyboard accelerators of this window into the given actioncollection.*/ - static void insertKeyboardActions( BtActionCollection* const a ); - - CReadWindow(QList<CSwordModuleInfo*> modules, CMDIArea* parent); - - protected: - /** - * Sets the display widget of this display window. - */ - virtual void setDisplayWidget( CDisplay* newDisplay ); - /** - * Reimplemented Qt function for resize of window. - */ - virtual void resizeEvent(QResizeEvent* e); - - /** Called to add actions to mainWindow toolbars.*/ - virtual void setupMainWindowToolBars() = 0; - - protected slots: - /** - * Load the text using the key - */ - virtual void lookupSwordKey( CSwordKey* ); - /** - * Catch the signal when the KHTMLPart has finished the layout (anchors are not ready before that). - */ - virtual void slotMoveToAnchor(); - - /** - * Update the status of the popup menu entries. - */ - virtual void copyDisplayedText(); - /** - * Open the search dialog with the strong info of the last clicked word. - */ - void openSearchStrongsDialog(); - - private: - CReadDisplay* m_readDisplayWidget; + + Q_OBJECT + +public: /* Methods: */ + + CReadWindow(QList<CSwordModuleInfo *> modules, CMDIArea * parent); + + /** + Inserts the keyboard accelerators of this window into the given + collection. + */ + static void insertKeyboardActions(BtActionCollection * const a); + + virtual CSwordModuleInfo::ModuleType moduleType() const = 0; + +protected: /* Methods: */ + + void setDisplayWidget(CDisplay * newDisplay) override; + + void resizeEvent(QResizeEvent * e) override; + +protected slots: + + void lookupSwordKey(CSwordKey *) override; + + /** + Catches the signal when the KHTMLPart has finished the layout (anchors are + not ready before that). + */ + virtual void slotMoveToAnchor(); + + /** Updates the status of the popup menu entries. */ + virtual void copyDisplayedText(); + + /** Opens the search dialog with the strong info of the last clicked word.*/ + void openSearchStrongsDialog(); + +private: /* Fields: */ + + CReadDisplay * m_readDisplayWidget; + }; -#endif +#endif /* CREADWINDOW_H */ diff --git a/src/frontend/keychooser/bthistory.cpp b/src/frontend/keychooser/bthistory.cpp index 22c9e69..a4ffd4a 100644 --- a/src/frontend/keychooser/bthistory.cpp +++ b/src/frontend/keychooser/bthistory.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -12,57 +12,64 @@ #include <QAction> #include <QList> #include "backend/keys/cswordkey.h" +#include "util/btassert.h" +namespace { +char const ActionText[] = "BtHistory key"; +} + BTHistory::BTHistory(QWidget* parent) : m_historyList(), m_index(-1), m_inHistoryFunction(false) { setParent(parent); - Q_ASSERT(class_invariant()); + BT_ASSERT(class_invariant()); } void BTHistory::add(CSwordKey* newKey) { - Q_ASSERT(newKey); + BT_ASSERT(newKey); // Add new key Action after current index if we were not using the history functions, // if it's not a duplicate and if it's not empty. - if (!m_inHistoryFunction && ((m_index < 0) || (newKey->key() != m_historyList.at(m_index)->text()) )) { + if (!m_inHistoryFunction && ((m_index < 0) || (newKey->key() != m_historyList.at(m_index)->property(ActionText).toString()) )) { if (!newKey->key().isEmpty()) { - m_historyList.insert(++m_index, new QAction(newKey->key(), this)); + auto * const a = new QAction(newKey->key(), this); + a->setProperty(ActionText, newKey->key()); + m_historyList.insert(++m_index, a); } // \todo history limit? sendChangedSignal(); } - Q_ASSERT(class_invariant()); + BT_ASSERT(class_invariant()); } void BTHistory::move(QAction* historyItem) { - //Q_ASSERT(historyItem); - Q_ASSERT(m_historyList.count()); + //BT_ASSERT(historyItem); + BT_ASSERT(m_historyList.count()); m_inHistoryFunction = true; //find the action in the list m_index = m_historyList.indexOf(historyItem); //move to the selected item in the list, it will be the current item - emit historyMoved(m_historyList.at(m_index)->text()); // signal to "outsiders"; key has been changed + emit historyMoved(m_historyList.at(m_index)->property(ActionText).toString()); // signal to "outsiders"; key has been changed sendChangedSignal(); m_inHistoryFunction = false; - Q_ASSERT(class_invariant()); + BT_ASSERT(class_invariant()); } void BTHistory::back() { if ( m_index >= 1) { move(m_historyList.at(m_index - 1)); } - Q_ASSERT(class_invariant()); + BT_ASSERT(class_invariant()); } void BTHistory::fw() { if (m_index < (m_historyList.size() - 1)) { move(m_historyList.at(m_index + 1)); } - Q_ASSERT(class_invariant()); + BT_ASSERT(class_invariant()); } QList<QAction*> BTHistory::getBackList() { @@ -72,7 +79,7 @@ QList<QAction*> BTHistory::getBackList() { list.append(m_historyList.at(i)); } - Q_ASSERT(class_invariant()); + BT_ASSERT(class_invariant()); return list; } @@ -82,7 +89,7 @@ QList<QAction*> BTHistory::getFwList() { list.append(m_historyList.at(i)); } - Q_ASSERT(class_invariant()); + BT_ASSERT(class_invariant()); return list; } @@ -90,12 +97,12 @@ void BTHistory::sendChangedSignal() { bool backEnabled = m_index > 0; //there are items in the back list bool fwEnabled = m_historyList.size() > m_index + 1; //there are items in the fw list emit historyChanged(backEnabled, fwEnabled); - Q_ASSERT(class_invariant()); + BT_ASSERT(class_invariant()); } bool BTHistory::class_invariant() { for (int i = 0; i < m_historyList.size(); ++i) { - if (!m_historyList.at(i) || m_historyList.at(i)->text().isEmpty()) return false; + if (!m_historyList.at(i) || m_historyList.at(i)->property(ActionText).toString().isEmpty()) return false; } if (!(m_index >= -1 && m_index < m_historyList.size())) return false; return true; diff --git a/src/frontend/keychooser/bthistory.h b/src/frontend/keychooser/bthistory.h index 6c65aca..4141e28 100644 --- a/src/frontend/keychooser/bthistory.h +++ b/src/frontend/keychooser/bthistory.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ diff --git a/src/frontend/keychooser/cbookkeychooser.cpp b/src/frontend/keychooser/cbookkeychooser.cpp index 9255980..f8a46d4 100644 --- a/src/frontend/keychooser/cbookkeychooser.cpp +++ b/src/frontend/keychooser/cbookkeychooser.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -17,28 +17,30 @@ #include "backend/drivers/cswordbookmoduleinfo.h" #include "backend/keys/cswordtreekey.h" #include "frontend/keychooser/bthistory.h" +#include "util/btassert.h" +#include "util/btconnect.h" #define ID_PROPERTY_NAME "CBookKeyChooser_ID" -CBookKeyChooser::CBookKeyChooser(const QList<const CSwordModuleInfo *> & modules, +CBookKeyChooser::CBookKeyChooser(const BtConstModuleList & modules, BTHistory * historyPtr, CSwordKey * key, QWidget * parent) : CKeyChooser(modules, historyPtr, parent) - , m_layout(0) + , m_layout(nullptr) { setModules(modules, false); m_key = dynamic_cast<CSwordTreeKey * >(key); if (!m_modules.count()) - m_key = 0; + m_key = nullptr; setModules(modules, true); setKey(key); adjustFont(); - connect(this, SIGNAL(keyChanged(CSwordKey *)), - history(), SLOT(add(CSwordKey *))); + BT_CONNECT(this, SIGNAL(keyChanged(CSwordKey *)), + history(), SLOT(add(CSwordKey *))); } void CBookKeyChooser::setKey(CSwordKey * newKey) { @@ -119,17 +121,17 @@ CSwordKey * CBookKeyChooser::key() { } /** Sets another module to this keychooser */ -void CBookKeyChooser::setModules(const QList<const CSwordModuleInfo *> & modules, +void CBookKeyChooser::setModules(const BtConstModuleList & modules, bool refresh) { - typedef CSwordBookModuleInfo CSBMI; + using CSBMI = CSwordBookModuleInfo; m_modules.clear(); // for (modules.first(); modules.current(); modules.next()) { - Q_FOREACH(const CSwordModuleInfo * m, modules) { + Q_FOREACH(const CSwordModuleInfo * const m, modules) { if (m->type() == CSwordModuleInfo::GenericBook ) { const CSBMI * const book = dynamic_cast<const CSBMI *>(m); - if (book != 0) + if (book != nullptr) m_modules.append(book); } } @@ -161,13 +163,14 @@ void CBookKeyChooser::setModules(const QList<const CSwordModuleInfo *> & modules } } - int maxWidth = (int) ((float) totalWidth / (float) m_modules.first()->depth()); + int maxWidth = static_cast<int>(static_cast<float>(totalWidth) + / m_modules.first()->depth()); w->comboBox().setMaximumWidth(maxWidth); w->comboBox().setCurrentIndex(0); - connect(w, SIGNAL(changed(int)), SLOT(keyChooserChanged(int))); - connect(w, SIGNAL(focusOut(int)), SLOT(keyChooserChanged(int))); + BT_CONNECT(w, SIGNAL(changed(int)), SLOT(keyChooserChanged(int))); + BT_CONNECT(w, SIGNAL(focusOut(int)), SLOT(keyChooserChanged(int))); m_layout->addWidget(w); w->setProperty(ID_PROPERTY_NAME, i+1); @@ -176,18 +179,18 @@ void CBookKeyChooser::setModules(const QList<const CSwordModuleInfo *> & modules //set the tab order of the key chooser widgets - CKeyChooserWidget * chooser = 0; - CKeyChooserWidget * chooser_prev = 0; + CKeyChooserWidget * chooser = nullptr; + CKeyChooserWidget * chooser_prev = nullptr; const int count = m_chooserWidgets.count(); for (int i = 0; i < count; i++) { chooser = m_chooserWidgets.at(i); - Q_ASSERT(chooser); + BT_ASSERT(chooser); if (chooser_prev) QWidget::setTabOrder(chooser_prev, chooser); chooser_prev = chooser; } - QWidget::setTabOrder(chooser, 0); + QWidget::setTabOrder(chooser, nullptr); updateKey(m_key); adjustFont(); // only when refresh is set. @@ -240,7 +243,7 @@ void CBookKeyChooser::keyChooserChanged(int newIndex) { sender()->property(ID_PROPERTY_NAME).toInt()); for (int i = 0; i < max; i++) { CKeyChooserWidget * const chooser = m_chooserWidgets.at(i); - Q_ASSERT(chooser); + BT_ASSERT(chooser); const QString currentText = chooser->comboBox().currentText(); if (currentText.isEmpty()) break; diff --git a/src/frontend/keychooser/cbookkeychooser.h b/src/frontend/keychooser/cbookkeychooser.h index c01e0e9..67703aa 100644 --- a/src/frontend/keychooser/cbookkeychooser.h +++ b/src/frontend/keychooser/cbookkeychooser.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -31,30 +31,18 @@ class CBookKeyChooser: public CKeyChooser { public: - CBookKeyChooser(const QList<const CSwordModuleInfo *> & modules, + CBookKeyChooser(const BtConstModuleList & modules, BTHistory * history, - CSwordKey * key = 0, - QWidget * parent = 0); + CSwordKey * key = nullptr, + QWidget * parent = nullptr); - /** - Reimplemented from CKeyChooser. - */ - virtual void refreshContent(); + void refreshContent() override; - /** - * Sets another module to this keychooser - */ - virtual void setModules(const QList<const CSwordModuleInfo *> & modules, - bool refresh = false); - /** - * Returns the key of this keychooser - */ - virtual CSwordKey * key(); + void setModules(const BtConstModuleList & modules, + bool refresh = false) override; + CSwordKey * key() override; - /** - * Sets a new key to this keychooser - */ - virtual void setKey(CSwordKey * key); + void setKey(CSwordKey * key) override; /** * Sets a new key to this keychooser @@ -66,7 +54,7 @@ public slots: // Public slots /** * Updates the keychoosers for the given key but emit no signal. */ - void updateKey(CSwordKey * key); + void updateKey(CSwordKey * key) override; protected: /* Methods: */ @@ -76,8 +64,7 @@ protected: /* Methods: */ */ void setupCombo(const QString & key, const int depth, const int currentItem); - /** No descriptions */ - virtual void adjustFont(); + void adjustFont() override; protected slots: @@ -86,7 +73,7 @@ protected slots: */ void keyChooserChanged(int); - virtual void setKey(const QString & newKey); + void setKey(const QString & newKey) override; private: /* Fields: */ diff --git a/src/frontend/keychooser/cbooktreechooser.cpp b/src/frontend/keychooser/cbooktreechooser.cpp index 96917d8..e793a17 100644 --- a/src/frontend/keychooser/cbooktreechooser.cpp +++ b/src/frontend/keychooser/cbooktreechooser.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -17,9 +17,10 @@ #include "backend/drivers/cswordbookmoduleinfo.h" #include "backend/keys/cswordtreekey.h" #include "frontend/keychooser/bthistory.h" +#include "util/btconnect.h" -CBookTreeChooser::CBookTreeChooser(const QList<const CSwordModuleInfo *> & modules, +CBookTreeChooser::CBookTreeChooser(const BtConstModuleList & modules, BTHistory * historyPtr, CSwordKey * key, QWidget * parent) @@ -32,7 +33,7 @@ CBookTreeChooser::CBookTreeChooser(const QList<const CSwordModuleInfo *> & modul //if there is no module there is no key either if (!modules.count()) { m_modules.clear(); - m_key = 0; + m_key = nullptr; } //now setup the keychooser widgets @@ -45,11 +46,14 @@ CBookTreeChooser::CBookTreeChooser(const QList<const CSwordModuleInfo *> & modul m_treeView->setHeaderHidden(true); //when user selects the item whe must react - connect(m_treeView, SIGNAL(currentItemChanged ( QTreeWidgetItem*, QTreeWidgetItem*)), SLOT(itemActivated(QTreeWidgetItem*))); + BT_CONNECT(m_treeView, + SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)), + SLOT(itemActivated(QTreeWidgetItem *))); setKey(key); adjustFont(); - connect(this, SIGNAL(keyChanged(CSwordKey*)), history(), SLOT(add(CSwordKey*)) ); + BT_CONNECT(this, SIGNAL(keyChanged(CSwordKey *)), + history(), SLOT(add(CSwordKey *))); } /** Sets a new key to this keychooser. Inherited from ckeychooser. */ @@ -85,16 +89,16 @@ void CBookTreeChooser::setKey(CSwordKey* newKey, const bool emitSignal) { } } -void CBookTreeChooser::setModules(const QList<const CSwordModuleInfo*> &modules, +void CBookTreeChooser::setModules(const BtConstModuleList &modules, bool refresh) { - typedef CSwordBookModuleInfo CSBMI; + using CSBMI = CSwordBookModuleInfo; //Add given modules into private list m_modules.clear(); - Q_FOREACH (const CSwordModuleInfo *m, modules) { + Q_FOREACH(CSwordModuleInfo const * const m, modules) { const CSBMI *book = dynamic_cast<const CSBMI*>(m); - if (book != 0) { + if (book != nullptr) { m_modules.append(book); } } @@ -144,9 +148,8 @@ void CBookTreeChooser::updateKey( CSwordKey* key ) { } /** Reimplementation to handle tree creation on show. */ -void CBookTreeChooser::show() { - CKeyChooser::show(); - +void CBookTreeChooser::doShow() { + show(); if (!m_treeView->topLevelItemCount()) { QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); setupTree(); //create the tree structure diff --git a/src/frontend/keychooser/cbooktreechooser.h b/src/frontend/keychooser/cbooktreechooser.h index 17b5825..bebf5e3 100644 --- a/src/frontend/keychooser/cbooktreechooser.h +++ b/src/frontend/keychooser/cbooktreechooser.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -33,55 +33,40 @@ class BTHistory; class CBookTreeChooser : public CKeyChooser { Q_OBJECT public: - CBookTreeChooser(const QList<const CSwordModuleInfo*> &modules, - BTHistory *history, CSwordKey *key = 0, - QWidget *parent = 0); + CBookTreeChooser(const BtConstModuleList &modules, + BTHistory *history, CSwordKey *key = nullptr, + QWidget *parent = nullptr); - /** - Reimplemented from CKeyChooser::refreshContent(). - */ - virtual void refreshContent(); + void refreshContent() override; - /** - Reimplemented from CKeyChooser::setModules(). - */ - virtual void setModules(const QList<const CSwordModuleInfo*> &modules, - bool refresh = true); + void setModules(const BtConstModuleList &modules, + bool refresh = true) override; - /** - Reimplemented from CKeyChooser::key(). - */ - virtual inline CSwordKey *key() { + inline CSwordKey *key() override { return m_key; } - /** - Reimplemented from CKeyChooser::setKey(). - */ - virtual void setKey(CSwordKey *key); + void setKey(CSwordKey *key) override; void setKey(CSwordKey*, const bool emitSinal); public slots: // Public slots - virtual void updateKey( CSwordKey* ); - /** - * Reimplementation to handle tree creation on show. - */ - virtual void show(); + void updateKey( CSwordKey* ) override; + void doShow(); protected: // Protected methods /** * Creates the first level of the tree structure. */ void setupTree(); - virtual void adjustFont(); + void adjustFont() override; void addKeyChildren(CSwordTreeKey* key, QTreeWidgetItem* item); protected slots: // Protected slots void itemActivated( QTreeWidgetItem* item ); - void setKey(const QString & newKey); + void setKey(const QString & newKey) override; private: QList<const CSwordBookModuleInfo*> m_modules; diff --git a/src/frontend/keychooser/ckeychooser.cpp b/src/frontend/keychooser/ckeychooser.cpp index 96b5638..5cc229e 100644 --- a/src/frontend/keychooser/ckeychooser.cpp +++ b/src/frontend/keychooser/ckeychooser.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -19,26 +19,27 @@ #include "frontend/keychooser/cbookkeychooser.h" #include "frontend/keychooser/clexiconkeychooser.h" #include "frontend/keychooser/versekeychooser/cbiblekeychooser.h" +#include "util/btassert.h" +#include "util/btconnect.h" -CKeyChooser::CKeyChooser(const QList<const CSwordModuleInfo *> &, +CKeyChooser::CKeyChooser(const BtConstModuleList &, BTHistory * historyPtr, QWidget * parent) : QWidget(parent) , m_history(historyPtr) { - bool ok = QObject::connect(history(), SIGNAL(historyMoved(QString)), - this, SLOT(setKey(const QString &))); - Q_ASSERT(ok); + BT_CONNECT(history(), SIGNAL(historyMoved(QString)), + this, SLOT(setKey(QString const &))); } -CKeyChooser * CKeyChooser::createInstance(const QList<const CSwordModuleInfo *> & modules, +CKeyChooser * CKeyChooser::createInstance(const BtConstModuleList & modules, BTHistory * historyPtr, CSwordKey * key, QWidget * parent) { - Q_ASSERT(!modules.empty()); - Q_ASSERT(modules.first()->type() == CSwordModuleInfo::Commentary + BT_ASSERT(!modules.empty()); + BT_ASSERT(modules.first()->type() == CSwordModuleInfo::Commentary || modules.first()->type() == CSwordModuleInfo::Bible || modules.first()->type() == CSwordModuleInfo::Lexicon || modules.first()->type() == CSwordModuleInfo::GenericBook); diff --git a/src/frontend/keychooser/ckeychooser.h b/src/frontend/keychooser/ckeychooser.h index 79706cc..c18adbe 100644 --- a/src/frontend/keychooser/ckeychooser.h +++ b/src/frontend/keychooser/ckeychooser.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -14,10 +14,11 @@ #include <QWidget> +#include "backend/drivers/btmodulelist.h" + class BTHistory; class CSwordKey; -class CSwordModuleInfo; class QAction; /** @@ -45,7 +46,7 @@ public: /* Methods: */ * @param key if not NULL, the @ref CKey the KeyChooser should be set to * @param parent the parent of the widget to create */ - static CKeyChooser * createInstance(const QList<const CSwordModuleInfo *> & modules, + static CKeyChooser * createInstance(const BtConstModuleList & modules, BTHistory * history, CSwordKey * key, QWidget * parent); @@ -72,7 +73,7 @@ public slots: /** Sets the module of this keychooser and refreshes the comboboxes */ - virtual void setModules(const QList<const CSwordModuleInfo *> & modules, + virtual void setModules(const BtConstModuleList & modules, bool refresh = true) = 0; /** @@ -89,9 +90,9 @@ signals: protected: /* Methods: */ - CKeyChooser(const QList<const CSwordModuleInfo *> & info, + CKeyChooser(const BtConstModuleList & info, BTHistory * history, - QWidget * parent = 0); + QWidget * parent = nullptr); /** Resets the appropriate font to for the modules. diff --git a/src/frontend/keychooser/ckeychooserwidget.cpp b/src/frontend/keychooser/ckeychooserwidget.cpp index ea3421e..2f2d384 100644 --- a/src/frontend/keychooser/ckeychooserwidget.cpp +++ b/src/frontend/keychooser/ckeychooserwidget.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -16,6 +16,7 @@ #include <QString> #include <QWheelEvent> #include "frontend/keychooser/cscrollerwidgetset.h" +#include "util/btconnect.h" class BtKeyLineEdit : public QLineEdit { @@ -27,7 +28,7 @@ public: /* Methods: */ protected: /* Methods: */ - virtual void focusInEvent(QFocusEvent * event) { + void focusInEvent(QFocusEvent * event) override { const Qt::FocusReason reason = event->reason(); if (reason == Qt::OtherFocusReason) selectAll(); @@ -85,7 +86,7 @@ bool CKCComboBox::eventFilter(QObject * o, QEvent * e) { void CKCComboBox::wheelEvent(QWheelEvent * e) { return QComboBox::wheelEvent(e); /// \bug rest method won't get executed. - const signed int change = (int)((float)e->delta() / (float)120); + int const change = static_cast<int>(static_cast<float>(e->delta()) / 120); int current = currentIndex(); if ((current + change >= 0) && (current + change < count()) ) { @@ -157,17 +158,13 @@ void CKeyChooserWidget::reset(const QStringList * list, int index, bool do_emit) //DON'T REMOVE THE HIDE: Otherwise QComboBox's sizeHint() function won't work properly m_comboBox->hide(); m_comboBox->clear(); - if (list) - m_comboBox->insertItems(-1, *list); - - if (!list || (list && !list->count())) { // nothing in the combobox - setEnabled(false); - } else if (!isEnabled()) { // was disabled + if (list && !list->empty()) { + m_comboBox->insertItems(0, *list); // Prepend items setEnabled(true); - } - - if (list->count()) m_comboBox->setCurrentIndex(index); + } else { + setEnabled(false); + } if (do_emit) emit changed(m_comboBox->currentIndex()); @@ -206,17 +203,16 @@ void CKeyChooserWidget::init() { m_mainLayout->addWidget(m_scroller); m_mainLayout->addSpacing(0); - setTabOrder(m_comboBox, 0); + setTabOrder(m_comboBox, nullptr); setFocusProxy(m_comboBox); - connect(m_scroller, SIGNAL(scroller_pressed()), SLOT(lock())); - connect(m_scroller, SIGNAL(scroller_released()), SLOT(unlock())); - connect(m_scroller, SIGNAL(change(int)), SLOT(changeCombo(int))); - connect(m_comboBox, SIGNAL(activated(int)), SLOT(slotComboChanged(int))); - // connect(m_comboBox, SIGNAL(activated(const QString&)), SLOT(slotReturnPressed(const QString&))); - connect(m_comboBox->lineEdit(), SIGNAL(returnPressed()), - SLOT(slotReturnPressed())); - connect(m_comboBox, SIGNAL(focusOut(int)), SIGNAL(focusOut(int))); + BT_CONNECT(m_scroller, SIGNAL(scroller_pressed()), SLOT(lock())); + BT_CONNECT(m_scroller, SIGNAL(scroller_released()), SLOT(unlock())); + BT_CONNECT(m_scroller, SIGNAL(change(int)), SLOT(changeCombo(int))); + BT_CONNECT(m_comboBox, SIGNAL(activated(int)), SLOT(slotComboChanged(int))); + BT_CONNECT(m_comboBox->lineEdit(), SIGNAL(returnPressed()), + SLOT(slotReturnPressed())); + BT_CONNECT(m_comboBox, SIGNAL(focusOut(int)), SIGNAL(focusOut(int))); updatelock = false; m_isResetting = false; @@ -224,7 +220,7 @@ void CKeyChooserWidget::init() { /** Is called when the return key was presed in the combobox. */ void CKeyChooserWidget::slotReturnPressed() { - Q_ASSERT(m_comboBox->lineEdit()); + BT_ASSERT(m_comboBox->lineEdit()); const QString text(m_comboBox->lineEdit()->text()); for (int index = 0; index < m_comboBox->count(); ++index) { diff --git a/src/frontend/keychooser/ckeychooserwidget.h b/src/frontend/keychooser/ckeychooserwidget.h index a1fd31d..efc1fb5 100644 --- a/src/frontend/keychooser/ckeychooserwidget.h +++ b/src/frontend/keychooser/ckeychooserwidget.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -15,6 +15,7 @@ #include <QComboBox> #include <QStringList> +#include "util/btassert.h" class CLexiconKeyChooser; @@ -35,13 +36,13 @@ class CKCComboBox: public QComboBox { public: /* Methods: */ - CKCComboBox(QWidget * parent = 0); + CKCComboBox(QWidget * parent = nullptr); protected: /* Methods: */ - virtual bool eventFilter(QObject * o, QEvent * e); + bool eventFilter(QObject * o, QEvent * e) override; - virtual void wheelEvent(QWheelEvent * e); + void wheelEvent(QWheelEvent * e) override; signals: @@ -65,11 +66,11 @@ class CKeyChooserWidget: public QWidget { public: /* Methods: */ - CKeyChooserWidget(QStringList * list = 0, - QWidget * parent = 0); + CKeyChooserWidget(QStringList * list = nullptr, + QWidget * parent = nullptr); CKeyChooserWidget(int count = 0, - QWidget * parent = 0); + QWidget * parent = nullptr); /** * This function does clear the combobox, then fill in @@ -90,7 +91,7 @@ public: /* Methods: */ * Initializes this widget. We need this function because * we have more than one constructor. */ - virtual void init(); + void init(); /** * Sets the tooltips for the given entries using the parameters as text. @@ -109,7 +110,7 @@ public: /* Methods: */ * Return the combobox of this key chooser widget. */ QComboBox & comboBox() const { - Q_ASSERT(m_comboBox); + BT_ASSERT(m_comboBox); return *m_comboBox; } diff --git a/src/frontend/keychooser/clexiconkeychooser.cpp b/src/frontend/keychooser/clexiconkeychooser.cpp index 2c6545a..27a7dea 100644 --- a/src/frontend/keychooser/clexiconkeychooser.cpp +++ b/src/frontend/keychooser/clexiconkeychooser.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -16,10 +16,11 @@ #include "frontend/keychooser/bthistory.h" #include "frontend/keychooser/ckeychooserwidget.h" #include "frontend/keychooser/cscrollbutton.h" +#include "util/btconnect.h" #include "util/cresmgr.h" -CLexiconKeyChooser::CLexiconKeyChooser(const QList<const CSwordModuleInfo *> & modules, +CLexiconKeyChooser::CLexiconKeyChooser(const BtConstModuleList & modules, BTHistory * historyPtr, CSwordKey * key, QWidget * parent) @@ -51,12 +52,13 @@ CLexiconKeyChooser::CLexiconKeyChooser(const QList<const CSwordModuleInfo *> & m m_layout->addWidget(m_widget, 0, Qt::AlignLeft); - connect(m_widget, SIGNAL(changed(int)), SLOT(activated(int))); - connect(m_widget, SIGNAL(focusOut(int)), SLOT(activated(int))); + BT_CONNECT(m_widget, SIGNAL(changed(int)), SLOT(activated(int))); + BT_CONNECT(m_widget, SIGNAL(focusOut(int)), SLOT(activated(int))); setModules(modules, true); setKey(key); - connect(this, SIGNAL(keyChanged(CSwordKey*)), history(), SLOT(add(CSwordKey*)) ); + BT_CONNECT(this, SIGNAL(keyChanged(CSwordKey *)), + history(), SLOT(add(CSwordKey *)) ); } CSwordKey* CLexiconKeyChooser::key() { @@ -109,7 +111,7 @@ void CLexiconKeyChooser::refreshContent() { // qWarning("resetted"); } else { - typedef std::multimap<unsigned int, const QStringList*> EntryMap; + using EntryMap = std::multimap<unsigned int, QStringList const *>; EntryMap entryMap; QListIterator<const CSwordLexiconModuleInfo*> mit(m_modules); @@ -149,20 +151,17 @@ void CLexiconKeyChooser::refreshContent() { } -void CLexiconKeyChooser::setModules(const QList<const CSwordModuleInfo*> &modules, +void CLexiconKeyChooser::setModules(const BtConstModuleList &modules, bool refresh) { - typedef CSwordLexiconModuleInfo CSLMI; + using CSLMI = CSwordLexiconModuleInfo; while (!m_modules.isEmpty()) m_modules.takeFirst(); // not deleting the pointer - Q_FOREACH(const CSwordModuleInfo *m, modules) { - const CSLMI *lexicon = dynamic_cast<const CSLMI*>(m); - if (lexicon != 0) { + Q_FOREACH(CSwordModuleInfo const * const m, modules) + if (CSLMI const * const lexicon = dynamic_cast<CSLMI const *>(m)) m_modules.append(lexicon); - } - } if (refresh) { refreshContent(); diff --git a/src/frontend/keychooser/clexiconkeychooser.h b/src/frontend/keychooser/clexiconkeychooser.h index 5f14747..cb59bca 100644 --- a/src/frontend/keychooser/clexiconkeychooser.h +++ b/src/frontend/keychooser/clexiconkeychooser.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -34,38 +34,27 @@ class CLexiconKeyChooser : public CKeyChooser { Q_OBJECT public: - CLexiconKeyChooser(const QList<const CSwordModuleInfo*> &modules, - BTHistory *history, CSwordKey *key = 0, - QWidget *parent = 0); + CLexiconKeyChooser(const BtConstModuleList &modules, + BTHistory *history, CSwordKey *key = nullptr, + QWidget *parent = nullptr); public slots: - /** - Reimplemented from CKeyChooser::key(). - */ - virtual CSwordKey *key(); - /** - Reimplemented from CKeyChooser::setKey(). - */ - virtual void setKey(CSwordKey* key); + CSwordKey *key() override; + + void setKey(CSwordKey* key) override; /** * used to react to changes in the @ref CKeyChooserWidget * * @param index not used **/ - virtual void activated(int index); + void activated(int index); - /** - Reimplemented from CKeyChooser::refreshContent(). - */ - virtual void refreshContent(); + void refreshContent() override; - /** - Reimplemented from CKeyChooser::setModules(). - */ - virtual void setModules(const QList<const CSwordModuleInfo*> &modules, - bool refresh = true); + void setModules(const BtConstModuleList &modules, + bool refresh = true) override; protected: CKeyChooserWidget *m_widget; @@ -73,13 +62,13 @@ class CLexiconKeyChooser : public CKeyChooser { QList<const CSwordLexiconModuleInfo*> m_modules; QHBoxLayout *m_layout; - virtual inline void adjustFont() {} + inline void adjustFont() override {} public slots: // Public slots - virtual void updateKey(CSwordKey* key); + void updateKey(CSwordKey* key) override; protected slots: - virtual void setKey(const QString & newKey); + void setKey(const QString & newKey) override; }; diff --git a/src/frontend/keychooser/cscrollbutton.cpp b/src/frontend/keychooser/cscrollbutton.cpp index 775d4db..1e46ecc 100644 --- a/src/frontend/keychooser/cscrollbutton.cpp +++ b/src/frontend/keychooser/cscrollbutton.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -52,13 +52,13 @@ void CScrollButton::mouseMoveEvent(QMouseEvent *e) { if (vchange != 0) { // Adapt the change value, so we get a more natural feeling: if(vchange > 0) - m_movement += pow((float)vchange/10.0, 1.2); + m_movement += pow(vchange/10.0f, 1.2); else // (vchange < 0) - m_movement -= pow(-(float)vchange/10.0, 1.2); + m_movement -= pow(-vchange/10.0f, 1.2); // Emit the change request signal only when the mouse was moved far enough if (m_movement >= 1.0 || m_movement <= -1.0) { - emit change_requested((int) m_movement); + emit change_requested(static_cast<int>(m_movement)); m_movement = 0.0; } } diff --git a/src/frontend/keychooser/cscrollbutton.h b/src/frontend/keychooser/cscrollbutton.h index 2b3f662..17b45e8 100644 --- a/src/frontend/keychooser/cscrollbutton.h +++ b/src/frontend/keychooser/cscrollbutton.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -26,7 +26,7 @@ class QWidget; class CScrollButton: public QToolButton { Q_OBJECT public: - CScrollButton(QWidget *parent = 0); + CScrollButton(QWidget *parent = nullptr); signals: /** @@ -53,19 +53,15 @@ class CScrollButton: public QToolButton { /** * \brief Grabs the mouse on left button click and emits lock(). */ - virtual void mousePressEvent(QMouseEvent *e); + void mousePressEvent(QMouseEvent *e) override; /** * \brief If the mouse is grabbed and we release the left mouse button, * releases the mouse and emits unlock(). */ - virtual void mouseReleaseEvent(QMouseEvent *e); + void mouseReleaseEvent(QMouseEvent *e) override; - /** - * \brief Reimplementation of QWidget::mouseMoveEvent() to process mouse - move events. - */ - virtual void mouseMoveEvent(QMouseEvent *e); + void mouseMoveEvent(QMouseEvent *e) override; protected: /** diff --git a/src/frontend/keychooser/cscrollerwidgetset.cpp b/src/frontend/keychooser/cscrollerwidgetset.cpp index e169ae9..a599bf5 100644 --- a/src/frontend/keychooser/cscrollerwidgetset.cpp +++ b/src/frontend/keychooser/cscrollerwidgetset.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -14,6 +14,7 @@ #include <QVBoxLayout> #include <QWheelEvent> #include "frontend/keychooser/cscrollbutton.h" +#include "util/btconnect.h" #define WIDTH (static_cast<unsigned int>(16)) @@ -51,11 +52,12 @@ CScrollerWidgetSet::CScrollerWidgetSet(QWidget * parent) m_layout->addWidget(m_buttonDown, 0); setMinimumWidth(WIDTH); // Kludge to add some spacing but seems to work. - connect(m_scrollButton, SIGNAL(lock()), SLOT(slotLock())); - connect(m_scrollButton, SIGNAL(unlock()), SLOT(slotUnlock())); - connect(m_scrollButton, SIGNAL(change_requested(int)), SLOT(slotScroller(int))); - connect(m_buttonUp, SIGNAL(clicked()), SLOT(slotUpClick())); - connect(m_buttonDown, SIGNAL(clicked()), SLOT(slotDownClick())); + BT_CONNECT(m_scrollButton, SIGNAL(lock()), SLOT(slotLock())); + BT_CONNECT(m_scrollButton, SIGNAL(unlock()), SLOT(slotUnlock())); + BT_CONNECT(m_scrollButton, SIGNAL(change_requested(int)), + SLOT(slotScroller(int))); + BT_CONNECT(m_buttonUp, SIGNAL(clicked()), SLOT(slotUpClick())); + BT_CONNECT(m_buttonDown, SIGNAL(clicked()), SLOT(slotDownClick())); } /** Sets the tooltips for the given entries using the parameters as text. */ @@ -70,16 +72,12 @@ void CScrollerWidgetSet::setToolTips(const QString & nextEntryTip, void CScrollerWidgetSet::wheelEvent(QWheelEvent * e) { - /** - * The problem is, that wheel events do everytime have the delta value 120 - */ - const int vchange = ((e->delta() > 0) ? -1 : 1); - - if (vchange != 0) { // Do not emit a change with value 0 - emit change(vchange); - e->accept(); - } else { + int const delta = e->delta(); + if (delta == 0) { e->ignore(); + } else { + emit change((delta > 0) ? -1 : 1); + e->accept(); } } diff --git a/src/frontend/keychooser/cscrollerwidgetset.h b/src/frontend/keychooser/cscrollerwidgetset.h index 2894928..016a282 100644 --- a/src/frontend/keychooser/cscrollerwidgetset.h +++ b/src/frontend/keychooser/cscrollerwidgetset.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -30,7 +30,7 @@ class CScrollerWidgetSet: public QWidget { public: /* Methods: */ - CScrollerWidgetSet(QWidget * parent = 0); + CScrollerWidgetSet(QWidget * parent = nullptr); /** * Sets the tooltips for the given entries using the parameters as text. @@ -54,7 +54,7 @@ signals: protected: /* Methods: */ - virtual void wheelEvent(QWheelEvent * e); + void wheelEvent(QWheelEvent * e) override; protected slots: diff --git a/src/frontend/keychooser/versekeychooser/btbiblekeywidget.cpp b/src/frontend/keychooser/versekeychooser/btbiblekeywidget.cpp index 2ac2574..98cd47f 100644 --- a/src/frontend/keychooser/versekeychooser/btbiblekeywidget.cpp +++ b/src/frontend/keychooser/versekeychooser/btbiblekeywidget.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -24,9 +24,8 @@ #include "bibletimeapp.h" #include "frontend/keychooser/cscrollerwidgetset.h" #include "frontend/keychooser/versekeychooser/btdropdownchooserbutton.h" -#include "util/btsignal.h" +#include "util/btconnect.h" #include "util/cresmgr.h" -#include "util/geticon.h" class BtLineEdit : public QLineEdit { @@ -35,7 +34,7 @@ class BtLineEdit : public QLineEdit { : QLineEdit(parent) { } protected: - void focusInEvent(QFocusEvent* event) { + void focusInEvent(QFocusEvent* event) override { Qt::FocusReason reason = event->reason(); if (reason == Qt::OtherFocusReason) { selectAll(); @@ -59,10 +58,10 @@ BtBibleKeyWidget::BtBibleKeyWidget(const CSwordBibleModuleInfo *mod, setFocusPolicy(Qt::WheelFocus); QToolButton* clearRef = new QToolButton(this); - clearRef->setIcon(util::getIcon("edit_clear_locationbar")); + clearRef->setIcon(CResMgr::icon_clearEdit()); clearRef->setAutoRaise(true); clearRef->setStyleSheet("QToolButton{margin:0px;}"); - connect(clearRef, SIGNAL(clicked()), SLOT(slotClearRef()) ); + BT_CONNECT(clearRef, SIGNAL(clicked()), SLOT(slotClearRef()) ); m_bookScroller = new CScrollerWidgetSet(this); @@ -83,8 +82,8 @@ BtBibleKeyWidget::BtBibleKeyWidget(const CSwordBibleModuleInfo *mod, m_mainLayout->addWidget(m_verseScroller); - setTabOrder(m_textbox, 0); - m_dropDownButtons = new QWidget(0); + setTabOrder(m_textbox, nullptr); + m_dropDownButtons = new QWidget(nullptr); m_dropDownButtons->setWindowFlags(Qt::Popup); m_dropDownButtons->setAttribute(Qt::WA_WindowPropagation); m_dropDownButtons->setCursor(Qt::ArrowCursor); @@ -104,8 +103,8 @@ BtBibleKeyWidget::BtBibleKeyWidget(const CSwordBibleModuleInfo *mod, m_dropDownHoverTimer.setInterval(500); m_dropDownHoverTimer.setSingleShot(true); - connect(&m_dropDownHoverTimer, SIGNAL(timeout()), - m_dropDownButtons, SLOT(hide())); + BT_CONNECT(&m_dropDownHoverTimer, SIGNAL(timeout()), + m_dropDownButtons, SLOT(hide())); QString scrollButtonToolTip(tr("Scroll through the entries of the list. Press the button and move the mouse to increase or decrease the item.")); m_bookScroller->setToolTips( @@ -126,18 +125,26 @@ BtBibleKeyWidget::BtBibleKeyWidget(const CSwordBibleModuleInfo *mod, // signals and slots connections - connect(m_bookScroller, SIGNAL(change(int)), SLOT(slotStepBook(int))); - connect(m_bookScroller, SIGNAL(scroller_pressed()), SLOT(slotUpdateLock())); - connect(m_bookScroller, SIGNAL(scroller_released()), SLOT(slotUpdateUnlock())); - connect(m_textbox, SIGNAL(returnPressed()), SLOT(slotReturnPressed())); - connect(m_chapterScroller, SIGNAL(change(int)), SLOT(slotStepChapter(int))); - connect(m_chapterScroller, SIGNAL(scroller_pressed()), SLOT(slotUpdateLock())); - connect(m_chapterScroller, SIGNAL(scroller_released()), SLOT(slotUpdateUnlock())); - connect(m_verseScroller, SIGNAL(change(int)), SLOT(slotStepVerse(int))); - connect(m_verseScroller, SIGNAL(scroller_pressed()), SLOT(slotUpdateLock())); - connect(m_verseScroller, SIGNAL(scroller_released()), SLOT(slotUpdateUnlock())); - bool ok = connect(m_key->afterChangedSignaller(), SIGNAL(signal()), this, SLOT(updateText())); - Q_ASSERT(ok); + BT_CONNECT(m_bookScroller, SIGNAL(change(int)), SLOT(slotStepBook(int))); + BT_CONNECT(m_bookScroller, SIGNAL(scroller_pressed()), + SLOT(slotUpdateLock())); + BT_CONNECT(m_bookScroller, SIGNAL(scroller_released()), + SLOT(slotUpdateUnlock())); + BT_CONNECT(m_textbox, SIGNAL(returnPressed()), + SLOT(slotReturnPressed())); + BT_CONNECT(m_chapterScroller, SIGNAL(change(int)), + SLOT(slotStepChapter(int))); + BT_CONNECT(m_chapterScroller, SIGNAL(scroller_pressed()), + SLOT(slotUpdateLock())); + BT_CONNECT(m_chapterScroller, SIGNAL(scroller_released()), + SLOT(slotUpdateUnlock())); + BT_CONNECT(m_verseScroller, SIGNAL(change(int)), SLOT(slotStepVerse(int))); + BT_CONNECT(m_verseScroller, SIGNAL(scroller_pressed()), + SLOT(slotUpdateLock())); + BT_CONNECT(m_verseScroller, SIGNAL(scroller_released()), + SLOT(slotUpdateUnlock())); + BT_CONNECT(m_key->afterChangedSignaller(), SIGNAL(signal()), + this, SLOT(updateText())); setKey(key); // The order of these two functions is important. setModule(); diff --git a/src/frontend/keychooser/versekeychooser/btbiblekeywidget.h b/src/frontend/keychooser/versekeychooser/btbiblekeywidget.h index 7d94c94..7a28ca0 100644 --- a/src/frontend/keychooser/versekeychooser/btbiblekeywidget.h +++ b/src/frontend/keychooser/versekeychooser/btbiblekeywidget.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -29,22 +29,22 @@ class BtBibleKeyWidget : public QWidget { public: BtBibleKeyWidget(const CSwordBibleModuleInfo *module, - CSwordVerseKey *key, QWidget *parent = 0, - const char *name = 0); + CSwordVerseKey *key, QWidget *parent = nullptr, + const char *name = nullptr); ~BtBibleKeyWidget(); bool setKey(CSwordVerseKey* key); - void setModule(const CSwordBibleModuleInfo *m = 0); - bool eventFilter(QObject *o, QEvent *e); + void setModule(const CSwordBibleModuleInfo *m = nullptr); + bool eventFilter(QObject *o, QEvent *e) override; signals: void beforeChange(CSwordVerseKey* key); void changed(CSwordVerseKey* key); protected: - void enterEvent(QEvent *event); - void leaveEvent(QEvent *event); - void resizeEvent(QResizeEvent *event); + void enterEvent(QEvent *event) override; + void leaveEvent(QEvent *event) override; + void resizeEvent(QResizeEvent *event) override; void resetDropDownButtons(); protected slots: // Protected slots diff --git a/src/frontend/keychooser/versekeychooser/btdropdownchooserbutton.cpp b/src/frontend/keychooser/versekeychooser/btdropdownchooserbutton.cpp index 70f800a..5c59717 100644 --- a/src/frontend/keychooser/versekeychooser/btdropdownchooserbutton.cpp +++ b/src/frontend/keychooser/versekeychooser/btdropdownchooserbutton.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -12,6 +12,7 @@ #include <QWheelEvent> #include "frontend/keychooser/versekeychooser/btversekeymenu.h" #include "frontend/keychooser/versekeychooser/btbiblekeywidget.h" +#include "util/btconnect.h" const unsigned int ARROW_HEIGHT = 15; @@ -31,7 +32,8 @@ BtDropdownChooserButton::BtDropdownChooserButton(BtBibleKeyWidget* ref) BtVerseKeyMenu* m = new BtVerseKeyMenu(this); // KAcceleratorManager::setNoAccel(m); setMenu(m); - QObject::connect(m, SIGNAL(triggered(QAction*)), this, SLOT(slotMenuTriggered(QAction*))); + BT_CONNECT(m, SIGNAL(triggered(QAction *)), + this, SLOT(slotMenuTriggered(QAction *))); } @@ -43,16 +45,13 @@ void BtDropdownChooserButton::mousePressEvent(QMouseEvent* e) { QToolButton::mousePressEvent(e); } -void BtDropdownChooserButton::wheelEvent(QWheelEvent* e) { - // The problem is, that wheel events do everytime have the delta value 120 - const int vchange = ((e->delta() > 0) ? (-1) : (1)); - - if (vchange != 0) {//do not emit a change with value 0 - emit stepItem(vchange); - e->accept(); - } - else { +void BtDropdownChooserButton::wheelEvent(QWheelEvent * e) { + int const delta = e->delta(); + if (delta == 0) { e->ignore(); + } else { + emit stepItem((delta > 0) ? -1 : 1); + e->accept(); } } @@ -62,19 +61,18 @@ void BtDropdownChooserButton::wheelEvent(QWheelEvent* e) { BtBookDropdownChooserButton::BtBookDropdownChooserButton(BtBibleKeyWidget* ref) : BtDropdownChooserButton(ref) { setToolTip(tr("Select book")); - QObject::connect(this, SIGNAL(stepItem(int)), m_ref, SLOT(slotStepBook(int))); + BT_CONNECT(this, SIGNAL(stepItem(int)), m_ref, SLOT(slotStepBook(int))); } void BtBookDropdownChooserButton::newList() { QMenu* m = menu(); QStringList* booklist = ref()->m_module->books(); - foreach (QString bookname, *booklist) { - m->addAction(bookname); - } + Q_FOREACH(QString const & bookname, *booklist) + m->addAction(bookname)->setProperty("bookname", bookname); } void BtBookDropdownChooserButton::slotMenuTriggered(QAction* action) { - m_ref->slotChangeBook(action->text()); + m_ref->slotChangeBook(action->property("bookname").toString()); } @@ -83,19 +81,18 @@ void BtBookDropdownChooserButton::slotMenuTriggered(QAction* action) { BtChapterDropdownChooserButton::BtChapterDropdownChooserButton(BtBibleKeyWidget* ref) : BtDropdownChooserButton(ref) { setToolTip(tr("Select chapter")); - QObject::connect(this, SIGNAL(stepItem(int)), m_ref, SLOT(slotStepChapter(int))); + BT_CONNECT(this, SIGNAL(stepItem(int)), m_ref, SLOT(slotStepChapter(int))); } void BtChapterDropdownChooserButton::newList() { QMenu* m = menu(); int count = ref()->m_module->chapterCount(ref()->m_key->book()); - for (int i = 1; i <= count; i++) { - m->addAction(QString::number(i)); - } + for (int i = 1; i <= count; i++) + m->addAction(QString::number(i))->setProperty("chapter", i); } void BtChapterDropdownChooserButton::slotMenuTriggered(QAction* action) { - m_ref->slotChangeChapter(action->text().toInt()); + m_ref->slotChangeChapter(action->property("chapter").toInt()); } @@ -104,17 +101,16 @@ void BtChapterDropdownChooserButton::slotMenuTriggered(QAction* action) { BtVerseDropdownChooserButton::BtVerseDropdownChooserButton(BtBibleKeyWidget* ref) : BtDropdownChooserButton(ref) { setToolTip(tr("Select verse")); - QObject::connect(this, SIGNAL(stepItem(int)), m_ref, SLOT(slotStepVerse(int))); + BT_CONNECT(this, SIGNAL(stepItem(int)), m_ref, SLOT(slotStepVerse(int))); } void BtVerseDropdownChooserButton::newList() { QMenu* m = menu(); int count = ref()->m_module->verseCount(ref()->m_key->book(), ref()->m_key->getChapter()); - for (int i = 1; i <= count; i++) { - m->addAction(QString::number(i)); - } + for (int i = 1; i <= count; i++) + m->addAction(QString::number(i))->setProperty("verse", i); } void BtVerseDropdownChooserButton::slotMenuTriggered(QAction* action) { - m_ref->slotChangeVerse(action->text().toInt()); + m_ref->slotChangeVerse(action->property("verse").toInt()); } diff --git a/src/frontend/keychooser/versekeychooser/btdropdownchooserbutton.h b/src/frontend/keychooser/versekeychooser/btdropdownchooserbutton.h index 646b7ef..d276bf8 100644 --- a/src/frontend/keychooser/versekeychooser/btdropdownchooserbutton.h +++ b/src/frontend/keychooser/versekeychooser/btdropdownchooserbutton.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -26,7 +26,7 @@ class BtDropdownChooserButton : public QToolButton { BtDropdownChooserButton(BtBibleKeyWidget* ref); /** The item list is constructed here just before the menu is shown.*/ - virtual void mousePressEvent(QMouseEvent* event); + void mousePressEvent(QMouseEvent* event) override; /** Recreates the menu list.*/ virtual void newList() = 0; /** Returns the verse reference widget which this button belongs to.*/ @@ -38,7 +38,7 @@ class BtDropdownChooserButton : public QToolButton { virtual void slotMenuTriggered(QAction* action) = 0; protected: BtBibleKeyWidget* m_ref; - void wheelEvent(QWheelEvent* event); + void wheelEvent(QWheelEvent* event) override; signals: void stepItem(int step); }; @@ -48,9 +48,9 @@ class BtBookDropdownChooserButton : public BtDropdownChooserButton { Q_OBJECT public: BtBookDropdownChooserButton(BtBibleKeyWidget* ref); - virtual void newList(); + void newList() override; public slots: - virtual void slotMenuTriggered(QAction* action); + void slotMenuTriggered(QAction* action) override; }; /** See BtDropdownChooserButton.*/ @@ -58,9 +58,9 @@ class BtChapterDropdownChooserButton : public BtDropdownChooserButton { Q_OBJECT public: BtChapterDropdownChooserButton(BtBibleKeyWidget* ref); - virtual void newList(); + void newList() override; public slots: - virtual void slotMenuTriggered(QAction* action); + void slotMenuTriggered(QAction* action) override; }; /** See BtDropdownChooserButton.*/ @@ -68,8 +68,8 @@ class BtVerseDropdownChooserButton : public BtDropdownChooserButton { Q_OBJECT public: BtVerseDropdownChooserButton(BtBibleKeyWidget* ref); - virtual void newList(); + void newList() override; public slots: - virtual void slotMenuTriggered(QAction* action); + void slotMenuTriggered(QAction* action) override; }; #endif diff --git a/src/frontend/keychooser/versekeychooser/btversekeymenu.cpp b/src/frontend/keychooser/versekeychooser/btversekeymenu.cpp index 9a8d35e..61dbcc2 100644 --- a/src/frontend/keychooser/versekeychooser/btversekeymenu.cpp +++ b/src/frontend/keychooser/versekeychooser/btversekeymenu.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -12,6 +12,7 @@ #include <QMenu> #include <QMouseEvent> #include <QTimerEvent> +#include "util/btconnect.h" BtVerseKeyMenu::BtVerseKeyMenu(QWidget* parent) @@ -19,21 +20,25 @@ BtVerseKeyMenu::BtVerseKeyMenu(QWidget* parent) , m_timerId(0) , m_firstClickLock(true) { - connect(this, SIGNAL(aboutToShow()), - this, SLOT(startFirstClickDelayTimer())); + BT_CONNECT(this, SIGNAL(aboutToShow()), + this, SLOT(startFirstClickDelayTimer())); } void BtVerseKeyMenu::startFirstClickDelayTimer() { m_firstClickLock = true; - if (m_timerId) + if (m_timerId) { killTimer(m_timerId); + m_timerId = 0; + } m_timerId = startTimer(300); } void BtVerseKeyMenu::timerEvent(QTimerEvent* e) { if (e->timerId() == m_timerId) { - if (m_timerId) + if (m_timerId) { killTimer(m_timerId); + m_timerId = 0; + } m_firstClickLock = false; } else { diff --git a/src/frontend/keychooser/versekeychooser/btversekeymenu.h b/src/frontend/keychooser/versekeychooser/btversekeymenu.h index 18caab5..56cbdf5 100644 --- a/src/frontend/keychooser/versekeychooser/btversekeymenu.h +++ b/src/frontend/keychooser/versekeychooser/btversekeymenu.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -29,9 +29,9 @@ class BtVerseKeyMenu : public QMenu { public: BtVerseKeyMenu(QWidget* parent); protected: - virtual void mouseReleaseEvent(QMouseEvent* event); + void mouseReleaseEvent(QMouseEvent* event) override; /** Frees the mouse button release after the delay has elapsed.*/ - virtual void timerEvent(QTimerEvent* event); + void timerEvent(QTimerEvent* event) override; private slots: /** Starts the delay timer for the first mouse button release.*/ void startFirstClickDelayTimer(); diff --git a/src/frontend/keychooser/versekeychooser/cbiblekeychooser.cpp b/src/frontend/keychooser/versekeychooser/cbiblekeychooser.cpp index e481020..6d4ca36 100644 --- a/src/frontend/keychooser/versekeychooser/cbiblekeychooser.cpp +++ b/src/frontend/keychooser/versekeychooser/cbiblekeychooser.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -17,23 +17,25 @@ #include "frontend/keychooser/bthistory.h" #include "frontend/keychooser/cscrollbutton.h" #include "frontend/keychooser/versekeychooser/btbiblekeywidget.h" +#include "util/btassert.h" +#include "util/btconnect.h" #include "util/cresmgr.h" -CBibleKeyChooser::CBibleKeyChooser(const QList<const CSwordModuleInfo *> & modules, +CBibleKeyChooser::CBibleKeyChooser(const BtConstModuleList & modules, BTHistory * historyPtr, CSwordKey * key, QWidget * parent) : CKeyChooser(modules, historyPtr, parent) , m_key(dynamic_cast<CSwordVerseKey *>(key)) { - typedef CSwordBibleModuleInfo CSBMI; + using CSBMI = CSwordBibleModuleInfo; - w_ref = 0; + w_ref = nullptr; setModules(modules, false); if (!m_modules.count()) { qWarning() << "CBibleKeyChooser: module is not a Bible or commentary!"; - m_key = 0; + m_key = nullptr; return; } QHBoxLayout* layout = new QHBoxLayout(this); @@ -46,16 +48,15 @@ CBibleKeyChooser::CBibleKeyChooser(const QList<const CSwordModuleInfo *> & modul setFocusProxy(w_ref); layout->addWidget(w_ref); - bool ok = connect(w_ref, SIGNAL(beforeChange(CSwordVerseKey *)), SLOT(beforeRefChange(CSwordVerseKey *))); - Q_ASSERT(ok); - - ok =connect(w_ref, SIGNAL(changed(CSwordVerseKey *)), SLOT(refChanged(CSwordVerseKey *))); - Q_ASSERT(ok); + BT_CONNECT(w_ref, SIGNAL(beforeChange(CSwordVerseKey *)), + SLOT(beforeRefChange(CSwordVerseKey *))); + BT_CONNECT(w_ref, SIGNAL(changed(CSwordVerseKey *)), + SLOT(refChanged(CSwordVerseKey *))); setKey(m_key); //set the key without changing it, setKey(key()) would change it - ok = connect(this, SIGNAL(keyChanged(CSwordKey*)), history(), SLOT(add(CSwordKey*)) ); - Q_ASSERT(ok); + BT_CONNECT(this, SIGNAL(keyChanged(CSwordKey *)), + history(), SLOT(add(CSwordKey *))); } CSwordKey* CBibleKeyChooser::key() { @@ -63,8 +64,8 @@ CSwordKey* CBibleKeyChooser::key() { } void CBibleKeyChooser::setKey(CSwordKey* key) { - Q_ASSERT(dynamic_cast<CSwordVerseKey*>(key)); - if (dynamic_cast<CSwordVerseKey*>(key) == 0) return; + BT_ASSERT(dynamic_cast<CSwordVerseKey *>(key)); + if (dynamic_cast<CSwordVerseKey*>(key) == nullptr) return; m_key = dynamic_cast<CSwordVerseKey*>(key); w_ref->setKey(m_key); @@ -74,15 +75,15 @@ void CBibleKeyChooser::setKey(CSwordKey* key) { void CBibleKeyChooser::beforeRefChange(CSwordVerseKey* key) { Q_UNUSED(key); - Q_ASSERT(m_key); + BT_ASSERT(m_key); if (!updatesEnabled()) return; } void CBibleKeyChooser::refChanged(CSwordVerseKey* key) { - Q_ASSERT(m_key); - Q_ASSERT(key); + BT_ASSERT(m_key); + BT_ASSERT(key); if (!updatesEnabled()) return; @@ -94,23 +95,18 @@ void CBibleKeyChooser::refChanged(CSwordVerseKey* key) { setUpdatesEnabled(true); } -void CBibleKeyChooser::setModules(const QList<const CSwordModuleInfo*> &modules, +void CBibleKeyChooser::setModules(const BtConstModuleList &modules, bool refresh) { - typedef CSwordBibleModuleInfo CSBMI; + using CSBMI = CSwordBibleModuleInfo; m_modules.clear(); - Q_FOREACH (const CSwordModuleInfo *mod, modules) { + Q_FOREACH(CSwordModuleInfo const * const mod, modules) if (mod->type() == CSwordModuleInfo::Bible || mod->type() == CSwordModuleInfo::Commentary) - { - const CSBMI* bible = dynamic_cast<const CSBMI*>(mod); - if (bible != 0) { + if (CSBMI const * const bible = dynamic_cast<CSBMI const *>(mod)) m_modules.append(bible); - } - } - } // First time this is called we havnt set up w_ref. if (w_ref) w_ref->setModule(dynamic_cast<const CSwordBibleModuleInfo*>(m_modules.first())); diff --git a/src/frontend/keychooser/versekeychooser/cbiblekeychooser.h b/src/frontend/keychooser/versekeychooser/cbiblekeychooser.h index 91ad265..4f49862 100644 --- a/src/frontend/keychooser/versekeychooser/cbiblekeychooser.h +++ b/src/frontend/keychooser/versekeychooser/cbiblekeychooser.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -37,26 +37,18 @@ class CBibleKeyChooser : public CKeyChooser { Q_OBJECT public: - CBibleKeyChooser(const QList<const CSwordModuleInfo*> &modules, - BTHistory *history, CSwordKey *key = 0, - QWidget *parent = 0); + CBibleKeyChooser(const BtConstModuleList &modules, + BTHistory *history, CSwordKey *key = nullptr, + QWidget *parent = nullptr); public slots: - /** - Reimplemented from CKeyChooser::key(). - */ - CSwordKey* key(); - /** - Reimplemented from CKeyChooser::setKey(). - */ - virtual void setKey(CSwordKey *key); + CSwordKey* key() override; - /** - Reimplemented from CKeyChooser::setModules(). - */ - virtual void setModules(const QList<const CSwordModuleInfo*> &modules, - bool refresh = true); + void setKey(CSwordKey *key) override; + + void setModules(const BtConstModuleList &modules, + bool refresh = true) override; /** * used to do actions before key changes @@ -67,13 +59,13 @@ class CBibleKeyChooser : public CKeyChooser { */ void refChanged(CSwordVerseKey *key); - void updateKey(CSwordKey* key); - void adjustFont(); - void refreshContent(); + void updateKey(CSwordKey* key) override; + void adjustFont() override; + void refreshContent() override; protected slots: - virtual void setKey(const QString & newKey); + void setKey(const QString & newKey) override; private: BtBibleKeyWidget* w_ref; diff --git a/src/frontend/messagedialog.cpp b/src/frontend/messagedialog.cpp index f064f06..7909b93 100644 --- a/src/frontend/messagedialog.cpp +++ b/src/frontend/messagedialog.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -13,6 +13,7 @@ #include <QDialogButtonBox> #include <QMessageBox> #include <QPushButton> +#include "util/btassert.h" namespace message { @@ -22,7 +23,7 @@ namespace { void replaceText(QDialogButtonBox *box, QDialogButtonBox::StandardButton flag, const QString &text) { QPushButton *button(box->button(flag)); - if (button != 0) { + if (button != nullptr) { button->setText(text); } } @@ -38,17 +39,17 @@ QMessageBox::StandardButton bt_messageBox(QMessageBox::Icon icon, messageBox.setTextFormat(Qt::RichText); //We need the button box to translate the strings (the idea of this whole function) QDialogButtonBox* box = dynamic_cast<QDialogButtonBox*>(messageBox.button(QMessageBox::Ok)->parent()); - Q_ASSERT(box); + BT_ASSERT(box); messageBox.setStandardButtons(buttons); messageBox.setDefaultButton(defaultButton); prepareDialogBox(box); - return (QMessageBox::StandardButton)messageBox.exec(); + return static_cast<QMessageBox::StandardButton>(messageBox.exec()); } } // anonymous namespace void setQActionCheckedNoTrigger(QAction * const action, const bool checked) { - Q_ASSERT(action); + BT_ASSERT(action); const bool signalsWereBlocked = action->blockSignals(true); action->setChecked(checked); action->blockSignals(signalsWereBlocked); diff --git a/src/frontend/messagedialog.h b/src/frontend/messagedialog.h index 3f1a34b..eda477a 100644 --- a/src/frontend/messagedialog.h +++ b/src/frontend/messagedialog.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ diff --git a/src/frontend/searchdialog/analysis/csearchanalysisdialog.cpp b/src/frontend/searchdialog/analysis/csearchanalysisdialog.cpp index 10e4566..8e7250d 100644 --- a/src/frontend/searchdialog/analysis/csearchanalysisdialog.cpp +++ b/src/frontend/searchdialog/analysis/csearchanalysisdialog.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -14,11 +14,13 @@ #include <QDesktopWidget> #include <QDialog> #include <QDialogButtonBox> +#include <QtGlobal> #include <QVBoxLayout> #include "backend/drivers/cswordmoduleinfo.h" #include "frontend/searchdialog/analysis/csearchanalysisscene.h" #include "frontend/searchdialog/analysis/csearchanalysisview.h" #include "frontend/messagedialog.h" +#include "util/btconnect.h" namespace Search { @@ -37,11 +39,10 @@ CSearchAnalysisDialog::CSearchAnalysisDialog( // Set initial width based on the search data, but limit to the // width of the desktop - int width = (int)( m_analysis->width() + DIALOG_BORDER ); - int desktopWidth = QApplication::desktop()->screenGeometry(this).width(); - if (width > desktopWidth) - width = desktopWidth; - resize(width, DIALOG_HEIGHT); + int const width = static_cast<int>(m_analysis->width() + DIALOG_BORDER); + int const desktopWidth = + QApplication::desktop()->screenGeometry(this).width(); + resize(qMin(width, desktopWidth), DIALOG_HEIGHT); } /** Initializes this dialog. */ @@ -62,10 +63,9 @@ void CSearchAnalysisDialog::initView() { message::prepareDialogBox(m_buttonBox); vboxLayout->addWidget(m_buttonBox); - bool ok = QObject::connect(m_buttonBox, SIGNAL(rejected()), this, SLOT(reject())); - Q_ASSERT(ok); - ok = QObject::connect(m_buttonBox, SIGNAL(clicked(QAbstractButton*)), this, SLOT(buttonClicked(QAbstractButton*))); - Q_ASSERT(ok); + BT_CONNECT(m_buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + BT_CONNECT(m_buttonBox, SIGNAL(clicked(QAbstractButton *)), + this, SLOT(buttonClicked(QAbstractButton *))); } void CSearchAnalysisDialog::buttonClicked(QAbstractButton* button) { diff --git a/src/frontend/searchdialog/analysis/csearchanalysisdialog.h b/src/frontend/searchdialog/analysis/csearchanalysisdialog.h index 454e105..c95875f 100644 --- a/src/frontend/searchdialog/analysis/csearchanalysisdialog.h +++ b/src/frontend/searchdialog/analysis/csearchanalysisdialog.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -16,9 +16,6 @@ #include "backend/cswordmodulesearch.h" -// Sword includes -#include <listkey.h> - class CSwordModuleInfo; class QAbstractButton; @@ -36,14 +33,14 @@ class CSearchAnalysisDialog : public QDialog { Q_OBJECT public: CSearchAnalysisDialog(const CSwordModuleSearch::Results &results, - QWidget *parentDialog = 0); + QWidget *parentDialog = nullptr); protected: // Protected methods /** * Initializes this dialog. */ void initView(); - void resizeEvent(QResizeEvent* event); + void resizeEvent(QResizeEvent* event) override; private slots: void buttonClicked(QAbstractButton* button); diff --git a/src/frontend/searchdialog/analysis/csearchanalysisitem.cpp b/src/frontend/searchdialog/analysis/csearchanalysisitem.cpp index c516184..6d41839 100644 --- a/src/frontend/searchdialog/analysis/csearchanalysisitem.cpp +++ b/src/frontend/searchdialog/analysis/csearchanalysisitem.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -17,19 +17,11 @@ #include <QRect> #include "backend/drivers/cswordmoduleinfo.h" #include "frontend/searchdialog/analysis/csearchanalysisscene.h" -#include "util/htmlescape.h" namespace Search { -const int SPACE_BETWEEN_PARTS = 5; -const int RIGHT_BORDER = 15; -const int LEFT_BORDER = 15; -const int LOWER_BORDER = 10; -const int UPPER_BORDER = 10; - const int ITEM_TEXT_SIZE = 8; -const int LABEL_TEXT_SIZE = 6; //used for the shift between the bars const int BAR_DELTAX = 4; @@ -38,10 +30,6 @@ const int BAR_WIDTH = 2 + (2*BAR_DELTAX); //should be equal or bigger than the // Used for the text below the bars const int BAR_LOWER_BORDER = 100; -const int LEGEND_INNER_BORDER = 5; -const int LEGEND_DELTAY = 4; -const int LEGEND_WIDTH = 85; - CSearchAnalysisItem::CSearchAnalysisItem( const int moduleCount, const QString &bookname, @@ -51,7 +39,7 @@ CSearchAnalysisItem::CSearchAnalysisItem( m_scaleFactor(scaleFactor), m_bookName(bookname), m_moduleCount(moduleCount), - m_bufferPixmap(0) + m_bufferPixmap(nullptr) { m_resultCountArray.resize(m_moduleCount); int index = 0; @@ -63,9 +51,9 @@ CSearchAnalysisItem::~CSearchAnalysisItem() { } bool CSearchAnalysisItem::hasHitsInAnyModule() { - foreach (const int hits, m_resultCountArray) { - if (hits) return true; - } + Q_FOREACH(int const hits, m_resultCountArray) + if (hits) + return true; return false; } @@ -93,10 +81,12 @@ void CSearchAnalysisItem::paint(QPainter* painter, const QStyleOptionGraphicsIte while (drawn < m_moduleCount) { for (index = 0; index < m_moduleCount; index++) { if (m_resultCountArray[index] == Value) { - QPoint p1((int)rect().x() + (m_moduleCount - drawn - 1)*BAR_DELTAX, - (int)rect().height() + (int)y() - BAR_LOWER_BORDER - (m_moduleCount - drawn)*BAR_DELTAY); + #define S(...) static_cast<int>(__VA_ARGS__) + QPoint p1(S(rect().x()) + (m_moduleCount - drawn - 1)*BAR_DELTAX, + S(rect().height()) + S(y()) - BAR_LOWER_BORDER - (m_moduleCount - drawn)*BAR_DELTAY); QPoint p2(p1.x() + BAR_WIDTH, - p1.y() - (int)( !m_resultCountArray[index] ? 0 : ((m_resultCountArray[index])*(*m_scaleFactor))) ); + p1.y() - S(!m_resultCountArray[index] ? 0 : ((m_resultCountArray[index])*(*m_scaleFactor)))); + #undef S QRect r(p1, p2); painter->fillRect(r, QBrush(CSearchAnalysisScene::getColor(index)) ); painter->drawRect(r); @@ -131,13 +121,13 @@ int CSearchAnalysisItem::width() { /** Returns the tooltip for this item. */ const QString CSearchAnalysisItem::getToolTip() { - typedef CSwordModuleSearch::Results::const_iterator RCI; - using util::htmlEscape; + using RCI = CSwordModuleSearch::Results::const_iterator; QString toolTipString("<center><b>"); - toolTipString.append(htmlEscape(m_bookName)).append("</b></center><hr/>") - .append("<table cellspacing=\"0\" cellpadding=\"3\" width=\"10" - "0%\" height=\"100%\" align=\"center\">"); + toolTipString.append(m_bookName.toHtmlEscaped()) + .append("</b></center><hr/><table cellspacing=\"0\" " + "cellpadding=\"3\" width=\"100%\" height=\"100%\" " + "align=\"center\">"); /// \todo Fix that loop int i = 0; diff --git a/src/frontend/searchdialog/analysis/csearchanalysisitem.h b/src/frontend/searchdialog/analysis/csearchanalysisitem.h index ec2cd03..cb83db9 100644 --- a/src/frontend/searchdialog/analysis/csearchanalysisitem.h +++ b/src/frontend/searchdialog/analysis/csearchanalysisitem.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -51,14 +51,14 @@ class CSearchAnalysisItem : public QGraphicsRectItem { /** * Returns the width of this item. */ - virtual int width(); + int width(); /** * Returns the tooltip for this item. */ const QString getToolTip(); private: - virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*); + void paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*) override; private: /* Fields: */ CSwordModuleSearch::Results m_results; diff --git a/src/frontend/searchdialog/analysis/csearchanalysislegenditem.cpp b/src/frontend/searchdialog/analysis/csearchanalysislegenditem.cpp index e630846..b091710 100644 --- a/src/frontend/searchdialog/analysis/csearchanalysislegenditem.cpp +++ b/src/frontend/searchdialog/analysis/csearchanalysislegenditem.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -18,33 +18,19 @@ namespace Search { -const int SPACE_BETWEEN_PARTS = 5; -const int RIGHT_BORDER = 15; -const int LEFT_BORDER = 15; -const int LOWER_BORDER = 10; -const int UPPER_BORDER = 10; - const int ITEM_TEXT_SIZE = 8; -const int LABEL_TEXT_SIZE = 6; - -//used for the shift between the bars -const int BAR_DELTAX = 4; -const int BAR_DELTAY = 2; -const int BAR_WIDTH = 2 + (2*BAR_DELTAX); //should be equal or bigger than the label font size -// Used for the text below the bars -const int BAR_LOWER_BORDER = 100; const int LEGEND_INNER_BORDER = 5; const int LEGEND_DELTAY = 4; -const int LEGEND_WIDTH = 85; void CSearchAnalysisLegendItem::paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*) { painter->save(); //the outer rectangle - QPoint p1( (int)(rect().x()), (int)(rect().y()) ); - QPoint p2( (int)(rect().x() + rect().width() ), (int)(rect().y() + rect().height())); + #define S(...) static_cast<int>(__VA_ARGS__) + QPoint p1(S(rect().x()), S(rect().y())); + QPoint p2(S(rect().x() + rect().width()), S(rect().y() + rect().height())); QRect r(p1, p2); r = r.normalized(); painter->drawRect(r); @@ -55,9 +41,10 @@ void CSearchAnalysisLegendItem::paint(QPainter* painter, const QStyleOptionGraph // for (unsigned int index=0; index < m_moduleList->count(); index++){ int moduleIndex = 0; - Q_FOREACH(const CSwordModuleInfo *m, m_moduleList) { + Q_FOREACH(CSwordModuleInfo const * const m, m_moduleList) { // the module color indicators - QPoint p1( (int)(rect().x()) + LEGEND_INNER_BORDER, (int)(rect().y()) + LEGEND_INNER_BORDER + moduleIndex*(LEGEND_DELTAY + ITEM_TEXT_SIZE) ); + QPoint p1(S(rect().x()) + LEGEND_INNER_BORDER, S(rect().y()) + LEGEND_INNER_BORDER + moduleIndex*(LEGEND_DELTAY + ITEM_TEXT_SIZE)); + #undef S QPoint p2(p1.x() + ITEM_TEXT_SIZE, p1.y() + ITEM_TEXT_SIZE); QRect r(p1, p2); painter->fillRect(r, QBrush(CSearchAnalysisScene::getColor(moduleIndex)) ); diff --git a/src/frontend/searchdialog/analysis/csearchanalysislegenditem.h b/src/frontend/searchdialog/analysis/csearchanalysislegenditem.h index f199aaf..55378f4 100644 --- a/src/frontend/searchdialog/analysis/csearchanalysislegenditem.h +++ b/src/frontend/searchdialog/analysis/csearchanalysislegenditem.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -14,22 +14,20 @@ #include <QGraphicsRectItem> - -class CSwordModuleInfo; +#include "backend/drivers/btmodulelist.h" namespace Search { class CSearchAnalysisLegendItem : public QGraphicsRectItem { public: /* Methods: */ - inline CSearchAnalysisLegendItem(const QList<const CSwordModuleInfo*> &modules) + inline CSearchAnalysisLegendItem(const BtConstModuleList &modules) : m_moduleList(modules) {} private: /* Methods: */ - /** Reimplementation of QGraphicsItem::paint. */ - virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*); + void paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*) override; private: /* Fields: */ - QList<const CSwordModuleInfo*> m_moduleList; + BtConstModuleList m_moduleList; }; diff --git a/src/frontend/searchdialog/analysis/csearchanalysisscene.cpp b/src/frontend/searchdialog/analysis/csearchanalysisscene.cpp index 9b375e8..5f63cf6 100644 --- a/src/frontend/searchdialog/analysis/csearchanalysisscene.cpp +++ b/src/frontend/searchdialog/analysis/csearchanalysisscene.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -18,9 +18,11 @@ #include "frontend/searchdialog/analysis/csearchanalysisitem.h" #include "frontend/searchdialog/analysis/csearchanalysislegenditem.h" #include "frontend/searchdialog/csearchdialog.h" -#include "util/htmlescape.h" #include "util/tool.h" +// Sword includes +#include <listkey.h> + namespace Search { @@ -31,7 +33,6 @@ const int LOWER_BORDER = 10; const int UPPER_BORDER = 10; const int ITEM_TEXT_SIZE = 8; -const int LABEL_TEXT_SIZE = 6; //used for the shift between the bars const int BAR_DELTAX = 4; @@ -48,7 +49,7 @@ const int LEGEND_WIDTH = 85; CSearchAnalysisScene::CSearchAnalysisScene(QObject *parent ) : QGraphicsScene(parent), m_scaleFactor(0.0), - m_legend(0) { + m_legend(nullptr) { setBackgroundBrush(QBrush(Qt::white)); setSceneRect(0, 0, 1, 1); } @@ -57,7 +58,7 @@ CSearchAnalysisScene::CSearchAnalysisScene(QObject *parent ) void CSearchAnalysisScene::analyse( const CSwordModuleSearch::Results &results) { - typedef CSwordModuleSearch::Results::const_iterator RCI; + using RCI = CSwordModuleSearch::Results::const_iterator; /** * Steps of analysing our search result; @@ -79,11 +80,11 @@ void CSearchAnalysisScene::analyse( LEGEND_WIDTH, LEGEND_INNER_BORDER*2 + ITEM_TEXT_SIZE*numberOfModules + LEGEND_DELTAY*(numberOfModules - 1) ); m_legend->show(); - int xPos = (int)(LEFT_BORDER + m_legend->rect().width() + SPACE_BETWEEN_PARTS); + int xPos = static_cast<int>(LEFT_BORDER + m_legend->rect().width() + SPACE_BETWEEN_PARTS); int moduleIndex = 0; m_maxCount = 0; int count = 0; - CSwordVerseKey key(0); + CSwordVerseKey key(nullptr); key.setKey("Genesis 1:1"); CSearchAnalysisItem* analysisItem = m_itemList[key.book()]; @@ -106,7 +107,7 @@ void CSearchAnalysisScene::analyse( QString tip = analysisItem->getToolTip(); analysisItem->setToolTip(tip); analysisItem->show(); - xPos += (int)analysisItem->width() + SPACE_BETWEEN_PARTS; + xPos += static_cast<int>(analysisItem->width() + SPACE_BETWEEN_PARTS); } ok = key.next(CSwordVerseKey::UseBook); analysisItem = m_itemList[key.book()]; @@ -119,7 +120,7 @@ void CSearchAnalysisScene::analyse( void CSearchAnalysisScene::setResults( const CSwordModuleSearch::Results &results) { - typedef CSwordModuleSearch::Results::const_iterator RCI; + using RCI = CSwordModuleSearch::Results::const_iterator; m_results.clear(); for (RCI it = results.begin(); it != results.end(); ++it) { @@ -130,8 +131,8 @@ void CSearchAnalysisScene::setResults( } m_itemList.clear(); - CSearchAnalysisItem* analysisItem = 0; - CSwordVerseKey key(0); + CSearchAnalysisItem* analysisItem = nullptr; + CSwordVerseKey key(nullptr); key.setKey("Genesis 1:1"); do { analysisItem = new CSearchAnalysisItem(m_results.count(), key.book(), &m_scaleFactor, m_results); @@ -157,15 +158,15 @@ void CSearchAnalysisScene::reset() { if (m_legend) m_legend->hide(); delete m_legend; - m_legend = 0; + m_legend = nullptr; update(); } /** No descriptions */ void CSearchAnalysisScene::slotResized() { - m_scaleFactor = (double)( (double)(height() - UPPER_BORDER - LOWER_BORDER - BAR_LOWER_BORDER - 100 - (m_results.count() - 1) * BAR_DELTAY) - / (double)m_maxCount); + m_scaleFactor = static_cast<double>(height() - UPPER_BORDER - LOWER_BORDER - BAR_LOWER_BORDER - 100 - (m_results.count() - 1) * BAR_DELTAY) + / static_cast<double>(m_maxCount); QHashIterator<QString, CSearchAnalysisItem*> it( m_itemList ); while ( it.hasNext() ) { it.next(); @@ -214,7 +215,7 @@ unsigned int CSearchAnalysisScene::getCount(const QString &book, unsigned int count = 0; const unsigned int resultCount = result.getCount(); while (i < resultCount) { - if (strncmp(book.toUtf8(), (const char *) *result.getElement(i), length)) + if (strncmp(book.toUtf8(), result.getElement(i)->getText(), length)) break; i++; ++count; @@ -224,11 +225,9 @@ unsigned int CSearchAnalysisScene::getCount(const QString &book, } void CSearchAnalysisScene::saveAsHTML() { - using util::htmlEscape; - - typedef CSwordModuleSearch::Results::const_iterator RCI; + using RCI = CSwordModuleSearch::Results::const_iterator; - const QString fileName = QFileDialog::getSaveFileName(0, + const QString fileName = QFileDialog::getSaveFileName(nullptr, tr("Save Search Analysis"), QString::null, tr("XHTML files (*.html *.HTML *.HTM *.htm);;All files (*)")); @@ -258,7 +257,7 @@ void CSearchAnalysisScene::saveAsHTML() { text += "</h1><p><span style=\"font-weight:bold\">"; text += tr("Search text:"); text += "</span> "; - text += htmlEscape(CSearchDialog::getSearchDialog()->searchText()); + text += CSearchDialog::getSearchDialog()->searchText().toHtmlEscaped(); text += "</p><table><caption>"; text += tr("Results by work and book"); text += "</caption><tr><th>"; @@ -267,18 +266,18 @@ void CSearchAnalysisScene::saveAsHTML() { for (RCI it = m_results.begin(); it != m_results.end(); ++it) { text += "<th>"; - text += htmlEscape(it.key()->name()); + text += it.key()->name().toHtmlEscaped(); text += "</th>"; } text += "</tr>"; - CSwordVerseKey key(0); + CSwordVerseKey key(nullptr); key.setKey("Genesis 1:1"); do { text += "<tr><td>"; const QString keyBook(key.book()); - text += htmlEscape(keyBook); + text += keyBook.toHtmlEscaped(); text += "</td>"; int mi = 0; // Module index diff --git a/src/frontend/searchdialog/analysis/csearchanalysisscene.h b/src/frontend/searchdialog/analysis/csearchanalysisscene.h index d1927d5..fde2a0a 100644 --- a/src/frontend/searchdialog/analysis/csearchanalysisscene.h +++ b/src/frontend/searchdialog/analysis/csearchanalysisscene.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -20,9 +20,6 @@ #include "backend/cswordmodulesearch.h" #include "frontend/searchdialog/analysis/csearchanalysisitem.h" -// Sword includes -#include <listkey.h> - class CSwordModuleInfo; diff --git a/src/frontend/searchdialog/analysis/csearchanalysisview.cpp b/src/frontend/searchdialog/analysis/csearchanalysisview.cpp index 277c1a3..479f2bf 100644 --- a/src/frontend/searchdialog/analysis/csearchanalysisview.cpp +++ b/src/frontend/searchdialog/analysis/csearchanalysisview.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -24,26 +24,10 @@ CSearchAnalysisView::CSearchAnalysisView(CSearchAnalysisScene* scene, QWidget* p resize(sizeHint()); } - -/** Returns the sizeHint for this view */ -QSize CSearchAnalysisView::sizeHint() const { - return QGraphicsView::sizeHint(); -} - /** No descriptions */ void CSearchAnalysisView::resizeEvent( QResizeEvent* e) { QGraphicsView::resizeEvent(e); scene()->setSceneRect(0, 0, scene()->sceneRect().width(), viewport()->height() ); } - -/** Returns the item at position p. If there no item at that point return 0. -Is needed? -*/ -//CSearchAnalysisItem* CSearchAnalysisView::itemAt( const QPoint& p ) -//{ -//} - - - } diff --git a/src/frontend/searchdialog/analysis/csearchanalysisview.h b/src/frontend/searchdialog/analysis/csearchanalysisview.h index 4b072f3..97780dc 100644 --- a/src/frontend/searchdialog/analysis/csearchanalysisview.h +++ b/src/frontend/searchdialog/analysis/csearchanalysisview.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -30,23 +30,9 @@ class CSearchAnalysisView : public QGraphicsView { public: CSearchAnalysisView(CSearchAnalysisScene* scene, QWidget* parent); - /** - * Returns the sizeHint for this view - * We give back the size of the parent widgetas default. - * This is a reimplementation from QCanvasView::sizeHint(). - */ - virtual QSize sizeHint() const; - - /** - * Returns the item at position p or 0 if there is no item. - */ - //CSearchAnalysisItem* itemAt( const QPoint& p ); - protected: - /** - * Reimplementation. - */ - virtual void resizeEvent(QResizeEvent* e); + + void resizeEvent(QResizeEvent* e) override; }; diff --git a/src/frontend/searchdialog/btsearchmodulechooserdialog.cpp b/src/frontend/searchdialog/btsearchmodulechooserdialog.cpp index a5bfd2c..661bd09 100644 --- a/src/frontend/searchdialog/btsearchmodulechooserdialog.cpp +++ b/src/frontend/searchdialog/btsearchmodulechooserdialog.cpp @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -16,6 +16,7 @@ #include <QToolButton> #include "backend/bookshelfmodel/btbookshelftreemodel.h" #include "backend/managers/cswordbackend.h" +#include "util/btconnect.h" #include "util/tool.h" @@ -31,8 +32,11 @@ BtSearchModuleChooserDialog::BtSearchModuleChooserDialog(QWidget *parent, BtBookshelfTreeModel::Grouping grouping(groupingOrderKey); BtBookshelfTreeModel *treeModel = new BtBookshelfTreeModel(grouping, this); treeModel->setCheckable(true); - connect(treeModel, SIGNAL(groupingOrderChanged(BtBookshelfTreeModel::Grouping)), - this, SLOT(slotGroupingOrderChanged(const BtBookshelfTreeModel::Grouping&))); + BT_CONNECT(treeModel, + SIGNAL(groupingOrderChanged(BtBookshelfTreeModel::Grouping)), + this, + SLOT(slotGroupingOrderChanged( + BtBookshelfTreeModel::Grouping const &))); // Initialize the bookshelf widget: bookshelfWidget()->showHideAction()->setVisible(false); diff --git a/src/frontend/searchdialog/btsearchmodulechooserdialog.h b/src/frontend/searchdialog/btsearchmodulechooserdialog.h index 79802b5..5b46835 100644 --- a/src/frontend/searchdialog/btsearchmodulechooserdialog.h +++ b/src/frontend/searchdialog/btsearchmodulechooserdialog.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -15,6 +15,7 @@ #include "frontend/btmodulechooserdialog.h" +#include "backend/drivers/btconstmoduleset.h" #include "backend/bookshelfmodel/btbookshelftreemodel.h" @@ -24,15 +25,14 @@ class CSwordModuleInfo; class BtSearchModuleChooserDialog: public BtModuleChooserDialog { Q_OBJECT public: - BtSearchModuleChooserDialog(QWidget *parent = 0, - Qt::WindowFlags flags = 0); - - inline void setCheckedModules(const QSet<CSwordModuleInfo*> &modules) { - bookshelfWidget()->treeModel()->setCheckedModules(modules); - } - inline const QSet<CSwordModuleInfo*> &checkedModules() const { - return bookshelfWidget()->treeModel()->checkedModules(); - } + BtSearchModuleChooserDialog(QWidget *parent = nullptr, + Qt::WindowFlags flags = nullptr); + + inline void setCheckedModules(BtConstModuleSet const & modules) + { bookshelfWidget()->treeModel()->setCheckedModules(modules); } + + inline BtConstModuleSet checkedModules() const + { return bookshelfWidget()->treeModel()->checkedModules(); } protected slots: void slotGroupingOrderChanged(const BtBookshelfTreeModel::Grouping &g); diff --git a/src/frontend/searchdialog/btsearchoptionsarea.cpp b/src/frontend/searchdialog/btsearchoptionsarea.cpp index d850344..ca92d4b 100644 --- a/src/frontend/searchdialog/btsearchoptionsarea.cpp +++ b/src/frontend/searchdialog/btsearchoptionsarea.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -21,13 +21,14 @@ #include "backend/bookshelfmodel/btbookshelftreemodel.h" #include "backend/config/btconfig.h" #include "backend/managers/cswordbackend.h" +#include "backend/drivers/btconstmoduleset.h" #include "backend/drivers/cswordmoduleinfo.h" #include "bibletimeapp.h" #include "frontend/searchdialog/btsearchmodulechooserdialog.h" #include "frontend/searchdialog/btsearchsyntaxhelpdialog.h" #include "frontend/searchdialog/crangechooserdialog.h" +#include "util/btconnect.h" #include "util/cresmgr.h" -#include "util/geticon.h" #include "util/tool.h" @@ -52,14 +53,14 @@ QString BtSearchOptionsArea::searchText() const { return m_searchTextCombo->currentText(); } -BtSearchOptionsArea::SearchType BtSearchOptionsArea::searchType() { +CSwordModuleSearch::SearchType BtSearchOptionsArea::searchType() { if (m_typeAndButton->isChecked()) { - return BtSearchOptionsArea::AndType; + return CSwordModuleSearch::AndType; } if (m_typeOrButton->isChecked()) { - return BtSearchOptionsArea::OrType; + return CSwordModuleSearch::OrType; } - return BtSearchOptionsArea::FullType; + return CSwordModuleSearch::FullType; } void BtSearchOptionsArea::setSearchText(const QString& text) { @@ -102,17 +103,17 @@ void BtSearchOptionsArea::initView() { m_searchButton = new QPushButton(this); m_searchButton->setText(tr("&Search")); - m_searchButton->setIcon(util::getIcon(CResMgr::searchdialog::icon)); + m_searchButton->setIcon(CResMgr::searchdialog::icon()); m_searchButton->setToolTip(tr("Start to search the text in the chosen works")); gridLayout->addWidget(m_searchButton, 0, 2); m_chooseModulesButton = new QPushButton(tr("Ch&oose..."), searchGroupBox); - m_chooseModulesButton->setIcon(util::getIcon(CResMgr::searchdialog::chooseworks_icon)); + m_chooseModulesButton->setIcon(CResMgr::searchdialog::icon_chooseWorks()); m_chooseModulesButton->setToolTip( tr("Choose works for the search")); gridLayout->addWidget(m_chooseModulesButton, 2, 2); m_chooseRangeButton = new QPushButton(tr("S&etup..."), searchGroupBox); - m_chooseRangeButton->setIcon(util::getIcon(CResMgr::searchdialog::setupscope_icon)); + m_chooseRangeButton->setIcon(CResMgr::searchdialog::icon_setupScope()); m_chooseRangeButton->setToolTip(tr("Configure predefined scopes for search")); gridLayout->addWidget(m_chooseRangeButton, 3, 2); @@ -192,26 +193,30 @@ void BtSearchOptionsArea::initView() { } void BtSearchOptionsArea::initConnections() { - QObject::connect( m_searchTextCombo->lineEdit(), SIGNAL(returnPressed ()), - this, SLOT( slotSearchTextEditReturnPressed() ) - ); - connect(m_chooseModulesButton, SIGNAL(clicked()), this, SLOT(chooseModules())); - connect(m_chooseRangeButton, SIGNAL(clicked()), this, SLOT(setupRanges())); - connect(m_modulesCombo, SIGNAL(activated(int)), this, SLOT(moduleListTextSelected(int) ) ); - connect(m_helpLabel, SIGNAL(linkActivated(QString)), this, SLOT(syntaxHelp())); - connect(m_searchTextCombo, SIGNAL(editTextChanged(const QString&)), this, SLOT(slotValidateText(const QString&))); + BT_CONNECT(m_searchTextCombo->lineEdit(), SIGNAL(returnPressed()), + this, SLOT(slotSearchTextEditReturnPressed())); + BT_CONNECT(m_chooseModulesButton, SIGNAL(clicked()), + this, SLOT(chooseModules())); + BT_CONNECT(m_chooseRangeButton, SIGNAL(clicked()), + this, SLOT(setupRanges())); + BT_CONNECT(m_modulesCombo, SIGNAL(activated(int)), + this, SLOT(moduleListTextSelected(int))); + BT_CONNECT(m_helpLabel, SIGNAL(linkActivated(QString)), + this, SLOT(syntaxHelp())); + BT_CONNECT(m_searchTextCombo, SIGNAL(editTextChanged(QString const &)), + this, SLOT(slotValidateText(QString const &))); } /** Sets the modules used by the search. */ -void BtSearchOptionsArea::setModules(const QList<const CSwordModuleInfo*> &modules) { +void BtSearchOptionsArea::setModules(const BtConstModuleList &modules) { QString t; m_modules.clear(); //remove old modules - QList<const CSwordModuleInfo*>::const_iterator end_it = modules.end(); + BtConstModuleList::const_iterator end_it = modules.end(); - for (QList<const CSwordModuleInfo*>::const_iterator it(modules.begin()); it != end_it; ++it) { + for (BtConstModuleList::const_iterator it(modules.begin()); it != end_it; ++it) { /// \todo Check for containsRef compat - if (*it == 0) { //don't operate on null modules. + if (*it == nullptr) { //don't operate on null modules. continue; } qDebug() << "new module:" << (*it)->name(); @@ -251,27 +256,20 @@ void BtSearchOptionsArea::moduleListTextSelected(int index) { //create the module list QString text = m_modulesCombo->itemText(index); QStringList moduleNamesList = text.split(", "); - QList<const CSwordModuleInfo*> moduleList; - foreach(QString name, moduleNamesList) { + BtConstModuleList moduleList; + Q_FOREACH(QString const & name, moduleNamesList) moduleList.append(CSwordBackend::instance()->findModuleByName(name)); - } //set the list and the combobox list and text setModules(moduleList); } void BtSearchOptionsArea::chooseModules() { BtSearchModuleChooserDialog* dlg = new BtSearchModuleChooserDialog(this); - QSet<CSwordModuleInfo*> ms; - Q_FOREACH (const CSwordModuleInfo *module, modules()) { - ms.insert(const_cast<CSwordModuleInfo*>(module)); - } - - dlg->setCheckedModules(ms); + dlg->setCheckedModules(BtConstModuleSet::fromList(modules())); if (dlg->exec() == QDialog::Accepted) { - QList<const CSwordModuleInfo*> ms; - Q_FOREACH(const CSwordModuleInfo *m, dlg->checkedModules()) { + BtConstModuleList ms; + Q_FOREACH(CSwordModuleInfo const * const m, dlg->checkedModules()) ms.append(m); - } setModules(ms); } delete dlg; @@ -284,12 +282,12 @@ void BtSearchOptionsArea::reset() { void BtSearchOptionsArea::saveSettings() { btConfig().setValue("properties/searchTexts", m_searchTextCombo->historyItems()); - SearchType t = FullType; + CSwordModuleSearch::SearchType t = CSwordModuleSearch::FullType; if (m_typeAndButton->isChecked()) { - t = AndType; + t = CSwordModuleSearch::AndType; } if (m_typeOrButton->isChecked()) { - t = OrType; + t = CSwordModuleSearch::OrType; } btConfig().setValue(SearchTypeKey, t); } @@ -302,19 +300,20 @@ void BtSearchOptionsArea::readSettings() { if (text.size() > 0) m_searchTextCombo->addItem(text); } - connect(m_searchTextCombo, SIGNAL(editTextChanged(const QString&)), this, SLOT(slotValidateText(const QString&))); + BT_CONNECT(m_searchTextCombo, SIGNAL(editTextChanged(QString const &)), + this, SLOT(slotValidateText(QString const &))); m_modulesCombo->insertItems(0, btConfig().value<QStringList>("history/searchModuleHistory", QStringList())); for (int i = 0; i < m_modulesCombo->count(); ++i) { m_modulesCombo->setItemData(i, m_modulesCombo->itemText(i), Qt::ToolTipRole); } - int stype = btConfig().value<int>(SearchTypeKey, AndType); + int stype = btConfig().value<int>(SearchTypeKey, CSwordModuleSearch::AndType); switch (stype) { - case AndType: + case CSwordModuleSearch::AndType: m_typeAndButton->setChecked(true); break; - case OrType: + case CSwordModuleSearch::OrType: m_typeOrButton->setChecked(true); break; default: @@ -353,11 +352,12 @@ void BtSearchOptionsArea::refreshRanges() { sword::ListKey BtSearchOptionsArea::searchScope() { if (m_rangeChooserCombo->currentIndex() > 0) { //is not "no scope" - BtConfig::StringMap map = btConfig().getSearchScopesForCurrentLocale(); - QString scope = map[ m_rangeChooserCombo->currentText() ]; - if (!scope.isEmpty()) { - return sword::VerseKey().parseVerseList( (const char*)scope.toUtf8(), "Genesis 1:1", true); - } + QString const scope = btConfig().getSearchScopesForCurrentLocale()[ + m_rangeChooserCombo->currentText()]; + if (!scope.isEmpty()) + return sword::VerseKey().parseVerseList(scope.toUtf8().constData(), + "Genesis 1:1", + true); } return sword::ListKey(); } @@ -416,14 +416,3 @@ void BtSearchOptionsArea::slotValidateText(const QString& /*newText*/) { } // namespace Search -QDataStream &operator<<(QDataStream &out, const Search::BtSearchOptionsArea::SearchType &searchType) { - out << static_cast<qint8>(searchType); - return out; -} - -QDataStream &operator>>(QDataStream &in, Search::BtSearchOptionsArea::SearchType &searchType) { - qint8 i; - in >> i; - searchType = (Search::BtSearchOptionsArea::SearchType) i; - return in; -} diff --git a/src/frontend/searchdialog/btsearchoptionsarea.h b/src/frontend/searchdialog/btsearchoptionsarea.h index a6483ac..9b535be 100644 --- a/src/frontend/searchdialog/btsearchoptionsarea.h +++ b/src/frontend/searchdialog/btsearchoptionsarea.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -14,11 +14,12 @@ #include <QWidget> +#include "backend/cswordmodulesearch.h" +#include "backend/drivers/btmodulelist.h" #include "backend/keys/cswordversekey.h" #include "frontend/searchdialog/chistorycombobox.h" -class CSwordModuleInfo; class QComboBox; class QEvent; class QGridLayout; @@ -35,13 +36,7 @@ class BtSearchOptionsArea : public QWidget { Q_OBJECT public: - enum SearchType { /* Values provided for serialization */ - AndType = 0, - OrType = 1, - FullType = 2 - }; - - BtSearchOptionsArea(QWidget *parent = 0); + BtSearchOptionsArea(QWidget *parent = nullptr); ~BtSearchOptionsArea(); /* * Add text to search combox box history @@ -56,14 +51,14 @@ class BtSearchOptionsArea : public QWidget { */ QString searchText() const; - SearchType searchType(); + CSwordModuleSearch::SearchType searchType(); inline QPushButton * searchButton() const { return m_searchButton; } /** Returns the list of used modules. */ - inline QList<const CSwordModuleInfo*> modules() const { + inline const BtConstModuleList & modules() const { return m_modules; } @@ -93,13 +88,13 @@ class BtSearchOptionsArea : public QWidget { * Reads the settings for the searchdialog from disk. */ void saveSettings(); - bool eventFilter(QObject* obj, QEvent* event); + bool eventFilter(QObject* obj, QEvent* event) override; public slots: /** Sets the modules used by the search. */ - void setModules(const QList<const CSwordModuleInfo*> &modules); + void setModules(const BtConstModuleList &modules); /** Sets the modules when user selects them from the combobox.*/ void moduleListTextSelected(int index); @@ -128,7 +123,7 @@ class BtSearchOptionsArea : public QWidget { void sigStartSearch(); private: - QList<const CSwordModuleInfo*> m_modules; + BtConstModuleList m_modules; QHBoxLayout *hboxLayout; QGroupBox *searchGroupBox; @@ -151,8 +146,5 @@ class BtSearchOptionsArea : public QWidget { } -QDataStream &operator<<(QDataStream &out, const Search::BtSearchOptionsArea::SearchType &searchType); -QDataStream &operator>>(QDataStream &in, Search::BtSearchOptionsArea::SearchType &searchType); -Q_DECLARE_METATYPE(Search::BtSearchOptionsArea::SearchType) #endif diff --git a/src/frontend/searchdialog/btsearchresultarea.cpp b/src/frontend/searchdialog/btsearchresultarea.cpp index 6a82a4f..18b8c2f 100644 --- a/src/frontend/searchdialog/btsearchresultarea.cpp +++ b/src/frontend/searchdialog/btsearchresultarea.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -26,6 +26,8 @@ #include "frontend/searchdialog/cmoduleresultview.h" #include "frontend/searchdialog/csearchdialog.h" #include "frontend/searchdialog/csearchresultview.h" +#include "util/btassert.h" +#include "util/btconnect.h" #include "util/tool.h" @@ -81,17 +83,17 @@ void BtSearchResultArea::initView() { QVBoxLayout* frameLayout = new QVBoxLayout(m_displayFrame); frameLayout->setContentsMargins(0, 0, 0, 0); - m_previewDisplay = new BtHtmlReadDisplay(0, m_displayFrame); + m_previewDisplay = new BtHtmlReadDisplay(nullptr, m_displayFrame); m_previewDisplay->view()->setToolTip(tr("Text of the selected search result item")); frameLayout->addWidget(m_previewDisplay->view()); QAction* selectAllAction = new QAction(QIcon(), tr("Select all"), this); selectAllAction->setShortcut(QKeySequence::SelectAll); - QObject::connect(selectAllAction, SIGNAL(triggered()), this, SLOT(selectAll()) ); + BT_CONNECT(selectAllAction, SIGNAL(triggered()), this, SLOT(selectAll())); QAction* copyAction = new QAction(tr("Copy"), this); copyAction->setShortcut( QKeySequence(Qt::CTRL + Qt::Key_C) ); - QObject::connect(copyAction, SIGNAL(triggered()), this, SLOT(copySelection()) ); + BT_CONNECT(copyAction, SIGNAL(triggered()), this, SLOT(copySelection())); QMenu* menu = new QMenu(); menu->addAction(selectAllAction); @@ -115,7 +117,7 @@ void BtSearchResultArea::setSearchResult( // Pre-select the first module in the list: m_moduleListBox->setCurrentItem(m_moduleListBox->topLevelItem(0), 0); - Q_ASSERT(qobject_cast<CSearchDialog*>(parent()) != 0); + BT_ASSERT(qobject_cast<CSearchDialog *>(parent())); static_cast<CSearchDialog*>(parent())->m_analyseButton->setEnabled(true); } @@ -140,7 +142,7 @@ void BtSearchResultArea::updatePreview(const QString& key) { QString text; CDisplayRendering render; - QList<const CSwordModuleInfo*> modules; + BtConstModuleList modules; modules.append(module); CTextRendering::KeyTreeItem::Settings settings; @@ -151,7 +153,9 @@ void BtSearchResultArea::updatePreview(const QString& key) { vk.setIntros(true); vk.setKey(key); - ((sword::VerseKey*)(module->module()->getKey()))->setIntros(true); //HACK: enable headings for VerseKeys + // HACK: enable headings for VerseKeys: + static_cast<sword::VerseKey *>(module->module().getKey()) + ->setIntros(true); //first go back and then go forward the keys to be in context vk.previous(CSwordVerseKey::UseVerse); @@ -182,7 +186,9 @@ void BtSearchResultArea::updatePreview(const QString& key) { vk.setIntros(true); vk.setKey(key); - ((sword::VerseKey*)(module->module()->getKey()))->setIntros(true); //HACK: enable headings for VerseKeys + // HACK: enable headings for VerseKeys: + static_cast<sword::VerseKey *>(module->module().getKey()) + ->setIntros(true); //include Headings in display, they are indexed and searched too if (vk.getVerse() == 1) { @@ -210,17 +216,23 @@ void BtSearchResultArea::updatePreview(const QString& key) { /** Initializes the signal slot conections of the child widgets, */ void BtSearchResultArea::initConnections() { - connect(m_resultListBox, SIGNAL(keySelected(const QString&)), this, SLOT(updatePreview(const QString&))); - connect(m_resultListBox, SIGNAL(keyDeselected()), this, SLOT(clearPreview())); - connect(m_moduleListBox, - SIGNAL(moduleSelected(const CSwordModuleInfo*, const sword::ListKey&)), - m_resultListBox, - SLOT(setupTree(const CSwordModuleInfo*, const sword::ListKey&))); - connect(m_moduleListBox, SIGNAL(moduleChanged()), m_previewDisplay->connectionsProxy(), SLOT(clear())); + BT_CONNECT(m_resultListBox, SIGNAL(keySelected(QString const &)), + this, SLOT(updatePreview(QString const &))); + BT_CONNECT(m_resultListBox, SIGNAL(keyDeselected()), this, SLOT(clearPreview())); + BT_CONNECT(m_moduleListBox, + SIGNAL(moduleSelected(CSwordModuleInfo const *, + sword::ListKey const &)), + m_resultListBox, + SLOT(setupTree(CSwordModuleInfo const *, + sword::ListKey const &))); + BT_CONNECT(m_moduleListBox, SIGNAL(moduleChanged()), + m_previewDisplay->connectionsProxy(), SLOT(clear())); // connect the strongs list - connect(m_moduleListBox, SIGNAL(strongsSelected(CSwordModuleInfo*, const QStringList&)), - m_resultListBox, SLOT(setupStrongsTree(CSwordModuleInfo*, const QStringList&))); + BT_CONNECT(m_moduleListBox, + SIGNAL(strongsSelected(CSwordModuleInfo *, QStringList const &)), + m_resultListBox, + SLOT(setupStrongsTree(CSwordModuleInfo *, QStringList const &))); } /** @@ -266,14 +278,14 @@ StrongsResultList::StrongsResultList(const CSwordModuleInfo *module, return; CTextRendering::KeyTreeItem::Settings settings; - QList<const CSwordModuleInfo*> modules; + BtConstModuleList modules; modules.append(module); clear(); // for whatever reason the text "Parsing...translations." does not appear. // this is not critical but the text is necessary to get the dialog box // to be wide enough. - QProgressDialog progress(QObject::tr("Parsing Strong's Numbers"), 0, 0, count); + QProgressDialog progress(QObject::tr("Parsing Strong's Numbers"), nullptr, 0, count); //0, "progressDialog", tr("Parsing Strong's Numbers"), tr("Parsing Strong's numbers for translations."), true); //progress->setAllowCancel(false); //progress->setMinimumDuration(0); diff --git a/src/frontend/searchdialog/btsearchresultarea.h b/src/frontend/searchdialog/btsearchresultarea.h index e7a167d..4c0284d 100644 --- a/src/frontend/searchdialog/btsearchresultarea.h +++ b/src/frontend/searchdialog/btsearchresultarea.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -95,7 +95,7 @@ class StrongsResultList: public QList<StrongsResult> { class BtSearchResultArea : public QWidget { Q_OBJECT public: /* Methods: */ - BtSearchResultArea(QWidget *parent = 0); + BtSearchResultArea(QWidget *parent = nullptr); inline ~BtSearchResultArea() { saveDialogSettings(); } /** @@ -104,17 +104,11 @@ class BtSearchResultArea : public QWidget { void setSearchResult( const CSwordModuleSearch::Results &results); - /** - Reimplemented from QWidget::sizeHint(). - */ - virtual QSize sizeHint() const { + QSize sizeHint() const override { return baseSize(); } - /** - Reimplemented from QWidget::minimumSizeHint(). - */ - virtual QSize minimumSizeHint() const { + QSize minimumSizeHint() const override { return minimumSize(); } diff --git a/src/frontend/searchdialog/btsearchsyntaxhelpdialog.cpp b/src/frontend/searchdialog/btsearchsyntaxhelpdialog.cpp index f1acddc..27a1fa3 100644 --- a/src/frontend/searchdialog/btsearchsyntaxhelpdialog.cpp +++ b/src/frontend/searchdialog/btsearchsyntaxhelpdialog.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -12,9 +12,9 @@ #include <QDesktopServices> #include <QDialogButtonBox> #include <QVBoxLayout> -#include <QWebView> +#include <frontend/btwebengineview.h> #include "frontend/messagedialog.h" -#include "util/directory.h" +#include "util/btconnect.h" namespace Search { @@ -26,14 +26,13 @@ BtSearchSyntaxHelpDialog::BtSearchSyntaxHelpDialog(QWidget *parent, Qt::WindowFl QVBoxLayout *l = new QVBoxLayout; - m_webView = new QWebView(this); - m_webView->page()->setLinkDelegationPolicy(QWebPage::DelegateExternalLinks); - connect(m_webView, SIGNAL(linkClicked(QUrl)), - this, SLOT(linkClicked(QUrl))); + m_webView = new BtWebEngineView(this); + BT_CONNECT(m_webView->btPage(), SIGNAL(linkClicked(QUrl)), + this, SLOT(linkClicked(QUrl))); l->addWidget(m_webView); m_buttons = new QDialogButtonBox(QDialogButtonBox::Close, Qt::Horizontal, this); - connect(m_buttons, SIGNAL(rejected()), this, SLOT(reject())); + BT_CONNECT(m_buttons, SIGNAL(rejected()), this, SLOT(reject())); l->addWidget(m_buttons); setLayout(l); @@ -42,8 +41,6 @@ BtSearchSyntaxHelpDialog::BtSearchSyntaxHelpDialog(QWidget *parent, Qt::WindowFl } void BtSearchSyntaxHelpDialog::retranslateUi() { - namespace DU = util::directory; - QString theTitle(tr("Search Syntax Help")); setWindowTitle(theTitle); @@ -212,7 +209,7 @@ void BtSearchSyntaxHelpDialog::retranslateUi() { .arg("http://lucene.apache.org/java/1_4_3/queryparsersyntax.html"); html += "</p></body></html>"; - m_webView->setHtml(html, QUrl::fromLocalFile(DU::getIconDir().path())); + m_webView->setHtml(html); message::prepareDialogBox(m_buttons); } diff --git a/src/frontend/searchdialog/btsearchsyntaxhelpdialog.h b/src/frontend/searchdialog/btsearchsyntaxhelpdialog.h index 74b74b5..f7aab44 100644 --- a/src/frontend/searchdialog/btsearchsyntaxhelpdialog.h +++ b/src/frontend/searchdialog/btsearchsyntaxhelpdialog.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -16,14 +16,14 @@ class QDialogButtonBox; class QUrl; -class QWebView; +class BtWebEngineView; namespace Search { class BtSearchSyntaxHelpDialog: public QDialog { Q_OBJECT public: - BtSearchSyntaxHelpDialog(QWidget *parent = 0, Qt::WindowFlags wflags = Qt::Dialog); + BtSearchSyntaxHelpDialog(QWidget *parent = nullptr, Qt::WindowFlags wflags = Qt::Dialog); protected: void retranslateUi(); @@ -32,7 +32,7 @@ class BtSearchSyntaxHelpDialog: public QDialog { void linkClicked(const QUrl &url); private: - QWebView *m_webView; + BtWebEngineView *m_webView; QDialogButtonBox *m_buttons; }; diff --git a/src/frontend/searchdialog/chistorycombobox.cpp b/src/frontend/searchdialog/chistorycombobox.cpp index 231bd65..403e743 100644 --- a/src/frontend/searchdialog/chistorycombobox.cpp +++ b/src/frontend/searchdialog/chistorycombobox.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ diff --git a/src/frontend/searchdialog/chistorycombobox.h b/src/frontend/searchdialog/chistorycombobox.h index 922b042..136f9ac 100644 --- a/src/frontend/searchdialog/chistorycombobox.h +++ b/src/frontend/searchdialog/chistorycombobox.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -20,7 +20,7 @@ namespace Search { class CHistoryComboBox : public QComboBox { Q_OBJECT public: - CHistoryComboBox(QWidget* parent = 0); + CHistoryComboBox(QWidget* parent = nullptr); ~CHistoryComboBox(); void addToHistory(const QString& item); QStringList historyItems() const; diff --git a/src/frontend/searchdialog/cmoduleresultview.cpp b/src/frontend/searchdialog/cmoduleresultview.cpp index 5bbc32f..4924949 100644 --- a/src/frontend/searchdialog/cmoduleresultview.cpp +++ b/src/frontend/searchdialog/cmoduleresultview.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -16,14 +16,14 @@ #include <QStringList> #include <QTreeWidget> #include <QtAlgorithms> - +#include "backend/config/btconfig.h" #include "backend/drivers/cswordmoduleinfo.h" #include "bibletimeapp.h" #include "frontend/cexportmanager.h" +#include "util/btassert.h" +#include "util/btconnect.h" #include "util/cresmgr.h" -#include "util/geticon.h" #include "util/tool.h" -#include "backend/config/btconfig.h" namespace Search { @@ -62,29 +62,34 @@ void CModuleResultView::initView() { m_popup = new QMenu(this); m_actions.copyMenu = new QMenu(tr("Copy..."), m_popup); - m_actions.copyMenu->setIcon(util::getIcon( CResMgr::searchdialog::result::moduleList::copyMenu::icon) ); + m_actions.copyMenu->setIcon(CResMgr::searchdialog::result::moduleList::copyMenu::icon()); m_actions.copy.result = new QAction(tr("Reference only"), this); - QObject::connect(m_actions.copy.result, SIGNAL(triggered()), this, SLOT(copyResult()) ); + BT_CONNECT(m_actions.copy.result, SIGNAL(triggered()), + this, SLOT(copyResult())); m_actions.copyMenu->addAction(m_actions.copy.result); m_actions.copy.resultWithText = new QAction(tr("Reference with text"), this); - QObject::connect(m_actions.copy.resultWithText, SIGNAL(triggered()), this, SLOT(copyResultWithText()) ); + BT_CONNECT(m_actions.copy.resultWithText, SIGNAL(triggered()), + this, SLOT(copyResultWithText())); m_actions.copyMenu->addAction(m_actions.copy.resultWithText); m_popup->addMenu(m_actions.copyMenu); m_actions.saveMenu = new QMenu(tr("Save..."), m_popup); - m_actions.saveMenu->setIcon(util::getIcon( CResMgr::searchdialog::result::moduleList::saveMenu::icon) ); + m_actions.saveMenu->setIcon(CResMgr::searchdialog::result::moduleList::saveMenu::icon()); m_actions.save.result = new QAction(tr("Reference only"), this); - QObject::connect(m_actions.save.result, SIGNAL(triggered()), this, SLOT(saveResult()) ); + BT_CONNECT(m_actions.save.result, SIGNAL(triggered()), + this, SLOT(saveResult())); m_actions.saveMenu->addAction(m_actions.save.result); m_actions.save.resultWithText = new QAction(tr("Reference with text"), this); - QObject::connect(m_actions.save.resultWithText, SIGNAL(triggered()), this, SLOT(saveResultWithText()) ); + BT_CONNECT(m_actions.save.resultWithText, SIGNAL(triggered()), + this, SLOT(saveResultWithText())); m_actions.saveMenu->addAction(m_actions.save.resultWithText); m_popup->addMenu(m_actions.saveMenu); m_actions.printMenu = new QMenu(tr("Print..."), m_popup); - m_actions.printMenu->setIcon(util::getIcon(CResMgr::searchdialog::result::moduleList::printMenu::icon)); + m_actions.printMenu->setIcon(CResMgr::searchdialog::result::moduleList::printMenu::icon()); m_actions.print.result = new QAction(tr("Reference with text"), this); - QObject::connect(m_actions.print.result, SIGNAL(triggered()), this, SLOT(printResult()) ); + BT_CONNECT(m_actions.print.result, SIGNAL(triggered()), + this, SLOT(printResult())); m_actions.printMenu->addAction(m_actions.print.result); m_popup->addMenu(m_actions.printMenu); } @@ -92,8 +97,10 @@ void CModuleResultView::initView() { /** Initializes the connections of this widget, */ void CModuleResultView::initConnections() { /// \todo - connect(this, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)), - this, SLOT(executed(QTreeWidgetItem*, QTreeWidgetItem*))); + BT_CONNECT(this, + SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)), + this, + SLOT(executed(QTreeWidgetItem *, QTreeWidgetItem *))); } void CModuleResultView::setupTree(const CSwordModuleSearch::Results & results, @@ -111,11 +118,11 @@ void CModuleResultView::setupTree(const CSwordModuleSearch::Results & results, bool strongsAvailable = false; Q_FOREACH(const CSwordModuleInfo * m, results.keys()) { - /// \todo Remove this constructor hack once sword gets it right: - const int count = sword::ListKey(results.value(m)).getCount(); - QTreeWidgetItem * item = new QTreeWidgetItem(this, - QStringList(m->name()) - << QString::number(count)); + QTreeWidgetItem * const item = + new QTreeWidgetItem(this, + QStringList(m->name()) + << QString::number( + results.value(m).getCount())); item->setIcon(0, util::tool::getIconForModule(m)); /* @@ -198,24 +205,15 @@ void CModuleResultView::executed( QTreeWidgetItem* i, QTreeWidgetItem*) { /** Returns the currently active module. */ CSwordModuleInfo* CModuleResultView::activeModule() { - Q_ASSERT(currentItem()); - - QTreeWidgetItem* item = currentItem(); - if (!item) { - return 0; - } + QTreeWidgetItem * item = currentItem(); + BT_ASSERT(item); // we need to find the parent most node because that is the node // that is the module name. - while (item->parent()) { + while (item->parent()) item = item->parent(); - } - - if (item) { - return CSwordBackend::instance()->findModuleByName(item->text(0)); - } - return 0; + return CSwordBackend::instance()->findModuleByName(item->text(0)); } /** Reimplementation from QWidget. */ @@ -227,7 +225,7 @@ void CModuleResultView::contextMenuEvent( QContextMenuEvent * event ) { /** Copies the whole search result into the clipboard. */ void CModuleResultView::copyResult() { CSwordModuleInfo *m = activeModule(); - if (m != 0) { + if (m != nullptr) { CExportManager mgr(true, tr("Copying search result")); mgr.copyKeyList(m_results[m], m, CExportManager::Text, false); @@ -237,7 +235,7 @@ void CModuleResultView::copyResult() { /** Copies the whole search result with the text into the clipboard. */ void CModuleResultView::copyResultWithText() { CSwordModuleInfo *m = activeModule(); - if (m != 0) { + if (m != nullptr) { CExportManager mgr(true, tr("Copying search result")); mgr.copyKeyList(m_results[m], m, CExportManager::Text, true); }; @@ -246,7 +244,7 @@ void CModuleResultView::copyResultWithText() { /** Saves the search result keys. */ void CModuleResultView::saveResult() { CSwordModuleInfo *m = activeModule(); - if (m != 0) { + if (m != nullptr) { CExportManager mgr(true, tr("Saving search result")); mgr.saveKeyList(m_results[m], m, CExportManager::Text, false); }; @@ -255,7 +253,7 @@ void CModuleResultView::saveResult() { /** Saves the search result with it's text. */ void CModuleResultView::saveResultWithText() { CSwordModuleInfo *m = activeModule(); - if (m != 0) { + if (m != nullptr) { CExportManager mgr(true, tr("Saving search result")); mgr.saveKeyList(m_results[m], m, CExportManager::Text, true); }; @@ -264,7 +262,7 @@ void CModuleResultView::saveResultWithText() { /** Appends the whole search result to the printer queue. */ void CModuleResultView::printResult() { CSwordModuleInfo *m = activeModule(); - if (m != 0) { + if (m != nullptr) { CExportManager mgr(true, tr("Printing search result")); mgr.printKeyList(m_results[m], m, btConfig().getDisplayOptions(), btConfig().getFilterOptions()); diff --git a/src/frontend/searchdialog/cmoduleresultview.h b/src/frontend/searchdialog/cmoduleresultview.h index 24571d9..6a69a65 100644 --- a/src/frontend/searchdialog/cmoduleresultview.h +++ b/src/frontend/searchdialog/cmoduleresultview.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -45,7 +45,7 @@ class CModuleResultView : public QTreeWidget { */ CSwordModuleInfo* activeModule(); - virtual QSize sizeHint() const { + QSize sizeHint() const override { return m_size; } @@ -81,7 +81,7 @@ class CModuleResultView : public QTreeWidget { /** * This event handler (reimplemented from QWidget) opens the popup menu at the given position. */ - void contextMenuEvent( QContextMenuEvent * event ); + void contextMenuEvent( QContextMenuEvent * event ) override; /** * Appends the whole search result to the printer queue. */ diff --git a/src/frontend/searchdialog/crangechooserdialog.cpp b/src/frontend/searchdialog/crangechooserdialog.cpp index efece49..99bbe42 100644 --- a/src/frontend/searchdialog/crangechooserdialog.cpp +++ b/src/frontend/searchdialog/crangechooserdialog.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -21,6 +21,8 @@ #include <QVBoxLayout> #include "backend/config/btconfig.h" #include "frontend/messagedialog.h" +#include "util/btassert.h" +#include "util/btconnect.h" // Sword includes: #include "versekey.h" @@ -107,27 +109,27 @@ void CRangeChooserDialog::initView() { } void CRangeChooserDialog::initConnections() { - connect(m_rangeList, SIGNAL(currentItemChanged(QListWidgetItem*, - QListWidgetItem*)), - this, SLOT(selectedRangeChanged(QListWidgetItem*, - QListWidgetItem*))); - connect(m_nameEdit, SIGNAL(textEdited(QString)), - this, SLOT(nameEditTextChanged(QString))); - connect(m_rangeEdit, SIGNAL(textChanged()), - this, SLOT(updateResultList())); + BT_CONNECT(m_rangeList, SIGNAL(currentItemChanged(QListWidgetItem *, + QListWidgetItem *)), + this, SLOT(selectedRangeChanged(QListWidgetItem *, + QListWidgetItem *))); + BT_CONNECT(m_nameEdit, SIGNAL(textEdited(QString)), + this, SLOT(nameEditTextChanged(QString))); + BT_CONNECT(m_rangeEdit, SIGNAL(textChanged()), + this, SLOT(updateResultList())); // Connect buttons: - connect(m_buttonBox, SIGNAL(accepted()), - this, SLOT(accept())); - connect(m_buttonBox, SIGNAL(rejected()), - this, SLOT(reject())); - connect(m_newRangeButton, SIGNAL(clicked()), - this, SLOT(addNewRange())); - connect(m_deleteRangeButton, SIGNAL(clicked()), - this, SLOT(deleteCurrentRange())); + BT_CONNECT(m_buttonBox, SIGNAL(accepted()), + this, SLOT(accept())); + BT_CONNECT(m_buttonBox, SIGNAL(rejected()), + this, SLOT(reject())); + BT_CONNECT(m_newRangeButton, SIGNAL(clicked()), + this, SLOT(addNewRange())); + BT_CONNECT(m_deleteRangeButton, SIGNAL(clicked()), + this, SLOT(deleteCurrentRange())); QPushButton * defaultsButton = m_buttonBox->button(QDialogButtonBox::RestoreDefaults); - connect(defaultsButton, SIGNAL(clicked()), - this, SLOT(restoreDefaults())); + BT_CONNECT(defaultsButton, SIGNAL(clicked()), + this, SLOT(restoreDefaults())); } void CRangeChooserDialog::retranslateUi() { @@ -178,7 +180,7 @@ void CRangeChooserDialog::selectedRangeChanged(QListWidgetItem * current, { Q_UNUSED(current); if (previous) { - Q_ASSERT(dynamic_cast<RangeItem*>(previous) != 0); + BT_ASSERT(dynamic_cast<RangeItem *>(previous)); saveCurrentToRange(static_cast<RangeItem*>(previous)); } @@ -187,30 +189,29 @@ void CRangeChooserDialog::selectedRangeChanged(QListWidgetItem * current, void CRangeChooserDialog::resetEditControls() { const QListWidgetItem * const item = m_rangeList->currentItem(); - Q_ASSERT(item == 0 || dynamic_cast<const RangeItem *>(item) != 0); + BT_ASSERT(!item || dynamic_cast<RangeItem const *>(item)); const RangeItem * rangeItem = static_cast<const RangeItem *>(item); - m_nameEdit->setEnabled(item != 0); - m_rangeEdit->setEnabled(item != 0); - m_resultList->setEnabled(item != 0); - m_deleteRangeButton->setEnabled(item != 0); - m_nameEdit->setText(item != 0 ? rangeItem->caption() : ""); - m_rangeEdit->setText(item != 0 ? rangeItem->range() : ""); + m_nameEdit->setEnabled(item != nullptr); + m_rangeEdit->setEnabled(item != nullptr); + m_resultList->setEnabled(item != nullptr); + m_deleteRangeButton->setEnabled(item != nullptr); + m_nameEdit->setText(item != nullptr ? rangeItem->caption() : ""); + m_rangeEdit->setText(item != nullptr ? rangeItem->range() : ""); - if (item != 0) + if (item != nullptr) m_nameEdit->setFocus(); - nameEditTextChanged(item != 0 ? rangeItem->caption() : ""); + nameEditTextChanged(item != nullptr ? rangeItem->caption() : ""); } void CRangeChooserDialog::updateResultList() { - typedef sword::VerseKey VK; + using VK = sword::VerseKey; m_resultList->clear(); - /// \todo remove this hack: - //HACK: repair range to work with Sword 1.5.6 - const QString range = m_rangeEdit->toPlainText().replace(QRegExp("\\s{0,}-\\s{0,}"), "-"); + QString const range = + m_rangeEdit->toPlainText().replace(QRegExp("\\s{0,}-\\s{0,}"), "-"); sword::ListKey verses = VK().parseVerseList(range.toUtf8().constData(), "Genesis 1:1", true); @@ -221,7 +222,7 @@ void CRangeChooserDialog::updateResultList() { } void CRangeChooserDialog::deleteCurrentRange() { - Q_ASSERT(dynamic_cast<RangeItem*>(m_rangeList->currentItem()) != 0); + BT_ASSERT(dynamic_cast<RangeItem *>(m_rangeList->currentItem())); QListWidgetItem *i = m_rangeList->currentItem(); m_rangeList->removeItemWidget(i); delete i; @@ -232,8 +233,8 @@ void CRangeChooserDialog::deleteCurrentRange() { void CRangeChooserDialog::accept() { // Update the active item: QListWidgetItem *currentItem = m_rangeList->currentItem(); - if (currentItem != 0) { - Q_ASSERT(dynamic_cast<RangeItem*>(currentItem) != 0); + if (currentItem != nullptr) { + BT_ASSERT(dynamic_cast<RangeItem *>(currentItem)); saveCurrentToRange(static_cast<RangeItem*>(currentItem)); } @@ -241,7 +242,7 @@ void CRangeChooserDialog::accept() { m_rangeList->sortItems(); BtConfig::StringMap map; for (int i = 0; i < m_rangeList->count(); i++) { - Q_ASSERT(dynamic_cast<RangeItem*>(m_rangeList->item(i)) != 0); + BT_ASSERT(dynamic_cast<RangeItem *>(m_rangeList->item(i))); const RangeItem * item = static_cast<RangeItem*>(m_rangeList->item(i)); map[item->caption()] = item->range(); } @@ -251,7 +252,7 @@ void CRangeChooserDialog::accept() { } void CRangeChooserDialog::restoreDefaults() { - typedef BtConfig::StringMap::ConstIterator SMCI; + using SMCI = BtConfig::StringMap::ConstIterator; m_rangeList->clear(); btConfig().deleteSearchScopesWithCurrentLocale(); @@ -259,7 +260,7 @@ void CRangeChooserDialog::restoreDefaults() { for (SMCI it = map.begin(); it != map.end(); ++it) { new RangeItem(it.key(), it.value(), m_rangeList); }; - m_rangeList->setCurrentItem(0); + m_rangeList->setCurrentItem(nullptr); resetEditControls(); } diff --git a/src/frontend/searchdialog/crangechooserdialog.h b/src/frontend/searchdialog/crangechooserdialog.h index a9cbaf4..c608c63 100644 --- a/src/frontend/searchdialog/crangechooserdialog.h +++ b/src/frontend/searchdialog/crangechooserdialog.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -39,7 +39,7 @@ private: /* Types: */ inline RangeItem(const QString &caption, const QString &range = QString::null, - QListWidget * parent = 0) + QListWidget * parent = nullptr) : QListWidgetItem(caption, parent) , m_range(range) {} @@ -56,9 +56,9 @@ private: /* Types: */ public: /* Methods: */ - CRangeChooserDialog(QWidget *parentDialog = 0); + CRangeChooserDialog(QWidget *parentDialog = nullptr); - virtual void accept(); + void accept() override; private: /* Methods: */ diff --git a/src/frontend/searchdialog/csearchdialog.cpp b/src/frontend/searchdialog/csearchdialog.cpp index 54981e3..ccefe9f 100644 --- a/src/frontend/searchdialog/csearchdialog.cpp +++ b/src/frontend/searchdialog/csearchdialog.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -19,7 +19,6 @@ #include <QRegExp> #include <QVBoxLayout> #include <QWidget> - #include "backend/config/btconfig.h" #include "backend/cswordmodulesearch.h" #include "backend/keys/cswordkey.h" @@ -29,8 +28,9 @@ #include "frontend/searchdialog/btsearchoptionsarea.h" #include "frontend/searchdialog/btsearchresultarea.h" #include "frontend/messagedialog.h" +#include "util/btassert.h" +#include "util/btconnect.h" #include "util/cresmgr.h" -#include "util/geticon.h" namespace { @@ -39,9 +39,9 @@ const QString GeometryKey = "GUI/SearchDialog/geometry"; namespace Search { -static CSearchDialog* m_staticDialog = 0; +static CSearchDialog* m_staticDialog = nullptr; -void CSearchDialog::openDialog(const QList<const CSwordModuleInfo*> modules, +void CSearchDialog::openDialog(const BtConstModuleList modules, const QString &searchText, QWidget *parentDialog) { if (!m_staticDialog) { @@ -71,19 +71,19 @@ void CSearchDialog::openDialog(const QList<const CSwordModuleInfo*> modules, } void CSearchDialog::closeDialog() { - if (m_staticDialog != 0) + if (m_staticDialog != nullptr) m_staticDialog->closeButtonClicked(); } CSearchDialog* CSearchDialog::getSearchDialog() { - Q_ASSERT(m_staticDialog); + BT_ASSERT(m_staticDialog); return m_staticDialog; } CSearchDialog::CSearchDialog(QWidget *parent) - : QDialog(parent), /*m_searchButton(0),*/ m_closeButton(0), - m_searchResultArea(0), m_searchOptionsArea(0) { - setWindowIcon(util::getIcon(CResMgr::searchdialog::icon)); + : QDialog(parent), /*m_searchButton(0),*/ m_closeButton(nullptr), + m_searchResultArea(nullptr), m_searchOptionsArea(nullptr) { + setWindowIcon(CResMgr::searchdialog::icon()); setWindowTitle(tr("Search")); setAttribute(Qt::WA_DeleteOnClose); @@ -93,11 +93,10 @@ CSearchDialog::CSearchDialog(QWidget *parent) CSearchDialog::~CSearchDialog() { saveDialogSettings(); - m_staticDialog = 0; + m_staticDialog = nullptr; } void CSearchDialog::startSearch() { - typedef QList<const CSwordModuleInfo*> ML; QString originalSearchText(m_searchOptionsArea->searchText()); // first check the search string for errors @@ -108,13 +107,19 @@ void CSearchDialog::startSearch() { return; } } - QString searchText = prepareSearchText(originalSearchText); + QString searchText = CSwordModuleSearch::prepareSearchText(originalSearchText, m_searchOptionsArea->searchType()); // Insert search text into history list of combobox m_searchOptionsArea->addToHistory(originalSearchText); // Check that we have the indices we need for searching - ML unindexedModules = CSwordModuleSearch::unindexedModules(modules()); + /// \warning indexing is some kind of internal optimization, so we leave + /// modules const, but unconst them here only + QList<CSwordModuleInfo*> unindexedModules; + Q_FOREACH(const CSwordModuleInfo * const m, + CSwordModuleSearch::unindexedModules(modules())) + unindexedModules.append(const_cast<CSwordModuleInfo*>(m)); + if (unindexedModules.size() > 0) { // Build the list of module names: QStringList moduleNameList; @@ -160,10 +165,21 @@ void CSearchDialog::startSearch() { setCursor(Qt::WaitCursor); // Execute search: - m_searcher.startSearch(); + try { + m_searcher.startSearch(); + } catch (...) { + message::showWarning(this, + tr("Search aborted"), + tr("An internal error occurred while executing " + "your search.")); + // Re-enable the dialog: + setEnabled(true); + setCursor(Qt::ArrowCursor); + return; + } // Display the search results: - if (m_searcher.foundItems() > 0) { + if (m_searcher.foundItems() > 0u) { m_searchResultArea->setSearchResult(m_searcher.results()); } else { m_searchResultArea->reset(); @@ -176,35 +192,7 @@ void CSearchDialog::startSearch() { setCursor(Qt::ArrowCursor); } -QString CSearchDialog::prepareSearchText(const QString& orig) { - qDebug() << "Original search text:" << orig; - static const QRegExp syntaxCharacters("[+\\-()!\"~]"); - static const QRegExp andWords("\\band\\b", Qt::CaseInsensitive); - static const QRegExp orWords("\\bor\\b", Qt::CaseInsensitive); - QString text(""); - if (m_searchOptionsArea->searchType() == BtSearchOptionsArea::AndType) { - text = orig.simplified(); - text.remove(syntaxCharacters); - qDebug() << "After syntax characters removed:" << text; - text.replace(andWords, "\"and\""); - text.replace(orWords, "\"or\""); - qDebug() << "After \"and\" and \"or\" replaced:" << text; - text.replace(" ", " AND "); - } - if (m_searchOptionsArea->searchType() == BtSearchOptionsArea::OrType) { - text = orig.simplified(); - text.remove(syntaxCharacters); - text.replace(andWords, "\"and\""); - text.replace(orWords, "\"or\""); - } - if (m_searchOptionsArea->searchType() == BtSearchOptionsArea::FullType) { - text = orig; - } - qDebug() << "The final search string:" << text; - return text; -} - -void CSearchDialog::startSearch(const QList<const CSwordModuleInfo*> modules, +void CSearchDialog::startSearch(const BtConstModuleList modules, const QString &searchText) { m_searchResultArea->reset(); @@ -238,7 +226,7 @@ void CSearchDialog::initView() { QHBoxLayout* horizontalLayout = new QHBoxLayout(); - m_analyseButton = new QPushButton(tr("&Analyze results..."), 0); + m_analyseButton = new QPushButton(tr("&Analyze results..."), nullptr); m_analyseButton->setToolTip(tr("Show a graphical analysis of the search result")); QSpacerItem* spacerItem = new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout->addWidget(m_analyseButton); @@ -246,7 +234,7 @@ void CSearchDialog::initView() { m_closeButton = new QPushButton(this); m_closeButton->setText(tr("&Close")); - m_closeButton->setIcon(util::getIcon(CResMgr::searchdialog::close_icon)); + m_closeButton->setIcon(CResMgr::searchdialog::icon_close()); horizontalLayout->addWidget(m_closeButton); verticalLayout->addLayout(horizontalLayout); @@ -261,15 +249,16 @@ void CSearchDialog::showModulesSelector() { /** Initializes the signal slot connections */ void CSearchDialog::initConnections() { // Search button is clicked - bool ok = connect(m_searchOptionsArea->searchButton(), SIGNAL(clicked()), this, SLOT(startSearch())); - Q_ASSERT(ok); + BT_CONNECT(m_searchOptionsArea->searchButton(), SIGNAL(clicked()), + this, SLOT(startSearch())); // Return/Enter is pressed in the search text field - ok = connect(m_searchOptionsArea, SIGNAL(sigStartSearch()), this, SLOT(startSearch()) ); - Q_ASSERT(ok); - ok = connect(m_closeButton, SIGNAL(clicked()), this, SLOT(closeButtonClicked())); - Q_ASSERT(ok); + BT_CONNECT(m_searchOptionsArea, SIGNAL(sigStartSearch()), + this, SLOT(startSearch()) ); + BT_CONNECT(m_closeButton, SIGNAL(clicked()), + this, SLOT(closeButtonClicked())); - connect(m_analyseButton, SIGNAL(clicked()), m_searchResultArea, SLOT(showAnalysis())); + BT_CONNECT(m_analyseButton, SIGNAL(clicked()), + m_searchResultArea, SLOT(showAnalysis())); } diff --git a/src/frontend/searchdialog/csearchdialog.h b/src/frontend/searchdialog/csearchdialog.h index dde8537..c0153fa 100644 --- a/src/frontend/searchdialog/csearchdialog.h +++ b/src/frontend/searchdialog/csearchdialog.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -33,9 +33,9 @@ namespace Search { class CSearchDialog : public QDialog { Q_OBJECT public: - static void openDialog(const QList<const CSwordModuleInfo*> modules, + static void openDialog(const BtConstModuleList modules, const QString &searchText = QString::null, - QWidget *parentDialog = 0); + QWidget *parentDialog = nullptr); static void closeDialog(); @@ -60,23 +60,20 @@ class CSearchDialog : public QDialog { /** Starts the search with the given module list and given search text. */ - void startSearch(const QList<const CSwordModuleInfo*> modules, + void startSearch(const BtConstModuleList modules, const QString &searchText); - /**Prepares the search string given by user for a specific search type */ - QString prepareSearchText(const QString& orig); - /** Sets the list of modules for the search. */ - void setModules(const QList<const CSwordModuleInfo*> modules) { + void setModules(const BtConstModuleList modules) { m_searchOptionsArea->setModules(modules); } /** Returns the list of used modules. */ - inline QList<const CSwordModuleInfo*> modules() const { + inline BtConstModuleList modules() const { return m_searchOptionsArea->modules(); } diff --git a/src/frontend/searchdialog/csearchresultview.cpp b/src/frontend/searchdialog/csearchresultview.cpp index c08e5cc..f5d6ff0 100644 --- a/src/frontend/searchdialog/csearchresultview.cpp +++ b/src/frontend/searchdialog/csearchresultview.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -15,20 +15,20 @@ #include <QTreeWidget> #include <QTreeWidgetItem> #include <QWidget> +#include "backend/config/btconfig.h" #include "backend/keys/cswordversekey.h" #include "bibletimeapp.h" #include "frontend/cdragdrop.h" #include "frontend/cexportmanager.h" +#include "util/btconnect.h" #include "util/cresmgr.h" -#include "util/geticon.h" -#include "backend/config/btconfig.h" namespace Search { CSearchResultView::CSearchResultView(QWidget* parent) : QTreeWidget(parent), - m_module(0) { + m_module(nullptr) { initView(); initConnections(); } @@ -45,48 +45,53 @@ void CSearchResultView::initView() { m_popup = new QMenu(this); m_actions.copyMenu = new QMenu(tr("Copy..."), m_popup); - m_actions.copyMenu->setIcon(util::getIcon(CResMgr::searchdialog::result::foundItems::copyMenu::icon)); + m_actions.copyMenu->setIcon(CResMgr::searchdialog::result::foundItems::copyMenu::icon()); m_actions.copy.result = new QAction(tr("Reference only"), this); - QObject::connect(m_actions.copy.result, SIGNAL(triggered()), this, SLOT(copyItems()) ); + BT_CONNECT(m_actions.copy.result, SIGNAL(triggered()), + this, SLOT(copyItems())); m_actions.copyMenu->addAction(m_actions.copy.result); m_actions.copy.resultWithText = new QAction(tr("Reference with text"), this); - QObject::connect(m_actions.copy.resultWithText, SIGNAL(triggered()), - this, SLOT(copyItemsWithText())); + BT_CONNECT(m_actions.copy.resultWithText, SIGNAL(triggered()), + this, SLOT(copyItemsWithText())); m_actions.copyMenu->addAction(m_actions.copy.resultWithText); m_popup->addMenu(m_actions.copyMenu); m_actions.saveMenu = new QMenu(tr("Save..."), m_popup); - m_actions.saveMenu->setIcon(util::getIcon(CResMgr::searchdialog::result::foundItems::saveMenu::icon)); + m_actions.saveMenu->setIcon(CResMgr::searchdialog::result::foundItems::saveMenu::icon()); m_actions.save.result = new QAction(tr("Reference only"), this); - QObject::connect(m_actions.save.result, SIGNAL(triggered()), this, SLOT(saveItems()) ); + BT_CONNECT(m_actions.save.result, SIGNAL(triggered()), + this, SLOT(saveItems()) ); m_actions.saveMenu->addAction(m_actions.save.result); m_actions.save.resultWithText = new QAction(tr("Reference with text"), this); m_actions.saveMenu->addAction(m_actions.save.resultWithText); - QObject::connect(m_actions.save.resultWithText, SIGNAL(triggered()), this, SLOT(saveItemsWithText())); + BT_CONNECT(m_actions.save.resultWithText, SIGNAL(triggered()), + this, SLOT(saveItemsWithText())); m_popup->addMenu(m_actions.saveMenu); m_actions.printMenu = new QMenu(tr("Print..."), m_popup); - m_actions.printMenu->setIcon(util::getIcon(CResMgr::searchdialog::result::foundItems::printMenu::icon)); + m_actions.printMenu->setIcon(CResMgr::searchdialog::result::foundItems::printMenu::icon()); m_actions.print.result = new QAction(tr("Reference with text"), this); - QObject::connect(m_actions.print.result, SIGNAL(triggered()), this, SLOT(printItems()) ); + BT_CONNECT(m_actions.print.result, SIGNAL(triggered()), + this, SLOT(printItems())); m_actions.printMenu->addAction(m_actions.print.result); m_popup->addMenu(m_actions.printMenu); } /** No descriptions */ void CSearchResultView::initConnections() { - // connect(this, SIGNAL(executed(QListViewItem*)), - // this, SLOT(executed(QListViewItem*))); + // BT_CONNECT(this, SIGNAL(executed(QListViewItem *)), + // this, SLOT(executed(QListViewItem *))); /// \todo are these right after porting? //items: current, previous - connect(this, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)), - this, SLOT(executed(QTreeWidgetItem*, QTreeWidgetItem*))); + BT_CONNECT(this, + SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)), + this, SLOT(executed(QTreeWidgetItem *, QTreeWidgetItem *))); } /** Setups the list with the given module. */ @@ -103,8 +108,8 @@ void CSearchResultView::setupTree(const CSwordModuleInfo *m, setUpdatesEnabled(false); - QTreeWidgetItem* oldItem = 0; - QTreeWidgetItem* item = 0; + QTreeWidgetItem* oldItem = nullptr; + QTreeWidgetItem* item = nullptr; for (int index = 0; index < count; index++) { item = new QTreeWidgetItem(this, oldItem); item->setText(0, QString::fromUtf8(result.getElement(index)->getText())); @@ -126,10 +131,10 @@ void CSearchResultView::setupStrongsTree(CSwordModuleInfo* m, const QStringList setUpdatesEnabled(false); - QTreeWidgetItem* oldItem = 0; - QTreeWidgetItem* item = 0; + QTreeWidgetItem* oldItem = nullptr; + QTreeWidgetItem* item = nullptr; - foreach (QString s, vList) { + Q_FOREACH(QString const & s, vList) { item = new QTreeWidgetItem(this, oldItem); item->setText(0, (s)); oldItem = item; @@ -164,9 +169,8 @@ void CSearchResultView::printItems() { CExportManager mgr(true, tr("Printing search result")); QStringList list; - foreach (QTreeWidgetItem* k, items) { + Q_FOREACH(QTreeWidgetItem const * const k, items) list.append( k->text(0) ); - } mgr.printKeyList( list, module(), btConfig().getDisplayOptions(), btConfig().getFilterOptions() ); } @@ -174,10 +178,10 @@ void CSearchResultView::saveItems() { CExportManager mgr(true, tr("Saving search result")); const CSwordModuleInfo *m = module(); - CSwordKey* k = 0; + CSwordKey* k = nullptr; QList<QTreeWidgetItem*> items = selectedItems(); QList<CSwordKey*> keys; - foreach (QTreeWidgetItem* i, items) { + Q_FOREACH(QTreeWidgetItem const * const i, items) { k = CSwordKey::createInstance( m ); k->setKey(i->text(0)); keys.append( k ); @@ -192,10 +196,10 @@ void CSearchResultView::saveItemsWithText() { CExportManager mgr(true, tr("Saving search result")); const CSwordModuleInfo *m = module(); - CSwordKey* k = 0; + CSwordKey* k = nullptr; QList<QTreeWidgetItem*> items = selectedItems(); QList<CSwordKey*> keys; - foreach (QTreeWidgetItem* i, items) { + Q_FOREACH(QTreeWidgetItem const * const i, items) { k = CSwordKey::createInstance( m ); k->setKey(i->text(0)); keys.append( k ); @@ -210,10 +214,10 @@ void CSearchResultView::copyItems() { CExportManager mgr(true, tr("Copying search result")); const CSwordModuleInfo *m = module(); - CSwordKey* k = 0; + CSwordKey* k = nullptr; QList<QTreeWidgetItem*> items = selectedItems(); QList<CSwordKey*> keys; - foreach (QTreeWidgetItem* i, items) { + Q_FOREACH(QTreeWidgetItem const * const i, items) { k = CSwordKey::createInstance( m ); k->setKey(i->text(0)); keys.append( k ); @@ -228,10 +232,10 @@ void CSearchResultView::copyItemsWithText() { CExportManager mgr(true, tr("Copying search result")); const CSwordModuleInfo *m = module(); - CSwordKey* k = 0; + CSwordKey* k = nullptr; QList<QTreeWidgetItem*> items = selectedItems(); QList<CSwordKey*> keys; - foreach (QTreeWidgetItem* i, items) { + Q_FOREACH(QTreeWidgetItem const * const i, items) { k = CSwordKey::createInstance( m ); k->setKey(i->text(0)); keys.append( k ); @@ -262,9 +266,8 @@ void CSearchResultView::copyItemsWithText() { QMimeData * CSearchResultView::mimeData ( const QList<QTreeWidgetItem *> items ) const { BTMimeData* mdata = new BTMimeData(m_module->name(), items.first()->text(0), QString::null); - foreach (QTreeWidgetItem* i, items) { + Q_FOREACH(QTreeWidgetItem const * const i, items) mdata->appendBookmark(m_module->name(), i->text(0), QString::null); - } return mdata; } diff --git a/src/frontend/searchdialog/csearchresultview.h b/src/frontend/searchdialog/csearchresultview.h index 76b6d38..33e095b 100644 --- a/src/frontend/searchdialog/csearchresultview.h +++ b/src/frontend/searchdialog/csearchresultview.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -45,8 +45,8 @@ class CSearchResultView : public QTreeWidget { void initConnections(); //from QTreeWidget - virtual QMimeData * mimeData ( const QList<QTreeWidgetItem *> items ) const; - virtual QStringList mimeTypes () const; + QMimeData * mimeData ( const QList<QTreeWidgetItem *> items ) const override; + QStringList mimeTypes () const override; public slots: // Public slots void saveItems(); @@ -60,10 +60,8 @@ class CSearchResultView : public QTreeWidget { void copyItemsWithText(); void copyItems(); void saveItemsWithText(); - /** - * Reimplementation to show the popup menu. - */ - virtual void contextMenuEvent(QContextMenuEvent* event); + + void contextMenuEvent(QContextMenuEvent* event) override; protected slots: // Protected slots void printItems(); diff --git a/src/frontend/settingsdialogs/btconfigdialog.cpp b/src/frontend/settingsdialogs/btconfigdialog.cpp new file mode 100644 index 0000000..7e971e9 --- /dev/null +++ b/src/frontend/settingsdialogs/btconfigdialog.cpp @@ -0,0 +1,87 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#include "btconfigdialog.h" + +#include <QDialogButtonBox> +#include <QFrame> +#include <QHBoxLayout> +#include <QListWidget> +#include <QStackedWidget> +#include <QVBoxLayout> +#include "util/btassert.h" +#include "util/btconnect.h" + + +BtConfigDialog::BtConfigDialog(QWidget * const parent, + Qt::WindowFlags const flags) + : QDialog(parent, flags) + , m_contentsList(new QListWidget(this)) + , m_pageWidget(new QStackedWidget(this)) +{ + QHBoxLayout * const mainLayout = new QHBoxLayout(this); + + m_contentsList->setViewMode(QListView::IconMode); + m_contentsList->setMovement(QListView::Static); + BT_CONNECT(m_contentsList, &QListWidget::currentRowChanged, + m_pageWidget, &QStackedWidget::setCurrentIndex); + mainLayout->addWidget(m_contentsList); + + m_pageLayout = new QVBoxLayout; + mainLayout->addLayout(m_pageLayout); + + m_pageWidget->setSizePolicy(QSizePolicy::MinimumExpanding, + QSizePolicy::MinimumExpanding); + m_pageLayout->addWidget(m_pageWidget); +} + +void BtConfigDialog::addPage(Page * const pageWidget) { + m_pageWidget->addWidget(pageWidget); + + QListWidgetItem * const item = new QListWidgetItem(m_contentsList); + item->setTextAlignment(Qt::AlignHCenter); + item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); + pageWidget->setListWidgetItem(item); + + int const thisItemWidth = m_contentsList->visualItemRect(item).width(); + if (m_maxItemWidth < thisItemWidth) { + // Reset the list width: + m_maxItemWidth = thisItemWidth; + m_contentsList->setFixedWidth( + m_maxItemWidth + (m_contentsList->frameWidth() * 2)); + } + + // All items should have the same width: + for (int i = 0; i < m_contentsList->count(); ++i) + m_contentsList->item(i)->setSizeHint( + QSize(m_maxItemWidth, + m_contentsList->visualItemRect( + m_contentsList->item(i)).height())); + + setCurrentPage(m_contentsList->row(item)); +} + +void BtConfigDialog::setButtonBox(QDialogButtonBox * const box) { + BT_ASSERT(box); + BT_ASSERT(m_pageLayout->count() == 1); // Only m_pageWidget in layout + + // First add a horizontal ruler: + QFrame * const buttonBoxRuler = new QFrame(this); + buttonBoxRuler->setGeometry(QRect(1, 1, 1, 3)); + buttonBoxRuler->setFrameShape(QFrame::HLine); + buttonBoxRuler->setFrameShadow(QFrame::Sunken); + buttonBoxRuler->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + m_pageLayout->addWidget(buttonBoxRuler); + + // Add button box: + m_pageLayout->addWidget(box); +} + +void BtConfigDialog::setCurrentPage(int const newIndex) +{ m_contentsList->setCurrentRow(newIndex); } diff --git a/src/frontend/settingsdialogs/btconfigdialog.h b/src/frontend/settingsdialogs/btconfigdialog.h new file mode 100644 index 0000000..ae096f3 --- /dev/null +++ b/src/frontend/settingsdialogs/btconfigdialog.h @@ -0,0 +1,94 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef BTCONFIGDIALOG_H +#define BTCONFIGDIALOG_H + +#include <QDialog> + +#include <QIcon> +#include <QListWidgetItem> + + +class QDialogButtonBox; +class QStackedWidget; +class QVBoxLayout; + +/** +* Base class for configuration dialogs. A dialog which has a page chooser (icons +* + text) at the left, widget pages and a buttonbox. +* +* Usage: add BtConfigPage pages with addPage(), add a button box with addButtonBox(). +* Connect the button box signals. Use setAttribute(Qt::WA_DeleteOnClose) if you want +* an auto-destroying window. +*/ +class BtConfigDialog : public QDialog { + +public: /* Types: */ + + /** Base class for configuration dialog pages. */ + class Page : public QWidget { + + friend class BtConfigDialog; + + public: /* Methods: */ + + inline Page(QIcon const & icon, QWidget * const parent) + : QWidget(parent) + , m_icon(icon) + {} + + inline void setHeaderText(QString const & headerText) { + m_headerText = headerText; + if (m_listWidgetItem) + m_listWidgetItem->setText(headerText); + } + + private: /* Methods: */ + + void setListWidgetItem(QListWidgetItem * const item) noexcept { + m_listWidgetItem = item; + item->setIcon(m_icon); + item->setText(m_headerText); + } + + private: /* Fields: */ + + QIcon const m_icon; + QString m_headerText; + QListWidgetItem * m_listWidgetItem = nullptr; + + }; + +public: /* Methods: */ + + BtConfigDialog(QWidget * const parent = nullptr, + Qt::WindowFlags const flags = 0); + + /** Adds a BtConfigPage to the paged widget stack. The new page will be the current page.*/ + void addPage(Page * const pageWidget); + + /** Adds a button box to the lower edge of the dialog. */ + void setButtonBox(QDialogButtonBox * const buttonBox); + + /** Changes the current page using the given index number. */ + void setCurrentPage(int const newIndex); + +private: /* Fields: */ + + QListWidget * const m_contentsList; + QStackedWidget * const m_pageWidget; + QVBoxLayout * m_pageLayout; + int m_maxItemWidth = 0; + +}; + +#endif diff --git a/src/frontend/settingsdialogs/btfontchooserwidget.cpp b/src/frontend/settingsdialogs/btfontchooserwidget.cpp index 7fcf6b5..9e3051c 100644 --- a/src/frontend/settingsdialogs/btfontchooserwidget.cpp +++ b/src/frontend/settingsdialogs/btfontchooserwidget.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -15,24 +15,24 @@ #include <QLabel> #include <QListWidget> #include <QListWidgetItem> -#include <QWebSettings> -#include <QWebView> +#include "frontend/btwebengineview.h" #include "frontend/settingsdialogs/clistwidget.h" +#include "util/btconnect.h" namespace { -class BtFontPreviewWebView: public QWebView { +class BtFontPreviewWebView: public BtWebEngineView { public: /* Methods: */ - inline BtFontPreviewWebView(QWidget *parent = 0) - : QWebView(parent) + inline BtFontPreviewWebView(QWidget *parent = nullptr) + : BtWebEngineView(parent) { setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); } - virtual inline QSize sizeHint() const { + inline QSize sizeHint() const override { return QSize(100, 100); } @@ -100,30 +100,24 @@ void BtFontChooserWidget::retranslateUi() { } void BtFontChooserWidget::connectListWidgets() { - bool ok = connect( - m_fontListWidget, - SIGNAL(currentItemChanged(QListWidgetItem *, QListWidgetItem *)), - this, - SLOT(fontChanged(QListWidgetItem *, QListWidgetItem *))); - Q_ASSERT(ok); - - ok = connect( + BT_CONNECT(m_fontListWidget, + SIGNAL(currentItemChanged(QListWidgetItem *, QListWidgetItem *)), + this, + SLOT(fontChanged(QListWidgetItem *, QListWidgetItem *))); + BT_CONNECT( m_styleListWidget, SIGNAL(currentItemChanged(QListWidgetItem *, QListWidgetItem *)), this, SLOT(styleChanged(QListWidgetItem *, QListWidgetItem *))); - Q_ASSERT(ok); - - ok = connect( + BT_CONNECT( m_sizeListWidget, SIGNAL(currentItemChanged(QListWidgetItem *, QListWidgetItem *)), this, SLOT(sizeChanged(QListWidgetItem *, QListWidgetItem *))); - Q_ASSERT(ok); } void BtFontChooserWidget::fontChanged(QListWidgetItem* current, QListWidgetItem* /*previous*/) { - if (current == 0) + if (current == nullptr) return; const QString fontFamily = current->text(); @@ -136,9 +130,9 @@ void BtFontChooserWidget::fontChanged(QListWidgetItem* current, QListWidgetItem* void BtFontChooserWidget::loadFonts() { m_fontListWidget->clear(); QFontDatabase database; - Q_FOREACH (const QString &font, database.families()) { + Q_FOREACH(QString const & font, database.families()) m_fontListWidget->addItem(font); - } + // This triggers loading the styles for the first font m_fontListWidget->setCurrentRow(0); } @@ -159,9 +153,8 @@ void BtFontChooserWidget::loadSizes(const QString& font, const QString& style) { // Put new values into listWidget m_sizeListWidget->clear(); QFontDatabase database; - Q_FOREACH (int size, database.pointSizes(font, style)) { + Q_FOREACH(int const size, database.pointSizes(font, style)) m_sizeListWidget->addItem(QString::number(size)); - } restoreListWidgetValue(m_sizeListWidget, saveText); } @@ -220,9 +213,9 @@ QString BtFontChooserWidget::saveListWidgetValue(QListWidget* listWidget) { } void BtFontChooserWidget::setFont(const QFont& font) { - disconnect(m_fontListWidget, 0, 0, 0); - disconnect(m_styleListWidget, 0, 0, 0); - disconnect(m_sizeListWidget, 0, 0, 0); + disconnect(m_fontListWidget, nullptr, nullptr, nullptr); + disconnect(m_styleListWidget, nullptr, nullptr, nullptr); + disconnect(m_sizeListWidget, nullptr, nullptr, nullptr); // set the font m_font = font; @@ -256,7 +249,7 @@ void BtFontChooserWidget::setSampleText(const QString& htmlText) { } void BtFontChooserWidget::sizeChanged(QListWidgetItem* current, QListWidgetItem* /*previous*/) { - if (current == 0) + if (current == nullptr) return; m_font.setPointSize(m_sizeListWidget->currentItem()->text().toInt()); @@ -270,7 +263,7 @@ QSize BtFontChooserWidget::sizeHint() const { } void BtFontChooserWidget::styleChanged(QListWidgetItem* current, QListWidgetItem* /*previous*/) { - if (current == 0) + if (current == nullptr) return; QString styleString = current->text(); diff --git a/src/frontend/settingsdialogs/btfontchooserwidget.h b/src/frontend/settingsdialogs/btfontchooserwidget.h index eba5607..078fd89 100644 --- a/src/frontend/settingsdialogs/btfontchooserwidget.h +++ b/src/frontend/settingsdialogs/btfontchooserwidget.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -22,7 +22,7 @@ class CListWidget; class QListWidget; class QListWidgetItem; class QString; -class QWebView; +class BtWebEngineView; class BtFontChooserWidget : public QFrame { @@ -30,13 +30,12 @@ class BtFontChooserWidget : public QFrame { public: /* Methods: */ - BtFontChooserWidget(QWidget *parent = 0); + BtFontChooserWidget(QWidget *parent = nullptr); void setFont(const QFont &font); void setSampleText(const QString &text); - // Inherited from QWidget: - virtual QSize sizeHint() const; + QSize sizeHint() const override; signals: @@ -72,7 +71,7 @@ class BtFontChooserWidget : public QFrame { QLabel *m_fontSizeLabel; CListWidget *m_sizeListWidget; - QWebView *m_fontPreview; + BtWebEngineView *m_fontPreview; QString m_htmlText; QFont m_font; diff --git a/src/frontend/settingsdialogs/btfontsettings.cpp b/src/frontend/settingsdialogs/btfontsettings.cpp index 57a8aba..77aad3f 100644 --- a/src/frontend/settingsdialogs/btfontsettings.cpp +++ b/src/frontend/settingsdialogs/btfontsettings.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -20,24 +20,20 @@ #include "bibletimeapp.h" #include "frontend/settingsdialogs/btfontchooserwidget.h" #include "frontend/settingsdialogs/cconfigurationdialog.h" +#include "util/btconnect.h" #include "util/cresmgr.h" -#include "util/geticon.h" #include "util/tool.h" -// Sword includes: -#include <localemgr.h> -#include <swlocale.h> - BtFontSettingsPage::BtFontSettingsPage(CConfigurationDialog *parent) - : BtConfigDialog::Page(util::getIcon(CResMgr::settings::fonts::icon), parent) + : BtConfigDialog::Page(CResMgr::settings::fonts::icon(), parent) { m_languageLabel = new QLabel(this); m_languageComboBox = new QComboBox(this); m_languageLabel->setBuddy(m_languageComboBox); m_languageCheckBox = new QCheckBox(this); - connect(m_languageCheckBox, SIGNAL(toggled(bool)), - this, SLOT(useOwnFontClicked(bool)) ); + BT_CONNECT(m_languageCheckBox, SIGNAL(toggled(bool)), + this, SLOT(useOwnFontClicked(bool)) ); QHBoxLayout *hLayout = new QHBoxLayout; @@ -47,7 +43,7 @@ BtFontSettingsPage::BtFontSettingsPage(CConfigurationDialog *parent) hLayout->addWidget(m_languageCheckBox); CLanguageMgr::LangMap langMap = CLanguageMgr::instance()->availableLanguages(); - typedef CLanguageMgr::Language L; + using L = CLanguageMgr::Language; for (CLanguageMgr::LangMapIterator it = langMap.constBegin(); it != langMap.constEnd(); it++) @@ -64,7 +60,7 @@ BtFontSettingsPage::BtFontSettingsPage(CConfigurationDialog *parent) for (FontMap::ConstIterator it = m_fontMap.constBegin(); it != m_fontMap.constEnd(); ++it) { const QString &k = it.key(); if (m_fontMap[k].first) { // show font icon - m_languageComboBox->addItem(util::getIcon("fonts.svg"), k); + m_languageComboBox->addItem(CResMgr::settings::fonts::icon(), k); } else { // don't show icon for font m_languageComboBox->addItem(k); } @@ -79,10 +75,10 @@ BtFontSettingsPage::BtFontSettingsPage(CConfigurationDialog *parent) */ // m_fontChooser->setSampleText("SOMETHING"); - connect(m_fontChooser, SIGNAL(fontSelected(const QFont&)), - this, SLOT(newDisplayWindowFontSelected(const QFont&))); - connect(m_languageComboBox, SIGNAL(activated(const QString&)), - this, SLOT(newDisplayWindowFontAreaSelected(const QString&))); + BT_CONNECT(m_fontChooser, SIGNAL(fontSelected(QFont const &)), + this, SLOT(newDisplayWindowFontSelected(QFont const &))); + BT_CONNECT(m_languageComboBox, SIGNAL(activated(QString const &)), + this, SLOT(newDisplayWindowFontAreaSelected(QString const &))); const BtConfig::FontSettingsPair &v = m_fontMap.value(m_languageComboBox->currentText()); m_fontChooser->setFont(v.second); @@ -143,7 +139,9 @@ void BtFontSettingsPage::useOwnFontClicked(bool isOn) { m_fontChooser->setEnabled(isOn); m_fontMap[m_languageComboBox->currentText()].first = isOn; m_languageComboBox->setItemIcon(m_languageComboBox->currentIndex(), - isOn ? util::getIcon("fonts.svg") : QIcon()); + isOn + ? CResMgr::settings::fonts::icon() + : QIcon()); } void BtFontSettingsPage::retranslateUi() { @@ -151,5 +149,4 @@ void BtFontSettingsPage::retranslateUi() { m_languageLabel->setText(tr("&Language:")); m_languageComboBox->setToolTip(tr("The font selection below will apply to all texts in this language")); m_languageCheckBox->setText(tr("Use custom font")); - m_fontsGroupBox->setTitle(tr("Optionally specify a custom font for each language:")); } diff --git a/src/frontend/settingsdialogs/btfontsettings.h b/src/frontend/settingsdialogs/btfontsettings.h index 70d0d20..356a9a9 100644 --- a/src/frontend/settingsdialogs/btfontsettings.h +++ b/src/frontend/settingsdialogs/btfontsettings.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -12,7 +12,7 @@ #ifndef BTFONTSETTINGS_H #define BTFONTSETTINGS_H -#include "frontend/bookshelfmanager/btconfigdialog.h" +#include "btconfigdialog.h" #include <QMap> #include <QWidget> @@ -32,11 +32,11 @@ class BtFontSettingsPage: public BtConfigDialog::Page { private: /* Types: */ - typedef QMap<QString, BtConfig::FontSettingsPair> FontMap; + using FontMap = QMap<QString, BtConfig::FontSettingsPair>; public: /* Methods: */ - BtFontSettingsPage(CConfigurationDialog *parent = 0); + BtFontSettingsPage(CConfigurationDialog *parent = nullptr); void save() const; diff --git a/src/frontend/settingsdialogs/btlanguagesettings.cpp b/src/frontend/settingsdialogs/btlanguagesettings.cpp deleted file mode 100644 index 37e53c8..0000000 --- a/src/frontend/settingsdialogs/btlanguagesettings.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/********* -* -* 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 "frontend/settingsdialogs/btlanguagesettings.h" - -#include <QComboBox> -#include <QFormLayout> -#include <QLabel> -#include <QVBoxLayout> -#include <QWidget> -#include "backend/config/btconfig.h" -#include "bibletimeapp.h" -#include "frontend/settingsdialogs/cconfigurationdialog.h" -#include "util/cresmgr.h" -#include "util/geticon.h" -#include "util/tool.h" - -// Sword includes: -#include <localemgr.h> -#include <swlocale.h> - - -typedef std::list<sword::SWBuf>::const_iterator SBLCI; - - -BtLanguageSettingsPage::BtLanguageSettingsPage(CConfigurationDialog *parent) - : BtConfigDialog::Page(util::getIcon(CResMgr::settings::languages::icon), parent) -{ - m_swordLocaleCombo = new QComboBox(this); - m_languageNamesLabel = new QLabel(this); - m_languageNamesLabel->setBuddy(m_swordLocaleCombo); - - QFormLayout * formLayout = new QFormLayout(this); - formLayout->addRow(m_languageNamesLabel, m_swordLocaleCombo); - - retranslateUi(); - - initSwordLocaleCombo(); -} - -void BtLanguageSettingsPage::save() { - btConfig().setValue("language", m_swordLocaleCombo->itemData(m_swordLocaleCombo->currentIndex())); -} - -void BtLanguageSettingsPage::resetLanguage() { - QVector<QString> atv = bookNameAbbreviationsTryVector(); - - QString best = "en_US"; - Q_ASSERT(atv.contains(best)); - int i = atv.indexOf(best); - if (i > 0) { - atv.resize(i); - const std::list<sword::SWBuf> locales = sword::LocaleMgr::getSystemLocaleMgr()->getAvailableLocales(); - for (SBLCI it = locales.begin(); it != locales.end(); ++it) { - const char * abbr = sword::LocaleMgr::getSystemLocaleMgr()->getLocale((*it).c_str())->getName(); - i = atv.indexOf(abbr); - if (i >= 0) { - best = abbr; - if (i == 0) - break; - atv.resize(i); - } - } - } - btConfig().setValue("language", best); -} - -QVector<QString> BtLanguageSettingsPage::bookNameAbbreviationsTryVector() { - QVector<QString> atv; - atv.reserve(4); - { - QString settingsLanguage = btConfig().value<QString>("language"); - if (!settingsLanguage.isEmpty()) - atv.append(settingsLanguage); - } - { - const QString localeLanguageAndCountry = QLocale::system().name(); - if (!localeLanguageAndCountry.isEmpty()) { - atv.append(localeLanguageAndCountry); - int i = localeLanguageAndCountry.indexOf('_'); - if (i > 0) - atv.append(localeLanguageAndCountry.left(i)); - } - } - Q_ASSERT(CLanguageMgr::instance()->languageForAbbrev("en_US")); - atv.append("en_US"); - return atv; -} - -void BtLanguageSettingsPage::initSwordLocaleCombo() { - typedef QMap<QString, QString>::const_iterator SSMCI; - - QMap<QString, QString> languageNames; - Q_ASSERT(CLanguageMgr::instance()->languageForAbbrev("en_US")); - languageNames.insert(CLanguageMgr::instance()->languageForAbbrev("en_US")->translatedName(), "en_US"); - - const std::list<sword::SWBuf> locales = sword::LocaleMgr::getSystemLocaleMgr()->getAvailableLocales(); - for (SBLCI it = locales.begin(); it != locales.end(); ++it) { - const char * const abbreviation = sword::LocaleMgr::getSystemLocaleMgr()->getLocale((*it).c_str())->getName(); - const CLanguageMgr::Language * const l = CLanguageMgr::instance()->languageForAbbrev(abbreviation); - - if (l->isValid()) { - languageNames.insert(l->translatedName(), abbreviation); - } else { - languageNames.insert( - sword::LocaleMgr::getSystemLocaleMgr()->getLocale((*it).c_str())->getDescription(), - abbreviation); - } - } - - int index = 0; - QVector<QString> atv = bookNameAbbreviationsTryVector(); - for (SSMCI it = languageNames.constBegin(); it != languageNames.constEnd(); ++it) { - if (!atv.isEmpty()) { - int i = atv.indexOf(it.value()); - if (i >= 0) { - atv.resize(i); - index = m_swordLocaleCombo->count(); - } - } - m_swordLocaleCombo->addItem(it.key(), it.value()); - } - m_swordLocaleCombo->setCurrentIndex(index); -} - -void BtLanguageSettingsPage::retranslateUi() { - setHeaderText(tr("Languages")); - - m_languageNamesLabel->setText(tr("Language for names of Bible books:")); - const QString toolTip(tr("The languages which can be used for the biblical book names. Translations are provided by the Sword library.")); - m_languageNamesLabel->setToolTip(toolTip); - m_swordLocaleCombo->setToolTip(toolTip); -} diff --git a/src/frontend/settingsdialogs/btlanguagesettings.h b/src/frontend/settingsdialogs/btlanguagesettings.h deleted file mode 100644 index 89caaf2..0000000 --- a/src/frontend/settingsdialogs/btlanguagesettings.h +++ /dev/null @@ -1,50 +0,0 @@ -/********* -* -* 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 BTLANGUAGESETTINGS_H -#define BTLANGUAGESETTINGS_H - -#include "frontend/bookshelfmanager/btconfigdialog.h" - -#include <QMap> -#include <QWidget> - - -class CConfigurationDialog; -class QComboBox; -class QLabel; - -class BtLanguageSettingsPage: public BtConfigDialog::Page { - - Q_OBJECT - - public: /* Methods: */ - - BtLanguageSettingsPage(CConfigurationDialog *parent = 0); - - void save(); - - static void resetLanguage(); - - private: /* Methods: */ - - static QVector<QString> bookNameAbbreviationsTryVector(); - void initSwordLocaleCombo(); - void retranslateUi(); - - private: /* Fields: */ - - QLabel *m_languageNamesLabel; - QComboBox* m_swordLocaleCombo; - -}; - -#endif diff --git a/src/frontend/settingsdialogs/btshortcutsdialog.cpp b/src/frontend/settingsdialogs/btshortcutsdialog.cpp index 10601f6..5299560 100644 --- a/src/frontend/settingsdialogs/btshortcutsdialog.cpp +++ b/src/frontend/settingsdialogs/btshortcutsdialog.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -16,13 +16,14 @@ #include <QLabel> #include <QRadioButton> #include <QVBoxLayout> +#include "util/btconnect.h" // *************** BtShortcutsDialog *************************************************************************** // A dialog to allow the user to input a shortcut for a primary and alternate key BtShortcutsDialog::BtShortcutsDialog(QWidget* parent) - : QDialog(parent), m_primaryLabel(0), m_alternateLabel(0), m_primaryButton(0), m_alternateButton(0) { + : QDialog(parent), m_primaryLabel(nullptr), m_alternateLabel(nullptr), m_primaryButton(nullptr), m_alternateButton(nullptr) { setWindowTitle(tr("Configure shortcuts")); setMinimumWidth(350); @@ -59,8 +60,8 @@ BtShortcutsDialog::BtShortcutsDialog(QWidget* parent) message::prepareDialogBox(buttons); vLayout->addWidget(buttons); - connect(buttons, SIGNAL(accepted()), this, SLOT(accept())); - connect(buttons, SIGNAL(rejected()), this, SLOT(reject())); + BT_CONNECT(buttons, SIGNAL(accepted()), this, SLOT(accept())); + BT_CONNECT(buttons, SIGNAL(rejected()), this, SLOT(reject())); } // get new primary key from dialog diff --git a/src/frontend/settingsdialogs/btshortcutsdialog.h b/src/frontend/settingsdialogs/btshortcutsdialog.h index 722cef9..e5294ac 100644 --- a/src/frontend/settingsdialogs/btshortcutsdialog.h +++ b/src/frontend/settingsdialogs/btshortcutsdialog.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -48,7 +48,7 @@ class BtShortcutsDialog : public QDialog { protected: // get key from users input, put into primary or alternate label for display to user - void keyReleaseEvent(QKeyEvent* event); + void keyReleaseEvent(QKeyEvent* event) override; private: QLabel* m_primaryLabel; diff --git a/src/frontend/settingsdialogs/btshortcutseditor.cpp b/src/frontend/settingsdialogs/btshortcutseditor.cpp index 2e943eb..3811f7d 100644 --- a/src/frontend/settingsdialogs/btshortcutseditor.cpp +++ b/src/frontend/settingsdialogs/btshortcutseditor.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -22,6 +22,7 @@ #include <QVBoxLayout> #include "frontend/displaywindow/btactioncollection.h" #include "frontend/settingsdialogs/btshortcutsdialog.h" +#include "util/btconnect.h" // *************** BtShortcutsEditorItem ******************************************************************* @@ -48,7 +49,7 @@ class BtShortcutsEditorItem : public QTableWidgetItem { }; BtShortcutsEditorItem::BtShortcutsEditorItem(QAction* action) - : m_action(action), m_newFirstHotkey(0), m_newSecondHotkey(0) { + : m_action(action), m_newFirstHotkey(nullptr), m_newSecondHotkey(nullptr) { QList<QKeySequence> list = m_action->shortcuts(); if (list.count() > 0) m_newFirstHotkey = new QKeySequence(list.at(0)); @@ -74,13 +75,13 @@ void BtShortcutsEditorItem::setDefaultKeys(QKeySequence keys) { } void BtShortcutsEditorItem::setFirstHotkey(QKeySequence keys) { - if (m_newFirstHotkey == 0) + if (m_newFirstHotkey == nullptr) m_newFirstHotkey = new QKeySequence(); *m_newFirstHotkey = keys; } void BtShortcutsEditorItem::setSecondHotkey(const QString& keys) { - if (m_newSecondHotkey == 0) + if (m_newSecondHotkey == nullptr) m_newSecondHotkey = new QKeySequence(); *m_newSecondHotkey = QKeySequence(keys); } @@ -88,22 +89,22 @@ void BtShortcutsEditorItem::setSecondHotkey(const QString& keys) { // Deletes hotkey information void BtShortcutsEditorItem::deleteHotkeys() { delete m_newFirstHotkey; - m_newFirstHotkey = 0; + m_newFirstHotkey = nullptr; delete m_newSecondHotkey; - m_newSecondHotkey = 0; + m_newSecondHotkey = nullptr; } // Moves the hotkey information into the QAction variable void BtShortcutsEditorItem::commitChanges() { QString actionName = text(); QList<QKeySequence> list; - if ( (m_newFirstHotkey != 0) && (*m_newFirstHotkey != QKeySequence()) ) { + if ( (m_newFirstHotkey != nullptr) && (*m_newFirstHotkey != QKeySequence()) ) { list << *m_newFirstHotkey; } - if ( (m_newSecondHotkey != 0) && (*m_newSecondHotkey != QKeySequence()) ) + if ( (m_newSecondHotkey != nullptr) && (*m_newSecondHotkey != QKeySequence()) ) list << *m_newSecondHotkey; - if (m_action != 0) + if (m_action != nullptr) m_action->setShortcuts(list); } @@ -111,29 +112,139 @@ void BtShortcutsEditorItem::commitChanges() { // ******************* BtShortcutsEditor ******************************************************* BtShortcutsEditor::BtShortcutsEditor(BtActionCollection* collection, QWidget* parent) - : QWidget(parent), m_dlg(new BtShortcutsDialog(this)), m_table(0), m_shortcutChooser(0), m_noneButton(0), m_defaultButton(0), - m_customButton(0), m_defaultLabelValue(0), m_currentRow(-1) { - init(); - addCollection(collection); - bool ok = connect(m_dlg, SIGNAL(keyChangeRequest(const QString&)), this, SLOT(makeKeyChangeRequest(const QString&)) ); - Q_ASSERT(ok); -} - -BtShortcutsEditor::BtShortcutsEditor(QWidget* parent) - : QWidget(parent), m_table(0) { - init(); -} + : QWidget(parent), m_dlg(new BtShortcutsDialog(this)), m_table(nullptr), m_shortcutChooser(nullptr), m_noneButton(nullptr), m_defaultButton(nullptr), + m_customButton(nullptr), m_defaultLabelValue(nullptr), m_currentRow(-1) { -// initialize this widget -void BtShortcutsEditor::init() { - QVBoxLayout* vBox = new QVBoxLayout(this); + QVBoxLayout * const vBox = new QVBoxLayout(this); setLayout(vBox); - m_table = createShortcutsTable(); + // Create the action and shortcuts table: + m_table = new QTableWidget{this}; + m_table->setColumnCount(3); + m_table->setAlternatingRowColors(true); + m_table->setSelectionBehavior(QAbstractItemView::SelectRows); + m_table->setHorizontalHeaderLabels({tr("Action\nname"), + tr("First\nshortcut"), + tr("Second\nshortcut")}); + m_table->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); + m_table->horizontalHeader()->resizeSection(0, 180); + m_table->horizontalHeader()->resizeSection(1, 100); + m_table->horizontalHeader()->setStretchLastSection(true); + m_table->verticalHeader()->setVisible(false); + m_table->setShowGrid(false); + BT_CONNECT(m_table, &QTableWidget::cellClicked, + this, &BtShortcutsEditor::changeRow); vBox->addWidget(m_table); - m_shortcutChooser = createShortcutChooser(); + // Create the area below the table where the shortcuts are edited: + m_shortcutChooser = + new QGroupBox(tr("Shortcut for selected action name"), this); + m_shortcutChooser->setFlat(false); + { + QVBoxLayout * const vLayout = new QVBoxLayout(m_shortcutChooser); + { + QHBoxLayout * const hLayout = new QHBoxLayout(); + vLayout->addLayout(hLayout); + + m_noneButton = new QRadioButton(tr("None"), m_shortcutChooser); + hLayout->addWidget(m_noneButton); + BT_CONNECT(m_noneButton, &QRadioButton::clicked, + this, &BtShortcutsEditor::noneButtonClicked); + + m_defaultButton = + new QRadioButton(tr("Default"), m_shortcutChooser); + hLayout->addWidget(m_defaultButton); + BT_CONNECT( + m_defaultButton, &QRadioButton::clicked, + this, &BtShortcutsEditor::defaultButtonClicked); + + m_customButton = new QRadioButton(tr("Custom"), m_shortcutChooser); + hLayout->addWidget(m_customButton); + BT_CONNECT(m_customButton, &QRadioButton::clicked, + this, &BtShortcutsEditor::customButtonClicked); + + m_customPushButton = new QPushButton(m_shortcutChooser); + m_customPushButton->setMinimumWidth(140); + hLayout->addWidget(m_customPushButton); + + hLayout->addItem(new QSpacerItem(1, + 1, + QSizePolicy::Expanding, + QSizePolicy::Minimum)); + } + + QHBoxLayout * const hLayout = new QHBoxLayout(); + vLayout->addLayout(hLayout); + + hLayout->addWidget(new QLabel(tr("Default key:"), m_shortcutChooser)); + + m_defaultLabelValue = new QLabel(m_shortcutChooser); + hLayout->addWidget(m_defaultLabelValue); + + hLayout->addItem(new QSpacerItem(1, + 1, + QSizePolicy::Expanding, + QSizePolicy::Minimum)); + } vBox->addWidget(m_shortcutChooser); + + collection->foreachQAction([this](QAction & action, + QKeySequence const & defaultKeys) + { + int const count = m_table->rowCount(); + m_table->insertRow(count); + + { + BtShortcutsEditorItem * const item = + new BtShortcutsEditorItem{&action}; + try { + /// \todo Remove this & hack and use Qt properties instead: + item->setText(action.text().replace(QRegExp("&(.)"), "\\1")); + item->setIcon(action.icon()); + item->setDefaultKeys(defaultKeys); + item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); + m_table->setItem(count, 0, item); + } catch (...) { + delete item; + throw; + } + } + + QList<QKeySequence> keys = action.shortcuts(); + + { + QTableWidgetItem * const item = new QTableWidgetItem; + try { + item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); + item->setToolTip(tr("Select to change key")); + if (keys.count() > 0) + item->setText(keys[0].toString()); + m_table->setItem(count, 1, item); + } catch (...) { + delete item; + throw; + } + } + + { + QTableWidgetItem * const item = new QTableWidgetItem; + try { + item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); + item->setToolTip(tr("Select to change key")); + if (keys.count() > 1) + item->setText(keys[1].toString()); + m_table->setItem(count, 2, item); + } catch (...) { + delete item; + throw; + } + } + }); + m_table->sortItems(0); + m_table->selectRow(0); + changeRow(0, 0); + BT_CONNECT(m_dlg, &BtShortcutsDialog::keyChangeRequest, + this, &BtShortcutsEditor::makeKeyChangeRequest); } // get the shortcut editor item from the zeroth column of the table @@ -148,77 +259,11 @@ void BtShortcutsEditor::commitChanges() { int rows = m_table->rowCount(); for (int row = 0; row < rows; row++) { BtShortcutsEditorItem* btItem = getShortcutsEditor(row); - if (btItem != 0) + if (btItem != nullptr) btItem->commitChanges(); } } -// puts actions and shortcut keys into QTableWidget -void BtShortcutsEditor::addCollection(BtActionCollection* collection, const QString& title) { - Q_UNUSED(title); /// \todo Is this correct? - - foreach (QAction *action, collection->actions()) { - /// \todo Is the following check really necessary? - if (action) { - int count = m_table->rowCount(); - m_table->insertRow(count); - - QString name = action->text().remove('&'); - QList<QKeySequence> keys = action->shortcuts(); - QIcon icon = action->icon(); - QKeySequence defaultKeys = collection->getDefaultShortcut(action); - - BtShortcutsEditorItem* item = new BtShortcutsEditorItem(action); - item->setText(name); - item->setIcon(icon); - item->setDefaultKeys(defaultKeys); - item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); - m_table->setItem(count, 0, item); - - QTableWidgetItem* item1 = new QTableWidgetItem(); - item1->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); - item1->setToolTip(tr("Select to change key")); - if (keys.count() > 0) - item1->setText(keys[0].toString()); - m_table->setItem(count, 1, item1); - - QTableWidgetItem* item2 = new QTableWidgetItem(); - item2->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); - item2->setToolTip(tr("Select to change key")); - if (keys.count() > 1) - item2->setText(keys[1].toString()); - m_table->setItem(count, 2, item2); - } - } - m_table->sortItems(0); - m_table->selectRow(0); - changeRow(0, 0); -} - -// create the action and shortcuts table -QTableWidget* BtShortcutsEditor::createShortcutsTable() { - QTableWidget* table = new QTableWidget(this); - table->setColumnCount(3); - table->setAlternatingRowColors(true); - table->setSelectionBehavior(QAbstractItemView::SelectRows); - QStringList headerList; - headerList << tr("Action\nname") << tr("First\nshortcut") << tr("Second\nshortcut"); - table->setHorizontalHeaderLabels(headerList); -#if QT_VERSION < 0x050000 - table->horizontalHeader()->setResizeMode(QHeaderView::Interactive); -#else - table->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); -#endif - table->horizontalHeader()->resizeSection(0, 180); - table->horizontalHeader()->resizeSection(1, 100); - table->horizontalHeader()->setStretchLastSection(true); - table->verticalHeader()->setVisible(false); - table->setShowGrid(false); - bool ok = connect(table, SIGNAL(cellClicked(int, int)), this, SLOT(changeRow(int, int))); - Q_ASSERT(ok); - return table; -} - // called when a different action name row is selected void BtShortcutsEditor::changeRow(int row, int column) { Q_UNUSED(column); /// \todo Is this correct? @@ -248,52 +293,6 @@ void BtShortcutsEditor::changeRow(int row, int column) { m_customButton->setChecked(true); } -// create the area below the table where the shortcuts are edited -QWidget* BtShortcutsEditor::createShortcutChooser() { - QGroupBox* box = new QGroupBox(tr("Shortcut for selected action name"), this); - box->setFlat(false); - QVBoxLayout* vLayout = new QVBoxLayout(box); - QHBoxLayout* hLayout = new QHBoxLayout(); - vLayout->addLayout(hLayout); - - m_noneButton = new QRadioButton(tr("None"), box); - hLayout->addWidget(m_noneButton); - bool ok = connect(m_noneButton, SIGNAL(clicked(bool)), this, SLOT(noneButtonClicked(bool))); - Q_ASSERT(ok); - - m_defaultButton = new QRadioButton(tr("Default"), box); - hLayout->addWidget(m_defaultButton); - ok = connect(m_defaultButton, SIGNAL(clicked(bool)), this, SLOT(defaultButtonClicked(bool))); - Q_ASSERT(ok); - - m_customButton = new QRadioButton(tr("Custom"), box); - hLayout->addWidget(m_customButton); - ok = connect(m_customButton, SIGNAL(clicked(bool)), this, SLOT(customButtonClicked(bool))); - Q_ASSERT(ok); - - m_customPushButton = new QPushButton(box); - m_customPushButton->setMinimumWidth(140); - hLayout->addWidget(m_customPushButton); - - QSpacerItem* spacer = new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Minimum); - hLayout->addItem(spacer); - - QHBoxLayout* hLayout2 = new QHBoxLayout(); - vLayout->addLayout(hLayout2); - - QLabel* defaultLabel = new QLabel(tr("Default key:"), box); - hLayout2->addWidget(defaultLabel); - - m_defaultLabelValue = new QLabel(box); - hLayout2->addWidget(m_defaultLabelValue); - - QSpacerItem* spacer2 = new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Minimum); - hLayout2->addItem(spacer2); - - return box; -} - - // called when the none radio button is clicked void BtShortcutsEditor::noneButtonClicked(bool checked) { Q_UNUSED(checked); /// \todo Is this correct? diff --git a/src/frontend/settingsdialogs/btshortcutseditor.h b/src/frontend/settingsdialogs/btshortcutseditor.h index d58ac08..66cee81 100644 --- a/src/frontend/settingsdialogs/btshortcutseditor.h +++ b/src/frontend/settingsdialogs/btshortcutseditor.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -19,6 +19,7 @@ class BtActionCollection; class BtShortcutsEditorItem; class BtShortcutsDialog; +class QGroupBox; class QLabel; class QPushButton; class QRadioButton; @@ -28,15 +29,11 @@ class QTableWidget; class BtShortcutsEditor : public QWidget { Q_OBJECT public: - BtShortcutsEditor(BtActionCollection* collection, QWidget* parent); - BtShortcutsEditor(QWidget* parent); + BtShortcutsEditor(BtActionCollection * collection, QWidget * parent); // saves shortcut keys into the QAction void commitChanges(); - // puts actions and shortcut keys into QTableWidget - void addCollection(BtActionCollection *collection, const QString &title = QString::null); - // clears any shortcut keys in the table matching the specified keys void clearConflictWithKeys(const QString& keys); @@ -70,21 +67,12 @@ class BtShortcutsEditor : public QWidget { private: - // create the action and shortcuts table - QTableWidget* createShortcutsTable(); - - // create the area below the table where the shortcuts are edited - QWidget* createShortcutChooser(); - // get the shortcut editor item from the zeroth column of the table BtShortcutsEditorItem* getShortcutsEditor(int row); - // initialize this widget - void init(); - BtShortcutsDialog* m_dlg; QTableWidget* m_table; - QWidget* m_shortcutChooser; + QGroupBox * m_shortcutChooser; QRadioButton* m_noneButton; QRadioButton* m_defaultButton; QRadioButton* m_customButton; diff --git a/src/frontend/settingsdialogs/btstandardworkstab.cpp b/src/frontend/settingsdialogs/btstandardworkstab.cpp index 9cef549..1190aa6 100644 --- a/src/frontend/settingsdialogs/btstandardworkstab.cpp +++ b/src/frontend/settingsdialogs/btstandardworkstab.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -23,8 +23,6 @@ BtStandardWorksTab::BtStandardWorksTab(CSwordSettingsPage *parent) : QWidget(parent) { - typedef QList<CSwordModuleInfo*>::const_iterator MLCI; - QVBoxLayout *mainLayout = new QVBoxLayout(this); mainLayout->setMargin(5); mainLayout->setSpacing(2); @@ -59,12 +57,13 @@ BtStandardWorksTab::BtStandardWorksTab(CSwordSettingsPage *parent) //fill the comboboxes with the right modules - const QList<CSwordModuleInfo*> &modules(CSwordBackend::instance()->moduleList()); QString modDescript; - for (MLCI it(modules.begin()); it != modules.end(); it++) { - modDescript = (*it)->config(CSwordModuleInfo::Description); + Q_FOREACH(CSwordModuleInfo const * const m, + CSwordBackend::instance()->moduleList()) + { + modDescript = m->config(CSwordModuleInfo::Description); - switch ((*it)->type()) { + switch (m->type()) { case CSwordModuleInfo::Bible: m_standardBibleCombo->addItem(modDescript); break; @@ -73,23 +72,23 @@ BtStandardWorksTab::BtStandardWorksTab(CSwordSettingsPage *parent) break; case CSwordModuleInfo::Lexicon: { bool inserted = false; - if ((*it)->has(CSwordModuleInfo::HebrewDef)) { + if (m->has(CSwordModuleInfo::HebrewDef)) { m_standardHebrewStrongsLexiconCombo->addItem(modDescript); inserted = true; } - if ((*it)->has(CSwordModuleInfo::GreekDef)) { + if (m->has(CSwordModuleInfo::GreekDef)) { m_standardGreekStrongsLexiconCombo->addItem(modDescript); inserted = true; } - if ((*it)->has(CSwordModuleInfo::HebrewParse)) { + if (m->has(CSwordModuleInfo::HebrewParse)) { m_standardHebrewMorphLexiconCombo->addItem(modDescript); inserted = true; } - if ((*it)->has(CSwordModuleInfo::GreekParse)) { + if (m->has(CSwordModuleInfo::GreekParse)) { m_standardGreekMorphLexiconCombo->addItem(modDescript); inserted = true; } - if ((*it)->category() == CSwordModuleInfo::DailyDevotional) { + if (m->category() == CSwordModuleInfo::DailyDevotional) { m_standardDailyDevotionalCombo->addItem(modDescript); inserted = true; } @@ -109,7 +108,7 @@ BtStandardWorksTab::BtStandardWorksTab(CSwordSettingsPage *parent) QStringList moduleList; // fill combobox and modulelist - const CSwordModuleInfo* m; + const CSwordModuleInfo* m; #define STANDARD_WORKS_COMBO_ADD(name) \ comboList.append(m_ ## name ## Combo); \ diff --git a/src/frontend/settingsdialogs/btstandardworkstab.h b/src/frontend/settingsdialogs/btstandardworkstab.h index 0b91b4c..d03fe9e 100644 --- a/src/frontend/settingsdialogs/btstandardworkstab.h +++ b/src/frontend/settingsdialogs/btstandardworkstab.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ diff --git a/src/frontend/settingsdialogs/bttextfilterstab.cpp b/src/frontend/settingsdialogs/bttextfilterstab.cpp index e8da038..ee1c410 100644 --- a/src/frontend/settingsdialogs/bttextfilterstab.cpp +++ b/src/frontend/settingsdialogs/bttextfilterstab.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -72,8 +72,9 @@ void BtTextFiltersTab::save() { void BtTextFiltersTab::retranslateUi() { util::tool::initExplanationLabel(m_explanationLabel, "", tr("Filters control the appearance of text. Here you can specify " - "default settings for all filters. You can override these " - "settings in each display window.")); + "default settings for all filters. These settings apply to newly " + "opened display windows only. You can override these settings in " + "each display window.")); m_lineBreaksCheck->setText(tr("Insert line break after each verse")); m_verseNumbersCheck->setText(tr("Show verse numbers")); diff --git a/src/frontend/settingsdialogs/bttextfilterstab.h b/src/frontend/settingsdialogs/bttextfilterstab.h index 3f6e904..fbfedde 100644 --- a/src/frontend/settingsdialogs/bttextfilterstab.h +++ b/src/frontend/settingsdialogs/bttextfilterstab.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ diff --git a/src/frontend/settingsdialogs/cacceleratorsettings.cpp b/src/frontend/settingsdialogs/cacceleratorsettings.cpp index d85bf51..c95a715 100644 --- a/src/frontend/settingsdialogs/cacceleratorsettings.cpp +++ b/src/frontend/settingsdialogs/cacceleratorsettings.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -26,12 +26,12 @@ #include "frontend/displaywindow/creadwindow.h" #include "frontend/messagedialog.h" #include "frontend/settingsdialogs/cconfigurationdialog.h" +#include "util/btconnect.h" #include "util/cresmgr.h" -#include "util/geticon.h" CAcceleratorSettingsPage::CAcceleratorSettingsPage(CConfigurationDialog *parent) - : BtConfigDialog::Page(util::getIcon(CResMgr::settings::keys::icon), parent) + : BtConfigDialog::Page(CResMgr::settings::keys::icon(), parent) { QVBoxLayout *mainLayout = new QVBoxLayout(this); @@ -44,9 +44,8 @@ CAcceleratorSettingsPage::CAcceleratorSettingsPage(CConfigurationDialog *parent) m_typeChooser = new QComboBox(this); layoutForWindowTypeChooser->addWidget(m_typeChooser); - bool ok = connect(m_typeChooser, SIGNAL(activated(const QString&)), - SLOT(slotKeyChooserTypeChanged(const QString&)) ); - Q_ASSERT(ok); + BT_CONNECT(m_typeChooser, SIGNAL(activated(QString const &)), + SLOT(slotKeyChooserTypeChanged(QString const &)) ); // m_*.title strings are empty here, they are filled and added to the stacked widget in the retranslateUi() function m_keyChooserStack = new QStackedWidget(this); @@ -60,9 +59,11 @@ CAcceleratorSettingsPage::CAcceleratorSettingsPage(CConfigurationDialog *parent) m_application.actionCollection->readShortcuts("Application shortcuts"); m_application.keyChooser = new BtShortcutsEditor(m_application.actionCollection, m_keyChooserStack); m_keyChooserStack->addWidget(m_application.keyChooser); - ok = connect(m_application.keyChooser, SIGNAL(keyChangeRequest(BtShortcutsEditor*, const QString&)), - this, SLOT(completeKeyChangeRequest(BtShortcutsEditor*, const QString&))); - Q_ASSERT(ok); + BT_CONNECT(m_application.keyChooser, + SIGNAL(keyChangeRequest(BtShortcutsEditor *, QString const &)), + this, + SLOT(completeKeyChangeRequest(BtShortcutsEditor *, + QString const &))); // ----- All display windows ------ // m_general.actionCollection = new BtActionCollection(this); @@ -70,9 +71,11 @@ CAcceleratorSettingsPage::CAcceleratorSettingsPage(CConfigurationDialog *parent) m_general.actionCollection->readShortcuts("Displaywindow shortcuts"); m_general.keyChooser = new BtShortcutsEditor(m_general.actionCollection, m_keyChooserStack); m_keyChooserStack->addWidget(m_general.keyChooser); - ok = connect(m_general.keyChooser, SIGNAL(keyChangeRequest(BtShortcutsEditor*, const QString&)), - this, SLOT(completeKeyChangeRequest(BtShortcutsEditor*, const QString&))); - Q_ASSERT(ok); + BT_CONNECT(m_general.keyChooser, + SIGNAL(keyChangeRequest(BtShortcutsEditor *, QString const &)), + this, + SLOT(completeKeyChangeRequest(BtShortcutsEditor *, + QString const &))); // ----- Bible windows ------ // m_bible.actionCollection = new BtActionCollection(this); @@ -80,9 +83,11 @@ CAcceleratorSettingsPage::CAcceleratorSettingsPage(CConfigurationDialog *parent) m_bible.actionCollection->readShortcuts("Bible shortcuts"); m_bible.keyChooser = new BtShortcutsEditor(m_bible.actionCollection, m_keyChooserStack); m_keyChooserStack->addWidget(m_bible.keyChooser); - ok = connect(m_bible.keyChooser, SIGNAL(keyChangeRequest(BtShortcutsEditor*, const QString&)), - this, SLOT(completeKeyChangeRequest(BtShortcutsEditor*, const QString&))); - Q_ASSERT(ok); + BT_CONNECT(m_bible.keyChooser, + SIGNAL(keyChangeRequest(BtShortcutsEditor *, QString const &)), + this, + SLOT(completeKeyChangeRequest(BtShortcutsEditor *, + QString const &))); // ----- Commentary windows ------ // m_commentary.actionCollection = new BtActionCollection(this); @@ -90,9 +95,11 @@ CAcceleratorSettingsPage::CAcceleratorSettingsPage(CConfigurationDialog *parent) m_commentary.actionCollection->readShortcuts("Commentary shortcuts"); m_commentary.keyChooser = new BtShortcutsEditor(m_commentary.actionCollection, m_keyChooserStack); m_keyChooserStack->addWidget(m_commentary.keyChooser); - ok = connect(m_commentary.keyChooser, SIGNAL(keyChangeRequest(BtShortcutsEditor*, const QString&)), - this, SLOT(completeKeyChangeRequest(BtShortcutsEditor*, const QString&))); - Q_ASSERT(ok); + BT_CONNECT(m_commentary.keyChooser, + SIGNAL(keyChangeRequest(BtShortcutsEditor *, QString const &)), + this, + SLOT(completeKeyChangeRequest(BtShortcutsEditor *, + QString const &))); // ----- Lexicon windows ------ // m_lexicon.actionCollection = new BtActionCollection(this); @@ -100,9 +107,11 @@ CAcceleratorSettingsPage::CAcceleratorSettingsPage(CConfigurationDialog *parent) m_lexicon.actionCollection->readShortcuts("Lexicon shortcuts"); m_lexicon.keyChooser = new BtShortcutsEditor(m_lexicon.actionCollection, m_keyChooserStack); m_keyChooserStack->addWidget(m_lexicon.keyChooser); - ok = connect(m_lexicon.keyChooser, SIGNAL(keyChangeRequest(BtShortcutsEditor*, const QString&)), - this, SLOT(completeKeyChangeRequest(BtShortcutsEditor*, const QString&))); - Q_ASSERT(ok); + BT_CONNECT(m_lexicon.keyChooser, + SIGNAL(keyChangeRequest(BtShortcutsEditor *, QString const &)), + this, + SLOT(completeKeyChangeRequest(BtShortcutsEditor *, + QString const &))); // ----- Book windows ------ // m_book.actionCollection = new BtActionCollection(this); @@ -110,9 +119,11 @@ CAcceleratorSettingsPage::CAcceleratorSettingsPage(CConfigurationDialog *parent) m_book.actionCollection->readShortcuts("Book shortcuts"); m_book.keyChooser = new BtShortcutsEditor(m_book.actionCollection, m_keyChooserStack); m_keyChooserStack->addWidget(m_book.keyChooser); - ok = connect(m_book.keyChooser, SIGNAL(keyChangeRequest(BtShortcutsEditor*, const QString&)), - this, SLOT(completeKeyChangeRequest(BtShortcutsEditor*, const QString&))); - Q_ASSERT(ok); + BT_CONNECT(m_book.keyChooser, + SIGNAL(keyChangeRequest(BtShortcutsEditor *, QString const &)), + this, + SLOT(completeKeyChangeRequest(BtShortcutsEditor *, + QString const &))); mainLayout->addWidget(m_keyChooserStack); slotKeyChooserTypeChanged(m_application.title); diff --git a/src/frontend/settingsdialogs/cacceleratorsettings.h b/src/frontend/settingsdialogs/cacceleratorsettings.h index 49408d5..4e79ca6 100644 --- a/src/frontend/settingsdialogs/cacceleratorsettings.h +++ b/src/frontend/settingsdialogs/cacceleratorsettings.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -12,7 +12,7 @@ #ifndef CACCELERATORSETTINGS_H #define CACCELERATORSETTINGS_H -#include "frontend/bookshelfmanager/btconfigdialog.h" +#include "btconfigdialog.h" #include <QPointer> #include <QWidget> @@ -36,7 +36,7 @@ class CAcceleratorSettingsPage: public BtConfigDialog::Page { public: /* Methods: */ - CAcceleratorSettingsPage(CConfigurationDialog *parent = 0); + CAcceleratorSettingsPage(CConfigurationDialog *parent = nullptr); void save(); @@ -58,13 +58,8 @@ class CAcceleratorSettingsPage: public BtConfigDialog::Page { QString title; WindowType() { - keyChooser = 0; - actionCollection = 0; - }; - WindowType(const QString& newTitle) { - title = newTitle; - keyChooser = 0; - actionCollection = 0; + keyChooser = nullptr; + actionCollection = nullptr; } }; diff --git a/src/frontend/settingsdialogs/cconfigurationdialog.cpp b/src/frontend/settingsdialogs/cconfigurationdialog.cpp index 951880b..93801f0 100644 --- a/src/frontend/settingsdialogs/cconfigurationdialog.cpp +++ b/src/frontend/settingsdialogs/cconfigurationdialog.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -18,9 +18,9 @@ #include "frontend/settingsdialogs/cacceleratorsettings.h" #include "frontend/settingsdialogs/cdisplaysettings.h" #include "frontend/settingsdialogs/btfontsettings.h" -#include "frontend/settingsdialogs/btlanguagesettings.h" #include "frontend/settingsdialogs/cswordsettings.h" #include "frontend/messagedialog.h" +#include "util/btconnect.h" #include "util/cresmgr.h" #include "util/directory.h" @@ -32,12 +32,11 @@ const QString GeometryKey = "GUI/SettingsDialog/geometry"; CConfigurationDialog::CConfigurationDialog(QWidget * parent, BtActionCollection* actionCollection ) : BtConfigDialog(parent), m_actionCollection(actionCollection), - m_displayPage(0), - m_swordPage(0), - m_acceleratorsPage(0), - m_fontsPage(0), - m_languagesPage(0), - m_bbox(0) { + m_displayPage(nullptr), + m_swordPage(nullptr), + m_acceleratorsPage(nullptr), + m_fontsPage(nullptr), + m_bbox(nullptr) { setWindowTitle(tr("Configure BibleTime")); setAttribute(Qt::WA_DeleteOnClose); @@ -49,10 +48,6 @@ CConfigurationDialog::CConfigurationDialog(QWidget * parent, BtActionCollection* m_swordPage = new CSwordSettingsPage(this); addPage(m_swordPage); - // Add "Languages" page - m_languagesPage = new BtLanguageSettingsPage(this); - addPage(m_languagesPage); - // Add "Fonts" page m_fontsPage = new BtFontSettingsPage(this); addPage(m_fontsPage); @@ -68,8 +63,8 @@ CConfigurationDialog::CConfigurationDialog(QWidget * parent, BtActionCollection* m_bbox->addButton(QDialogButtonBox::Cancel); message::prepareDialogBox(m_bbox); setButtonBox(m_bbox); - bool ok = connect(m_bbox, SIGNAL(clicked(QAbstractButton *)), SLOT(slotButtonClicked(QAbstractButton *))); - Q_ASSERT(ok); + BT_CONNECT(m_bbox, SIGNAL(clicked(QAbstractButton *)), + SLOT(slotButtonClicked(QAbstractButton *))); loadDialogSettings(); @@ -83,7 +78,6 @@ CConfigurationDialog::~CConfigurationDialog() { /** Save the dialog settings **/ void CConfigurationDialog::save() { m_acceleratorsPage->save(); - m_languagesPage->save(); m_fontsPage->save(); m_swordPage->save(); m_displayPage->save(); diff --git a/src/frontend/settingsdialogs/cconfigurationdialog.h b/src/frontend/settingsdialogs/cconfigurationdialog.h index fbd4944..ec00cf4 100644 --- a/src/frontend/settingsdialogs/cconfigurationdialog.h +++ b/src/frontend/settingsdialogs/cconfigurationdialog.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -12,14 +12,13 @@ #ifndef CCONFIGURATIONDIALOG_H #define CCONFIGURATIONDIALOG_H -#include "frontend/bookshelfmanager/btconfigdialog.h" +#include "btconfigdialog.h" class BtActionCollection; class CAcceleratorSettingsPage; class CDisplaySettingsPage; class BtFontSettingsPage; -class BtLanguageSettingsPage; class CSwordSettingsPage; class QAbstractButton; class QDialogButtonBox; @@ -41,7 +40,6 @@ class CConfigurationDialog : public BtConfigDialog { CSwordSettingsPage* m_swordPage; CAcceleratorSettingsPage* m_acceleratorsPage; BtFontSettingsPage* m_fontsPage; - BtLanguageSettingsPage* m_languagesPage; QDialogButtonBox* m_bbox; // Load the settings from the resource file diff --git a/src/frontend/settingsdialogs/cdisplaysettings.cpp b/src/frontend/settingsdialogs/cdisplaysettings.cpp index 5b690f6..92bf5a0 100644 --- a/src/frontend/settingsdialogs/cdisplaysettings.cpp +++ b/src/frontend/settingsdialogs/cdisplaysettings.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -13,24 +13,31 @@ #include <QComboBox> #include <QLabel> #include <QVBoxLayout> -#include <QWebView> +#include <QFormLayout> #include "backend/config/btconfig.h" #include "backend/managers/cdisplaytemplatemgr.h" #include "backend/rendering/cdisplayrendering.h" #include "bibletimeapp.h" +#include "frontend/btwebengineview.h" #include "frontend/settingsdialogs/cconfigurationdialog.h" +#include "util/btassert.h" +#include "util/btconnect.h" #include "util/cresmgr.h" -#include "util/geticon.h" #include "util/tool.h" +// Sword includes: +#include <localemgr.h> +#include <swlocale.h> + +using SBLCI = std::list<sword::SWBuf>::const_iterator; // *********************** -// Container for QWebView to control its size +// Container for BtWebEngineView to control its size class CWebViewerWidget : public QWidget { public: - CWebViewerWidget(QWidget* parent = 0); + CWebViewerWidget(QWidget* parent = nullptr); ~CWebViewerWidget(); - virtual QSize sizeHint () const; + QSize sizeHint() const override; }; CWebViewerWidget::CWebViewerWidget(QWidget* parent) @@ -47,36 +54,37 @@ QSize CWebViewerWidget::sizeHint () const { /** Initializes the startup section of the OD. */ CDisplaySettingsPage::CDisplaySettingsPage(CConfigurationDialog *parent) - : BtConfigDialog::Page(util::getIcon(CResMgr::settings::startup::icon), parent) + : BtConfigDialog::Page(CResMgr::settings::startup::icon(), parent) { QVBoxLayout *mainLayout = new QVBoxLayout(this); - { //startup logo - m_showLogoCheck = new QCheckBox(this); - m_showLogoCheck->setChecked(btConfig().value<bool>("GUI/showSplashScreen", true)); - mainLayout->addWidget(m_showLogoCheck); - } - mainLayout->addSpacing(20); + QFormLayout *formLayout = new QFormLayout(); + + //startup logo + m_showLogoLabel = new QLabel(this); + m_showLogoCheck = new QCheckBox(this); + m_showLogoCheck->setChecked(btConfig().value<bool>("GUI/showSplashScreen", true)); + formLayout->addRow(m_showLogoLabel, m_showLogoCheck); - m_explanationLabel = new QLabel(this); - mainLayout->addWidget(m_explanationLabel); + m_swordLocaleCombo = new QComboBox(this); + m_languageNamesLabel = new QLabel(this); + m_languageNamesLabel->setBuddy(m_swordLocaleCombo); + formLayout->addRow(m_languageNamesLabel, m_swordLocaleCombo); - QHBoxLayout* hboxlayout = new QHBoxLayout(); + initSwordLocaleCombo(); m_styleChooserCombo = new QComboBox( this ); //create first to enable buddy for label - connect( m_styleChooserCombo, SIGNAL( activated( int ) ), - this, SLOT( updateStylePreview() ) ); + BT_CONNECT(m_styleChooserCombo, SIGNAL(activated(int)), + this, SLOT(updateStylePreview())); m_availableLabel = new QLabel(this); m_availableLabel->setBuddy(m_styleChooserCombo); - hboxlayout->addWidget(m_availableLabel); - hboxlayout->addWidget( m_styleChooserCombo ); - hboxlayout->addStretch(); - mainLayout->addLayout( hboxlayout ); + formLayout->addRow(m_availableLabel, m_styleChooserCombo ); + mainLayout->addLayout(formLayout); QWidget* webViewWidget = new CWebViewerWidget(this); QLayout* webViewLayout = new QVBoxLayout(webViewWidget); - m_stylePreviewViewer = new QWebView(webViewWidget); + m_stylePreviewViewer = new BtWebEngineView(webViewWidget); m_previewLabel = new QLabel(webViewWidget); m_previewLabel->setBuddy(m_stylePreviewViewer); webViewLayout->addWidget(m_previewLabel); @@ -94,25 +102,116 @@ CDisplaySettingsPage::CDisplaySettingsPage(CConfigurationDialog *parent) } } + m_transifexLabel = new QLabel(this); + mainLayout->addWidget(m_transifexLabel); + retranslateUi(); // also calls updateStylePreview(); } void CDisplaySettingsPage::retranslateUi() { setHeaderText(tr("Display")); - util::tool::initExplanationLabel( - m_explanationLabel, - tr("Display templates"), - tr("Display templates define how text is displayed.") - ); + m_languageNamesLabel->setText(tr("Language for names of Bible books:")); + const QString toolTip(tr("The languages which can be used for the biblical book names. Translations are provided by the Sword library.")); + m_languageNamesLabel->setToolTip(toolTip); + m_swordLocaleCombo->setToolTip(toolTip); - m_showLogoCheck->setText(tr("Show startup logo")); - m_showLogoCheck->setToolTip(tr("Show the BibleTime logo on startup")); + m_showLogoLabel->setText(tr("Show startup logo:")); + m_showLogoLabel->setToolTip(tr("Show the BibleTime logo on startup.")); m_availableLabel->setText(tr("Available display styles:")); m_previewLabel->setText(tr("Style preview")); updateStylePreview(); + + m_transifexLabel->setWordWrap(true); + m_transifexLabel->setOpenExternalLinks(true); + m_transifexLabel->setText(tr( + "Did you know? You can help translating the GUI of BibleTime to your language at %1." + ).arg(QString("<a href=\"https://www.transifex.com/bibletime/bibletime/\">") + .append(tr("Transifex")) + .append("</a>"))); +} + +void CDisplaySettingsPage::resetLanguage() { + QVector<QString> atv = bookNameAbbreviationsTryVector(); + + QString best = "en_US"; + BT_ASSERT(atv.contains(best)); + int i = atv.indexOf(best); + if (i > 0) { + atv.resize(i); + const std::list<sword::SWBuf> locales = sword::LocaleMgr::getSystemLocaleMgr()->getAvailableLocales(); + for (SBLCI it = locales.begin(); it != locales.end(); ++it) { + const char * abbr = sword::LocaleMgr::getSystemLocaleMgr()->getLocale((*it).c_str())->getName(); + i = atv.indexOf(abbr); + if (i >= 0) { + best = abbr; + if (i == 0) + break; + atv.resize(i); + } + } + } + btConfig().setValue("GUI/booknameLanguage", best); +} + +QVector<QString> CDisplaySettingsPage::bookNameAbbreviationsTryVector() { + QVector<QString> atv; + atv.reserve(4); + { + QString settingsLanguage = btConfig().value<QString>("GUI/booknameLanguage"); + if (!settingsLanguage.isEmpty()) + atv.append(settingsLanguage); + } + { + const QString localeLanguageAndCountry = QLocale::system().name(); + if (!localeLanguageAndCountry.isEmpty()) { + atv.append(localeLanguageAndCountry); + int i = localeLanguageAndCountry.indexOf('_'); + if (i > 0) + atv.append(localeLanguageAndCountry.left(i)); + } + } + BT_ASSERT(CLanguageMgr::instance()->languageForAbbrev("en_US")); + atv.append("en_US"); + return atv; +} + +void CDisplaySettingsPage::initSwordLocaleCombo() { + using SSMCI = QMap<QString, QString>::const_iterator; + + QMap<QString, QString> languageNames; + BT_ASSERT(CLanguageMgr::instance()->languageForAbbrev("en_US")); + languageNames.insert(CLanguageMgr::instance()->languageForAbbrev("en_US")->translatedName(), "en_US"); + + const std::list<sword::SWBuf> locales = sword::LocaleMgr::getSystemLocaleMgr()->getAvailableLocales(); + for (SBLCI it = locales.begin(); it != locales.end(); ++it) { + const char * const abbreviation = sword::LocaleMgr::getSystemLocaleMgr()->getLocale((*it).c_str())->getName(); + const CLanguageMgr::Language * const l = CLanguageMgr::instance()->languageForAbbrev(abbreviation); + + if (l->isValid()) { + languageNames.insert(l->translatedName(), abbreviation); + } else { + languageNames.insert( + sword::LocaleMgr::getSystemLocaleMgr()->getLocale((*it).c_str())->getDescription(), + abbreviation); + } + } + + int index = 0; + QVector<QString> atv = bookNameAbbreviationsTryVector(); + for (SSMCI it = languageNames.constBegin(); it != languageNames.constEnd(); ++it) { + if (!atv.isEmpty()) { + int i = atv.indexOf(it.value()); + if (i >= 0) { + atv.resize(i); + index = m_swordLocaleCombo->count(); + } + } + m_swordLocaleCombo->addItem(it.key(), it.value()); + } + m_swordLocaleCombo->setCurrentIndex(index); } @@ -172,4 +271,5 @@ void CDisplaySettingsPage::updateStylePreview() { void CDisplaySettingsPage::save() { btConfig().setValue("GUI/showSplashScreen", m_showLogoCheck->isChecked() ); btConfig().setValue("GUI/activeTemplateName", m_styleChooserCombo->currentText()); + btConfig().setValue("GUI/booknameLanguage", m_swordLocaleCombo->itemData(m_swordLocaleCombo->currentIndex())); } diff --git a/src/frontend/settingsdialogs/cdisplaysettings.h b/src/frontend/settingsdialogs/cdisplaysettings.h index 834c846..1f6ad6a 100644 --- a/src/frontend/settingsdialogs/cdisplaysettings.h +++ b/src/frontend/settingsdialogs/cdisplaysettings.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -12,7 +12,7 @@ #ifndef CDISPLAYSETTINGS_H #define CDISPLAYSETTINGS_H -#include "frontend/bookshelfmanager/btconfigdialog.h" +#include "btconfigdialog.h" #include <QWidget> @@ -21,7 +21,7 @@ class CConfigurationDialog; class QCheckBox; class QComboBox; class QLabel; -class QWebView; +class BtWebEngineView; class CDisplaySettingsPage: public BtConfigDialog::Page { @@ -29,10 +29,12 @@ class CDisplaySettingsPage: public BtConfigDialog::Page { public: /* Methods: */ - CDisplaySettingsPage(CConfigurationDialog *parent = 0); + CDisplaySettingsPage(CConfigurationDialog *parent = nullptr); void save(); + static void resetLanguage(); + protected: /* Methods: */ void retranslateUi(); @@ -41,13 +43,21 @@ class CDisplaySettingsPage: public BtConfigDialog::Page { /** Update the style preview widget. */ void updateStylePreview(); + private: /* Methods: */ + + static QVector<QString> bookNameAbbreviationsTryVector(); + void initSwordLocaleCombo(); + private: /* Fields: */ + QLabel* m_showLogoLabel; QCheckBox* m_showLogoCheck; - QLabel *m_explanationLabel; + QLabel *m_languageNamesLabel; + QComboBox* m_swordLocaleCombo; + QLabel *m_transifexLabel; QComboBox* m_styleChooserCombo; QLabel *m_availableLabel; - QWebView* m_stylePreviewViewer; + BtWebEngineView* m_stylePreviewViewer; QLabel *m_previewLabel; }; diff --git a/src/frontend/settingsdialogs/clistwidget.cpp b/src/frontend/settingsdialogs/clistwidget.cpp index 9504009..79a254e 100644 --- a/src/frontend/settingsdialogs/clistwidget.cpp +++ b/src/frontend/settingsdialogs/clistwidget.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ diff --git a/src/frontend/settingsdialogs/clistwidget.h b/src/frontend/settingsdialogs/clistwidget.h index 393754c..2693463 100644 --- a/src/frontend/settingsdialogs/clistwidget.h +++ b/src/frontend/settingsdialogs/clistwidget.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -18,9 +18,9 @@ class CListWidget : public QListWidget { Q_OBJECT public: - CListWidget(QWidget* parent = 0); + CListWidget(QWidget* parent = nullptr); - virtual QSize sizeHint () const; + QSize sizeHint() const override; void setCharWidth(int width); }; diff --git a/src/frontend/settingsdialogs/cswordsettings.cpp b/src/frontend/settingsdialogs/cswordsettings.cpp index f8f0ebf..5913d78 100644 --- a/src/frontend/settingsdialogs/cswordsettings.cpp +++ b/src/frontend/settingsdialogs/cswordsettings.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -15,11 +15,10 @@ #include "frontend/settingsdialogs/bttextfilterstab.h" #include "frontend/settingsdialogs/cconfigurationdialog.h" #include "util/cresmgr.h" -#include "util/geticon.h" CSwordSettingsPage::CSwordSettingsPage(CConfigurationDialog * parent) - : BtConfigDialog::Page(util::getIcon(CResMgr::settings::sword::icon), parent) + : BtConfigDialog::Page(CResMgr::settings::sword::icon(), parent) { static const QString nullString; diff --git a/src/frontend/settingsdialogs/cswordsettings.h b/src/frontend/settingsdialogs/cswordsettings.h index 18a4268..16f4b9a 100644 --- a/src/frontend/settingsdialogs/cswordsettings.h +++ b/src/frontend/settingsdialogs/cswordsettings.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -12,7 +12,8 @@ #ifndef CSWORDSETTINGS_H #define CSWORDSETTINGS_H -#include "frontend/bookshelfmanager/btconfigdialog.h" +#include "btconfigdialog.h" + #include <QWidget> @@ -26,7 +27,7 @@ class CSwordSettingsPage: public BtConfigDialog::Page { public: /* Methods: */ - CSwordSettingsPage(CConfigurationDialog * parent = 0); + CSwordSettingsPage(CConfigurationDialog * parent = nullptr); void save(); diff --git a/src/frontend/tips/bttipdialog.cpp b/src/frontend/tips/bttipdialog.cpp index 75b7a6d..994b655 100644 --- a/src/frontend/tips/bttipdialog.cpp +++ b/src/frontend/tips/bttipdialog.cpp @@ -2,27 +2,29 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ #include "bttipdialog.h" +#include "frontend/btwebengineview.h" +#include "frontend/btwebenginepage.h" + #include <QCheckBox> #include <QDesktopServices> #include <QDialogButtonBox> #include <QHBoxLayout> #include <QPushButton> #include <QVBoxLayout> -#include <QWebView> #include "backend/config/btconfig.h" #include "bibletimeapp.h" -#include "util/cresmgr.h" #include "frontend/messagedialog.h" +#include "util/btconnect.h" +#include "util/bticons.h" +#include "util/cresmgr.h" #include "util/directory.h" -#include "util/geticon.h" -#include "util/htmlescape.h" namespace { @@ -50,13 +52,6 @@ inline QString make_html(QWidget *widget, const QString &text) { + vertical_align(text) + "</body></html>"; } -inline QString make_icon(const QString &icon) { - namespace DU = util::directory; - QString fileName = DU::getIconDir().filePath(icon); - QString iconUrl = QUrl::fromLocalFile(fileName).toString(); - return "<img src=\"" + util::htmlEscape(iconUrl) + "\" width=\"32\" />"; -} - const QString LastTipNumberKey = "GUI/lastTipNumber"; } // anonymous namespace @@ -67,14 +62,15 @@ BtTipDialog::BtTipDialog(QWidget *parent, Qt::WindowFlags wflags) { setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); setWindowTitle(tr("Tip Of The Day")); - setWindowIcon(util::getIcon(CResMgr::mainMenu::help::tipOfTheDay::icon)); + setWindowIcon(CResMgr::mainMenu::help::tipOfTheDay::icon()); resize(450, 240); QVBoxLayout *mainLayout = new QVBoxLayout; - m_tipView = new QWebView; + m_tipView = new BtWebEngineView(this); + BtWebEnginePage *page = new BtWebEnginePage(this); + m_tipView->setPage(page); m_tipView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - m_tipView->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks); mainLayout->addWidget(m_tipView); QHBoxLayout* hLayout = new QHBoxLayout; @@ -98,22 +94,14 @@ BtTipDialog::BtTipDialog(QWidget *parent, Qt::WindowFlags wflags) mainLayout->addLayout(hLayout); setLayout(mainLayout); - bool ok; - ok = connect(m_showTipsCheckBox, SIGNAL(toggled(bool)), - this, SLOT(startupBoxChanged(bool))); - Q_ASSERT(ok); - - ok = connect(m_buttonBox, SIGNAL(rejected()), - this, SLOT(reject())); - Q_ASSERT(ok); - - ok = connect(nextButton, SIGNAL(clicked()), - this, SLOT(nextTip())); - Q_ASSERT(ok); - - ok = connect(m_tipView->page(), SIGNAL(linkClicked(const QUrl&)), - this, SLOT(linkClicked(const QUrl&))); - Q_ASSERT(ok); + BT_CONNECT(m_showTipsCheckBox, SIGNAL(toggled(bool)), + this, SLOT(startupBoxChanged(bool))); + BT_CONNECT(m_buttonBox, SIGNAL(rejected()), + this, SLOT(reject())); + BT_CONNECT(nextButton, SIGNAL(clicked()), + this, SLOT(nextTip())); + BT_CONNECT(m_tipView->btPage(), SIGNAL(linkClicked(QUrl const &)), + this, SLOT(linkClicked(QUrl const &))); m_tipNumber = btConfig().value<int>(LastTipNumberKey, 0); initTips(); @@ -125,18 +113,18 @@ void BtTipDialog::initTips() { m_tips << tr("To add multiple Bible works in parallel in your active Bible window" " select this icon and choose another Bible work.") - + "<br><center>" + make_icon(CResMgr::modules::bible::icon_add) + "</center>"; + + "<br><center>" + iconToHtml(CResMgr::modules::bible::icon_add()) + "</center>"; m_tips << tr("To add multiple commentary works in parallel in your active commentary window" " select this icon and choose another commentary work.") - + "<br><center>" + make_icon(CResMgr::modules::commentary::icon_add) + "</center>"; + + "<br><center>" + iconToHtml(CResMgr::modules::commentary::icon_add()) + "</center>"; m_tips << tr("To learn more about the BibleTime project please go to our web site.") + "<br><center><a href=\"http://www.bibletime.info\">www.bibletime.info</a></center>"; m_tips << tr("To synchronize a commentary window with the active Bible window, activate the" " commentary window and select this icon.") + "<br><center>" - + make_icon(CResMgr::displaywindows::commentaryWindow::syncWindow::icon) + + iconToHtml(CResMgr::displaywindows::commentaryWindow::syncWindow::icon()) + "</center><br>" + tr("Select the icon again to stop the synchronization."); m_tips << tr("To create a bookmark drag any verse reference from a Bible or commentary work" @@ -148,9 +136,6 @@ void BtTipDialog::initTips() { " and select the Edit Bookmark menu. After finishing the edit the description can be" " seen by hovering over the bookmark."); - m_tips << tr("To load multiple installation sources for works, go to the Bookshelf Manager" - ", select the Add button, and then the Get List button."); - m_tips << tr("To find more information about a work, go the the Bookshelf window, right" " click on the work, and select the About menu."); diff --git a/src/frontend/tips/bttipdialog.h b/src/frontend/tips/bttipdialog.h index e8058ee..1da539c 100644 --- a/src/frontend/tips/bttipdialog.h +++ b/src/frontend/tips/bttipdialog.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -21,8 +21,7 @@ class QCheckBox; class QDialogButtonBox; class QPushButton; class QUrl; -class QWebView; - +class BtWebEngineView; /** The Tip Of The Day dialog. */ @@ -31,7 +30,7 @@ class BtTipDialog: public QDialog { public: /* Methods: */ - BtTipDialog(QWidget *parent = 0, Qt::WindowFlags wflags = Qt::Dialog); + BtTipDialog(QWidget *parent = nullptr, Qt::WindowFlags wflags = Qt::Dialog); private: /* Methods: */ @@ -55,7 +54,7 @@ class BtTipDialog: public QDialog { private: /* Fields: */ QDialogButtonBox* m_buttonBox; - QWebView* m_tipView; + BtWebEngineView* m_tipView; QCheckBox* m_showTipsCheckBox; int m_tipNumber; QStringList m_tips; diff --git a/src/frontend/welcome/btwelcomedialog.cpp b/src/frontend/welcome/btwelcomedialog.cpp new file mode 100644 index 0000000..63346d0 --- /dev/null +++ b/src/frontend/welcome/btwelcomedialog.cpp @@ -0,0 +1,95 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#include "btwelcomedialog.h" + +#include "bibletime.h" +#include "frontend/messagedialog.h" + +#include <QDialogButtonBox> +#include <QLabel> +#include <QPushButton> +#include <QVBoxLayout> +#include "util/btconnect.h" +#include "util/bticons.h" +#include "util/cresmgr.h" + +void BtWelcomeDialog::openWelcome() { + BtWelcomeDialog dlg(BibleTime::instance()); + dlg.exec(); +} + +BtWelcomeDialog::BtWelcomeDialog(QWidget *parent, Qt::WindowFlags wflags) + : QDialog(parent, wflags) +{ + setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); + setWindowIcon(CResMgr::mainMenu::help::tipOfTheDay::icon()); + resize(560, 300); + + QVBoxLayout *mainLayout = new QVBoxLayout; + + m_iconLabel = new QLabel(this); + m_iconLabel->setPixmap(BtIcons::instance().icon_bibletime.pixmap(48)); + mainLayout->addWidget(m_iconLabel, 0, Qt::AlignHCenter); + + m_label = new QLabel(this); + m_label->setWordWrap(true); + mainLayout->addWidget(m_label); + + mainLayout->addStretch(); + + m_buttonBox = new QDialogButtonBox(Qt::Horizontal, this); + + m_installButton = m_buttonBox->addButton( + "", QDialogButtonBox::AcceptRole); + + m_laterButton = m_buttonBox->addButton( + "", QDialogButtonBox::RejectRole); + + mainLayout->addWidget(m_buttonBox); + + setLayout(mainLayout); + + retranslateUi(); + + BT_CONNECT(m_buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + BT_CONNECT(m_buttonBox, SIGNAL(accepted()), this, SLOT(slotAccept())); + +} + +void BtWelcomeDialog::slotAccept() { + hide(); + accept(); + BibleTime::instance()->slotBookshelfWizard(); +} + +void BtWelcomeDialog::retranslateUi() { + setWindowTitle(tr("Welcome to BibleTime")); + + QString msg("<p>"); + msg += tr("BibleTime is an easy to use but powerful Bible study tool."); + msg += "</p><p>"; + msg += tr("Before you can use this application some works must be installed. "); + msg += tr("Various works such as Bibles, books, commentaries, and lexicons are available from remote libraries. "); + msg += "</p><p>"; + msg += tr("Choose the \"Install works\" button to download works. "); + msg += tr("The menu \"Settings > Bookshelf Manager\" also installs works and can be used later."); + m_label->setText(msg); + + m_laterButton->setText(tr("Install later")); + + m_installButton->setText( QString(" ") + tr("Install works...") + QString(" ")); + QFont font = m_installButton->font(); + font.setBold(true); + m_installButton->setFont(font); +} + +//void BtWelcomeDialog::linkClicked(const QUrl& url) { +// QDesktopServices::openUrl(url); +//} diff --git a/src/frontend/welcome/btwelcomedialog.h b/src/frontend/welcome/btwelcomedialog.h new file mode 100644 index 0000000..0b8320f --- /dev/null +++ b/src/frontend/welcome/btwelcomedialog.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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef BTWELCOMEDIALOG_H +#define BTWELCOMEDIALOG_H + +#include <QDialog> + +class QDialogButtonBox; +class QLabel; + +class BtWelcomeDialog: public QDialog { + + Q_OBJECT + +public: + + BtWelcomeDialog(QWidget *parent = nullptr, Qt::WindowFlags wflags = Qt::Dialog); + + static void openWelcome(); + +protected: + void retranslateUi(); + +private slots: + void slotAccept(); + +private: + + QLabel *m_iconLabel; + QLabel *m_label; + QPushButton *m_laterButton; + QPushButton *m_installButton; + QDialogButtonBox* m_buttonBox; +}; + +#endif diff --git a/src/main.cpp b/src/main.cpp index 6f459b9..93750ca 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,29 +2,30 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ #include <cstdlib> #include <iostream> +#include <memory> #include <QDateTime> -#ifndef NO_DBUS -#include <QDBusConnection> -#endif #include <QFile> #include <QLocale> #include <QTextCodec> #include <QTranslator> +#include "backend/bookshelfmodel/btbookshelfmodel.h" #include "backend/bookshelfmodel/btbookshelftreemodel.h" #include "backend/config/btconfig.h" #include "bibletime.h" -#include "bibletime_dbus_adaptor.h" #include "bibletimeapp.h" #include "frontend/searchdialog/btsearchoptionsarea.h" +#include "frontend/welcome/btwelcomedialog.h" #include "util/directory.h" - +#ifdef Q_OS_WIN +#include <windows.h> +#endif /// \todo Reimplement signal handler which handles consecutive crashes. @@ -60,12 +61,71 @@ void printHelp(const QString &executable) { } /******************************************************************************* + Console messaging. +*******************************************************************************/ + +std::unique_ptr<QFile> debugStream; +bool showDebugMessages = false; + +void myMessageOutput( + QtMsgType type, + const QMessageLogContext&, + const QString& message ) { + QByteArray msg = message.toLatin1(); + switch (type) { + case QtDebugMsg: + if (showDebugMessages) { // Only show messages if they are enabled! + debugStream->write("(BibleTime " BT_VERSION ") Debug: "); + debugStream->write(msg); + debugStream->write("\n"); + debugStream->flush(); + } + break; +#if QT_VERSION >= 0x050500 + case QtInfoMsg: + debugStream->write("(BibleTime " BT_VERSION ") INFO: "); + debugStream->write(msg); + debugStream->write("\n"); + debugStream->flush(); + break; +#endif + case QtWarningMsg: + debugStream->write("(BibleTime " BT_VERSION ") WARNING: "); + debugStream->write(msg); + debugStream->write("\n"); + debugStream->flush(); + break; + case QtCriticalMsg: + debugStream->write("(BibleTime " BT_VERSION ") CRITICAL: "); + debugStream->write(msg); + debugStream->write("\nPlease report this bug at " + "https://github.com/bibletime/bibletime/issues" + "\n"); + debugStream->flush(); + break; + case QtFatalMsg: + debugStream->write("(BibleTime " BT_VERSION ") FATAL: "); + debugStream->write(msg); + debugStream->write("\nPlease report this bug at " + "https://github.com/bibletime/bibletime/issues" + "\n"); + + // Dump core on purpose (see qInstallMsgHandler documentation): + debugStream->close(); + abort(); + } +} + +inline void installMessageHandler() { + qInstallMessageHandler(myMessageOutput); +} + +/******************************************************************************* Parsing command-line arguments *******************************************************************************/ /** Parses all command-line arguments. - \param[out] showDebugMessages Whether --debug was specified. \param[out] ignoreSession Whether --ignore-session was specified. \param[out] openBibleKey Will be set to --open-default-bible if specified. \retval -1 Parsing was successful, the application should exit with @@ -73,9 +133,7 @@ void printHelp(const QString &executable) { \retval 0 Parsing was successful. \retval 1 Parsing failed, the application should exit with EXIT_FAILURE. */ -int parseCommandLine(bool &showDebugMessages, bool &ignoreSession, - QString &openBibleKey) -{ +int parseCommandLine(bool & ignoreSession, QString & openBibleKey) { QStringList args = BibleTimeApp::arguments(); for (int i = 1; i < args.size(); i++) { const QString &arg = args.at(i); @@ -87,7 +145,8 @@ int parseCommandLine(bool &showDebugMessages, bool &ignoreSession, printHelp(args.at(0)); return -1; } else if (arg == "--version" - || arg == "-V") + || arg == "-V" + || arg == "/V") { std::cout << "BibleTime " BT_VERSION << std::endl; return -1; @@ -118,72 +177,6 @@ int parseCommandLine(bool &showDebugMessages, bool &ignoreSession, } /******************************************************************************* - Console messaging. -*******************************************************************************/ - -#if QT_VERSION >= 0x040600 -QScopedPointer<QFile> debugStream; -#else -struct DebugStreamPtr { - QFile * m_f; - inline DebugStreamPtr() : m_f(0) {} - inline ~DebugStreamPtr() { delete m_f; } - inline void reset(QFile * f) { m_f = f; } - inline QFile * operator->() const { - Q_ASSERT(m_f); - return m_f; - } -} debugStream; -#endif -bool showDebugMessages = false; - -void myMessageOutput( - QtMsgType type, -#if QT_VERSION >= 0x050000 - const QMessageLogContext&, - const QString& message ) { - QByteArray msg = message.toLatin1(); -#else - const char *msg ) { -#endif - // We use this messagehandler to switch debugging off in final releases - switch (type) { - case QtDebugMsg: - if (showDebugMessages) { // Only show messages if they are enabled! - debugStream->write("(BibleTime " BT_VERSION ") Debug: "); - debugStream->write(msg); - debugStream->write("\n"); - debugStream->flush(); - } - break; - case QtWarningMsg: -#ifndef QT_NO_DEBUG // don't show in release builds so users don't get our debug warnings - debugStream->write("(BibleTime " BT_VERSION ") WARNING: "); - debugStream->write(msg); - debugStream->write("\n"); - debugStream->flush(); -#endif - break; - case QtCriticalMsg: - debugStream->write("(BibleTime " BT_VERSION ") CRITICAL: "); - debugStream->write(msg); - debugStream->write("\nPlease report this bug at " - "http://bugs.bibletime.info/"); - debugStream->flush(); - break; - case QtFatalMsg: - debugStream->write("(BibleTime " BT_VERSION ") FATAL: "); - debugStream->write(msg); - debugStream->write("\nPlease report this bug at " - "http://bugs.bibletime.info/"); - - // Dump core on purpose (see qInstallMsgHandler documentation): - debugStream->close(); - abort(); - } -} - -/******************************************************************************* Handle Qt's meta type system. *******************************************************************************/ @@ -198,8 +191,8 @@ void registerMetaTypes() { qRegisterMetaType<alignmentMode>("alignmentMode"); qRegisterMetaTypeStreamOperators<alignmentMode>("alignmentMode"); - qRegisterMetaType<Search::BtSearchOptionsArea::SearchType>("SearchType"); - qRegisterMetaTypeStreamOperators<Search::BtSearchOptionsArea::SearchType>("SearchType"); + qRegisterMetaType<CSwordModuleSearch::SearchType>("SearchType"); + qRegisterMetaTypeStreamOperators<CSwordModuleSearch::SearchType>("SearchType"); qRegisterMetaType<BtConfig::StringMap>("StringMap"); qRegisterMetaTypeStreamOperators<BtConfig::StringMap>("StringMap"); @@ -223,11 +216,8 @@ int main(int argc, char* argv[]) { // Parse command line arguments: bool ignoreSession = false; QString openBibleKey; - int r = parseCommandLine(showDebugMessages, ignoreSession, openBibleKey); - if (r != 0) { - if (r < 0) return EXIT_SUCCESS; - return EXIT_FAILURE; - } + if (int const r = parseCommandLine(ignoreSession, openBibleKey)) + return r < 0 ? EXIT_SUCCESS : EXIT_FAILURE; // Initialize random number generator: srand(qHash(QDateTime::currentDateTime().toString(Qt::ISODate))); @@ -239,20 +229,12 @@ int main(int argc, char* argv[]) { if (showDebugMessages) { debugStream.reset(new QFile(QDir::homePath().append("/BibleTime Debug.txt"))); debugStream->open(QIODevice::WriteOnly | QIODevice::Text); -#if QT_VERSION >= 0x050000 - qInstallMessageHandler(myMessageOutput); -#else - qInstallMsgHandler(myMessageOutput); -#endif + installMessageHandler(); } #else debugStream.reset(new QFile); debugStream->open(stderr, QIODevice::WriteOnly | QIODevice::Text); -#if QT_VERSION >= 0x050000 - qInstallMessageHandler(myMessageOutput); -#else - qInstallMsgHandler(myMessageOutput); -#endif + installMessageHandler(); #endif #ifdef Q_OS_WIN @@ -261,9 +243,11 @@ int main(int argc, char* argv[]) { app.addLibraryPath(app.applicationDirPath() + "/plugins"); // Must set HOME var on Windows - QString homeDir(getenv("APPDATA")); - _putenv_s("HOME", qPrintable(homeDir)); - + // getenv and qgetenv don't work right on Windows with unicode characters +#define BUFSIZE 4096 + wchar_t homeDir[BUFSIZE]; + GetEnvironmentVariable(TEXT("APPDATA"), homeDir, BUFSIZE); + SetEnvironmentVariable(TEXT("HOME"), homeDir); #endif registerMetaTypes(); @@ -273,7 +257,7 @@ int main(int argc, char* argv[]) { return EXIT_FAILURE; } - app.startInit(); + app.startInit(showDebugMessages); if (!app.initBtConfig()) { return EXIT_FAILURE; } @@ -303,14 +287,14 @@ int main(int argc, char* argv[]) { BibleTimeTranslator.load( QString("bibletime_ui_").append(QLocale::system().name()), DU::getLocaleDir().canonicalPath()); app.installTranslator(&BibleTimeTranslator); - app.setProperty("--debug", QVariant(showDebugMessages)); - // Initialize display template manager: if (!app.initDisplayTemplateManager()) { qFatal("Error initializing display template manager!"); return EXIT_FAILURE; } + app.initIcons(); + BibleTime *mainWindow = new BibleTime(); mainWindow->setAttribute(Qt::WA_DeleteOnClose); @@ -327,17 +311,12 @@ int main(int argc, char* argv[]) { // The following must be done after the bibletime window is visible: mainWindow->processCommandline(ignoreSession, openBibleKey); -#ifndef NO_DBUS - new BibleTimeDBusAdaptor(mainWindow); - // connect to D-Bus and register as an object: - QDBusConnection::sessionBus().registerService("info.bibletime.BibleTime"); - QDBusConnection::sessionBus().registerObject("/BibleTime", mainWindow); -#endif - - if (btConfig().value<bool>("GUI/showTipAtStartup", true)) + BtBookshelfModel *bookshelfModel = CSwordBackend::instance()->model(); + if (bookshelfModel->moduleList().empty()) + BtWelcomeDialog::openWelcome(); + else if (btConfig().value<bool>("GUI/showTipAtStartup", true)) mainWindow->slotOpenTipDialog(); - r = app.exec(); - return r; + return app.exec(); } diff --git a/src/mobile/ChangeLog b/src/mobile/ChangeLog new file mode 100644 index 0000000..0c12198 --- /dev/null +++ b/src/mobile/ChangeLog @@ -0,0 +1,62 @@ +ChangeLog for BibleTime Mobile + +2016-07-06 + Version 1.07 + Fix more translation issues + +2016-06-22 + Version 1.06 + Fix some translation issues + Fix update of module reference in toolbar + +2016-06-08 + Version 1.05 + Add Spanish translation + +2016-05-24 + Version 1.04 + Add Lithuanian translation + +2016-05-23 + Version 1.03 + Improve the Portuguese translation + +2016-05-14 + Version 1.02 + Improve the Portuguese translation + Fix problem with upper bound of some modules. + +2016-04-25 + Add localization and Portuguese translation + Improve font size sliders + +2014-11-08 + Add color themes with dark and light themes. + +2014-10-06 + Implement setting font name and size for each text language + +2014-08-21 + Set version to 0.2 + +2014-08-16 + Look for documents in 2nd directory (Same as AndBible) + +2014-07-31 + Add history for each window + +2014-06-29 + Add ability to unlock encrypted documents + +2014-06-29 + Improve usability of the Bookshelf (document install/remove panel) + +2014-06-07 + Various improvements to the appearance of the UI + +2014-06.01 + Improve performance of Bookshelf manager + +2014-05-24 + Set version to 0.1 + diff --git a/src/mobile/bibletime.cpp b/src/mobile/bibletime.cpp index dd32bf4..3aed555 100644 --- a/src/mobile/bibletime.cpp +++ b/src/mobile/bibletime.cpp @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -16,7 +16,10 @@ #include "backend/managers/btstringmgr.h" #include "backend/managers/clanguagemgr.h" #include "backend/managers/cswordbackend.h" +#include "bibletimeapp.h" +#include "util/directory.h" #include <QLocale> +#include <QTextStream> #include <stringmgr.h> #include <swlog.h> @@ -33,11 +36,9 @@ 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); - } + sword::SWLog::getSystemLog()->setLogLevel(btApp->debugMode() + ? sword::SWLog::LOG_DEBUG + : sword::SWLog::LOG_ERROR); #ifdef Q_OS_MAC // set a LocaleMgr with a fixed path to the locales.d of the DMG image on MacOS @@ -80,6 +81,21 @@ void BibleTime::initSwordConfigFile() { file.close(); #endif +#ifdef Q_OS_ANDROID + QString configFile = util::directory::getUserHomeSwordDir().filePath("sword.conf"); + QFile file(configFile); + 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 << "AugmentPath=" << util::directory::convertDirSeparators( util::directory::getSharedSwordDir().absolutePath()) << "\n"; + out << "\n"; + file.close(); +#endif + #ifdef Q_OS_MAC QString configFile = util::directory::getUserHomeSwordDir().filePath("sword.conf"); QFile file(configFile); diff --git a/src/mobile/bibletime.h b/src/mobile/bibletime.h index b424571..e353123 100644 --- a/src/mobile/bibletime.h +++ b/src/mobile/bibletime.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -20,7 +20,7 @@ class BibleTime : public QObject { Q_OBJECT public: - BibleTime(QObject* parent = 0); + BibleTime(QObject* parent = nullptr); private: void initBackends(); diff --git a/src/mobile/bibletimeapp.cpp b/src/mobile/bibletimeapp.cpp index f7801b8..707ea6c 100644 --- a/src/mobile/bibletimeapp.cpp +++ b/src/mobile/bibletimeapp.cpp @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -18,21 +18,23 @@ #include "backend/managers/cswordbackend.h" #include "backend/managers/cdisplaytemplatemgr.h" #include "frontend/messagedialog.h" +#include "util/btassert.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) { + , m_init(false) + , m_debugMode(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) + if (!m_init || BtConfig::m_instance == nullptr) return; //we can set this safely now because we close now (hopyfully without crash) @@ -40,56 +42,61 @@ BibleTimeApp::~BibleTimeApp() { btConfig().setValue("state/crashedTwoTimes", false); delete CDisplayTemplateMgr::instance(); + CLanguageMgr::destroyInstance(); CSwordBackend::destroyInstance(); - util::clearIconCache(); BtConfig::destroyInstance(); } bool BibleTimeApp::initBtConfig() { - Q_ASSERT(m_init); + BT_ASSERT(m_init); - return BtConfig::initBtConfig(); + BtConfig::InitState const r = BtConfig::initBtConfig(); + if (r == BtConfig::INIT_OK) + return true; + if (r == BtConfig::INIT_NEED_UNIMPLEMENTED_FORWARD_MIGRATE) { + /// \todo Migrate from btConfigOldApi to BTCONFIG_API_VERSION + qWarning() << "BibleTime configuration migration is not yet implemented!!!"; + if (message::showWarning( + nullptr, + tr("Warning!"), + tr("Migration to the new configuration system is not yet " + "implemented. Proceeding might result in <b>loss of data" + "</b>. Please backup your configuration files before " + "you continue!<br/><br/>Do you want to continue? Press " + "\"No\" to quit BibleTime immediately."), + QMessageBox::Yes | QMessageBox::No, + QMessageBox::No) == QMessageBox::No) + return false; + } else { + BT_ASSERT(r == BtConfig::INIT_NEED_UNIMPLEMENTED_BACKWARD_MIGRATE); + if (message::showWarning( + nullptr, + tr("Error loading configuration!"), + tr("Failed to load BibleTime's configuration, because it " + "appears that the configuration file corresponds to a " + "newer version of BibleTime. This is likely caused by " + "BibleTime being downgraded. Loading the new " + "configuration file may result in <b>loss of data</b>." + "<br/><br/>Do you still want to try to load the new " + "configuration file? Press \"No\" to quit BibleTime " + "immediately."), + QMessageBox::Yes | QMessageBox::No, + QMessageBox::No) == QMessageBox::No) + return false; + } + BtConfig::forceMigrate(); + return true; } bool BibleTimeApp::initDisplayTemplateManager() { - Q_ASSERT(m_init); + BT_ASSERT(m_init); QString errorMessage; new CDisplayTemplateMgr(errorMessage); if (errorMessage.isNull()) return true; - message::showCritical(0, tr("Fatal error!"), errorMessage); + message::showCritical(nullptr, 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 index 08cd0a5..f92cd42 100644 --- a/src/mobile/bibletimeapp.h +++ b/src/mobile/bibletimeapp.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -14,8 +14,6 @@ #define BIBLETIMEAPP_H #include <QGuiApplication> -#include <QIcon> -#include <QMap> /** @@ -31,25 +29,23 @@ class BibleTimeApp : public QGuiApplication { BibleTimeApp(int &argc, char **argv); ~BibleTimeApp(); - inline void startInit() { m_init = true; } + inline void startInit(bool const debugMode = false) { + m_init = true; + m_debugMode = debugMode; + } + 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; + bool debugMode() const { return m_debugMode; } private: /* Fields: */ - mutable QMap<QString, QIcon> m_iconCache; - const QIcon m_nullIcon; bool m_init; + bool m_debugMode; }; -#define bApp (static_cast<BibleTimeApp *>(QCoreApplication::instance())) +#define btApp (static_cast<BibleTimeApp *>(BibleTimeApp::instance())) #endif diff --git a/src/mobile/bookshelfmanager/installmanager.cpp b/src/mobile/bookshelfmanager/installmanager.cpp index 99a72a0..ab1fc36 100644 --- a/src/mobile/bookshelfmanager/installmanager.cpp +++ b/src/mobile/bookshelfmanager/installmanager.cpp @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -12,15 +12,18 @@ #include "installmanager.h" +#include <QDebug> +#include <QQuickItem> +#include <QtAlgorithms> #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> +#include "util/btassert.h" +#include "util/btconnect.h" + namespace btm { @@ -31,12 +34,13 @@ enum TextRoles { enum WorksRoles { TitleRole = Qt::UserRole + 1, DescriptionRole = Qt::UserRole + 2, - InstalledRole = Qt::UserRole + 3 + SelectedRole = Qt::UserRole + 3, + InstalledRole = Qt::UserRole + 4 }; static bool moduleInstalled(const CSwordModuleInfo& moduleInfo) { const CSwordModuleInfo *installedModule = CSwordBackend::instance()->findModuleByName(moduleInfo.name()); - return installedModule != 0; + return installedModule != nullptr; } static void setupTextModel(const QStringList& modelList, RoleItemModel* model) { @@ -57,12 +61,13 @@ 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()); + BT_ASSERT(titleList.count() == descriptionList.count()); + BT_ASSERT(titleList.count() == installedList.count()); QHash<int, QByteArray> roleNames; roleNames[TitleRole] = "title"; roleNames[DescriptionRole] = "desc"; + roleNames[SelectedRole] = "selected"; roleNames[InstalledRole] = "installed"; model->setRoleNames(roleNames); @@ -75,44 +80,55 @@ static void setupWorksModel(const QStringList& titleList, item->setData(description, DescriptionRole); int installed = installedList.at(i); item->setData(installed, InstalledRole); + item->setData(0, SelectedRole); model->appendRow(item); } } InstallManager::InstallManager(QObject* /* parent */) - : m_installManagerChooserObject(0), - m_btInstallMgr(0) { + : m_installManagerChooserObject(nullptr), + m_btInstallMgr(nullptr), + m_backend(nullptr) { + + BT_CONNECT(&m_installSourcesManager, SIGNAL(sourcesUpdated()), + this, SLOT(updateModels())); } void InstallManager::openChooser() { - if (m_installManagerChooserObject == 0) + if (m_installManagerChooserObject == nullptr) findInstallManagerObject(); - if (m_installManagerChooserObject == 0) + if (m_installManagerChooserObject == nullptr) return; + m_modulesToInstallRemove.clear(); setupSourceModel(); makeConnections(); setProperties(); sourceIndexChanged(0); } +void InstallManager::updateModels() { + setupSourceModel(); + sourceIndexChanged(0); +} + void InstallManager::findInstallManagerObject() { QtQuick2ApplicationViewer* viewer = getViewManager()->getViewer(); - QQuickItem * rootObject = 0; - if (viewer != 0) + QQuickItem * rootObject = nullptr; + if (viewer != nullptr) rootObject = viewer->rootObject(); - if (rootObject != 0) + if (rootObject != nullptr) m_installManagerChooserObject = rootObject->findChild<QQuickItem*>("installManagerChooser"); } void InstallManager::findProgressObject() { QtQuick2ApplicationViewer* viewer = getViewManager()->getViewer(); - QQuickItem * rootObject = 0; - if (viewer != 0) + QQuickItem * rootObject = nullptr; + if (viewer != nullptr) rootObject = viewer->rootObject(); - if (rootObject != 0) + if (rootObject != nullptr) m_progressObject = rootObject->findChild<QQuickItem*>("progress"); } @@ -126,33 +142,20 @@ 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); + BT_CONNECT(m_installManagerChooserObject, SIGNAL(sourceChanged(int)), + this, SLOT(sourceIndexChanged(int))); + BT_CONNECT(m_installManagerChooserObject, SIGNAL(categoryChanged(int)), + this, SLOT(categoryIndexChanged(int))); + BT_CONNECT(m_installManagerChooserObject, SIGNAL(languageChanged(int)), + this, SLOT(languageIndexChanged(int))); + BT_CONNECT(m_installManagerChooserObject, SIGNAL(workSelected(int)), + this, SLOT(workSelected(int))); + BT_CONNECT(m_installManagerChooserObject, SIGNAL(cancel()), + this, SLOT(cancel())); + BT_CONNECT(m_installManagerChooserObject, SIGNAL(installRemove()), + this, SLOT(installRemove())); + BT_CONNECT(m_installManagerChooserObject, SIGNAL(refreshLists()), + this, SLOT(refreshLists())); } void InstallManager::setProperties() { @@ -164,11 +167,18 @@ void InstallManager::setProperties() { m_installManagerChooserObject->setProperty("visible", true); } +void InstallManager::updateSwordBackend() { + QString sourceName = getCurrentListItem("sourceIndex", m_sourceList); + sword::InstallSource source = BtInstallBackend::source(sourceName); + m_backend = BtInstallBackend::backend(source); +} + void InstallManager::sourceIndexChanged(int index) { if (index < 0 || index >= m_sourceList.count()) return; + updateSwordBackend(); updateCategoryAndLanguageModels(); updateWorksModel(); } @@ -189,13 +199,13 @@ void InstallManager::languageIndexChanged(int index) 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); + QVariant vSelected = item->data(SelectedRole); + int selected = vSelected.toInt(); + selected = selected == 0 ? 1 : 0; + item->setData(selected, SelectedRole); CSwordModuleInfo* moduleInfo = m_worksList.at(index); - m_modulesToInstallRemove[moduleInfo] = installed == 1; + m_modulesToInstallRemove[moduleInfo] = selected == 1; } void InstallManager::cancel() { @@ -205,32 +215,32 @@ void InstallManager::cancel() { void InstallManager::installRemove() { m_installManagerChooserObject->setProperty("visible", false); - QList<CSwordModuleInfo*> modulesToRemove; - QList<CSwordModuleInfo*> modulesToInstall; + m_modulesToRemove.clear(); + m_modulesToInstall.clear(); 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); + bool selected = it.value(); + if ( ! selected) + continue; + if (moduleInstalled(*moduleInfo)) { + m_modulesToRemove.append(moduleInfo); } - else if ( ! moduleInstalled(*moduleInfo) && install == true) { - modulesToInstall.append(moduleInfo); + else if ( ! moduleInstalled(*moduleInfo)) { + m_modulesToInstall.append(moduleInfo); } } - removeModules(modulesToRemove); - installModules(modulesToInstall); + installModules(m_modulesToInstall); + removeModules(m_modulesToRemove); } 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(); + if (m_backend == nullptr) + return; + const QList<CSwordModuleInfo*> modules = m_backend->moduleList(); QSet<QString> categories; QSet<QString> languages; @@ -285,14 +295,15 @@ void InstallManager::updateWorksModel() 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(); + if (m_backend == nullptr) + return; + const QList<CSwordModuleInfo*> modules = m_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); @@ -317,47 +328,7 @@ void InstallManager::updateWorksModel() } 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(); + CSwordBackend::instance()->uninstallModules(modules.toSet()); } void InstallManager::installModules(const QList<CSwordModuleInfo*>& modules) { @@ -368,4 +339,7 @@ void InstallManager::refreshLists() { m_installSourcesManager.refreshSources(); } +int InstallManager::getInstalledModuleCount() const { + return 0; +} } // end namespace diff --git a/src/mobile/bookshelfmanager/installmanager.h b/src/mobile/bookshelfmanager/installmanager.h index a976ad8..ee385a9 100644 --- a/src/mobile/bookshelfmanager/installmanager.h +++ b/src/mobile/bookshelfmanager/installmanager.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -16,11 +16,13 @@ #include "installsourcesmanager.h" #include "mobile/models/roleitemmodel.h" #include "installprogress.h" +#include <QList> #include <QMap> #include <QObject> class QQuickItem; class CSwordModuleInfo; +class CSwordBackend; class BtInstallMgr; namespace btm { @@ -29,10 +31,14 @@ class InstallManager :public QObject { Q_OBJECT public: - InstallManager(QObject* parent = 0); + InstallManager(QObject* parent = nullptr); + + Q_PROPERTY(int installedModuleCount READ getInstalledModuleCount) Q_INVOKABLE void openChooser(); + int getInstalledModuleCount() const; + private slots: void cancel(); void categoryIndexChanged(int index); @@ -40,6 +46,7 @@ private slots: void languageIndexChanged(int index); void refreshLists(); void sourceIndexChanged(int index); + void updateModels(); void workSelected(int index); private: @@ -56,12 +63,15 @@ private: const QStringList& list, const QString& itemName); void updateCategoryAndLanguageModels(); + void updateSwordBackend(); void updateWorksModel(); QQuickItem* m_installManagerChooserObject; QQuickItem* m_progressObject; BtInstallMgr* m_btInstallMgr; InstallSourcesManager m_installSourcesManager; + CSwordBackend* m_backend; + InstallProgress m_installProgress; QStringList m_sourceList; @@ -76,6 +86,8 @@ private: RoleItemModel m_categoryModel; RoleItemModel m_languageModel; RoleItemModel m_worksModel; + QList<CSwordModuleInfo*> m_modulesToRemove; + QList<CSwordModuleInfo*> m_modulesToInstall; }; } // end namespace diff --git a/src/mobile/bookshelfmanager/installprogress.cpp b/src/mobile/bookshelfmanager/installprogress.cpp index dd113ec..034611b 100644 --- a/src/mobile/bookshelfmanager/installprogress.cpp +++ b/src/mobile/bookshelfmanager/installprogress.cpp @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -12,28 +12,34 @@ #include "installprogress.h" +#include <QDebug> +#include <QQuickItem> #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> +#include "util/btassert.h" +#include "util/btconnect.h" + namespace btm { InstallProgress::InstallProgress(QObject* parent) - : QObject(parent), m_progressObject(0) { + : QObject(parent), m_progressObject(nullptr), + m_thread(nullptr), m_nextInstallIndex(0) { } void InstallProgress::openProgress(const QList<CSwordModuleInfo*>& modules) { if (modules.count() == 0) return; - if (m_progressObject == 0) + m_nextInstallIndex = 0; + m_modules = modules; + if (m_progressObject == nullptr) findProgressObject(); - if (m_progressObject == 0) + if (m_progressObject == nullptr) return; QString destination = getSourcePath(); @@ -42,27 +48,24 @@ void InstallProgress::openProgress(const QList<CSwordModuleInfo*>& modules) { 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(); + m_thread = new BtInstallThread(m_modules, destination, this); + // Connect the signals between the dialog, items and threads + BT_CONNECT(m_thread, SIGNAL(preparingInstall(int)), + this, SLOT(slotInstallStarted(int)), + Qt::QueuedConnection); + BT_CONNECT(m_thread, SIGNAL(downloadStarted(int)), + this, SLOT(slotDownloadStarted(int)), + Qt::QueuedConnection); + BT_CONNECT(m_thread, SIGNAL(statusUpdated(int, int)), + this, SLOT(slotStatusUpdated(int, int)), + Qt::QueuedConnection); + BT_CONNECT(m_thread, SIGNAL(installCompleted(int, bool)), + this, SLOT(slotOneItemCompleted(int, bool)), + Qt::QueuedConnection); + BT_CONNECT(m_thread, SIGNAL(finished()), + this, SLOT(slotThreadFinished()), + Qt::QueuedConnection); + m_thread->start(); } void InstallProgress::cancel() { @@ -74,98 +77,47 @@ void InstallProgress::close() { 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::slotStopInstall() { + m_thread->stopInstall(); } -void InstallProgress::slotOneItemStopped(QString module, QString source) { - oneItemStoppedOrCompleted(module, source, tr("Cancelled")); +QString InstallProgress::getModuleName(int moduleIndex) { + BT_ASSERT(moduleIndex < m_modules.count()); + CSwordModuleInfo * module = m_modules.at(moduleIndex); + return module->name(); } -// 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::slotInstallStarted(int moduleIndex) { + BT_ASSERT(moduleIndex == m_nextInstallIndex); + m_nextInstallIndex++; + QString message = tr("Installing") + " " + getModuleName(moduleIndex); + m_progressObject->setProperty("text", message); } -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::slotDownloadStarted(int moduleIndex) { + m_progressObject->setProperty("value", 0); + QString message = tr("Downloading")+ " " + getModuleName(moduleIndex); + m_progressObject->setProperty("text", message); } -void InstallProgress::slotStatusUpdated(QString /* module */, int status) { +void InstallProgress::slotStatusUpdated(int /*moduleIndex*/, 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(); - } +void InstallProgress::slotOneItemCompleted(int /* moduleIndex */, bool /* successful */) { + // TODO show failed status } -bool InstallProgress::threadsDone() { - return (m_waitingThreads.isEmpty() && m_runningThreads.isEmpty()); +void InstallProgress::slotThreadFinished() { + close(); } void InstallProgress::findProgressObject() { QtQuick2ApplicationViewer* viewer = getViewManager()->getViewer(); - QQuickItem * rootObject = 0; - if (viewer != 0) + QQuickItem * rootObject = nullptr; + if (viewer != nullptr) rootObject = viewer->rootObject(); - if (rootObject != 0) + if (rootObject != nullptr) m_progressObject = rootObject->findChild<QQuickItem*>("progress"); } diff --git a/src/mobile/bookshelfmanager/installprogress.h b/src/mobile/bookshelfmanager/installprogress.h index 4f9908c..f6f7e84 100644 --- a/src/mobile/bookshelfmanager/installprogress.h +++ b/src/mobile/bookshelfmanager/installprogress.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -13,6 +13,7 @@ #ifndef INSTALL_PROGRESS_H #define INSTALL_PROGRESS_H +#include <QList> #include <QObject> #include <QMultiMap> #include <QMap> @@ -27,35 +28,33 @@ class InstallProgress: public QObject { Q_OBJECT public: - InstallProgress(QObject* parent = 0); + InstallProgress(QObject* parent = nullptr); 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(); + void slotInstallStarted(int moduleIndex); + void slotDownloadStarted(int moduleIndex); + void slotStatusUpdated(int moduleIndex, int status); + void slotOneItemCompleted(int moduleIndex, bool status); + void slotThreadFinished(); private: void findProgressObject(); + QString getModuleName(int moduleIndex); 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; + BtInstallThread * m_thread; + int m_nextInstallIndex; + QList<CSwordModuleInfo*> m_modules; }; - } #endif diff --git a/src/mobile/bookshelfmanager/installsources.cpp b/src/mobile/bookshelfmanager/installsources.cpp index 6f6fa91..076b295 100644 --- a/src/mobile/bookshelfmanager/installsources.cpp +++ b/src/mobile/bookshelfmanager/installsources.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -52,9 +52,8 @@ void InstallSources::refreshWorks(const QStringList& sourceNames) { break; QString sourceName = sourceNames.at(i); int percent = 10 + 90 *((double)i/sourceCount); - QString title = "Refreshing " + sourceName; + QString title = tr("Refreshing") + " " + sourceName; emit percentComplete(percent, title); - qDebug() << title << percent; sword::InstallSource source = BtInstallBackend::source(sourceName); bool result = (m_iMgr->refreshRemoteSource(&source) == 0); if (result) { @@ -69,7 +68,6 @@ void InstallSources::refreshWorks(const QStringList& sourceNames) { void InstallSources::cancel() { m_canceled = true; - qDebug() << "IS canceled"; } } diff --git a/src/mobile/bookshelfmanager/installsources.h b/src/mobile/bookshelfmanager/installsources.h index f552c68..e753625 100644 --- a/src/mobile/bookshelfmanager/installsources.h +++ b/src/mobile/bookshelfmanager/installsources.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -21,7 +21,7 @@ namespace btm { class InstallSources : public QObject { Q_OBJECT public: - InstallSources(QObject *parent = 0); + InstallSources(QObject *parent = nullptr); ~InstallSources(); diff --git a/src/mobile/bookshelfmanager/installsourcesmanager.cpp b/src/mobile/bookshelfmanager/installsourcesmanager.cpp index bc55f12..9a92bee 100644 --- a/src/mobile/bookshelfmanager/installsourcesmanager.cpp +++ b/src/mobile/bookshelfmanager/installsourcesmanager.cpp @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -12,19 +12,22 @@ #include "installsourcesmanager.h" -#include "installsources.h" +#include <QDebug> +#include <QQuickItem> +#include <QThread> #include "backend/btinstallbackend.h" +#include "mobile/bookshelfmanager/installsources.h" #include "mobile/btmmain.h" #include "mobile/ui/qtquick2applicationviewer.h" #include "mobile/ui/viewmanager.h" -#include <QDebug> -#include <QQuickItem> -#include <QThread> +#include "util/btassert.h" +#include "util/btconnect.h" + namespace btm { InstallSourcesManager::InstallSourcesManager(QObject* /* parent */) - : m_worker(0) { + : m_worker(nullptr) { } InstallSourcesManager::~InstallSourcesManager() { @@ -32,17 +35,17 @@ InstallSourcesManager::~InstallSourcesManager() { void InstallSourcesManager::refreshSources() { findProgressObject(); - Q_ASSERT(m_progressObject != 0); - if (m_progressObject == 0) + BT_ASSERT(m_progressObject); + if (m_progressObject == nullptr) return; m_progressObject->disconnect(this); - connect(m_progressObject, SIGNAL(cancel()), this, SLOT(cancel())); + BT_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"); + m_progressObject->setProperty("text", tr("Refreshing Source List")); runThread(); } @@ -56,29 +59,32 @@ 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&))); +// BT_CONNECT(m_worker, SIGNAL(error(QString)), +// this, SLOT(errorString(QString))); + BT_CONNECT(thread, SIGNAL(started()), m_worker, SLOT(process())); + BT_CONNECT(m_worker, SIGNAL(finished()), thread, SLOT(quit())); + BT_CONNECT(m_worker, SIGNAL(finished()), m_worker, SLOT(deleteLater())); + BT_CONNECT(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); + BT_CONNECT(m_worker, SIGNAL(percentComplete(int, QString const &)), + this, SLOT(percentComplete(int, QString const &))); thread->start(); } void InstallSourcesManager::percentComplete(int percent, const QString& title) { m_progressObject->setProperty("value", percent); m_progressObject->setProperty("text", title); - if (percent == 100) + if (percent == 100) { m_progressObject->setProperty("visible", false); + emit sourcesUpdated(); + } } void InstallSourcesManager::findProgressObject() { QtQuick2ApplicationViewer* viewer = getViewManager()->getViewer(); - QQuickItem * rootObject = 0; - if (viewer != 0) + QQuickItem * rootObject = nullptr; + if (viewer != nullptr) rootObject = viewer->rootObject(); - if (rootObject != 0) + if (rootObject != nullptr) m_progressObject = rootObject->findChild<QQuickItem*>("progress"); } diff --git a/src/mobile/bookshelfmanager/installsourcesmanager.h b/src/mobile/bookshelfmanager/installsourcesmanager.h index 07665b4..3fa2f2b 100644 --- a/src/mobile/bookshelfmanager/installsourcesmanager.h +++ b/src/mobile/bookshelfmanager/installsourcesmanager.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -24,11 +24,14 @@ class InstallSourcesManager :public QObject { Q_OBJECT public: - InstallSourcesManager(QObject* parent = 0); + InstallSourcesManager(QObject* parent = nullptr); ~InstallSourcesManager(); void refreshSources(); +signals: + void sourcesUpdated(); + private slots: void cancel(); void percentComplete(int percent, const QString& title); diff --git a/src/mobile/btm.qrc b/src/mobile/btm.qrc new file mode 100644 index 0000000..e08b7a2 --- /dev/null +++ b/src/mobile/btm.qrc @@ -0,0 +1,61 @@ +<RCC> + <qresource prefix="/share/bibletime"> + <file>qml/About.qml</file> + <file>qml/BtButtonStyle.qml</file> + <file>qml/ContextMenu.qml</file> + <file>qml/FontSizeSlider.qml</file> + <file>qml/GridChooserButton.qml</file> + <file>qml/GridChooser.qml</file> + <file>qml/InstallManagerChooser.qml</file> + <file>qml/KeyNameChooser.qml</file> + <file>qml/LeftArrow.qml</file> + <file>qml/ListSelectView.qml</file> + <file>qml/ListTextView.qml</file> + <file>qml/ListWorksView.qml</file> + <file>qml/main.qml</file> + <file>qml/MainToolbar.qml</file> + <file>qml/MenuButton.qml</file> + <file>qml/Menus.qml</file> + <file>qml/ModuleChooser.qml</file> + <file>qml/PrevNextArrow.qml</file> + <file>qml/Progress.qml</file> + <file>qml/Question.qml</file> + <file>qml/RightArrow.qml</file> + <file>qml/Search.qml</file> + <file>qml/SearchIcon.qml</file> + <file>qml/SearchResults.qml</file> + <file>qml/StartupBookshelfManager.qml</file> + <file>qml/SetFont.qml</file> + <file>qml/TitleColorBar.qml</file> + <file>qml/SimpleComboBox.qml</file> + <file>qml/TreeChooser.qml</file> + <file>qml/WindowManager.qml</file> + <file>qml/Window.qml</file> + </qresource> + <qresource prefix="/share/bibletime/license"> + <file>qml/main.qml</file> + </qresource> + <qresource prefix="/share/bibletime/javascript"> + <file>qml/main.qml</file> + </qresource> + <qresource prefix="/share/bibletime/pics"> + <file>qml/main.qml</file> + </qresource> + <qresource prefix="/share/bibletime/docs/handbook/en"> + <file>qml/main.qml</file> + </qresource> + <qresource prefix="/share/bibletime/docs/howto/en"> + <file>qml/main.qml</file> + </qresource> + <qresource prefix="/share/bibletime/icons"> + <file alias="back.svg">../../pics/icons/back.svg</file> + <file alias="bibletime.svg">../../pics/icons/bibletime.svg</file> + <file alias="forward.svg">../../pics/icons/forward.svg</file> + </qresource> + <qresource prefix="/"/> + <qresource prefix="/share/bibletime/display-templates"> + <file alias="Basic.tmpl">../display-templates/Basic-mobile.tmpl</file> + <file alias="Simple.css">../display-templates/Simple.css</file> + <file alias="Blue.css">../display-templates/Blue.css</file> + </qresource> +</RCC> diff --git a/src/mobile/btmmain.cpp b/src/mobile/btmmain.cpp index 12cbbf4..ed762ae 100644 --- a/src/mobile/btmmain.cpp +++ b/src/mobile/btmmain.cpp @@ -4,33 +4,43 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * **********/ +#include <QBrush> +#include <QColor> +#include <QDateTime> +#include <QGuiApplication> +#include <QPalette> +#include <QQuickItem> +#include <QQmlDebuggingEnabler> +#include <QMetaType> +#include <QTranslator> #include "bibletime.h" #include "backend/config/btconfig.h" +#include "backend/managers/cswordbackend.h" #include "backend/bookshelfmodel/btbookshelftreemodel.h" #include "mobile/bibletimeapp.h" #include "mobile/bookshelfmanager/installmanager.h" +#include "mobile/models/searchmodel.h" +#include "mobile/sessionmanager/sessionmanager.h" #include "mobile/ui/btstyle.h" +#include "mobile/ui/btsearchinterface.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/btassert.h" #include "util/directory.h" +#include "util/findqmlobject.h" + -btm::ViewManager* mgr = 0; +btm::ViewManager* mgr = nullptr; +btm::SessionManager* sessionMgr = nullptr; +static QFont defaultFont; void register_gml_classes() { QQmlDebuggingEnabler enabler; @@ -39,12 +49,60 @@ void register_gml_classes() { qmlRegisterType<btm::BtStyle>("BibleTime", 1, 0, "BtStyle"); qmlRegisterType<btm::InstallManager>("BibleTime", 1, 0, "InstallManager"); qmlRegisterType<btm::ModuleInterface>("BibleTime", 1, 0, "ModuleInterface"); + qmlRegisterType<btm::SearchModel>("BibleTime", 1, 0, "SearchModel"); + qmlRegisterType<btm::BtSearchInterface>("BibleTime", 1, 0, "BtSearchInterface"); } btm::ViewManager* getViewManager() { return mgr; } +QFont getDefaultFont() { + return defaultFont; +} + +void openBookshelfManager() { + QQuickItem* item = btm::findQmlObject("startupBookshelfManager"); + BT_ASSERT(item); + if (item == nullptr) + return; + + item->setProperty("visible", true); + +} + +#if defined(Q_OS_WIN) || defined(Q_OS_ANDROID) +// Copies locale.qrc files into home sword directory under locales.d directory +static void installSwordLocales(QDir& homeSword) +{ + QDir sourceSwordLocales(":/sword/locales.d"); + if (!sourceSwordLocales.exists()) + return; + + QStringList filters; + filters << "*.conf"; + QFileInfoList fileInfoList = sourceSwordLocales.entryInfoList(filters); + + if (!homeSword.exists("locales.d")) + homeSword.mkdir(("locales.d")); + homeSword.cd("locales.d"); + + for (auto sourceFileInfo : fileInfoList) { + + QString fileName = sourceFileInfo.fileName(); + QString sourceFilePath = sourceFileInfo.absoluteFilePath(); + QFile sourceFile(sourceFilePath); + + QFileInfo destinationFileInfo(homeSword, fileName); + QString destinationFilePath = destinationFileInfo.absoluteFilePath(); + QFile destinationFile(destinationFileInfo.absoluteFilePath()); + + destinationFile.remove(); + sourceFile.copy(destinationFilePath); + } +} +#endif + /******************************************************************************* Handle Qt's meta type system. *******************************************************************************/ @@ -72,35 +130,67 @@ int main(int argc, char *argv[]) { registerMetaTypes(); + defaultFont = app.font(); + if (!DU::initDirectoryCache()) { qFatal("Error initializing directory cache!"); return EXIT_FAILURE; } +#if defined(Q_OS_WIN) || defined(Q_OS_ANDROID) + // change directory to the Sword or .sword directory in the $HOME dir so that + // the sword.conf is found. It points to the sword/locales.d directory + // This is also needed for the AugmentPath or DataPath to work + QString homeSwordDir = util::directory::getUserHomeSwordDir().absolutePath(); + QDir dir; + dir.setCurrent(homeSwordDir); +#endif + app.startInit(); if (!app.initBtConfig()) { return EXIT_FAILURE; } +#if defined(Q_OS_WIN) || defined(Q_OS_ANDROID) + if (btm::BtStyle::getAppVersion() > btConfig().value<QString>("btm/version")) { + installSwordLocales(dir); + btConfig().setValue<QString>("btm/version", btm::BtStyle::getAppVersion()); + } +#endif + //first install QT's own translations QTranslator qtTranslator; - qtTranslator.load("qt_" + QLocale::system().name()); + QString locale = QLocale::system().name(); + qtTranslator.load("qt_" + locale); 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(); -// } + QTranslator bibleTimeTranslator; + bibleTimeTranslator.load( QString("mobile_ui_").append(locale), DU::getLocaleDir().canonicalPath()); + app.installTranslator(&bibleTimeTranslator); + + // Initialize display template manager: + if (!app.initDisplayTemplateManager()) { + qFatal("Error initializing display template manager!"); + return EXIT_FAILURE; + } register_gml_classes(); + mgr = new btm::ViewManager; mgr->show(); + btm::BibleTime btm; - return app.exec(); + sessionMgr = new btm::SessionManager(); + int installedModules = CSwordBackend::instance()->moduleList().count(); + if (installedModules == 0) { + openBookshelfManager(); + } + else { + sessionMgr->loadDefaultSession(); + } + + int rtn = app.exec(); + sessionMgr->saveDefaultSession(); + return rtn; } diff --git a/src/mobile/btmmain.h b/src/mobile/btmmain.h index 64bd25e..68e777a 100644 --- a/src/mobile/btmmain.h +++ b/src/mobile/btmmain.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -19,5 +19,9 @@ namespace btm { btm::ViewManager* getViewManager(); +void openBookshelfManager(); + +QFont getDefaultFont(); + #endif diff --git a/src/mobile/keychooser/bookkeychooser.cpp b/src/mobile/keychooser/bookkeychooser.cpp index 9ae3ef9..a9ea29d 100644 --- a/src/mobile/keychooser/bookkeychooser.cpp +++ b/src/mobile/keychooser/bookkeychooser.cpp @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -13,8 +13,6 @@ #include "bookkeychooser.h" #include <cmath> -#include "mobile/ui/btwindowinterface.h" -#include "mobile/ui/qtquick2applicationviewer.h" #include <QCoreApplication> #include <QDebug> #include <QQmlProperty> @@ -23,6 +21,11 @@ #include <QQuickItem> #include <QStandardItem> #include <QString> +#include "mobile/ui/btwindowinterface.h" +#include "mobile/ui/qtquick2applicationviewer.h" +#include "util/btassert.h" +#include "util/btconnect.h" + namespace btm { @@ -37,8 +40,8 @@ BookKeyChooser::BookKeyChooser(QtQuick2ApplicationViewer* viewer, BtWindowInterface* windowInterface) : m_viewer(viewer), m_windowInterface(windowInterface), - m_key(0), - m_treeChooserObject(0), + m_key(nullptr), + m_treeChooserObject(nullptr), m_state(CLOSED ) { findTreeChooserObject(); initializeRoleNameModel(); @@ -53,7 +56,7 @@ void BookKeyChooser::copyKey() void BookKeyChooser::findTreeChooserObject() { QQuickItem * rootObject = m_viewer->rootObject(); - if (rootObject != 0) + if (rootObject != nullptr) m_treeChooserObject = rootObject->findChild<QQuickItem*>("treeChooser"); } @@ -66,7 +69,7 @@ void BookKeyChooser::initializeRoleNameModel() { void BookKeyChooser::populateRoleNameModel(const QStringList& sibblings, const QList<int>& sibblingChildCounts) { m_roleItemModel.clear(); - Q_ASSERT(sibblings.count() == sibblingChildCounts.count()); + BT_ASSERT(sibblings.count() == sibblingChildCounts.count()); for (int i=0; i< sibblings.count(); ++i) { QString sibbling = sibblings.at(i); int childCount = sibblingChildCounts.at(i); @@ -179,22 +182,17 @@ void BookKeyChooser::setProperties() { } void BookKeyChooser::openChooser(bool open) { - Q_ASSERT(m_treeChooserObject != 0); - if (m_treeChooserObject == 0) + BT_ASSERT(m_treeChooserObject); + if (m_treeChooserObject == nullptr) 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); + BT_CONNECT(m_treeChooserObject, SIGNAL(select(QString)), + this, SLOT(select(QString))); + BT_CONNECT(m_treeChooserObject, SIGNAL(next(QString)), + this, SLOT(next(QString))); + BT_CONNECT(m_treeChooserObject, SIGNAL(back()), + this, SLOT(back())); setProperties(); diff --git a/src/mobile/keychooser/bookkeychooser.h b/src/mobile/keychooser/bookkeychooser.h index 720e5f0..1dacbc5 100644 --- a/src/mobile/keychooser/bookkeychooser.h +++ b/src/mobile/keychooser/bookkeychooser.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * diff --git a/src/mobile/keychooser/keynamechooser.cpp b/src/mobile/keychooser/keynamechooser.cpp new file mode 100644 index 0000000..dd1c4e5 --- /dev/null +++ b/src/mobile/keychooser/keynamechooser.cpp @@ -0,0 +1,65 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +#include "keynamechooser.h" + +#include <QQuickItem> +#include "backend/keys/cswordldkey.h" +#include "backend/models/btmoduletextmodel.h" +#include "mobile/ui/btwindowinterface.h" +#include "mobile/ui/qtquick2applicationviewer.h" +#include "util/btassert.h" +#include "util/btconnect.h" + + +namespace btm { + +KeyNameChooser::KeyNameChooser(QtQuick2ApplicationViewer* viewer, + BtWindowInterface* windowInterface) + : m_viewer(viewer), + m_windowInterface(windowInterface), + m_key(nullptr), + m_keyNameChooserObject(nullptr) { + findKeyNameChooserObject(); +} + +void KeyNameChooser::open(BtModuleTextModel* model) { + m_keyNameChooserObject->setProperty("model", QVariant::fromValue(model)); + openChooser(true); +} + +void KeyNameChooser::openChooser(bool open) { + BT_ASSERT(m_keyNameChooserObject); + if (m_keyNameChooserObject == nullptr) + return; + + m_keyNameChooserObject->disconnect(); + BT_CONNECT(m_keyNameChooserObject, SIGNAL(itemSelected(int)), + this, SLOT(selected(int))); + + m_keyNameChooserObject->setProperty("visible",open); +} + +void KeyNameChooser::selected(int index) { + emit referenceChanged(index); +} + +void KeyNameChooser::findKeyNameChooserObject() { + QQuickItem * rootObject = m_viewer->rootObject(); + if (rootObject != nullptr) + m_keyNameChooserObject = rootObject->findChild<QQuickItem*>("keyNameChooser"); + BT_ASSERT(m_keyNameChooserObject); +} + + + +} // end namespace diff --git a/src/mobile/keychooser/keynamechooser.h b/src/mobile/keychooser/keynamechooser.h new file mode 100644 index 0000000..e70b2af --- /dev/null +++ b/src/mobile/keychooser/keynamechooser.h @@ -0,0 +1,66 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +#ifndef KEY_NAME_CHOOSER_H +#define KEY_NAME_CHOOSER_H + +#include <QObject> + +class CSwordLDKey; +class QtQuick2ApplicationViewer; +class QQmlComponent; +class QQuickItem; +class BtModuleTextModel; + +/** + \brief Handles signals and properties of KeyNameChooser.qml + + The KeyNameChooser.qml object is in the main.qml. It need to + be called from a lexicon Window.qml. This module assists this + process by setting the visibility and model to open the KEY_NAME_CHOOSER + and then catches the signals to finish the choice and close the chooser. + */ + + +namespace btm { + +class BtWindowInterface; + +class KeyNameChooser : public QObject { + Q_OBJECT + +public: + KeyNameChooser(QtQuick2ApplicationViewer* viewer, + BtWindowInterface* windowInterface); + void open(BtModuleTextModel* model); + +signals: + void referenceChanged(int index); + +private slots: + void selected(int index); + +private: + void findKeyNameChooserObject(); + void openChooser(bool open); + void setProperties(); + + QtQuick2ApplicationViewer* m_viewer; + BtWindowInterface* m_windowInterface; + CSwordLDKey* m_key; + QQuickItem* m_keyNameChooserObject; + +}; + +} // end namespace + +#endif diff --git a/src/mobile/keychooser/versechooser.cpp b/src/mobile/keychooser/versechooser.cpp index f510da0..04a564c 100644 --- a/src/mobile/keychooser/versechooser.cpp +++ b/src/mobile/keychooser/versechooser.cpp @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -12,36 +12,37 @@ #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> +#include "backend/drivers/cswordbiblemoduleinfo.h" +#include "backend/drivers/cswordmoduleinfo.h" +#include "backend/keys/cswordversekey.h" +#include "mobile/ui/btwindowinterface.h" +#include "mobile/ui/gridchooser.h" +#include "mobile/ui/qtquick2applicationviewer.h" +#include "util/btconnect.h" + namespace btm { VerseChooser::VerseChooser(QtQuick2ApplicationViewer* viewer, BtWindowInterface* bibleVerse) : m_viewer(viewer), - m_gridChooser(0), + m_gridChooser(nullptr), bibleVerse_(bibleVerse), - m_key(0), + m_key(nullptr), 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); + BT_CONNECT(m_gridChooser, SIGNAL(accepted(QString const &)), + this, SLOT(stringAccepted(QString const &))); } void VerseChooser::open(CSwordVerseKey* key) { - if (key == 0) + if (key == nullptr) return; m_key = key; m_oldBook = getBook(); @@ -49,7 +50,7 @@ void VerseChooser::open(CSwordVerseKey* key) { m_oldVerse = getVerse(); m_state = BOOK; QStringList books = getBooks(); - m_gridChooser->open(books, m_oldBook, "Book"); + m_gridChooser->open(books, m_oldBook, tr("Book")); } void VerseChooser::stringAccepted(const QString& value) { @@ -58,14 +59,14 @@ void VerseChooser::stringAccepted(const QString& value) { m_state = CHAPTER; setBook(value); QStringList chapters = getChapters(); - m_gridChooser->open(chapters, m_oldChapter, "Chapter"); + m_gridChooser->open(chapters, m_oldChapter, tr("Chapter")); } else if (m_state == CHAPTER) { m_newChapter = value; m_state = VERSE; setChapter(value); QStringList verses = getVerses(); - m_gridChooser->open(verses, m_oldVerse, "Verse"); + m_gridChooser->open(verses, m_oldVerse, tr("Verse")); } else if (m_state == VERSE) { m_newVerse = value; diff --git a/src/mobile/keychooser/versechooser.h b/src/mobile/keychooser/versechooser.h index 3c7f52b..28adabb 100644 --- a/src/mobile/keychooser/versechooser.h +++ b/src/mobile/keychooser/versechooser.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * diff --git a/src/mobile/locales.qrc b/src/mobile/locales.qrc new file mode 100644 index 0000000..de50121 --- /dev/null +++ b/src/mobile/locales.qrc @@ -0,0 +1,93 @@ +<RCC> + <qresource prefix="/"> + <file>../../../sword/locales.d/abbr.conf</file> + <file>../../../sword/locales.d/af.conf</file> + <file>../../../sword/locales.d/af-utf8.conf</file> + <file>../../../sword/locales.d/ar_EG-cp1256.conf</file> + <file>../../../sword/locales.d/ar_EG-utf8.conf</file> + <file>../../../sword/locales.d/ar-utf8.conf</file> + <file>../../../sword/locales.d/az-utf8.conf</file> + <file>../../../sword/locales.d/bg_BG-cp1251.conf</file> + <file>../../../sword/locales.d/bg-utf8.conf</file> + <file>../../../sword/locales.d/cs.conf</file> + <file>../../../sword/locales.d/cs-utf8.conf</file> + <file>../../../sword/locales.d/cy.conf</file> + <file>../../../sword/locales.d/cy-utf8.conf</file> + <file>../../../sword/locales.d/da.conf</file> + <file>../../../sword/locales.d/da-utf8.conf</file> + <file>../../../sword/locales.d/de.conf</file> + <file>../../../sword/locales.d/de_abbrev.conf</file> + <file>../../../sword/locales.d/de_abbrev-utf8.conf</file> + <file>../../../sword/locales.d/de-utf8.conf</file> + <file>../../../sword/locales.d/es.conf</file> + <file>../../../sword/locales.d/es-utf8.conf</file> + <file>../../../sword/locales.d/et.conf</file> + <file>../../../sword/locales.d/et_abbr.conf</file> + <file>../../../sword/locales.d/et_abbr-utf8.conf</file> + <file>../../../sword/locales.d/et-utf8.conf</file> + <file>../../../sword/locales.d/fa-utf8.conf</file> + <file>../../../sword/locales.d/fi.conf</file> + <file>../../../sword/locales.d/fi-utf8.conf</file> + <file>../../../sword/locales.d/fo-utf8.conf</file> + <file>../../../sword/locales.d/fr.conf</file> + <file>../../../sword/locales.d/fr_abbrev.conf</file> + <file>../../../sword/locales.d/fr_abbrev-utf8.conf</file> + <file>../../../sword/locales.d/fr-utf8.conf</file> + <file>../../../sword/locales.d/ga-utf8.conf</file> + <file>../../../sword/locales.d/he-utf8.conf</file> + <file>../../../sword/locales.d/hr-utf8.conf</file> + <file>../../../sword/locales.d/hu.conf</file> + <file>../../../sword/locales.d/hu-utf8.conf</file> + <file>../../../sword/locales.d/id.conf</file> + <file>../../../sword/locales.d/id-utf8.conf</file> + <file>../../../sword/locales.d/it.conf</file> + <file>../../../sword/locales.d/it-utf8.conf</file> + <file>../../../sword/locales.d/iu-utf8.conf</file> + <file>../../../sword/locales.d/ja-utf8.conf</file> + <file>../../../sword/locales.d/ko.conf</file> + <file>../../../sword/locales.d/ko_abbrev.conf</file> + <file>../../../sword/locales.d/ko_abbrev-utf8.conf</file> + <file>../../../sword/locales.d/ko-utf8.conf</file> + <file>../../../sword/locales.d/la.conf</file> + <file>../../../sword/locales.d/la-utf8.conf</file> + <file>../../../sword/locales.d/locales.conf</file> + <file>../../../sword/locales.d/lt-utf8.conf</file> + <file>../../../sword/locales.d/Makefile.am</file> + <file>../../../sword/locales.d/mt-utf8.conf</file> + <file>../../../sword/locales.d/nb.conf</file> + <file>../../../sword/locales.d/nb-utf8.conf</file> + <file>../../../sword/locales.d/nl.conf</file> + <file>../../../sword/locales.d/nl-utf8.conf</file> + <file>../../../sword/locales.d/no.conf</file> + <file>../../../sword/locales.d/no-utf8.conf</file> + <file>../../../sword/locales.d/pl.conf</file> + <file>../../../sword/locales.d/pl-utf8.conf</file> + <file>../../../sword/locales.d/pon_utf8.conf</file> + <file>../../../sword/locales.d/pt.conf</file> + <file>../../../sword/locales.d/pt_BR.conf</file> + <file>../../../sword/locales.d/pt_BR-utf8.conf</file> + <file>../../../sword/locales.d/pt-utf8.conf</file> + <file>../../../sword/locales.d/ro.conf</file> + <file>../../../sword/locales.d/ro-utf8.conf</file> + <file>../../../sword/locales.d/ru_RU-cp1251.conf</file> + <file>../../../sword/locales.d/ru_RU-koi8-r.conf</file> + <file>../../../sword/locales.d/ru_RU-utf8.conf</file> + <file>../../../sword/locales.d/ru-utf8.conf</file> + <file>../../../sword/locales.d/sk.conf</file> + <file>../../../sword/locales.d/sk-utf8.conf</file> + <file>../../../sword/locales.d/sl.conf</file> + <file>../../../sword/locales.d/sl-utf8.conf</file> + <file>../../../sword/locales.d/sv.conf</file> + <file>../../../sword/locales.d/sv-utf8.conf</file> + <file>../../../sword/locales.d/th-utf8.conf</file> + <file>../../../sword/locales.d/uk_UA-cp1251.conf</file> + <file>../../../sword/locales.d/uk_UA-koi8-u.conf</file> + <file>../../../sword/locales.d/uk-utf8.conf</file> + <file>../../../sword/locales.d/vi-utf8.conf</file> + <file>../../../sword/locales.d/zh_CN-utf8.conf</file> + <file>../../../sword/locales.d/zh_english-utf8.conf</file> + <file>../../../sword/locales.d/zh_Hans-utf8.conf</file> + <file>../../../sword/locales.d/zh_Hant-utf8.conf</file> + <file>../../../sword/locales.d/zh_TW-utf8.conf</file> + </qresource> +</RCC> diff --git a/src/mobile/models/bibletextmodelbuilder.cpp b/src/mobile/models/bibletextmodelbuilder.cpp deleted file mode 100644 index 20faf14..0000000 --- a/src/mobile/models/bibletextmodelbuilder.cpp +++ /dev/null @@ -1,184 +0,0 @@ -/********* -* -* 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 deleted file mode 100644 index 620810a..0000000 --- a/src/mobile/models/bibletextmodelbuilder.h +++ /dev/null @@ -1,46 +0,0 @@ -/********* -* -* 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 deleted file mode 100644 index 44d5d92..0000000 --- a/src/mobile/models/booktextmodelbuilder.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/********* -* -* 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 deleted file mode 100644 index a64c380..0000000 --- a/src/mobile/models/booktextmodelbuilder.h +++ /dev/null @@ -1,40 +0,0 @@ -/********* -* -* 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 index 95634af..d215b8b 100644 --- a/src/mobile/models/roleitemmodel.cpp +++ b/src/mobile/models/roleitemmodel.cpp @@ -1,3 +1,15 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + #include "roleitemmodel.h" /* Example usage: diff --git a/src/mobile/models/roleitemmodel.h b/src/mobile/models/roleitemmodel.h index 46f02be..42a3c17 100644 --- a/src/mobile/models/roleitemmodel.h +++ b/src/mobile/models/roleitemmodel.h @@ -1,3 +1,15 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + #ifndef ROLEITEMMODEL_H #define ROLEITEMMODEL_H @@ -13,7 +25,7 @@ public: // is associated with what name on QML side (e.g. 'bookTitle') // RoleItemModel(const QHash<int, QByteArray> &roleNames); - QHash<int, QByteArray> roleNames() const; + QHash<int, QByteArray> roleNames() const override; void setRoleNames(const QHash<int, QByteArray> &roleNames); private: diff --git a/src/mobile/models/searchmodel.cpp b/src/mobile/models/searchmodel.cpp new file mode 100644 index 0000000..148d150 --- /dev/null +++ b/src/mobile/models/searchmodel.cpp @@ -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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +#include "searchmodel.h" + +#include "backend/models/btmoduletextmodel.h" +#include <QAbstractItemModel> +#include <QStandardItemModel> +#include <QVariant> + +namespace btm { + +int SearchModel::indexMatchingKeyName(const QString& keyName, const QVariant& vModel) { + BtModuleTextModel* model = vModel.value<BtModuleTextModel*>(); + if (model == nullptr) + return 0; + + int first = 0; + int last = model->rowCount(); + + int trials = 24; + while (trials > 0 && (last - first) > 1) { + int middle = (first + last) /2; + QString name = model->indexToKeyName(middle); + int c = name.compare(keyName,Qt::CaseInsensitive); + if (c < 0) + first = middle; + else if (c > 0) + last = middle; + else + return middle; + --trials; + } + return first; +} + +} diff --git a/src/mobile/models/searchmodel.h b/src/mobile/models/searchmodel.h new file mode 100644 index 0000000..890d513 --- /dev/null +++ b/src/mobile/models/searchmodel.h @@ -0,0 +1,47 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +/** + \brief Searches the keyNames of a BtModuleTextModel to find an index. + + Does a binary search though a BtModuleTextModel with a given possible + keyName. Finds the index for the keyName or the index just before it + if there is not an exact match. + + Invokable from QML. + */ + + +#ifndef SEARCH_MODEL_H +#define SEARCH_MODEL_H + +#include <QObject> + +class QAbstractItemModel; +class QVariant; + +namespace btm { + +class SearchModel: public QObject { + + Q_OBJECT + +public: + SearchModel(QObject* parent = nullptr) + : QObject(parent) { } + + Q_INVOKABLE static int indexMatchingKeyName(const QString& keyName, const QVariant& vModel); +}; + +} + +#endif diff --git a/src/mobile/qml/About.qml b/src/mobile/qml/About.qml new file mode 100644 index 0000000..b7da131 --- /dev/null +++ b/src/mobile/qml/About.qml @@ -0,0 +1,114 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ +import QtQuick 2.2 +import QtQuick.Controls 1.2 +import QtQuick.Controls.Styles 1.2 +import BibleTime 1.0 + +Rectangle { + id: aboutDialog + + color: btStyle.textBackgroundColor + anchors.fill: parent + + BtStyle { + id: btStyle + } + + Flickable { + anchors.left: parent.left + anchors.right: parent.right + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.topMargin: btStyle.pixelsPerMillimeterY * 2 + contentWidth: width + contentHeight: column.height * 1.1 + + Column { + id: column + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: parent.top + spacing: btStyle.pixelsPerMillimeterY * 2 + + Image { + id: logo + + width: aboutDialog.width/8 + height: width + anchors.horizontalCenter: parent.horizontalCenter + source: "qrc:/share/bibletime/icons/bibletime.svg" + } + + Text { + id: titleText + + text: qsTranslate("About", "BibleTime Mobile") + width: aboutDialog.width + horizontalAlignment: Text.AlignHCenter + font.pointSize: btStyle.uiFontPointSize + 4 + color: btStyle.textColor + } + + Text { + id: versionText + + wrapMode: Text.WordWrap + width: aboutDialog.width + horizontalAlignment: Text.AlignHCenter + textFormat: Text.RichText + text: formatText(); + font.pointSize: btStyle.uiFontPointSize + color: btStyle.textColor + onLinkActivated: { + Qt.openUrlExternally(link); + } + + function formatText() { + var btstr = qsTranslate("About", "Brought to you by the") + " <a href=\"http://www.bibletime.info\">BibleTime Team</a><br><br>"; + var appstr = qsTranslate("About", "Version") + "<br>" + appstr += btStyle.appVersion; + appstr += "<br><br>"; + + var qtstr = qsTranslate("About", "Qt version") + "<br>" + qtstr += btStyle.qtVersion; + qtstr += "<br><br>"; + + var swordstr = qsTranslate("About", "Sword version") + "<br>" + swordstr += btStyle.swordVersion; + swordstr += "<br><br>"; + + var gplstr = qsTranslate("About", "Licensed Under the") + "<br><a href=\"http://www.gnu.org/licenses/gpl-2.0.html\">GNU General Public License Version 2</a><br><br>" + + var gitstr = ""; + var gitversion = btStyle.gitVersion; + var len = gitversion.length; + if (len != 0) { + gitstr = "<a href=\"https://github.com/bibletime\">Git version</a><br>"; + gitstr += gitversion.substring(0, len/2-1); + gitstr += "<br>"; + gitstr += gitversion.substring(len/2, len); + gitstr += "<br><br>"; + } + + return btstr + appstr + qtstr + swordstr + gplstr + gitstr; + } + } + } + } + + Keys.onReleased: { + if ((event.key == Qt.Key_Back || event.key == Qt.Key_Escape) && aboutDialog.visible == true) { + aboutDialog.visible = false; + event.accepted = true; + } + } +} diff --git a/src/mobile/qml/BtButtonStyle.qml b/src/mobile/qml/BtButtonStyle.qml new file mode 100644 index 0000000..7fa7301 --- /dev/null +++ b/src/mobile/qml/BtButtonStyle.qml @@ -0,0 +1,38 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +import QtQuick 2.2 +import QtQuick.Controls 1.2 +import QtQuick.Controls.Styles 1.2 +import BibleTime 1.0 + +ButtonStyle { + + background: Rectangle { + border.width: 2 + border.color: "black" + radius: btStyle.pixelsPerMillimeterX + gradient: Gradient { + GradientStop { position: 0 ; color: control.pressed ? "#ccc" : "#fff" } + GradientStop { position: 1 ; color: control.pressed ? "#aaa" : "#ccc" } + } + } + + label: Text { + anchors.centerIn: parent + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + font.pointSize: btStyle.uiFontPointSize + color: "black" + text: control.text + } +} diff --git a/src/mobile/qml/ContextMenu.qml b/src/mobile/qml/ContextMenu.qml index bf55ebf..5024b21 100644 --- a/src/mobile/qml/ContextMenu.qml +++ b/src/mobile/qml/ContextMenu.qml @@ -1,4 +1,15 @@ -import QtQuick 2.1 +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ +import QtQuick 2.2 import BibleTime 1.0 Rectangle { diff --git a/src/mobile/qml/FontSizeSlider.qml b/src/mobile/qml/FontSizeSlider.qml index 6c11dc0..69e5cb2 100644 --- a/src/mobile/qml/FontSizeSlider.qml +++ b/src/mobile/qml/FontSizeSlider.qml @@ -1,139 +1,154 @@ -import QtQuick 2.1 +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +import QtQuick 2.2 import BibleTime 1.0 +import QtQuick.Controls 1.2 +import QtQuick.Controls.Styles 1.3 Rectangle { id: fontPointSize property string title: "" property int min: 10 - property int max: 22 - property int current: 12 - property int previous: 12 + property int max: 30 + property int current: 20 + property int previous: 20 + property bool ready: false 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 + color: btStyle.textBackgroundColor + border.color: btStyle.textColor + border.width: 3 + anchors.right: parent.right + anchors.bottom: parent.bottom + anchors.topMargin: 20 + anchors.bottomMargin: btStyle.pixelsPerMillimeterX * 2 + anchors.rightMargin: btStyle.pixelsPerMillimeterX * 2 + height: { + var height = titleText.contentHeight + slider.height * 1.4 + buttons.height; + height = height + titleText.anchors.topMargin; + height = height + buttons.anchors.bottomMargin + buttons.anchors.topMargin; + height = height + btStyle.pixelsPerMillimeterX*3 + return height; } - - Rectangle { - id: bar - - color: "blue" - width: parent.width *.80 - height: 3 - anchors.centerIn: parent + width: { + var width = Math.min(parent.width, parent.height); + width = width - 2 * anchors.rightMargin + return width; } - - 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 + onVisibleChanged: { + fontPointSize.ready = false; + if (visible) { + var uiTextSize = btStyle.uiFontPointSize; + slider.value = uiTextSize; + fontPointSize.ready = true; + } + } + Keys.onReleased: { + if ((event.key == Qt.Key_Back || event.key == Qt.Key_Escape) && fontPointSize.visible == true) { + accepted(previous); + fontPointSize.visible = false; + event.accepted = true; } } - MouseArea { - property bool active: false - width: bar.width - anchors.left: bar.left - height: 40 - anchors.verticalCenter: bar.verticalCenter + Text { + id: titleText - onPressed: { - active = true; - } + text: qsTranslate("main", title) + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: parent.top + anchors.topMargin: 20 + font.pointSize: btStyle.uiFontPointSize + color: btStyle.textColor + } - onReleased: { - active = false; - } + Slider { + id: slider - 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); + anchors.top: titleText.bottom + anchors.horizontalCenter: parent.horizontalCenter + width: parent.width - 60 + anchors.topMargin: 20 + minimumValue: fontPointSize.min + maximumValue: fontPointSize.max + style: SliderStyle { + groove: Rectangle { + implicitWidth: 200 + implicitHeight: 8 + color: btStyle.textColor + radius: 8 + } + handle: Rectangle { + anchors.centerIn: parent + color: btStyle.textBackgroundColor + border.color: btStyle.textColor + border.width: 3 + implicitWidth: btStyle.pixelsPerMillimeterY * 4 + implicitHeight: btStyle.pixelsPerMillimeterY * 4 + radius: btStyle.pixelsPerMillimeterY * 2 + } + } + onValueChanged: { + if (fontPointSize.ready) + accepted(slider.value); } - } Grid { id: buttons - spacing: 10 + spacing: btStyle.pixelsPerMillimeterY * 4 columns: 2 - anchors.right: parent.right + anchors.horizontalCenter: parent.horizontalCenter 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 + anchors.bottomMargin: 20 + anchors.topMargin: 30 + + Action { + id: okAction + text: qsTr("Ok") + onTriggered: { + fontPointSize.visible = false; } + } - MouseArea { - anchors.fill: parent - onClicked: { - fontPointSize.visible = false; - } + Button { + id: okButton + height: titleText.height*1.5 + width: fontPointSize.width/3 + action: okAction + style: BtButtonStyle { } } - Rectangle { - height: 40 - width: 120 - border.color: "black" - border.width: 1 - - Text { - text: "Cancel" - anchors.centerIn: parent - font.pointSize: btStyle.uiFontPointSize + Action { + id: cancelAction + text: qsTr("Cancel") + onTriggered: { + accepted(previous); + fontPointSize.visible = false; } + } - MouseArea { - anchors.fill: parent - onClicked: { - accepted(previous); - fontPointSize.visible = false; - } + Button { + id: cancelButton + height: titleText.height*1.5 + width: fontPointSize.width/3 + action: cancelAction + style: BtButtonStyle { } } } - } diff --git a/src/mobile/qml/GridChooser.qml b/src/mobile/qml/GridChooser.qml index b4d1612..b8cd198 100644 --- a/src/mobile/qml/GridChooser.qml +++ b/src/mobile/qml/GridChooser.qml @@ -1,4 +1,16 @@ -import QtQuick 2.1 +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +import QtQuick 2.2 import BibleTime 1.0 Rectangle { @@ -8,30 +20,38 @@ Rectangle { 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 int space: 10 property string selected: "" property string titleText: "" property int maxLength: 0 signal accepted(string choosenText); - signal canceled(); + signal backup(); - onVisibleChanged: { + color: btStyle.toolbarColor + height: parent.height + width: parent.width + + Keys.onReleased: { + if ((event.key == Qt.Key_Back || event.key == Qt.Key_Escape) && gridChooser.visible == true) { + event.accepted = true; + gridChooser.visible = false; + backup(); + } + } + onVisibleChanged: { + if ( ! visible) + return; 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; + buttonWidth = (width - ((columns +1) *space))/columns + var buttonH = Math.floor((height-(rows*space))/rows) ; + buttonHeight = Math.max(btStyle.pixelsPerMillimeterY*7.5, buttonH); + flick.contentY = 0; } function calculateColumns(count) { @@ -46,71 +66,55 @@ Rectangle { 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 + TitleColorBar { + id: title - width: leftMargin - height: topMargin - color: btStyle.buttonBackground + title: qsTranslate("Choose Reference", titleText) + anchors.top: parent.top + anchors.horizontalCenter: parent.horizontalCenter } - 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 + Flickable { + id: flick + + anchors.top: title.bottom + anchors.left: parent.left + anchors.leftMargin: space + width: parent.width + height: parent.height + contentHeight: (rows+1)*(buttonHeight+space); + contentWidth: width + clip: true + + Grid { + id: grid + + width: parent.width + height: parent.contentHeight + columns: gridChooser.columns + spacing: gridChooser.space + + Repeater { + id: repeater + + model: gridChooserModel + + GridChooserButton { + id: button + + text: modelData + textHeight: btStyle.uiFontPointSize + buttonWidth: gridChooser.buttonWidth + buttonHeight: gridChooser.buttonHeight + textColor: btStyle.buttonTextColor + buttonColor: (text == gridChooser.selected) ? btStyle.buttonBackground : "white" + activeButtonColor: btStyle.buttonTextColor + onClicked: gridChooser.accept(text) } - buttonColor: btStyle.buttonColor - activeButtonColor: btStyle.buttonTextColor - onClicked: gridChooser.accept(text) } } } diff --git a/src/mobile/qml/GridChooserButton.qml b/src/mobile/qml/GridChooserButton.qml index 9a65041..50c554c 100644 --- a/src/mobile/qml/GridChooserButton.qml +++ b/src/mobile/qml/GridChooserButton.qml @@ -1,4 +1,16 @@ -import QtQuick 2.1 +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +import QtQuick 2.2 import BibleTime 1.0 Rectangle { @@ -16,12 +28,7 @@ Rectangle { 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 } - } + color: btStyle.textBackgroundColor smooth: true border { @@ -38,7 +45,7 @@ Rectangle { width: buttonWidth-8 anchors.centerIn: parent - color: button.textColor + color: btStyle.textColor font.pointSize: parent.textHeight elide: Text.ElideRight } diff --git a/src/mobile/qml/ImageButton.qml b/src/mobile/qml/ImageButton.qml deleted file mode 100644 index 552a9b4..0000000 --- a/src/mobile/qml/ImageButton.qml +++ /dev/null @@ -1,24 +0,0 @@ -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 index 15b6079..2d23c7b 100644 --- a/src/mobile/qml/InstallManagerChooser.qml +++ b/src/mobile/qml/InstallManagerChooser.qml @@ -1,4 +1,17 @@ -import QtQuick 2.1 +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +import QtQuick 2.2 +import QtQuick.Controls 1.2 Rectangle { id: installManager @@ -10,10 +23,11 @@ Rectangle { property alias sourceIndex: sourceView.currentIndex property alias categoryIndex: categoryView.currentIndex property alias languageIndex: languageView.currentIndex - property int spacing: 8 + property int spacing: btStyle.pixelsPerMillimeterX + property bool refreshOnOpen: false objectName: "installManager" - color: "lightgray" + color: btStyle.toolbarColor border.color: "black" border.width: 2 @@ -25,6 +39,20 @@ Rectangle { signal installRemove(); signal refreshLists(); + onVisibleChanged: { + if (refreshOnOpen) { + refreshOnOpen =false; + refreshAction.trigger(); + } + } + + Keys.onReleased: { + if ((event.key == Qt.Key_Back || event.key == Qt.Key_Escape) && installManager.visible == true) { + event.accepted = true; + installManager.visible = false; + } + } + Grid { id: grid columns: 3 @@ -42,7 +70,7 @@ Rectangle { sourceChanged(currentIndex) } - title: "Source" + title: qsTranslate("InstallManagerChooser","Source") width: parent.width/3 - grid.spacing height: installManager.height/3 } @@ -50,7 +78,7 @@ Rectangle { ListTextView { id: categoryView - title: "Category" + title: qsTranslate("InstallManagerChooser","Category") width: parent.width/3 - grid.spacing height: installManager.height/3 onItemSelected: { @@ -61,7 +89,7 @@ Rectangle { ListTextView { id: languageView - title: "Language" + title: qsTranslate("InstallManagerChooser","Language") width: parent.width/3 - grid.spacing height: installManager.height/3 onItemSelected: { @@ -73,81 +101,66 @@ Rectangle { ListWorksView { id: worksView - title: "Work" + title: qsTranslate("InstallManagerChooser","Document") width: parent.width - 2 * installManager.spacing anchors.top: grid.bottom anchors.left: parent.left - anchors.bottom: installRemoveButton.top + anchors.bottom: buttonRow.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() - } + Text { + id: dummyTextForHeight + text: "x" + font.pointSize: btStyle.uiFontPointSize + visible: false } - Rectangle { - id: "installRemoveButton" - width:150 - height: 40 + + Row { + id: buttonRow + 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 + anchors.left: parent.left + anchors.bottomMargin: 20 + spacing: (parent.width - refreshButton.width - installRemoveButton.width) / 3 + anchors.leftMargin: (parent.width - refreshButton.width - installRemoveButton.width) / 3 + + Action { + id: refreshAction + text: qsTranslate("InstallManagerChooser", "Refresh Sources") + onTriggered: { + installManager.refreshLists(); + } } - MouseArea { - anchors.fill: parent - onClicked: installManager.installRemove() + Button { + id: refreshButton + width: installManager.width * 4.5 / 10; + height: dummyTextForHeight.height*1.5 + action: refreshAction + style: BtButtonStyle { + } } - } - 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 + Action { + id: installRemoveAction + text: qsTranslate("InstallManagerChooser", "Install / Remove") + onTriggered: { + installManager.installRemove(); + } } - MouseArea { - anchors.fill: parent - onClicked: installManager.cancel(); + Button { + id: installRemoveButton + width: installManager.width * 4.5 / 10; + height: dummyTextForHeight.height*1.5 + action: installRemoveAction + style: BtButtonStyle { + } } } - } diff --git a/src/mobile/qml/KeyNameChooser.qml b/src/mobile/qml/KeyNameChooser.qml new file mode 100644 index 0000000..67f94aa --- /dev/null +++ b/src/mobile/qml/KeyNameChooser.qml @@ -0,0 +1,171 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +import QtQuick 2.2 +import QtQuick.Controls 1.2 +import BibleTime 1.0 + +Rectangle { + id: top + + property alias model: listView.model + property alias currentIndex: listView.currentIndex + property bool highlight: true + + border.color: "black" + border.width: 2 + + signal itemSelected(int index) + + Keys.onReleased: { + if ((event.key == Qt.Key_Back || event.key == Qt.Key_Escape) && top.visible == true) { + event.accepted = true; + top.visible = false; + } + } + + BtStyle { + id: btStyle + } + + SearchModel { + id: searchModel + } + + Rectangle { + id: searchRect + + color: "#a0d0ff" + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + height: btStyle.pixelsPerMillimeterY * 8 + border.color: "gray" + border.width: 1 + + Row { + id: searchRow + + anchors.fill: parent + anchors.leftMargin: 20 + + Text { + text: "Search " + height: btStyle.pixelsPerMillimeterY * 6 + verticalAlignment: TextEdit.AlignVCenter + font.pointSize: btStyle.uiFontPointSize + color: "black" + } + + Rectangle { + + height: searchRect.height - 5 + anchors.verticalCenter: parent.verticalCenter + width: height * 10 + color: "white" + border.color: "gray" + border.width: 1 + + TextField { + id: textEdit + + text: "" + height: parent.height + width: height * 10 + anchors.top: parent.top + anchors.left: parent.left + inputMethodHints: Qt.ImhNoPredictiveText + verticalAlignment: Text.AlignVCenter + font.pointSize: btStyle.uiFontPointSize + focus: true + onTextChanged: { + var matchingIndex = searchModel.indexMatchingKeyName(text, listView.model); + listView.positionViewAtIndex(matchingIndex, ListView.Beginning); + } + } + } + } + } + + ListView { + id: listView + + anchors.top: searchRect.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: { + var pixel = btStyle.pixelsPerMillimeterY * 8; + var uiFont = btStyle.uiFontPointSize * 3.5; + return Math.max(pixel, uiFont); + } + + 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 + verticalAlignment: Text.AlignVCenter + text: keyName + font.pointSize: btStyle.uiFontPointSize + font.bold: highlight && entry.selected + } + } + + MouseArea { + anchors.fill: listView + onClicked: itemSelected() + + function itemSelected() { + listView.selectItem(mouseX, mouseY); + top.visible = false; + } + } + } +} diff --git a/src/mobile/qml/LeftArrow.qml b/src/mobile/qml/LeftArrow.qml new file mode 100644 index 0000000..5c6b2b3 --- /dev/null +++ b/src/mobile/qml/LeftArrow.qml @@ -0,0 +1,31 @@ + +import QtQuick 2.3 + + Canvas { + id: canvas + width: 260 + height: 260 + antialiasing: true + + property color color: "#808080" + + onColorChanged:requestPaint(); + + onPaint: { + var ctx = getContext("2d"); + ctx.save(); + ctx.clearRect(0,0,canvas.width, canvas.height); + + ctx.fillStyle = canvas.color + ctx.globalAlpha = canvas.alpha + + ctx.beginPath(); + ctx.moveTo(width*0.8,height*0.8); + ctx.lineTo(width*0.8,height*0.2); + ctx.lineTo(width*0.2,height*0.5); + ctx.closePath(); + ctx.fill(); + + ctx.restore(); + } + } diff --git a/src/mobile/qml/ListSelectView.qml b/src/mobile/qml/ListSelectView.qml new file mode 100644 index 0000000..527a6f6 --- /dev/null +++ b/src/mobile/qml/ListSelectView.qml @@ -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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +import QtQuick 2.2 + +Rectangle { + id: top + + property alias model: listView.model + property alias currentIndex: listView.currentIndex + property real leftTextMargin: 10 + property bool highlight: true + + signal itemSelected(int index) + + color: btStyle.textBackgroundColor + + ListView { + id: listView + + anchors.fill: parent + 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: btStyle.pixelsPerMillimeterX + height: listView.visibleArea.heightRatio * listView.height + color: btStyle.textColor + visible: listView.visibleArea.heightRatio < 0.99 + } + + delegate: Rectangle { + id: entry + + property bool selected: ListView.isCurrentItem ? true : false + objectName: "entry" + + color: (highlight && ListView.isCurrentItem) ? btStyle.textBackgroundHighlightColor : btStyle.textBackgroundColor + border.width: buttonMouseArea.pressed ? 5 :1 + border.color: "darkgray" + width: parent.width + height: { + var pixel = btStyle.pixelsPerMillimeterY * 7; + var uiFont = btStyle.uiFontPointSize * 3.5; + return Math.max(pixel, uiFont); + } + + Text { + id: entryText + + anchors.fill: parent + anchors.leftMargin: leftTextMargin + anchors.rightMargin: 10 + anchors.topMargin: 10 + verticalAlignment: Text.AlignVCenter + text: model.text + font.pointSize: btStyle.uiFontPointSize + font.bold: highlight && entry.selected + color: btStyle.textColor + } + } + + MouseArea { + id: buttonMouseArea + + anchors.fill: listView + onPressed: { + + } + + onClicked: itemWasSelected() + + function itemWasSelected() { + listView.selectItem(mouseX, mouseY); + itemSelected(currentIndex); + } + } + } +} diff --git a/src/mobile/qml/ListTextView.qml b/src/mobile/qml/ListTextView.qml index 703fe48..6080f89 100644 --- a/src/mobile/qml/ListTextView.qml +++ b/src/mobile/qml/ListTextView.qml @@ -1,4 +1,16 @@ -import QtQuick 2.1 +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +import QtQuick 2.2 Rectangle { id: top @@ -16,9 +28,10 @@ Rectangle { Rectangle { id: titleRect - border.color: "black" + border.color: btStyle.textColor border.width: 1 - height:25 + color: btStyle.textBackgroundColor + height: btStyle.uiFontPointSize * 4; anchors.left: parent.left anchors.right: parent.right anchors.top: parent.top @@ -33,6 +46,7 @@ Rectangle { horizontalAlignment: Text.AlignCenter verticalAlignment: Text.AlignBottom style: Text.Sunken + color: btStyle.textColor font.pointSize: btStyle.uiFontPointSize } } @@ -51,6 +65,7 @@ Rectangle { highlightFollowsCurrentItem: true currentIndex: 2 + function selectItem(x, y) { var index = listView.indexAt(x+contentX,y+contentY); currentIndex = index; @@ -58,46 +73,63 @@ Rectangle { } Rectangle { + id: background + + color: btStyle.textBackgroundColor + anchors.fill: parent + z: -1 + } + + Rectangle { id: scrollbar anchors.right: listView.right y: listView.visibleArea.yPosition * listView.height - width: 7 + width: 10 height: listView.visibleArea.heightRatio * listView.height - color: "black" + color: btStyle.textColor visible: listView.visibleArea.heightRatio < 0.99 } - delegate { - Rectangle { - id: entry + delegate: Rectangle { + id: entry + + property bool selected: ListView.isCurrentItem ? true : false + objectName: "entry" - property bool selected: ListView.isCurrentItem ? true : false - objectName: "entry" - color: (highlight && ListView.isCurrentItem) ? "#ffeeaa" : "white" - border.width: 1 - border.color: "darkgray" + color: (highlight && ListView.isCurrentItem) ? btStyle.textBackgroundHighlightColor : btStyle.textBackgroundColor + border.width: buttonMouseArea.pressed ? 5 :1 + border.color: "darkgray" + width: parent.width + height: { + var pixel = btStyle.pixelsPerMillimeterY * 8; + var uiFont = btStyle.uiFontPointSize * 3.5; + return Math.max(pixel, uiFont); + } + + Text { + id: entryText + + anchors.fill: entry 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 - } + anchors.leftMargin: 10 + anchors.rightMargin: 10 + anchors.topMargin: 10 + verticalAlignment: Text.AlignVCenter + text: modelText + color: btStyle.textColor + font.pointSize: btStyle.uiFontPointSize - 1 + font.bold: highlight && entry.selected } } MouseArea { + id: buttonMouseArea + anchors.fill: listView + onPressed: { + + } + onClicked: itemSelected() function itemSelected() { diff --git a/src/mobile/qml/ListWorksView.qml b/src/mobile/qml/ListWorksView.qml index 6e6dd13..644dceb 100644 --- a/src/mobile/qml/ListWorksView.qml +++ b/src/mobile/qml/ListWorksView.qml @@ -1,4 +1,18 @@ -import QtQuick 2.1 +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +import QtQuick 2.2 +import QtQuick.Controls 1.2 +import QtQuick.Controls.Styles 1.2 import BibleTime 1.0 Rectangle { @@ -16,22 +30,25 @@ Rectangle { border.color: "black" border.width: 1 - height:25 + height: btStyle.uiFontPointSize * 4; anchors.left: parent.left anchors.right: parent.right anchors.top: parent.top anchors.leftMargin: 3 anchors.rightMargin: 3 anchors.topMargin: 3 + color: btStyle.textBackgroundColor Text { id: title anchors.horizontalCenter: parent.horizontalCenter anchors.centerIn: parent + anchors.topMargin: 5 horizontalAlignment: Text.AlignCenter verticalAlignment: Text.AlignBottom style: Text.Sunken font.pointSize: btStyle.uiFontPointSize + color: btStyle.textColor } } @@ -49,70 +66,141 @@ Rectangle { } Rectangle { + id: background + + color: btStyle.textBackgroundColor + anchors.fill: parent + z: -1 + } + + Rectangle { id: scrollbar anchors.right: listView.right y: listView.visibleArea.yPosition * listView.height - width: 5 + width: 7 height: listView.visibleArea.heightRatio * listView.height - color: "black" + color: btStyle.textColor 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 - } + delegate: Rectangle { + id: entry + + color: btStyle.textBackgroundColor + border.width: 1 + border.color: ListView.isCurrentItem ? "#c0c0c0" : "#a0a0a0" + width: parent.width + height: { + var pixel = btStyle.pixelsPerMillimeterY * 7; + var uiFont = titleText.contentHeight; + var uiHeight = Math.max(pixel, uiFont); + return uiHeight * 1.25; + } + + Text { + id: dummyTextForHeight + text: "x" + font.pointSize: btStyle.uiFontPointSize + visible: false + } - MouseArea { - anchors.fill: parent - onClicked: {listView.itemSelected(index)} + Action { + id: manageAction + text: { + if (installed) + return qsTranslate("Install Documents", "Remove"); + else + return qsTranslate("Install Documents", "Install"); + } + onTriggered: { + listView.itemSelected(index); + manageButton.checked = ! manageButton.checked; + manageButton.chooseGradient(); } + } + + Gradient { + id: gradient1 + GradientStop { position: 0 ; color: manageButton.pressed ? "#ccc" : "#eee" } + GradientStop { position: 1 ; color: manageButton.pressed ? "#aaa" : "#ccc" } + } + + Gradient { + id: gradient2 + GradientStop { position: 0 ; color: manageButton.pressed ? "#daa" : "#fcc" } + GradientStop { position: 1 ; color: manageButton.pressed ? "#b88" : "#daa" } + } - 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 + Gradient { + id: gradient3 + GradientStop { position: 0 ; color: manageButton.pressed ? "#ada" : "#cfc" } + GradientStop { position: 1 ; color: manageButton.pressed ? "#8b8" : "#ada" } + } + + Button{ + id: manageButton + + property Gradient buttonGradient : gradient1 + + function chooseGradient() { + if (manageButton.checked) { + if (installed) + buttonGradient = gradient2; + else + buttonGradient = gradient3; + } + else { + buttonGradient = gradient1; + } } - 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 + action: manageAction + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + anchors.leftMargin: 10 + width: btStyle.uiFontPointSize * 12 + height: dummyTextForHeight.height*1.5 + + checkable: true; + style: ButtonStyle { + id: buttonStyle + + background: Rectangle { + implicitWidth: 100 + implicitHeight: 25 + border.width: manageButton.checked ? 4 : 1 + border.color: manageButton.checked ? "black" : "#777" + radius: 4 + + gradient: manageButton.buttonGradient + } + label: Text { + anchors.centerIn: parent + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + font.pointSize: btStyle.uiFontPointSize -1 + color: "black" + text: control.text + } } } + + Text { + id: titleText + + anchors.verticalCenter: entry.verticalCenter + anchors.left: manageButton.right + anchors.right: entry.right + height: entry.height + wrapMode: Text.WrapAtWordBoundaryOrAnywhere + anchors.leftMargin: btStyle.pixelsPerMillimeterX + anchors.rightMargin: 10 + anchors.topMargin: 5 + verticalAlignment: Text.AlignVCenter + text: "<b>" + title + "</b> - " + desc + font.pointSize: btStyle.uiFontPointSize + color: btStyle.textColor + } } BtStyle { diff --git a/src/mobile/qml/MainToolbar.qml b/src/mobile/qml/MainToolbar.qml index 66513b2..3576479 100644 --- a/src/mobile/qml/MainToolbar.qml +++ b/src/mobile/qml/MainToolbar.qml @@ -1,17 +1,59 @@ -import QtQuick 2.1 +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +import QtQuick 2.2 import BibleTime 1.0 Rectangle { id: toolbar + color: btStyle.toolbarColor + z:0 + onEnabledChanged: { + menuButton.visible = toolbar.enabled + searchIconQml.visible = toolbar.enabled + } + signal buttonClicked + signal searchClicked BtStyle { id: btStyle } - color: btStyle.toolbarColor - z:0 + Image { + id: logo + + width: parent.height-10 + height: parent.height-10 + anchors.left: parent.left + anchors.top: parent.top + anchors.topMargin: 5 + anchors.bottomMargin: 5 + anchors.leftMargin: 10 + source: "qrc:/share/bibletime/icons/bibletime.svg" + } + + Text { + id: title + color: btStyle.toolbarTextColor + font.pointSize: btStyle.uiFontPointSize + anchors.left: logo.right + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.leftMargin: 20 + verticalAlignment: Text.AlignVCenter + text: qsTranslate("MainToolbar", "BibleTime Mobile") + } MenuButton { id: menuButton @@ -20,8 +62,28 @@ Rectangle { height: parent.height anchors.right: parent.right anchors.top: parent.top + foreground: btStyle.toolbarTextColor + background: btStyle.toolbarColor onButtonClicked: { toolbar.buttonClicked() } } + + SearchIcon { + id: searchIconQml + + width: parent.height + height: parent.height + anchors.right: menuButton.left + anchors.top: parent.top + anchors.rightMargin: 0 + strokeStyle: btStyle.toolbarTextColor + + MouseArea { + anchors.fill: parent + onClicked: { + toolbar.searchClicked() + } + } + } } diff --git a/src/mobile/qml/MenuButton.qml b/src/mobile/qml/MenuButton.qml index b3ba458..0687069 100644 --- a/src/mobile/qml/MenuButton.qml +++ b/src/mobile/qml/MenuButton.qml @@ -1,23 +1,55 @@ -import QtQuick 2.1 +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +import QtQuick 2.2 import BibleTime 1.0 Rectangle { id: menuButton + + property color foreground: "#444444" + property color background: "#cccccc" + signal buttonClicked - color: "black" - BtStyle { - id: btStyle - } + color: background Column { - spacing:3 + id: column + property real ppmy: btStyle.pixelsPerMillimeterY + property real buttonWidth: { + var w = column.ppmy * 0.7; + return Math.max(3, w); + } - Rectangle { color: "white"; width:2; height:2 } - Rectangle { color: "white"; width:2; height:2 } - Rectangle { color: "white"; width:2; height:2 } + spacing: menuButton.height*0.1 + + Rectangle { + color: foreground + width: column.buttonWidth + height:column.buttonWidth + } + Rectangle { + color: foreground + width: column.buttonWidth + height:column.buttonWidth + } + Rectangle { + color: foreground + width: column.buttonWidth + height:column.buttonWidth + } anchors.centerIn: parent } diff --git a/src/mobile/qml/MenuView.qml b/src/mobile/qml/MenuView.qml deleted file mode 100644 index 01b5142..0000000 --- a/src/mobile/qml/MenuView.qml +++ /dev/null @@ -1,28 +0,0 @@ -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 index 1a9e53b..ac93526 100644 --- a/src/mobile/qml/Menus.qml +++ b/src/mobile/qml/Menus.qml @@ -1,4 +1,16 @@ -import QtQuick 2.1 +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +import QtQuick 2.2 import BibleTime 1.0 Rectangle { @@ -6,15 +18,26 @@ Rectangle { property alias model: menusRepeater.model property int fontPointSize: 15 - property int menuHeight: 70 + property int menuHeight: { + var pixel = btStyle.pixelsPerMillimeterY * 9; + var uiFont = btStyle.uiFontPointSize * 3.5; + return Math.max(pixel, uiFont); + } property int topMenuMargin: 150 property int leftMenuMargin: 50 signal menuSelected(string action) + Keys.onReleased: { + if ((event.key == Qt.Key_Back || event.key == Qt.Key_Escape) && menu.visible == true) { + event.accepted = true; + menu.visible = false; + } + } + visible: false anchors.fill: parent - color: "#f0f0f0" + color: btStyle.textBackgroundColor BtStyle { id: btStyle @@ -26,14 +49,14 @@ Rectangle { Rectangle { width: menu.width height: menuHeight - color: "white" - border.color: "#f0f0f0" + color: btStyle.textBackgroundColor + border.color: btStyle.menuBorder border.width: 2 Text { - text: title + text: qsTranslate("main",title) font.pointSize: btStyle.uiFontPointSize - color: "black" + color: btStyle.textColor anchors.fill: parent anchors.leftMargin: leftMenuMargin verticalAlignment: Text.AlignVCenter diff --git a/src/mobile/qml/ModuleChooser.qml b/src/mobile/qml/ModuleChooser.qml index 49d19d1..25fc9a4 100644 --- a/src/mobile/qml/ModuleChooser.qml +++ b/src/mobile/qml/ModuleChooser.qml @@ -1,4 +1,18 @@ -import QtQuick 2.1 +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +import QtQuick 2.2 +import QtQuick.Controls 1.2 +import QtQuick.Controls.Styles 1.2 import BibleTime 1.0 Rectangle { @@ -12,15 +26,28 @@ Rectangle { property alias moduleIndex: worksView.currentIndex property int lastCategoryIndex: 0 property int lastLanguageIndex: 0 - property int spacing: 5 + property int spacing: 4 property string selectedModule: "" property string selectedCategory: "" objectName: "moduleChooser" + + function requestModuleUnlockKey() { + unlockDlg.visible = true; + } + color: "lightgray" border.color: "black" border.width: 2 + Keys.onReleased: { + if ((event.key == Qt.Key_Back || event.key == Qt.Key_Escape) && moduleChooser.visible == true) { + event.accepted = true; + moduleChooser.visible = false; + unlockDlg.visible = false; + } + } + onVisibleChanged: { if (visible == true) { moduleInterface.updateCategoryAndLanguageModels(); @@ -45,10 +72,87 @@ Rectangle { signal languageChanged(int index); signal moduleSelected(); + Rectangle { + id: unlockDlg + + z: 100 + visible: false + color: btStyle.textBackgroundColor + anchors.fill: parent + + signal finished(string unlockKey); + + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + anchors.right: parent.right + Text { + id: message + text: "This document is locked.\nYou must enter the unlock key." + horizontalAlignment: Text.AlignHCenter + anchors.verticalCenter: parent.verticalCenter + font.pointSize: btStyle.uiFontPointSize + width: parent.width + height: contentHeight * 1.1 + color: btStyle.textColor + } + + TextField { + id: input + + anchors.top: message.bottom + anchors.horizontalCenter: parent.horizontalCenter + width: parent.width/2 + font.pointSize: btStyle.uiFontPointSize + textColor: btStyle.textColor + style: TextFieldStyle { + textColor: btStyle.textColor + background: Rectangle { + radius: 6 + anchors.fill: parent + border.color: btStyle.textColor + border.width: 1 + color: btStyle.textBackgroundColor + } + } + } + + Action { + id: unlockAction + text: QT_TR_NOOP("Unlock") + onTriggered: { + unlockDlg.visible = false; + moduleInterface.unlock(selectedModule, input.text); + if (moduleInterface.isLocked(selectedModule)) { + console.log("module did not unlock"); + return; + } + moduleSelected(); + moduleChooser.visible = false; + } + } + + Button { + id: unlockButton + anchors.top: input.bottom + anchors.horizontalCenter: parent.horizontalCenter + anchors.topMargin: btStyle.pixelsPerMillimeterY * 3 + height: btStyle.pixelsPerMillimeterY * 7 + width: btStyle.pixelsPerMillimeterY * 25 + action: unlockAction + style: BtButtonStyle { + } + } + } + + ModuleInterface { id: moduleInterface } + BtStyle { + id: beStyle + } + Grid { id: grid columns: 2 @@ -63,7 +167,7 @@ Rectangle { ListTextView { id: categoryView - title: "Category" + title: qsTranslate("ModuleChooser", "Category") width: grid.width/2 - grid.spacing height: grid.height onItemSelected: { @@ -74,7 +178,7 @@ Rectangle { ListTextView { id: languageView - title: "Language" + title: qsTranslate("ModuleChooser", "Language") width: grid.width/2 - grid.spacing height: grid.height onItemSelected: { @@ -86,7 +190,7 @@ Rectangle { ListTextView { id: worksView - title: "Work" + title: qsTranslate("ModuleChooser", "Work") width: parent.width - 2 * parent.spacing anchors.top: grid.bottom anchors.left: parent.left @@ -95,15 +199,14 @@ Rectangle { highlight: false onItemSelected: { selectedModule = moduleInterface.module(index); - selectedCategory = moduleInterface.category(index); + selectedCategory = moduleInterface.englishCategory(index); + if (moduleInterface.isLocked(selectedModule)) { + requestModuleUnlockKey(); + return; + } moduleSelected(); moduleChooser.visible = false; } } - -// MouseArea { -// anchors.fill: parent -// onClicked: moduleChooser.cancel(); -// } } diff --git a/src/mobile/qml/PrevNextArrow.qml b/src/mobile/qml/PrevNextArrow.qml new file mode 100644 index 0000000..deafe45 --- /dev/null +++ b/src/mobile/qml/PrevNextArrow.qml @@ -0,0 +1,83 @@ + +import QtQuick 2.3 + +Item { + id:container + + property color background: "#000000" + property bool show: false + property bool prev: false + property color borderColor: "black" + property color textColor: Qt.rgba(1,1,1, 1) + onTextColorChanged: canvas.requestPaint(); + + signal clicked + + Rectangle { + anchors.fill: parent + color: background + opacity: show ? 0 : 0.7 + z: 2 + } + + Rectangle { + anchors.fill: parent + color: Qt.rgba(0,0,0,0) + border.width: 1 + border.color: borderColor + z: 1 + } + + MouseArea { + anchors.fill: parent + onClicked: { + container.clicked(); + } + } + Column { + spacing: 1 + anchors.fill: parent + anchors.topMargin: 0 + + Canvas { + id: canvas + width: parent.width-2 + height: parent.height-2 + antialiasing: true + + property color bright: Qt.rgba(255, 255, 255, 0.0) + + onPaint: { + var ctx = getContext("2d"); + ctx.save(); + ctx.globalAlpha = canvas.alpha + ctx.clearRect(0,0,canvas.width, canvas.height); + + ctx.lineCap = "round"; + ctx.lineJoin = "round"; + ctx.strokeStyle = container.textColor; + ctx.lineWidth = width * 0.09; + + var arrowhead = width*0.8; + var arrowtail = width*0.2; + if (prev) { + arrowhead = width*0.2; + arrowtail = width*0.8; + } + + ctx.beginPath(); + ctx.moveTo(arrowtail,height*0.5); + ctx.lineTo(arrowhead,height*0.5); + ctx.stroke(); + + ctx.beginPath(); + ctx.moveTo(width*0.5,arrowtail); + ctx.lineTo(arrowhead,height*0.5); + ctx.lineTo(width*0.5,arrowhead); + ctx.stroke(); + + ctx.restore(); + } + } + } +} diff --git a/src/mobile/qml/Progress.qml b/src/mobile/qml/Progress.qml index e5f75b3..c4d7fd0 100644 --- a/src/mobile/qml/Progress.qml +++ b/src/mobile/qml/Progress.qml @@ -1,6 +1,18 @@ -import QtQuick 2.1 -import QtQuick.Controls 1.0 -import QtQuick.Controls.Styles 1.0 +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +import QtQuick 2.2 +import QtQuick.Controls 1.2 +import QtQuick.Controls.Styles 1.2 import BibleTime 1.0 Rectangle { @@ -11,8 +23,8 @@ Rectangle { property alias maximumValue: progressBar.maximumValue property alias text: label.text - color: btStyle.buttonBackground - border.color: "black" + color: btStyle.textBackgroundColor + border.color: btStyle.textColor border.width: 5 signal cancel() @@ -26,7 +38,9 @@ Rectangle { anchors.horizontalCenter: parent.horizontalCenter anchors.bottom: progressBar.top - anchors.bottomMargin: 20 + anchors.bottomMargin: parent.height / 8 + font.pointSize: btStyle.uiFontPointSize + color: btStyle.textColor } ProgressBar { @@ -34,30 +48,36 @@ Rectangle { anchors.centerIn: parent width: parent.width - 100 - height: 16 + height: parent.height /10 + style: ProgressBarStyle { + background: Rectangle { + radius: 2 + color: "lightgray" + border.color: "gray" + border.width: 1 + implicitWidth: 200 + implicitHeight: 24 + } + } } - 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" - + Action { + id: cancelAction + text: qsTranslate("Progress", "Cancel") + onTriggered: { + cancel(); } + } - MouseArea { - anchors.fill: parent - onClicked: { - cancel(); - } + Button { + id: cancelButton + height: btStyle.pixelsPerMillimeterY * 7 + width: btStyle.pixelsPerMillimeterY * 25 + anchors.top: progressBar.bottom + anchors.topMargin: parent.height / 8 + anchors.horizontalCenter: parent.horizontalCenter + action: cancelAction + style: BtButtonStyle { } } } diff --git a/src/mobile/qml/Question.qml b/src/mobile/qml/Question.qml new file mode 100644 index 0000000..68b6e31 --- /dev/null +++ b/src/mobile/qml/Question.qml @@ -0,0 +1,124 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +import QtQuick 2.2 +import QtQuick.Controls 1.2 +import BibleTime 1.0 + +Rectangle { + id: question + + property alias text: questionText.text + property bool answer + property color background + + signal finished(); + + anchors.fill: parent + color: btStyle.textBackgroundColor + visible: false + width: parent.width + + Image { + id: logo + + width: btStyle.pixelsPerMillimeterX*12 + height: width + anchors.left: parent.left + anchors.top: parent.top + anchors.topMargin: width * 0.2 + anchors.leftMargin: width * 0.2 + source: "qrc:/share/bibletime/icons/bibletime.svg" + } + + Text { + id: questionTitle + + color: btStyle.textColor + font.pointSize: btStyle.uiFontPointSize+2 + text: "BibleTime" + anchors.left: logo.right + anchors.verticalCenter: logo.verticalCenter + anchors.leftMargin: logo.width * 0.2 + } + + Text { + id: questionText + height: contentHeight + width: parent.width + anchors.centerIn: parent + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + wrapMode: Text.WordWrap + font.pointSize: btStyle.uiFontPointSize + anchors.margins: 60 + color: btStyle.textColor + } + + Text { + id: dummyTextForHeight + text: "x" + font.pointSize: btStyle.uiFontPointSize + visible: false + } + + Grid { + id: buttons + + spacing: btStyle.pixelsPerMillimeterY * 4 + columns: 2 + anchors.top: questionText.bottom + anchors.topMargin: 50 + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottomMargin: 50 + + Action { + id: yesAction + text: qsTranslate("Question","Yes") + onTriggered: { + question.visible = false; + answer = true; + finished(); + } + } + + Button { + id: yesButton + width: btStyle.pixelsPerMillimeterY * 25 + height: dummyTextForHeight.height*1.5 + action: yesAction + style: BtButtonStyle { + } + } + + Action { + id: noAction + text: qsTranslate("Question","No") + onTriggered: { + question.visible = false; + answer = false; + finished(); + } + } + + Button { + id: noButton + width: btStyle.pixelsPerMillimeterY * 25 + height: dummyTextForHeight.height*1.5 + action: noAction + style: BtButtonStyle { + } + } + + } + +} diff --git a/src/mobile/qml/RightArrow.qml b/src/mobile/qml/RightArrow.qml new file mode 100644 index 0000000..323be57 --- /dev/null +++ b/src/mobile/qml/RightArrow.qml @@ -0,0 +1,31 @@ + +import QtQuick 2.3 + + Canvas { + id: canvas + width: 260 + height: 260 + antialiasing: true + + property color color: "#808080" + + onColorChanged:requestPaint(); + + onPaint: { + var ctx = getContext("2d"); + ctx.save(); + ctx.clearRect(0,0,canvas.width, canvas.height); + + ctx.fillStyle = canvas.color + ctx.globalAlpha = canvas.alpha + + ctx.beginPath(); + ctx.moveTo(width*0.2,height*0.8); + ctx.lineTo(width*0.2,height*0.2); + ctx.lineTo(width*0.8,height*0.5); + ctx.closePath(); + ctx.fill(); + + ctx.restore(); + } + } diff --git a/src/mobile/qml/Search.qml b/src/mobile/qml/Search.qml new file mode 100644 index 0000000..dd71539 --- /dev/null +++ b/src/mobile/qml/Search.qml @@ -0,0 +1,260 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +import QtQuick 2.2 +import QtQuick.Controls 1.2 +import QtQuick.Controls.Styles 1.2 +import QtQuick.Controls.Private 1.0 +import BibleTime 1.0 + +FocusScope { + id: search + + property int spacing: btStyle.pixelsPerMillimeterX * 1.5 + property string searchText: "" + property string findChoice: "" + property string moduleList: "" + property alias moduleChoices: searchComboBox.model + + signal searchRequest(); + + function setupSearch() { + + Qt.inputMethod.hide(); // hide keyboard + searchText = textInput.displayText; + if (radioAny.checked) + findChoice = "or"; + if (radioAll.checked) + findChoice = "and"; + if (radioPhrase.checked) + findChoice = "regexpr"; + moduleList = searchComboBox.currentText; + searchRequest(); + } + anchors.fill: parent + visible: false + onVisibleChanged: { + if (visible) { + textInput.text = searchText; + } + } + + Rectangle { + + anchors.fill: parent + color: btStyle.textBackgroundColor + + Rectangle { + id: searchTitleBar + color: btStyle.toolbarColor + width: parent.width + height: btStyle.pixelsPerMillimeterY * 7 + + Text { + id: title + color: btStyle.toolbarTextColor + font.pointSize: btStyle.uiFontPointSize + anchors.left: parent.left + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.leftMargin: search.spacing + verticalAlignment: Text.AlignVCenter + text: qsTranslate("Search", "Search") + } + } + + Row { + id: searchInput + + anchors.left: parent.left + anchors.top: searchTitleBar.bottom + anchors.leftMargin: search.spacing + anchors.topMargin: btStyle.pixelsPerMillimeterY*5 + spacing: search.spacing + + Column { + + spacing: btStyle.pixelsPerMillimeterY + + TextField { + id: textInput + + width: search.width -searchButton.width - search.spacing * 3 + height: searchIn.height*1.4 + font.pointSize: btStyle.uiFontPointSize + verticalAlignment: Text.AlignVCenter + inputMethodHints: Qt.ImhNoAutoUppercase + focus: true + text: "" + textColor: btStyle.textColor + + style: TextFieldStyle { + textColor: btStyle.textColor + background: Rectangle { + radius: 6 + anchors.fill: parent + border.color: btStyle.textColor + border.width: 2 + color: btStyle.textBackgroundColor + } + } + + onAccepted: { + search.setupSearch(); + } + } + } + + Button { + id: searchButton + text: qsTranslate("Search", "Search") + height: textInput.height + style: ButtonStyle { + label: Text { + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: parent.horizontalCenter + anchors.right: background.right + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + font.pointSize: btStyle.uiFontPointSize + color: "black" + text: control.text + } + } + onClicked: { + search.setupSearch(); + } + } + } + + Text { + id: titleText + + anchors.left: parent.left + anchors.top: searchInput.bottom + anchors.leftMargin: search.spacing + anchors.topMargin: btStyle.pixelsPerMillimeterY*5 + font.pointSize: btStyle.uiFontPointSize + text: qsTr("Find") + color: btStyle.textColor + } + + GroupBox { + id: findWords + + anchors.top: titleText.bottom + anchors.left: parent.left + anchors.leftMargin: search.spacing + title: "" + + Column { + spacing: 30 + ExclusiveGroup { id: group } + RadioButton { + id: radioAll + + text: qsTr("All Words") + exclusiveGroup: group + style: RadioButtonStyle { + + label: Label { + wrapMode: Text.WrapAtWordBoundaryOrAnywhere + font.pointSize: btStyle.uiFontPointSize + text: control.text + color: btStyle.textColor + } + } + checked: true + } + RadioButton { + id: radioAny + + text: qsTr("Any Word") + exclusiveGroup: group + style: RadioButtonStyle { + + label: Label { + wrapMode: Text.WrapAtWordBoundaryOrAnywhere + font.pointSize: btStyle.uiFontPointSize + text: control.text + color: btStyle.textColor + } + } + } + RadioButton { + id: radioPhrase + + text: qsTr("Regular Expression") + exclusiveGroup: group + style: RadioButtonStyle { + + label: Label { + wrapMode: Text.WrapAtWordBoundaryOrAnywhere + font.pointSize: btStyle.uiFontPointSize + text: control.text + color: btStyle.textColor + } + } + } + } + } + + Row { + id: searchIn + + anchors.left: parent.left + anchors.top: findWords.bottom + anchors.topMargin: btStyle.pixelsPerMillimeterY*5 + anchors.leftMargin: search.spacing + spacing: search.spacing + + Text { + id: searchInLabel + text: qsTranslate("Search", "Search in") + font.pointSize: btStyle.uiFontPointSize + color: btStyle.textColor + } + + ComboBox { + id: searchComboBox + + width: search.width * 2 / 3 + + + style: ComboBoxStyle { + label: Text { + anchors.verticalCenter: parent.verticalCenter + anchors.right: background.right + anchors.leftMargin: search.spacing + font.pointSize: btStyle.uiFontPointSize + color: "black" + text: control.currentText + } + } + + } + } + + + + BtStyle { + id: btStyle + } + } + + Keys.onReleased: { + if ((event.key == Qt.Key_Back || event.key == Qt.Key_Escape) && search.visible == true) { + search.visible = false; + event.accepted = true; + } + } +} diff --git a/src/mobile/qml/SearchIcon.qml b/src/mobile/qml/SearchIcon.qml new file mode 100644 index 0000000..38eff2c --- /dev/null +++ b/src/mobile/qml/SearchIcon.qml @@ -0,0 +1,36 @@ + +import QtQuick 2.3 + + Canvas { + id: canvas + width: 160 + height: 160 + antialiasing: true + + property color strokeStyle: "#888888" + property color fillStyle: "#000000" + + onStrokeStyleChanged:requestPaint(); + + onPaint: { + var ctx = getContext("2d"); + ctx.save(); + ctx.clearRect(0,0,canvas.width, canvas.height); + + ctx.strokeStyle = canvas.strokeStyle; + ctx.fillStyle = canvas.fillStyle + ctx.globalAlpha = canvas.alpha + + ctx.lineWidth = width * 0.08 + ctx.beginPath(); + ctx.arc(width*.48,height*0.42,width*0.2,0,Math.PI*2,true); + ctx.stroke(); + + ctx.beginPath(); + ctx.moveTo(width*0.59,height*0.56); + ctx.lineTo(width*0.78,height*0.82); + ctx.stroke(); + + ctx.restore(); + } + } diff --git a/src/mobile/qml/SearchResults.qml b/src/mobile/qml/SearchResults.qml new file mode 100644 index 0000000..b6ac208 --- /dev/null +++ b/src/mobile/qml/SearchResults.qml @@ -0,0 +1,238 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +import QtQuick 2.2 +import QtQuick.Controls 1.2 +import QtQuick.Controls.Styles 1.2 +import QtQuick.Layouts 1.1 +import BibleTime 1.0 + +SplitView { + id: searchResults + + property alias searchText: btSearchInterface.searchText + property alias findChoice: btSearchInterface.findChoice + property alias moduleList: btSearchInterface.moduleList + property alias indexingFinished: btSearchInterface.indexingFinished + + property real leftRightSplit: 0.35 + property real topBottomSplit: 0.45 + property real handleWidth: btStyle.pixelsPerMillimeterX * 3 + property bool indexingCancelled; + + function cancel() { + btSearchInterface.cancel(); + indexingCancelled = true; + } + + function indexingWasCancelled() { + return indexingCancelled; + } + + orientation: Qt.Vertical + handleDelegate: Rectangle { + width: 1; + height: { + var pixel = btStyle.pixelsPerMillimeterY * 6; + var uiFont = btStyle.uiFontPointSize * 2.0; + return Math.max(pixel, uiFont); + } + + color: btStyle.toolbarColor + border.color: btStyle.textColor + border.width: 2 + + Text { + id: title + text: { + return btWindowInterface.moduleName + " " + btWindowInterface.reference; + } + color: btStyle.toolbarTextColor + font.pointSize: btStyle.uiFontPointSize + anchors.fill: parent + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + } + + anchors.fill: parent + visible: false + + Keys.onReleased: { + if ((event.key == Qt.Key_Back || event.key == Qt.Key_Escape) && searchResults.visible == true) { + searchResults.visible = false; + event.accepted = true; + } + } + + function modulesAreIndexed() { + return btSearchInterface.modulesAreIndexed(); + } + + function indexModules() { + indexingCancelled = false; + return btSearchInterface.indexModules(); + } + + function performSearch() { + btWindowInterface.highlightWords = btSearchInterface.searchText; + btSearchInterface.performSearch(); + modulesView.currentIndex = 0; + referencesView.currentIndex = 0; + referencesView.updateTextDisplay(); + Qt.inputMethod.hide(); + } + + Rectangle { + id: topArea + + width: parent.width + height: parent.height * searchResults.topBottomSplit + color: btStyle.textBackgroundColor + + SplitView { + id: topSplitter + + orientation: Qt.Horizontal + anchors.fill: parent + handleDelegate: Rectangle { + width: handleWidth; + height: 2; + color: btStyle.toolbarColor + border.color: "black" + border.width: 2 + } + + Rectangle { + id: modules + + color: btStyle.textBackgroundColor + anchors.left: parent.left + anchors.top: parent.top + width: parent.width * searchResults.leftRightSplit + height: parent.height + + TitleColorBar { + id: titleBar1 + + title: qsTr("Documents") + width: parent.width + anchors.left: parent.left + anchors.top: parent.top + } + + ListSelectView { + id: modulesView + + model: btSearchInterface.modulesModel + anchors.top: titleBar1.bottom + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: parent.right + leftTextMargin: 30 + + onItemSelected: { + btSearchInterface.selectReferences(currentIndex); + } + } + } + + Rectangle { + id: references + + color: "white" + anchors.top: parent.top + Layout.fillWidth: true + + TitleColorBar { + id: titleBar2 + title: qsTr("References") + width: parent.width + } + + ListSelectView { + id: referencesView + + model: btSearchInterface.referencesModel + anchors.top: titleBar2.bottom + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: parent.right + leftTextMargin: 30 + + onItemSelected: { + updateTextDisplay() + } + + function updateTextDisplay() { + var moduleName = btSearchInterface.getModuleName(modulesView.currentIndex); + var reference = btSearchInterface.getReference(referencesView.currentIndex); + btWindowInterface.moduleName = moduleName; + btWindowInterface.reference = reference; + btWindowInterface.updateCurrentModelIndex(); + } + } + } + } + } + + Rectangle { + id: text + + color: btStyle.textBackgroundColor + anchors.right: parent.right + anchors.bottom: parent.bottom + width: parent.width + Layout.fillWidth: true + + ListView { + id: listView + + clip: true + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: parent.right + anchors.leftMargin: 8 + anchors.rightMargin: 8 + model: btWindowInterface.textModel + highlightFollowsCurrentItem: true + currentIndex: btWindowInterface.currentModelIndex + onCurrentIndexChanged: { + positionViewAtIndex(currentIndex,ListView.Beginning) + } + onMovementEnded: { + var index = indexAt(contentX,contentY+30); + btWindowInterface.updateKeyText(index); + } + + delegate: Text { + text: line + textFormat: Text.RichText + width: parent.width + color: btStyle.textColor + font.family: btWindowInterface.fontName + font.pointSize: btWindowInterface.fontSize + wrapMode: Text.WordWrap + onWidthChanged: doLayout() + } + } + } + + BtWindowInterface { + id: btWindowInterface + } + + BtSearchInterface { + id: btSearchInterface + } +} diff --git a/src/mobile/qml/SetFont.qml b/src/mobile/qml/SetFont.qml new file mode 100644 index 0000000..3dd793a --- /dev/null +++ b/src/mobile/qml/SetFont.qml @@ -0,0 +1,264 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +import QtQuick 2.2 +import QtQuick.Controls 1.2 +import QtQuick.Controls.Styles 1.2 +import QtQuick.Layouts 1.1 +import BibleTime 1.0 + +Rectangle { + id: setFont + + property string language: "" + property bool ready: false + + signal textFontChanged + + height: languageRow.height + slider.height + buttons.height + buttons.anchors.bottomMargin + languageRow.anchors.bottomMargin +btStyle.pixelsPerMillimeterX*3 + width: { + var width = Math.min(parent.width, parent.height); + width = width - 2 * anchors.rightMargin + return width; + } + color: btStyle.textBackgroundColor + border.width: 3 + border.color: btStyle.textColor + anchors.right: parent.right + anchors.bottom: parent.bottom + anchors.bottomMargin: btStyle.pixelsPerMillimeterX * 2 + anchors.rightMargin: btStyle.pixelsPerMillimeterX * 2 + + onVisibleChanged: { + setFont.ready = false; + if (visible) { + updateLanguageCombo(setFont.language) + var index = languageCombo.currentIndex; + updateUiFontNameAndSize(index); + moduleInterface.saveCurrentFonts(); + setFont.ready = true; + } + } + + Keys.onReleased: { + if ((event.key == Qt.Key_Back || event.key == Qt.Key_Escape) && setFont.visible == true) { + moduleInterface.restoreSavedFonts(); + setFont.textFontChanged(); + setFont.visible = false; + event.accepted = true; + } + } + + function updateUiFontNameAndSize(index) { + var language = languageCombo.textAt(index); + var fontSize = moduleInterface.getFontSizeForLanguage(language); + slider.value = fontSize; + var fontName = moduleInterface.getFontNameForLanguage(language); + updateFontNameCombo(fontName); + } + + function updateLanguageCombo(language) { + languageCombo.model = moduleInterface.installedModuleLanguages(); + var index = languageCombo.find(language); + if (index >= 0) + languageCombo.currentIndex = index; + } + + function updateFontNameCombo(fontName) { + var index = fontCombo.find(fontName); + if (index >= 0) + fontCombo.currentIndex = index; + } + + function setFontForLanguage(fontName) { + if (! setFont.ready) + return; + var language = languageCombo.currentText; + var fontSize = slider.value; + moduleInterface.setFontForLanguage(language, fontName, fontSize); + setFont.textFontChanged(); + } + + ModuleInterface { + id: moduleInterface + } + + Grid { + id: languageRow + + rows: 3 + columns: 2 + + anchors.top: parent.top + anchors.topMargin: btStyle.pixelsPerMillimeterX * 2 + anchors.horizontalCenter: parent.horizontalCenter + spacing: btStyle.pixelsPerMillimeterX * 2 + + Text { + id: title + horizontalAlignment: Text.AlignHCenter + elide: Text.ElideRight + text: qsTr("For Language") + font.pointSize: btStyle.uiFontPointSize + color: btStyle.textColor + } + + ComboBox { + id: languageCombo + + width: { + var width = setFont.width; + width = width - Math.max(title.width, fontText.width, fontSize.width); + width = width - languageRow.spacing * 3; + return width; + } + Layout.fillWidth: true + currentIndex: 0 + style: ComboBoxStyle { + label: Text { + horizontalAlignment: Text.AlignHCenter + font.pointSize: btStyle.uiFontPointSize + color: "black" + text: control.currentText + elide: Text.ElideRight + } + } + + onActivated: { + updateUiFontNameAndSize(index); + } + } + + Text { + id: fontText + horizontalAlignment: Text.AlignHCenter + elide: Text.ElideRight + text: qsTr("Font") + font.pointSize: btStyle.uiFontPointSize + color: btStyle.textColor + } + + ComboBox { + id: fontCombo + + model: Qt.fontFamilies() + width: languageCombo.width + height: languageCombo.height + Layout.fillWidth: true + style: ComboBoxStyle { + label: Text { + horizontalAlignment: Text.AlignHCenter + font.pointSize: btStyle.uiFontPointSize + color: "black" + text: control.currentText + elide: Text.ElideRight + } + } + onActivated: { + var fontName = fontCombo.textAt(index); + setFont.setFontForLanguage(fontName); + } + + BtStyle { + id: btStyle + } + } + + Text { + id: fontSize + horizontalAlignment: Text.AlignHCenter + elide: Text.ElideRight + text: qsTr("Font Size") + font.pointSize: btStyle.uiFontPointSize + color: btStyle.textColor + } + + Slider { + id: slider + + width: languageCombo.width + height: fontSize.height + minimumValue: 10 + maximumValue: 30 + style: SliderStyle { + groove: Rectangle { + implicitWidth: 200 + implicitHeight: 8 + color: btStyle.textColor + radius: 8 + } + handle: Rectangle { + anchors.centerIn: parent + color: btStyle.textBackgroundColor + border.color: btStyle.textColor + border.width: 3 + implicitWidth: btStyle.pixelsPerMillimeterY * 4 + implicitHeight: btStyle.pixelsPerMillimeterY * 4 + radius: btStyle.pixelsPerMillimeterY * 2 + } + } + onValueChanged: { + + var fontName = fontCombo.currentText + setFont.setFontForLanguage(fontName); + } + + } + } + + + Grid { + id: buttons + + spacing: btStyle.pixelsPerMillimeterY * 5 + columns: 2 + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom: parent.bottom + anchors.bottomMargin: btStyle.pixelsPerMillimeterX * 2 + + Action { + id: okAction + text: qsTr("Ok") + onTriggered: { + setFont.visible = false; + } + } + + Button { + id: okButton + height: fontCombo.height + width: setFont.width/3 + action: okAction + style: BtButtonStyle { + } + } + + Action { + id: cancelAction + text: qsTr("Cancel") + onTriggered: { + setFont.visible = false; + moduleInterface.restoreSavedFonts(); + setFont.textFontChanged(); + } + } + + Button { + id: cancelButton + height: fontCombo.height + width: setFont.width/3 + action: cancelAction + style: BtButtonStyle { + } + } + } +} diff --git a/src/mobile/qml/Settings.qml b/src/mobile/qml/Settings.qml deleted file mode 100644 index 391ce4c..0000000 --- a/src/mobile/qml/Settings.qml +++ /dev/null @@ -1,93 +0,0 @@ -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/SimpleComboBox.qml b/src/mobile/qml/SimpleComboBox.qml new file mode 100644 index 0000000..def54e1 --- /dev/null +++ b/src/mobile/qml/SimpleComboBox.qml @@ -0,0 +1,353 @@ +import QtQuick 2.2 +import QtQuick.Controls 1.2 +import QtQuick.Controls.Private 1.0 + + +Rectangle { + id: comboBox + + property alias model: popupItems.model + property alias currentIndex: popup.__selectedIndex + readonly property alias currentText: popup.currentText + property bool editable: false + property alias editText: input.text + property bool activeFocusOnPress: false + readonly property bool pressed: mouseArea.pressed && mouseArea.containsMouse || popup.__popupVisible + readonly property alias hovered: mouseArea.containsMouse + readonly property alias count: popupItems.count + + function textAt (index) { + if (index >= count || index < 0) + return null; + return popupItems.objectAt(index).text; + } + + function find (text) { + return input.find(text, Qt.MatchExactly) + } + + property alias validator: input.validator + readonly property alias acceptableInput: input.acceptableInput + + signal accepted + signal activated(int index) + + function selectAll() { + input.selectAll() + } + + function __selectPrevItem() { + input.blockUpdate = true + if (currentIndex > 0) { + currentIndex--; + input.text = popup.currentText; + activated(currentIndex); + } + input.blockUpdate = false; + } + + function __selectNextItem() { + input.blockUpdate = true; + if (currentIndex < popupItems.count - 1) { + currentIndex++; + input.text = popup.currentText; + activated(currentIndex); + } + input.blockUpdate = false; + } + + property var __popup: popup + + activeFocusOnTab: true + + Accessible.role: Accessible.ComboBox + + MouseArea { + id: mouseArea + anchors.fill: parent + hoverEnabled: true + onPressed: { + if (comboBox.activeFocusOnPress) + forceActiveFocus() + popup.show() + } + onWheel: { + if (wheel.angleDelta.y > 0) { + __selectPrevItem(); + } else if (wheel.angleDelta.y < 0){ + __selectNextItem(); + } + } + } + + Component.onCompleted: { + if (currentIndex === -1) + currentIndex = 0 + + popup.ready = true +// popup.resolveTextValue(textRole) + } + + Keys.onPressed: { + // Perform one-character based lookup for non-editable combo box + if (!editable && event.text.length > 0) { + var index = input.find(event.text, Qt.MatchStartsWith); + if (index >= 0 && index !== currentIndex) { + currentIndex = index; + activated(currentIndex); + } + } + } + + TextInput { + id: input + + visible: editable + enabled: editable + focus: true + clip: contentWidth > width + + anchors.fill: parent + anchors.leftMargin: 8 + + verticalAlignment: Text.AlignVCenter + + renderType: Text.NativeRendering + selectByMouse: true + color: "red" + onAccepted: { + var idx = input.find(editText, Qt.MatchFixedString) + if (idx > -1) { + editTextMatches = true; + currentIndex = idx; + editText = textAt(idx); + } else { + editTextMatches = false; + currentIndex = -1; + popup.currentText = editText; + } + comboBox.accepted(); + } + + property bool blockUpdate: false + property string prevText + property bool editTextMatches: true + + function find (text, searchType) { + for (var i = 0 ; i < popupItems.count ; ++i) { + var currentString = popupItems.objectAt(i).text + if (searchType === Qt.MatchExactly) { + if (text === currentString) + return i; + } else if (searchType === Qt.CaseSensitive) { + if (currentString.indexOf(text) === 0) + return i; + } else if (searchType === Qt.MatchFixedString) { + if (currentString.toLowerCase().indexOf(text.toLowerCase()) === 0 + && currentString.length === text.length) + return i; + } else if (currentString.toLowerCase().indexOf(text.toLowerCase()) === 0) { + return i + } + } + return -1; + } + + // Finds first entry and shortest entry. Used by editable combo + function tryComplete (inputText) { + var candidate = ""; + var shortestString = ""; + for (var i = 0 ; i < popupItems.count ; ++i) { + var currentString = popupItems.objectAt(i).text; + + if (currentString.toLowerCase().indexOf(inputText.toLowerCase()) === 0) { + if (candidate.length) { // Find smallest possible match + var cmp = 0; + + // We try to complete the shortest string that matches our search + if (currentString.length < candidate.length) + candidate = currentString + + while (cmp < Math.min(currentString.length, shortestString.length) + && shortestString[cmp].toLowerCase() === currentString[cmp].toLowerCase()) + cmp++; + shortestString = shortestString.substring(0, cmp); + } else { // First match, select as current index and find other matches + candidate = currentString; + shortestString = currentString; + } + } + } + + if (candidate.length) + return inputText + candidate.substring(inputText.length, candidate.length); + return inputText; + } + + property bool allowComplete: false + Keys.onPressed: allowComplete = (event.key !== Qt.Key_Backspace && event.key !== Qt.Key_Delete); + + onTextChanged: { + if (editable && !blockUpdate && allowComplete && text.length > 0) { + var completed = input.tryComplete(text) + if (completed.length > text.length) { + var oldtext = input.text; + input.text = completed; + input.select(text.length, oldtext.length); + } + } + prevText = text + } + } + + Binding { + target: input + property: "text" + value: popup.currentText + when: input.editTextMatches + } + +// onTextRoleChanged: popup.resolveTextValue(textRole) + + Menu { + id: popup + objectName: "popup" + +// style: isPopup ? __style.__popupStyle : __style.__dropDownStyle + + property string currentText: selectedText + onSelectedTextChanged: if (selectedText) popup.currentText = selectedText + + property string selectedText + on__SelectedIndexChanged: { + if (__selectedIndex === -1) + popup.currentText = "" + else + updateSelectedText() + } + property string textRole: "" + + property bool ready: false + property bool isPopup: !editable && !!__panel && __panel.popup + +// property int y: isPopup ? (comboBox.__panel.height - comboBox.__panel.implicitHeight) / 2.0 : comboBox.__panel.height + __minimumWidth: comboBox.width + __visualItem: comboBox + + property ExclusiveGroup eg: ExclusiveGroup { id: eg } + + property bool modelIsArray: false + + Instantiator { + id: popupItems + active: false + + property bool updatingModel: false + onModelChanged: { + popup.modelIsArray = !!model ? model.constructor === Array : false + if (active) { + if (updatingModel && popup.__selectedIndex === 0) { + // We still want to update the currentText + popup.updateSelectedText() + } else { + updatingModel = true + popup.__selectedIndex = 0 + } + } + popup.resolveTextValue(comboBox.textRole) + } + + MenuItem { + text: popup.textRole === '' ? + modelData : + ((popup.modelIsArray ? modelData[popup.textRole] : model[popup.textRole]) || '') + onTriggered: { + if (index !== currentIndex) + activated(index) + comboBox.editText = text + } + checkable: true + exclusiveGroup: eg + } + onObjectAdded: { + popup.insertItem(index, object) + if (!updatingModel && index === popup.__selectedIndex) + popup.selectedText = object["text"] + } + onObjectRemoved: popup.removeItem(object) + + } + + function resolveTextValue(initialTextRole) { + if (!ready || !model) { + popupItems.active = false + return; + } + + var get = model['get']; + if (!get && popup.modelIsArray && !!model[0]) { + if (model[0].constructor !== String && model[0].constructor !== Number) + get = function(i) { return model[i]; } + } + + var modelMayHaveRoles = get !== undefined + textRole = initialTextRole + if (textRole === "" && modelMayHaveRoles && get(0)) { + // No text role set, check whether model has a suitable role + // If 'text' is found, or there's only one role, pick that. + var listElement = get(0) + var roleName = "" + var roleCount = 0 + for (var role in listElement) { + if (listElement[role].constructor === Function) + continue; + if (role === "text") { + roleName = role + break + } else if (!roleName) { + roleName = role + } + ++roleCount + } + if (roleCount > 1 && roleName !== "text") { + console.warn("No suitable 'textRole' found for ComboBox.") + } else { + textRole = roleName + } + } + + if (!popupItems.active) + popupItems.active = true + else + updateSelectedText() + } + + function show() { + if (items[__selectedIndex]) + items[__selectedIndex].checked = true + __currentIndex = comboBox.currentIndex + if (Qt.application.layoutDirection === Qt.RightToLeft) + __popup(comboBox.width, y, isPopup ? __selectedIndex : 0) + else + __popup(0, y, isPopup ? __selectedIndex : 0) + } + + function updateSelectedText() { + var selectedItem; + if (__selectedIndex !== -1 && (selectedItem = items[__selectedIndex])) { + input.editTextMatches = true + selectedText = selectedItem.text + } + } + } + + // The key bindings below will only be in use when popup is + // not visible. Otherwise, native popup key handling will take place: + Keys.onSpacePressed: { + if (!popup.popupVisible) + popup.show() + } + + Keys.onUpPressed: __selectPrevItem() + Keys.onDownPressed: __selectNextItem() +} diff --git a/src/mobile/qml/StartupBookshelfManager.qml b/src/mobile/qml/StartupBookshelfManager.qml new file mode 100644 index 0000000..6ad4448 --- /dev/null +++ b/src/mobile/qml/StartupBookshelfManager.qml @@ -0,0 +1,89 @@ + +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ +import QtQuick 2.2 +import BibleTime 1.0 + +Rectangle { + id: startupBookshelfManager + + signal bookshelfRequested() + + color: btStyle.textBackgroundColor + + Text { + width: parent.width + anchors.fill: parent + text: qsTr("There are currently no documents installed. Please click on the Ok button below to install new documents.") + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + wrapMode: Text.WordWrap + font.pointSize: btStyle.uiFontPointSize + anchors.margins: 30 + color: btStyle.textColor + } + + Grid { + id: buttons + + spacing: btStyle.pixelsPerMillimeterY * 4 + columns: 2 + anchors.bottom: startupBookshelfManager.bottom + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottomMargin: 50 + + Rectangle { + height: btStyle.pixelsPerMillimeterY * 7 + width: btStyle.pixelsPerMillimeterY * 25 + border.color: "black" + border.width: 4 + + Text { + text: qsTr("Ok") + anchors.centerIn: parent + font.pointSize: btStyle.uiFontPointSize + } + + MouseArea { + anchors.fill: parent + onClicked: { + startupBookshelfManager.visible = false; + startupBookshelfManager.bookshelfRequested() + } + } + } + + Rectangle { + height: btStyle.pixelsPerMillimeterY * 7 + width: btStyle.pixelsPerMillimeterY * 25 + border.color: "black" + border.width: 4 + + Text { + text: qsTr("Cancel") + anchors.centerIn: parent + font.pointSize: btStyle.uiFontPointSize + } + + MouseArea { + anchors.fill: parent + onClicked: { + startupBookshelfManager.visible = false; + } + } + } + } + + BtStyle { + id: btStyle + } +} diff --git a/src/mobile/qml/TitleColorBar.qml b/src/mobile/qml/TitleColorBar.qml new file mode 100644 index 0000000..affea57 --- /dev/null +++ b/src/mobile/qml/TitleColorBar.qml @@ -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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +import QtQuick 2.2 +import BibleTime 1.0 + +Rectangle { + id: titleBar + + property string title: "" + property int barHeight: { + var pixel = btStyle.pixelsPerMillimeterY * 6; + var uiFont = btStyle.uiFontPointSize * 2; + return Math.max(pixel, uiFont); + } + + color: btStyle.toolbarColor + border.color: "black" + border.width: 1 + height: barHeight + + Text { + id: title + color: btStyle.toolbarTextColor + font.pointSize: btStyle.uiFontPointSize + anchors.fill: parent + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + text: titleBar.title + } + + BtStyle { + id: btStyle + } +} + diff --git a/src/mobile/qml/TreeChooser.qml b/src/mobile/qml/TreeChooser.qml index 5dc1eeb..d7eb6c9 100644 --- a/src/mobile/qml/TreeChooser.qml +++ b/src/mobile/qml/TreeChooser.qml @@ -1,4 +1,16 @@ -import QtQuick 2.1 +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +import QtQuick 2.2 Rectangle { id: treeChooser @@ -8,22 +20,29 @@ Rectangle { property string path: "" property int pathCount: 0 - color: "white" + color: btStyle.textBackgroundColor border.width: 2 - border.color: "black" + border.color: btStyle.textColor signal back() signal next(string childText) signal select(string childText) + Keys.onReleased: { + if ((event.key == Qt.Key_Back || event.key == Qt.Key_Escape) && treeChooser.visible == true) { + event.accepted = true; + treeChooser.visible = false; + } + } + Rectangle { id: pathArea border.color: "black" border.width: 0 - color: "white" + color: btStyle.textBackgroundColor - height: {20 * pathCount } + height: btStyle.uiFontPointSize * (5 + pathCount *3); anchors.right: parent.right anchors.left: parent.left anchors.top: parent.top @@ -45,15 +64,19 @@ Rectangle { return newPath; } - ImageButton { + LeftArrow { id: backButton - icon: "leftarrow.svg" - height: 36 - width: 56 + height: { + var pixel = btStyle.pixelsPerMillimeterY * 8; + var uiFont = btStyle.uiFontPointSize * 4.5; + return Math.max(pixel, uiFont); + } + width: height anchors.verticalCenter: parent.verticalCenter anchors.right : parent.right anchors.topMargin: 2 + color: btStyle.textColor visible: true MouseArea { @@ -68,14 +91,13 @@ Rectangle { id: pathText text: pathArea.splitPath(treeChooser.path) - font.pointSize: 12 - height: parent.height -// width: parent.width - backButton.width -50 + height: btStyle.uiFontPointSize * 5; anchors.top: parent.top anchors.left: parent.left anchors.right: backButton.left anchors.leftMargin: 10 elide: Text.ElideRight + color: btStyle.textColor } } @@ -101,23 +123,26 @@ Rectangle { boundsBehavior: Flickable.StopAtBounds width: pathArea.width model: treeChooser.model - delegate: - Rectangle { + + delegate: Rectangle { id: entry property string action: "" - + color: btStyle.textBackgroundColor border.color: "#eeeeee" border.width: 1 width: parent.width - height: 40 + height: { + var pixel = btStyle.pixelsPerMillimeterY * 8; + var uiFont = btStyle.uiFontPointSize * 4.5; + return Math.max(pixel, uiFont); + } Text { id: entryText - font.pointSize: 12 -// anchors.fill: entry + font.pointSize: btStyle.uiFontPointSize anchors.top: entry.top anchors.left: entry.left anchors.right: entry.right @@ -127,17 +152,18 @@ Rectangle { anchors.topMargin: 10 text: name elide: Text.ElideRight + color: btStyle.textColor } - ImageButton { + RightArrow { id: imageButton - icon: "rightarrow.svg" - height: parent.height-4 - width: 56 + height: entry.height; + width: entry.height; anchors.right: parent.right anchors.top: parent.top anchors.topMargin: 2 + color: btStyle.textColor visible: childcount > 0 MouseArea { diff --git a/src/mobile/qml/Window.qml b/src/mobile/qml/Window.qml index a14131f..8172cd4 100644 --- a/src/mobile/qml/Window.qml +++ b/src/mobile/qml/Window.qml @@ -1,4 +1,16 @@ -import QtQuick 2.1 +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +import QtQuick 2.2 import BibleTime 1.0 Rectangle { @@ -6,12 +18,46 @@ Rectangle { property string title: toolbar.title + border.color: btStyle.toolbarTextColor + + signal swipeLeft + signal swipeRight + + function getModuleLanguage() { + return btWindowInterface.moduleLanguage + } + + function updateTextFonts() { + btWindowInterface.updateTextFonts(); + } + + function getModule() { + return btWindowInterface.moduleName; + } + + function getReference() { + return btWindowInterface.reference; + } + function setModule(module) { btWindowInterface.moduleName = module; } - function contextMenus() { -// contextMenu.visible = true; + function setKey(key) { + btWindowInterface.reference = key; + btWindowInterface.updateCurrentModelIndex(); + } + + function saveWindowStateToConfig (index) { + btWindowInterface.saveWindowStateToConfig(index); + } + + function setHistoryPoint() { + btWindowInterface.setHistoryPoint(); + } + + function setModuleToBeginning() { + btWindowInterface.setModuleToBeginning(); } color: "black" @@ -29,26 +75,72 @@ Rectangle { property string title: btWindowInterface.moduleName + " (" + btWindowInterface.reference + ")" - width: parent.width - height: 36 + height: { + var pixel = btStyle.pixelsPerMillimeterY * 8; + var uiFont = btStyle.uiFontPointSize * 4.4; + var mix = pixel * 0.7 + uiFont * 0.3; + return Math.max(pixel, mix); + } + anchors.left: parent.left + anchors.right: parent.right + anchors.top: parent.top + anchors.margins: 1 + + color: btStyle.toolbarColor - border.width: 1 - border.color: "black" + + PrevNextArrow { + id: prevHistory + + background: btStyle.toolbarColor + textColor: btStyle.toolbarTextColor + borderColor: btStyle.toolbarTextColor + prev: true + width: parent.height * 0.80 + height: parent.height * 0.80 + anchors.left: parent.left + anchors.top: parent.top + anchors.margins: parent.height * 0.1; + show: btWindowInterface.historyBackwardVisible + onClicked: { + if (show) + btWindowInterface.moveHistoryBackward(); + } + } + + PrevNextArrow { + id: nextHistory + + background: btStyle.toolbarColor + textColor: btStyle.toolbarTextColor + borderColor: btStyle.toolbarTextColor + prev: false + width: parent.height * 0.80 + height: parent.height * 0.80 + anchors.left: prevHistory.right + anchors.top: parent.top + anchors.margins: parent.height * 0.1; + show: btWindowInterface.historyForwardVisible + onClicked: { + if (show) + btWindowInterface.moveHistoryForward(); + } + } Rectangle { id: moduleDisplay - width: text.width +10 - radius:btStyle.buttonRadius - anchors.left: parent.left + width: text.width + 30 + radius:btStyle.pixelsPerMillimeterX + anchors.left: nextHistory.right 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 + anchors.topMargin: btStyle.pixelsPerMillimeterY * 0.7 + anchors.leftMargin: parent.height * 0.1 + anchors.bottomMargin: btStyle.pixelsPerMillimeterY * 0.7 + color: btStyle.textBackgroundColor + border.color: btStyle.toolbarTextColor + border.width: 2 Text { id: text @@ -58,7 +150,7 @@ Rectangle { anchors.rightMargin: 4 font.pointSize: btStyle.uiFontPointSize elide: Text.ElideMiddle - color: btStyle.toolbarButtonText + color: btStyle.textColor text: btWindowInterface.moduleName } @@ -77,31 +169,33 @@ Rectangle { id: referenceDisplay width: { - var w1 = 300 - var w2 = toolbar.width - moduleDisplay.width; - var w = Math.min(w1,w2); - return w - 15; + var w2 = toolbar.width - prevHistory.width -prevHistory.anchors.margins*2; + w2 = w2 - nextHistory.width -nextHistory.anchors.margins*2; + w2 = w2 - moduleDisplay.width - moduleDisplay.anchors.leftMargin - moduleDisplay.anchors.rightMargin; + w2 - w2 - parent.height * 0.2; + return w2; } - radius: btStyle.buttonRadius + radius: btStyle.pixelsPerMillimeterX 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 + anchors.topMargin: btStyle.pixelsPerMillimeterY * 0.7 + anchors.bottomMargin: btStyle.pixelsPerMillimeterY * 0.7 + anchors.leftMargin: parent.height * 0.1 + color: btStyle.textBackgroundColor + border.color: btStyle.toolbarTextColor + border.width: 2 Text { id: referenceText - anchors.centerIn: parent - anchors.leftMargin: 6 + anchors.fill: parent + anchors.leftMargin: btStyle.pixelsPerMillimeterX *4.5 anchors.rightMargin: 4 - width: referenceDisplay.width - 4 + horizontalAlignment: Text.AlignLeft + verticalAlignment: Text.AlignVCenter font.pointSize: btStyle.uiFontPointSize elide: Text.ElideMiddle - color: btStyle.toolbarButtonText + color: btStyle.textColor text: btWindowInterface.reference } @@ -120,11 +214,12 @@ Rectangle { Rectangle { id: mainTextView - color: "white" + color: btStyle.textBackgroundColor anchors.top: toolbar.bottom anchors.left: windowView.left anchors.right: windowView.right anchors.bottom: windowView.bottom + anchors.margins: 2 ListView { id: listView @@ -134,45 +229,73 @@ Rectangle { anchors.leftMargin: 8 anchors.rightMargin: 8 model: btWindowInterface.textModel + highlightFollowsCurrentItem: true currentIndex: btWindowInterface.currentModelIndex + onCurrentIndexChanged: { + positionViewAtIndex(currentIndex,ListView.Beginning) + } + onMovementEnded: { + var index = indexAt(contentX,contentY+30); + btWindowInterface.updateKeyText(index); + } + delegate: Text { - text: "<font color=\"blue\">" + ref + "</font> " + line + text: line + textFormat: Text.RichText width: parent.width - color: "black" - font.pointSize: btStyle.textFontPointSize + color: btStyle.textColor + font.family: btWindowInterface.fontName + font.pointSize: btWindowInterface.fontSize wrapMode: Text.WordWrap + onWidthChanged: doLayout() } - MouseArea { + MultiPointTouchArea { + id: globalTouchArea + + property bool activeGesture: false + property int firstX + property int firstY anchors.fill: parent - onDoubleClicked: { - windowView.contextMenus(); + enabled: false + minimumTouchPoints: 1 + maximumTouchPoints: 1 + z:0 + touchPoints: [ + TouchPoint { id: touch1 } + ] + + onPressed: { + firstX = touch1.x + firstY = touch1.y } - onPressAndHold: { - windowView.contextMenus(); + onGestureStarted: { + if (!activeGesture) { + var dx = touch1.x - firstX + var dy = touch1.y - firstY + if (Math.abs(dx) > dy * 3 && Math.abs(dx) > 0.05 * width) { + activeGesture = true; + gesture.grab() + } + } + } + onReleased: { + if (activeGesture) { + var dx = touch1.x - firstX; + var dy = touch1.y - firstY; + if (dx < 0) { + windowView.swipeLeft() + } + else { + windowView.swipeRight() + } + } + activeGesture = false; } } } } - - 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 index 3a66219..f23a6c4 100644 --- a/src/mobile/qml/WindowManager.qml +++ b/src/mobile/qml/WindowManager.qml @@ -1,42 +1,129 @@ -import QtQuick 2.1 +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +import QtQuick 2.2 import BibleTime 1.0 Rectangle { - id: windowArea + id: windowManager + + objectName: "WindowManager" 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 + + property int autoTileVer: 1 + property int autoTileHor: 2 + property int single: 3 // Tile in Desktop + // 4 is Manual in Desktop + property int autoTile: 5 + property int tabLayout: 6 + + property int windowArrangement: single + + signal setFontForLanguage(string language) + + function getTopWindowIndex() { + if (windowArrangement == single || windowArrangement == tabLayout) + return tabbedWindows.current; + return 0; + } + + function getLanguageForWindow(index) { + if (index < 0 || index >= windows.length) + return ""; + return windows[index].getModuleLanguage(); + } + + function updateTextFont() { + for (var i=0; i<windows.length; ++i) { + var window = windows[i]; + var name = window.updateTextFonts(); + } + } + + function getWindowCount() { + return windows.length; + } + + function saveWindowStateToConfig(windowIndex) { + var window = windows[windowIndex]; + window.saveWindowStateToConfig(windowIndex); + } + + function getModuleNames() { + var names = []; + for (var i=0; i<windows.length; ++i) { + var window = windows[i]; + var name = window.getModule(); + names.push(name); + } + return names; + } + + function getUniqueModuleNames() { + var moduleNames = getModuleNames(); + var uniqueNames = []; + for (var i=0; i<moduleNames.length; ++i) { + var name = moduleNames[i]; + var index = uniqueNames.indexOf(name); + if (index < 0) { + uniqueNames.push(name); + } + } + return uniqueNames; + } function setCurrentTabbedWindow(index) { tabbedWindows.current = index; } + function setNextWindow() { + var index = tabbedWindows.current + 1; + if (index >= windows.length) + index = 0; + setCurrentTabbedWindow(index); + } + + function setPreviousWindow() { + var index = tabbedWindows.current - 1; + if (index < 0) + index = windows.length - 1; + setCurrentTabbedWindow(index); + } + + function closeWindow(index) { + var window = windows[index]; + windows.splice(index,1); + window.destroy(); + layoutWindows(); + } + function setWindowArrangement(arrangement) { - if (arrangement < single || arrangement > autoTileVer) + if (arrangement < autoTileVer || arrangement > tabLayout) return; - windowLayout = arrangement; - layoutWindows(); + windowArrangement = arrangement; } - function createWindowMenus() { - windowsModel.clear(); + function createWindowMenus(model) { + model.clear(); for (var i=0; i<windows.length; ++i) { var window = windows[i]; - windowsModel.append ( + model.append ( { title: window.title, action: i.toString() } ) } - windowTitlesMenus.model = windowsModel - windowTitlesMenus.visible = true; } - function newWindow() { moduleChooser.moduleSelected.connect(openWindowSlot); moduleChooser.visible = true; @@ -44,15 +131,16 @@ Rectangle { function openWindowSlot() { moduleChooser.moduleSelected.disconnect(openWindowSlot); - openWindow(moduleChooser.selectedCategory, moduleChooser.selectedModule) + 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") + function openWindow(category, module, key) { + if (category == "Bibles"|| + category == "Cults/Unorthodox" || + category == "Commentaries" || + category == "Books" || + category == "Lexicons and Dictionaries" || + category == "Daily Devotionals") component = Qt.createComponent("Window.qml"); else { console.log(category, " are not yet supported."); @@ -60,20 +148,30 @@ Rectangle { } window = component.createObject(null, {"width": 250, "height": 200}); - window.setModule(module); if (window == null) { // Error Handling console.log("Error creating object"); } else { + window.setModule(module); + window.setModuleToBeginning(); + window.swipeLeft.connect(windowManager,setPreviousWindow) + window.swipeRight.connect(windowManager,setNextWindow) windows.push(window) layoutWindows(); var curWindow = windows.length -1; selectWindow(curWindow); + if (key !== "") + window.setKey(key); + window.setHistoryPoint(); } } + function setFont(lang) { + windowManager.setFontForLanguage(lang) + } + function layoutTiles(rows, columns) { gridWindows.columns = columns; @@ -87,6 +185,7 @@ Rectangle { window.height = height; window.width = width; window.parent = gridWindows; + window.border.width = 1; } } @@ -96,7 +195,8 @@ Rectangle { for (var i=0; i<windows.length; ++i) { var window = windows[i]; window.parent = tabbedWindowsStack; - window.anchors.fill = tabbedWindowsStack + window.anchors.fill = tabbedWindowsStack; + window.border.width = 0; } } @@ -107,6 +207,7 @@ Rectangle { var window = windows[i]; window.parent = tabbedWindowsStack; window.anchors.fill = tabbedWindowsStack + window.border.width = 0; } } @@ -116,17 +217,17 @@ Rectangle { var rows = 1; var count = windows.length; - if (windowLayout == autoTile) { + if (windowArrangement == autoTile) { if (count > 1) { columns = 2 rows = Math.floor((count+1)/2); } } - else if (windowLayout == autoTileHor) + else if (windowArrangement == autoTileHor) { rows = count; } - else if (windowLayout == autoTileVer) + else if (windowArrangement == autoTileVer) { columns = count; } @@ -134,13 +235,15 @@ Rectangle { } function layoutWindows() { + tipText.visible = (windows.length == 0); + tabbedWindows.z = -2; gridWindows.z = -3; - if (windowLayout == single) { + if (windowArrangement == single) { arrangeSingleWindow(); } - else if (windowLayout == tabLayout) { + else if (windowArrangement == tabLayout) { arrangeTabbedWindows(); } else { @@ -149,16 +252,28 @@ Rectangle { } function selectWindow(n) { - if (windowLayout == tabLayout || windowLayout == single) { + if (windowArrangement == tabLayout || windowArrangement == single) { tabbedWindows.current = n; } } -// anchors.top: spacer.bottom -// anchors.left: parent.left -// anchors.right: parent.right -// anchors.bottom: parent.bottom -// color: "#646464" + onWindowArrangementChanged: layoutWindows() + + Text { + id: tipText + + text: qsTranslate("Welcome", "Use the \"New Window\" menu to open a document.") + anchors.left: windowManager.left + anchors.right: windowManager.right + anchors.verticalCenter: windowManager.verticalCenter + anchors.margins: btStyle.pixelsPerMillimeterX*6 + horizontalAlignment: Text.AlignJustify + font.pointSize: btStyle.uiFontPointSize; + color: btStyle.textColor + visible: false + wrapMode: Text.Wrap + z: 10 + } Grid { id: gridWindows @@ -166,8 +281,14 @@ Rectangle { objectName: "gridWindows" anchors.fill: parent columns: 2 - spacing: 2 + spacing: 0 z: 2 + onWidthChanged: { + layoutWindows(); + } + onHeightChanged: { + layoutWindows(); + } } Item { @@ -217,22 +338,21 @@ Rectangle { function calculateTabWidth() { var tabWidth = (tabbedWindows.width) / tabbedWindowsStack.children.length; + tabWidth = Math.min(tabbedWindows.width/2, tabWidth) 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" + height: { + var pixel = btStyle.pixelsPerMillimeterY * 7.5; + var uiFont = btStyle.uiFontPointSize * 4.4; + var mix = pixel * 0.7 + uiFont * 0.3; + return Math.max(pixel, mix); } + color: btStyle.toolbarColor Rectangle { id: tabImage @@ -244,8 +364,15 @@ Rectangle { else return btStyle.windowTab } - border.color: btStyle.windowTab - border.width: 2 + radius: height/2 + + Rectangle { + color: tabImage.color + height: tabImage.height/2 + width: tabImage.width + anchors.left: tabImage.left + anchors.bottom: tabImage.bottom + } Text { id: tabText @@ -253,8 +380,8 @@ Rectangle { horizontalAlignment: Qt.AlignHCenter; verticalAlignment: Qt.AlignVCenter anchors.fill: parent - anchors.topMargin: 6 - font.pointSize: btStyle.uiFontPointSize -3 + anchors.topMargin: 4 + font.pointSize: btStyle.uiFontPointSize -1 text: tabbedWindowsStack.children[index].title elide: Text.ElideLeft color: { diff --git a/src/mobile/qml/checkmark.svg b/src/mobile/qml/checkmark.svg deleted file mode 100644 index 07a3ad8..0000000 --- a/src/mobile/qml/checkmark.svg +++ /dev/null @@ -1,42 +0,0 @@ -<?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 deleted file mode 100644 index 6143c87..0000000 --- a/src/mobile/qml/leftarrow.svg +++ /dev/null @@ -1,83 +0,0 @@ -<?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 index d7597b1..b47af04 100644 --- a/src/mobile/qml/main.qml +++ b/src/mobile/qml/main.qml @@ -1,15 +1,40 @@ -import QtQuick 2.1 +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +import QtQuick 2.2 +import QtQml 2.2 +import QtQuick.Window 2.1 import BibleTime 1.0 Rectangle { id: root + color: "blue" property int opacitypopup: 0 property QtObject component: null; property Item window: null; + Component.onCompleted: { + setFontDialog.textFontChanged.connect(windowManager.updateTextFont) + } + + ListModel { + id: viewWindowsModel + + ListElement { title: ""; action: "" } + } + ListModel { - id: windowsModel + id: closeWindowsModel ListElement { title: ""; action: "" } } @@ -18,11 +43,44 @@ Rectangle { installManager.openChooser(); } -// width: 1280 // Nexus 7 (2012) -// height: 800 + function startSearch() { + var moduleNames = windowManager.getUniqueModuleNames(); + searchModel.appendModuleChoices(moduleNames); + search.searchText = ""; + search.visible = true; + } - width: 480 // Phone - height: 800 + Keys.forwardTo: [ + gridChooser, + moduleChooser, + mainMenus, + windowArrangementMenus, + viewWindowsMenus, + closeWindowsMenus, + searchResults, + search, + installManagerChooser, + keyNameChooser, + treeChooser, + aboutDialog, + uiFontPointSize, + setFontDialog + ] + + Keys.onReleased: { + if (event.key == Qt.Key_Back || event.key == Qt.Key_Escape) { + event.accepted = true; + quitQuestion.visible = true; + } + } + + Keys.onMenuPressed: { + event.accepted = true; + mainMenus.visible = ! mainMenus.visible + } + + width: 1000 + height: 750 rotation: 0 @@ -32,10 +90,18 @@ Rectangle { anchors.left: parent.left anchors.top: parent.top anchors.right: parent.right - height: 30 + height: { + var pixel = btStyle.pixelsPerMillimeterY * 7.5; + var uiFont = btStyle.uiFontPointSize * 4.4; + var mix = pixel * 0.7 + uiFont * 0.3; + return Math.max(pixel, mix); + } onButtonClicked: { mainMenus.visible = ! mainMenus.visible; } + onSearchClicked: { + startSearch(); + } } Rectangle { @@ -54,14 +120,8 @@ Rectangle { anchors.left: parent.left anchors.right: parent.right anchors.bottom: parent.bottom - color: "#646464" - - } - - Settings { - id: settings + color: btStyle.toolbarColor - visible: false; } GridChooser { @@ -91,7 +151,7 @@ Rectangle { id: treeChooser objectName: "treeChooser" - width:480 + width:parent.width height: parent.height anchors.top: parent.top anchors.horizontalCenter: parent.horizontalCenter @@ -100,6 +160,132 @@ Rectangle { z: 100 } + KeyNameChooser { + id: keyNameChooser + + objectName: "keyNameChooser" + width: parent.width + height: parent.height + anchors.top: parent.top + visible: false + } + + Question { + id: startupBookshelfManager + + objectName: "startupBookshelfManager" + background: btStyle.toolbarColor + text: qsTr("BibleTime views documents such as Bibles and commentaries. These documents are downloaded and stored locally." + + "There are currently no documents. Do you want to install documents now?") + onFinished: { + startupBookshelfManager.visible = false; + if (answer == true) { + installManagerChooser.refreshOnOpen = true; + installModules(); + } + } + } + + Search { + id: search + + moduleChoices: searchModel + onSearchRequest: { + searchResults.moduleList = search.moduleList; + if ( ! searchResults.modulesAreIndexed()) { + search.visible = false; + indexQuestion.visible = true; + return; + } + openSearchResults(); + } + + function openSearchResults() { + searchResults.searchText = search.searchText; + searchResults.findChoice = search.findChoice; + searchResults.moduleList = search.moduleList; + search.visible = false; + searchResults.performSearch(); + searchResults.visible = true; + } + } + + SearchResults { + id: searchResults + z:2 + + onVisibleChanged: { + if ( ! visible) { + search.visible = true; + } + } + onIndexingFinishedChanged: { + indexProgress.visible = false; + if ( ! searchResults.indexingWasCancelled()) { + search.openSearchResults(); + } + } + } + + Question { + id: indexQuestion + background: btStyle.toolbarColor + text: qsTr("Some of the modules you want to search need to be indexed. Do you want to index them now?") + onFinished: { + indexQuestion.visible = false; + + if (answer == true) { + indexProgress.visible = true; + } else { + search.visible = false; + } + } + } + + Progress { + id: indexProgress + + objectName: "indexProgress" + value: 0 + minimumValue: 0 + maximumValue: 100 + width:parent.width * 0.85 + height: btStyle.pixelsPerMillimeterY * 30 + anchors.centerIn: parent + anchors.top: parent.top + visible: false + onVisibleChanged: { + if (visible == true) { + searchResults.indexModules(); + } + } + onCancel: { + searchResults.cancel(); + } + } + + ListModel { + id:searchModel + + function appendModuleChoices(choices) { + searchModel.clear(); + var firstChoice = ""; + for (var j=0; j<choices.length; ++j) { + var choice = choices[j]; + if (j>0) + firstChoice += ", "; + firstChoice += choice; + } + searchModel.append({"text": firstChoice , "value": firstChoice}) + + for (var j=0; j<choices.length; ++j) { + var choice = choices[j]; + searchModel.append({"text": choice , "value": choice}) + } + } + ListElement { text: "ESV"; value: "ESV" } + } + InstallManager { id: installManager } @@ -108,7 +294,7 @@ Rectangle { id: installManagerChooser objectName: "installManagerChooser" - width: Math.min(parent.height, parent.width); + width: parent.width; height: parent.height anchors.centerIn: parent anchors.top: parent.top @@ -122,8 +308,8 @@ Rectangle { value: 0.25 minimumValue: 0 maximumValue: 1 - width:550 - height: 200 + width:parent.width * 0.85 + height: btStyle.pixelsPerMillimeterY * 30 anchors.centerIn: parent anchors.top: parent.top visible: false @@ -132,15 +318,15 @@ Rectangle { 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" } + ListElement { title: QT_TR_NOOP("New Window"); action: "newWindow" } + ListElement { title: QT_TR_NOOP("View Window"); action: "view window" } + ListElement { title: QT_TR_NOOP("Close Window"); action: "close window" } + ListElement { title: QT_TR_NOOP("Manage Installed Documents");action: "install" } + ListElement { title: QT_TR_NOOP("Text Font"); action: "textFontSize" } + ListElement { title: QT_TR_NOOP("User Interface Font Size"); action: "uiFontSize" } + ListElement { title: QT_TR_NOOP("Window Arrangement"); action: "windowArrangement" } + ListElement { title: QT_TR_NOOP("Color Theme"); action: "colortheme" } + ListElement { title: QT_TR_NOOP("About"); action: "about" } } Menus { @@ -153,27 +339,35 @@ Rectangle { if (action == "newWindow") { windowManager.newWindow(); } - else if (action == "windows") { - windowManager.createWindowMenus(); + else if (action == "view window") { + windowManager.createWindowMenus(viewWindowsModel); + viewWindowsMenus.visible = true; } - else if (action == "gnomeStyle") { - btStyle.setStyle(1) + else if (action == "close window") { + windowManager.createWindowMenus(closeWindowsModel); + closeWindowsMenus.visible = true; } - else if (action == "androidStyle") { - btStyle.setStyle(2) + else if (action == "colortheme") { + colorThemeMenus.visible = true; } else if (action == "install") { installModules(); } + else if (action == "about") { + aboutDialog.visible = true; + } else if (action == "settings") { settings.visible = true; } else if (action == "textFontSize") { - textFontPointSize.visible = true; + setFontDialog.open(); } else if (action == "uiFontSize") { uiFontPointSize.visible = true; } + else if (action == "windowArrangement") { + windowArrangementMenus.visible = true; + } } @@ -218,26 +412,71 @@ Rectangle { model: windowArrangementModel } + ListModel { + id: colorThemeModel + + ListElement { title: QT_TR_NOOP("Dark"); action: "dark" } + ListElement { title: QT_TR_NOOP("Light Blue"); action: "lightblue" } + ListElement { title: QT_TR_NOOP("Crimson"); action: "crimson" } + } + + Menus { + id: colorThemeMenus + + Component.onCompleted: menuSelected.connect(colorThemeMenus.doAction) + + function doAction(action) { + colorThemeMenus.visible = false; + if (action == "dark") { + btStyle.setStyle(1) + } + else if (action == "lightblue") { + btStyle.setStyle(2) + } + else if (action == "crimson") { + btStyle.setStyle(3) + } + } + + model: colorThemeModel + } + Menus { - id: windowTitlesMenus + id: viewWindowsMenus - model: windowsModel + model: viewWindowsModel visible: false - Component.onCompleted: menuSelected.connect(windowTitlesMenus.doAction) + Component.onCompleted: menuSelected.connect(viewWindowsMenus.doAction) function doAction(action) { - windowTitlesMenus.visible = false; + viewWindowsMenus.visible = false; var index = Number(action) windowManager.setCurrentTabbedWindow(index); } } + Menus { + id: closeWindowsMenus + + model: closeWindowsModel + visible: false + Component.onCompleted: menuSelected.connect(closeWindowsMenus.doAction) + + function doAction(action) { + closeWindowsMenus.visible = false; + var index = Number(action) + windowManager.closeWindow(index); + } + } + FontSizeSlider { id: uiFontPointSize + visible: false - title: "User Interface Font Size" + title: QT_TR_NOOP("User Interface Font Size") onVisibleChanged: { + mainToolbar.enabled = ! uiFontPointSize.visible if (visible) { uiFontPointSize.current = btStyle.uiFontPointSize; @@ -250,21 +489,33 @@ Rectangle { } } - FontSizeSlider { - id: textFontPointSize + Question { + id: quitQuestion + background: btStyle.toolbarColor + text: qsTranslate("Quit", "Are you sure you want to quit?") + onFinished: { + if (answer == true) + Qt.quit(); + } + } + + About { + id: aboutDialog visible: false - title: "Text Font Size" + } + + SetFont { + id:setFontDialog + visible: false onVisibleChanged: { - if (visible) - { - textFontPointSize.current = btStyle.textFontPointSize; - textFontPointSize.previous = btStyle.textFontPointSize; - } + mainToolbar.enabled = ! setFontDialog.visible } - onAccepted: { - btStyle.textFontPointSize = pointSize; + function open() { + var index = windowManager.getTopWindowIndex(); + language = windowManager.getLanguageForWindow(index); + setFontDialog.visible = true; } } } diff --git a/src/mobile/qml/rightarrow.svg b/src/mobile/qml/rightarrow.svg deleted file mode 100644 index e9fd5d1..0000000 --- a/src/mobile/qml/rightarrow.svg +++ /dev/null @@ -1,82 +0,0 @@ -<?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 Binary files differdeleted file mode 100644 index ad80216..0000000 --- a/src/mobile/qml/tab.png +++ /dev/null diff --git a/src/mobile/sessionmanager/sessionmanager.cpp b/src/mobile/sessionmanager/sessionmanager.cpp new file mode 100644 index 0000000..2984213 --- /dev/null +++ b/src/mobile/sessionmanager/sessionmanager.cpp @@ -0,0 +1,125 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +#include "sessionmanager.h" + +#include <QGenericReturnArgument> +#include <QMetaObject> +#include <QQuickItem> +#include "backend/config/btconfig.h" +#include "backend/managers/cswordbackend.h" +#include "mobile/ui/btstyle.h" +#include "mobile/util/findqmlobject.h" +#include "util/btassert.h" + + +namespace btm { + +SessionManager::SessionManager(QObject* parent) + : QObject(parent) { + m_windowMgr = findQmlObject("WindowManager"); + BT_ASSERT(m_windowMgr); +} + +void SessionManager::loadDefaultSession() { + loadWindows(); + + int colorTheme = getColorTheme(); + BtStyle::setCurrentStyle(colorTheme); + + int windowArrangementMode = getWindowArrangementMode(); + m_windowMgr->setProperty("windowArrangement", windowArrangementMode); +} + +void SessionManager::loadWindows() { + BtConfig & conf = btConfig(); + Q_FOREACH (const QString & w, + conf.sessionValue<QStringList>("windowsList")) + { + const QString windowGroup = "window/" + w + '/'; + + QStringList moduleNames = conf.sessionValue<QStringList>(windowGroup + "modules"); + if (moduleNames.count() == 0) + continue; + const QString key = conf.sessionValue<QString>(windowGroup + "key"); + loadWindow(moduleNames, key); + } +} + +void SessionManager::loadWindow(const QStringList& moduleNames, const QString& key) { + + const QString moduleName = moduleNames.at(0); // We don't support parallel yet! + CSwordModuleInfo * const m = CSwordBackend::instance()->findModuleByName(moduleName); + if (m == nullptr) + return; + CSwordModuleInfo::Category category = m->category(); + const QString categoryName = m->englishCategoryName(category); + newWindow(categoryName, moduleName, key); +} + +void SessionManager::newWindow(const QString& category, + const QString& moduleName, + const QString& key) { + + QMetaObject::invokeMethod(m_windowMgr, "openWindow", + Q_ARG(QVariant, category), + Q_ARG(QVariant, moduleName), + Q_ARG(QVariant, key)); +} + +int SessionManager::getWindowArrangementMode() { + BtConfig & conf = btConfig(); + return conf.sessionValue<int>("MainWindow/MDIArrangementMode"); +} + +int SessionManager::getColorTheme() { + BtConfig & conf = btConfig(); + return conf.sessionValue<int>("ColorTheme", BtStyle::darkTheme); +} + +void SessionManager::saveDefaultSession() { + + BtConfig & conf = btConfig(); + + int currentStyle = BtStyle::getCurrentStyle(); + conf.setSessionValue("ColorTheme",currentStyle); + + int windowArrangementMode = m_windowMgr->property("windowArrangement").toInt(); + conf.setSessionValue("MainWindow/MDIArrangementMode", windowArrangementMode); + + + int windowCount = getWindowCount(); + QStringList windowsList; + for (int windowIndex = 0; windowIndex < windowCount; ++windowIndex) + { + windowsList.append(QString::number(windowIndex)); + saveWindowStateToConfig(windowIndex); + } + conf.setSessionValue("windowsList", windowsList); +} + +int SessionManager::getWindowCount() { + QVariant windowCountV; + QMetaObject::invokeMethod(m_windowMgr, "getWindowCount", Q_RETURN_ARG(QVariant, windowCountV)); + + int windowCount = 0; + if (windowCountV.canConvert(QMetaType::Int)) + windowCount = windowCountV.toInt(); + return windowCount; +} + +void SessionManager::saveWindowStateToConfig(int windowIndex) { + + QMetaObject::invokeMethod(m_windowMgr, "saveWindowStateToConfig", + Q_ARG(QVariant, windowIndex)); +} +} diff --git a/src/mobile/sessionmanager/sessionmanager.h b/src/mobile/sessionmanager/sessionmanager.h new file mode 100644 index 0000000..b85486e --- /dev/null +++ b/src/mobile/sessionmanager/sessionmanager.h @@ -0,0 +1,43 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +#pragma once + +#include <QObject> +#include <QString> +#include <QStringList> + +class QQuickItem; + +namespace btm { + +class SessionManager : public QObject { + Q_OBJECT + +public: + SessionManager(QObject* parent = nullptr); + void loadDefaultSession(); + void saveDefaultSession(); + +private: + int getColorTheme(); + int getWindowArrangementMode(); + int getWindowCount(); + void loadWindow(const QStringList& moduleNames, const QString& key); + void loadWindows(); + void newWindow(const QString& category, const QString& moduleName, const QString& key); + void saveWindowStateToConfig(int windowIndex); + + QQuickItem* m_windowMgr; +}; + +} diff --git a/src/mobile/ui/btsearchinterface.cpp b/src/mobile/ui/btsearchinterface.cpp new file mode 100644 index 0000000..2e6f1d7 --- /dev/null +++ b/src/mobile/ui/btsearchinterface.cpp @@ -0,0 +1,276 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +#include "btsearchinterface.h" + +#include <QDebug> +#include <QQuickItem> +#include "../util/findqmlobject.h" +#include "backend/drivers/cswordmoduleinfo.h" +#include "backend/managers/cswordbackend.h" +#include "mobile/ui/indexthread.h" +#include "util/btconnect.h" + + +namespace btm { +using CSMI = QList<CSwordModuleInfo const *>; + +BtSearchInterface::BtSearchInterface(QObject* parent) + : QObject(parent), m_searchType(AndType), m_progressObject(nullptr), m_wasCancelled(false) { +} + +BtSearchInterface::~BtSearchInterface() { +} + +static const CSwordModuleInfo* getModuleFromResults(const CSwordModuleSearch::Results& results, int index) { + + int moduleIndex = 0; + Q_FOREACH(CSwordModuleInfo const * const module, results.keys()) { + if (moduleIndex == index) + return module; + ++moduleIndex; + } + return nullptr; +} + +bool BtSearchInterface::modulesAreIndexed() { + QStringList moduleList = m_moduleList.split(", "); + CSMI modules = CSwordBackend::instance()->getConstPointerList(moduleList); + CSMI unindexedModules = CSwordModuleSearch::unindexedModules(modules); + if (unindexedModules.size() > 0) + return false; + return true; +} + +void BtSearchInterface::slotModuleProgress(int value) { + if (m_progressObject != nullptr) + m_progressObject->setProperty("value", value); +} + +void BtSearchInterface::slotBeginModuleIndexing(const QString& moduleName) { + QString title = tr("Indexing") + " " + moduleName; + m_progressObject->setProperty("text", title); +} +void BtSearchInterface::slotIndexingFinished() { + emit indexingFinished(); +} + +void BtSearchInterface::cancel() { + m_thread->stopIndex(); + m_wasCancelled = true; +} + +bool BtSearchInterface::wasCanceled() { + return m_wasCancelled; +} + +enum TextRoles { + TextRole = Qt::UserRole + 1, + ValueRole = Qt::UserRole + 2 +}; + +bool BtSearchInterface::indexModules() { + QStringList moduleList = m_moduleList.split(", "); + CSMI modules = CSwordBackend::instance()->getConstPointerList(moduleList); + bool success = true; + m_wasCancelled = false; + + if (m_progressObject == nullptr) + m_progressObject = findQmlObject("indexProgress"); + + QList<CSwordModuleInfo *> nonIndexedModules; + Q_FOREACH(CSwordModuleInfo const * const cm, modules) { + if (cm->hasIndex()) + continue; + CSwordModuleInfo *m = const_cast<CSwordModuleInfo*>(cm); + nonIndexedModules.append(m); + } + m_thread = new IndexThread(nonIndexedModules); + BT_CONNECT(m_thread, SIGNAL(indexingProgress(int)), + this, SLOT(slotModuleProgress(int))); + BT_CONNECT(m_thread, SIGNAL(beginIndexingModule(QString const &)), + this, SLOT(slotBeginModuleIndexing(QString const &))); + BT_CONNECT(m_thread, SIGNAL(indexingFinished()), + this, SLOT(slotIndexingFinished())); + + m_thread->start(); + return success; +} + +bool BtSearchInterface::performSearch() { + + setupSearchType(); + QString searchText = prepareSearchText(m_searchText); + + // Check that we have the indices we need for searching + QStringList moduleList = m_moduleList.split(", "); + CSMI modules = CSwordBackend::instance()->getConstPointerList(moduleList); + + // Set the search options: + CSwordModuleSearch searcher; + searcher.setSearchedText(searchText); + searcher.setModules(modules); + searcher.resetSearchScope(); + + searcher.startSearch(); + + m_results = searcher.results(); + setupModuleModel(m_results); + const CSwordModuleInfo* module = getModuleFromResults(m_results,0); + setupReferenceModel(module, m_results.value(module)); + return true; +} + +void BtSearchInterface::setupSearchType() { + if (m_findChoice == "and") + m_searchType = AndType; + else if (m_findChoice == "or") + m_searchType = OrType; + else + m_searchType = FullType; +} + +QString BtSearchInterface::prepareSearchText(const QString& orig) { + static const QRegExp syntaxCharacters("[+\\-()!\"~]"); + static const QRegExp andWords("\\band\\b", Qt::CaseInsensitive); + static const QRegExp orWords("\\bor\\b", Qt::CaseInsensitive); + QString text(""); + if (m_searchType == AndType) { + text = orig.simplified(); + text.remove(syntaxCharacters); + text.replace(andWords, "\"and\""); + text.replace(orWords, "\"or\""); + text.replace(" ", " AND "); + } + if (m_searchType == OrType) { + text = orig.simplified(); + text.remove(syntaxCharacters); + text.replace(andWords, "\"and\""); + text.replace(orWords, "\"or\""); + } + if (m_searchType == FullType) { + text = orig; + } + return text; +} + +void BtSearchInterface::setupModuleModel(const CSwordModuleSearch::Results & results) { + QHash<int, QByteArray> roleNames; + roleNames[TextRole] = "text"; + roleNames[ValueRole] = "value"; + m_modulesModel.setRoleNames(roleNames); + + m_modulesModel.clear(); + Q_FOREACH(CSwordModuleInfo const * const m, results.keys()) { + const int count = sword::ListKey(results.value(m)).getCount(); + QString moduleName = m->name(); + QString moduleEntry = moduleName + "(" +QString::number(count) + ")"; + + QStandardItem* item = new QStandardItem(); + item->setData(moduleEntry, TextRole); + item->setData(moduleName, ValueRole); + m_modulesModel.appendRow(item); + } + modulesModelChanged(); +} + +/** Setups the list with the given module. */ +void BtSearchInterface::setupReferenceModel(const CSwordModuleInfo *m, + const sword::ListKey & results) +{ + QHash<int, QByteArray> roleNames; + roleNames[TextRole] = "text"; + roleNames[ValueRole] = "value"; + m_referencesModel.setRoleNames(roleNames); + + m_referencesModel.clear(); + if (!m) + return; + const int count = results.getCount(); + if (!count) + return; + + for (int index = 0; index < count; index++) { + QString reference = QString::fromUtf8(results.getElement(index)->getText()); + QStandardItem* item = new QStandardItem(); + item->setData(reference, TextRole); + item->setData(reference, ValueRole); + m_referencesModel.appendRow(item); + } + referencesModelChanged(); +} + +QString BtSearchInterface::getSearchText() const { + return m_searchText; +} + +QString BtSearchInterface::getFindChoice() const { + return m_findChoice; +} + +QString BtSearchInterface::getModuleList() const { + return m_moduleList; +} + +void BtSearchInterface::setSearchText(const QString& searchText) { + m_searchText = searchText; +} + +void BtSearchInterface::setFindChoice(const QString& findChoice) { + m_findChoice = findChoice; +} + +void BtSearchInterface::setModuleList(const QString& moduleList) { + m_moduleList = moduleList; +} + +QVariant BtSearchInterface::getModulesModel() { + QVariant var; + var.setValue(&m_modulesModel); + return var; +} + +QVariant BtSearchInterface::getReferencesModel() { + QVariant var; + var.setValue(&m_referencesModel); + return var; +} + +void BtSearchInterface::selectReferences(int moduleIndex) { + const int count = m_results.count(); + if ( moduleIndex < 0 || moduleIndex >= count) + return; + const CSwordModuleInfo* module = getModuleFromResults(m_results, moduleIndex); + setupReferenceModel(module, m_results.value(module)); +} + +QString BtSearchInterface::getReference(int index) { + const int count = m_referencesModel.rowCount(); + if ( index < 0 || index >= count) + return QString(); + QString value = m_referencesModel.item(index,0)->data(ValueRole).toString(); + return value; +} + +QString BtSearchInterface::getModuleName(int index) { + const int count = m_modulesModel.rowCount(); + if ( index < 0 || index >= count) + return QString(); + QString value = m_modulesModel.item(index,0)->data(ValueRole).toString(); + return value; +} + +void BtSearchInterface::setSearchType(int searchType) { + m_searchType = searchType; +} + +} // end namespace diff --git a/src/mobile/ui/btsearchinterface.h b/src/mobile/ui/btsearchinterface.h new file mode 100644 index 0000000..ae2e972 --- /dev/null +++ b/src/mobile/ui/btsearchinterface.h @@ -0,0 +1,117 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +#ifndef BT_SEARCH_INTERFACE_H +#define BT_SEARCH_INTERFACE_H + +#include <QObject> +#include <QString> +#include "backend/cswordmodulesearch.h" +#include "mobile/models/roleitemmodel.h" +#include "mobile/models/roleitemmodel.h" +#include <listkey.h> + +class CSwordKey; +class CSwordVerseKey; +class CSwordModuleInfo; +class BtModuleTextModel; +class QQuickItem; +class IndexThread; + +namespace btm { + +class BtSearchInterface : public QObject { + + Q_OBJECT + + enum findType { + AndType, + OrType, + FullType + }; + + Q_PROPERTY(QString searchText READ getSearchText WRITE setSearchText) + Q_PROPERTY(QString findChoice READ getFindChoice WRITE setFindChoice) + Q_PROPERTY(QString moduleList READ getModuleList WRITE setModuleList) + Q_PROPERTY(QVariant modulesModel READ getModulesModel NOTIFY modulesModelChanged) + Q_PROPERTY(QVariant referencesModel READ getReferencesModel NOTIFY referencesModelChanged) + Q_PROPERTY(int AndType READ getAndType) + Q_PROPERTY(int OrType READ getAndType) + Q_PROPERTY(int FullType READ getAndType) + Q_PROPERTY(int searchType READ getSearchType WRITE setSearchType) + Q_PROPERTY(bool indexingFinished READ getIndexingFinished NOTIFY indexingFinished) + +public: + Q_INVOKABLE bool performSearch(); + Q_INVOKABLE bool modulesAreIndexed(); + Q_INVOKABLE bool indexModules(); + Q_INVOKABLE void selectReferences(int moduleIndex); + Q_INVOKABLE QString getModuleName(int index); + Q_INVOKABLE QString getReference(int index); + Q_INVOKABLE void cancel(); + + BtSearchInterface(QObject *parent = nullptr); + ~BtSearchInterface(); + + QString getSearchText() const; + QString getFindChoice() const; + QString getModuleList() const; + + void setSearchText(const QString& searchText); + void setFindChoice(const QString& findChoice); + void setModuleList(const QString& moduleList); + + QVariant getModulesModel(); + QVariant getReferencesModel(); + + int getAndType() { return AndType; } + int getOrType() { return OrType; } + int getFullType() { return FullType; } + int getSearchType() { return m_searchType; } + bool getIndexingFinished() { + return true; + }; + void setSearchType(int searchType); + +signals: + void modulesModelChanged(); + void referencesModelChanged(); + void indexingFinished(); + +private slots: + void slotModuleProgress(int value); + void slotBeginModuleIndexing(const QString& moduleName); + void slotIndexingFinished(); + +private: + QString prepareSearchText(const QString& orig); + void setupModuleModel(const CSwordModuleSearch::Results& results); + void setupReferenceModel(const CSwordModuleInfo *m, + const sword::ListKey & results); + void setupSearchType(); + bool wasCanceled(); + + int m_searchType; + QQuickItem* m_progressObject; + IndexThread* m_thread; + bool m_wasCancelled; + QString m_searchText; + QString m_findChoice; + QString m_moduleList; + RoleItemModel m_modulesModel; + RoleItemModel m_referencesModel; + CSwordModuleSearch::Results m_results; +}; + +} // end namespace + +#endif diff --git a/src/mobile/ui/btstyle.cpp b/src/mobile/ui/btstyle.cpp index ee22d15..300e91d 100644 --- a/src/mobile/ui/btstyle.cpp +++ b/src/mobile/ui/btstyle.cpp @@ -1,8 +1,22 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ #include "btstyle.h" +#include <QGuiApplication> #include <QList> #include <QPointer> +#include <QScreen> #include "backend/config/btconfig.h" +#include "backend/models/btmoduletextmodel.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 @@ -23,6 +37,11 @@ namespace btm { // Only one copy of properties so they are the same everywhere used. +static QColor textColor = QColor(); +static QColor linkColor = QColor(); +static QColor textBackgroundColor = QColor(); +static QColor textBackgroundHighlightColor= QColor(); + static QColor buttonColor = QColor(); static QColor buttonBackground = QColor(); static QColor buttonTextColor = QColor(); @@ -45,55 +64,52 @@ static QColor menuText = QColor(); static int menuHeight = 0; static QColor toolbarColor = QColor(); -static QColor toolbarButton = QColor(); +static QColor toolbarTextColor = QColor(); static QColor toolbarButtonText = QColor(); static double toolbarTextPointSize = 6; +int currentStyle = BtStyle::darkTheme; static QList<QPointer<BtStyle> > styles; +static double millimeterPerInch = 25.4; + static void emitChanged() { for (int i=0; i<styles.count(); ++i) { QPointer<BtStyle> style = styles.at(i); - if (style != 0) + if (style != nullptr) style->changed(); } } +int BtStyle::getCurrentStyle() { + return currentStyle; +} + 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)); + setCurrentStyle(style); + emitChanged(); +} - setMenu(QColor(255,255,255)); - setMenuBorder(QColor(255,255,255)); - setMenuText(QColor(0,0,0)); - setMenuHeight(40); +void BtStyle::setCurrentStyle(int style) { + if (style == BtStyle::darkTheme) { + + currentStyle = style; + + BtModuleTextModel::setLinkColor(QColor(0,191,255)); + BtModuleTextModel::setHighlightColor(QColor(255,255,0)); + BtModuleTextModel::setJesusWordsColor(QColor(255,0,0)); + + setTextColor(QColor(255,255,255)); + setLinkColor(QColor(0,0,80)); + setTextBackgroundColor(QColor(0,0,0)); + setTextBackgroundHighlightColor(QColor(184,135,11)); - 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)); + setButtonBorder(QColor(110,110,110)); setButtonRadius(3); setButtonGradient0(QColor(125,125,125)); setButtonGradient1(QColor(60,60,60)); @@ -101,22 +117,98 @@ void BtStyle::setStyle(int style) { setButtonGradient3(QColor(20,20,20)); setWindowTab(QColor(100,100,100)); - setWindowTabSelected(QColor(255,255,255)); + setWindowTabSelected(QColor(218,165,3)); setWindowTabText(QColor(255,255,255)); setWindowTabTextSelected(QColor(0,0,0)); setMenu(QColor(255,255,255)); - setMenuBorder(QColor(224,224,224)); + setMenuBorder(QColor(60,60,60)); setMenuText(QColor(0,0,0)); setMenuHeight(34); - setToolbarColor(QColor(120,120,120)); - setToolbarButton(QColor(255,210,0)); + setToolbarColor(QColor(0,0,0)); + setToolbarTextColor(QColor(218,165,3)); + setToolbarButtonText(QColor(255,255,255)); + setToolbarTextPointSize(10); + } + else if (style == BtStyle::lightBlueTheme) { + + currentStyle = style; + + BtModuleTextModel::setLinkColor(QColor(0,0,255)); + BtModuleTextModel::setHighlightColor(QColor(0,0,255)); + BtModuleTextModel::setJesusWordsColor(QColor(255,0,0)); + + setTextColor(QColor(0,0,0)); + setLinkColor(QColor(0,0,220)); + setTextBackgroundColor(QColor(255,255,255)); + setTextBackgroundHighlightColor(QColor(255,240,170)); + + setButtonColor(QColor(0,0,0)); + setButtonBackground(QColor(190,220,255)); + setButtonTextColor(QColor(0,0,0)); + setButtonHighlightedText(QColor(0,0,255)); + setButtonBorder(QColor(80,80,0)); + setButtonRadius(3); + setButtonGradient0(QColor(180,180,255)); + setButtonGradient1(QColor(255,255,255)); + setButtonGradient2(QColor(255,255,255)); + setButtonGradient3(QColor(180,180,255)); + + setWindowTab(QColor(245,245,245)); + setWindowTabSelected(QColor(65,105,225)); + setWindowTabText(QColor(100,100,100)); + setWindowTabTextSelected(QColor(255,255,255)); + + setMenu(QColor(255,255,255)); + setMenuBorder(QColor(220,220,220)); + setMenuText(QColor(0,0,0)); + setMenuHeight(40); + + setToolbarColor(QColor(190,220,255)); + setToolbarTextColor(QColor(0,0,0)); setToolbarButtonText(QColor(0,0,0)); setToolbarTextPointSize(10); } + else if (style == BtStyle::crimsonTheme) { - emitChanged(); + currentStyle = style; + + BtModuleTextModel::setLinkColor(QColor(0,0,255)); + BtModuleTextModel::setHighlightColor(QColor(0,0,255)); + BtModuleTextModel::setJesusWordsColor(QColor(170,0,0)); + + setTextColor(QColor(0,0,0)); + setLinkColor(QColor(0,0,220)); + setTextBackgroundColor(QColor(255,255,255)); + setTextBackgroundHighlightColor(QColor(255,240,170)); + + setButtonColor(QColor(0,0,0)); + setButtonBackground(QColor(190,220,255)); + setButtonTextColor(QColor(0,0,0)); + setButtonHighlightedText(QColor(0,0,255)); + setButtonBorder(QColor(80,80,0)); + setButtonRadius(3); + setButtonGradient0(QColor(180,180,255)); + setButtonGradient1(QColor(255,255,255)); + setButtonGradient2(QColor(255,255,255)); + setButtonGradient3(QColor(180,180,255)); + + setWindowTab(QColor(245,245,245)); + setWindowTabSelected(QColor(218,165,3)); + setWindowTabText(QColor(100,100,100)); + setWindowTabTextSelected(QColor(0,0,0)); + + setMenu(QColor(255,255,255)); + setMenuBorder(QColor(220,220,220)); + setMenuText(QColor(0,0,0)); + setMenuHeight(40); + + setToolbarColor(QColor(99,0,0)); + setToolbarTextColor(QColor(255,255,255)); + setToolbarButtonText(QColor(0,0,0)); + setToolbarTextPointSize(10); + } } BtStyle::BtStyle(QObject* parent) @@ -124,7 +216,43 @@ BtStyle::BtStyle(QObject* parent) styles.append(this); } -QColor BtStyle::getButtonColor() const { +QColor BtStyle::getTextColor() { + return textColor; +} +void BtStyle::setTextColor(const QColor& color) { + textColor = color; + emitChanged(); +} + + +QColor BtStyle::getLinkColor() { + return linkColor; +} +void BtStyle::setLinkColor(const QColor& color) { + linkColor = color; + emitChanged(); +} + + +QColor BtStyle::getTextBackgroundColor() { + return textBackgroundColor; +} +void BtStyle::setTextBackgroundColor(const QColor& color) { + textBackgroundColor = color; + emitChanged(); +} + + +QColor BtStyle::getTextBackgroundHighlightColor() { + return textBackgroundHighlightColor; +} +void BtStyle::setTextBackgroundHighlightColor(const QColor& color) { + textBackgroundHighlightColor = color; + emitChanged(); +} + + +QColor BtStyle::getButtonColor() { return buttonColor; } void BtStyle::setButtonColor(const QColor& color) { @@ -133,7 +261,7 @@ void BtStyle::setButtonColor(const QColor& color) { } -QColor BtStyle::getButtonBackground() const { +QColor BtStyle::getButtonBackground() { return buttonBackground; } void BtStyle::setButtonBackground(const QColor& color) { @@ -142,7 +270,7 @@ void BtStyle::setButtonBackground(const QColor& color) { } -QColor BtStyle::getButtonTextColor() const { +QColor BtStyle::getButtonTextColor() { return buttonTextColor; } void BtStyle::setButtonTextColor(const QColor& color) { @@ -151,7 +279,7 @@ void BtStyle::setButtonTextColor(const QColor& color) { } -QColor BtStyle::getButtonHighlightedText() const { +QColor BtStyle::getButtonHighlightedText() { return buttonHighlightedText; } void BtStyle::setButtonHighlightedText(const QColor& color) { @@ -160,7 +288,7 @@ void BtStyle::setButtonHighlightedText(const QColor& color) { } -QColor BtStyle::getButtonBorder() const { +QColor BtStyle::getButtonBorder() { return buttonBorder; } void BtStyle::setButtonBorder(const QColor& color) { @@ -168,7 +296,7 @@ void BtStyle::setButtonBorder(const QColor& color) { emitChanged(); } -int BtStyle::getButtonRadius() const { +int BtStyle::getButtonRadius() { return buttonRadius; } void BtStyle::setButtonRadius(int radius) { @@ -176,7 +304,7 @@ void BtStyle::setButtonRadius(int radius) { emitChanged(); } -QColor BtStyle::getButtonGradient0() const { +QColor BtStyle::getButtonGradient0() { return buttonGradient0; } void BtStyle::setButtonGradient0(const QColor& color) { @@ -184,7 +312,7 @@ void BtStyle::setButtonGradient0(const QColor& color) { emitChanged(); } -QColor BtStyle::getButtonGradient1() const { +QColor BtStyle::getButtonGradient1() { return buttonGradient1; } void BtStyle::setButtonGradient1(const QColor& color) { @@ -192,7 +320,7 @@ void BtStyle::setButtonGradient1(const QColor& color) { emitChanged(); } -QColor BtStyle::getButtonGradient2() const { +QColor BtStyle::getButtonGradient2() { return buttonGradient2; } void BtStyle::setButtonGradient2(const QColor& color) { @@ -200,7 +328,7 @@ void BtStyle::setButtonGradient2(const QColor& color) { emitChanged(); } -QColor BtStyle::getButtonGradient3() const { +QColor BtStyle::getButtonGradient3() { return buttonGradient3; } void BtStyle::setButtonGradient3(const QColor& color) { @@ -208,7 +336,7 @@ void BtStyle::setButtonGradient3(const QColor& color) { emitChanged(); } -QColor BtStyle::getWindowTab() const { +QColor BtStyle::getWindowTab() { return windowTab; } @@ -217,7 +345,7 @@ void BtStyle::setWindowTab(const QColor& color) { emitChanged(); } -QColor BtStyle::getWindowTabSelected() const { +QColor BtStyle::getWindowTabSelected() { return windowTabSelected; } @@ -226,7 +354,7 @@ void BtStyle::setWindowTabSelected(const QColor& color) { emitChanged(); } -QColor BtStyle::getWindowTabText() const { +QColor BtStyle::getWindowTabText() { return windowTabText; } @@ -235,7 +363,7 @@ void BtStyle::setWindowTabText(const QColor& color) { emitChanged(); } -QColor BtStyle::getWindowTabTextSelected() const { +QColor BtStyle::getWindowTabTextSelected() { return windowTabTextSelected; } @@ -244,7 +372,7 @@ void BtStyle::setWindowTabTextSelected(const QColor& color) { emitChanged(); } -QColor BtStyle::getMenu() const { +QColor BtStyle::getMenu() { return menu; } @@ -253,7 +381,7 @@ void BtStyle::setMenu(const QColor& color) { emitChanged(); } -QColor BtStyle::getMenuBorder() const { +QColor BtStyle::getMenuBorder() { return menuBorder; } @@ -262,7 +390,7 @@ void BtStyle::setMenuBorder(const QColor& color) { emitChanged(); } -QColor BtStyle::getMenuText() const { +QColor BtStyle::getMenuText() { return menuText; } @@ -271,7 +399,7 @@ void BtStyle::setMenuText(const QColor& color) { emitChanged(); } -int BtStyle::getMenuHeight() const { +int BtStyle::getMenuHeight() { return menuHeight; } void BtStyle::setMenuHeight(int height) { @@ -279,7 +407,7 @@ void BtStyle::setMenuHeight(int height) { emitChanged(); } -QColor BtStyle::getToolbarColor() const { +QColor BtStyle::getToolbarColor() { return toolbarColor; } void BtStyle::setToolbarColor(const QColor& color) { @@ -287,15 +415,15 @@ void BtStyle::setToolbarColor(const QColor& color) { emitChanged(); } -QColor BtStyle::getToolbarButton() const { - return toolbarButton; +QColor BtStyle::getToolbarTextColor() { + return toolbarTextColor; } -void BtStyle::setToolbarButton(const QColor& color) { - toolbarButton = color; +void BtStyle::setToolbarTextColor(const QColor& color) { + toolbarTextColor = color; emitChanged(); } -QColor BtStyle::getToolbarButtonText() const { +QColor BtStyle::getToolbarButtonText() { return toolbarButtonText; } void BtStyle::setToolbarButtonText(const QColor& color) { @@ -303,7 +431,7 @@ void BtStyle::setToolbarButtonText(const QColor& color) { emitChanged(); } -double BtStyle::getToolbarTextPointSize() const { +double BtStyle::getToolbarTextPointSize() { return toolbarTextPointSize; } @@ -312,22 +440,46 @@ void BtStyle::setToolbarTextPointSize(double pointSize) { emitChanged(); } -double BtStyle::getTextFontPointSize() const { - return btConfig().value<int>("ui/textFontSize",14); +double BtStyle::getUiFontPointSize() { + return btConfig().value<int>("ui/uiFontSize",18); } -void BtStyle::setTextFontPointSize(double pointSize) { - btConfig().setValue<int>("ui/textFontSize", pointSize); +void BtStyle::setUiFontPointSize(double pointSize) { + btConfig().setValue<int>("ui/uiFontSize", pointSize); emitChanged(); } -double BtStyle::getUiFontPointSize() const { - return btConfig().value<int>("ui/uiFontSize",14); +int BtStyle::pixelsPerMillimeterX() { + QScreen* screen = QGuiApplication::screens().at(0); + return screen->physicalDotsPerInchX() / millimeterPerInch; } -void BtStyle::setUiFontPointSize(double pointSize) { - btConfig().setValue<int>("ui/uiFontSize", pointSize); - emitChanged(); +int BtStyle::pixelsPerMillimeterY() { + QScreen* screen = QGuiApplication::screens().at(0); + int dpm = screen->physicalDotsPerInchY() / millimeterPerInch; + return dpm; +} + +QString BtStyle::getAppVersion() { + return "1.09"; +} + +QString BtStyle::getGitVersion() const { +#ifdef BT_GIT_VERSION + return BT_GIT_VERSION; +#else + return ""; +#endif +} + +QString BtStyle::getQtVersion() const { + QString version = qVersion(); + return version; +} + +QString BtStyle::getSwordVersion() const { + QString version(sword::SWVersion::currentVersion.getText()); + return version; } } // end namespace diff --git a/src/mobile/ui/btstyle.h b/src/mobile/ui/btstyle.h index 7f65c22..502a921 100644 --- a/src/mobile/ui/btstyle.h +++ b/src/mobile/ui/btstyle.h @@ -1,3 +1,15 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + #ifndef BT_STYLE_H #define BT_STYLE_H @@ -9,6 +21,11 @@ namespace btm { class BtStyle : public QObject { Q_OBJECT + Q_PROPERTY(QColor textColor READ getTextColor NOTIFY changed) + Q_PROPERTY(QColor linkColor READ getLinkColor NOTIFY changed) + Q_PROPERTY(QColor textBackgroundColor READ getTextBackgroundColor NOTIFY changed) + Q_PROPERTY(QColor textBackgroundHighlightColor READ getTextBackgroundHighlightColor NOTIFY changed) + Q_PROPERTY(QColor buttonColor READ getButtonColor NOTIFY changed) Q_PROPERTY(QColor buttonBackground READ getButtonBackground NOTIFY changed) Q_PROPERTY(QColor buttonTextColor READ getButtonTextColor NOTIFY changed) @@ -33,98 +50,127 @@ class BtStyle : public QObject { 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 toolbarTextColor READ getToolbarTextColor 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); + Q_PROPERTY(double pixelsPerMillimeterX READ pixelsPerMillimeterX NOTIFY changed); + Q_PROPERTY(double pixelsPerMillimeterY READ pixelsPerMillimeterY NOTIFY changed); + + Q_PROPERTY(QString appVersion READ getAppVersion NOTIFY versionChanged); + Q_PROPERTY(QString gitVersion READ getGitVersion NOTIFY versionChanged); + Q_PROPERTY(QString qtVersion READ getQtVersion NOTIFY versionChanged); + Q_PROPERTY(QString swordVersion READ getSwordVersion NOTIFY versionChanged); + + public: Q_INVOKABLE void setStyle(int style); enum Style { - gnome = 1, - android = 2 + darkTheme = 1, + lightBlueTheme = 2, + crimsonTheme = 3 }; + static int getCurrentStyle(); + static void setCurrentStyle(int style); + + BtStyle(QObject *parent = nullptr); + + static QColor getTextColor(); + static void setTextColor(const QColor& color); + + static QColor getLinkColor(); + static void setLinkColor(const QColor& color); + + static QColor getTextBackgroundColor(); + static void setTextBackgroundColor(const QColor& color); + + static QColor getTextBackgroundHighlightColor(); + static void setTextBackgroundHighlightColor(const QColor& color); - BtStyle(QObject *parent = 0); + static QColor getButtonColor(); + static void setButtonColor(const QColor& color); - QColor getButtonColor() const; - void setButtonColor(const QColor& color); + static QColor getButtonBackground(); + static void setButtonBackground(const QColor& color); - QColor getButtonBackground() const; - void setButtonBackground(const QColor& color); + static QColor getButtonTextColor(); + static void setButtonTextColor(const QColor& color); - QColor getButtonTextColor() const; - void setButtonTextColor(const QColor& color); + static QColor getButtonHighlightedText(); + static void setButtonHighlightedText(const QColor& color); - QColor getButtonHighlightedText() const; - void setButtonHighlightedText(const QColor& color); + static QColor getButtonBorder(); + static void setButtonBorder(const QColor& color); - QColor getButtonBorder() const; - void setButtonBorder(const QColor& color); + static int getButtonRadius(); + static void setButtonRadius(int radius); - int getButtonRadius() const; - void setButtonRadius(int radius); + static QColor getButtonGradient0(); + static void setButtonGradient0(const QColor& color); - QColor getButtonGradient0() const; - void setButtonGradient0(const QColor& color); + static QColor getButtonGradient1(); + static void setButtonGradient1(const QColor& color); - QColor getButtonGradient1() const; - void setButtonGradient1(const QColor& color); + static QColor getButtonGradient2(); + static void setButtonGradient2(const QColor& color); - QColor getButtonGradient2() const; - void setButtonGradient2(const QColor& color); + static QColor getButtonGradient3(); + static void setButtonGradient3(const QColor& color); - QColor getButtonGradient3() const; - void setButtonGradient3(const QColor& color); + static QColor getWindowTab(); + static void setWindowTab(const QColor& color); - QColor getWindowTab() const; - void setWindowTab(const QColor& color); + static QColor getWindowTabSelected(); + static void setWindowTabSelected(const QColor& color); - QColor getWindowTabSelected() const; - void setWindowTabSelected(const QColor& color); + static QColor getWindowTabText(); + static void setWindowTabText(const QColor& color); - QColor getWindowTabText() const; - void setWindowTabText(const QColor& color); + static QColor getWindowTabTextSelected(); + static void setWindowTabTextSelected(const QColor& color); - QColor getWindowTabTextSelected() const; - void setWindowTabTextSelected(const QColor& color); + static QColor getMenu(); + static void setMenu(const QColor& color); - QColor getMenu() const; - void setMenu(const QColor& color); + static QColor getMenuBorder(); + static void setMenuBorder(const QColor& color); - QColor getMenuBorder() const; - void setMenuBorder(const QColor& color); + static QColor getMenuText(); + static void setMenuText(const QColor& color); - QColor getMenuText() const; - void setMenuText(const QColor& color); + static int getMenuHeight(); + static void setMenuHeight(int height); - int getMenuHeight() const; - void setMenuHeight(int height); + static QColor getToolbarColor(); + static void setToolbarColor(const QColor& color); - QColor getToolbarColor() const; - void setToolbarColor(const QColor& color); + static QColor getToolbarTextColor(); + static void setToolbarTextColor(const QColor& color); - QColor getToolbarButton() const; - void setToolbarButton(const QColor& color); + static QColor getToolbarButtonText(); + static void setToolbarButtonText(const QColor& color); - QColor getToolbarButtonText() const; - void setToolbarButtonText(const QColor& color); + static double getToolbarTextPointSize(); + static void setToolbarTextPointSize(double pointSize); - double getToolbarTextPointSize() const; - void setToolbarTextPointSize(double pointSize); + static double getUiFontPointSize(); + static void setUiFontPointSize(double pointSize); - double getTextFontPointSize() const; - void setTextFontPointSize(double pointSize); + static int pixelsPerMillimeterX(); + static int pixelsPerMillimeterY(); - double getUiFontPointSize() const; - void setUiFontPointSize(double pointSize); + static QString getAppVersion(); + QString getGitVersion() const; + QString getQtVersion() const; + QString getSwordVersion() const; signals: void changed(); + void versionChanged(); }; } // end namespace diff --git a/src/mobile/ui/btwindowinterface.cpp b/src/mobile/ui/btwindowinterface.cpp index 1016055..00c4af3 100644 --- a/src/mobile/ui/btwindowinterface.cpp +++ b/src/mobile/ui/btwindowinterface.cpp @@ -1,101 +1,154 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ #include "btwindowinterface.h" +#include <QDebug> +#include <QFile> +#include <QObject> +#include <QQmlContext> +#include <QQmlEngine> +#include <QQuickItem> +#include <QStringList> +#include <swkey.h> #include "backend/config/btconfig.h" #include "backend/drivers/cswordbiblemoduleinfo.h" +#include "backend/drivers/cswordbookmoduleinfo.h" +#include "backend/drivers/cswordlexiconmoduleinfo.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/models/btmoduletextmodel.h" #include "backend/rendering/cdisplayrendering.h" +#include "backend/rendering/centrydisplay.h" #include "mobile/btmmain.h" -#include "mobile/keychooser/versechooser.h" #include "mobile/keychooser/bookkeychooser.h" +#include "mobile/keychooser/keynamechooser.h" +#include "mobile/keychooser/versechooser.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> +#include "util/btconnect.h" namespace btm { BtWindowInterface::BtWindowInterface(QObject* parent) : QObject(parent), - m_key(0), + m_key(nullptr), m_textModel(new RoleItemModel()), - m_bookKeyChooser(0), - m_verseKeyChooser(0), - m_bibleTextModelBuilder(m_textModel), - m_bookTextModelBuilder(m_textModel){ - - QtQuick2ApplicationViewer* viewer = getViewManager()->getViewer(); + m_moduleTextModel(new BtModuleTextModel(this)), + m_bookKeyChooser(nullptr), + m_keyNameChooser(nullptr), + m_verseKeyChooser(nullptr), + m_historyIndex(-1) { + + ViewManager* viewManager = getViewManager(); + if (viewManager == nullptr) + return; + QtQuick2ApplicationViewer* viewer = viewManager->getViewer(); m_verseKeyChooser = new VerseChooser(viewer, this); - bool ok = connect(m_verseKeyChooser, SIGNAL(referenceChanged()), this, SLOT(referenceChanged())); - Q_ASSERT(ok); + + BT_CONNECT(m_verseKeyChooser, SIGNAL(referenceChanged()), + this, SLOT(referenceChosen())); m_bookKeyChooser = new BookKeyChooser(viewer, this); - ok = connect(m_bookKeyChooser, SIGNAL(referenceChanged()), this, SLOT(referenceChanged())); - Q_ASSERT(ok); -} + BT_CONNECT(m_bookKeyChooser, SIGNAL(referenceChanged()), + this, SLOT(referenceChosen())); -static QString getKeyText(CSwordKey* key) { - QString keyText; - if ( ! key) - return keyText; + m_keyNameChooser = new KeyNameChooser(viewer, this); + BT_CONNECT(m_keyNameChooser, SIGNAL(referenceChanged(int)), + this, SLOT(referenceChosen(int))); - CSwordVerseKey* verseKey = dynamic_cast<CSwordVerseKey*>(key); - if (verseKey) { - keyText = verseKey->key(); - return keyText; - } + BT_CONNECT(CSwordBackend::instance(), + SIGNAL(sigSwordSetupChanged(CSwordBackend::SetupChangedReason)), + this, + SLOT(reloadModules(CSwordBackend::SetupChangedReason))); +} + +void BtWindowInterface::reloadModules(CSwordBackend::SetupChangedReason /* reason */ ) { + //first make sure all used Sword modules are still present - CSwordTreeKey* treeKey = dynamic_cast<CSwordTreeKey*>(key); - if (treeKey) { - keyText = treeKey->key(); - return keyText; + if (CSwordBackend::instance()->findModuleByName(m_moduleName)) { + QString moduleName = m_moduleName; + m_moduleName = ""; + setModuleName(moduleName); + ; + } else { + // close window ? } - 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); + CSwordBackend::instance()->getConstPointerList(moduleList); +} - emit currentModelIndexChanged(); +static bool moduleIsBook(const CSwordModuleInfo* module) { + CSwordModuleInfo::Category category = module->category(); + if (category == CSwordModuleInfo::Books) + return true; + return false; } -int BtWindowInterface::getCurrentModelIndex() const { - return m_bibleTextModelBuilder.getCurrentModelIndex(); +static bool moduleIsLexicon(const CSwordModuleInfo* module) { + CSwordModuleInfo::Category category = module->category(); + if (category == CSwordModuleInfo::Lexicons || + category == CSwordModuleInfo::DailyDevotional) + return true; + return false; } static bool moduleIsBibleOrCommentary(const CSwordModuleInfo* module) { CSwordModuleInfo::Category category = module->category(); if (category == CSwordModuleInfo::Bibles || + category == CSwordModuleInfo::Cult || 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; +int BtWindowInterface::getCurrentModelIndex() const { + if (m_key == nullptr) + return 0; + if (moduleIsBibleOrCommentary(module())) { + CSwordVerseKey* verseKey = dynamic_cast<CSwordVerseKey*>(m_key); + int index = m_moduleTextModel->verseKeyToIndex(*verseKey); + return index; + } + else if (moduleIsBook(module())) { + const CSwordBookModuleInfo *m = qobject_cast<const CSwordBookModuleInfo*>(module()); + CSwordTreeKey key(m->tree(), m); + QString keyName = m_key->key(); + key.setKey(keyName); + CSwordTreeKey p(key); + p.root(); + if(p != key) + return key.getIndex()/4; + } + else if (moduleIsLexicon(module())){ const CSwordLexiconModuleInfo *li = qobject_cast<const CSwordLexiconModuleInfo*>(m_key->module()); + int index = li->entries().indexOf(m_key->key()); + return index; + } + return 0; +} + +QString BtWindowInterface::getModuleLanguage() const { + QString language; + if (m_key) + language = m_key->module()->language()->englishName(); + return language; } QString BtWindowInterface::getModuleName() const { @@ -105,7 +158,38 @@ QString BtWindowInterface::getModuleName() const { return moduleName; } +void BtWindowInterface::setReference(const QString& key) { + if (m_key && m_key->key() == key) + return; + if (m_key) { + CSwordVerseKey* verseKey = dynamic_cast<CSwordVerseKey*>(m_key); + if (verseKey) + verseKey->setIntros(true); + m_key->setKey(key); + referenceChanged(); + } +} + +void BtWindowInterface::moduleNameChanged(const QString& moduleName) +{ + setModuleName(moduleName); + setHistoryPoint(); +} + +void BtWindowInterface::setModuleToBeginning() { + if (moduleIsBibleOrCommentary(m_key->module())) { + CSwordVerseKey* verseKey = dynamic_cast<CSwordVerseKey*>(m_key); + verseKey->setPosition(sword::TOP); + emit referenceChange(); + } +} + void BtWindowInterface::setModuleName(const QString& moduleName) { + if (m_key && m_moduleName == moduleName) + return; + if (moduleName.isEmpty()) + return; + m_moduleName = moduleName; CSwordModuleInfo* m = CSwordBackend::instance()->findModuleByName(moduleName); if (!m_key) { m_key = CSwordKey::createInstance(m); @@ -131,6 +215,10 @@ void BtWindowInterface::setModuleName(const QString& moduleName) { if (treeKey) treeKey->firstChild(); + QStringList moduleNames; + moduleNames.append(moduleName); + m_moduleTextModel->setModules(moduleNames); + emit moduleChanged(); emit referenceChange(); updateModel(); @@ -149,9 +237,17 @@ void BtWindowInterface::changeModule() { dlg->open(); } +void BtWindowInterface::updateCurrentModelIndex() { + emit currentModelIndexChanged(); +} + +void BtWindowInterface::updateTextFonts() { + emit textChanged(); +} + static void parseKey(CSwordTreeKey* currentKey, QStringList* keyPath, QStringList* children) { - if (currentKey == 0) + if (currentKey == nullptr) return; CSwordTreeKey localKey(*currentKey); @@ -162,7 +258,6 @@ static void parseKey(CSwordTreeKey* currentKey, QStringList* keyPath, QStringLis localKey.firstChild(); oldKey = localKey.key(); } -// const int oldOffset = localKey.getOffset(); //backup key position QStringList siblings; //split up key if (!oldKey.isEmpty()) { @@ -204,24 +299,72 @@ static void parseKey(CSwordTreeKey* currentKey, QStringList* keyPath, QStringLis } } +static QString getEnglishKey(CSwordKey* m_key) { + sword::VerseKey * vk = dynamic_cast<sword::VerseKey*>(m_key); + QString oldLang; + if (vk) { + // Save keys in english only: + const QString oldLang = QString::fromLatin1(vk->getLocale()); + vk->setLocale("en"); + QString englishKey = m_key->key(); + vk->setLocale(oldLang.toLatin1()); + return englishKey; + } else { + return m_key->key(); + } +} + +void BtWindowInterface::saveWindowStateToConfig(int windowIndex) { + const QString windowKey = QString::number(windowIndex); + const QString windowGroup = "window/" + windowKey + '/'; + + BtConfig & conf = btConfig(); + conf.beginGroup(windowGroup); + conf.setSessionValue("key", getEnglishKey(m_key)); + QStringList modules; + QString moduleName = getModuleName(); + modules.append(moduleName); + conf.setSessionValue("modules", modules); + conf.endGroup(); +} + void BtWindowInterface::changeReference() { CSwordVerseKey* verseKey = dynamic_cast<CSwordVerseKey*>(m_key); - if (verseKey != 0) { + if (verseKey != nullptr) { m_verseKeyChooser->open(verseKey); } CSwordTreeKey* treeKey = dynamic_cast<CSwordTreeKey*>(m_key); - if (treeKey != 0) { + if (treeKey != nullptr) { QStringList keyPath; QStringList children; parseKey(treeKey, &keyPath, &children); m_bookKeyChooser->open(); } + CSwordLDKey* lexiconKey = dynamic_cast<CSwordLDKey*>(m_key); + if (lexiconKey != nullptr) { + m_keyNameChooser->open(m_moduleTextModel); + } } void BtWindowInterface::referenceChanged() { emit referenceChange(); +} + +void BtWindowInterface::referenceChosen() { + emit referenceChange(); updateModel(); + emit currentModelIndexChanged(); + setHistoryPoint(); +} + +void BtWindowInterface::referenceChosen(int index) { + updateKeyText(index); + QString keyName = m_moduleTextModel->indexToKeyName(index); + m_key->setKey(keyName); + setReference(keyName); + emit currentModelIndexChanged(); + setHistoryPoint(); } const CSwordModuleInfo* BtWindowInterface::module() const { @@ -233,11 +376,34 @@ CSwordKey* BtWindowInterface::getKey() const { return m_key; } +QString BtWindowInterface::getFontName() const { + const CSwordModuleInfo* m = module(); + if (m == nullptr) + return QString(); + const CLanguageMgr::Language* lang = m->language(); + if (lang == nullptr) + return QString(); + BtConfig::FontSettingsPair fontPair = btConfig().getFontForLanguage(*lang); + if (fontPair.first) { + QFont font = fontPair.second; + QString fontName = font.family(); + return fontName; + } + QFont font = getDefaultFont(); + QString fontName = font.family(); + return fontName; +} + int BtWindowInterface::getFontSize() const { const CLanguageMgr::Language* lang = module()->language(); BtConfig::FontSettingsPair fontPair = btConfig().getFontForLanguage(*lang); - QFont font = fontPair.second; - return font.pointSize(); + if (fontPair.first) { + QFont font = fontPair.second; + int fontPointSize = font.pointSize(); + return fontPointSize; + } + int fontPointSize = btConfig().value<int>("ui/textFontSize",22); + return fontPointSize; } void BtWindowInterface::setFontSize(int size) { @@ -250,8 +416,63 @@ void BtWindowInterface::setFontSize(int size) { QVariant BtWindowInterface::getTextModel() { QVariant var; - var.setValue(m_textModel); + var.setValue(m_moduleTextModel); return var; } +void BtWindowInterface::updateKeyText(int index) { + QString keyName = m_moduleTextModel->indexToKeyName(index); + setReference(keyName); +} + +QString BtWindowInterface::getHighlightWords() const { + return m_highlightWords; +} + +void BtWindowInterface::setHighlightWords(const QString& words) { + m_highlightWords = words; + m_moduleTextModel->setHighlightWords(words); +} + +void BtWindowInterface::setHistoryPoint() { + History history; + while ( m_history.count()>0 && (m_historyIndex<m_history.count()-1) ) + m_history.pop_back(); + history.moduleName = getModuleName(); + history.reference = getReference(); + m_history.append(history); + m_historyIndex = m_history.count() - 1; + emit historyChanged(); +} + +bool BtWindowInterface::getHistoryForwardVisible() const { + return m_historyIndex < (m_history.count() - 1); +} + +bool BtWindowInterface::getHistoryBackwardVisible() const { + return (m_historyIndex > 0) && (m_history.count() > 1); +} + +void BtWindowInterface::moveHistoryBackward() { + if ( ! getHistoryBackwardVisible()) + return; + m_historyIndex--; + History history = m_history.at(m_historyIndex); + setModuleName(history.moduleName); + setReference(history.reference); + emit currentModelIndexChanged(); + emit historyChanged(); +} + +void BtWindowInterface::moveHistoryForward() { + if ( ! getHistoryForwardVisible()) + return; + m_historyIndex++; + History history = m_history.at(m_historyIndex); + setModuleName(history.moduleName); + setReference(history.reference); + emit currentModelIndexChanged(); + emit historyChanged(); +} + } // end namespace diff --git a/src/mobile/ui/btwindowinterface.h b/src/mobile/ui/btwindowinterface.h index c6c31b0..a94c2c4 100644 --- a/src/mobile/ui/btwindowinterface.h +++ b/src/mobile/ui/btwindowinterface.h @@ -1,60 +1,102 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + #ifndef BT_WINDOW_INTERFACE_H #define BT_WINDOW_INTERFACE_H +#include <QList> #include <QObject> #include <QString> +#include "backend/managers/cswordbackend.h" #include "mobile/models/roleitemmodel.h" -#include "mobile/models/bibletextmodelbuilder.h" -#include "mobile/models/booktextmodelbuilder.h" class CSwordKey; class CSwordVerseKey; class CSwordModuleInfo; +class BtModuleTextModel; namespace btm { class BookKeyChooser; +class KeyNameChooser; class VerseChooser; +struct History +{ + QString moduleName; + QString reference; +}; + 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) + Q_PROPERTY(int currentModelIndex READ getCurrentModelIndex NOTIFY currentModelIndexChanged) + Q_PROPERTY(int fontSize READ getFontSize WRITE setFontSize NOTIFY textChanged) + Q_PROPERTY(QString fontName READ getFontName NOTIFY textChanged) + Q_PROPERTY(QString highlightWords READ getHighlightWords WRITE setHighlightWords) + Q_PROPERTY(QString moduleLanguage READ getModuleLanguage) + Q_PROPERTY(QString moduleName READ getModuleName WRITE setModuleName NOTIFY moduleChanged) + Q_PROPERTY(QString reference READ getReference WRITE setReference NOTIFY referenceChange) + Q_PROPERTY(QVariant textModel READ getTextModel NOTIFY textModelChanged) + Q_PROPERTY(bool historyBackwardVisible READ getHistoryBackwardVisible NOTIFY historyChanged) + Q_PROPERTY(bool historyForwardVisible READ getHistoryForwardVisible NOTIFY historyChanged) public: Q_INVOKABLE void changeModule(); Q_INVOKABLE void changeReference(); + Q_INVOKABLE void saveWindowStateToConfig(int windowIndex); + Q_INVOKABLE void updateCurrentModelIndex(); + Q_INVOKABLE void updateTextFonts(); + Q_INVOKABLE void updateKeyText(int modelIndex); + Q_INVOKABLE void moveHistoryBackward(); + Q_INVOKABLE void moveHistoryForward(); + Q_INVOKABLE void setHistoryPoint(); + Q_INVOKABLE void setModuleToBeginning(); - BtWindowInterface(QObject *parent = 0); + BtWindowInterface(QObject *parent = nullptr); + int getCurrentModelIndex() const; + int getFontSize() const; + QString getFontName() const; + QString getHighlightWords() const; CSwordKey* getKey() const; - + QString getModuleLanguage() const; QString getModuleName() const; - void setModuleName(const QString& moduleName); - QString getReference() const; + QVariant getTextModel(); - int getCurrentModelIndex() const; - - int getFontSize() const; + void moduleNameChanged(const QString& moduleName); void setFontSize(int size); + void setHighlightWords(const QString& words); + void setModuleName(const QString& moduleName); + void setReference(const QString& key); - QVariant getTextModel(); + bool getHistoryBackwardVisible() const; + bool getHistoryForwardVisible() const; signals: - void referenceChange(); + void currentModelIndexChanged(); + void historyChanged(); void moduleChanged(); + void referenceChange(); void textChanged(); void textModelChanged(); - void currentModelIndexChanged(); private slots: void referenceChanged(); + void referenceChosen(); + void referenceChosen(int index); + void reloadModules(CSwordBackend::SetupChangedReason reason); private: const CSwordModuleInfo* module() const; @@ -62,10 +104,15 @@ private: CSwordKey* m_key; RoleItemModel* m_textModel; + BtModuleTextModel* m_moduleTextModel; BookKeyChooser* m_bookKeyChooser; + KeyNameChooser* m_keyNameChooser; VerseChooser* m_verseKeyChooser; - BibleTextModelBuilder m_bibleTextModelBuilder; - BookTextModelBuilder m_bookTextModelBuilder; + QString m_highlightWords; + QString m_moduleName; + QList<History> m_history; + int m_historyIndex; + }; } // end namespace diff --git a/src/mobile/ui/gridchooser.cpp b/src/mobile/ui/gridchooser.cpp index 3836b18..86c9cd2 100644 --- a/src/mobile/ui/gridchooser.cpp +++ b/src/mobile/ui/gridchooser.cpp @@ -1,8 +1,17 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ #include "gridchooser.h" -#include "qtquick2applicationviewer.h" - #include <algorithm> #include <cmath> #include <QEventLoop> @@ -10,14 +19,18 @@ #include <QQmlContext> #include <QDebug> #include <QCoreApplication> +#include "qtquick2applicationviewer.h" +#include "util/btassert.h" +#include "util/btconnect.h" + namespace btm { GridChooser::GridChooser(QtQuick2ApplicationViewer* viewer) : viewer_(viewer), - gridChooserObject_(0) { + gridChooserObject_(nullptr) { QQuickItem * rootObject = viewer_->rootObject(); - if (rootObject != 0) + if (rootObject != nullptr) gridChooserObject_ = rootObject->findChild<QQuickItem*>("gridChooser"); } @@ -25,14 +38,13 @@ GridChooser::~GridChooser() { } void GridChooser::open(const QStringList& stringList, const QString& highlight, const QString& title) { - Q_ASSERT(gridChooserObject_ != 0); - if (gridChooserObject_ == 0) + BT_ASSERT(gridChooserObject_); + if (gridChooserObject_ == nullptr) return; gridChooserObject_->disconnect(); - bool ok = connect(gridChooserObject_, SIGNAL(accepted(QString)), - this, SLOT(gridChooserAccepted(QString))); - Q_ASSERT(ok); + BT_CONNECT(gridChooserObject_, SIGNAL(accepted(QString)), + this, SLOT(gridChooserAccepted(QString))); setProperties(stringList, highlight, title); } diff --git a/src/mobile/ui/gridchooser.h b/src/mobile/ui/gridchooser.h index 8200f91..ffb2be6 100644 --- a/src/mobile/ui/gridchooser.h +++ b/src/mobile/ui/gridchooser.h @@ -1,3 +1,15 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + #ifndef GRID_CHOOSER_H #define GRID_CHOOSER_H diff --git a/src/mobile/ui/indexthread.cpp b/src/mobile/ui/indexthread.cpp new file mode 100644 index 0000000..bbe1b1e --- /dev/null +++ b/src/mobile/ui/indexthread.cpp @@ -0,0 +1,74 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#include "indexthread.h" + +#include <QDebug> +#include <QString> +#include <QThread> +#include "backend/btinstallbackend.h" +#include "backend/managers/cswordbackend.h" +#include "util/btconnect.h" + +// Sword includes: +#include <filemgr.h> + + +IndexThread::IndexThread(const QList<CSwordModuleInfo*>& modules, QObject* const parent) + : QThread(parent) + , m_modules(modules), + m_currentModuleIndex(0), + m_stopRequested(false) { +} + +void IndexThread::run() { + m_stopRequestedMutex.lock(); + try { + for (m_currentModuleIndex = 0; + !m_stopRequested && (m_currentModuleIndex < m_modules.size()); + m_currentModuleIndex++) + { + m_stopRequestedMutex.unlock(); + indexModule(); + m_stopRequestedMutex.lock(); + } + emit indexingFinished(); + } catch (...) { + m_stopRequestedMutex.unlock(); + throw; + } + m_stopRequestedMutex.unlock(); +} + +void IndexThread::stopIndex() { + const QMutexLocker lock(&m_stopRequestedMutex); + m_stopRequested = true; + CSwordModuleInfo* module = m_modules.at(m_currentModuleIndex); + module->cancelIndexing(); +} + +void IndexThread::indexModule() { + CSwordModuleInfo* module = m_modules.at(m_currentModuleIndex); + QString moduleName = module->name(); + emit beginIndexingModule(moduleName); + BT_CONNECT(module, SIGNAL(indexingProgress(int)), + this, SLOT(slotModuleProgress(int))); + bool success = true; + try { + module->buildIndex(); + } + catch (...) { + success = false; + } + emit endIndexingModule(moduleName, success); +} + +void IndexThread::slotModuleProgress(int percentComplete) { + emit indexingProgress(percentComplete); +} diff --git a/src/mobile/ui/indexthread.h b/src/mobile/ui/indexthread.h new file mode 100644 index 0000000..3382eab --- /dev/null +++ b/src/mobile/ui/indexthread.h @@ -0,0 +1,51 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef INDEX_THREAD_H +#define INDEX_THREAD_H + +#include <QList> +#include <QMutex> +#include <QThread> + +class CSwordModuleInfo; + +class IndexThread: public QThread { + + Q_OBJECT + + public: + explicit IndexThread(const QList<CSwordModuleInfo*>& modules, QObject* const parent = nullptr); + void stopIndex(); + + signals: + void indexingProgress(int progressPercent); + void indexingFinished(); + void beginIndexingModule(const QString& moduleName); + void endIndexingModule(const QString& moduleName, bool success); + + protected: + void run() override; + + private: + void indexModule(); + + private slots: + void slotModuleProgress(int percentComplete); + + private: + QList<CSwordModuleInfo*> m_modules; + int m_currentModuleIndex; + bool m_stopRequested; + QMutex m_stopRequestedMutex; +}; + +#endif diff --git a/src/mobile/ui/modulechooser.cpp b/src/mobile/ui/modulechooser.cpp index bc3d582..fad2f02 100644 --- a/src/mobile/ui/modulechooser.cpp +++ b/src/mobile/ui/modulechooser.cpp @@ -1,44 +1,58 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ #include "modulechooser.h" -#include "qtquick2applicationviewer.h" - -#include "backend/bookshelfmodel/btbookshelftreemodel.h" -#include "backend/managers/cswordbackend.h" #include <cmath> #include <QQuickItem> #include <QQmlProperty> +#include "backend/bookshelfmodel/btbookshelftreemodel.h" +#include "backend/managers/cswordbackend.h" #include "btwindowinterface.h" #include "mobile/util/findqmlobject.h" +#include "qtquick2applicationviewer.h" +#include "util/btassert.h" +#include "util/btconnect.h" + namespace btm { -ModuleChooser::ModuleChooser(QtQuick2ApplicationViewer* viewer, BtWindowInterface* bibleVerse) +ModuleChooser::ModuleChooser(QtQuick2ApplicationViewer* viewer, BtWindowInterface* windowInterface) : viewer_(viewer), - bibleVerse_(bibleVerse) { + windowInterface_(windowInterface) { } void ModuleChooser::open() { QQuickItem* item = findQmlObject("moduleChooser"); - Q_ASSERT(item != 0); - if (item == 0) + BT_ASSERT(item); + if (item == nullptr) return; item->setProperty("visible", true); - bool ok = connect(item, SIGNAL(moduleSelected()), this, SLOT(moduleSelectedSlot())); - Q_ASSERT(ok); + disconnect(item, SIGNAL(moduleSelected()), nullptr, nullptr); + BT_CONNECT(item, SIGNAL(moduleSelected()), + this, SLOT(moduleSelectedSlot())); } void ModuleChooser::moduleSelectedSlot() { QQuickItem* item = findQmlObject("moduleChooser"); - Q_ASSERT(item != 0); - if (item == 0) + BT_ASSERT(item); + if (item == nullptr) return; item->setProperty("visible", false); QVariant v = item->property("selectedModule"); QString moduleName = v.toString(); - bibleVerse_->setModuleName(moduleName); + windowInterface_->moduleNameChanged(moduleName); } } // end namespace diff --git a/src/mobile/ui/modulechooser.h b/src/mobile/ui/modulechooser.h index 4e261f9..297bbba 100644 --- a/src/mobile/ui/modulechooser.h +++ b/src/mobile/ui/modulechooser.h @@ -1,3 +1,15 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + #ifndef MODULE_CHOOSER_H #define MODULE_CHOOSER_H @@ -27,7 +39,7 @@ private: void setProperties(const QStringList& list); QtQuick2ApplicationViewer* viewer_; - BtWindowInterface* bibleVerse_; + BtWindowInterface* windowInterface_; }; } // end namespace diff --git a/src/mobile/ui/moduleinterface.cpp b/src/mobile/ui/moduleinterface.cpp index 4d898b4..31f3637 100644 --- a/src/mobile/ui/moduleinterface.cpp +++ b/src/mobile/ui/moduleinterface.cpp @@ -1,11 +1,25 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ #include "moduleinterface.h" #include "qtquick2applicationviewer.h" +#include "backend/config/btconfig.h" #include "backend/bookshelfmodel/btbookshelftreemodel.h" #include "backend/managers/cswordbackend.h" +#include "backend/keys/cswordversekey.h" #include "mobile/util/findqmlobject.h" +#include "mobile/btmmain.h" #include <cmath> #include <QQuickItem> #include <QQmlProperty> @@ -18,6 +32,14 @@ namespace btm { +struct FontSettings { + QString language; + QString fontName; + qreal fontSize; +}; + +static QList<FontSettings> savedFontSettings; + ModuleInterface::ModuleInterface() { } @@ -25,7 +47,7 @@ enum TextRoles { TextRole = Qt::UserRole + 1 }; -typedef BtBookshelfModel::ModuleRole MRole; +using MRole = BtBookshelfModel::ModuleRole; static const MRole HR(BtBookshelfModel::ModuleHiddenRole); static const MRole PR(BtBookshelfModel::ModulePointerRole); static const MRole IR(BtBookshelfModel::ModuleHasIndexRole); @@ -57,12 +79,13 @@ static CSwordModuleInfo* getModule(BtBookshelfModel* bookshelfModel, const QMode void ModuleInterface::updateCategoryAndLanguageModels() { QQuickItem* object = findQmlObject("moduleChooser"); - if (object == 0) + if (object == nullptr) return; getCategoriesAndLanguages(); setupTextModel(m_categories, &m_categoryModel); setupTextModel(m_languages, &m_languageModel); + updateWorksModel(); object->setProperty("categoryModel", QVariant::fromValue(&m_categoryModel)); object->setProperty("languageModel", QVariant::fromValue(&m_languageModel)); } @@ -73,11 +96,11 @@ void ModuleInterface::getCategoriesAndLanguages() { m_languages.clear(); QQuickItem* object = findQmlObject("moduleChooser"); - if (object == 0) + if (object == nullptr) return; BtBookshelfModel* bookshelfModel = CSwordBackend::instance()->model(); - if (bookshelfModel == 0) + if (bookshelfModel == nullptr) return; int count = bookshelfModel->rowCount(); for (int row=0; row<count; ++row) { @@ -92,6 +115,16 @@ void ModuleInterface::getCategoriesAndLanguages() { } } +QStringList ModuleInterface::installedModuleLanguages() { + QStringList languages; + CLanguageMgr::LangMap langMap = CLanguageMgr::instance()->availableLanguages(); + for (auto lang: langMap) { + languages << lang->englishName(); + } + return languages; +} + + void ModuleInterface::updateWorksModel() { m_worksModel.clear(); m_modules.clear(); @@ -104,7 +137,7 @@ void ModuleInterface::updateWorksModel() { m_worksModel.setRoleNames(roleNames); BtBookshelfModel* bookshelfModel = CSwordBackend::instance()->model(); - if (bookshelfModel == 0) + if (bookshelfModel == nullptr) return; int count = bookshelfModel->rowCount(); for (int row=0; row<count; ++row) { @@ -125,14 +158,14 @@ void ModuleInterface::updateWorksModel() { } QQuickItem* object = findQmlObject("moduleChooser"); - if (object == 0) + if (object == nullptr) return; object->setProperty("worksModel", QVariant::fromValue(&m_worksModel)); } QString ModuleInterface::currentLanguage() const { QQuickItem* object = findQmlObject("moduleChooser"); - if (object == 0) + if (object == nullptr) return ""; int row = object->property("languageIndex").toInt(); QModelIndex modelIndex = m_languageModel.index(row,0); @@ -143,7 +176,7 @@ QString ModuleInterface::currentLanguage() const { QString ModuleInterface::currentCategory() const { QQuickItem* object = findQmlObject("moduleChooser"); - if (object == 0) + if (object == nullptr) return ""; int row = object->property("categoryIndex").toInt(); QModelIndex modelIndex = m_categoryModel.index(row,0); @@ -155,7 +188,7 @@ QString ModuleInterface::category(int index) { if (index < 0 || index >= m_modules.count()) return ""; CSwordModuleInfo* module = m_modules.at(index); - if (module == 0) + if (module == nullptr) return ""; CSwordModuleInfo::Category category = module->category(); if (category == 0) @@ -163,14 +196,26 @@ QString ModuleInterface::category(int index) { return module->categoryName(category); } +QString ModuleInterface::englishCategory(int index) { + if (index < 0 || index >= m_modules.count()) + return ""; + CSwordModuleInfo* module = m_modules.at(index); + if (module == nullptr) + return ""; + CSwordModuleInfo::Category category = module->category(); + if (category == 0) + return ""; + return module->englishCategoryName(category); +} + QString ModuleInterface::language(int index) { if (index < 0 || index >= m_modules.count()) return ""; CSwordModuleInfo* module = m_modules.at(index); - if (module == 0) + if (module == nullptr) return ""; const CLanguageMgr::Language* language = module->language(); - if (language == 0) + if (language == nullptr) return ""; return language->translatedName(); } @@ -179,9 +224,115 @@ QString ModuleInterface::module(int index) { if (index < 0 || index >= m_modules.count()) return ""; CSwordModuleInfo* module = m_modules.at(index); - if (module == 0) + if (module == nullptr) return ""; return module->name(); } +bool ModuleInterface::isLocked(const QString& moduleName) { + CSwordModuleInfo* module = CSwordBackend::instance()->findModuleByName(moduleName); + if (module) { + + // Verse intros must be false for checking lock + if (module->type() == CSwordModuleInfo::Bible || + module->type() == CSwordModuleInfo::Commentary) { + ((sword::VerseKey*)(module->module().getKey()))->setIntros(false); + } + + bool locked = module->isLocked(); + return locked; + } + return false; +} + +void ModuleInterface::unlock(const QString& moduleName, const QString& unlockKey) { + CSwordModuleInfo* module = CSwordBackend::instance()->findModuleByName(moduleName); + if (module) { + module->unlock(unlockKey); + + // Re-initialize module pointers: + CSwordBackend *backend = CSwordBackend::instance(); + backend->reloadModules(CSwordBackend::OtherChange); + module = CSwordBackend::instance()->findModuleByName(moduleName); + updateWorksModel(); + } +} + +static const CLanguageMgr::Language* getLanguageFromEnglishName(const QString& name) { + CLanguageMgr::LangMap langMap = CLanguageMgr::instance()->availableLanguages(); + for (auto l: langMap) { + if (l->englishName() == name) + return l; + } + return nullptr; + } + +QString ModuleInterface::getFontNameForLanguage(const QString& language) +{ + auto lang = getLanguageFromEnglishName(language); + if (lang) { + BtConfig::FontSettingsPair fontPair = btConfig().getFontForLanguage(*lang); + if (fontPair.first) { + QFont font = fontPair.second; + QString fontFamily = font.family(); + return fontFamily; + } + } + QString fontFamily = getDefaultFont().family(); + return fontFamily; +} + +qreal ModuleInterface::getFontSizeForLanguage(const QString& language) +{ + auto lang = getLanguageFromEnglishName(language); + if (lang) { + BtConfig::FontSettingsPair fontPair = btConfig().getFontForLanguage(*lang); + if (fontPair.first) { + QFont font = fontPair.second; + int fontPointSize = font.pointSize(); + return fontPointSize; + } + } + qreal pointSize = getDefaultFont().pointSizeF(); + return pointSize; +} + +void ModuleInterface::setFontForLanguage(const QString& language, const QString& fontName, qreal fontSize) { + if (CLanguageMgr::instance() == nullptr) + return; + auto lang = getLanguageFromEnglishName(language); + if (lang) { + + QFont font; + font.setFamily(fontName); + font.setPointSizeF(fontSize); + BtConfig::FontSettingsPair fontPair; + fontPair.first = true; + fontPair.second = font; + btConfig().setFontForLanguage(*lang, fontPair); + } +} + +void ModuleInterface::saveCurrentFonts() { + savedFontSettings.clear(); + CLanguageMgr::LangMap langMap = CLanguageMgr::instance()->availableLanguages(); + for (auto lang: langMap) { + BtConfig::FontSettingsPair fontPair = btConfig().getFontForLanguage(*lang); + if (fontPair.first) { + FontSettings fontSettings; + QFont font = fontPair.second; + fontSettings.language = lang->englishName(); + fontSettings.fontName = font.family(); + fontSettings.fontSize = font.pointSize(); + savedFontSettings.append(fontSettings); + } + } +} + +void ModuleInterface::restoreSavedFonts() { + for (auto fontSettings : savedFontSettings) { + setFontForLanguage(fontSettings.language, fontSettings.fontName, fontSettings.fontSize); + } +} + } // end namespace diff --git a/src/mobile/ui/moduleinterface.h b/src/mobile/ui/moduleinterface.h index 165c30f..c2c714f 100644 --- a/src/mobile/ui/moduleinterface.h +++ b/src/mobile/ui/moduleinterface.h @@ -1,3 +1,15 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + #ifndef MODULE_INTERFACE_H #define MODULE_INTERFACE_H @@ -25,8 +37,17 @@ public: Q_INVOKABLE void updateCategoryAndLanguageModels(); Q_INVOKABLE void updateWorksModel(); Q_INVOKABLE QString category(int index); + Q_INVOKABLE QString englishCategory(int index); Q_INVOKABLE QString language(int index); Q_INVOKABLE QString module(int index); + Q_INVOKABLE bool isLocked(const QString& moduleName); + Q_INVOKABLE void unlock(const QString& moduleName, const QString& unlockKey); + Q_INVOKABLE QStringList installedModuleLanguages(); + Q_INVOKABLE QString getFontNameForLanguage(const QString& language); + Q_INVOKABLE qreal getFontSizeForLanguage(const QString& language); + Q_INVOKABLE void setFontForLanguage(const QString& language, const QString& fontName, qreal fontSize); + Q_INVOKABLE void saveCurrentFonts(); + Q_INVOKABLE void restoreSavedFonts(); private: void getCategoriesAndLanguages(); diff --git a/src/mobile/ui/qtquick2applicationviewer.cpp b/src/mobile/ui/qtquick2applicationviewer.cpp index b6077d8..7f30a6c 100644 --- a/src/mobile/ui/qtquick2applicationviewer.cpp +++ b/src/mobile/ui/qtquick2applicationviewer.cpp @@ -1,3 +1,15 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + // checksum 0x56a9 version 0x80001 /* This file was generated by the Qt Quick 2 Application wizard of Qt Creator. @@ -13,6 +25,7 @@ #include <QtCore/QCoreApplication> #include <QtCore/QDir> #include <QtQml/QQmlEngine> +#include "util/btconnect.h" class QtQuick2ApplicationViewerPrivate { QString mainQmlFile; @@ -37,7 +50,7 @@ QString QtQuick2ApplicationViewerPrivate::adjustPath(const QString &path) { QtQuick2ApplicationViewer::QtQuick2ApplicationViewer(QWindow *parent) : QQuickView(parent) , d(new QtQuick2ApplicationViewerPrivate()) { - connect(engine(), SIGNAL(quit()), SLOT(close())); + BT_CONNECT(engine(), SIGNAL(quit()), SLOT(close())); setResizeMode(QQuickView::SizeRootObjectToView); } @@ -47,7 +60,11 @@ QtQuick2ApplicationViewer::~QtQuick2ApplicationViewer() { void QtQuick2ApplicationViewer::setMainQmlFile(const QString &file) { d->mainQmlFile = QtQuick2ApplicationViewerPrivate::adjustPath(file); - setSource(QUrl::fromLocalFile(d->mainQmlFile)); + + if(d->mainQmlFile[0] == ':') + setSource(QUrl("qrc:/" + d->mainQmlFile.mid(1))); // QUrl can not be constructed correctly from :share/... + else + setSource(QUrl::fromLocalFile(d->mainQmlFile)); } void QtQuick2ApplicationViewer::addImportPath(const QString &path) { diff --git a/src/mobile/ui/qtquick2applicationviewer.h b/src/mobile/ui/qtquick2applicationviewer.h index a3db59d..98194e1 100644 --- a/src/mobile/ui/qtquick2applicationviewer.h +++ b/src/mobile/ui/qtquick2applicationviewer.h @@ -1,3 +1,15 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + // checksum 0xfde6 version 0x80001 /* This file was generated by the Qt Quick 2 Application wizard of Qt Creator. @@ -17,7 +29,7 @@ class QtQuick2ApplicationViewer : public QQuickView { Q_OBJECT public: - explicit QtQuick2ApplicationViewer(QWindow *parent = 0); + explicit QtQuick2ApplicationViewer(QWindow *parent = nullptr); virtual ~QtQuick2ApplicationViewer(); void setMainQmlFile(const QString &file); diff --git a/src/mobile/ui/treechoosermodel.cpp b/src/mobile/ui/treechoosermodel.cpp index cc5e2a7..1465832 100644 --- a/src/mobile/ui/treechoosermodel.cpp +++ b/src/mobile/ui/treechoosermodel.cpp @@ -1,3 +1,14 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ #include "treechoosermodel.h" @@ -14,9 +25,3 @@ QHash<int, QByteArray> TreeChooserModel::roleNames() const { 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 index c1575ae..6ae670c 100644 --- a/src/mobile/ui/treechoosermodel.h +++ b/src/mobile/ui/treechoosermodel.h @@ -1,3 +1,15 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + #ifndef TREE_CHOOSER_MODEL_H #define TREE_CHOOSER_MODEL_H @@ -13,7 +25,7 @@ public: }; TreeChooserModel(QObject *parent = 0); - QHash<int, QByteArray> TreeChooserModel::roleNames() const; + QHash<int, QByteArray> roleNames() const; }; diff --git a/src/mobile/ui/viewmanager.cpp b/src/mobile/ui/viewmanager.cpp index 041699a..a1ae7c0 100644 --- a/src/mobile/ui/viewmanager.cpp +++ b/src/mobile/ui/viewmanager.cpp @@ -1,9 +1,21 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ #include "viewmanager.h" #include "qtquick2applicationviewer.h" #include "btstyle.h" +#include "util/directory.h" #include <cmath> #include <QGuiApplication> #include <QJsonValue> @@ -15,17 +27,10 @@ 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); + style.setStyle(BtStyle::darkTheme); initialize_string_list_chooser_model(); initialize_main_qml(); } @@ -37,8 +42,7 @@ void ViewManager::initialize_string_list_chooser_model() { } void ViewManager::initialize_main_qml() { - QString mainQml = qmlFilePath("qml", "main.qml"); - viewer_->setMainQmlFile(mainQml); + viewer_->setMainQmlFile(util::directory::getQmlDir().filePath("main.qml")); } void ViewManager::show() { diff --git a/src/mobile/ui/viewmanager.h b/src/mobile/ui/viewmanager.h index 7c50d35..4d94526 100644 --- a/src/mobile/ui/viewmanager.h +++ b/src/mobile/ui/viewmanager.h @@ -1,3 +1,15 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + #ifndef VIEW_MANAGER_H #define VIEW_MANAGER_H diff --git a/src/mobile/util/findqmlobject.cpp b/src/mobile/util/findqmlobject.cpp index 25a317c..c1a08f7 100644 --- a/src/mobile/util/findqmlobject.cpp +++ b/src/mobile/util/findqmlobject.cpp @@ -4,30 +4,32 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 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 "findqmlobject.h" + #include <QQuickItem> #include "mobile/btmmain.h" #include "mobile/ui/qtquick2applicationviewer.h" #include "mobile/ui/viewmanager.h" +#include "util/btassert.h" namespace btm { QQuickItem* findQmlObject(const QString& objectName) { QtQuick2ApplicationViewer* viewer = getViewManager()->getViewer(); - QQuickItem * rootObject = 0; - if (viewer != 0) + QQuickItem * rootObject = nullptr; + if (viewer != nullptr) rootObject = viewer->rootObject(); - QQuickItem* object = 0; - if (rootObject != 0) + QQuickItem* object = nullptr; + if (rootObject != nullptr) object = rootObject->findChild<QQuickItem*>(objectName); - Q_ASSERT(object != 0); + BT_ASSERT(object); return object; } diff --git a/src/mobile/util/findqmlobject.h b/src/mobile/util/findqmlobject.h index bfbbcac..977629b 100644 --- a/src/mobile/util/findqmlobject.h +++ b/src/mobile/util/findqmlobject.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * diff --git a/src/mobile/util/messagedialog.cpp b/src/mobile/util/messagedialog.cpp index a68857a..c0fd34b 100644 --- a/src/mobile/util/messagedialog.cpp +++ b/src/mobile/util/messagedialog.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -24,6 +24,15 @@ int showWarning(QWidget * /*parent*/, return 0; } +int showCritical(QWidget * /*parent*/, + const QString & /*title*/, + const QString & /*text*/, + QMessageBox::StandardButtons /*buttons*/, + QMessageBox::StandardButton /*defaultButton*/) { + // TODO - implement showCritical + return 0; +} + int showQuestion(QWidget * /*parent*/, const QString & /*title*/, const QString & /*text*/, diff --git a/src/mobile/util/messagedialog.h b/src/mobile/util/messagedialog.h index d56b9ea..e9fb503 100644 --- a/src/mobile/util/messagedialog.h +++ b/src/mobile/util/messagedialog.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -25,6 +25,12 @@ int showWarning(QWidget * parent, QMessageBox::StandardButtons buttons = QMessageBox::Ok, QMessageBox::StandardButton defaultButton = QMessageBox::NoButton); +int showCritical(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, diff --git a/src/util/btassert.h b/src/util/btassert.h new file mode 100644 index 0000000..e154cb4 --- /dev/null +++ b/src/util/btassert.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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef BTASSERT_H +#define BTASSERT_H + +#if !defined(QT_NO_DEBUG) && !defined(NDEBUG) +#include <QtGlobal> +#define BT_ASSERT(...) ([&]{ Q_ASSERT(__VA_ARGS__); }()) +#else +#include <cassert> +#define BT_ASSERT(...) assert(__VA_ARGS__) +#endif + +#endif /* BTASSERT_H */ diff --git a/src/util/btconnect.h b/src/util/btconnect.h new file mode 100644 index 0000000..76ceab3 --- /dev/null +++ b/src/util/btconnect.h @@ -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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef BTCONNECT_H +#define BTCONNECT_H + +#include <QObject> +#include "btassert.h" +#include "btwrap.h" + + +#ifndef NDEBUG +#define BT_CONNECT_WITH(with, ...) \ + do { \ + bool const ok = with connect(__VA_ARGS__); \ + BT_ASSERT(ok); \ + } while (false) +#define BT_CONNECT(...) BT_CONNECT_WITH(, BT_WRAP(__VA_ARGS__)) +#define BT_CONNECT_QOBJECT(...) BT_CONNECT_WITH(QObject::,BT_WRAP(__VA_ARGS__)) +#else +#define BT_CONNECT_WITH(with, ...) with connect(__VA_ARGS__) +#define BT_CONNECT(...) connect(__VA_ARGS__) +#define BT_CONNECT_QOBJECT(...) QObject::connect(__VA_ARGS__) +#endif + +#endif /* BTCONNECT_H */ diff --git a/src/util/bticons.cpp b/src/util/bticons.cpp new file mode 100644 index 0000000..9b55377 --- /dev/null +++ b/src/util/bticons.cpp @@ -0,0 +1,187 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#include "bticons.h" + +#include <QByteArray> +#include <QBuffer> +#include <QPixmap> +#include <QDebug> +#include <QIconEngine> +#include <QPainter> +#include "directory.h" + + +namespace { + +class BtOverlayIconEngine: public QIconEngine { + +public: /* Methods: */ + + BtOverlayIconEngine(QIcon const & icon, QIcon const & overlay) + : m_icon(icon) + , m_overlayIcon(overlay) + {} + + QIconEngine * clone() const override + { return new BtOverlayIconEngine(m_icon, m_overlayIcon); } + + void paint(QPainter * painter, + QRect const & rect, + QIcon::Mode mode, + QIcon::State state) override + { + { + QBrush brush(painter->background()); + brush.setColor(Qt::transparent); + painter->setBackground(brush); + } + painter->eraseRect(rect); + painter->setCompositionMode(QPainter::CompositionMode_SourceOver); + m_icon.paint(painter, rect, Qt::AlignCenter, mode, state); + m_overlayIcon.paint(painter, + rect.adjusted(0.4 * rect.width(), + 0.4 * rect.height(), + 0, + 0), + Qt::AlignCenter, + mode, + state); + } + + QPixmap pixmap(QSize const & size, + QIcon::Mode mode, + QIcon::State state) override + { + QImage img(size, QImage::Format_ARGB32); + img.fill(qRgba(0,0,0,0)); + QPixmap pix = QPixmap::fromImage(img, Qt::NoFormatConversion); + QPainter painter(&pix); + this->paint(&painter, QRect(QPoint(0, 0), size), mode, state); + return pix; + } + +private: /* Fields: */ + + QIcon const & m_icon; + QIcon const & m_overlayIcon; + +}; + +} // anonymous namespace + +BtIcons::RegularIcon::RegularIcon(char const * const name) + : QIcon(util::directory::getIconDir().canonicalPath() + "/" + name + ".svg") +{} + +BtIcons::OverlayedIcon::OverlayedIcon(QIcon const & icon, + QIcon const & overlayedIcon) + : QIcon(new BtOverlayIconEngine(icon, overlayedIcon)) +{} + +BtIcons * BtIcons::m_instance = nullptr; + +BtIcons::BtIcons() + /* Regular icons: */ + : icon_add("add") + , icon_automatically("automatically") + , icon_back("back") + , icon_bible("bible") + , icon_bibletime("bibletime") + , icon_book("book") + , icon_bookmark("bookmark") + , icon_books("books") + , icon_calendar("calendar") + , icon_cascade("cascade") + , icon_checkbox("checkbox") + , icon_commentary("commentary") + , icon_configure("configure") + , icon_contents2("contents2") + , icon_delete("delete") + , icon_dictionary("dictionary") + , icon_displayconfig("displayconfig") + , icon_document_magnifier("document_magnifier") + , icon_edit_clear_locationbar("edit_clear_locationbar") + , icon_edit_copy("edit_copy") + , icon_exit("exit") + , icon_export("export") + , icon_file_save("file_save") + , icon_fileclose("fileclose") + , icon_find("find") + , icon_flag("flag") + , icon_folder_open("folder-open") + , icon_folder("folder") + , icon_fonts("fonts") + , icon_forward("forward") + , icon_import("import") + , icon_info("info") + , icon_key_bindings("key_bindings") + , icon_layer_visible_on("layer-visible-on") + , icon_lexicon("lexicon") + , icon_light_bulb("light_bulb") + , icon_lock("lock") + , icon_manual("manual") + , icon_map("map") + , icon_pencil("pencil") + , icon_plus("plus") + , icon_pointing_arrow("pointing_arrow") + , icon_print("print") + , icon_remove("remove") + , icon_questionable("questionable") + , icon_questionmark("questionmark") + , icon_refresh("refresh") + , icon_startconfig("startconfig") + , icon_stop("stop") + , icon_swordconfig("swordconfig") + , icon_sync("sync") + , icon_tabbed("tabbed") + , icon_text_bold("text_bold") + , icon_text_center("text_center") + , icon_text_italic("text_italic") + , icon_text_leftalign("text_leftalign") + , icon_text_rightalign("text_rightalign") + , icon_text_under("text_under") + , icon_tile("tile") + , icon_tile_horiz("tile_horiz") + , icon_tile_vert("tile_vert") + , icon_trash("trash") + , icon_unlock("unlock") + , icon_view_tree("view-tree") + , icon_view_index("view_index") + , icon_view_mag("view_mag") + , icon_view_profile("view_profile") + , icon_window_fullscreen("window_fullscreen") + /* Overlayed icons: */ + , icon_bible_add(icon_bible, icon_add) + , icon_bible_install(icon_bible, icon_plus) + , icon_bible_locked(icon_bible, icon_lock) + , icon_bible_remove(icon_bible, icon_remove) + , icon_bible_uninstall(icon_bible, icon_delete) + , icon_book_add(icon_book, icon_add) + , icon_book_locked(icon_book, icon_lock) + , icon_cascade_auto(icon_cascade, icon_automatically) + , icon_commentary_add(icon_commentary, icon_add) + , icon_commentary_locked(icon_commentary, icon_lock) + , icon_folder_add(icon_folder, icon_add) + , icon_lexicon_add(icon_lexicon, icon_add) + , icon_lexicon_locked(icon_lexicon, icon_lock) + , icon_tile_auto(icon_tile, icon_automatically) + , icon_tile_horiz_auto(icon_tile_horiz, icon_automatically) + , icon_tile_vert_auto(icon_tile_vert, icon_automatically) +{ + BT_ASSERT(!m_instance); + m_instance = this; +} + +QString iconToHtml(QIcon const & icon, int const extent) { + QByteArray bytes; + QBuffer buffer(&bytes); + icon.pixmap(extent).save(&buffer, "PNG"); + return "<img src=\"data:image/png;base64," + bytes.toBase64() + "\" />"; +} diff --git a/src/util/bticons.h b/src/util/bticons.h new file mode 100644 index 0000000..9289969 --- /dev/null +++ b/src/util/bticons.h @@ -0,0 +1,149 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef BTICONS_H +#define BTICONS_H + +#include <QIcon> +#include <QString> +#include "btassert.h" + + +class BtIcons { + +public: /* Types: */ + + class RegularIcon: public QIcon { + + public: /* Methods: */ + + RegularIcon(char const * const name); + + }; + + class OverlayedIcon: public QIcon { + + public: /* Methods: */ + + OverlayedIcon(QIcon const & icon, QIcon const & overlayedIcon); + + }; + +public: /* Methods: */ + + BtIcons(); + + static inline BtIcons & instance() { + BT_ASSERT(m_instance); + return *m_instance; + } + +private: /* Fields: */ + + static BtIcons * m_instance; + +public: /* Fields: */ + + QIcon const icon_null; + + /* Regular icons: */ + RegularIcon const icon_add; + RegularIcon const icon_automatically; + RegularIcon const icon_back; + RegularIcon const icon_bible; + RegularIcon const icon_bibletime; + RegularIcon const icon_book; + RegularIcon const icon_bookmark; + RegularIcon const icon_books; + RegularIcon const icon_calendar; + RegularIcon const icon_cascade; + RegularIcon const icon_checkbox; + RegularIcon const icon_commentary; + RegularIcon const icon_configure; + RegularIcon const icon_contents2; + RegularIcon const icon_delete; + RegularIcon const icon_dictionary; + RegularIcon const icon_displayconfig; + RegularIcon const icon_document_magnifier; + RegularIcon const icon_edit_clear_locationbar; + RegularIcon const icon_edit_copy; + RegularIcon const icon_exit; + RegularIcon const icon_export; + RegularIcon const icon_file_save; + RegularIcon const icon_fileclose; + RegularIcon const icon_find; + RegularIcon const icon_flag; + RegularIcon const icon_folder_open; + RegularIcon const icon_folder; + RegularIcon const icon_fonts; + RegularIcon const icon_forward; + RegularIcon const icon_import; + RegularIcon const icon_info; + RegularIcon const icon_key_bindings; + RegularIcon const icon_layer_visible_on; + RegularIcon const icon_lexicon; + RegularIcon const icon_light_bulb; + RegularIcon const icon_lock; + RegularIcon const icon_manual; + RegularIcon const icon_map; + RegularIcon const icon_pencil; + RegularIcon const icon_plus; + RegularIcon const icon_pointing_arrow; + RegularIcon const icon_print; + RegularIcon const icon_remove; + RegularIcon const icon_questionable; + RegularIcon const icon_questionmark; + RegularIcon const icon_refresh; + RegularIcon const icon_startconfig; + RegularIcon const icon_stop; + RegularIcon const icon_swordconfig; + RegularIcon const icon_sync; + RegularIcon const icon_tabbed; + RegularIcon const icon_text_bold; + RegularIcon const icon_text_center; + RegularIcon const icon_text_italic; + RegularIcon const icon_text_leftalign; + RegularIcon const icon_text_rightalign; + RegularIcon const icon_text_under; + RegularIcon const icon_tile; + RegularIcon const icon_tile_horiz; + RegularIcon const icon_tile_vert; + RegularIcon const icon_trash; + RegularIcon const icon_unlock; + RegularIcon const icon_view_tree; + RegularIcon const icon_view_index; + RegularIcon const icon_view_mag; + RegularIcon const icon_view_profile; + RegularIcon const icon_window_fullscreen; + + /* Overlayed icons: */ + OverlayedIcon const icon_bible_add; + OverlayedIcon const icon_bible_install; + OverlayedIcon const icon_bible_locked; + OverlayedIcon const icon_bible_remove; + OverlayedIcon const icon_bible_uninstall; + OverlayedIcon const icon_book_add; + OverlayedIcon const icon_book_locked; + OverlayedIcon const icon_cascade_auto; + OverlayedIcon const icon_commentary_add; + OverlayedIcon const icon_commentary_locked; + OverlayedIcon const icon_folder_add; + OverlayedIcon const icon_lexicon_add; + OverlayedIcon const icon_lexicon_locked; + OverlayedIcon const icon_tile_auto; + OverlayedIcon const icon_tile_horiz_auto; + OverlayedIcon const icon_tile_vert_auto; + +}; + +QString iconToHtml(QIcon const & icon, int const extent = 32); + +#endif /* BTICONS_H */ diff --git a/src/util/btmodules.cpp b/src/util/btmodules.cpp index 7ba31c6..5bc1ce1 100644 --- a/src/util/btmodules.cpp +++ b/src/util/btmodules.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -12,26 +12,24 @@ #include "backend/managers/cswordbackend.h" -bool equalModuleCategories(const QString& name1, const QString& name2) { - CSwordModuleInfo* m1 = CSwordBackend::instance()->findModuleByName(name1); - CSwordModuleInfo* m2 = CSwordBackend::instance()->findModuleByName(name2); - if (m1 == 0 || m2 == 0) - return false; - if (m1->category() == m2->category()) { - return true; - } +namespace { +inline bool equalModuleCategories(QString const & n1, QString const & n2) { + if (CSwordModuleInfo const * const m1 = + CSwordBackend::instance()->findModuleByName(n1)) + if (CSwordModuleInfo const * const m2 = + CSwordBackend::instance()->findModuleByName(n2)) + return m1->category() == m2->category(); return false; } +} // anonymous namespace -int leftLikeParallelModules(const QStringList modules) { +int leftLikeParallelModules(QStringList const & modules) { // Count the number of leftmost modules that are of the same category int leftLikeModules = 0; for (int i = 0; i < modules.count(); i++) { - if ( ! equalModuleCategories(modules.at(0), modules.at(i))) { + if (!equalModuleCategories(modules.at(0), modules.at(i))) break; - } leftLikeModules++; } return leftLikeModules; } - diff --git a/src/util/btmodules.h b/src/util/btmodules.h index cb99d1c..881cb72 100644 --- a/src/util/btmodules.h +++ b/src/util/btmodules.h @@ -4,15 +4,12 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ -#include <QString> #include <QStringList> -bool equalModuleCategories(const QString& name1, const QString& name2); - -int leftLikeParallelModules(const QStringList modules); +int leftLikeParallelModules(QStringList const & modules); diff --git a/src/util/btscopeexit.h b/src/util/btscopeexit.h new file mode 100644 index 0000000..34cd805 --- /dev/null +++ b/src/util/btscopeexit.h @@ -0,0 +1,42 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef BTSCOPEEXIT_H +#define BTSCOPEEXIT_H + +#include <type_traits> +#include <utility> +#include "btstringjoin.h" + + +template <typename F> +class BtScopeExit { + +public: /* Methods: */ + + inline BtScopeExit(F f) : m_f{f} {} + inline ~BtScopeExit() noexcept { m_f(); } + +private: /* Fields: */ + + F m_f; + +}; + +template <typename F> +BtScopeExit<typename std::remove_reference<F>::type> createBtScopeExit(F f) +{ return f; } + +#define BT_SCOPE_EXIT(...) \ + auto BT_STRING_JOIN(bt_scope_exit_, __LINE__) = \ + createBtScopeExit([=](){__VA_ARGS__}) + +#endif /* BTSCOPEEXIT_H */ diff --git a/src/util/btstringjoin.h b/src/util/btstringjoin.h new file mode 100644 index 0000000..f5579c3 --- /dev/null +++ b/src/util/btstringjoin.h @@ -0,0 +1,18 @@ +/********* +* +* 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-2016 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef BTSTRINGJOIN_H +#define BTSTRINGJOIN_H + +#define BT_STRING_JOIN_(a, b) a ## b +#define BT_STRING_JOIN(a, b) BT_STRING_JOIN_(a, b) + +#endif /* BTSTRINGJOIN_H */ diff --git a/src/util/exceptions.h b/src/util/btwrap.h index 3084ff8..02a2185 100644 --- a/src/util/exceptions.h +++ b/src/util/btwrap.h @@ -4,15 +4,14 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ -#ifndef EXCEPTIONS_H -#define EXCEPTIONS_H -class BTException {}; +#ifndef BTWRAP_H +#define BTWRAP_H -class BTCLuceneException: public BTException {}; +#define BT_WRAP(...) __VA_ARGS__ -#endif +#endif /* BTWRAP_H */ diff --git a/src/util/cresmgr.cpp b/src/util/cresmgr.cpp index a122039..4e4380c 100644 --- a/src/util/cresmgr.cpp +++ b/src/util/cresmgr.cpp @@ -2,192 +2,107 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ #include "util/cresmgr.h" -#include <QString> - - namespace CResMgr { -namespace mainWindow { -const QString icon = "bibletime.svg"; -} // mainWindow -namespace modules { -namespace bible { -const QString icon_unlocked = "bible.svg"; -const QString icon_locked = "bible_locked.svg"; -const QString icon_add = "bible_add.svg"; -} //bible -namespace commentary { -const QString icon_unlocked = "commentary.svg"; -const QString icon_locked = "commentary_locked.svg"; -const QString icon_add = "commentary_add.svg"; -} //commentary -namespace lexicon { -const QString icon_unlocked = "lexicon.svg"; -const QString icon_locked = "lexicon_locked.svg"; -const QString icon_add = "lexicon_add.svg"; -}//lexicon -namespace book { -const QString icon_unlocked = "book.svg"; -const QString icon_locked = "book_locked.svg"; -const QString icon_add = "book_add.svg"; -}//book -}//modules -namespace categories { -namespace bibles { -const QString icon = "bible.svg"; -} -namespace commentaries { -const QString icon = "commentary.svg"; -} -namespace lexicons { -const QString icon = "lexicon.svg"; -} -namespace dailydevotional { -const QString icon = "calendar.svg"; -} -namespace books { -const QString icon = "books.svg"; -} -namespace glossary { -const QString icon = "dictionary.svg"; -} -namespace images { -const QString icon = "map.svg"; -} -namespace cults { -const QString icon = "questionable.svg"; -} -}//categories -namespace mainMenu { //Main menu +namespace mainMenu { // Main menu -namespace view { //Main menu->View -namespace showBookshelf { -const QString icon = "books.svg"; -} -namespace showBookmarks { -const QString icon = "bookmark.svg"; -} -namespace showMag { -const QString icon = "document_magnifier.svg"; -} +namespace view { // Main menu->View namespace showMainIndex { -const QString icon = "view_index.svg"; const QKeySequence accel(Qt::Key_F9); const char* actionName = "viewMainIndex_action"; } namespace showInfoDisplay { -const QString icon = "view_mag.svg"; const QKeySequence accel(Qt::Key_F8); const char* actionName = "viewInfoDisplay_action"; } -}//mainMenu::view +} // namespace view { namespace mainIndex { namespace search { -const QString icon = "find.svg"; const QKeySequence accel(Qt::CTRL + Qt::Key_O); const char* actionName = "mainindex_search_action"; } namespace searchdefaultbible { -const QString icon = "find.svg"; const QKeySequence accel(Qt::CTRL + Qt::ALT + Qt::Key_F); const char* actionName = "mainindex_searchdefaultbible_action"; } -}//mainMenu::mainIndex +} // namespace mainIndex { namespace window { //mainMenu::window namespace loadProfile { -const QString icon = "view_profile.svg"; const char* actionName = "windowLoadProfile_action"; } namespace saveProfile { -const QString icon = "view_profile.svg"; const char* actionName = "windowSaveProfile_action"; } namespace saveToNewProfile { -const QString icon = "view_profile.svg"; const QKeySequence accel(Qt::CTRL + Qt::ALT + Qt::Key_S); const char* actionName = "windowSaveToNewProfile_action"; } namespace deleteProfile { -const QString icon = "view_profile.svg"; const char* actionName = "windowDeleteProfile_action"; } namespace showFullscreen { -const QString icon = "window_fullscreen.svg"; const QKeySequence accel(Qt::Key_F5); const char* actionName = "windowFullscreen_action"; } namespace arrangementMode { -const QString icon = "cascade_auto.svg"; const QKeySequence accel; const char* actionName = "windowArrangementMode_action"; namespace manual { -const QString icon = "tile.svg"; const QKeySequence accel(Qt::CTRL + Qt::ALT + Qt::Key_M); const char* actionName = "windowArrangementManual_action"; } namespace autoTileHorizontal { -const QString icon = "tile_horiz.svg"; const QKeySequence accel(Qt::CTRL + Qt::ALT + Qt::Key_H); const char* actionName = "windowAutoTileHorizontal_action"; } namespace autoTileVertical { -const QString icon = "tile_vert.svg"; const QKeySequence accel(Qt::CTRL + Qt::ALT + Qt::Key_G); const char* actionName = "windowAutoTileVertical_action"; } namespace autoTile { -const QString icon = "tile_auto.svg"; const QKeySequence accel(Qt::CTRL + Qt::ALT + Qt::Key_I); const char* actionName = "windowAutoTile_action"; } namespace autoTabbed { -const QString icon = "tabbed.svg"; const QKeySequence accel(Qt::CTRL + Qt::ALT + Qt::Key_T); const char* actionName = "windowAutoTabbed_action"; } namespace autoCascade { -const QString icon = "cascade_auto.svg"; const QKeySequence accel(Qt::CTRL + Qt::ALT + Qt::Key_J); const char* actionName = "windowAutoCascade_action"; } } namespace tileHorizontal { -const QString icon = "tile_horiz.svg"; const QKeySequence accel(Qt::CTRL + Qt::Key_H); const char* actionName = "windowTileHorizontal_action"; } namespace tileVertical { -const QString icon = "tile_vert.svg"; const QKeySequence accel(Qt::CTRL + Qt::Key_G); const char* actionName = "windowTileVertical_action"; } namespace tile { -const QString icon = "tile.svg"; const QKeySequence accel(Qt::CTRL + Qt::Key_I); const char* actionName = "windowTile_action"; } namespace cascade { -const QString icon = "cascade.svg"; const QKeySequence accel(Qt::CTRL + Qt::Key_J); const char* actionName = "windowCascade_action"; } namespace close { -const QString icon = "fileclose.svg"; const QKeySequence accel(Qt::CTRL + Qt::Key_W); const char* actionName = "windowClose_action"; } namespace closeAll { -const QString icon = "fileclose.svg"; const QKeySequence accel(Qt::CTRL + Qt::ALT + Qt::Key_W); const char* actionName = "windowCloseAll_action"; } @@ -195,7 +110,6 @@ const char* actionName = "windowCloseAll_action"; namespace settings { //Main menu->Settings namespace swordSetupDialog { -const QString icon = "swordconfig.svg"; const QKeySequence accel(Qt::Key_F4); const char* actionName = "options_sword_setup"; } @@ -204,94 +118,36 @@ const char* actionName = "options_sword_setup"; namespace help { //Main menu->Help namespace handbook { -const QString icon = "contents2.svg"; const QKeySequence accel(Qt::Key_F1); const char* actionName = "helpHandbook_action"; } namespace bibleStudyHowTo { -const QString icon = "contents2.svg"; const QKeySequence accel(Qt::Key_F2); const char* actionName = "helpHowTo_action"; } namespace tipOfTheDay { -const QString icon = "light_bulb.svg"; const QKeySequence accel(Qt::Key_F3); const char* actionName = "tipOfTheDay_action"; } }//mainMenu::help } //end of mainMenu -namespace findWidget { -const QString close_icon = "stop.svg"; -const QString previous_icon = "back.svg"; -const QString next_icon = "forward.svg"; -} - -namespace searchdialog { -const QString icon = "find.svg"; -const QString close_icon = "stop.svg"; -const QString help_icon = "questionmark"; -const QString chooseworks_icon = "checkbox"; -const QString setupscope_icon = "configure"; - -namespace result { -namespace moduleList { - -namespace copyMenu { -const QString icon = "edit_copy.svg"; -} -namespace saveMenu { -const QString icon = "file_save.svg"; -} -namespace printMenu { -const QString icon = "print.svg"; -} -} -namespace foundItems { - -namespace copyMenu { -const QString icon = "edit_copy.svg"; -} -namespace saveMenu { -const QString icon = "file_save.svg"; -} -namespace printMenu { -const QString icon = "print.svg"; -} -} -} -} //searchDialog - namespace displaywindows { -/* namespace transliteration { - const QString icon = "bt_displaytranslit"; - }*/ -namespace displaySettings { -const QString icon = "displayconfig.svg"; -} - namespace general { -const QString removemoduleicon = "fileclose"; -const QString addmoduleicon = "plus"; -const QString replacemoduleicon = "checkbox"; namespace search { -const QString icon = "find.svg"; const QKeySequence accel(Qt::CTRL + Qt::Key_N); const char* actionName = "window_search_action"; } namespace backInHistory { -const QString icon = "back.svg"; const QKeySequence accel(Qt::ALT + Qt::Key_Left); const char* actionName = "window_history_back_action"; } namespace forwardInHistory { -const QString icon = "forward.svg"; const QKeySequence accel(Qt::ALT + Qt::Key_Right); const char* actionName = "window_history_forward_action"; } namespace findStrongs { -const QString icon = "bt_findstrongs.svg"; const QKeySequence accel; const char* actionName = "window_find_strongs_action"; } @@ -317,20 +173,9 @@ const QKeySequence accel(Qt::CTRL + Qt::Key_V); namespace previousVerse { const QKeySequence accel(Qt::CTRL + Qt::SHIFT + Qt::Key_V); } - -namespace copyMenu { -const QString icon = "edit_copy.svg"; -} -namespace saveMenu { -const QString icon = "file_save.svg"; -} -namespace printMenu { -const QString icon = "print.svg"; -} } namespace commentaryWindow { namespace syncWindow { -const QString icon = "sync.svg"; const QKeySequence accel(Qt::SHIFT + Qt::Key_S); const char* actionName = "commentary_syncWindow"; } @@ -345,79 +190,48 @@ const QKeySequence accel(Qt::CTRL + Qt::Key_V); namespace previousEntry { const QKeySequence accel(Qt::CTRL + Qt::SHIFT + Qt::Key_V); } - -namespace copyMenu { -const QString icon = "edit_copy.svg"; -} -namespace saveMenu { -const QString icon = "file_save.svg"; -} -namespace printMenu { -const QString icon = "print.svg"; -} -} -namespace bookWindow { -namespace toggleTree { -const QString icon = "view_sidetree.svg"; -const QKeySequence accel; -} } namespace writeWindow { namespace saveText { -const QString icon = "file_save"; const QKeySequence accel; const char* actionName = "writeWindow_saveText"; } namespace restoreText { -const QString icon = "import.svg"; const QKeySequence accel; const char* actionName = "writeWindow_restoreText"; } namespace deleteEntry { -const QString icon = "edit_delete.svg"; const QKeySequence accel; const char* actionName = "writeWindow_deleteEntry"; } //formatting buttons namespace boldText { -const QString icon = "text_bold.svg"; const QKeySequence accel; const char* actionName = "writeWindow_boldText"; } namespace italicText { -const QString icon = "text_italic.svg"; const QKeySequence accel; const char* actionName = "writeWindow_italicText"; } namespace underlinedText { -const QString icon = "text_under.svg"; const QKeySequence accel; const char* actionName = "writeWindow_underlineText"; } namespace alignLeft { -const QString icon = "text_leftalign"; const QKeySequence accel; const char* actionName = "writeWindow_alignLeft"; } namespace alignCenter { -const QString icon = "text_center"; const QKeySequence accel; const char* actionName = "writeWindow_alignCenter"; } namespace alignRight { -const QString icon = "text_rightalign"; const QKeySequence accel; const char* actionName = "writeWindow_alignRight"; } -namespace alignJustify { -const QString icon = "text_justify"; -const QKeySequence accel; -const char* actionName = "writeWindow_alignJustify"; -} - namespace fontFamily { const QKeySequence accel; const char* actionName = "writeWindow_fontFamily"; @@ -429,115 +243,11 @@ const char* actionName = "writeWindow_fontSize"; } }//displayWindows -namespace settings { -namespace startup { -const QString icon = "startconfig.svg"; -} -namespace fonts { -const QString icon = "fonts.svg"; -} -namespace languages { -const QString icon = "flag.svg"; -} -namespace profiles { -const QString icon = "view_profile.svg"; -} -namespace sword { -const QString icon = "swordconfig.svg"; - -} -namespace keys { -const QString icon = "key_bindings.svg"; -} -}//settings - namespace mainIndex { // Bookshelf view namespace search { -const QString icon = "find.svg"; const QKeySequence accel(Qt::CTRL + Qt::ALT + Qt::Key_M); const char* actionName = "GMsearch_action"; } -namespace newFolder { -const QString icon = "folder_new.svg"; -} -namespace changeFolder { -const QString icon = "folder.svg"; -} -namespace openedFolder { -const QString icon = "folder_open.svg"; -} -namespace closedFolder { -const QString icon = "folder.svg"; -} - -namespace bookmark { -const QString icon = "bookmark.svg"; -} -namespace editBookmark { -const QString icon = "bookmark.svg"; -} -namespace sortFolderBookmarks { -const QString icon = "bookmark.svg"; -} -namespace sortAllBookmarks { -const QString icon = "bookmark.svg"; -} -namespace importBookmarks { -const QString icon = "import.svg"; -} -namespace exportBookmarks { -const QString icon = "export.svg"; -} -namespace printBookmarks { -const QString icon = "print.svg"; -} -namespace deleteItems { -const QString icon = "edit_delete.svg"; -} - -namespace editModuleMenu { -const QString icon = "pencil.svg"; -} -namespace editModulePlain { -const QString icon = "pencil.svg"; -} -namespace editModuleHTML { -const QString icon = "pencil.svg"; -} - -namespace unlockModule { -const QString icon = "unlock.svg"; -} -namespace aboutModule { -const QString icon = "info.svg"; -} -namespace grouping { -const QString icon = "view-tree.svg"; -} }//mainIndex -namespace bookshelfmgr { -namespace installpage { -const QString icon = "bible_add"; -const QString refresh_icon = "refresh"; -const QString delete_icon = "trash"; -const QString add_icon = "plus"; -const QString install_icon = "bible_add"; -const QString path_icon = "configure"; -} -namespace removepage { -const QString icon = "bible_remove"; -const QString remove_icon = "trash"; -} -namespace indexpage { -const QString icon = "document_magnifier"; -const QString create_icon = "folder_new"; -const QString delete_icon = "trash"; -} -namespace paths { -const QString add_icon = "plus"; -const QString edit_icon = "pencil"; -const QString remove_icon = "trash"; -} -} // namespace bookshelfmgr } // namespace CResMgr diff --git a/src/util/cresmgr.h b/src/util/cresmgr.h index b09c9fa..097f795 100644 --- a/src/util/cresmgr.h +++ b/src/util/cresmgr.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -14,197 +14,189 @@ #include <QKeySequence> #include <QString> +#include "bticons.h" + +#define BT_GETICON2(fname,name) \ + inline QIcon const & fname() { return BtIcons::instance().icon_ ## name; } +#define BT_GETICON(name) BT_GETICON2(icon,name) namespace CResMgr { +BT_GETICON2(icon_clearEdit, edit_clear_locationbar) + namespace mainWindow { -extern const QString icon; +BT_GETICON(bibletime) +BT_GETICON2(icon_openAction, folder_open) } namespace modules { + +BT_GETICON2(icon_moduleLanguage, flag) + +BT_GETICON2(icon_cult, stop) + namespace bible { -extern const QString icon_unlocked; -extern const QString icon_locked; -extern const QString icon_add; -} +BT_GETICON2(icon_unlocked, bible) +BT_GETICON2(icon_locked, bible_locked) +BT_GETICON2(icon_add, bible_add) +} /* namespace bible { */ + namespace commentary { -extern const QString icon_unlocked; -extern const QString icon_locked; -extern const QString icon_add; -} +BT_GETICON2(icon_unlocked, commentary) +BT_GETICON2(icon_locked, commentary_locked) +BT_GETICON2(icon_add, commentary_add) +} /* namespace commentary { */ + namespace lexicon { -extern const QString icon_unlocked; -extern const QString icon_locked; -extern const QString icon_add; -} +BT_GETICON2(icon_unlocked, lexicon) +BT_GETICON2(icon_locked, lexicon_locked) +BT_GETICON2(icon_add, lexicon_add) +} /* namespace lexicon { */ + namespace book { -extern const QString icon_unlocked; -extern const QString icon_locked; -extern const QString icon_add; -} -} +BT_GETICON2(icon_unlocked, book) +BT_GETICON2(icon_locked, book_locked) +BT_GETICON2(icon_add, book_add) +} /* namespace book { */ +} /* namespace modules { */ namespace categories { -namespace bibles { -extern const QString icon; -} -namespace commentaries { -extern const QString icon; -} -namespace lexicons { -extern const QString icon; -} -namespace dailydevotional { -extern const QString icon; -} -namespace books { -extern const QString icon; -} -namespace glossary { -extern const QString icon; -} -namespace images { -extern const QString icon; -} -namespace cults { -extern const QString icon; -} -} - -namespace mainMenu { //Main menu - -namespace view { //Main menu->View -namespace showBookshelf { -extern const QString icon; -} -namespace showBookmarks { -extern const QString icon; -} -namespace showMag { -extern const QString icon; -} +namespace bibles { BT_GETICON(bible) } +namespace commentaries { BT_GETICON(commentary) } +namespace lexicons { BT_GETICON(lexicon) } +namespace dailydevotional { BT_GETICON(calendar) } +namespace books { BT_GETICON(books) } +namespace glossary { BT_GETICON(dictionary) } +namespace images { BT_GETICON(map) } +namespace cults { BT_GETICON(questionable) } +} /* namespace categories { */ + +namespace mainMenu { // Main menu + +namespace view { // Main menu->View +namespace showBookshelf { BT_GETICON(books) } +namespace showBookmarks { BT_GETICON(bookmark) } +namespace showMag { BT_GETICON(document_magnifier) } namespace showMainIndex { -extern const QString icon; +BT_GETICON(view_index) extern const QKeySequence accel; extern const char* actionName; -} +} /* namespace showMainIndex { */ namespace showInfoDisplay { -extern const QString icon; +BT_GETICON(view_mag) extern const QKeySequence accel; extern const char* actionName; -} -} +} /* namespace showInfoDisplay { */ +} /* namespace view { */ namespace mainIndex { //configuration for the main index and the view->search menu namespace search { -extern const QString icon; +BT_GETICON(find) extern const QKeySequence accel; extern const char* actionName; } namespace searchdefaultbible { -extern const QString icon; +BT_GETICON(find) extern const QKeySequence accel; extern const char* actionName; } } namespace window { //Main menu->Window +namespace quit { BT_GETICON(exit) } namespace loadProfile { -extern const QString icon; +BT_GETICON(view_profile) extern const char* actionName; } namespace saveProfile { -extern const QString icon; +BT_GETICON(view_profile) extern const char* actionName; } namespace saveToNewProfile { -extern const QString icon; +BT_GETICON(view_profile) extern const QKeySequence accel; extern const char* actionName; } namespace deleteProfile { -extern const QString icon; +BT_GETICON(view_profile) extern const char* actionName; } namespace showFullscreen { -extern const QString icon; +BT_GETICON(window_fullscreen) extern const QKeySequence accel; extern const char* actionName; } namespace arrangementMode { -extern const QString icon; +BT_GETICON(cascade_auto) extern const QKeySequence accel; extern const char* actionName; namespace manual { -extern const QString icon; +BT_GETICON(manual) extern const QKeySequence accel; extern const char* actionName; } -namespace autoTileVertical { -extern const QString icon; +namespace autoTileHorizontal { +BT_GETICON(tile_horiz_auto) extern const QKeySequence accel; extern const char* actionName; } -namespace autoTileHorizontal { -extern const QString icon; +namespace autoTileVertical { +BT_GETICON(tile_vert_auto) extern const QKeySequence accel; extern const char* actionName; } namespace autoTile { -extern const QString icon; +BT_GETICON(tile_auto); extern const QKeySequence accel; extern const char* actionName; } namespace autoTabbed { -extern const QString icon; +BT_GETICON(tabbed) extern const QKeySequence accel; extern const char* actionName; } namespace autoCascade { -extern const QString icon; +BT_GETICON(cascade_auto) extern const QKeySequence accel; extern const char* actionName; } } -namespace tileVertical { -extern const QString icon; +namespace tileHorizontal { +BT_GETICON(tile_horiz) extern const QKeySequence accel; extern const char* actionName; } -namespace tileHorizontal { -extern const QString icon; +namespace tileVertical { +BT_GETICON(tile_vert) extern const QKeySequence accel; extern const char* actionName; } namespace tile { -extern const QString icon; +BT_GETICON(tile) extern const QKeySequence accel; extern const char* actionName; } namespace cascade { -extern const QString icon; +BT_GETICON(cascade) extern const QKeySequence accel; extern const char* actionName; } namespace close { -extern const QString icon; +BT_GETICON(fileclose) extern const QKeySequence accel; extern const char* actionName; } namespace closeAll { -extern const QString icon; +BT_GETICON(fileclose) extern const QKeySequence accel; extern const char* actionName; } } namespace settings { //Main menu->Settings -namespace editToolBar { // available as KStdAction -} -namespace optionsDialog { // available as KStdAction -} +namespace configureDialog { BT_GETICON(configure) } namespace swordSetupDialog { -extern const QString icon; +BT_GETICON(swordconfig) extern const QKeySequence accel; extern const char* actionName; } @@ -212,98 +204,78 @@ extern const char* actionName; namespace help { //Main menu->Help namespace handbook { -extern const QString icon; +BT_GETICON(contents2) extern const QKeySequence accel; extern const char* actionName; } namespace bibleStudyHowTo { -extern const QString icon; +BT_GETICON(contents2) extern const QKeySequence accel; extern const char* actionName; } namespace tipOfTheDay { -extern const QString icon; +BT_GETICON(light_bulb) extern const QKeySequence accel; extern const char* actionName; } +namespace aboutBibleTime { BT_GETICON(bibletime) } } } //end of main menu namespace findWidget { -extern const QString close_icon; -extern const QString previous_icon; -extern const QString next_icon; +BT_GETICON2(icon_close, stop) +BT_GETICON2(icon_previous, back) +BT_GETICON2(icon_next, forward) } namespace searchdialog { -extern const QString icon; -extern const QString close_icon; -extern const QString help_icon; -extern const QString chooseworks_icon; -extern const QString setupscope_icon; +BT_GETICON(find) +BT_GETICON2(icon_close, stop) +BT_GETICON2(icon_help, questionmark) +BT_GETICON2(icon_chooseWorks, checkbox) +BT_GETICON2(icon_setupScope, configure) namespace result { namespace moduleList { - -namespace copyMenu { -extern const QString icon; -} -namespace saveMenu { -extern const QString icon; -} -namespace printMenu { -extern const QString icon; -} +namespace copyMenu { BT_GETICON(edit_copy) } +namespace saveMenu { BT_GETICON(file_save) } +namespace printMenu { BT_GETICON(print) } } namespace foundItems { - -namespace copyMenu { -extern const QString icon; -} -namespace saveMenu { -extern const QString icon; -} -namespace printMenu { -extern const QString icon; -} - +namespace copyMenu { BT_GETICON(edit_copy) } +namespace saveMenu { BT_GETICON(file_save) } +namespace printMenu { BT_GETICON(print) } } } } -namespace workspace {} - namespace displaywindows { -namespace transliteration { -extern const QString icon; -} namespace displaySettings { -extern const QString icon; +BT_GETICON(displayconfig) } namespace general { -extern const QString removemoduleicon; -extern const QString addmoduleicon; -extern const QString replacemoduleicon; +BT_GETICON2(icon_removeModule, fileclose) +BT_GETICON2(icon_addModule, plus) +BT_GETICON2(icon_replaceModule, checkbox) namespace search { -extern const QString icon; +BT_GETICON(find) extern const QKeySequence accel; extern const char* actionName; } namespace backInHistory { -extern const QString icon; +BT_GETICON(back) extern const QKeySequence accel; extern const char* actionName; } namespace forwardInHistory { -extern const QString icon; +BT_GETICON(forward) extern const QKeySequence accel; extern const char* actionName; } namespace findStrongs { -extern const QString icon; extern const QKeySequence accel; extern const char* actionName; } @@ -331,19 +303,13 @@ namespace previousVerse { extern const QKeySequence accel; } -namespace copyMenu { -extern const QString icon; -} -namespace saveMenu { -extern const QString icon; -} -namespace printMenu { -extern const QString icon; -} +namespace copyMenu { BT_GETICON(edit_copy) } +namespace saveMenu { BT_GETICON(file_save) } +namespace printMenu { BT_GETICON(print) } } namespace commentaryWindow { namespace syncWindow { -extern const QString icon; +BT_GETICON(sync) extern const QKeySequence accel; extern const char* actionName; } @@ -357,80 +323,60 @@ extern const QKeySequence accel; namespace previousEntry { extern const QKeySequence accel; } - -namespace copyMenu { -extern const QString icon; -} -namespace saveMenu { -extern const QString icon; -} -namespace printMenu { -extern const QString icon; -} -} -namespace bookWindow { -namespace toggleTree { -extern const QString icon; -extern const QKeySequence accel; -} +namespace copyMenu { BT_GETICON(edit_copy) } +namespace saveMenu { BT_GETICON(file_save) } +namespace printMenu { BT_GETICON(print) } } - namespace writeWindow { namespace saveText { -extern const QString icon; +BT_GETICON(file_save) extern const QKeySequence accel; extern const char* actionName; } namespace restoreText { -extern const QString icon; +BT_GETICON(import) extern const QKeySequence accel; extern const char* actionName; } namespace deleteEntry { -extern const QString icon; +BT_GETICON(delete) extern const QKeySequence accel; extern const char* actionName; } //formatting buttons namespace boldText { -extern const QString icon; +BT_GETICON(text_bold) extern const QKeySequence accel; extern const char* actionName; } namespace italicText { -extern const QString icon; +BT_GETICON(text_italic) extern const QKeySequence accel; extern const char* actionName; } namespace underlinedText { -extern const QString icon; +BT_GETICON(text_under) extern const QKeySequence accel; extern const char* actionName; } namespace alignLeft { -extern const QString icon; +BT_GETICON(text_leftalign) extern const QKeySequence accel; extern const char* actionName; } namespace alignCenter { -extern const QString icon; +BT_GETICON(text_center) extern const QKeySequence accel; extern const char* actionName; } namespace alignRight { -extern const QString icon; -extern const QKeySequence accel; -extern const char* actionName; -} -namespace alignJustify { -extern const QString icon; +BT_GETICON(text_rightalign) extern const QKeySequence accel; extern const char* actionName; } - namespace fontFamily { extern const QKeySequence accel; extern const char* actionName; @@ -439,123 +385,74 @@ namespace fontSize { extern const QKeySequence accel; extern const char* actionName; } -namespace fontColor { -} - } } namespace settings { -namespace startup { -extern const QString icon; -} -namespace fonts { -extern const QString icon; -} -namespace languages { -extern const QString icon; -} -namespace profiles { -extern const QString icon; -} -namespace sword { -extern const QString icon; - -} -namespace keys { -extern const QString icon; -} +namespace startup { BT_GETICON(startconfig) } +namespace fonts { BT_GETICON(fonts) } +namespace profiles { BT_GETICON(view_profile) } +namespace sword { BT_GETICON(swordconfig) } +namespace keys { BT_GETICON(key_bindings) } } namespace mainIndex { //configuration for the main index and the view->search menu +namespace showHide { BT_GETICON(layer_visible_on) } namespace search { -extern const QString icon; +BT_GETICON(find) extern const QKeySequence accel; extern const char* actionName; } -namespace newFolder { -extern const QString icon; -} -namespace changeFolder { -extern const QString icon; -} -namespace openedFolder { -extern const QString icon; -} -namespace closedFolder { -extern const QString icon; -} +namespace newFolder { BT_GETICON(folder_add) } +namespace changeFolder { BT_GETICON(folder) } +namespace openedFolder { BT_GETICON(folder_open) } +namespace closedFolder { BT_GETICON(folder) } -namespace bookmark { -extern const QString icon; -} -namespace editBookmark { -extern const QString icon; -} -namespace sortFolderBookmarks { -extern const QString icon; -} -namespace sortAllBookmarks { -extern const QString icon; -} -namespace importBookmarks { -extern const QString icon; -} -namespace exportBookmarks { -extern const QString icon; -} -namespace printBookmarks { -extern const QString icon; -} -namespace deleteItems { -extern const QString icon; -} +namespace bookmark { BT_GETICON(bookmark) } +namespace editBookmark { BT_GETICON(bookmark) } +namespace sortFolderBookmarks { BT_GETICON(null) } +namespace sortAllBookmarks { BT_GETICON(null) } +namespace importBookmarks { BT_GETICON(import) } +namespace exportBookmarks { BT_GETICON(export) } +namespace printBookmarks { BT_GETICON(print) } +namespace deleteItems { BT_GETICON(delete) } -namespace editModuleMenu { -extern const QString icon; -} -namespace editModulePlain { -extern const QString icon; -} -namespace editModuleHTML { -extern const QString icon; -} +namespace editModuleMenu { BT_GETICON(pencil) } +namespace editModulePlain { BT_GETICON(pencil) } +namespace editModuleHTML { BT_GETICON(pencil) } -namespace unlockModule { -extern const QString icon; -} -namespace aboutModule { -extern const QString icon; -} -namespace grouping { -extern const QString icon; -} +namespace unlockModule { BT_GETICON(unlock) } +namespace aboutModule { BT_GETICON(info) } +namespace grouping { BT_GETICON(view_tree) } } namespace bookshelfmgr { namespace installpage { -extern const QString icon; -extern const QString refresh_icon; -extern const QString delete_icon; -extern const QString add_icon; -extern const QString install_icon; -extern const QString path_icon; +BT_GETICON(bible_install) +BT_GETICON2(icon_refresh, refresh) +BT_GETICON2(icon_addSource, plus) +BT_GETICON2(icon_deleteSource, delete) +BT_GETICON2(icon_install, plus) +BT_GETICON2(icon_path, configure) } namespace removepage { -extern const QString icon; -extern const QString remove_icon; +BT_GETICON(bible_uninstall) +BT_GETICON2(icon_remove, delete) } namespace indexpage { -extern const QString icon; -extern const QString create_icon; -extern const QString delete_icon; +BT_GETICON(document_magnifier) +BT_GETICON2(icon_create, plus) +BT_GETICON2(icon_delete, delete) } namespace paths { -extern const QString add_icon; -extern const QString edit_icon; -extern const QString remove_icon; +BT_GETICON2(icon_add, add) +BT_GETICON2(icon_edit, pencil) +BT_GETICON2(icon_remove, remove) } } } +#undef BT_GETICON +#undef BT_GETICON2 + #endif diff --git a/src/util/directory.cpp b/src/util/directory.cpp index 6ce80b4..53086ec 100644 --- a/src/util/directory.cpp +++ b/src/util/directory.cpp @@ -2,13 +2,14 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ -#include "util/directory.h" +#include "directory.h" +#include <memory> #include <QCoreApplication> #include <QDebug> #include <QDir> @@ -16,6 +17,7 @@ #include <QFileInfo> #include <QFileInfoList> #include <QLocale> +#include "btassert.h" namespace util { @@ -23,33 +25,39 @@ namespace directory { namespace { -QScopedPointer<QDir> cachedIconDir; -QScopedPointer<QDir> cachedJavascriptDir; -QScopedPointer<QDir> cachedLicenseDir; -QScopedPointer<QDir> cachedPicsDir; -QScopedPointer<QDir> cachedLocaleDir; -QScopedPointer<QDir> cachedHandbookDir; -QScopedPointer<QDir> cachedHowtoDir; -QScopedPointer<QDir> cachedDisplayTemplatesDir; -QScopedPointer<QDir> cachedUserDisplayTemplatesDir; -QScopedPointer<QDir> cachedUserBaseDir; -QScopedPointer<QDir> cachedUserHomeDir; -QScopedPointer<QDir> cachedUserHomeSwordDir; -QScopedPointer<QDir> cachedUserHomeSwordModsDir; -QScopedPointer<QDir> cachedUserSessionsDir; -QScopedPointer<QDir> cachedUserCacheDir; -QScopedPointer<QDir> cachedUserIndexDir; -QScopedPointer<QDir> cachedSwordPathDir; +std::unique_ptr<QDir> cachedIconDir; +std::unique_ptr<QDir> cachedJavascriptDir; +std::unique_ptr<QDir> cachedLicenseDir; +std::unique_ptr<QDir> cachedPicsDir; +std::unique_ptr<QDir> cachedLocaleDir; +std::unique_ptr<QDir> cachedHandbookDir; +std::unique_ptr<QDir> cachedHowtoDir; +std::unique_ptr<QDir> cachedDisplayTemplatesDir; +std::unique_ptr<QDir> cachedQmlDir; +std::unique_ptr<QDir> cachedUserDisplayTemplatesDir; +std::unique_ptr<QDir> cachedUserBaseDir; +std::unique_ptr<QDir> cachedUserHomeDir; +std::unique_ptr<QDir> cachedUserHomeSwordDir; +std::unique_ptr<QDir> cachedUserHomeSwordModsDir; +std::unique_ptr<QDir> cachedUserSessionsDir; +std::unique_ptr<QDir> cachedUserCacheDir; +std::unique_ptr<QDir> cachedUserIndexDir; +std::unique_ptr<QDir> cachedSwordPathDir; #ifdef Q_OS_WIN -QScopedPointer<QDir> cachedApplicationSwordDir; // Only Windows installs the sword directory which contains locales.d -QScopedPointer<QDir> cachedSharedSwordDir; +std::unique_ptr<QDir> cachedApplicationSwordDir; // Only Windows installs the sword directory which contains locales.d +std::unique_ptr<QDir> cachedSharedSwordDir; #endif #ifdef Q_OS_MAC -QScopedPointer<QDir> cachedSwordLocalesDir; +std::unique_ptr<QDir> cachedSwordLocalesDir; #endif -#ifdef Q_OS_WIN +#ifdef Q_OS_ANDROID +std::unique_ptr<QDir> cachedSharedSwordDir; // Directory that AndBible uses +static const char AND_BIBLE[] = "/sdcard/Android/data/net.bible.android.activity/files"; +#endif + +#if defined Q_OS_WIN || defined Q_OS_SYMBIAN static const char BIBLETIME[] = "Bibletime"; static const char SWORD_DIR[] = "Sword"; #else @@ -65,22 +73,37 @@ static const char SWORD_PATH[] = "SWORD_PATH"; } // anonymous namespace bool initDirectoryCache() { - QDir wDir(QCoreApplication::applicationDirPath()); - wDir.makeAbsolute(); + QDir wDir(":/share/bibletime"); // check if resources would be read from qrc + if(wDir.exists()) + wDir = ":/"; + else { + wDir = QCoreApplication::applicationDirPath(); + wDir.makeAbsolute(); + if (!wDir.cdUp()) { // Installation prefix + qWarning() << "Cannot cd up from directory " << QCoreApplication::applicationDirPath(); + return false; + } + } - if (!wDir.cdUp()) { // Installation prefix - qWarning() << "Cannot cd up from directory " << QCoreApplication::applicationDirPath(); - return false; +#ifdef Q_OS_ANDROID + cachedSharedSwordDir.reset(new QDir()); + if (!cachedSharedSwordDir->cd(AND_BIBLE)) { + cachedSharedSwordDir->mkpath(AND_BIBLE); + cachedSharedSwordDir->cd(AND_BIBLE); } +#endif -#ifdef Q_OS_WIN +#ifdef Q_OS_WIN cachedApplicationSwordDir.reset(new QDir(wDir)); // application sword dir for Windows only +#if !defined BT_MINI && !defined BT_MOBILE if (!cachedApplicationSwordDir->cd("share/sword") || !cachedApplicationSwordDir->isReadable()) { qWarning() << "Cannot find sword directory relative to" << QCoreApplication::applicationDirPath(); return false; } +#endif +#if !defined Q_OS_WINCE && !defined BT_MOBILE && !defined Q_OS_WINRT cachedSharedSwordDir.reset(new QDir(qgetenv("ALLUSERSPROFILE"))); // sword dir for Windows only if (!cachedSharedSwordDir->cd("Application Data")) { qWarning() << "Cannot find ALLUSERSPROFILE\\Application Data"; @@ -93,6 +116,7 @@ bool initDirectoryCache() { } } #endif +#endif #ifdef Q_OS_MAC cachedSwordLocalesDir.reset(new QDir(wDir)); // application sword dir for Windows only @@ -102,13 +126,18 @@ bool initDirectoryCache() { } #endif +#ifdef Q_OS_WINCE cachedSwordPathDir.reset(new QDir(wDir)); - char* swordPath = qgetenv(SWORD_PATH).data(); - if (swordPath != 0) { - cachedSwordPathDir.reset(new QDir(swordPath)); +#elif defined (ANDROID) +#else + cachedSwordPathDir.reset(new QDir()); + auto swordPath(qgetenv(SWORD_PATH)); + if (swordPath.data()) { + cachedSwordPathDir.reset(new QDir(swordPath.data())); // We unset the SWORD_PATH so libsword finds paths correctly qputenv(SWORD_PATH, ""); } +#endif cachedIconDir.reset(new QDir(wDir)); // Icon dir if (!cachedIconDir->cd("share/bibletime/icons") || !cachedIconDir->isReadable()) { @@ -116,6 +145,7 @@ bool initDirectoryCache() { return false; } +#ifndef BT_MINI cachedJavascriptDir.reset(new QDir(wDir)); if (!cachedJavascriptDir->cd("share/bibletime/javascript") || !cachedJavascriptDir->isReadable()) { qWarning() << "Cannot find javascript directory relative to" << wDir.absolutePath(); @@ -133,6 +163,7 @@ bool initDirectoryCache() { qWarning() << "Cannot find pics directory relative to" << wDir.absolutePath(); return false; } +#endif cachedLocaleDir.reset(new QDir(wDir)); if (!cachedLocaleDir->cd("share/bibletime/locale")) { @@ -143,6 +174,7 @@ bool initDirectoryCache() { QString localeName(QLocale::system().name()); QString langCode(localeName.section('_', 0, 0)); +#ifndef BT_MINI cachedHandbookDir.reset(new QDir(wDir)); if (!cachedHandbookDir->cd("share/bibletime/docs/handbook/" + localeName)) { if (!cachedHandbookDir->cd("share/bibletime/docs/handbook/" + langCode)) { @@ -162,6 +194,7 @@ bool initDirectoryCache() { } } } +#endif cachedDisplayTemplatesDir.reset(new QDir(wDir)); //display templates dir if (!cachedDisplayTemplatesDir->cd("share/bibletime/display-templates/")) { @@ -169,7 +202,36 @@ bool initDirectoryCache() { return false; } +#ifdef BT_MOBILE + cachedQmlDir.reset(new QDir(wDir)); //qml files dir + if (!cachedQmlDir->cd("share/bibletime/qml/")) { + qWarning() << "Cannot find qml relative to" << wDir.absolutePath(); + return false; + } +#endif + +#ifdef Q_OS_WINRT + cachedUserHomeDir.reset(new QDir("")); +#elif defined (Q_OS_WIN) && !defined(Q_OS_WIN32) + cachedUserHomeDir.reset(new QDir(QCoreApplication::applicationDirPath())); +#elif defined(ANDROID) + cachedUserHomeDir.reset(new QDir(qgetenv("EXTERNAL_STORAGE"))); + if(!cachedUserHomeDir->exists() || !cachedUserHomeDir->isReadable()) + { + qWarning() << "No external storage found, use application home."; + cachedUserHomeDir->setPath(QDir::homePath()); + } +#elif defined Q_OS_SYMBIAN + cachedUserHomeDir.reset(new QDir(QCoreApplication::applicationDirPath()[0] + ":\\")); + if (!cachedUserHomeDir->cd("data")) { + if(!cachedUserHomeDir->mkpath("data") || !cachedUserHomeDir->cd("data")) { + qWarning() << "Could not create user home directory" << cachedUserHomeDir->absolutePath(); + return false; + } + } +#else cachedUserHomeDir.reset(new QDir(qgetenv("HOME"))); +#endif cachedUserBaseDir.reset(new QDir(*cachedUserHomeDir)); if (!cachedUserBaseDir->cd(BIBLETIME)) { @@ -180,12 +242,20 @@ bool initDirectoryCache() { } cachedUserHomeSwordDir.reset(new QDir(*cachedUserHomeDir)); +#if defined(Q_OS_WIN) && !defined(Q_OS_WIN32) +#else if (!cachedUserHomeSwordDir->cd(SWORD_DIR)) { if (!cachedUserHomeSwordDir->mkpath(SWORD_DIR) || !cachedUserHomeSwordDir->cd(SWORD_DIR)) { qWarning() << "Could not create user home " << SWORD_DIR << " directory."; return false; } } +#endif + +#if defined Q_OS_ANDROID || defined Q_OS_SYMBIAN + // help for SWMgr to find the right place + qputenv(SWORD_PATH, cachedUserHomeSwordDir->absolutePath().toLocal8Bit()); +#endif cachedUserHomeSwordModsDir.reset(new QDir(*cachedUserHomeSwordDir)); if (!cachedUserHomeSwordModsDir->cd("mods.d")) { @@ -257,17 +327,19 @@ void removeRecursive(const QString &dir) { /** Returns the size of the directory including the size of all it's files and it's subdirs. */ -unsigned long getDirSizeRecursive(const QString &dir) { +size_t getDirSizeRecursive(QString const & dir) { //Check for validity of argument QDir d(dir); - if (!d.exists()) return 0; + if (!d.exists()) + return 0u; - unsigned long size = 0; + size_t size = 0u; //First get the size of all files int this folder d.setFilter(QDir::Files); const QFileInfoList infoList = d.entryInfoList(); for (QFileInfoList::const_iterator it = infoList.begin(); it != infoList.end(); ++it) { + BT_ASSERT(it->size() > 0); size += it->size(); } @@ -283,29 +355,6 @@ unsigned long getDirSizeRecursive(const QString &dir) { return size; } -/**Recursively copies a directory, overwriting existing files*/ -void copyRecursive(const QString &src, const QString &dest) { - QDir srcDir(src); - QDir destDir(dest); - //Copy files - QStringList files = srcDir.entryList(QDir::Files); - for (QStringList::iterator it = files.begin(); it != files.end(); ++it) { - QFile currFile(src + "/" + *it); - QString newFileLoc = dest + "/" + *it; - QFile newFile(newFileLoc); - newFile.remove(); - currFile.copy(newFileLoc); - } - QStringList dirs = srcDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); - for (QStringList::iterator it = dirs.begin(); it != dirs.end(); ++it) { - QString temp = *it; - if (!destDir.cd(*it)) { - destDir.mkdir(*it); - } - copyRecursive(src + "/" + *it, dest + "/" + *it); - } -} - QString convertDirSeparators(const QString& path) { QString result = path; #ifdef Q_OS_WIN @@ -320,7 +369,9 @@ QString convertDirSeparators(const QString& path) { const QDir &getApplicationSwordDir() { return *cachedApplicationSwordDir; } +#endif +#if defined Q_OS_WIN || defined Q_OS_ANDROID const QDir &getSharedSwordDir() { return *cachedSharedSwordDir; } @@ -369,6 +420,13 @@ const QDir &getDisplayTemplatesDir() { return *cachedDisplayTemplatesDir; } +const QDir &getQmlDir() { +#ifndef BT_MOBILE + BT_ASSERT(false && "Qml files currently required for BibleTime Mobile frontend only."); +#endif + return *cachedQmlDir; +} + const QDir &getUserBaseDir() { return *cachedUserBaseDir; } diff --git a/src/util/directory.h b/src/util/directory.h index 447cabf..78721f9 100644 --- a/src/util/directory.h +++ b/src/util/directory.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -48,30 +48,24 @@ void removeRecursive(const QString &dir); * * @return The size of the dir in bytes */ -unsigned long getDirSizeRecursive(const QString &dir); - -/** Recursively copies one directory into another. This WILL OVERWRITE - * any existing files of the same name, and WILL NOT handle symlinks. - * - * This probably won't need to be used for large directory structures. - */ -void copyRecursive(const QString &src, const QString &dest); +size_t getDirSizeRecursive(QString const & dir); /** Convert directory path separators to those for each platform * Windows = "\", Others = "/" */ QString convertDirSeparators(const QString& path); -#ifdef Q_OS_WIN // Windows only directories +#ifdef Q_OS_WIN // Windows only directory /** Return the path to the sword dir., Windows only C:\Program Files\BibleTime\share\sword */ const QDir &getApplicationSwordDir(); +#endif +#if defined Q_OS_WIN || defined Q_OS_ANDROID /** Return the path to the %ALLUSERSPROFILE%\Sword directory */ const QDir &getSharedSwordDir(); - #endif #ifdef Q_OS_MAC // Mac only directories @@ -110,6 +104,9 @@ const QDir &getHowtoDir(); /** Return the path to the default display template files. */ const QDir &getDisplayTemplatesDir(); +/** Return the path to qml files. */ +const QDir &getQmlDir(); + /** Return the path to the user's home directory. %APPDATA% on Windows $HOME on linux */ diff --git a/src/util/geticon.cpp b/src/util/geticon.cpp deleted file mode 100644 index 5658798..0000000 --- a/src/util/geticon.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/********* -* -* 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 "geticon.h" - -#include <QDebug> -#include <QFile> -#include <QMap> -#include "util/directory.h" - -namespace util { - -static QMap<QString, QIcon> iconCache; -static const QIcon nullIcon; - -const QIcon& getIcon(const QString & name) { - QString plainName(name); - if (plainName.endsWith(".svg", Qt::CaseInsensitive)) - plainName.chop(4); - - const QMap<QString, QIcon>::const_iterator i = iconCache.find(plainName); - if (i != iconCache.end()) - return *i; - - const QString iconDir = util::directory::getIconDir().canonicalPath(); - QString iconFileName = iconDir + "/" + plainName + ".svg"; - if (QFile(iconFileName).exists()) - return *iconCache.insert(plainName, QIcon(iconFileName)); - - iconFileName = iconDir + "/" + plainName + ".png"; - if (QFile(iconFileName).exists()) - return *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 nullIcon; -} - -void clearIconCache() { - iconCache.clear(); -} -} diff --git a/src/util/geticon.h b/src/util/geticon.h deleted file mode 100644 index 97a8c84..0000000 --- a/src/util/geticon.h +++ /dev/null @@ -1,30 +0,0 @@ -/********* -* -* 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 GETICON_H -#define GETICON_H - -#include <QIcon> -#include <QString> - -namespace util { - - /** - \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); - - void clearIconCache(); -} - -#endif diff --git a/src/util/htmlescape.h b/src/util/htmlescape.h deleted file mode 100644 index 875cfaa..0000000 --- a/src/util/htmlescape.h +++ /dev/null @@ -1,33 +0,0 @@ -/********* -* -* 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_HTMLESCAPE_H -#define UTIL_HTMLESCAPE_H - -#include <QString> -#if QT_VERSION < 0x050000 -#include <QTextDocument> -#endif - - -namespace util { - -inline QString htmlEscape(const QString & str) { -#if QT_VERSION < 0x050000 - return Qt::escape(str); -#else - return str.toHtmlEscaped(); -#endif -} - -} /* namespace util { */ - -#endif /* UTIL_HTMLESCAPE_H */ diff --git a/src/util/macros.h b/src/util/macros.h index 853d5c7..fa9be0b 100644 --- a/src/util/macros.h +++ b/src/util/macros.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ diff --git a/src/util/tool.cpp b/src/util/tool.cpp index ca8024a..a54681d 100644 --- a/src/util/tool.cpp +++ b/src/util/tool.cpp @@ -2,12 +2,12 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ -#include "util/tool.h" +#include "tool.h" #include <QApplication> #include <QFile> @@ -16,13 +16,13 @@ #include <QRegExp> #include <QTextStream> #include <QWidget> -#include "backend/drivers/cswordmoduleinfo.h" -#include "backend/managers/cswordbackend.h" -#include "bibletimeapp.h" -#include "frontend/messagedialog.h" -#include "util/cresmgr.h" -#include "util/directory.h" -#include "util/geticon.h" +#include "../backend/drivers/cswordmoduleinfo.h" +#include "../backend/managers/cswordbackend.h" +#include "../bibletimeapp.h" +#include "../frontend/messagedialog.h" +#include "btassert.h" +#include "cresmgr.h" +#include "directory.h" namespace util { @@ -36,14 +36,14 @@ bool savePlainFile(const QString & filename, const bool forceOverwrite, QTextCodec * const fileCodec) { - Q_ASSERT(fileCodec); - Q_ASSERT(!filename.isEmpty()); + BT_ASSERT(fileCodec); + BT_ASSERT(!filename.isEmpty()); QFile saveFile(filename); if (saveFile.exists()) { if (!forceOverwrite - && message::showQuestion(0, QObject::tr("Overwrite File?"), + && message::showQuestion(nullptr, QObject::tr("Overwrite File?"), QString::fromLatin1("<qt><b>%1</b><br/>%2</qt>") .arg( QObject::tr("The file already exists.") ) .arg( QObject::tr("Do you want to overwrite it?")), @@ -66,13 +66,13 @@ bool savePlainFile(const QString & filename, if (saveFile.error() == QFile::NoError) return true; - QMessageBox::critical(0, QObject::tr("Error"), + QMessageBox::critical(nullptr, QObject::tr("Error"), QString::fromLatin1("<qt>%1<br/><b>%2</b></qt>") .arg(QObject::tr("Error while writing to file.")) .arg(QObject::tr("Please check that enough disk space is available."))); } else { - QMessageBox::critical(0, QObject::tr("Error"), + QMessageBox::critical(nullptr, QObject::tr("Error"), QString::fromLatin1("<qt>%1<br/><b>%2</b></qt>") .arg(QObject::tr("The file couldn't be opened for saving.")) .arg(QObject::tr("Please check permissions etc."))); @@ -81,57 +81,41 @@ bool savePlainFile(const QString & filename, return false; } - -QIcon getIconForModule(const CSwordModuleInfo * const module) { - return util::getIcon(getIconNameForModule(module)); -} - -QString getIconNameForModule(const CSwordModuleInfo * const module) { - //qDebug() << "util::tool::getIconNameForModule"; +QIcon const & getIconForModule(const CSwordModuleInfo * const module) { if (!module) - return CResMgr::modules::book::icon_locked; + return CResMgr::modules::book::icon_locked(); if (module->category() == CSwordModuleInfo::Cult) - return "stop.svg"; + return CResMgr::modules::icon_cult(); switch (module->type()) { case CSwordModuleInfo::Bible: if (module->isLocked()) - return CResMgr::modules::bible::icon_locked; - else - return CResMgr::modules::bible::icon_unlocked; - break; + return CResMgr::modules::bible::icon_locked(); + return CResMgr::modules::bible::icon_unlocked(); case CSwordModuleInfo::Lexicon: if (module->isLocked()) - return CResMgr::modules::lexicon::icon_locked; - else - return CResMgr::modules::lexicon::icon_unlocked; - break; + return CResMgr::modules::lexicon::icon_locked(); + return CResMgr::modules::lexicon::icon_unlocked(); case CSwordModuleInfo::Commentary: if (module->isLocked()) - return CResMgr::modules::commentary::icon_locked; - else - return CResMgr::modules::commentary::icon_unlocked; - break; + return CResMgr::modules::commentary::icon_locked(); + return CResMgr::modules::commentary::icon_unlocked(); case CSwordModuleInfo::GenericBook: if (module->isLocked()) - return CResMgr::modules::book::icon_locked; - else - return CResMgr::modules::book::icon_unlocked; - break; + return CResMgr::modules::book::icon_locked(); + return CResMgr::modules::book::icon_unlocked(); case CSwordModuleInfo::Unknown: //fallback default: if (module->isLocked()) - return CResMgr::modules::book::icon_locked; - else - return CResMgr::modules::book::icon_unlocked; - break; + return CResMgr::modules::book::icon_locked(); + return CResMgr::modules::book::icon_unlocked(); } - return CResMgr::modules::book::icon_unlocked; + return CResMgr::modules::book::icon_unlocked(); } QLabel * explanationLabel(QWidget * const parent, diff --git a/src/util/tool.h b/src/util/tool.h index cb59495..25117f9 100644 --- a/src/util/tool.h +++ b/src/util/tool.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2014 by the BibleTime developers. +* Copyright 1999-2016 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -44,13 +44,7 @@ bool savePlainFile(const QString & filename, \param[in] module the module whose icon to return. \returns the icon used for the a module. */ -QIcon getIconForModule(const CSwordModuleInfo * module); - -/** - \param[in] module the module whose icon name to return. - \returns the icon name used for the a module. -*/ -QString getIconNameForModule(const CSwordModuleInfo * module); +QIcon const & getIconForModule(const CSwordModuleInfo * module); /** Creates a new explanation label. |