summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRoberto C. Sanchez <roberto@connexer.com>2014-10-21 22:48:27 -0400
committerRoberto C. Sanchez <roberto@connexer.com>2014-10-21 22:48:27 -0400
commitdd2f7ce46df53f2c377c02d1bf4df8adcf092072 (patch)
tree51d4bd5d66a45a24784695c4e99b452b417dc3d1 /src
parentb954e6dbcceaba3b50aca624e1bddc6db4830829 (diff)
Imported Upstream version 2.3
Diffstat (limited to 'src')
-rw-r--r--src/backend/bookshelfmodel/btbookshelfmodel.cpp184
-rw-r--r--src/backend/bookshelfmodel/btbookshelfmodel.h67
-rw-r--r--src/backend/bookshelfmodel/btbookshelftreemodel.cpp474
-rw-r--r--src/backend/bookshelfmodel/btbookshelftreemodel.h114
-rw-r--r--src/backend/bookshelfmodel/btcheckstatefilterproxymodel.cpp70
-rw-r--r--src/backend/bookshelfmodel/btcheckstatefilterproxymodel.h47
-rw-r--r--src/backend/bookshelfmodel/btmodulenamefilterproxymodel.cpp43
-rw-r--r--src/backend/bookshelfmodel/btmodulenamefilterproxymodel.h34
-rw-r--r--src/backend/bookshelfmodel/categoryitem.cpp23
-rw-r--r--src/backend/bookshelfmodel/categoryitem.h54
-rw-r--r--src/backend/bookshelfmodel/distributionitem.cpp23
-rw-r--r--src/backend/bookshelfmodel/distributionitem.h43
-rw-r--r--src/backend/bookshelfmodel/item.cpp57
-rw-r--r--src/backend/bookshelfmodel/item.h170
-rw-r--r--src/backend/bookshelfmodel/languageitem.cpp23
-rw-r--r--src/backend/bookshelfmodel/languageitem.h50
-rw-r--r--src/backend/bookshelfmodel/moduleitem.cpp25
-rw-r--r--src/backend/bookshelfmodel/moduleitem.h41
-rw-r--r--src/backend/keys/cswordversekey.cpp7
-rw-r--r--src/backend/rendering/cdisplayrendering.cpp5
-rw-r--r--src/bibletime.cpp53
-rw-r--r--src/bibletime.h13
-rw-r--r--src/bibletime_init.cpp25
-rw-r--r--src/bibletime_slots.cpp1
-rw-r--r--src/frontend/bookshelfmanager/indexpage/btindexpage.cpp14
-rw-r--r--src/frontend/btbookshelfdockwidget.cpp300
-rw-r--r--src/frontend/btbookshelfdockwidget.h94
-rw-r--r--src/frontend/displaywindow/btactioncollection.cpp9
-rw-r--r--src/frontend/displaywindow/cbookreadwindow.cpp5
-rw-r--r--src/frontend/displaywindow/cdisplaywindow.cpp31
-rw-r--r--src/frontend/displaywindow/cdisplaywindow.h1
-rw-r--r--src/frontend/displaywindow/chtmlwritewindow.cpp4
-rw-r--r--src/frontend/displaywindow/clexiconreadwindow.cpp4
-rw-r--r--src/frontend/displaywindow/cmodulechooserbar.cpp2
-rw-r--r--src/frontend/displaywindow/cplainwritewindow.cpp2
-rw-r--r--src/frontend/keychooser/ckeychooserwidget.cpp138
-rw-r--r--src/frontend/keychooser/clexiconkeychooser.cpp1
-rw-r--r--src/frontend/keychooser/versekeychooser/cbiblekeychooser.cpp1
-rw-r--r--src/frontend/keychooser/versekeychooser/ckeyreferencewidget.cpp99
-rw-r--r--src/frontend/keychooser/versekeychooser/ckeyreferencewidget.h4
-rw-r--r--src/frontend/mainindex/bookmarks/cbookmarkindex.h1
-rw-r--r--src/frontend/mainindex/bookshelf/btindexitem.h1
-rw-r--r--src/frontend/mainindex/bookshelf/cbookshelfindex.h1
-rw-r--r--src/frontend/mainindex/btbookshelfview.cpp105
-rw-r--r--src/frontend/mainindex/btbookshelfview.h42
-rw-r--r--src/frontend/mainindex/cmainindex.cpp36
-rw-r--r--src/frontend/mainindex/cmainindex.h57
-rw-r--r--src/main.cpp3
-rw-r--r--src/util/cresmgr.cpp2
49 files changed, 2393 insertions, 210 deletions
diff --git a/src/backend/bookshelfmodel/btbookshelfmodel.cpp b/src/backend/bookshelfmodel/btbookshelfmodel.cpp
new file mode 100644
index 0000000..6764a88
--- /dev/null
+++ b/src/backend/bookshelfmodel/btbookshelfmodel.cpp
@@ -0,0 +1,184 @@
+/*********
+*
+* In the name of the Father, and of the Son, and of the Holy Spirit.
+*
+* This file is part of BibleTime's source code, http://www.bibletime.info/.
+*
+* Copyright 1999-2009 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 <QSet>
+#include "util/cresmgr.h"
+#include "util/directoryutil.h"
+
+BtBookshelfModel::BtBookshelfModel(QObject *parent)
+ : QAbstractListModel(parent)
+{
+ // Intentionally empty
+}
+
+BtBookshelfModel::~BtBookshelfModel() {
+ // Intentionally empty
+}
+
+int BtBookshelfModel::rowCount(const QModelIndex &parent) const {
+ return m_data.size();
+}
+
+QVariant BtBookshelfModel::data(const QModelIndex &index, int role) const {
+ if (!index.isValid() || index.column() != 0 || index.parent().isValid()) {
+ return QVariant();
+ }
+ int row(index.row());
+ if (row >= m_data.size()) return QVariant();
+
+ switch (role) {
+ case ModuleNameRole: // Qt::DisplayRole
+ return m_data.at(row)->name();
+ case ModuleIconRole: // Qt::DecorationRole
+ return categoryIcon(m_data.at(row)->category());
+ case ModulePointerRole:
+ return qVariantFromValue((void*) m_data.at(row));
+ default:
+ return QVariant();
+ }
+}
+
+QVariant BtBookshelfModel::headerData(int section, Qt::Orientation orientation,
+ int role) const
+{
+ if (role == Qt::DisplayRole && orientation == Qt::Horizontal &&
+ section == 0)
+ {
+ return tr("Module");
+ }
+
+ return QVariant();
+}
+
+QIcon BtBookshelfModel::categoryIcon(const CSwordModuleInfo::Category &category)
+{
+ typedef util::filesystem::DirectoryUtil DU;
+
+ switch (category) {
+ case CSwordModuleInfo::Bibles:
+ return DU::getIcon(CResMgr::categories::bibles::icon);
+ case CSwordModuleInfo::Commentaries:
+ return DU::getIcon(CResMgr::categories::commentaries::icon);
+ case CSwordModuleInfo::Books:
+ return DU::getIcon(CResMgr::categories::books::icon);
+ case CSwordModuleInfo::Cult:
+ return DU::getIcon(CResMgr::categories::cults::icon);
+ case CSwordModuleInfo::Images:
+ return DU::getIcon(CResMgr::categories::images::icon);
+ case CSwordModuleInfo::DailyDevotional:
+ return DU::getIcon(CResMgr::categories::dailydevotional::icon);
+ case CSwordModuleInfo::Lexicons:
+ return DU::getIcon(CResMgr::categories::lexicons::icon);
+ case CSwordModuleInfo::Glossary:
+ return DU::getIcon(CResMgr::categories::glossary::icon);
+ case CSwordModuleInfo::UnknownCategory:
+ default:
+ return QIcon();
+ }
+}
+
+QString BtBookshelfModel::categoryName(
+ const CSwordModuleInfo::Category &category)
+{
+ switch (category) {
+ case CSwordModuleInfo::Bibles:
+ return tr("Bibles");
+ case CSwordModuleInfo::Commentaries:
+ return tr("Commentaries");
+ case CSwordModuleInfo::Books:
+ return tr("Books");
+ case CSwordModuleInfo::Cult:
+ return tr("Cults/Unorthodox");
+ case CSwordModuleInfo::Images:
+ return tr("Maps and Images");
+ case CSwordModuleInfo::DailyDevotional:
+ return tr("Daily Devotionals");
+ case CSwordModuleInfo::Lexicons:
+ return tr("Lexicons and Dictionaries");
+ case CSwordModuleInfo::Glossary:
+ return tr("Glossaries");
+ default:
+ return tr("Unknown");
+ }
+}
+
+QString BtBookshelfModel::languageName(
+ const CLanguageMgr::Language *language)
+{
+ return language->translatedName();
+}
+
+void BtBookshelfModel::clear() {
+ beginRemoveRows(QModelIndex(), 0, m_data.size() - 1);
+ m_data.clear();
+ endRemoveRows();
+}
+
+void BtBookshelfModel::addModule(CSwordModuleInfo * const module) {
+ Q_ASSERT(module != 0);
+
+ if (m_data.contains(module)) return;
+
+ const int index(m_data.size());
+ beginInsertRows(QModelIndex(), index, index);
+ m_data.append(module);
+ endInsertRows();
+}
+
+void BtBookshelfModel::addModules(const QList<CSwordModuleInfo *> &modules) {
+ addModules(modules.toSet());
+}
+
+void BtBookshelfModel::addModules(const QSet<CSwordModuleInfo *> &modules) {
+ QList<CSwordModuleInfo *> newModules;
+ Q_FOREACH(CSwordModuleInfo *module, modules) {
+ if (!m_data.contains(module)) {
+ newModules.append(module);
+ }
+ }
+
+ if (newModules.isEmpty()) return;
+
+ beginInsertRows(QModelIndex(), m_data.size(),
+ m_data.size() + newModules.size() - 1);
+ m_data.append(newModules);
+ endInsertRows();
+}
+
+void BtBookshelfModel::removeModule(CSwordModuleInfo * const module) {
+ const int index(m_data.indexOf(module));
+ if (index == -1) return;
+
+ beginRemoveRows(QModelIndex(), index, index);
+ m_data.removeAt(index);
+ endRemoveRows();
+}
+
+void BtBookshelfModel::removeModules(const QList<CSwordModuleInfo *> &modules) {
+ removeModules(modules.toSet());
+}
+
+void BtBookshelfModel::removeModules(const QSet<CSwordModuleInfo *> &modules) {
+ // This is inefficient, since signals are emitted for each removed module:
+ Q_FOREACH(CSwordModuleInfo *module, modules) {
+ removeModule(module);
+ }
+}
+
+CSwordModuleInfo* BtBookshelfModel::getModule(const QString &name) const {
+ Q_FOREACH(CSwordModuleInfo *module, m_data) {
+ if (module->name() == name) return module;
+ }
+ return 0;
+}
diff --git a/src/backend/bookshelfmodel/btbookshelfmodel.h b/src/backend/bookshelfmodel/btbookshelfmodel.h
new file mode 100644
index 0000000..c268d2c
--- /dev/null
+++ b/src/backend/bookshelfmodel/btbookshelfmodel.h
@@ -0,0 +1,67 @@
+/*********
+*
+* 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-2009 by the BibleTime developers.
+* The BibleTime source code is licensed under the GNU General Public License
+* version 2.0.
+*
+**********/
+
+#ifndef BTBOOKSHELFMODEL_H
+#define BTBOOKSHELFMODEL_H
+
+#include <QAbstractListModel>
+
+#include "backend/drivers/cswordmoduleinfo.h"
+
+class BtBookshelfModel: public QAbstractListModel {
+ Q_OBJECT
+ public:
+ enum ModuleRole {
+ ModuleNameRole = Qt::DisplayRole,
+ ModuleIconRole = Qt::DecorationRole,
+ ModulePointerRole = Qt::UserRole,
+ ModuleCategoryRole = Qt::UserRole + 1,
+ ModuleLanguageRole = Qt::UserRole + 2,
+ UserRole = Qt::UserRole + 100
+ };
+
+ BtBookshelfModel(QObject *parent = 0);
+ virtual ~BtBookshelfModel();
+
+ virtual int rowCount(const QModelIndex &parent) const;
+ virtual QVariant data(const QModelIndex &index, int role) const;
+ virtual QVariant headerData(int section, Qt::Orientation orientation,
+ int role = Qt::DisplayRole) const;
+
+ inline CSwordModuleInfo *module(const QModelIndex &index) const {
+ return (CSwordModuleInfo *)
+ data(index, BtBookshelfModel::ModulePointerRole)
+ .value<void *>();
+ }
+
+ static QIcon categoryIcon(const CSwordModuleInfo::Category &category);
+ static QString categoryName(const CSwordModuleInfo::Category &category);
+ static QString languageName(const CLanguageMgr::Language *language);
+
+ void clear();
+ void addModule(CSwordModuleInfo * const module);
+ void addModules(const QSet<CSwordModuleInfo *> &modules);
+ void addModules(const QList<CSwordModuleInfo *> &modules);
+ void removeModule(CSwordModuleInfo * const module);
+ void removeModules(const QSet<CSwordModuleInfo *> &modules);
+ void removeModules(const QList<CSwordModuleInfo *> &modules);
+
+ CSwordModuleInfo* getModule(const QString &name) const;
+ inline const QList<CSwordModuleInfo *> &modules() const {
+ return m_data;
+ }
+
+ protected:
+ QList<CSwordModuleInfo *> m_data;
+};
+
+#endif // BTBOOKSHELFMODEL_H
diff --git a/src/backend/bookshelfmodel/btbookshelftreemodel.cpp b/src/backend/bookshelfmodel/btbookshelftreemodel.cpp
new file mode 100644
index 0000000..47526e9
--- /dev/null
+++ b/src/backend/bookshelfmodel/btbookshelftreemodel.cpp
@@ -0,0 +1,474 @@
+/*********
+*
+* 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-2009 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 <QQueue>
+#include <QSet>
+#include "backend/bookshelfmodel/categoryitem.h"
+#include "backend/bookshelfmodel/distributionitem.h"
+#include "backend/bookshelfmodel/languageitem.h"
+#include "backend/bookshelfmodel/moduleitem.h"
+
+using namespace BookshelfModel;
+
+BtBookshelfTreeModel::BtBookshelfTreeModel(QObject *parent)
+ : QAbstractItemModel(parent), m_sourceModel(0), m_rootItem(new RootItem),
+ m_checkable(false), m_defaultChecked(false)
+{
+ m_groupingOrder.push_back(GROUP_CATEGORY);
+ m_groupingOrder.push_back(GROUP_LANGUAGE);
+}
+
+BtBookshelfTreeModel::~BtBookshelfTreeModel() {
+ delete m_rootItem;
+}
+
+int BtBookshelfTreeModel::rowCount(const QModelIndex &parent) const {
+ return getItem(parent)->children().size();
+}
+
+int BtBookshelfTreeModel::columnCount(const QModelIndex &parent) const {
+ return 1;
+}
+
+bool BtBookshelfTreeModel::hasChildren(const QModelIndex &parent) const {
+ return !getItem(parent)->children().isEmpty();
+}
+
+QModelIndex BtBookshelfTreeModel::index(int row, int column,
+ const QModelIndex &parent) const
+{
+ if (!hasIndex(row, column, parent)) return QModelIndex();
+
+ Item *parentItem(getItem(parent));
+ Item *childItem(parentItem->childAt(row));
+ if (childItem != 0) {
+ return createIndex(row, column, childItem);
+ } else {
+ return QModelIndex();
+ }
+}
+
+QModelIndex BtBookshelfTreeModel::parent(const QModelIndex &index) const {
+ if (!index.isValid()) return QModelIndex();
+
+ Item *childItem(static_cast<Item*>(index.internalPointer()));
+ Q_ASSERT(childItem != 0);
+ Item *parentItem(childItem->parent());
+ Q_ASSERT(parentItem != 0);
+
+ if (parentItem == m_rootItem) {
+ return QModelIndex();
+ }
+ return createIndex(parentItem->childIndex(), 0, parentItem);
+}
+
+QVariant BtBookshelfTreeModel::data(const QModelIndex &index, int role) const {
+ typedef util::filesystem::DirectoryUtil DU;
+
+ if (!index.isValid() || index.column() != 0) {
+ return QVariant();
+ }
+
+ Item *i(static_cast<Item*>(index.internalPointer()));
+ Q_ASSERT(i != 0);
+ switch (role) {
+ case Qt::DisplayRole:
+ return i->name();
+ case Qt::CheckStateRole:
+ if (!m_checkable) break;
+ case BtBookshelfTreeModel::CheckStateRole:
+ return i->checkState();
+ case Qt::DecorationRole:
+ return i->icon();
+ case BtBookshelfModel::ModulePointerRole:
+ if (i->type() == Item::ITEM_MODULE) {
+ ModuleItem *mi(dynamic_cast<ModuleItem *>(i));
+ if (mi != 0) {
+ return qVariantFromValue((void*) mi->moduleInfo());
+ }
+ }
+ return 0;
+ default:
+ break;
+ }
+ return QVariant();
+}
+
+bool BtBookshelfTreeModel::setData(const QModelIndex &itemIndex,
+ const QVariant &value,
+ int role)
+{
+ typedef QPair<Item *, QModelIndex> IP;
+
+ if (role == Qt::CheckStateRole) {
+ bool ok;
+ Qt::CheckState newState((Qt::CheckState) value.toInt(&ok));
+ if (ok && newState != Qt::PartiallyChecked) {
+ Item *i(static_cast<Item*>(itemIndex.internalPointer()));
+ Q_ASSERT(i != 0);
+ // Recursively (un)check all children:
+ QList<IP> q;
+ q.append(IP(i, itemIndex));
+ while (!q.isEmpty()) {
+ const IP p(q.takeFirst());
+ Item *item(p.first);
+ item->setCheckState(newState);
+ emit dataChanged(p.second, p.second);
+ const QList<Item*> &children(item->children());
+ for (int i(0); i < children.size(); i++) {
+ q.append(IP(children.at(i), index(i, 0, p.second)));
+ }
+ }
+
+ // Change check state of the item itself
+ i->setCheckState(newState);
+ emit dataChanged(itemIndex, itemIndex);
+
+ // Recursively change parent check states.
+ resetParentCheckStates(itemIndex.parent());
+
+ return true;
+ } // if (ok && newState != Qt::PartiallyChecked)
+ } // if (role == Qt::CheckStateRole)
+ return false;
+}
+
+Qt::ItemFlags BtBookshelfTreeModel::flags(const QModelIndex &index) const {
+ if (!index.isValid()) return 0;
+
+ Qt::ItemFlags f(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
+
+ if (m_checkable) {
+ f |= Qt::ItemIsUserCheckable;
+
+ Item *i(static_cast<Item*>(index.internalPointer()));
+ Q_ASSERT(i != 0);
+
+ if (i->type() != Item::ITEM_MODULE) {
+ f |= Qt::ItemIsTristate;
+ }
+ }
+
+ return f;
+}
+
+QVariant BtBookshelfTreeModel::headerData(int section,
+ Qt::Orientation orientation,
+ int role) const
+{
+ if (orientation == Qt::Horizontal) {
+ return m_sourceModel->headerData(section, orientation, role);
+ }
+ return QVariant();
+}
+
+void BtBookshelfTreeModel::setSourceModel(QAbstractListModel *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)));
+ beginRemoveRows(QModelIndex(), 0, m_rootItem->children().size() - 1);
+ delete m_rootItem;
+ m_modules.clear();
+ m_rootItem = new RootItem;
+ endRemoveRows();
+ }
+
+ 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)));
+
+ BtBookshelfModel *m(dynamic_cast<BtBookshelfModel*>(sourceModel));
+ if (m != 0) {
+ Q_FOREACH(CSwordModuleInfo *module, m->modules()) {
+ addModule(module, m_defaultChecked);
+ }
+ } else {
+ for (int i(0); i < sourceModel->rowCount(); i++) {
+ CSwordModuleInfo *module(
+ static_cast<CSwordModuleInfo *>(
+ sourceModel->data(
+ sourceModel->index(i),
+ BtBookshelfModel::ModulePointerRole
+ ).value<void*>()
+ )
+ );
+ Q_ASSERT(module != 0);
+ addModule(
+ module,
+ m_defaultChecked
+ );
+ }
+ }
+ }
+}
+
+void BtBookshelfTreeModel::setGroupingOrder(const Grouping &groupingOrder) {
+ if (m_groupingOrder == groupingOrder) return;
+ m_groupingOrder = groupingOrder;
+
+ if (m_sourceModel != 0) {
+ QSet<CSwordModuleInfo*> checked(checkedModules().toSet());
+ beginRemoveRows(QModelIndex(), 0, m_rootItem->children().size() - 1);
+ delete m_rootItem;
+ m_modules.clear();
+ m_rootItem = new RootItem;
+ endRemoveRows();
+
+ BtBookshelfModel *m(dynamic_cast<BtBookshelfModel*>(m_sourceModel));
+ if (m != 0) {
+ Q_FOREACH(CSwordModuleInfo *module, m->modules()) {
+ addModule(module, checked.contains(module));
+ }
+ } else {
+ for (int i(0); i < m_sourceModel->rowCount(); i++) {
+ CSwordModuleInfo *module(
+ static_cast<CSwordModuleInfo *>(
+ m_sourceModel->data(
+ m_sourceModel->index(i),
+ BtBookshelfModel::ModulePointerRole
+ ).value<void*>()
+ )
+ );
+ Q_ASSERT(module != 0);
+ addModule(module, checked.contains(module));
+ }
+ }
+ }
+}
+
+void BtBookshelfTreeModel::setCheckable(bool checkable) {
+ if (m_checkable == checkable) return;
+ m_checkable = checkable;
+ if (m_sourceModel != 0) {
+ QModelIndexList queue;
+ queue.append(QModelIndex());
+ do {
+ QModelIndex parent(queue.takeFirst());
+ int numChildren(rowCount(parent));
+ emit dataChanged(index(0, 0, parent),
+ index(numChildren - 1, 0, parent));
+ for (int i(0); i < numChildren; i++) {
+ QModelIndex childIndex(index(i, 0, parent));
+ if (rowCount(childIndex) > 0) {
+ queue.append(childIndex);
+ }
+ }
+ } while (!queue.isEmpty());
+ }
+}
+
+QList<CSwordModuleInfo*> BtBookshelfTreeModel::checkedModules() const {
+ typedef ModuleItemMap::const_iterator MMCI;
+
+ QList<CSwordModuleInfo*> modules;
+ for (MMCI it(m_modules.constBegin()); it != m_modules.constEnd(); it++) {
+ if (it.value()->checkState() == Qt::Checked) {
+ modules.append(it.key());
+ }
+ }
+ return modules;
+}
+
+void BtBookshelfTreeModel::addModule(CSwordModuleInfo *module, bool checked) {
+ if (m_modules.contains(module)) return;
+ Grouping g(m_groupingOrder);
+ addModule(module, QModelIndex(), g, checked);
+
+ /**
+ \bug Calling reset() shouldn't be necessary here, but omitting it will
+ will break things like switching to a grouped layout or installing
+ new modules. As a side effect, all attached views will also reset
+ themselves.
+ */
+ reset();
+}
+
+void BtBookshelfTreeModel::addModule(CSwordModuleInfo *module,
+ QModelIndex parentIndex,
+ Grouping &intermediateGrouping,
+ bool checked)
+{
+ Q_ASSERT(module != 0);
+
+ if (!intermediateGrouping.empty()) {
+ QModelIndex newIndex;
+ switch (intermediateGrouping.front()) {
+ case GROUP_DISTRIBUTION:
+ newIndex = getGroup<DistributionItem>(module, parentIndex);
+ break;
+ case GROUP_CATEGORY:
+ newIndex = getGroup<CategoryItem>(module, parentIndex);
+ break;
+ case GROUP_LANGUAGE:
+ newIndex = getGroup<LanguageItem>(module, parentIndex);
+ break;
+ }
+ intermediateGrouping.pop_front();
+ addModule(module, newIndex, intermediateGrouping, checked);
+ } else {
+ Item *parentItem(getItem(parentIndex));
+ ModuleItem *newItem(new ModuleItem(module));
+ newItem->setCheckState(checked ? Qt::Checked : Qt::Unchecked);
+ const int newIndex(parentItem->indexFor(newItem));
+ beginInsertRows(parentIndex, newIndex, newIndex);
+ parentItem->insertChild(newIndex, newItem);
+ m_modules.insert(module, newItem);
+ endInsertRows();
+ resetParentCheckStates(parentIndex);
+ }
+}
+
+void BtBookshelfTreeModel::removeModule(CSwordModuleInfo *module) {
+ Item *i(m_modules.value(module, 0));
+ if (i == 0) return;
+
+ // Set i to be the lowest item (including empty groups) to remove:
+ Q_ASSERT(i->parent() != 0);
+ while (i->parent() != m_rootItem && i->parent()->children().size() <= 1) {
+ i = i->parent();
+ }
+ Q_ASSERT(i != 0);
+
+ // Calculate index of parent item:
+ QModelIndex parentIndex;
+ {
+ QList<int> indexes;
+ for (Item *j(i->parent()); j != m_rootItem; j = j->parent()) {
+ Q_ASSERT(j != 0);
+ indexes.push_back(j->childIndex());
+ }
+ while (!indexes.isEmpty()) {
+ parentIndex = index(indexes.takeLast(), 0, parentIndex);
+ }
+ }
+
+ // Remove item:
+ int index(i->childIndex());
+ beginRemoveRows(parentIndex, index, index);
+ i->parent()->deleteChildAt(index);
+ m_modules.remove(module);
+ endRemoveRows();
+ resetParentCheckStates(parentIndex);
+}
+
+Item *BtBookshelfTreeModel::getItem(const QModelIndex &index) const {
+ if (index.isValid()) {
+ Item *item(static_cast<Item*>(index.internalPointer()));
+ Q_ASSERT(item != 0);
+ return item;
+ } else {
+ return m_rootItem;
+ }
+}
+
+void BtBookshelfTreeModel::resetParentCheckStates(QModelIndex parentIndex) {
+ for ( ; parentIndex.isValid(); parentIndex = parentIndex.parent()) {
+ Item *parentItem(static_cast<Item*>(parentIndex.internalPointer()));
+ Q_ASSERT(parentItem != 0);
+
+ Qt::CheckState oldState(parentItem->checkState());
+ bool haveCheckedChildren(false);
+ bool haveUncheckedChildren(false);
+ for (int i(0); i < parentItem->children().size(); i++) {
+ Qt::CheckState state(parentItem->childAt(i)->checkState());
+ if (state == Qt::PartiallyChecked) {
+ haveCheckedChildren = true;
+ haveUncheckedChildren = true;
+ break;
+ } else if (state == Qt::Checked) {
+ haveCheckedChildren = true;
+ if (haveUncheckedChildren) break;
+ } else if (state == Qt::Unchecked) {
+ haveUncheckedChildren = true;
+ if (haveCheckedChildren) break;
+ }
+ }
+
+ Qt::CheckState newState;
+ if (haveCheckedChildren) {
+ if (haveUncheckedChildren) {
+ newState = Qt::PartiallyChecked;
+ } else {
+ newState = Qt::Checked;
+ }
+ } else {
+ newState = Qt::Unchecked;
+ }
+ if (newState == oldState) break;
+
+ parentItem->setCheckState(newState);
+ emit dataChanged(parentIndex, parentIndex);
+ } // for ( ; parentIndex.isValid(); parentIndex = parentIndex.parent())
+}
+
+void BtBookshelfTreeModel::moduleDataChanged(const QModelIndex &topLeft,
+ const QModelIndex &bottomRight)
+{
+ typedef BtBookshelfModel BM;
+ static const BM::ModuleRole PR(BM::ModulePointerRole);
+
+ Q_ASSERT(!topLeft.parent().isValid());
+ Q_ASSERT(!bottomRight.parent().isValid());
+ Q_ASSERT(topLeft.column() == 0 && bottomRight.column() == 0);
+
+ for (int i(topLeft.row()); i <= bottomRight.row(); i++) {
+ QModelIndex moduleIndex(m_sourceModel->index(i, 0, topLeft.parent()));
+ QVariant data(m_sourceModel->data(moduleIndex, PR));
+ CSwordModuleInfo *module((CSwordModuleInfo *) (data.value<void*>()));
+
+ /// \todo There might be a better way to do this.
+ bool checked(m_modules.value(module)->checkState() == Qt::Checked);
+ removeModule(module);
+ addModule(module, checked);
+ }
+}
+
+void BtBookshelfTreeModel::moduleInserted(const QModelIndex &parent, int start,
+ int end)
+{
+ typedef BtBookshelfModel BM;
+ static const BM::ModuleRole PR(BM::ModulePointerRole);
+
+ for (int i(start); i <= end; i++) {
+ QModelIndex moduleIndex(m_sourceModel->index(i, 0, parent));
+ QVariant data(m_sourceModel->data(moduleIndex, PR));
+ CSwordModuleInfo *module((CSwordModuleInfo *) (data.value<void*>()));
+
+ addModule(module, m_defaultChecked);
+ }
+}
+
+void BtBookshelfTreeModel::moduleRemoved(const QModelIndex &parent, int start,
+ int end)
+{
+ typedef BtBookshelfModel BM;
+ static const BM::ModuleRole PR(BM::ModulePointerRole);
+
+ for (int i(start); i <= end; i++) {
+ QModelIndex moduleIndex(m_sourceModel->index(i, 0, parent));
+ QVariant data(m_sourceModel->data(moduleIndex, PR));
+ CSwordModuleInfo *module((CSwordModuleInfo *) (data.value<void*>()));
+
+ removeModule(module);
+ }
+}
diff --git a/src/backend/bookshelfmodel/btbookshelftreemodel.h b/src/backend/bookshelfmodel/btbookshelftreemodel.h
new file mode 100644
index 0000000..0a84ac3
--- /dev/null
+++ b/src/backend/bookshelfmodel/btbookshelftreemodel.h
@@ -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-2009 by the BibleTime developers.
+* The BibleTime source code is licensed under the GNU General Public License
+* version 2.0.
+*
+**********/
+
+#ifndef BTBOOKSHELFTREEMODEL_H
+#define BTBOOKSHELFTREEMODEL_H
+
+#include <QAbstractItemModel>
+
+#include <QMap>
+#include "backend/bookshelfmodel/btbookshelfmodel.h"
+#include "backend/bookshelfmodel/item.h"
+
+namespace BookshelfModel {
+ class ModuleItem;
+}
+class CSwordModuleInfo;
+
+class BtBookshelfTreeModel: public QAbstractItemModel {
+ Q_OBJECT
+
+ typedef QMap<CSwordModuleInfo*, BookshelfModel::ModuleItem*> ModuleItemMap;
+
+ public:
+ enum ModuleRole {
+ CheckStateRole = BtBookshelfModel::UserRole,
+ UserRole = BtBookshelfModel::UserRole + 100
+ };
+ enum Group { GROUP_CATEGORY, GROUP_LANGUAGE, GROUP_DISTRIBUTION };
+ typedef QList<Group> Grouping;
+
+ BtBookshelfTreeModel(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) 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);
+
+ void setSourceModel(QAbstractListModel *sourceModel);
+ inline QAbstractListModel *sourceModel() const { return m_sourceModel; }
+ void setGroupingOrder(const Grouping &groupingOrder);
+ inline Grouping groupingOrder() const { return m_groupingOrder; }
+ void setCheckable(bool checkable);
+ inline bool checkable() const { return m_checkable; }
+ inline void setDefaultChecked(bool defaultChecked) {
+ m_defaultChecked = defaultChecked;
+ }
+ inline bool defaultChecked() const { return m_defaultChecked; }
+
+ QList<CSwordModuleInfo*> checkedModules() const;
+
+ protected:
+ void addModule(CSwordModuleInfo *module, bool checked);
+ void addModule(CSwordModuleInfo *module, QModelIndex parentIndex,
+ Grouping &intermediateGrouping, bool checked);
+ void removeModule(CSwordModuleInfo *module);
+
+ BookshelfModel::Item *getItem(const QModelIndex &index) const;
+ void resetParentCheckStates(QModelIndex parentIndex);
+
+ template <class T>
+ QModelIndex getGroup(CSwordModuleInfo *module,
+ QModelIndex parentIndex)
+ {
+ BookshelfModel::Item *parentItem(getItem(parentIndex));
+ int groupIndex;
+ T *groupItem(parentItem->getGroupItem<T>(module, &groupIndex));
+
+ if (groupItem == 0) {
+ groupItem = new T(module);
+ groupIndex = parentItem->indexFor(groupItem);
+ beginInsertRows(parentIndex, groupIndex, groupIndex);
+ parentItem->insertChild(groupIndex, groupItem);
+ endInsertRows();
+ }
+ return index(groupIndex, 0, parentIndex);
+ }
+
+ protected slots:
+ void moduleDataChanged(const QModelIndex &topLeft,
+ const QModelIndex &bottomRight);
+ void moduleInserted(const QModelIndex &parent, int start, int end);
+ void moduleRemoved(const QModelIndex &parent, int start, int end);
+
+ protected:
+ QAbstractListModel *m_sourceModel;
+ BookshelfModel::Item *m_rootItem;
+ ModuleItemMap m_modules;
+ Grouping m_groupingOrder;
+ bool m_checkable;
+ bool m_defaultChecked;
+};
+
+#endif // BTBOOKSHELFTREEMODEL_H
diff --git a/src/backend/bookshelfmodel/btcheckstatefilterproxymodel.cpp b/src/backend/bookshelfmodel/btcheckstatefilterproxymodel.cpp
new file mode 100644
index 0000000..4d9cfd6
--- /dev/null
+++ b/src/backend/bookshelfmodel/btcheckstatefilterproxymodel.cpp
@@ -0,0 +1,70 @@
+/*********
+*
+* 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-2009 by the BibleTime developers.
+* The BibleTime source code is licensed under the GNU General Public License
+* version 2.0.
+*
+**********/
+
+#include "backend/bookshelfmodel/btcheckstatefilterproxymodel.h"
+
+BtCheckStateFilterProxyModel::BtCheckStateFilterProxyModel(QObject *parent)
+ : QSortFilterProxyModel(parent), m_enabled(true), m_showChecked(true),
+ m_showUnchecked(false), m_showPartiallyChecked(true)
+{
+ setFilterRole(Qt::CheckStateRole);
+}
+
+BtCheckStateFilterProxyModel::~BtCheckStateFilterProxyModel() {
+ // Intentionally empty
+}
+
+void BtCheckStateFilterProxyModel::setEnabled(bool enable) {
+ if (enable == m_enabled) return;
+ m_enabled = enable;
+ invalidateFilter();
+}
+
+void BtCheckStateFilterProxyModel::setShowChecked(bool show) {
+ if (m_showChecked == show) return;
+ m_showChecked = show;
+ invalidateFilter();
+}
+
+void BtCheckStateFilterProxyModel::setShowUnchecked(bool show) {
+ if (m_showUnchecked == show) return;
+ m_showUnchecked = show;
+ invalidateFilter();
+}
+
+void BtCheckStateFilterProxyModel::setShowPartiallyChecked(bool show) {
+ if (m_showPartiallyChecked == show) return;
+ m_showPartiallyChecked = show;
+ invalidateFilter();
+}
+
+bool BtCheckStateFilterProxyModel::filterAcceptsRow(int row,
+ const QModelIndex &parent) const
+{
+ typedef Qt::CheckState CS;
+
+ if (!m_enabled) return true;
+
+ QAbstractItemModel *m(sourceModel());
+
+ QModelIndex i(m->index(row, filterKeyColumn(), parent));
+ CS state((CS) m->data(i, filterRole()).toInt());
+ Q_ASSERT(state == Qt::Checked || state == Qt::Unchecked ||
+ state == Qt::PartiallyChecked);
+ if (state == Qt::Unchecked) {
+ return m_showUnchecked;
+ } else if (state == Qt::Checked) {
+ return m_showChecked;
+ } else {
+ return m_showPartiallyChecked;
+ }
+}
diff --git a/src/backend/bookshelfmodel/btcheckstatefilterproxymodel.h b/src/backend/bookshelfmodel/btcheckstatefilterproxymodel.h
new file mode 100644
index 0000000..b2081f1
--- /dev/null
+++ b/src/backend/bookshelfmodel/btcheckstatefilterproxymodel.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-2009 by the BibleTime developers.
+* The BibleTime source code is licensed under the GNU General Public License
+* version 2.0.
+*
+**********/
+
+#ifndef BTCHECKSTATEFILTERPROXYMODEL_H
+#define BTCHECKSTATEFILTERPROXYMODEL_H
+
+#include <QSortFilterProxyModel>
+
+class BtCheckStateFilterProxyModel: public QSortFilterProxyModel {
+ Q_OBJECT
+ public:
+ BtCheckStateFilterProxyModel(QObject *parent = 0);
+ virtual ~BtCheckStateFilterProxyModel();
+
+ inline bool enabled() const { return m_enabled; }
+ void setEnabled(bool enable);
+
+ inline bool showChecked() const { return m_showChecked; }
+ void setShowChecked(bool show);
+
+ inline bool showUnchecked() const { return m_showUnchecked; }
+ void setShowUnchecked(bool show);
+
+ inline bool showPartiallyChecked() const {
+ return m_showPartiallyChecked;
+ }
+ void setShowPartiallyChecked(bool show);
+
+ virtual bool filterAcceptsRow(int row, const QModelIndex &parent) const;
+
+ protected:
+ bool m_enabled;
+ bool m_showChecked;
+ bool m_showUnchecked;
+ bool m_showPartiallyChecked;
+};
+
+#endif // BTSELECTEDMODULESBOOKSHELFPROXYMODEL_H
diff --git a/src/backend/bookshelfmodel/btmodulenamefilterproxymodel.cpp b/src/backend/bookshelfmodel/btmodulenamefilterproxymodel.cpp
new file mode 100644
index 0000000..f416175
--- /dev/null
+++ b/src/backend/bookshelfmodel/btmodulenamefilterproxymodel.cpp
@@ -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-2009 by the BibleTime developers.
+* The BibleTime source code is licensed under the GNU General Public License
+* version 2.0.
+*
+**********/
+
+#include "backend/bookshelfmodel/btmodulenamefilterproxymodel.h"
+
+BtModuleNameFilterProxyModel::BtModuleNameFilterProxyModel(QObject *parent)
+ : QSortFilterProxyModel(parent), m_enabled(true)
+{
+ setFilterCaseSensitivity(Qt::CaseInsensitive);
+}
+
+BtModuleNameFilterProxyModel::~BtModuleNameFilterProxyModel() {
+ // Intentionally empty
+}
+
+bool BtModuleNameFilterProxyModel::filterAcceptsRow(int row,
+ const QModelIndex &p) const
+{
+ if (!m_enabled) return true;
+
+ const QAbstractItemModel *m(sourceModel());
+ Q_ASSERT(m != 0);
+
+ QModelIndex itemIndex(m->index(row, 0, p));
+ int numChildren(m->rowCount(itemIndex));
+ if (numChildren == 0) {
+ return QSortFilterProxyModel::filterAcceptsRow(row, p);
+ } else {
+ for (int i(0); i < numChildren; i++) {
+ if (filterAcceptsRow(i, itemIndex)) return true;
+ }
+ return false;
+ }
+}
diff --git a/src/backend/bookshelfmodel/btmodulenamefilterproxymodel.h b/src/backend/bookshelfmodel/btmodulenamefilterproxymodel.h
new file mode 100644
index 0000000..dd6f652
--- /dev/null
+++ b/src/backend/bookshelfmodel/btmodulenamefilterproxymodel.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-2009 by the BibleTime developers.
+* The BibleTime source code is licensed under the GNU General Public License
+* version 2.0.
+*
+**********/
+
+#ifndef BTMODULENAMEFILTERPROXYMODEL_H
+#define BTMODULENAMEFILTERPROXYMODEL_H
+
+#include <QSortFilterProxyModel>
+
+class BtModuleNameFilterProxyModel: public QSortFilterProxyModel {
+ Q_OBJECT
+ public:
+ BtModuleNameFilterProxyModel(QObject *parent = 0);
+ virtual ~BtModuleNameFilterProxyModel();
+
+ inline bool enabled() const { return m_enabled; }
+ void setEnabled(bool enable);
+
+ virtual bool filterAcceptsRow(int row, const QModelIndex &parent) const;
+
+ protected:
+ QString m_filter;
+ bool m_enabled;
+};
+
+#endif // BTMODULENAMEFILTERPROXYMODEL_H
diff --git a/src/backend/bookshelfmodel/categoryitem.cpp b/src/backend/bookshelfmodel/categoryitem.cpp
new file mode 100644
index 0000000..0d4b853
--- /dev/null
+++ b/src/backend/bookshelfmodel/categoryitem.cpp
@@ -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-2009 by the BibleTime developers.
+* The BibleTime source code is licensed under the GNU General Public License
+* version 2.0.
+*
+**********/
+
+#include "categoryitem.h"
+
+namespace BookshelfModel {
+
+CategoryItem::CategoryItem(CSwordModuleInfo *module)
+ : Item(ITEM_CATEGORY), m_category(module->category())
+{
+ // Intentionally empty
+}
+
+} // namespace BookshelfModel
diff --git a/src/backend/bookshelfmodel/categoryitem.h b/src/backend/bookshelfmodel/categoryitem.h
new file mode 100644
index 0000000..3cf7996
--- /dev/null
+++ b/src/backend/bookshelfmodel/categoryitem.h
@@ -0,0 +1,54 @@
+/*********
+*
+* 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-2009 by the BibleTime developers.
+* The BibleTime source code is licensed under the GNU General Public License
+* version 2.0.
+*
+**********/
+
+#ifndef CATEGORYITEM_H
+#define CATEGORYITEM_H
+
+#include "backend/bookshelfmodel/item.h"
+
+#include <QCoreApplication>
+#include "backend/bookshelfmodel/btbookshelfmodel.h"
+#include "backend/drivers/cswordmoduleinfo.h"
+
+namespace BookshelfModel {
+
+class CategoryItem: public Item {
+ Q_DECLARE_TR_FUNCTIONS(CategoryItem);
+
+ public:
+ static const Item::Type GROUP_TYPE = Item::ITEM_CATEGORY;
+
+ CategoryItem(CSwordModuleInfo *module);
+
+ inline const CSwordModuleInfo::Category &category() const {
+ return m_category;
+ }
+
+ inline QString name() const {
+ return BtBookshelfModel::categoryName(m_category);
+ }
+
+ inline QIcon icon() const {
+ return BtBookshelfModel::categoryIcon(m_category);
+ }
+
+ inline bool fitFor(CSwordModuleInfo *module) {
+ return module->category() == m_category;
+ }
+
+ protected:
+ CSwordModuleInfo::Category m_category;
+};
+
+} // namespace BookshelfModel
+
+#endif // CATEGORYITEM_H
diff --git a/src/backend/bookshelfmodel/distributionitem.cpp b/src/backend/bookshelfmodel/distributionitem.cpp
new file mode 100644
index 0000000..411e236
--- /dev/null
+++ b/src/backend/bookshelfmodel/distributionitem.cpp
@@ -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-2009 by the BibleTime developers.
+* The BibleTime source code is licensed under the GNU General Public License
+* version 2.0.
+*
+**********/
+
+#include "backend/bookshelfmodel/distributionitem.h"
+
+namespace BookshelfModel {
+
+DistributionItem::DistributionItem(CSwordModuleInfo *module)
+ : Item(ITEM_DISTRIBUTION)
+{
+ m_distribution = module->config(CSwordModuleInfo::DistributionSource);
+}
+
+} // namespace BookshelfModel
diff --git a/src/backend/bookshelfmodel/distributionitem.h b/src/backend/bookshelfmodel/distributionitem.h
new file mode 100644
index 0000000..ac3912d
--- /dev/null
+++ b/src/backend/bookshelfmodel/distributionitem.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-2009 by the BibleTime developers.
+* The BibleTime source code is licensed under the GNU General Public License
+* version 2.0.
+*
+**********/
+
+#ifndef DISTRIBUTIONITEM_H
+#define DISTRIBUTIONITEM_H
+
+#include "backend/bookshelfmodel/item.h"
+
+#include "backend/drivers/cswordmoduleinfo.h"
+
+namespace BookshelfModel {
+
+class DistributionItem: public Item {
+ public:
+ static const Item::Type GROUP_TYPE = Item::ITEM_DISTRIBUTION;
+
+ DistributionItem(CSwordModuleInfo *module);
+
+ inline QString distribution() const { return m_distribution; }
+
+ inline QString name() const { return m_distribution; }
+
+ inline bool fitFor(CSwordModuleInfo *module) {
+ return module->config(CSwordModuleInfo::DistributionSource)
+ == m_distribution;
+ }
+
+ protected:
+ QString m_distribution;
+};
+
+} // namespace BookshelfModel
+
+#endif // DISTRIBUTIONITEM_H
diff --git a/src/backend/bookshelfmodel/item.cpp b/src/backend/bookshelfmodel/item.cpp
new file mode 100644
index 0000000..22bed91
--- /dev/null
+++ b/src/backend/bookshelfmodel/item.cpp
@@ -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-2009 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 "backend/bookshelfmodel/categoryitem.h"
+#include "backend/bookshelfmodel/distributionitem.h"
+#include "backend/bookshelfmodel/languageitem.h"
+
+namespace BookshelfModel {
+
+Item::Item(Type type)
+ : m_type(type), m_parent(0), m_checkState(Qt::Unchecked)
+{
+ // Intentionally empty
+}
+
+Item::~Item() {
+ qDeleteAll(m_children);
+}
+
+int Item::indexFor(Item *newItem) {
+ Q_ASSERT(newItem != 0);
+
+ if (m_children.empty()) return 0;
+
+ int i(0);
+ for (;;) {
+ Item *nextItem(m_children.at(i));
+ Q_ASSERT(nextItem->type() == newItem->type());
+ if (*newItem < *nextItem) {
+ return i;
+ }
+ i++;
+ if (i >= m_children.size()) {
+ return i;
+ }
+ }
+}
+
+bool Item::operator<(const Item &other) const {
+ if (m_type != other.type()) {
+ return m_type < other.type();
+ }
+ return name().localeAwareCompare(other.name()) < 0;
+}
+
+} // namespace BookshelfModel
diff --git a/src/backend/bookshelfmodel/item.h b/src/backend/bookshelfmodel/item.h
new file mode 100644
index 0000000..cb2e6d9
--- /dev/null
+++ b/src/backend/bookshelfmodel/item.h
@@ -0,0 +1,170 @@
+/*********
+*
+* 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-2009 by the BibleTime developers.
+* The BibleTime source code is licensed under the GNU General Public License
+* version 2.0.
+*
+**********/
+
+#ifndef ITEM_H
+#define ITEM_H
+
+#include <QIcon>
+#include <QList>
+#include <QString>
+#include <QtGlobal>
+
+class CSwordModuleInfo;
+
+namespace BookshelfModel {
+
+class Item {
+ public:
+ enum Type {
+ ITEM_ROOT = 0,
+ ITEM_CATEGORY = 1,
+ ITEM_LANGUAGE = 2,
+ ITEM_MODULE = 3,
+ ITEM_DISTRIBUTION = 4
+ };
+
+ Item(Type type);
+ virtual ~Item();
+
+ /**
+ \brief Returns the type of this item.
+ */
+ inline Type type() const { return m_type; }
+
+ /**
+ \brief Returns a pointer to the parent item of this item.
+ \retval 0 if this item has no parent.
+ */
+ inline Item *parent() const { return m_parent; }
+
+ /**
+ \brief Returns the list of child items of this node.
+ */
+ inline const QList<Item*> &children() const { return m_children; }
+
+ /**
+ \brief Returns a pointer to the child item at the given index.
+ \pre The given index is valid
+ \param[in] index Index of child item to return.
+ */
+ Item *childAt(int index) const {
+ Q_ASSERT(index >= 0 && index < m_children.size());
+ return m_children.at(index);
+ }
+
+ /**
+ \brief Returns the index of this item under its parent.
+ \retval -1 if this item has no parent.
+ */
+ inline int childIndex() {
+ if (m_parent == 0) return -1;
+ return m_parent->m_children.indexOf(this);
+ }
+
+ /**
+ \brief Returns the position for where the given child item would be
+ inserted.
+ \param[in] newItem Pointer to the item that would be inserted.
+ */
+ int indexFor(Item *newItem);
+
+ /**
+ \brief Inserts the given item as a child at the given index.
+ \pre The given index is a valid position for the item.
+ \param[in] index The child index to insert the item at.
+ \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());
+ m_children.insert(index, newItem);
+ newItem->setParent(this);
+ }
+
+ inline void deleteChildAt(int index) {
+ Q_ASSERT(index >= 0 && index <= m_children.size());
+ delete m_children.takeAt(index);
+ }
+
+ template <class T>
+ T *getGroupItem(CSwordModuleInfo *module, int *index) {
+ for (int i(0); i < m_children.size(); i++) {
+ Q_ASSERT(m_children.at(i)->type() == T::GROUP_TYPE);
+ T *item(static_cast<T*>(m_children.at(i)));
+ if (item->fitFor(module)) {
+ if (index != 0) *index = i;
+ return item;
+ }
+ }
+ return 0;
+ }
+
+ /**
+ \brief Returns the visible name of the item.
+ */
+ inline virtual QString name() const { return QString::null; }
+
+ /**
+ \brief Returns the visible icon of the item.
+ */
+ inline virtual QIcon icon() const { return QIcon(); }
+
+ /**
+ \brief Returns the check state of this item.
+ */
+ inline const Qt::CheckState checkState() const { return m_checkState; }
+
+ /**
+ \brief Sets the check state of this item.
+ \param[in] state new check state.
+ */
+ inline void setCheckState(const Qt::CheckState state) {
+ m_checkState = state;
+ }
+
+ /**
+ \brief Returns whether this item is fit to contain the given module.
+ \param[in] module The module to check with.
+ \retval true If this item is a group and can contain the given module.
+ \retval false This item is not a group or a wrong group.
+ */
+ inline virtual bool fitFor(CSwordModuleInfo *module) {
+ Q_UNUSED(module);
+ return false;
+ }
+
+ /**
+ \brief Comparsion operator used sorting child items.
+ */
+ bool operator<(const Item &other) const;
+
+ protected:
+ inline void setParent(Item *parent) {
+ Q_ASSERT(parent != 0);
+ m_parent = parent;
+ }
+
+ protected:
+ Type m_type;
+ Item *m_parent;
+ QList<Item*> m_children;
+ Qt::CheckState m_checkState;
+};
+
+class RootItem: public Item {
+ public:
+ inline RootItem() : Item(Item::ITEM_ROOT) {}
+};
+
+} // Namespace BookshelfModel
+
+#endif // ITEM_H
diff --git a/src/backend/bookshelfmodel/languageitem.cpp b/src/backend/bookshelfmodel/languageitem.cpp
new file mode 100644
index 0000000..6c2af30
--- /dev/null
+++ b/src/backend/bookshelfmodel/languageitem.cpp
@@ -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-2009 by the BibleTime developers.
+* The BibleTime source code is licensed under the GNU General Public License
+* version 2.0.
+*
+**********/
+
+#include "languageitem.h"
+
+namespace BookshelfModel {
+
+LanguageItem::LanguageItem(CSwordModuleInfo *module)
+ : Item(ITEM_LANGUAGE), m_language(module->language())
+{
+ // Intentionally empty
+}
+
+} // namespace BookshelfModel
diff --git a/src/backend/bookshelfmodel/languageitem.h b/src/backend/bookshelfmodel/languageitem.h
new file mode 100644
index 0000000..3b329f1
--- /dev/null
+++ b/src/backend/bookshelfmodel/languageitem.h
@@ -0,0 +1,50 @@
+/*********
+*
+* 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-2009 by the BibleTime developers.
+* The BibleTime source code is licensed under the GNU General Public License
+* version 2.0.
+*
+**********/
+
+#ifndef LANGUAGEITEM_H
+#define LANGUAGEITEM_H
+
+#include "backend/bookshelfmodel/item.h"
+
+#include "backend/bookshelfmodel/btbookshelfmodel.h"
+#include "backend/drivers/cswordmoduleinfo.h"
+#include "util/directoryutil.h"
+
+namespace BookshelfModel {
+
+class LanguageItem: public Item {
+ public:
+ static const Item::Type GROUP_TYPE = Item::ITEM_LANGUAGE;
+
+ LanguageItem(CSwordModuleInfo *module);
+
+ inline const CLanguageMgr::Language *language() const { return m_language; }
+
+ inline QString name() const {
+ return BtBookshelfModel::languageName(m_language);
+ }
+
+ inline QIcon icon() const {
+ return util::filesystem::DirectoryUtil::getIcon("flag.svg");
+ }
+
+ inline bool fitFor(CSwordModuleInfo *module) {
+ return module->language() == m_language;
+ }
+
+ protected:
+ const CLanguageMgr::Language *m_language;
+};
+
+} // namespace BookshelfModel
+
+#endif // LANGUAGEITEM_H
diff --git a/src/backend/bookshelfmodel/moduleitem.cpp b/src/backend/bookshelfmodel/moduleitem.cpp
new file mode 100644
index 0000000..6a543bc
--- /dev/null
+++ b/src/backend/bookshelfmodel/moduleitem.cpp
@@ -0,0 +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-2009 by the BibleTime developers.
+* The BibleTime source code is licensed under the GNU General Public License
+* version 2.0.
+*
+**********/
+
+#include "moduleitem.h"
+
+#include "util/cresmgr.h"
+
+namespace BookshelfModel {
+
+ModuleItem::ModuleItem(CSwordModuleInfo *module)
+ : Item(ITEM_MODULE), m_moduleInfo(module)
+{
+ Q_ASSERT(module != 0);
+}
+
+} // namespace BookshelfModel
diff --git a/src/backend/bookshelfmodel/moduleitem.h b/src/backend/bookshelfmodel/moduleitem.h
new file mode 100644
index 0000000..7bafc1f
--- /dev/null
+++ b/src/backend/bookshelfmodel/moduleitem.h
@@ -0,0 +1,41 @@
+/*********
+*
+* 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-2009 by the BibleTime developers.
+* The BibleTime source code is licensed under the GNU General Public License
+* version 2.0.
+*
+**********/
+
+#ifndef MODULEITEM_H
+#define MODULEITEM_H
+
+#include "backend/bookshelfmodel/item.h"
+
+#include "backend/bookshelfmodel/btbookshelfmodel.h"
+#include "backend/drivers/cswordmoduleinfo.h"
+
+namespace BookshelfModel {
+
+class ModuleItem: public Item {
+ public:
+ ModuleItem(CSwordModuleInfo *module);
+
+ CSwordModuleInfo *moduleInfo() const { return m_moduleInfo; }
+
+ inline QString name() const { return m_moduleInfo->name(); }
+
+ inline QIcon icon() const {
+ return BtBookshelfModel::categoryIcon(m_moduleInfo->category());
+ }
+
+ protected:
+ CSwordModuleInfo *m_moduleInfo;
+};
+
+} // namespace BookshelfModel
+
+#endif // MODULEITEM_H
diff --git a/src/backend/keys/cswordversekey.cpp b/src/backend/keys/cswordversekey.cpp
index 8db5d74..8008a7f 100644
--- a/src/backend/keys/cswordversekey.cpp
+++ b/src/backend/keys/cswordversekey.cpp
@@ -18,8 +18,13 @@
#include <swmodule.h>
#include <localemgr.h>
-CSwordVerseKey::CSwordVerseKey( CSwordModuleInfo* const module ) : CSwordKey(module) {
+CSwordVerseKey::CSwordVerseKey( CSwordModuleInfo* const module ) :
+ CSwordKey(module)
+{
if ( CSwordBibleModuleInfo* bible = dynamic_cast<CSwordBibleModuleInfo*>(module) ) {
+ // Copy important settings like versification system
+ copyFrom((sword::VerseKey*) bible->module()->getKey());
+
key( bible->lowerBound().key() );
}
}
diff --git a/src/backend/rendering/cdisplayrendering.cpp b/src/backend/rendering/cdisplayrendering.cpp
index 50d5b18..32444b4 100644
--- a/src/backend/rendering/cdisplayrendering.cpp
+++ b/src/backend/rendering/cdisplayrendering.cpp
@@ -99,8 +99,9 @@ namespace Rendering {
const QString CDisplayRendering::keyToHTMLAnchor(const QString& key) {
QString ret = key;
- ret = ret.trimmed().remove(QRegExp("[^A-Za-z0-9]+"));
- ret = ret.remove(QRegExp("^\\d+|"));
+ // Be careful not to remove non-ASCII characters, this causes problems
+ // with many languages.
+ ret = ret.trimmed().remove(QRegExp("\\s")).replace(QString(":"), QString("_"));
return ret;
}
diff --git a/src/bibletime.cpp b/src/bibletime.cpp
index fdc9f48..c7af792 100644
--- a/src/bibletime.cpp
+++ b/src/bibletime.cpp
@@ -8,8 +8,8 @@
**********/
#include "bibletime.h"
+#include "frontend/btaboutmoduledialog.h"
#include "frontend/cmdiarea.h"
-#include "frontend/mainindex/cmainindex.h"
#include "frontend/mainindex/bookshelf/cbookshelfindex.h"
#include "frontend/displaywindow/btactioncollection.h"
#include "frontend/displaywindow/cdisplaywindow.h"
@@ -17,6 +17,7 @@
#include "frontend/displaywindow/creadwindow.h"
#include "frontend/displaywindow/cwritewindow.h"
#include "frontend/keychooser/ckeychooser.h"
+#include "frontend/searchdialog/csearchdialog.h"
#include "backend/config/cbtconfig.h"
#include "util/ctoolclass.h"
@@ -33,6 +34,7 @@
#include "backend/keys/cswordldkey.h"
//Qt includes
+#include <QInputDialog>
#include <QSplitter>
#include <QDebug>
#include <QAction>
@@ -155,7 +157,7 @@ CDisplayWindow* BibleTime::createReadDisplayWindow(QList<CSwordModuleInfo*> modu
qApp->processEvents();
// Now all events, including mouse clicks for the displayWindow have been handled
// and we can let the user click the same module again
- m_bookshelfPage->unfreezeModules(modules);
+ //m_bookshelfPage->unfreezeModules(modules);
qApp->restoreOverrideCursor();
return displayWindow;
}
@@ -192,6 +194,53 @@ CDisplayWindow* BibleTime::createWriteDisplayWindow(CSwordModuleInfo* module, co
return displayWindow;
}
+CDisplayWindow* BibleTime::moduleEditPlain(CSwordModuleInfo *module) {
+ /// \todo Refactor this.
+ return createWriteDisplayWindow(module,
+ QString::null,
+ CDisplayWindow::PlainTextWindow);
+}
+
+CDisplayWindow* BibleTime::moduleEditHtml(CSwordModuleInfo *module) {
+ /// \todo Refactor this.
+ return createWriteDisplayWindow(module,
+ QString::null,
+ CDisplayWindow::HTMLWindow);
+}
+
+
+void BibleTime::searchInModule(CSwordModuleInfo *module) {
+ /// \todo Refactor this.
+ QList<CSwordModuleInfo *> modules;
+ modules.append(module);
+ Search::CSearchDialog::openDialog(modules, QString::null);
+}
+
+void BibleTime::moduleUnlock(CSwordModuleInfo *module) {
+ bool ok;
+ const QString unlockKey =
+ QInputDialog::getText(
+ this,
+ tr("Unlock Work"),
+ tr("Enter the unlock key for this work."),
+ QLineEdit::Normal,
+ module->config(CSwordModuleInfo::CipherKey),
+ &ok
+ );
+ if (ok) {
+ /// \todo Refactor. Unlock the module via a global modules model.
+ if (module->unlock(unlockKey)) {
+ CPointers::backend()->reloadModules(CSwordBackend::OtherChange);
+ }
+ }
+}
+
+void BibleTime::moduleAbout(CSwordModuleInfo *module) {
+ BTAboutModuleDialog *dialog(new BTAboutModuleDialog(this, module));
+ dialog->show();
+ dialog->raise();
+}
+
/** Refreshes all presenters.*/
void BibleTime::refreshDisplayWindows()
{
diff --git a/src/bibletime.h b/src/bibletime.h
index 63d603d..4ddf2e1 100644
--- a/src/bibletime.h
+++ b/src/bibletime.h
@@ -22,9 +22,9 @@ class CSwordModuleInfo;
class BtActionClass;
class CMDIArea;
class CDisplayWindow;
-class CMainIndex;
class CBookmarkIndex;
class CBookshelfIndex;
+class BtBookshelfDockWidget;
namespace InfoDisplay {
class CInfoDisplay;
@@ -232,8 +232,14 @@ protected slots:
* Creates a new presenter in the MDI area according to the type of the module.
*/
CDisplayWindow* createReadDisplayWindow(QList<CSwordModuleInfo*> modules, const QString& key);
- CDisplayWindow* createReadDisplayWindow(CSwordModuleInfo* module, const QString& key);
+ CDisplayWindow* createReadDisplayWindow(CSwordModuleInfo* module, const QString& key = QString::null);
CDisplayWindow* createWriteDisplayWindow(CSwordModuleInfo* module, const QString& key, const CDisplayWindow::WriteWindowType& type);
+ CDisplayWindow* moduleEditPlain(CSwordModuleInfo *module);
+ CDisplayWindow* moduleEditHtml(CSwordModuleInfo *module);
+ void searchInModule(CSwordModuleInfo *module);
+ void moduleUnlock(CSwordModuleInfo *module);
+ void moduleAbout(CSwordModuleInfo *module);
+
/**
* Is called when the window menu is about to show ;-)
*/
@@ -327,8 +333,7 @@ protected slots:
private:
// Docking widgets and their respective content widgets:
- QDockWidget* m_bookshelfDock;
- CBookshelfIndex* m_bookshelfPage;
+ BtBookshelfDockWidget* m_bookshelfDock;
QDockWidget* m_bookmarksDock;
CBookmarkIndex* m_bookmarksPage;
QDockWidget* m_magDock;
diff --git a/src/bibletime_init.cpp b/src/bibletime_init.cpp
index c59964b..614469b 100644
--- a/src/bibletime_init.cpp
+++ b/src/bibletime_init.cpp
@@ -15,7 +15,7 @@
#include "backend/managers/btstringmgr.h"
#include "backend/managers/cswordbackend.h"
#include "backend/managers/clanguagemgr.h"
-#include "frontend/mainindex/cmainindex.h"
+#include "frontend/btbookshelfdockwidget.h"
#include "frontend/displaywindow/btactioncollection.h"
#include "frontend/profile/cprofilemgr.h"
#include "frontend/profile/cprofile.h"
@@ -50,10 +50,7 @@ void BibleTime::initView()
m_mdi = new CMDIArea(this);
setCentralWidget(m_mdi);
- m_bookshelfDock = new QDockWidget(tr("Bookshelf"), this);
- m_bookshelfDock->setObjectName("BookshelfDock");
- m_bookshelfPage = new CBookshelfIndex(0);
- m_bookshelfDock->setWidget(m_bookshelfPage);
+ m_bookshelfDock = new BtBookshelfDockWidget(this);
addDockWidget(Qt::LeftDockWidgetArea, m_bookshelfDock);
m_bookmarksDock = new QDockWidget(tr("Bookmarks"), this);
@@ -396,12 +393,18 @@ void BibleTime::initConnections()
ok = connect(m_bookmarksPage, SIGNAL(createReadDisplayWindow(QList<CSwordModuleInfo*>, const QString&)),
this, SLOT(createReadDisplayWindow(QList<CSwordModuleInfo*>,const QString&)));
Q_ASSERT(ok);
- ok = connect(m_bookshelfPage, SIGNAL(createReadDisplayWindow(QList<CSwordModuleInfo*>, const QString&)),
- this, SLOT(createReadDisplayWindow(QList<CSwordModuleInfo*>,const QString&)));
- Q_ASSERT(ok);
- ok = connect(m_bookshelfPage, SIGNAL(createWriteDisplayWindow(CSwordModuleInfo*, const QString&, const CDisplayWindow::WriteWindowType&)),
- this, SLOT(createWriteDisplayWindow(CSwordModuleInfo*,const QString&, const CDisplayWindow::WriteWindowType&)));
- Q_ASSERT(ok);
+ 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(moduleUnlock(CSwordModuleInfo*)));
+ connect(m_bookshelfDock, SIGNAL(moduleAboutTriggered(CSwordModuleInfo*)),
+ this, SLOT(moduleAbout(CSwordModuleInfo*)));
connect(qApp, SIGNAL(aboutToQuit()), this, SLOT(slot_aboutToQuit()));
}
diff --git a/src/bibletime_slots.cpp b/src/bibletime_slots.cpp
index 471c96f..40d1319 100644
--- a/src/bibletime_slots.cpp
+++ b/src/bibletime_slots.cpp
@@ -23,7 +23,6 @@
#include "backend/config/cbtconfig.h"
#include "frontend/cinputdialog.h"
#include "frontend/cinfodisplay.h"
-#include "frontend/mainindex/cmainindex.h"
#include "frontend/displaywindow/cdisplaywindow.h"
#include "frontend/displaywindow/cbiblereadwindow.h"
#include "frontend/searchdialog/csearchdialog.h"
diff --git a/src/frontend/bookshelfmanager/indexpage/btindexpage.cpp b/src/frontend/bookshelfmanager/indexpage/btindexpage.cpp
index 8b2b335..cad5a84 100644
--- a/src/frontend/bookshelfmanager/indexpage/btindexpage.cpp
+++ b/src/frontend/bookshelfmanager/indexpage/btindexpage.cpp
@@ -37,7 +37,7 @@ BtIndexPage::BtIndexPage()
QVBoxLayout *vboxLayout;
QHBoxLayout *hboxLayout;
vboxLayout = new QVBoxLayout(this);
-
+
m_autoDeleteOrphanedIndicesBox = new QCheckBox(this);
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"));
@@ -106,15 +106,15 @@ QString BtIndexPage::header()
/** Populates the module list with installed modules and orphaned indices */
void BtIndexPage::populateModuleList() {
m_moduleList->clear();
-
+
// populate installed modules
m_modsWithIndices = new QTreeWidgetItem(m_moduleList);
- m_modsWithIndices->setText(0, tr("Works with indexes"));
+ 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("Works without indexes"));
+ m_modsWithoutIndices->setText(0, tr("Unindexed Works"));
m_modsWithoutIndices->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsTristate);
m_modsWithoutIndices->setExpanded(true);
@@ -124,7 +124,7 @@ void BtIndexPage::populateModuleList() {
QList<CSwordModuleInfo*>::iterator end_it = modules.end();
for (QList<CSwordModuleInfo*>::iterator it = modules.begin(); it != end_it; ++it) {
QTreeWidgetItem* item = 0;
-
+
if ((*it)->hasIndex()) {
item = new QTreeWidgetItem(m_modsWithIndices);
item->setText(0, (*it)->name());
@@ -169,7 +169,7 @@ void BtIndexPage::createIndices()
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 = CPointers::backend()->findModuleByName(m_modsWithIndices->child(i)->text(0).toUtf8());
@@ -191,7 +191,7 @@ void BtIndexPage::deleteOrphanedIndices()
QDir dir(CSwordModuleInfo::getGlobalBaseIndexLocation());
dir.setFilter(QDir::Dirs);
CSwordModuleInfo* module;
-
+
for (unsigned int i = 0; i < dir.count(); i++) {
if (dir[i] != "." && dir[i] != "..") {
if ( (module = CPointers::backend()->findModuleByName(dir[i])) ) { //mod exists
diff --git a/src/frontend/btbookshelfdockwidget.cpp b/src/frontend/btbookshelfdockwidget.cpp
new file mode 100644
index 0000000..4b73c3a
--- /dev/null
+++ b/src/frontend/btbookshelfdockwidget.cpp
@@ -0,0 +1,300 @@
+/*********
+*
+* 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-2009 by the BibleTime developers.
+* The BibleTime source code is licensed under the GNU General Public License
+* version 2.0.
+*
+**********/
+
+#include "frontend/btbookshelfdockwidget.h"
+
+#include <QAction>
+#include <QActionGroup>
+#include <QApplication>
+#include <QHBoxLayout>
+#include <QKeyEvent>
+#include <QLabel>
+#include <QLineEdit>
+#include <QMenu>
+#include <QToolBar>
+#include <QToolButton>
+#include <QVBoxLayout>
+#include "backend/bookshelfmodel/btbookshelfmodel.h"
+#include "backend/bookshelfmodel/btbookshelftreemodel.h"
+#include "backend/bookshelfmodel/btcheckstatefilterproxymodel.h"
+#include "backend/bookshelfmodel/btmodulenamefilterproxymodel.h"
+#include "backend/drivers/cswordmoduleinfo.h"
+#include "backend/managers/cswordbackend.h"
+#include "frontend/btaboutmoduledialog.h"
+#include "frontend/mainindex/btbookshelfview.h"
+#include "util/cpointers.h"
+#include "util/cresmgr.h"
+#include "util/directoryutil.h"
+
+BtBookshelfDockWidget::BtBookshelfDockWidget(QWidget *parent, Qt::WindowFlags f)
+ : QDockWidget(parent, f)
+{
+ setObjectName("BookshelfDock");
+
+ // Setup models:
+ m_bookshelfModel = new BtBookshelfModel(this);
+ m_bookshelfModel->addModules(CPointers::backend()->moduleList());
+ m_bookshelfTreeModel = new BtBookshelfTreeModel(this);
+ m_bookshelfTreeModel->setDefaultChecked(true);
+ m_bookshelfTreeModel->setSourceModel(m_bookshelfModel);
+ m_filterProxyModel = new BtCheckStateFilterProxyModel(this);
+ m_filterProxyModel->setFilterRole(BtBookshelfTreeModel::CheckStateRole);
+ m_filterProxyModel->setSourceModel(m_bookshelfTreeModel);
+ m_nameFilterProxyModel = new BtModuleNameFilterProxyModel(this);
+ m_nameFilterProxyModel->setSourceModel(m_filterProxyModel);
+
+ // Setup actions and menus:
+ initMenus();
+
+ // Setup widgets:
+ m_widget = new QWidget(this);
+ QVBoxLayout *layout(new QVBoxLayout);
+ layout->setContentsMargins(0, 0, 0, 0);
+ QHBoxLayout *toolBar(new QHBoxLayout);
+ m_nameFilterLabel = new QLabel(this);
+ toolBar->addWidget(m_nameFilterLabel);
+
+ m_nameFilterEdit = new QLineEdit(this);
+ m_nameFilterEdit->installEventFilter(this);
+ m_nameFilterLabel->setBuddy(m_nameFilterEdit);
+ toolBar->addWidget(m_nameFilterEdit);
+
+ 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);
+ toolBar->addWidget(m_groupingButton);
+
+ m_showHideButton = new QToolButton(this);
+ m_showHideButton->setDefaultAction(m_showHideAction);
+ m_showHideButton->setAutoRaise(true);
+ toolBar->addWidget(m_showHideButton);
+ layout->addLayout(toolBar);
+
+ m_view = new BtBookshelfView(this);
+ m_view->setModel(m_nameFilterProxyModel);
+ layout->addWidget(m_view);
+ m_widget->setLayout(layout);
+ setWidget(m_widget);
+
+ connect(CPointers::backend(),
+ SIGNAL(sigSwordSetupChanged(CSwordBackend::SetupChangedReason)),
+ this, SLOT(swordSetupChanged()));
+ connect(m_nameFilterEdit, SIGNAL(textEdited(QString)),
+ m_nameFilterProxyModel, SLOT(setFilterFixedString(QString)));
+ connect(m_view, SIGNAL(contextMenuActivated(QPoint)),
+ this, SLOT(showContextMenu(QPoint)));
+ connect(m_view,
+ SIGNAL(moduleContextMenuActivated(CSwordModuleInfo*,QPoint)),
+ this, SLOT(showItemContextMenu(CSwordModuleInfo*,QPoint)));
+ connect(m_view, SIGNAL(moduleActivated(CSwordModuleInfo*)),
+ this, SIGNAL(moduleOpenTriggered(CSwordModuleInfo*)));
+
+ retranslateInterface();
+}
+
+bool BtBookshelfDockWidget::eventFilter(QObject *object, QEvent *event) {
+ Q_ASSERT(object == m_nameFilterEdit);
+ if (event->type() == QEvent::KeyPress) {
+ QKeyEvent *e = static_cast<QKeyEvent*>(event);
+ switch (e->key()) {
+ case Qt::Key_Up:
+ case Qt::Key_Down:
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ QApplication::sendEvent(m_view, event);
+ return true;
+ default:
+ break;
+ }
+ }
+ return false;
+}
+
+void BtBookshelfDockWidget::initMenus() {
+ typedef util::filesystem::DirectoryUtil DU;
+ namespace RM = CResMgr::mainIndex;
+
+ m_contextMenu = new QMenu(this);
+ m_groupingMenu = new QMenu(this);
+ m_contextMenu->addMenu(m_groupingMenu);
+ m_groupingMenu->setIcon(DU::getIcon(RM::grouping::icon));
+ m_groupingActionGroup = new QActionGroup(this);
+ connect(m_groupingActionGroup, SIGNAL(triggered(QAction*)),
+ this, SLOT(groupingActionTriggered(QAction*)));
+
+ m_groupingCatLangAction = new QAction(this);
+ m_groupingCatLangAction->setIcon(DU::getIcon(RM::grouping::icon));
+ m_groupingCatLangAction->setChecked(true);
+ m_groupingActionGroup->addAction(m_groupingCatLangAction);
+ m_groupingMenu->addAction(m_groupingCatLangAction);
+
+ m_groupingCatAction = new QAction(this);
+ m_groupingCatAction->setIcon(DU::getIcon(RM::grouping::icon));
+ m_groupingActionGroup->addAction(m_groupingCatAction);
+ m_groupingMenu->addAction(m_groupingCatAction);
+
+ m_groupingLangCatAction = new QAction(this);
+ m_groupingLangCatAction->setIcon(DU::getIcon(RM::grouping::icon));
+ m_groupingActionGroup->addAction(m_groupingLangCatAction);
+ m_groupingMenu->addAction(m_groupingLangCatAction);
+
+ m_groupingLangAction = new QAction(this);
+ m_groupingLangAction->setIcon(DU::getIcon(RM::grouping::icon));
+ m_groupingActionGroup->addAction(m_groupingLangAction);
+ m_groupingMenu->addAction(m_groupingLangAction);
+
+ m_groupingNoneAction = new QAction(this);
+ m_groupingNoneAction->setIcon(DU::getIcon(RM::grouping::icon));
+ m_groupingActionGroup->addAction(m_groupingNoneAction);
+ m_groupingMenu->addAction(m_groupingNoneAction);
+
+ m_showHideAction = new QAction(this);
+ m_showHideAction->setIcon(DU::getIcon(RM::search::icon));
+ m_showHideAction->setCheckable(true);
+ connect(m_showHideAction, SIGNAL(toggled(bool)),
+ this, SLOT(showHideEnabled(bool)));
+ m_contextMenu->addAction(m_showHideAction);
+
+ m_itemContextMenu = new QMenu(this);
+ m_itemActionGroup = new QActionGroup(this);
+ connect(m_itemActionGroup, SIGNAL(triggered(QAction*)),
+ this, SLOT(itemActionTriggered(QAction*)));
+
+ m_itemOpenAction = new QAction(this);
+ m_itemActionGroup->addAction(m_itemOpenAction);
+ m_itemContextMenu->addAction(m_itemOpenAction);
+
+ m_itemSearchAction = new QAction(this);
+ m_itemSearchAction->setIcon(DU::getIcon(RM::search::icon));
+ m_itemActionGroup->addAction(m_itemSearchAction);
+ m_itemContextMenu->addAction(m_itemSearchAction);
+
+ m_itemEditMenu = new QMenu(this);
+ m_itemEditMenu->setIcon(DU::getIcon(RM::editModuleMenu::icon));
+ m_itemContextMenu->addMenu(m_itemEditMenu);
+ m_itemEditPlainAction = new QAction(this);
+ m_itemEditPlainAction->setIcon(DU::getIcon(RM::editModulePlain::icon));
+ m_itemActionGroup->addAction(m_itemEditPlainAction);
+ m_itemEditMenu->addAction(m_itemEditPlainAction);
+
+ m_itemEditHtmlAction = new QAction(this);
+ m_itemEditHtmlAction->setIcon(DU::getIcon(RM::editModuleHTML::icon));
+ m_itemActionGroup->addAction(m_itemEditHtmlAction);
+ m_itemEditMenu->addAction(m_itemEditHtmlAction);
+
+ m_itemUnlockAction = new QAction(this);
+ m_itemUnlockAction->setIcon(DU::getIcon(RM::unlockModule::icon));
+ m_itemActionGroup->addAction(m_itemUnlockAction);
+ m_itemContextMenu->addAction(m_itemUnlockAction);
+
+ m_itemAboutAction = new QAction(this);
+ m_itemAboutAction->setIcon(DU::getIcon(RM::aboutModule::icon));
+ m_itemActionGroup->addAction(m_itemAboutAction);
+ m_itemContextMenu->addAction(m_itemAboutAction);
+}
+
+void BtBookshelfDockWidget::retranslateInterface() {
+ setWindowTitle(tr("Bookshelf"));
+
+ m_nameFilterLabel->setText(tr("Fi&lter:"));
+ m_groupingButton->setText(tr("Grouping"));
+ m_groupingButton->setToolTip(tr("Change the grouping of items in the bookshelf."));
+
+ m_groupingMenu->setTitle(tr("Grouping"));
+ m_groupingCatLangAction->setText(tr("Category/Language"));
+ m_groupingCatAction->setText(tr("Category"));
+ m_groupingLangCatAction->setText(tr("Language/Category"));
+ m_groupingLangAction->setText(tr("Language"));
+ m_groupingNoneAction->setText(tr("No grouping"));
+ m_showHideAction->setText(tr("Show/hide works"));
+
+ m_itemOpenAction->setText(tr("&Open"));
+ m_itemEditMenu->setTitle(tr("&Edit"));
+ m_itemEditPlainAction->setText(tr("&Plain text"));
+ m_itemEditHtmlAction->setText(tr("&HTML"));
+ m_itemUnlockAction->setText(tr("&Unlock..."));
+ m_itemAboutAction->setText(tr("&About..."));
+}
+
+void BtBookshelfDockWidget::swordSetupChanged() {
+ QSet<CSwordModuleInfo*> added(CPointers::backend()->moduleList().toSet());
+ QSet<CSwordModuleInfo*> removed(m_bookshelfModel->modules().toSet());
+ QSet<CSwordModuleInfo*> t(removed);
+ removed.subtract(added);
+ added.subtract(t);
+ m_bookshelfModel->removeModules(removed);
+ m_bookshelfModel->addModules(added);
+}
+
+void BtBookshelfDockWidget::showContextMenu(QPoint pos) {
+ m_contextMenu->popup(pos);
+}
+
+void BtBookshelfDockWidget::groupingActionTriggered(QAction *action) {
+ BtBookshelfTreeModel::Grouping g;
+ if (action == m_groupingCatAction) {
+ g.append(BtBookshelfTreeModel::GROUP_CATEGORY);
+ } else if (action == m_groupingCatLangAction) {
+ g.append(BtBookshelfTreeModel::GROUP_CATEGORY);
+ g.append(BtBookshelfTreeModel::GROUP_LANGUAGE);
+ } else if (action == m_groupingLangAction) {
+ g.append(BtBookshelfTreeModel::GROUP_LANGUAGE);
+ } else if (action == m_groupingLangCatAction) {
+ g.append(BtBookshelfTreeModel::GROUP_LANGUAGE);
+ g.append(BtBookshelfTreeModel::GROUP_CATEGORY);
+ }
+ m_bookshelfTreeModel->setGroupingOrder(g);
+ m_view->setRootIsDecorated(!g.isEmpty());
+}
+
+void BtBookshelfDockWidget::showHideEnabled(bool enable) {
+ if (enable) {
+ m_bookshelfTreeModel->setCheckable(true);
+ m_filterProxyModel->setEnabled(false);
+ } else {
+ m_filterProxyModel->setEnabled(true);
+ m_bookshelfTreeModel->setCheckable(false);
+ }
+}
+
+void BtBookshelfDockWidget::showItemContextMenu(CSwordModuleInfo *module,
+ QPoint pos)
+{
+ m_itemContextMenu->setProperty("BtModule", qVariantFromValue((void*) module));
+ m_itemSearchAction->setText(tr("&Search in %1...").arg(module->name()));
+ m_itemOpenAction->setEnabled(!module->isLocked());
+ m_itemEditMenu->setEnabled(module->isWritable());
+ m_itemUnlockAction->setEnabled(module->isLocked());
+
+ m_itemContextMenu->popup(pos);
+}
+
+void BtBookshelfDockWidget::itemActionTriggered(QAction *action) {
+ CSwordModuleInfo *module((CSwordModuleInfo*) m_itemContextMenu->property("BtModule").value<void*>());
+ if (module == 0) return;
+
+ if (action == m_itemOpenAction) {
+ emit moduleOpenTriggered(module);
+ } else if (action == m_itemSearchAction) {
+ emit moduleSearchTriggered(module);
+ } else if (action == m_itemEditPlainAction) {
+ emit moduleEditPlainTriggered(module);
+ } else if (action == m_itemEditHtmlAction) {
+ emit moduleEditHtmlTriggered(module);
+ } else if (action == m_itemUnlockAction) {
+ emit moduleUnlockTriggered(module);
+ } else if (action == m_itemAboutAction) {
+ emit moduleAboutTriggered(module);
+ }
+}
diff --git a/src/frontend/btbookshelfdockwidget.h b/src/frontend/btbookshelfdockwidget.h
new file mode 100644
index 0000000..d437c92
--- /dev/null
+++ b/src/frontend/btbookshelfdockwidget.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-2009 by the BibleTime developers.
+* The BibleTime source code is licensed under the GNU General Public License
+* version 2.0.
+*
+**********/
+
+#ifndef BTBOOKSHELFDOCKWIDGET_H
+#define BTBOOKSHELFDOCKWIDGET_H
+
+#include <QDockWidget>
+
+class CSwordModuleInfo;
+class BtBookshelfView;
+class BtBookshelfModel;
+class BtBookshelfTreeModel;
+class BtCheckStateFilterProxyModel;
+class BtModuleNameFilterProxyModel;
+class QAction;
+class QActionGroup;
+class QLabel;
+class QLineEdit;
+class QMenu;
+class QToolBar;
+class QToolButton;
+
+class BtBookshelfDockWidget: public QDockWidget {
+ Q_OBJECT
+ public:
+ BtBookshelfDockWidget(QWidget *parent = 0, Qt::WindowFlags f = 0);
+
+ signals:
+ void moduleOpenTriggered(CSwordModuleInfo *module);
+ void moduleSearchTriggered(CSwordModuleInfo *module);
+ void moduleEditPlainTriggered(CSwordModuleInfo *module);
+ void moduleEditHtmlTriggered(CSwordModuleInfo *module);
+ void moduleUnlockTriggered(CSwordModuleInfo *module);
+ void moduleAboutTriggered(CSwordModuleInfo *module);
+
+ protected:
+ bool eventFilter(QObject *object, QEvent *event);
+ void initMenus();
+ void retranslateInterface();
+
+ protected slots:
+ void swordSetupChanged();
+ void showContextMenu(QPoint pos);
+ void groupingActionTriggered(QAction *action);
+ void showHideEnabled(bool enable);
+ void showItemContextMenu(CSwordModuleInfo *module, QPoint pos);
+ void itemActionTriggered(QAction *action);
+
+ protected:
+ // Models:
+ BtBookshelfModel *m_bookshelfModel;
+ BtBookshelfTreeModel *m_bookshelfTreeModel;
+ BtCheckStateFilterProxyModel *m_filterProxyModel;
+ BtModuleNameFilterProxyModel *m_nameFilterProxyModel;
+
+ // Widgets:
+ QWidget *m_widget;
+ BtBookshelfView *m_view;
+ QLabel *m_nameFilterLabel;
+ QLineEdit *m_nameFilterEdit;
+ QToolButton *m_groupingButton;
+ QToolButton *m_showHideButton;
+
+ // Popup menus:
+ QMenu *m_contextMenu;
+ QMenu *m_groupingMenu;
+ QActionGroup *m_groupingActionGroup;
+ QAction *m_groupingCatLangAction;
+ QAction *m_groupingCatAction;
+ QAction *m_groupingLangCatAction;
+ QAction *m_groupingLangAction;
+ QAction *m_groupingNoneAction;
+ QAction *m_showHideAction;
+ QMenu *m_itemContextMenu;
+ QActionGroup *m_itemActionGroup;
+ QAction *m_itemOpenAction;
+ QAction *m_itemSearchAction;
+ QMenu *m_itemEditMenu;
+ QAction *m_itemEditPlainAction;
+ QAction *m_itemEditHtmlAction;
+ QAction *m_itemUnlockAction;
+ QAction *m_itemAboutAction;
+};
+
+#endif // BTBOOKSHELFDOCKWIDGET_H
diff --git a/src/frontend/displaywindow/btactioncollection.cpp b/src/frontend/displaywindow/btactioncollection.cpp
index 046c3c0..fc1a412 100644
--- a/src/frontend/displaywindow/btactioncollection.cpp
+++ b/src/frontend/displaywindow/btactioncollection.cpp
@@ -15,6 +15,7 @@
#include <QSettings>
#include <QString>
#include <QStringList>
+#include <QDebug>
class BtActionItem : public QObject
{
@@ -52,10 +53,10 @@ QList<QAction*> BtActionCollection::actions()
QAction* BtActionCollection::action(const QString& name)
{
- Q_ASSERT(m_actions[name] != 0);
- QAction* action = m_actions[name]->action;
- Q_ASSERT(action != 0);
- return action;
+ if (m_actions.contains(name))
+ return m_actions[name]->action;
+ qWarning() << "A QAction for a shortcut named" << name << "was requested but it is not defined.";
+ return (new QAction(this)); // dummy QAction*
}
QAction* BtActionCollection::addAction(const QString& name, QAction* action)
diff --git a/src/frontend/displaywindow/cbookreadwindow.cpp b/src/frontend/displaywindow/cbookreadwindow.cpp
index 40f737d..465eec9 100644
--- a/src/frontend/displaywindow/cbookreadwindow.cpp
+++ b/src/frontend/displaywindow/cbookreadwindow.cpp
@@ -100,6 +100,9 @@ void CBookReadWindow::initView()
QSplitter* splitter = new QSplitter(this);
setMainToolBar( new QToolBar(this) );
+ mainToolBar()->setAllowedAreas(Qt::TopToolBarArea);
+ mainToolBar()->setFloatable(false);
+
addToolBar(mainToolBar());
m_treeChooser = new CBookTreeChooser(modules(), key(), splitter);
@@ -112,6 +115,8 @@ void CBookReadWindow::initView()
addToolBar(moduleChooserBar());
setButtonsToolBar( new QToolBar(this) );
+ buttonsToolBar()->setAllowedAreas(Qt::TopToolBarArea);
+ buttonsToolBar()->setFloatable(false);
setDisplaySettingsButton( new CDisplaySettingsButton( &displayOptions(), &filterOptions(), modules(), buttonsToolBar()) );
addToolBar(buttonsToolBar());
m_treeChooser->hide();
diff --git a/src/frontend/displaywindow/cdisplaywindow.cpp b/src/frontend/displaywindow/cdisplaywindow.cpp
index 6cf160d..8b4a9cd 100644
--- a/src/frontend/displaywindow/cdisplaywindow.cpp
+++ b/src/frontend/displaywindow/cdisplaywindow.cpp
@@ -129,6 +129,15 @@ void CDisplayWindow::insertKeyboardActions( BtActionCollection* a )
actn->setShortcut(QKeySequence::Find);
a->addAction("findText", actn);
+ actn = new QAction(QIcon(), tr("Change location"), 0);
+ actn->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_L));
+ a->addAction("openLocation", actn);
+
+ actn = new QAction(QIcon(util::filesystem::DirectoryUtil::getIcon(CResMgr::displaywindows::general::search::icon)),
+ tr("Search with works of this window"), 0);
+ actn->setShortcut(CResMgr::displaywindows::general::search::accel);
+ a->addAction(CResMgr::displaywindows::general::search::actionName, actn);
+
BtToolBarPopupAction* action = new BtToolBarPopupAction(
QIcon(util::filesystem::DirectoryUtil::getIcon(CResMgr::displaywindows::general::backInHistory::icon)),
tr("Back in history"),
@@ -154,18 +163,16 @@ void CDisplayWindow::initActions()
CDisplayWindow::insertKeyboardActions(ac);
- QAction* qaction = new QAction(
- QIcon(util::filesystem::DirectoryUtil::getIcon(CResMgr::displaywindows::general::search::icon)),
- tr("Open the search dialog with the works of this window"),
- ac
- );
- qaction->setShortcut(CResMgr::displaywindows::general::search::accel);
- QObject::connect(qaction, SIGNAL(triggered()), this, SLOT(slotSearchInModules()));
- ac->addAction(CResMgr::displaywindows::general::search::actionName, qaction);
+ QAction* actn = ac->action(CResMgr::displaywindows::general::search::actionName);
+ QObject::connect(actn, SIGNAL(triggered()), this, SLOT(slotSearchInModules()));
CDisplayConnections* conn = displayWidget()->connectionsProxy();
- QAction* actn = ac->action("zoomIn");
+ actn = ac->action("openLocation");
+ QObject::connect(actn, SIGNAL(triggered()), this, SLOT(setFocusKeyChooser()));
+ addAction(actn);
+
+ actn = ac->action("zoomIn");
QObject::connect(actn, SIGNAL(triggered()), conn, SLOT(zoomIn()));
addAction(actn);
@@ -536,3 +543,9 @@ BtActionCollection* CDisplayWindow::actionCollection()
{
return m_actionCollection;
}
+
+void CDisplayWindow::setFocusKeyChooser()
+{
+ keyChooser()->setFocus();
+}
+
diff --git a/src/frontend/displaywindow/cdisplaywindow.h b/src/frontend/displaywindow/cdisplaywindow.h
index 80877fb..733f06e 100644
--- a/src/frontend/displaywindow/cdisplaywindow.h
+++ b/src/frontend/displaywindow/cdisplaywindow.h
@@ -202,6 +202,7 @@ protected slots:
void printAnchorWithText();
+ void setFocusKeyChooser();
private:
BtActionCollection* m_actionCollection;
diff --git a/src/frontend/displaywindow/chtmlwritewindow.cpp b/src/frontend/displaywindow/chtmlwritewindow.cpp
index 7e97aa6..cee16e0 100644
--- a/src/frontend/displaywindow/chtmlwritewindow.cpp
+++ b/src/frontend/displaywindow/chtmlwritewindow.cpp
@@ -42,6 +42,8 @@ void CHTMLWriteWindow::initView() {
setCentralWidget( displayWidget()->view() );
setMainToolBar( new QToolBar(this) );
+ mainToolBar()->setAllowedAreas(Qt::TopToolBarArea);
+ mainToolBar()->setFloatable(false);
addToolBar(mainToolBar());
setKeyChooser( CKeyChooser::createInstance(modules(), key(), mainToolBar()) );
@@ -104,6 +106,8 @@ void CHTMLWriteWindow::initToolbars() {
//html formatting toolbar
QToolBar* bar = new QToolBar(this);
+ bar->setAllowedAreas(Qt::TopToolBarArea);
+ bar->setFloatable(false);
((CWriteDisplay*)displayWidget())->setupToolbar( bar, actionCollection() );
addToolBar(bar);
}
diff --git a/src/frontend/displaywindow/clexiconreadwindow.cpp b/src/frontend/displaywindow/clexiconreadwindow.cpp
index 8ceb326..df22de9 100644
--- a/src/frontend/displaywindow/clexiconreadwindow.cpp
+++ b/src/frontend/displaywindow/clexiconreadwindow.cpp
@@ -187,6 +187,8 @@ void CLexiconReadWindow::initView()
qDebug("CLexiconReadWindow::initView");
setDisplayWidget( CDisplay::createReadInstance(this) );
setMainToolBar( new QToolBar(this) );
+ mainToolBar()->setAllowedAreas(Qt::TopToolBarArea);
+ mainToolBar()->setFloatable(false);
addToolBar(mainToolBar());
setKeyChooser( CKeyChooser::createInstance(modules(), key(), mainToolBar()) );
mainToolBar()->addWidget(keyChooser());
@@ -194,6 +196,8 @@ void CLexiconReadWindow::initView()
moduleChooserBar()->adjustSize();
addToolBar(moduleChooserBar());
setButtonsToolBar( new QToolBar(this) );
+ buttonsToolBar()->setAllowedAreas(Qt::TopToolBarArea);
+ buttonsToolBar()->setFloatable(false);
addToolBar(buttonsToolBar());
setWindowIcon(CToolClass::getIconForModule(modules().first()));
setCentralWidget( displayWidget()->view() );
diff --git a/src/frontend/displaywindow/cmodulechooserbar.cpp b/src/frontend/displaywindow/cmodulechooserbar.cpp
index fc891ad..a282c4b 100644
--- a/src/frontend/displaywindow/cmodulechooserbar.cpp
+++ b/src/frontend/displaywindow/cmodulechooserbar.cpp
@@ -22,6 +22,8 @@ CModuleChooserBar::CModuleChooserBar(QList<CSwordModuleInfo*> useModules, CSword
m_idCounter(0),
m_buttonLimit(-1) //-1 means no limit
{
+ setAllowedAreas(Qt::TopToolBarArea);
+ setFloatable(false);
//insert buttons if useModules != 0
QList<CSwordModuleInfo*>::iterator end_it = useModules.end();
for (QList<CSwordModuleInfo*>::iterator it(useModules.begin()); it != end_it; ++it) {
diff --git a/src/frontend/displaywindow/cplainwritewindow.cpp b/src/frontend/displaywindow/cplainwritewindow.cpp
index 9f12020..71dc603 100644
--- a/src/frontend/displaywindow/cplainwritewindow.cpp
+++ b/src/frontend/displaywindow/cplainwritewindow.cpp
@@ -45,6 +45,8 @@ void CPlainWriteWindow::initView() {
setCentralWidget( displayWidget()->view() );
setMainToolBar( new QToolBar(this) );
+ mainToolBar()->setAllowedAreas(Qt::TopToolBarArea);
+ mainToolBar()->setFloatable(false);
addToolBar(mainToolBar());
addToolBarBreak();
diff --git a/src/frontend/keychooser/ckeychooserwidget.cpp b/src/frontend/keychooser/ckeychooserwidget.cpp
index dd8f7a5..d3e1a55 100644
--- a/src/frontend/keychooser/ckeychooserwidget.cpp
+++ b/src/frontend/keychooser/ckeychooserwidget.cpp
@@ -22,20 +22,46 @@
#include <QLineEdit>
#include <QDebug>
+class BtKeyLineEdit : public QLineEdit
+{
+public:
+ BtKeyLineEdit(QWidget* parent)
+ : QLineEdit(parent)
+ {
+ }
+protected:
+ void focusInEvent(QFocusEvent* event)
+ {
+ Qt::FocusReason reason = event->reason();
+ if (reason == Qt::OtherFocusReason)
+ {
+ selectAll();
+ }
+ QWidget::focusInEvent(event);
+ }
+};
+
+
+
CKCComboBox::CKCComboBox()
-: QComboBox() {
+: QComboBox()
+{
setFocusPolicy(Qt::WheelFocus);
+ setLineEdit(new BtKeyLineEdit(this));
if (lineEdit()) {
installEventFilter( lineEdit() );
}
}
/** Reimplementation. */
-bool CKCComboBox::eventFilter( QObject *o, QEvent *e ) {
- if (e->type() == QEvent::FocusOut) {
+bool CKCComboBox::eventFilter( QObject *o, QEvent *e )
+{
+ if (e->type() == QEvent::FocusOut)
+ {
QFocusEvent* f = static_cast<QFocusEvent*>(e);
- if (o == lineEdit() && f->reason() == Qt::TabFocusReason) {
+ if (o == lineEdit() && f->reason() == Qt::TabFocusReason)
+ {
int index = findText(currentText());
if (index == -1) {
index = 0;// return 0 if not found
@@ -45,18 +71,22 @@ bool CKCComboBox::eventFilter( QObject *o, QEvent *e ) {
return false;
}
- else if (f->reason() == Qt::PopupFocusReason) {
+ else if (f->reason() == Qt::PopupFocusReason)
+ {
return false;
}
- else if (f->reason() == Qt::ActiveWindowFocusReason) {
+ else if (f->reason() == Qt::ActiveWindowFocusReason)
+ {
emit activated(currentText());
return false;
}
- else if (f->reason() == Qt::MouseFocusReason) {
+ else if (f->reason() == Qt::MouseFocusReason)
+ {
emit activated(currentText());
return false;
}
- else if (o == this) {
+ else if (o == this)
+ {
emit activated(currentText());
return false;
}
@@ -66,13 +96,15 @@ bool CKCComboBox::eventFilter( QObject *o, QEvent *e ) {
}
/** Scrolls in the list if the wheel of the mouse was used. */
-void CKCComboBox::wheelEvent( QWheelEvent* e ) {
+void CKCComboBox::wheelEvent( QWheelEvent* e )
+{
return QComboBox::wheelEvent(e);
const signed int change = (int)((float)e->delta()/(float)120);
int current = currentIndex();
- if ((current+change >= 0) && (current+change<count()) ) {
+ if ((current+change >= 0) && (current+change<count()) )
+ {
setCurrentIndex(current+change);
e->accept();
emit activated( currentIndex() );
@@ -84,23 +116,28 @@ void CKCComboBox::wheelEvent( QWheelEvent* e ) {
//**********************************************************************************/
-CKeyChooserWidget::CKeyChooserWidget(int count, const bool useNextPrevSignals, QWidget *parent ) : QWidget(parent) {
+CKeyChooserWidget::CKeyChooserWidget(int count, const bool useNextPrevSignals, QWidget *parent ) : QWidget(parent)
+{
m_useNextPrevSignals = useNextPrevSignals;
- for (int index=1; index <= count; index++) {
+ for (int index=1; index <= count; index++)
+ {
m_list.append( QString::number(index) );
}
init();
reset(m_list,0,false);
}
-CKeyChooserWidget::CKeyChooserWidget(QStringList *list, const bool useNextPrevSignals, QWidget *parent ) : QWidget(parent) {
+CKeyChooserWidget::CKeyChooserWidget(QStringList *list, const bool useNextPrevSignals, QWidget *parent ) : QWidget(parent)
+{
m_useNextPrevSignals = useNextPrevSignals;
- if (list) {
+ if (list)
+ {
m_list = *list; //deep copy the items of list
}
- else {
+ else
+ {
m_list.clear();
}
@@ -108,21 +145,24 @@ CKeyChooserWidget::CKeyChooserWidget(QStringList *list, const bool useNextPrevSi
reset(m_list,0,false);
}
-void CKeyChooserWidget::reset(const int count, int index, bool do_emit) {
+void CKeyChooserWidget::reset(const int count, int index, bool do_emit)
+{
//This prevents the widget from resetting during application load, which
//produces undesirable behavior.
//if (!updatesEnabled())
// return;
m_list.clear();
- for (int i=1; i <= count; i++) { //TODO: CHECK
+ for (int i=1; i <= count; i++)
+ { //TODO: CHECK
m_list.append( QString::number(i) );
}
reset(&m_list,index,do_emit);
}
-void CKeyChooserWidget::reset(QStringList& list, int index, bool do_emit) {
+void CKeyChooserWidget::reset(QStringList& list, int index, bool do_emit)
+{
//This prevents the widget from resetting during application load, which
//produces undesirable behavior.
//if (!updatesEnabled())
@@ -133,7 +173,8 @@ void CKeyChooserWidget::reset(QStringList& list, int index, bool do_emit) {
}
-void CKeyChooserWidget::reset(QStringList *list, int index, bool do_emit) {
+void CKeyChooserWidget::reset(QStringList *list, int index, bool do_emit)
+{
//if (isResetting || !updatesEnabled())
if (isResetting)
return;
@@ -147,18 +188,21 @@ void CKeyChooserWidget::reset(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) {
+ if (list)
+ {
m_comboBox->insertItems(-1, *list);
}
if (!list || (list && !list->count())) { //nothing in the combobox
setEnabled(false);
}
- else if (!isEnabled()) { //was disabled
+ else if (!isEnabled())
+ { //was disabled
setEnabled(true);
}
- if (list->count()) {
+ if (list->count())
+ {
m_comboBox->setCurrentIndex(index);
}
if (do_emit) {
@@ -177,13 +221,15 @@ void CKeyChooserWidget::reset(QStringList *list, int index, bool do_emit) {
}
/** Initializes this widget. We need this function because we have more than one constructor. */
-void CKeyChooserWidget::init() {
+void CKeyChooserWidget::init()
+{
qDebug("CKeyChooserWidget::init");
oldKey = QString::null;
setFocusPolicy(Qt::WheelFocus);
m_comboBox = new CKCComboBox();
+ setFocusProxy(m_comboBox);
m_comboBox->setAutoCompletion( true );
m_comboBox->setEditable(true);
m_comboBox->setInsertPolicy(QComboBox::NoInsert);
@@ -200,6 +246,7 @@ void CKeyChooserWidget::init() {
m_mainLayout->addSpacing(0);
setTabOrder(m_comboBox, 0);
+ setFocusProxy(m_comboBox);
connect(m_scroller, SIGNAL(scroller_pressed()), SLOT(lock()));
connect(m_scroller, SIGNAL(scroller_released()), SLOT(unlock()));
@@ -215,13 +262,16 @@ void CKeyChooserWidget::init() {
}
/** Is called when the return key was presed in the combobox. */
-void CKeyChooserWidget::slotReturnPressed( /*const QString& text*/) {
+void CKeyChooserWidget::slotReturnPressed( /*const QString& text*/)
+{
Q_ASSERT(comboBox()->lineEdit());
qDebug("return pressed");
QString text = comboBox()->lineEdit()->text();
- for (int index = 0; index < comboBox()->count(); ++index) {
- if (comboBox()->itemText(index) == text) {
+ for (int index = 0; index < comboBox()->count(); ++index)
+ {
+ if (comboBox()->itemText(index) == text)
+ {
// emit changed(index);
emit focusOut(index); // a workaround because focusOut is not checked, the slot connected to changed to check
break;
@@ -230,16 +280,19 @@ void CKeyChooserWidget::slotReturnPressed( /*const QString& text*/) {
}
/** Is called when the current item of the combo box was changed. */
-void CKeyChooserWidget::slotComboChanged(int index) {
+void CKeyChooserWidget::slotComboChanged(int index)
+{
qDebug("CKeyChooserWidget::slotComboChanged(int index)");
- if (!updatesEnabled()) {
+ if (!updatesEnabled())
+ {
return;
}
setUpdatesEnabled(false);
const QString key = comboBox()->itemText( index );
- if (oldKey.isNull() || (oldKey != key)) {
+ if (oldKey.isNull() || (oldKey != key))
+ {
emit changed(index);
}
@@ -249,17 +302,21 @@ void CKeyChooserWidget::slotComboChanged(int index) {
}
/** Sets the tooltips for the given entries using the parameters as text. */
-void CKeyChooserWidget::setToolTips( const QString comboTip, const QString nextEntryTip, const QString scrollButtonTip, const QString previousEntryTip) {
+void CKeyChooserWidget::setToolTips( const QString comboTip, const QString nextEntryTip, const QString scrollButtonTip, const QString previousEntryTip)
+{
comboBox()->setToolTip(comboTip);
m_scroller->setToolTips(nextEntryTip, scrollButtonTip, previousEntryTip);
}
/** Sets the current item to the one with the given text */
-bool CKeyChooserWidget::setItem( const QString item ) {
+bool CKeyChooserWidget::setItem( const QString item )
+{
bool ret = false;
const int count = comboBox()->count();
- for (int i = 0; i < count; ++i) {
- if (comboBox()->itemText(i) == item) {
+ for (int i = 0; i < count; ++i)
+ {
+ if (comboBox()->itemText(i) == item)
+ {
comboBox()->setCurrentIndex(i);
ret = true;
break;
@@ -271,22 +328,26 @@ bool CKeyChooserWidget::setItem( const QString item ) {
}
/* Handlers for the various scroller widgetset. */
-void CKeyChooserWidget::lock() {
+void CKeyChooserWidget::lock()
+{
updatelock = true;
comboBox()->setEditable(false);
oldKey = comboBox()->currentText();
}
-void CKeyChooserWidget::unlock() {
+void CKeyChooserWidget::unlock()
+{
updatelock = false;
comboBox()->setEditable(true);
comboBox()->setEditText(comboBox()->itemText(comboBox()->currentIndex()));
- if (comboBox()->currentText() != oldKey) {
+ if (comboBox()->currentText() != oldKey)
+ {
emit changed(comboBox()->currentIndex());
}
}
-void CKeyChooserWidget::changeCombo(int n) {
+void CKeyChooserWidget::changeCombo(int n)
+{
const int old_index = comboBox()->currentIndex();
int new_index = old_index + n;
@@ -295,7 +356,8 @@ void CKeyChooserWidget::changeCombo(int n) {
if(new_index > max) new_index = max;
if(new_index < 0) new_index = 0;
- if(new_index != old_index) {
+ if(new_index != old_index)
+ {
comboBox()->setCurrentIndex(new_index);
if(!updatelock)
emit changed(new_index);
diff --git a/src/frontend/keychooser/clexiconkeychooser.cpp b/src/frontend/keychooser/clexiconkeychooser.cpp
index 00c02ba..53d8ac0 100644
--- a/src/frontend/keychooser/clexiconkeychooser.cpp
+++ b/src/frontend/keychooser/clexiconkeychooser.cpp
@@ -42,6 +42,7 @@ CLexiconKeyChooser::CLexiconKeyChooser(QList<CSwordModuleInfo*> modules, CSwordK
m_layout->setSizeConstraint(QLayout::SetNoConstraint);
m_widget = new CKeyChooserWidget(0, false, this);
+ setFocusProxy(m_widget);
//don't allow a too high width, try to keep as narrow as possible
//to aid users with smaller screen resolutions
diff --git a/src/frontend/keychooser/versekeychooser/cbiblekeychooser.cpp b/src/frontend/keychooser/versekeychooser/cbiblekeychooser.cpp
index 2bc9e77..afe3482 100644
--- a/src/frontend/keychooser/versekeychooser/cbiblekeychooser.cpp
+++ b/src/frontend/keychooser/versekeychooser/cbiblekeychooser.cpp
@@ -40,6 +40,7 @@ CBibleKeyChooser::CBibleKeyChooser(QList<CSwordModuleInfo*> modules, CSwordKey *
layout->setDirection( QBoxLayout::LeftToRight );
w_ref = new CKeyReferenceWidget(dynamic_cast<CSwordBibleModuleInfo*>(m_modules.first()), m_key, this);
+ setFocusProxy(w_ref);
layout->addWidget(w_ref);
connect(w_ref,SIGNAL(changed(CSwordVerseKey *)),SLOT(refChanged(CSwordVerseKey *)));
diff --git a/src/frontend/keychooser/versekeychooser/ckeyreferencewidget.cpp b/src/frontend/keychooser/versekeychooser/ckeyreferencewidget.cpp
index 11c5ddc..cedb4b3 100644
--- a/src/frontend/keychooser/versekeychooser/ckeyreferencewidget.cpp
+++ b/src/frontend/keychooser/versekeychooser/ckeyreferencewidget.cpp
@@ -31,12 +31,32 @@
#include <QString>
#include <QStringList>
#include <QToolButton>
+#include <QFocusEvent>
+class BtLineEdit : public QLineEdit
+{
+public:
+ BtLineEdit(QWidget* parent)
+ : QLineEdit(parent)
+ {
+ }
+protected:
+ void focusInEvent(QFocusEvent* event)
+ {
+ Qt::FocusReason reason = event->reason();
+ if (reason == Qt::OtherFocusReason)
+ {
+ selectAll();
+ }
+ QWidget::focusInEvent(event);
+ }
+};
-CKeyReferenceWidget::CKeyReferenceWidget( CSwordBibleModuleInfo *mod, CSwordVerseKey *key, QWidget *parent, const char* /*name*/) :
+
+CKeyReferenceWidget::CKeyReferenceWidget( CSwordBibleModuleInfo *mod, CSwordVerseKey *key, QWidget *parent, const char* /*name*/) :
QWidget(parent),
- m_key(new CSwordVerseKey(mod)),
+ m_key(key),
m_dropDownHoverTimer(this)
{
@@ -53,7 +73,8 @@ CKeyReferenceWidget::CKeyReferenceWidget( CSwordBibleModuleInfo *mod, CSwordVers
m_bookScroller = new CScrollerWidgetSet(this);
- m_textbox = new QLineEdit( this );
+ m_textbox = new BtLineEdit( this );
+ setFocusProxy(m_textbox);
m_textbox->setContentsMargins(0, 0, 0, 0);
setKey(key); // The order of these two functions is important.
@@ -127,7 +148,8 @@ CKeyReferenceWidget::CKeyReferenceWidget( CSwordBibleModuleInfo *mod, CSwordVers
connect(m_verseScroller, SIGNAL(scroller_released()), SLOT(slotUpdateUnlock()));
}
-CKeyReferenceWidget::~CKeyReferenceWidget() {
+CKeyReferenceWidget::~CKeyReferenceWidget()
+{
delete m_dropDownButtons;
}
@@ -140,7 +162,8 @@ void CKeyReferenceWidget::setModule(CSwordBibleModuleInfo *m)
}
}
-bool CKeyReferenceWidget::eventFilter(QObject *o, QEvent *e) {
+bool CKeyReferenceWidget::eventFilter(QObject *o, QEvent *e)
+{
if (o != m_dropDownButtons) return false;
switch (e->type()) {
case QEvent::Enter:
@@ -154,7 +177,8 @@ bool CKeyReferenceWidget::eventFilter(QObject *o, QEvent *e) {
}
}
-void CKeyReferenceWidget::enterEvent(QEvent *) {
+void CKeyReferenceWidget::enterEvent(QEvent *)
+{
m_dropDownHoverTimer.stop();
resetDropDownButtons();
@@ -163,18 +187,22 @@ void CKeyReferenceWidget::enterEvent(QEvent *) {
m_dropDownButtons->show();
}
-void CKeyReferenceWidget::leaveEvent(QEvent *) {
+void CKeyReferenceWidget::leaveEvent(QEvent *)
+{
m_dropDownHoverTimer.start();
}
-void CKeyReferenceWidget::resizeEvent(QResizeEvent *event) {
- if (m_dropDownButtons->isVisible()) {
+void CKeyReferenceWidget::resizeEvent(QResizeEvent *event)
+{
+ if (m_dropDownButtons->isVisible())
+ {
resetDropDownButtons();
}
QWidget::resizeEvent(event);
}
-void CKeyReferenceWidget::resetDropDownButtons() {
+void CKeyReferenceWidget::resetDropDownButtons()
+{
m_dropDownButtons->setParent(window());
int h(m_dropDownButtons->layout()->minimumSize().height());
QPoint topLeft(mapTo(window(), QPoint(m_textbox->x(), height())));
@@ -203,7 +231,7 @@ void CKeyReferenceWidget::updateText()
bool CKeyReferenceWidget::setKey(CSwordVerseKey *key)
{
if (!key) return false;
-
+
m_key->key(key->key());
updateText();
return true;
@@ -218,8 +246,7 @@ void CKeyReferenceWidget::slotReturnPressed()
{
m_key->key(m_textbox->text());
updateText();
-
- emit changed(m_key.get());
+ emit changed(m_key);
}
/* Handlers for the various scroller widgetsets. Do we really want a verse scroller? */
@@ -232,58 +259,70 @@ void CKeyReferenceWidget::slotUpdateLock()
void CKeyReferenceWidget::slotUpdateUnlock()
{
updatelock = false;
- if (oldKey != m_key->key()) emit changed(m_key.get());
+ if (oldKey != m_key->key())
+ emit changed(m_key);
}
void CKeyReferenceWidget::slotStepBook(int n)
{
- n > 0 ? m_key->next( CSwordVerseKey::UseBook ) : m_key->previous( CSwordVerseKey::UseBook );
+ CSwordVerseKey key = *m_key;
+ n > 0 ? key.next( CSwordVerseKey::UseBook ) : key.previous( CSwordVerseKey::UseBook );
+ if (!updatelock)
+ emit changed(&key); // does *m_key = key
updateText();
- if (!updatelock) emit changed(m_key.get());
}
void CKeyReferenceWidget::slotStepChapter(int n)
{
- n > 0 ? m_key->next( CSwordVerseKey::UseChapter ) : m_key->previous( CSwordVerseKey::UseChapter );
- updateText();
- if (!updatelock) emit changed(m_key.get());
+ CSwordVerseKey key = *m_key;
+ n > 0 ? key.next( CSwordVerseKey::UseChapter ) : key.previous( CSwordVerseKey::UseChapter );
+ if (!updatelock)
+ emit changed(&key); // does *m_key = key
+ updateText();
}
void CKeyReferenceWidget::slotStepVerse(int n)
{
- n > 0 ? m_key->next( CSwordVerseKey::UseVerse ) : m_key->previous( CSwordVerseKey::UseVerse );
+ CSwordVerseKey key = *m_key;
+ n > 0 ? key.next( CSwordVerseKey::UseVerse ) : key.previous( CSwordVerseKey::UseVerse );
+ if (!updatelock)
+ emit changed(&key); // does *m_key = key
updateText();
- if (!updatelock) emit changed(m_key.get());
}
void CKeyReferenceWidget::slotChangeVerse(int n)
{
- if (m_key->Verse() != n) {
+ if (m_key->Verse() != n)
+ {
m_key->Verse( n );
- setKey( m_key.get() );
+ setKey( m_key );
}
updateText();
- if (!updatelock) emit changed(m_key.get());
+ if (!updatelock) emit changed(m_key);
}
void CKeyReferenceWidget::slotChangeChapter(int n)
{
- if (m_key->Chapter() != n) {
+ if (m_key->Chapter() != n)
+ {
m_key->Chapter( n );
- setKey( m_key.get() );
+ setKey( m_key );
}
updateText();
- if (!updatelock) emit changed(m_key.get());
+ if (!updatelock)
+ emit changed(m_key);
}
void CKeyReferenceWidget::slotChangeBook(QString bookname)
{
- if (m_key->book() != bookname) {
+ if (m_key->book() != bookname)
+ {
m_key->book( bookname );
- setKey( m_key.get() );
+ setKey( m_key );
}
updateText();
- if (!updatelock) emit changed(m_key.get());
+ if (!updatelock)
+ emit changed(m_key);
}
diff --git a/src/frontend/keychooser/versekeychooser/ckeyreferencewidget.h b/src/frontend/keychooser/versekeychooser/ckeyreferencewidget.h
index 0ecb7a9..0324dbe 100644
--- a/src/frontend/keychooser/versekeychooser/ckeyreferencewidget.h
+++ b/src/frontend/keychooser/versekeychooser/ckeyreferencewidget.h
@@ -14,8 +14,6 @@
#include "backend/drivers/cswordbiblemoduleinfo.h"
#include <QWidget>
-
-#include <boost/scoped_ptr.hpp>
#include <QTimer>
@@ -73,7 +71,7 @@ private:
friend class BtChapterDropdownChooserButton;
friend class BtVerseDropdownChooserButton;
- boost::scoped_ptr<CSwordVerseKey> m_key;
+ CSwordVerseKey *m_key;
QLineEdit* m_textbox;
diff --git a/src/frontend/mainindex/bookmarks/cbookmarkindex.h b/src/frontend/mainindex/bookmarks/cbookmarkindex.h
index 39e2df3..340fabc 100644
--- a/src/frontend/mainindex/bookmarks/cbookmarkindex.h
+++ b/src/frontend/mainindex/bookmarks/cbookmarkindex.h
@@ -26,7 +26,6 @@ class CSwordModuleInfo;
#include <QTreeWidgetItem>
class CSearchDialog;
-class CMainIndex;
class QWidget;
class QDropEvent;
class QDragMoveEvent;
diff --git a/src/frontend/mainindex/bookshelf/btindexitem.h b/src/frontend/mainindex/bookshelf/btindexitem.h
index 33d2f7b..d9e74ad 100644
--- a/src/frontend/mainindex/bookshelf/btindexitem.h
+++ b/src/frontend/mainindex/bookshelf/btindexitem.h
@@ -15,7 +15,6 @@
#include <QTreeWidgetItem>
#include <QString>
-class CMainIndex;
class QMimeData;
class QAction;
diff --git a/src/frontend/mainindex/bookshelf/cbookshelfindex.h b/src/frontend/mainindex/bookshelf/cbookshelfindex.h
index f9e56e7..bd21069 100644
--- a/src/frontend/mainindex/bookshelf/cbookshelfindex.h
+++ b/src/frontend/mainindex/bookshelf/cbookshelfindex.h
@@ -27,7 +27,6 @@ class CSwordModuleInfo;
class CSearchDialog;
-class CMainIndex;
class QWidget;
class QDropEvent;
class QDragMoveEvent;
diff --git a/src/frontend/mainindex/btbookshelfview.cpp b/src/frontend/mainindex/btbookshelfview.cpp
new file mode 100644
index 0000000..52d0ec4
--- /dev/null
+++ b/src/frontend/mainindex/btbookshelfview.cpp
@@ -0,0 +1,105 @@
+/*********
+*
+* 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-2009 by the BibleTime developers.
+* The BibleTime source code is licensed under the GNU General Public License
+* version 2.0.
+*
+**********/
+
+#include "frontend/mainindex/btbookshelfview.h"
+
+#include <QApplication>
+#include <QHeaderView>
+#include <QMouseEvent>
+#include "backend/bookshelfmodel/btbookshelftreemodel.h"
+#include "backend/drivers/cswordmoduleinfo.h"
+
+BtBookshelfView::BtBookshelfView(QWidget *parent)
+ : QTreeView(parent)
+{
+ header()->hide();
+
+ /*
+ Uncommenting the following statement will hide the [+]expand/[-]collapse
+ controls in front of first-level items, which might not be desirable since
+ hiding them also means that one has to do a total of 2 clicks (double-
+ click)to expand or collapse top-level items:
+ */
+ // setRootIsDecorated(false);
+
+ connect(this, SIGNAL(activated(QModelIndex)),
+ this, SLOT(slotItemActivated(QModelIndex)));
+}
+
+BtBookshelfView::~BtBookshelfView() {
+ // Intentionally empty
+}
+
+CSwordModuleInfo *BtBookshelfView::getModule(const QModelIndex &index) const {
+ return (CSwordModuleInfo *) model()
+ ->data(index, BtBookshelfModel::ModulePointerRole).value<void*>();
+}
+
+void BtBookshelfView::keyPressEvent(QKeyEvent *event) {
+ switch (event->key()) {
+ case Qt::Key_Menu:
+ scrollTo(currentIndex());
+ {
+ CSwordModuleInfo *i(getModule(currentIndex()));
+ QRect itemRect(visualRect(currentIndex()));
+ QPoint p(viewport()->mapToGlobal(itemRect.bottomLeft()));
+ if (i == 0) {
+ emit contextMenuActivated(p);
+ } else {
+ emit moduleContextMenuActivated(i, p);
+ }
+ }
+ event->accept();
+ break;
+ case Qt::Key_Return:
+ case Qt::Key_Enter:
+ {
+ QModelIndex i(currentIndex());
+ CSwordModuleInfo *m(getModule(i));
+ if (m != 0) {
+ emit moduleActivated(m);
+ } else {
+ setExpanded(i, !isExpanded(i));
+ }
+ }
+ event->accept();
+ break;
+ default:
+ QTreeView::keyPressEvent(event);
+ break;
+ }
+}
+
+void BtBookshelfView::mousePressEvent(QMouseEvent *event) {
+ if (event->buttons() == Qt::RightButton) {
+ QModelIndex clickedItemIndex(indexAt(event->pos()));
+ if (clickedItemIndex.isValid()) {
+ setCurrentIndex(clickedItemIndex);
+ }
+ CSwordModuleInfo *i(getModule(clickedItemIndex));
+ if (i == 0) {
+ emit contextMenuActivated(mapToGlobal(event->pos()));
+ } else {
+ emit moduleContextMenuActivated(i, mapToGlobal(event->pos()));
+ }
+ event->accept();
+ } else {
+ QTreeView::mousePressEvent(event);
+ }
+}
+
+void BtBookshelfView::slotItemActivated(const QModelIndex &index) {
+ CSwordModuleInfo *i(getModule(index));
+ if (i != 0) {
+ emit moduleActivated(i);
+ }
+}
diff --git a/src/frontend/mainindex/btbookshelfview.h b/src/frontend/mainindex/btbookshelfview.h
new file mode 100644
index 0000000..80c7f31
--- /dev/null
+++ b/src/frontend/mainindex/btbookshelfview.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-2009 by the BibleTime developers.
+* The BibleTime source code is licensed under the GNU General Public License
+* version 2.0.
+*
+**********/
+
+#ifndef BTBOOKSHELFVIEW_H
+#define BTBOOKSHELFVIEW_H
+
+#include <QTreeView>
+
+class CSwordModuleInfo;
+
+class BtBookshelfView: public QTreeView {
+ Q_OBJECT
+ public:
+ BtBookshelfView(QWidget *parent = 0);
+ virtual ~BtBookshelfView();
+
+ CSwordModuleInfo *getModule(const QModelIndex &index) const;
+
+ signals:
+ void contextMenuActivated(QPoint pos);
+ void moduleContextMenuActivated(CSwordModuleInfo *item,
+ QPoint pos);
+ void moduleActivated(CSwordModuleInfo *item);
+
+ protected:
+ void keyPressEvent(QKeyEvent *event);
+ void mousePressEvent(QMouseEvent *event);
+
+ protected slots:
+ void slotItemActivated(const QModelIndex &index);
+};
+
+#endif // BTBOOKSHELFVIEW_H
diff --git a/src/frontend/mainindex/cmainindex.cpp b/src/frontend/mainindex/cmainindex.cpp
deleted file mode 100644
index 04341b0..0000000
--- a/src/frontend/mainindex/cmainindex.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-/*********
-*
-* This file is part of BibleTime's source code, http://www.bibletime.info/.
-*
-* Copyright 1999-2008 by the BibleTime developers.
-* The BibleTime source code is licensed under the GNU General Public License version 2.0.
-*
-**********/
-
-//BibleTime includes
-#include "cmainindex.h"
-
-#include "backend/drivers/cswordmoduleinfo.h"
-
-#include "bookshelf/cbookshelfindex.h"
-#include "bookmarks/cbookmarkindex.h"
-
-#include <QTabWidget>
-
-
-CMainIndex::CMainIndex(QWidget *parent) : QTabWidget(parent)
-{
- setFocusPolicy(Qt::StrongFocus);
- m_bookmarksPage = new CBookmarkIndex(0);
- m_bookshelfPage = new CBookshelfIndex(0);
- addTab(m_bookshelfPage, tr("Bookshelf"));
- addTab(m_bookmarksPage, tr("Bookmarks"));
-
- //shortcut some signals from pages to signals of this widget so that outsiders
- // do not have to use the pages directly
- QObject::connect(m_bookshelfPage, SIGNAL(createReadDisplayWindow( QList<CSwordModuleInfo*>, const QString& )), this, SIGNAL(createReadDisplayWindow( QList<CSwordModuleInfo*>, const QString& )));
- QObject::connect(m_bookmarksPage, SIGNAL(createReadDisplayWindow( QList<CSwordModuleInfo*>, const QString& )), this, SIGNAL(createReadDisplayWindow( QList<CSwordModuleInfo*>, const QString& )));
-
- QObject::connect(m_bookshelfPage, SIGNAL(createWriteDisplayWindow( CSwordModuleInfo*, const QString&, const CDisplayWindow::WriteWindowType& )), this, SIGNAL(createWriteDisplayWindow( CSwordModuleInfo*, const QString&, const CDisplayWindow::WriteWindowType&)));
-
-}
diff --git a/src/frontend/mainindex/cmainindex.h b/src/frontend/mainindex/cmainindex.h
deleted file mode 100644
index b5d217d..0000000
--- a/src/frontend/mainindex/cmainindex.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*********
-*
-* This file is part of BibleTime's source code, http://www.bibletime.info/.
-*
-* Copyright 1999-2008 by the BibleTime developers.
-* The BibleTime source code is licensed under the GNU General Public License version 2.0.
-*
-**********/
-
-#ifndef CMAININDEX_H
-#define CMAININDEX_H
-
-#include "frontend/displaywindow/cdisplaywindow.h"
-
-#include <QTabWidget>
-#include <QFocusEvent>
-
-class CBookmarkIndex;
-class CBookshelfIndex;
-class CSwordModuleInfo;
-
-/** The class which manages all bookmarks and modules. The modules are put into own, fixed subfolders sorted by language.
- * @author The BibleTime team
- */
-class CMainIndex : public QTabWidget {
- Q_OBJECT
-
-public:
- CMainIndex(QWidget *parent);
- virtual ~CMainIndex() {};
-
- //void reloadSword();
-
- CBookshelfIndex* bookshelfIndex() {return m_bookshelfPage;}
-
-signals:
- /**
- * Is emitted when a module should be opened,
- */
- void createReadDisplayWindow( QList<CSwordModuleInfo*>, const QString& );
- /**
- * Is emitted when a write window should be created.
- */
- void createWriteDisplayWindow( CSwordModuleInfo*, const QString&, const CDisplayWindow::WriteWindowType& );
-
-protected:
- /** QWidget method - move focus to the active page widget */
- virtual void focusInEvent(QFocusEvent*) {currentWidget()->setFocus();}
-
-private:
-
- CBookmarkIndex* m_bookmarksPage;
- CBookshelfIndex* m_bookshelfPage;
-
-};
-
-#endif
diff --git a/src/main.cpp b/src/main.cpp
index bf8aff7..785cc1c 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -178,7 +178,7 @@ int main(int argc, char* argv[]) {
BibleTime bibleTime;
// a new BibleTime version was installed (maybe a completely new installation)
- if (CBTConfig::get(CBTConfig::bibletimeVersion) != BT_VERSION)
+ if (CBTConfig::get(CBTConfig::bibletimeVersion) != BT_VERSION)
{
CBTConfig::set(CBTConfig::bibletimeVersion, BT_VERSION);
bibleTime.saveConfigSettings();
@@ -192,6 +192,7 @@ int main(int argc, char* argv[]) {
#ifndef NO_DBUS
new BibleTimeDBusAdaptor(&bibleTime);
// connect to D-Bus and register as an object:
+ QDBusConnection::sessionBus().registerService("info.bibletime.BibleTime");
QDBusConnection::sessionBus().registerObject("/BibleTime", &bibleTime);
#endif
diff --git a/src/util/cresmgr.cpp b/src/util/cresmgr.cpp
index 27eb8f4..e0c7573 100644
--- a/src/util/cresmgr.cpp
+++ b/src/util/cresmgr.cpp
@@ -233,7 +233,7 @@ namespace CResMgr {
namespace general {
namespace search {
const QString icon = "find.svg";
- const QKeySequence accel(Qt::CTRL + Qt::Key_L);
+ const QKeySequence accel(Qt::CTRL + Qt::Key_N);
const char* actionName = "window_search_action";
}