summaryrefslogtreecommitdiff
path: root/src/backend/bookshelfmodel
diff options
context:
space:
mode:
authorRoberto C. Sanchez <roberto@connexer.com>2014-10-21 22:48:31 -0400
committerRoberto C. Sanchez <roberto@connexer.com>2014-10-21 22:48:31 -0400
commit294b5ec5834affa57641475946b8d2aeca53c577 (patch)
treeca25b634d0f24ab5b1fc38eb805e72e0e993e0f1 /src/backend/bookshelfmodel
parente8a196082586bb68e0bf254a8f6f4b8f39071f32 (diff)
Imported Upstream version 2.4
Diffstat (limited to 'src/backend/bookshelfmodel')
-rw-r--r--src/backend/bookshelfmodel/btbookshelfmodel.cpp74
-rw-r--r--src/backend/bookshelfmodel/btbookshelfmodel.h8
-rw-r--r--src/backend/bookshelfmodel/btbookshelftreemodel.cpp205
-rw-r--r--src/backend/bookshelfmodel/btbookshelftreemodel.h24
-rw-r--r--src/backend/bookshelfmodel/btmodulecategoryfilterproxymodel.cpp71
-rw-r--r--src/backend/bookshelfmodel/btmodulecategoryfilterproxymodel.h49
-rw-r--r--src/backend/bookshelfmodel/btmodulehiddenfilterproxymodel.cpp61
-rw-r--r--src/backend/bookshelfmodel/btmodulehiddenfilterproxymodel.h48
-rw-r--r--src/backend/bookshelfmodel/btmodulenamefilterproxymodel.cpp6
-rw-r--r--src/backend/bookshelfmodel/btmodulenamefilterproxymodel.h1
-rw-r--r--src/backend/bookshelfmodel/categoryitem.cpp8
-rw-r--r--src/backend/bookshelfmodel/categoryitem.h3
-rw-r--r--src/backend/bookshelfmodel/distributionitem.cpp1
-rw-r--r--src/backend/bookshelfmodel/distributionitem.h3
-rw-r--r--src/backend/bookshelfmodel/item.cpp9
-rw-r--r--src/backend/bookshelfmodel/item.h9
-rw-r--r--src/backend/bookshelfmodel/languageitem.cpp3
-rw-r--r--src/backend/bookshelfmodel/languageitem.h7
-rw-r--r--src/backend/bookshelfmodel/moduleitem.cpp3
-rw-r--r--src/backend/bookshelfmodel/moduleitem.h9
20 files changed, 482 insertions, 120 deletions
diff --git a/src/backend/bookshelfmodel/btbookshelfmodel.cpp b/src/backend/bookshelfmodel/btbookshelfmodel.cpp
index 99f83ba..6882b90 100644
--- a/src/backend/bookshelfmodel/btbookshelfmodel.cpp
+++ b/src/backend/bookshelfmodel/btbookshelfmodel.cpp
@@ -14,7 +14,8 @@
#include <QSet>
#include "util/cresmgr.h"
-#include "util/directoryutil.h"
+#include "util/directory.h"
+
BtBookshelfModel::BtBookshelfModel(QObject *parent)
: QAbstractListModel(parent) {
@@ -29,25 +30,35 @@ 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();
-
+QVariant BtBookshelfModel::data(CSwordModuleInfo *module, int role) const {
switch (role) {
case ModuleNameRole: // Qt::DisplayRole
- return m_data.at(row)->name();
+ return module->name();
case ModuleIconRole: // Qt::DecorationRole
- return moduleIcon(m_data.at(row));
+ return moduleIcon(module);
case ModulePointerRole:
- return qVariantFromValue((void*) m_data.at(row));
+ return qVariantFromValue((void*) module);
+ case ModuleCategoryRole:
+ return QVariant::fromValue(module->category());
+ case ModuleLanguageRole:
+ return QVariant(); /// \todo Unimplemented
+ case ModuleHiddenRole:
+ return module->isHidden();
default:
return QVariant();
}
}
+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();
+
+ return data(m_data.at(row), role);
+}
+
QVariant BtBookshelfModel::headerData(int section, Qt::Orientation orientation,
int role) const {
if (role == Qt::DisplayRole && orientation == Qt::Horizontal &&
@@ -58,8 +69,25 @@ QVariant BtBookshelfModel::headerData(int section, Qt::Orientation orientation,
return QVariant();
}
+bool BtBookshelfModel::setData(const QModelIndex &index, const QVariant &value,
+ int role) {
+ int row(index.row());
+ if (role == ModuleHiddenRole && row >= 0 && row < m_data.size()
+ && index.column() == 0)
+ {
+ /*
+ Emitting dataChanged here is actually mandatory, but were not doing it
+ directly. Since we're connected to the module, changing its hidden
+ state will emit a signal we catch in moduleHidden(), which in turn is
+ what will actually emit dataChanged().
+ */
+ return m_data.at(row)->setHidden(value.toBool());
+ }
+ return false;
+}
+
QIcon BtBookshelfModel::moduleIcon(const CSwordModuleInfo *m) {
- typedef util::filesystem::DirectoryUtil DU;
+ namespace DU = util::directory;
/// \todo Make CSwordModuleInfo::isLocked() const and remove const_cast:
CSwordModuleInfo *module(const_cast<CSwordModuleInfo*>(m));
@@ -101,7 +129,7 @@ QIcon BtBookshelfModel::moduleIcon(const CSwordModuleInfo *m) {
}
QIcon BtBookshelfModel::categoryIcon(const CSwordModuleInfo::Category &category) {
- typedef util::filesystem::DirectoryUtil DU;
+ namespace DU = util::directory;
switch (category) {
case CSwordModuleInfo::Bibles:
@@ -174,6 +202,8 @@ void BtBookshelfModel::addModule(CSwordModuleInfo * const module) {
const int index(m_data.size());
beginInsertRows(QModelIndex(), index, index);
m_data.append(module);
+ connect(module, SIGNAL(hiddenChanged(bool)),
+ this, SLOT(moduleHidden(bool)));
endInsertRows();
}
@@ -193,13 +223,11 @@ void BtBookshelfModel::addModules(const QSet<CSwordModuleInfo *> &modules) {
beginInsertRows(QModelIndex(), m_data.size(),
m_data.size() + newModules.size() - 1);
-#if QT_VERSION >= 0x040500
- m_data.append(newModules);
-#else
Q_FOREACH(CSwordModuleInfo *module, newModules) {
m_data.append(module);
+ connect(module, SIGNAL(hiddenChanged(bool)),
+ this, SLOT(moduleHidden(bool)));
}
-#endif
endInsertRows();
}
@@ -210,6 +238,8 @@ void BtBookshelfModel::removeModule(CSwordModuleInfo * const module,
if (index == -1) return;
beginRemoveRows(QModelIndex(), index, index);
+ disconnect(module, SIGNAL(hiddenChanged(bool)),
+ this, SLOT(moduleHidden(bool)));
m_data.removeAt(index);
endRemoveRows();
if (destroy) delete module;
@@ -236,3 +266,13 @@ CSwordModuleInfo* BtBookshelfModel::getModule(const QString &name) const {
}
return 0;
}
+
+void BtBookshelfModel::moduleHidden(bool) {
+ Q_ASSERT(qobject_cast<CSwordModuleInfo*>(sender()) != 0);
+
+ CSwordModuleInfo *module(static_cast<CSwordModuleInfo*>(sender()));
+ Q_ASSERT(m_data.count(module) == 1);
+
+ QModelIndex i(index(m_data.indexOf(module), 0));
+ emit dataChanged(i, i);
+}
diff --git a/src/backend/bookshelfmodel/btbookshelfmodel.h b/src/backend/bookshelfmodel/btbookshelfmodel.h
index 01fc260..16fdb13 100644
--- a/src/backend/bookshelfmodel/btbookshelfmodel.h
+++ b/src/backend/bookshelfmodel/btbookshelfmodel.h
@@ -17,6 +17,7 @@
#include "backend/drivers/cswordmoduleinfo.h"
+
class BtBookshelfModel: public QAbstractListModel {
Q_OBJECT
public:
@@ -26,6 +27,7 @@ class BtBookshelfModel: public QAbstractListModel {
ModulePointerRole = Qt::UserRole,
ModuleCategoryRole = Qt::UserRole + 1,
ModuleLanguageRole = Qt::UserRole + 2,
+ ModuleHiddenRole = Qt::UserRole + 3,
UserRole = Qt::UserRole + 100
};
@@ -33,9 +35,12 @@ class BtBookshelfModel: public QAbstractListModel {
virtual ~BtBookshelfModel();
virtual int rowCount(const QModelIndex &parent) const;
+ virtual QVariant data(CSwordModuleInfo *module, int role) const;
virtual QVariant data(const QModelIndex &index, int role) const;
virtual QVariant headerData(int section, Qt::Orientation orientation,
int role = Qt::DisplayRole) const;
+ bool setData(const QModelIndex &index, const QVariant &value,
+ int role = ModuleHiddenRole);
inline CSwordModuleInfo *module(const QModelIndex &index) const {
return (CSwordModuleInfo *)
@@ -64,6 +69,9 @@ class BtBookshelfModel: public QAbstractListModel {
return m_data;
}
+ protected slots:
+ void moduleHidden(bool hidden);
+
protected:
QList<CSwordModuleInfo *> m_data;
};
diff --git a/src/backend/bookshelfmodel/btbookshelftreemodel.cpp b/src/backend/bookshelfmodel/btbookshelftreemodel.cpp
index 8e457e7..5be1aec 100644
--- a/src/backend/bookshelfmodel/btbookshelftreemodel.cpp
+++ b/src/backend/bookshelfmodel/btbookshelftreemodel.cpp
@@ -12,25 +12,26 @@
#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_defaultChecked(MODULE_HIDDEN), m_checkable(false) {
m_groupingOrder.push_back(GROUP_CATEGORY);
m_groupingOrder.push_back(GROUP_LANGUAGE);
}
BtBookshelfTreeModel::BtBookshelfTreeModel(const Grouping &g, QObject *parent)
: QAbstractItemModel(parent), m_sourceModel(0), m_rootItem(new RootItem),
- m_groupingOrder(g), m_checkable(false), m_defaultChecked(false) {
+ m_groupingOrder(g), m_defaultChecked(MODULE_HIDDEN), m_checkable(false)
+{
// Intentionally empty
}
@@ -79,8 +80,6 @@ QModelIndex BtBookshelfTreeModel::parent(const QModelIndex &index) const {
}
QVariant BtBookshelfTreeModel::data(const QModelIndex &index, int role) const {
- typedef util::filesystem::DirectoryUtil DU;
-
if (!index.isValid() || index.column() != 0) {
return QVariant();
}
@@ -89,22 +88,33 @@ QVariant BtBookshelfTreeModel::data(const QModelIndex &index, int role) const {
Q_ASSERT(i != 0);
switch (role) {
case Qt::DisplayRole:
- return i->name();
+ if (i->type() == Item::ITEM_MODULE) {
+ return parentData(static_cast<ModuleItem *>(i), role);
+ } else {
+ return i->name();
+ }
case Qt::CheckStateRole:
if (!m_checkable) break;
case BtBookshelfTreeModel::CheckStateRole:
return i->checkState();
case Qt::DecorationRole:
- return i->icon();
+ if (i->type() == Item::ITEM_MODULE) {
+ return parentData(static_cast<ModuleItem *>(i), role);
+ } else {
+ 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());
- }
+ ModuleItem *mi(static_cast<ModuleItem *>(i));
+ return qVariantFromValue((void*) mi->moduleInfo());
}
return 0;
+ case BtBookshelfModel::ModuleHiddenRole:
+ return i->isHidden();
default:
+ if (i->type() == Item::ITEM_MODULE) {
+ return parentData(static_cast<ModuleItem *>(i), role);
+ }
break;
}
return QVariant();
@@ -115,37 +125,47 @@ bool BtBookshelfTreeModel::setData(const QModelIndex &itemIndex,
int role) {
typedef QPair<Item *, QModelIndex> IP;
- if (role == Qt::CheckStateRole) {
+ Qt::CheckState newState;
+ if (role == BtBookshelfModel::ModuleHiddenRole) {
+ newState = value.toBool() ? Qt::Checked : Qt::Unchecked;
+ } else 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);
+ newState = (Qt::CheckState) value.toInt(&ok);
+ if (!ok || newState == Qt::PartiallyChecked) return false;
+ } else {
+ return false;
+ }
+
+ Item *item(static_cast<Item*>(itemIndex.internalPointer()));
+ Q_ASSERT(item != 0);
+ if (item->checkState() == newState) return false;
+
+ // Recursively (un)check all children:
+ QList<IP> q;
+ IP p(item, itemIndex);
+ for (;;) {
+ if (item->checkState() != newState) {
+ item->setCheckState(newState);
+ emit dataChanged(p.second, p.second);
+ if (item->type() == Item::ITEM_MODULE) {
+ ModuleItem *mi(static_cast<ModuleItem*>(item));
+ emit moduleChecked(mi->moduleInfo(), newState == Qt::Checked);
+ } else {
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)));
}
}
+ }
+ if (q.empty()) break;
+ p = q.takeFirst();
+ item = p.first;
+ }
- // Change check state of the item itself
- i->setCheckState(newState);
- emit dataChanged(itemIndex, itemIndex);
-
- // Recursively change parent check states.
- resetParentCheckStates(itemIndex.parent());
+ // Recursively change parent check states.
+ resetParentCheckStates(itemIndex.parent());
- return true;
- } // if (ok && newState != Qt::PartiallyChecked)
- } // if (role == Qt::CheckStateRole)
- return false;
+ return true;
}
Qt::ItemFlags BtBookshelfTreeModel::flags(const QModelIndex &index) const {
@@ -176,7 +196,7 @@ QVariant BtBookshelfTreeModel::headerData(int section,
return QVariant();
}
-void BtBookshelfTreeModel::setSourceModel(QAbstractListModel *sourceModel) {
+void BtBookshelfTreeModel::setSourceModel(QAbstractItemModel *sourceModel) {
if (m_sourceModel == sourceModel) return;
if (m_sourceModel != 0) {
@@ -186,6 +206,7 @@ void BtBookshelfTreeModel::setSourceModel(QAbstractListModel *sourceModel) {
beginRemoveRows(QModelIndex(), 0, m_rootItem->children().size() - 1);
delete m_rootItem;
m_modules.clear();
+ m_sourceIndexMap.clear();
m_rootItem = new RootItem;
endRemoveRows();
}
@@ -200,28 +221,25 @@ void BtBookshelfTreeModel::setSourceModel(QAbstractListModel *sourceModel) {
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
- );
+ for (int i(0); i < sourceModel->rowCount(); i++) {
+ typedef BtBookshelfModel::ModuleRole MRole;
+ static const MRole HR(BtBookshelfModel::ModuleHiddenRole);
+ static const MRole PR(BtBookshelfModel::ModulePointerRole);
+ QModelIndex moduleIndex(sourceModel->index(i, 0));
+ CSwordModuleInfo *module(
+ static_cast<CSwordModuleInfo *>(
+ sourceModel->data(moduleIndex, PR).value<void*>()
+ )
+ );
+ Q_ASSERT(module != 0);
+ bool checked;
+ if (m_defaultChecked == MODULE_HIDDEN) {
+ checked = !sourceModel->data(moduleIndex, HR).toBool();
+ } else {
+ checked = (m_defaultChecked == CHECKED);
}
+ m_sourceIndexMap[module] = moduleIndex;
+ addModule(module, checked);
}
}
}
@@ -249,7 +267,7 @@ void BtBookshelfTreeModel::setGroupingOrder(const Grouping &groupingOrder) {
CSwordModuleInfo *module(
static_cast<CSwordModuleInfo *>(
m_sourceModel->data(
- m_sourceModel->index(i),
+ m_sourceModel->index(i, 0),
BtBookshelfModel::ModulePointerRole
).value<void*>()
)
@@ -295,6 +313,14 @@ QList<CSwordModuleInfo*> BtBookshelfTreeModel::checkedModules() const {
return modules;
}
+QVariant BtBookshelfTreeModel::parentData(BookshelfModel::ModuleItem *item,
+ int role) const
+{
+ CSwordModuleInfo* m(item->moduleInfo());
+ Q_ASSERT(m_sourceIndexMap.contains(m));
+ return m_sourceModel->data(m_sourceIndexMap.value(m), role);
+}
+
void BtBookshelfTreeModel::addModule(CSwordModuleInfo *module, bool checked) {
if (m_modules.contains(module)) return;
Grouping g(m_groupingOrder);
@@ -345,8 +371,9 @@ void BtBookshelfTreeModel::addModule(CSwordModuleInfo *module,
}
void BtBookshelfTreeModel::removeModule(CSwordModuleInfo *module) {
- Item *i(m_modules.value(module, 0));
- if (i == 0) return;
+ if (!m_modules.contains(module)) return;
+
+ Item *i(m_modules[module]);
// Set i to be the lowest item (including empty groups) to remove:
Q_ASSERT(i->parent() != 0);
@@ -354,22 +381,11 @@ void BtBookshelfTreeModel::removeModule(CSwordModuleInfo *module) {
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);
- }
- }
+ Q_ASSERT(i->parent() != 0);
// Remove item:
int index(i->childIndex());
+ QModelIndex parentIndex(getIndex(i->parent()));
beginRemoveRows(parentIndex, index, index);
i->parent()->deleteChildAt(index);
m_modules.remove(module);
@@ -388,6 +404,24 @@ Item *BtBookshelfTreeModel::getItem(const QModelIndex &index) const {
}
}
+QModelIndex BtBookshelfTreeModel::getIndex(const BookshelfModel::Item *item) {
+ Q_ASSERT(item != 0);
+
+ QList<int> indexes;
+ for (;;) {
+ int i(item->childIndex());
+ if (i < 0) break;
+ indexes.append(i);
+ item = item->parent();
+ }
+
+ QModelIndex i;
+ while (!indexes.isEmpty()) {
+ i = index(indexes.takeLast(), 0, i);
+ }
+ return i;
+}
+
void BtBookshelfTreeModel::resetParentCheckStates(QModelIndex parentIndex) {
for ( ; parentIndex.isValid(); parentIndex = parentIndex.parent()) {
Item *parentItem(static_cast<Item*>(parentIndex.internalPointer()));
@@ -445,11 +479,19 @@ void BtBookshelfTreeModel::moduleDataChanged(const QModelIndex &topLeft,
QModelIndex moduleIndex(m_sourceModel->index(i, 0, topLeft.parent()));
QVariant data(m_sourceModel->data(moduleIndex, PR));
CSwordModuleInfo *module((CSwordModuleInfo *) (data.value<void*>()));
+ QModelIndex itemIndex(getIndex(m_modules[module]));
+ Q_ASSERT(itemIndex.isValid());
- /// \todo There might be a better way to do this.
- bool checked(m_modules.value(module)->checkState() == Qt::Checked);
- removeModule(module);
- addModule(module, checked);
+ emit dataChanged(itemIndex, itemIndex);
+
+ /*
+ Also emit signals for parent items because the change might alter them
+ as well, e.g. isHidden()
+ */
+ do {
+ itemIndex = itemIndex.parent();
+ emit dataChanged(itemIndex, itemIndex);
+ } while (itemIndex.isValid());
}
}
@@ -457,13 +499,21 @@ void BtBookshelfTreeModel::moduleInserted(const QModelIndex &parent, int start,
int end) {
typedef BtBookshelfModel BM;
static const BM::ModuleRole PR(BM::ModulePointerRole);
+ static const BM::ModuleRole HR(BM::ModuleHiddenRole);
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);
+ bool checked;
+ if (m_defaultChecked == MODULE_HIDDEN) {
+ checked = !m_sourceModel->data(moduleIndex, HR).toBool();
+ } else {
+ checked = (m_defaultChecked == CHECKED);
+ }
+ m_sourceIndexMap[module] = moduleIndex;
+ addModule(module, checked);
}
}
@@ -478,6 +528,7 @@ void BtBookshelfTreeModel::moduleRemoved(const QModelIndex &parent, int start,
CSwordModuleInfo *module((CSwordModuleInfo *) (data.value<void*>()));
removeModule(module);
+ m_sourceIndexMap.remove(module);
}
}
diff --git a/src/backend/bookshelfmodel/btbookshelftreemodel.h b/src/backend/bookshelfmodel/btbookshelftreemodel.h
index 84293e1..e73b154 100644
--- a/src/backend/bookshelfmodel/btbookshelftreemodel.h
+++ b/src/backend/bookshelfmodel/btbookshelftreemodel.h
@@ -16,9 +16,11 @@
#include <QAbstractItemModel>
#include <QMap>
+#include <QPersistentModelIndex>
#include "backend/bookshelfmodel/btbookshelfmodel.h"
#include "backend/bookshelfmodel/item.h"
+
namespace BookshelfModel {
class ModuleItem;
}
@@ -30,6 +32,7 @@ class BtBookshelfTreeModel: public QAbstractItemModel {
Q_ENUMS(Group)
typedef QMap<CSwordModuleInfo*, BookshelfModel::ModuleItem*> ModuleItemMap;
+ typedef QMap<CSwordModuleInfo*, QPersistentModelIndex> SourceIndexMap;
public:
enum ModuleRole {
@@ -37,6 +40,7 @@ class BtBookshelfTreeModel: public QAbstractItemModel {
UserRole = BtBookshelfModel::UserRole + 100
};
enum Group { GROUP_CATEGORY = 0, GROUP_LANGUAGE, GROUP_DISTRIBUTION };
+ enum CheckedBehavior { CHECKED, UNCHECKED, MODULE_HIDDEN };
typedef QList<Group> Grouping;
BtBookshelfTreeModel(QObject *parent = 0);
@@ -59,8 +63,8 @@ class BtBookshelfTreeModel: public QAbstractItemModel {
virtual bool setData(const QModelIndex &index, const QVariant &value,
int role);
- void setSourceModel(QAbstractListModel *sourceModel);
- inline QAbstractListModel *sourceModel() const {
+ void setSourceModel(QAbstractItemModel *sourceModel);
+ inline QAbstractItemModel *sourceModel() const {
return m_sourceModel;
}
void setGroupingOrder(const Grouping &groupingOrder);
@@ -71,22 +75,24 @@ class BtBookshelfTreeModel: public QAbstractItemModel {
inline bool checkable() const {
return m_checkable;
}
- inline void setDefaultChecked(bool defaultChecked) {
- m_defaultChecked = defaultChecked;
+ inline void setDefaultChecked(CheckedBehavior b) {
+ m_defaultChecked = b;
}
- inline bool defaultChecked() const {
+ inline CheckedBehavior defaultChecked() const {
return m_defaultChecked;
}
QList<CSwordModuleInfo*> checkedModules() const;
protected:
+ QVariant parentData(BookshelfModel::ModuleItem *item, int role) const;
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;
+ QModelIndex getIndex(const BookshelfModel::Item *item);
void resetParentCheckStates(QModelIndex parentIndex);
template <class T>
@@ -112,13 +118,17 @@ class BtBookshelfTreeModel: public QAbstractItemModel {
void moduleInserted(const QModelIndex &parent, int start, int end);
void moduleRemoved(const QModelIndex &parent, int start, int end);
+ signals:
+ void moduleChecked(CSwordModuleInfo *module, bool checked);
+
protected:
- QAbstractListModel *m_sourceModel;
+ QAbstractItemModel *m_sourceModel;
BookshelfModel::Item *m_rootItem;
ModuleItemMap m_modules;
+ SourceIndexMap m_sourceIndexMap;
Grouping m_groupingOrder;
+ CheckedBehavior m_defaultChecked;
bool m_checkable;
- bool m_defaultChecked;
};
QDataStream &operator<<(QDataStream &os, const BtBookshelfTreeModel::Grouping &o);
diff --git a/src/backend/bookshelfmodel/btmodulecategoryfilterproxymodel.cpp b/src/backend/bookshelfmodel/btmodulecategoryfilterproxymodel.cpp
new file mode 100644
index 0000000..a969218
--- /dev/null
+++ b/src/backend/bookshelfmodel/btmodulecategoryfilterproxymodel.cpp
@@ -0,0 +1,71 @@
+/*********
+*
+* 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/btmodulecategoryfilterproxymodel.h"
+
+#include "backend/bookshelfmodel/btbookshelfmodel.h"
+
+
+typedef CSwordModuleInfo::Categories CS;
+
+BtModuleCategoryFilterProxyModel::BtModuleCategoryFilterProxyModel(
+ QObject *parent)
+ : QSortFilterProxyModel(parent), m_filter(CSwordModuleInfo::AllCategories),
+ m_enabled(true)
+{
+ setFilterRole(BtBookshelfModel::ModuleCategoryRole);
+}
+
+BtModuleCategoryFilterProxyModel::~BtModuleCategoryFilterProxyModel() {
+ // Intentionally empty
+}
+
+void BtModuleCategoryFilterProxyModel::setEnabled(bool enable) {
+ m_enabled = enable;
+ invalidateFilter();
+}
+
+void BtModuleCategoryFilterProxyModel::setShownCategories(CS cs) {
+ if (m_filter == cs) return;
+ m_filter = cs;
+ invalidateFilter();
+}
+
+void BtModuleCategoryFilterProxyModel::setHiddenCategories(CS cs) {
+ cs ^= CSwordModuleInfo::AllCategories;
+ if (m_filter == cs) return;
+ m_filter = cs;
+ invalidateFilter();
+}
+
+bool BtModuleCategoryFilterProxyModel::filterAcceptsRow(int row,
+ const QModelIndex &parent) const
+{
+ typedef CSwordModuleInfo::Category C;
+
+ if (!m_enabled) return true;
+
+ const QAbstractItemModel *m(sourceModel());
+ Q_ASSERT(m != 0);
+
+ QModelIndex itemIndex(m->index(row, filterKeyColumn(), parent));
+ int numChildren(m->rowCount(itemIndex));
+ if (numChildren == 0) {
+ return m_filter.testFlag(m->data(itemIndex, filterRole()).value<C>());
+ }
+ else {
+ for (int i(0); i < numChildren; i++) {
+ if (filterAcceptsRow(i, itemIndex)) return true;
+ }
+ return false;
+ }
+}
diff --git a/src/backend/bookshelfmodel/btmodulecategoryfilterproxymodel.h b/src/backend/bookshelfmodel/btmodulecategoryfilterproxymodel.h
new file mode 100644
index 0000000..7517986
--- /dev/null
+++ b/src/backend/bookshelfmodel/btmodulecategoryfilterproxymodel.h
@@ -0,0 +1,49 @@
+/*********
+*
+* 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 BTMODULECATEGORYFILTERPROXYMODEL_H
+#define BTMODULECATEGORYFILTERPROXYMODEL_H
+
+#include <QSortFilterProxyModel>
+
+#include "backend/drivers/cswordmoduleinfo.h"
+
+
+class BtModuleCategoryFilterProxyModel: public QSortFilterProxyModel {
+ Q_OBJECT
+ public:
+ BtModuleCategoryFilterProxyModel(QObject *parent = 0);
+ virtual ~BtModuleCategoryFilterProxyModel();
+
+ inline bool enabled() const {
+ return m_enabled;
+ }
+ void setEnabled(bool enable);
+
+ inline CSwordModuleInfo::Categories shownCategories() const {
+ return m_filter;
+ }
+
+ inline CSwordModuleInfo::Categories hiddenCategories() const {
+ return ~m_filter & CSwordModuleInfo::AllCategories;
+ }
+ void setShownCategories(CSwordModuleInfo::Categories cs);
+ void setHiddenCategories(CSwordModuleInfo::Categories cs);
+
+ virtual bool filterAcceptsRow(int row, const QModelIndex &parent) const;
+
+ protected:
+ CSwordModuleInfo::Categories m_filter;
+ bool m_enabled;
+};
+
+#endif // BTMODULECATEGORYFILTERPROXYMODEL_H
diff --git a/src/backend/bookshelfmodel/btmodulehiddenfilterproxymodel.cpp b/src/backend/bookshelfmodel/btmodulehiddenfilterproxymodel.cpp
new file mode 100644
index 0000000..3a50300
--- /dev/null
+++ b/src/backend/bookshelfmodel/btmodulehiddenfilterproxymodel.cpp
@@ -0,0 +1,61 @@
+/*********
+*
+* In the name of the Father, and of the Son, and of the Holy Spirit.
+*
+* This file is part of BibleTime's source code, http://www.bibletime.info/.
+*
+* Copyright 1999-2009 by the BibleTime developers.
+* The BibleTime source code is licensed under the GNU General Public License
+* version 2.0.
+*
+**********/
+
+#include "backend/bookshelfmodel/btmodulehiddenfilterproxymodel.h"
+
+#include "backend/bookshelfmodel/btbookshelfmodel.h"
+
+
+BtModuleHiddenFilterProxyModel::BtModuleHiddenFilterProxyModel(QObject *parent)
+ : QSortFilterProxyModel(parent), m_enabled(true), m_showHidden(false),
+ m_showShown(true) {
+ setFilterRole(BtBookshelfModel::ModuleHiddenRole);
+}
+
+BtModuleHiddenFilterProxyModel::~BtModuleHiddenFilterProxyModel() {
+ // Intentionally empty
+}
+
+void BtModuleHiddenFilterProxyModel::setEnabled(bool enable) {
+ if (enable == m_enabled) return;
+ m_enabled = enable;
+ invalidateFilter();
+}
+
+void BtModuleHiddenFilterProxyModel::setShowHidden(bool show) {
+ if (m_showHidden == show) return;
+ m_showHidden = show;
+ invalidateFilter();
+}
+
+void BtModuleHiddenFilterProxyModel::setShowShown(bool show) {
+ if (m_showShown == show) return;
+ m_showShown = show;
+ invalidateFilter();
+}
+
+bool BtModuleHiddenFilterProxyModel::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));
+ if ((CS) m->data(i, filterRole()).toBool()) {
+ return m_showHidden;
+ }
+ else {
+ return m_showShown;
+ }
+}
diff --git a/src/backend/bookshelfmodel/btmodulehiddenfilterproxymodel.h b/src/backend/bookshelfmodel/btmodulehiddenfilterproxymodel.h
new file mode 100644
index 0000000..8871930
--- /dev/null
+++ b/src/backend/bookshelfmodel/btmodulehiddenfilterproxymodel.h
@@ -0,0 +1,48 @@
+/*********
+*
+* In the name of the Father, and of the Son, and of the Holy Spirit.
+*
+* This file is part of BibleTime's source code, http://www.bibletime.info/.
+*
+* Copyright 1999-2009 by the BibleTime developers.
+* The BibleTime source code is licensed under the GNU General Public License
+* version 2.0.
+*
+**********/
+
+#ifndef BTMODULEHIDDENFILTERPROXYMODEL_H
+#define BTMODULEHIDDENFILTERPROXYMODEL_H
+
+#include <QSortFilterProxyModel>
+
+
+class BtModuleHiddenFilterProxyModel: public QSortFilterProxyModel {
+ Q_OBJECT
+ public:
+ BtModuleHiddenFilterProxyModel(QObject *parent = 0);
+ virtual ~BtModuleHiddenFilterProxyModel();
+
+ inline bool enabled() const {
+ return m_enabled;
+ }
+ void setEnabled(bool enable);
+
+ inline bool showHidden() const {
+ return m_showHidden;
+ }
+ void setShowHidden(bool show);
+
+ inline bool showShown() const {
+ return m_showShown;
+ }
+ void setShowShown(bool show);
+
+ virtual bool filterAcceptsRow(int row, const QModelIndex &parent) const;
+
+ protected:
+ bool m_enabled;
+ bool m_showHidden;
+ bool m_showShown;
+};
+
+#endif // BTMODULEHIDDENFILTERPROXYMODEL_H
diff --git a/src/backend/bookshelfmodel/btmodulenamefilterproxymodel.cpp b/src/backend/bookshelfmodel/btmodulenamefilterproxymodel.cpp
index 31b93e1..1d20cdb 100644
--- a/src/backend/bookshelfmodel/btmodulenamefilterproxymodel.cpp
+++ b/src/backend/bookshelfmodel/btmodulenamefilterproxymodel.cpp
@@ -12,8 +12,12 @@
#include "backend/bookshelfmodel/btmodulenamefilterproxymodel.h"
+#include "backend/bookshelfmodel/btbookshelfmodel.h"
+
+
BtModuleNameFilterProxyModel::BtModuleNameFilterProxyModel(QObject *parent)
: QSortFilterProxyModel(parent), m_enabled(true) {
+ setFilterRole(BtBookshelfModel::ModuleNameRole);
setFilterCaseSensitivity(Qt::CaseInsensitive);
}
@@ -28,7 +32,7 @@ bool BtModuleNameFilterProxyModel::filterAcceptsRow(int row,
const QAbstractItemModel *m(sourceModel());
Q_ASSERT(m != 0);
- QModelIndex itemIndex(m->index(row, 0, p));
+ QModelIndex itemIndex(m->index(row, filterKeyColumn(), p));
int numChildren(m->rowCount(itemIndex));
if (numChildren == 0) {
return QSortFilterProxyModel::filterAcceptsRow(row, p);
diff --git a/src/backend/bookshelfmodel/btmodulenamefilterproxymodel.h b/src/backend/bookshelfmodel/btmodulenamefilterproxymodel.h
index e4499be..9b24dd6 100644
--- a/src/backend/bookshelfmodel/btmodulenamefilterproxymodel.h
+++ b/src/backend/bookshelfmodel/btmodulenamefilterproxymodel.h
@@ -15,6 +15,7 @@
#include <QSortFilterProxyModel>
+
class BtModuleNameFilterProxyModel: public QSortFilterProxyModel {
Q_OBJECT
public:
diff --git a/src/backend/bookshelfmodel/categoryitem.cpp b/src/backend/bookshelfmodel/categoryitem.cpp
index 3ce6e88..1788dfc 100644
--- a/src/backend/bookshelfmodel/categoryitem.cpp
+++ b/src/backend/bookshelfmodel/categoryitem.cpp
@@ -10,7 +10,8 @@
*
**********/
-#include "categoryitem.h"
+#include "backend/bookshelfmodel/categoryitem.h"
+
namespace BookshelfModel {
@@ -23,7 +24,10 @@ bool CategoryItem::operator<(const Item &other) const {
if (other.type() != ITEM_CATEGORY) {
return ITEM_CATEGORY < other.type();
}
- return m_category < static_cast<const CategoryItem &>(other).m_category;
+ const CategoryItem &o(static_cast<const CategoryItem &>(other));
+ if (m_category == CSwordModuleInfo::UnknownCategory) return false;
+ if (o.m_category == CSwordModuleInfo::UnknownCategory) return true;
+ return m_category < o.m_category;
}
} // namespace BookshelfModel
diff --git a/src/backend/bookshelfmodel/categoryitem.h b/src/backend/bookshelfmodel/categoryitem.h
index 40820a2..fcff12b 100644
--- a/src/backend/bookshelfmodel/categoryitem.h
+++ b/src/backend/bookshelfmodel/categoryitem.h
@@ -19,6 +19,7 @@
#include "backend/bookshelfmodel/btbookshelfmodel.h"
#include "backend/drivers/cswordmoduleinfo.h"
+
namespace BookshelfModel {
class CategoryItem: public Item {
@@ -41,7 +42,7 @@ class CategoryItem: public Item {
return BtBookshelfModel::categoryIcon(m_category);
}
- inline bool fitFor(CSwordModuleInfo *module) {
+ inline bool fitFor(CSwordModuleInfo *module) const {
return module->category() == m_category;
}
diff --git a/src/backend/bookshelfmodel/distributionitem.cpp b/src/backend/bookshelfmodel/distributionitem.cpp
index 4ae81c5..fee9c19 100644
--- a/src/backend/bookshelfmodel/distributionitem.cpp
+++ b/src/backend/bookshelfmodel/distributionitem.cpp
@@ -12,6 +12,7 @@
#include "backend/bookshelfmodel/distributionitem.h"
+
namespace BookshelfModel {
DistributionItem::DistributionItem(CSwordModuleInfo *module)
diff --git a/src/backend/bookshelfmodel/distributionitem.h b/src/backend/bookshelfmodel/distributionitem.h
index 44ae591..4ae1197 100644
--- a/src/backend/bookshelfmodel/distributionitem.h
+++ b/src/backend/bookshelfmodel/distributionitem.h
@@ -17,6 +17,7 @@
#include "backend/drivers/cswordmoduleinfo.h"
+
namespace BookshelfModel {
class DistributionItem: public Item {
@@ -33,7 +34,7 @@ class DistributionItem: public Item {
return m_distribution;
}
- inline bool fitFor(CSwordModuleInfo *module) {
+ inline bool fitFor(CSwordModuleInfo *module) const {
return module->config(CSwordModuleInfo::DistributionSource)
== m_distribution;
}
diff --git a/src/backend/bookshelfmodel/item.cpp b/src/backend/bookshelfmodel/item.cpp
index 8556274..ec2dcab 100644
--- a/src/backend/bookshelfmodel/item.cpp
+++ b/src/backend/bookshelfmodel/item.cpp
@@ -16,6 +16,7 @@
#include "backend/bookshelfmodel/distributionitem.h"
#include "backend/bookshelfmodel/languageitem.h"
+
namespace BookshelfModel {
Item::Item(Type type)
@@ -53,4 +54,12 @@ bool Item::operator<(const Item &other) const {
return name().localeAwareCompare(other.name()) < 0;
}
+bool Item::isHidden() const {
+ if (m_children.empty()) return true;
+ Q_FOREACH(Item *child, m_children) {
+ if (!child->isHidden()) return false;
+ }
+ return true;
+}
+
} // namespace BookshelfModel
diff --git a/src/backend/bookshelfmodel/item.h b/src/backend/bookshelfmodel/item.h
index b24b503..665343f 100644
--- a/src/backend/bookshelfmodel/item.h
+++ b/src/backend/bookshelfmodel/item.h
@@ -18,6 +18,7 @@
#include <QString>
#include <QtGlobal>
+
class CSwordModuleInfo;
namespace BookshelfModel {
@@ -71,9 +72,9 @@ class Item {
\brief Returns the index of this item under its parent.
\retval -1 if this item has no parent.
*/
- inline int childIndex() {
+ inline int childIndex() const {
if (m_parent == 0) return -1;
- return m_parent->m_children.indexOf(this);
+ return m_parent->m_children.indexOf(const_cast<Item*>(this));
}
/**
@@ -149,7 +150,7 @@ class Item {
\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) {
+ inline virtual bool fitFor(CSwordModuleInfo *module) const {
Q_UNUSED(module);
return false;
}
@@ -159,6 +160,8 @@ class Item {
*/
virtual bool operator<(const Item &other) const;
+ virtual bool isHidden() const;
+
protected:
inline void setParent(Item *parent) {
Q_ASSERT(parent != 0);
diff --git a/src/backend/bookshelfmodel/languageitem.cpp b/src/backend/bookshelfmodel/languageitem.cpp
index 6758178..8d37891 100644
--- a/src/backend/bookshelfmodel/languageitem.cpp
+++ b/src/backend/bookshelfmodel/languageitem.cpp
@@ -10,7 +10,8 @@
*
**********/
-#include "languageitem.h"
+#include "backend/bookshelfmodel/languageitem.h"
+
namespace BookshelfModel {
diff --git a/src/backend/bookshelfmodel/languageitem.h b/src/backend/bookshelfmodel/languageitem.h
index 262ca65..b5696d9 100644
--- a/src/backend/bookshelfmodel/languageitem.h
+++ b/src/backend/bookshelfmodel/languageitem.h
@@ -17,7 +17,8 @@
#include "backend/bookshelfmodel/btbookshelfmodel.h"
#include "backend/drivers/cswordmoduleinfo.h"
-#include "util/directoryutil.h"
+#include "util/directory.h"
+
namespace BookshelfModel {
@@ -36,10 +37,10 @@ class LanguageItem: public Item {
}
inline QIcon icon() const {
- return util::filesystem::DirectoryUtil::getIcon("flag.svg");
+ return util::directory::getIcon("flag.svg");
}
- inline bool fitFor(CSwordModuleInfo *module) {
+ inline bool fitFor(CSwordModuleInfo *module) const {
return module->language() == m_language;
}
diff --git a/src/backend/bookshelfmodel/moduleitem.cpp b/src/backend/bookshelfmodel/moduleitem.cpp
index 8d02111..95e6f62 100644
--- a/src/backend/bookshelfmodel/moduleitem.cpp
+++ b/src/backend/bookshelfmodel/moduleitem.cpp
@@ -10,10 +10,11 @@
*
**********/
-#include "moduleitem.h"
+#include "backend/bookshelfmodel/moduleitem.h"
#include "util/cresmgr.h"
+
namespace BookshelfModel {
ModuleItem::ModuleItem(CSwordModuleInfo *module)
diff --git a/src/backend/bookshelfmodel/moduleitem.h b/src/backend/bookshelfmodel/moduleitem.h
index 40ecc79..9657423 100644
--- a/src/backend/bookshelfmodel/moduleitem.h
+++ b/src/backend/bookshelfmodel/moduleitem.h
@@ -18,6 +18,7 @@
#include "backend/bookshelfmodel/btbookshelfmodel.h"
#include "backend/drivers/cswordmoduleinfo.h"
+
namespace BookshelfModel {
class ModuleItem: public Item {
@@ -28,12 +29,8 @@ class ModuleItem: public Item {
return m_moduleInfo;
}
- inline QString name() const {
- return m_moduleInfo->name();
- }
-
- inline QIcon icon() const {
- return BtBookshelfModel::moduleIcon(m_moduleInfo);
+ inline bool isHidden() const {
+ return m_moduleInfo->isHidden();
}
protected: