diff options
Diffstat (limited to 'src/backend/bookshelfmodel')
25 files changed, 619 insertions, 656 deletions
diff --git a/src/backend/bookshelfmodel/btbookshelffiltermodel.cpp b/src/backend/bookshelfmodel/btbookshelffiltermodel.cpp new file mode 100644 index 0000000..b896556 --- /dev/null +++ b/src/backend/bookshelfmodel/btbookshelffiltermodel.cpp @@ -0,0 +1,202 @@ +/********* +* +* 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/btbookshelffiltermodel.h" + +#include "backend/bookshelfmodel/btbookshelfmodel.h" + + +BtBookshelfFilterModel::BtBookshelfFilterModel(QObject *parent) + : QSortFilterProxyModel(parent), m_enabled(true), + m_nameFilterRole(BtBookshelfModel::ModuleNameRole), m_nameFilterColumn(0), + m_nameFilterCase(Qt::CaseInsensitive), + m_hiddenFilterRole(BtBookshelfModel::ModuleHiddenRole), + m_hiddenFilterColumn(0), m_showHidden(false), m_showShown(true), + m_categoryFilter(CSwordModuleInfo::AllCategories), + m_categoryFilterRole(BtBookshelfModel::ModuleCategoryRole), + m_categoryFilterColumn(0) +{ + // Intentionally empty +} + +BtBookshelfFilterModel::~BtBookshelfFilterModel() { + // Intentionally empty +} + +void BtBookshelfFilterModel::setEnabled(bool enable) { + if (enable == m_enabled) return; + m_enabled = enable; + invalidateFilter(); +} + +// Name filter: + +void BtBookshelfFilterModel::setNameFilterRole(int role) { + if (m_nameFilterRole == role) return; + m_nameFilterRole = role; + invalidateFilter(); +} + +void BtBookshelfFilterModel::setNameFilterKeyColumn(int column) { + if (m_nameFilterColumn == column) return; + m_nameFilterColumn = column; + invalidateFilter(); +} + +void BtBookshelfFilterModel::setNameFilterFixedString(const QString &filter) { + if (m_nameFilter == filter) return; + m_nameFilter = filter; + invalidateFilter(); +} + +void BtBookshelfFilterModel::setNameFilterCase(Qt::CaseSensitivity value) { + if (m_nameFilterCase == value) return; + m_nameFilterCase = value; + invalidateFilter(); +} + +// Hidden filter: + +void BtBookshelfFilterModel::setHiddenFilterRole(int role) { + if (m_hiddenFilterRole == role) return; + m_hiddenFilterRole = role; + invalidateFilter(); +} + +void BtBookshelfFilterModel::setHiddenFilterKeyColumn(int column) { + if (m_hiddenFilterColumn == column) return; + m_hiddenFilterColumn = column; + invalidateFilter(); +} + +void BtBookshelfFilterModel::setShowHidden(bool show) { + if (m_showHidden == show) return; + m_showHidden = show; + invalidateFilter(); +} + +void BtBookshelfFilterModel::setShowShown(bool show) { + if (m_showShown == show) return; + m_showShown = show; + invalidateFilter(); +} + +// Category filter: + +void BtBookshelfFilterModel::setCategoryFilterRole(int role) { + if (m_categoryFilterRole == role) return; + m_categoryFilterRole = role; + invalidateFilter(); +} + +void BtBookshelfFilterModel::setCategoryFilterKeyColumn(int column) { + if (m_categoryFilterColumn == column) return; + m_categoryFilterColumn = column; + invalidateFilter(); +} + +void BtBookshelfFilterModel::setShownCategories( + const CSwordModuleInfo::Categories &categories) +{ + if (m_categoryFilter == categories) return; + m_categoryFilter = categories; + invalidateFilter(); +} + +// Filtering: + +bool BtBookshelfFilterModel::filterAcceptsRow(int row, + const QModelIndex &parent) const +{ + if (!m_enabled) return true; + + if (!hiddenFilterAcceptsRow(row, parent)) return false; + if (!nameFilterAcceptsRow(row, parent)) return false; + if (!categoryFilterAcceptsRow(row, parent)) return false; + return true; +} + +bool BtBookshelfFilterModel::nameFilterAcceptsRow(int row, const QModelIndex &p) + const +{ + if (!m_enabled) return true; + if (m_nameFilter.isEmpty()) return true; + + const QAbstractItemModel *m(sourceModel()); + Q_ASSERT(m != 0); + + QModelIndex itemIndex(m->index(row, m_nameFilterColumn, p)); + int numChildren(m->rowCount(itemIndex)); + if (numChildren == 0) { + QVariant data(m->data(itemIndex, m_nameFilterRole)); + return data.toString().contains(m_nameFilter, m_nameFilterCase); + } + else { + for (int i(0); i < numChildren; i++) { + if (filterAcceptsRow(i, itemIndex)) return true; + } + return false; + } +} + +bool BtBookshelfFilterModel::hiddenFilterAcceptsRow(int row, + const QModelIndex &parent) const +{ + if (m_showHidden && m_showShown) return true; + + typedef Qt::CheckState CS; + + QAbstractItemModel *m(sourceModel()); + + QModelIndex itemIndex(m->index(row, m_hiddenFilterColumn, parent)); + int numChildren(m->rowCount(itemIndex)); + if (numChildren == 0) { + if ((CS) m->data(itemIndex, m_hiddenFilterRole).toBool()) { + return m_showHidden; + } + else { + return m_showShown; + } + } + else { + for (int i(0); i < numChildren; i++) { + if (filterAcceptsRow(i, itemIndex)) return true; + } + return false; + } +} + +bool BtBookshelfFilterModel::categoryFilterAcceptsRow(int row, + const QModelIndex &parent) const +{ + if (m_categoryFilter == CSwordModuleInfo::AllCategories) return true; + + QAbstractItemModel *m(sourceModel()); + + QModelIndex itemIndex(m->index(row, m_categoryFilterColumn, parent)); + int numChildren(m->rowCount(itemIndex)); + if (numChildren == 0) { + int cat = m->data(itemIndex, m_categoryFilterRole).toInt(); + if (m_categoryFilter.testFlag((CSwordModuleInfo::Category) cat)) { + return true; + } + else { + return false; + } + } + else { + for (int i(0); i < numChildren; i++) { + if (filterAcceptsRow(i, itemIndex)) return true; + } + return false; + } +} diff --git a/src/backend/bookshelfmodel/btbookshelffiltermodel.h b/src/backend/bookshelfmodel/btbookshelffiltermodel.h new file mode 100644 index 0000000..e440c69 --- /dev/null +++ b/src/backend/bookshelfmodel/btbookshelffiltermodel.h @@ -0,0 +1,127 @@ +/********* +* +* 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 BTBOOKSHELFFILTERMODEL_H +#define BTBOOKSHELFFILTERMODEL_H + +#include <QSortFilterProxyModel> + +#include "backend/drivers/cswordmoduleinfo.h" + + +class BtBookshelfFilterModel: public QSortFilterProxyModel { + Q_OBJECT + public: + BtBookshelfFilterModel(QObject *parent = 0); + virtual ~BtBookshelfFilterModel(); + + // Common methods: + inline bool enabled() const { + return m_enabled; + } + + virtual bool filterAcceptsRow(int row, const QModelIndex &parent) const; + + // Name filter: + inline int nameFilterRole() const { + return m_nameFilterRole; + } + + inline int nameFilterKeyColumn() const { + return m_nameFilterColumn; + } + + inline const QString &nameFilter() const { + return m_nameFilter; + } + + inline const Qt::CaseSensitivity nameFilterCase() const { + return m_nameFilterCase; + } + + // Hidden filter: + int hiddenFilterRole() const { + return m_hiddenFilterRole; + } + + int hiddenFilterKeyColumn() const { + return m_hiddenFilterColumn; + } + + inline bool showHidden() const { + return m_showHidden; + } + + inline bool showShown() const { + return m_showShown; + } + + // Category filter: + int categoryFilterRole() const { + return m_categoryFilterRole; + } + + int categoryFilterKeyColumn() const { + return m_categoryFilterColumn; + } + + inline CSwordModuleInfo::Categories shownCategories() const { + return m_categoryFilter; + } + + public slots: + void setEnabled(bool enable); + + // Name filter: + void setNameFilterRole(int role); + void setNameFilterKeyColumn(int column); + void setNameFilterFixedString(const QString &nameFilter); + void setNameFilterCase(Qt::CaseSensitivity value); + + // Hidden filter: + void setHiddenFilterRole(int role); + void setHiddenFilterKeyColumn(int column); + void setShowHidden(bool show); + void setShowShown(bool show); + + // Category filter: + void setCategoryFilterRole(int role); + void setCategoryFilterKeyColumn(int column); + void setShownCategories(const CSwordModuleInfo::Categories &categories); + + protected: + bool nameFilterAcceptsRow(int row, const QModelIndex &parent) const; + bool hiddenFilterAcceptsRow(int row, const QModelIndex &parent) const; + bool categoryFilterAcceptsRow(int row, const QModelIndex &parent) const; + + protected: + bool m_enabled; + + // Name filter: + QString m_nameFilter; + int m_nameFilterRole; + int m_nameFilterColumn; + Qt::CaseSensitivity m_nameFilterCase; + + // Hidden filter: + int m_hiddenFilterRole; + int m_hiddenFilterColumn; + bool m_showHidden; + bool m_showShown; + + // Categories filter: + CSwordModuleInfo::Categories m_categoryFilter; + int m_categoryFilterRole; + int m_categoryFilterColumn; +}; + +#endif // BTBOOKSHELFFILTERMODEL_H diff --git a/src/backend/bookshelfmodel/btbookshelfmodel.cpp b/src/backend/bookshelfmodel/btbookshelfmodel.cpp index 6882b90..ccbb5a5 100644 --- a/src/backend/bookshelfmodel/btbookshelfmodel.cpp +++ b/src/backend/bookshelfmodel/btbookshelfmodel.cpp @@ -27,6 +27,8 @@ BtBookshelfModel::~BtBookshelfModel() { } int BtBookshelfModel::rowCount(const QModelIndex &parent) const { + if (parent.isValid()) return 0; + return m_data.size(); } @@ -44,6 +46,12 @@ QVariant BtBookshelfModel::data(CSwordModuleInfo *module, int role) const { return QVariant(); /// \todo Unimplemented case ModuleHiddenRole: return module->isHidden(); + case ModuleInstallPathRole: + return module->config(CSwordModuleInfo::AbsoluteDataPath); + case ModuleHasIndexRole: + return module->hasIndex(); + case ModuleIndexSizeRole: + return (qulonglong) module->indexSize(); default: return QVariant(); } @@ -73,8 +81,7 @@ 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) - { + && 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 @@ -97,25 +104,29 @@ QIcon BtBookshelfModel::moduleIcon(const CSwordModuleInfo *m) { case CSwordModuleInfo::Bibles: if (module->isLocked()) { return DU::getIcon(CResMgr::modules::bible::icon_locked); - } else { + } + else { return DU::getIcon(CResMgr::modules::bible::icon_unlocked); } case CSwordModuleInfo::Commentaries: if (module->isLocked()) { return DU::getIcon(CResMgr::modules::commentary::icon_locked); - } else { + } + else { return DU::getIcon(CResMgr::modules::commentary::icon_unlocked); } case CSwordModuleInfo::Lexicons: if (module->isLocked()) { return DU::getIcon(CResMgr::modules::lexicon::icon_locked); - } else { + } + else { return DU::getIcon(CResMgr::modules::lexicon::icon_unlocked); } case CSwordModuleInfo::Books: if (module->isLocked()) { return DU::getIcon(CResMgr::modules::book::icon_locked); - } else { + } + else { return DU::getIcon(CResMgr::modules::book::icon_unlocked); } case CSwordModuleInfo::Cult: @@ -204,6 +215,8 @@ void BtBookshelfModel::addModule(CSwordModuleInfo * const module) { m_data.append(module); connect(module, SIGNAL(hiddenChanged(bool)), this, SLOT(moduleHidden(bool))); + connect(module, SIGNAL(hasIndexChanged(bool)), + this, SLOT(moduleIndexed(bool))); endInsertRows(); } @@ -227,33 +240,34 @@ void BtBookshelfModel::addModules(const QSet<CSwordModuleInfo *> &modules) { m_data.append(module); connect(module, SIGNAL(hiddenChanged(bool)), this, SLOT(moduleHidden(bool))); + connect(module, SIGNAL(hasIndexChanged(bool)), + this, SLOT(moduleIndexed(bool))); } endInsertRows(); } void BtBookshelfModel::removeModule(CSwordModuleInfo * const module, - bool destroy) -{ + bool destroy) { const int index(m_data.indexOf(module)); if (index == -1) return; beginRemoveRows(QModelIndex(), index, index); disconnect(module, SIGNAL(hiddenChanged(bool)), this, SLOT(moduleHidden(bool))); + disconnect(module, SIGNAL(hasIndexChanged(bool)), + this, SLOT(moduleIndexed(bool))); m_data.removeAt(index); endRemoveRows(); if (destroy) delete module; } void BtBookshelfModel::removeModules(const QList<CSwordModuleInfo *> &modules, - bool destroy) -{ + bool destroy) { removeModules(modules.toSet(), destroy); } void BtBookshelfModel::removeModules(const QSet<CSwordModuleInfo *> &modules, - bool destroy) -{ + bool destroy) { // This is inefficient, since signals are emitted for each removed module: Q_FOREACH(CSwordModuleInfo *module, modules) { removeModule(module, destroy); @@ -270,7 +284,16 @@ CSwordModuleInfo* BtBookshelfModel::getModule(const QString &name) const { void BtBookshelfModel::moduleHidden(bool) { Q_ASSERT(qobject_cast<CSwordModuleInfo*>(sender()) != 0); - CSwordModuleInfo *module(static_cast<CSwordModuleInfo*>(sender())); + moduleDataChanged(static_cast<CSwordModuleInfo*>(sender())); +} + +void BtBookshelfModel::moduleIndexed(bool) { + Q_ASSERT(qobject_cast<CSwordModuleInfo*>(sender()) != 0); + + moduleDataChanged(static_cast<CSwordModuleInfo*>(sender())); +} + +void BtBookshelfModel::moduleDataChanged(CSwordModuleInfo *module) { Q_ASSERT(m_data.count(module) == 1); QModelIndex i(index(m_data.indexOf(module), 0)); diff --git a/src/backend/bookshelfmodel/btbookshelfmodel.h b/src/backend/bookshelfmodel/btbookshelfmodel.h index 16fdb13..735c655 100644 --- a/src/backend/bookshelfmodel/btbookshelfmodel.h +++ b/src/backend/bookshelfmodel/btbookshelfmodel.h @@ -28,6 +28,9 @@ class BtBookshelfModel: public QAbstractListModel { ModuleCategoryRole = Qt::UserRole + 1, ModuleLanguageRole = Qt::UserRole + 2, ModuleHiddenRole = Qt::UserRole + 3, + ModuleInstallPathRole = Qt::UserRole + 4, + ModuleHasIndexRole = Qt::UserRole + 5, + ModuleIndexSizeRole = Qt::UserRole + 6, UserRole = Qt::UserRole + 100 }; @@ -71,6 +74,10 @@ class BtBookshelfModel: public QAbstractListModel { protected slots: void moduleHidden(bool hidden); + void moduleIndexed(bool indexed); + + protected: + void moduleDataChanged(CSwordModuleInfo *module); protected: QList<CSwordModuleInfo *> m_data; diff --git a/src/backend/bookshelfmodel/btbookshelftreemodel.cpp b/src/backend/bookshelfmodel/btbookshelftreemodel.cpp index 5be1aec..a2a988c 100644 --- a/src/backend/bookshelfmodel/btbookshelftreemodel.cpp +++ b/src/backend/bookshelfmodel/btbookshelftreemodel.cpp @@ -14,7 +14,7 @@ #include <QSet> #include "backend/bookshelfmodel/categoryitem.h" -#include "backend/bookshelfmodel/distributionitem.h" +#include "backend/bookshelfmodel/indexingitem.h" #include "backend/bookshelfmodel/languageitem.h" #include "backend/bookshelfmodel/moduleitem.h" @@ -30,8 +30,7 @@ BtBookshelfTreeModel::BtBookshelfTreeModel(QObject *parent) BtBookshelfTreeModel::BtBookshelfTreeModel(const Grouping &g, QObject *parent) : QAbstractItemModel(parent), m_sourceModel(0), m_rootItem(new RootItem), - m_groupingOrder(g), m_defaultChecked(MODULE_HIDDEN), m_checkable(false) -{ + m_groupingOrder(g), m_defaultChecked(MODULE_HIDDEN), m_checkable(false) { // Intentionally empty } @@ -44,6 +43,8 @@ int BtBookshelfTreeModel::rowCount(const QModelIndex &parent) const { } int BtBookshelfTreeModel::columnCount(const QModelIndex &parent) const { + Q_UNUSED(parent); + return 1; } @@ -56,7 +57,7 @@ QModelIndex BtBookshelfTreeModel::index(int row, int column, if (!hasIndex(row, column, parent)) return QModelIndex(); Item *parentItem(getItem(parent)); - Item *childItem(parentItem->childAt(row)); + Item *childItem(parentItem->children().at(row)); if (childItem != 0) { return createIndex(row, column, childItem); } @@ -87,55 +88,56 @@ QVariant BtBookshelfTreeModel::data(const QModelIndex &index, int role) const { Item *i(static_cast<Item*>(index.internalPointer())); Q_ASSERT(i != 0); switch (role) { - case Qt::DisplayRole: - 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: - if (i->type() == Item::ITEM_MODULE) { - return parentData(static_cast<ModuleItem *>(i), role); - } else { - return i->icon(); - } case BtBookshelfModel::ModulePointerRole: + /* This case is just an optimization. */ if (i->type() == Item::ITEM_MODULE) { ModuleItem *mi(static_cast<ModuleItem *>(i)); return qVariantFromValue((void*) mi->moduleInfo()); } return 0; + case Qt::DisplayRole: + case Qt::DecorationRole: case BtBookshelfModel::ModuleHiddenRole: - return i->isHidden(); default: if (i->type() == Item::ITEM_MODULE) { - return parentData(static_cast<ModuleItem *>(i), role); + ModuleItem *item(static_cast<ModuleItem *>(i)); + CSwordModuleInfo* m(item->moduleInfo()); + return data(m, role); + } + else { + return i->data(role); } - break; } return QVariant(); } +QVariant BtBookshelfTreeModel::data(CSwordModuleInfo *module, int role) const { + Q_ASSERT(m_sourceIndexMap.contains(module)); + return m_sourceModel->data(m_sourceIndexMap.value(module), role); +} + bool BtBookshelfTreeModel::setData(const QModelIndex &itemIndex, const QVariant &value, int role) { typedef QPair<Item *, QModelIndex> IP; Qt::CheckState newState; - if (role == BtBookshelfModel::ModuleHiddenRole) { - newState = value.toBool() ? Qt::Checked : Qt::Unchecked; - } else if (role == Qt::CheckStateRole) { + if (role == Qt::CheckStateRole) { bool ok; newState = (Qt::CheckState) value.toInt(&ok); - if (!ok || newState == Qt::PartiallyChecked) return false; - } else { + if (!ok) return false; + } + else { return false; } + // Handle partially checked as checked here in setData(): + if (newState == Qt::PartiallyChecked) newState = Qt::Checked; + Item *item(static_cast<Item*>(itemIndex.internalPointer())); Q_ASSERT(item != 0); if (item->checkState() == newState) return false; @@ -148,9 +150,18 @@ bool BtBookshelfTreeModel::setData(const QModelIndex &itemIndex, 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 { + ModuleItem *mItem(static_cast<ModuleItem*>(item)); + CSwordModuleInfo *mInfo(mItem->moduleInfo()); + if (newState == Qt::Checked) { + m_checkedModulesCache.insert(mInfo); + emit moduleChecked(mInfo, true); + } + else { + m_checkedModulesCache.remove(mInfo); + emit moduleChecked(mInfo, false); + } + } + 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))); @@ -207,6 +218,7 @@ void BtBookshelfTreeModel::setSourceModel(QAbstractItemModel *sourceModel) { delete m_rootItem; m_modules.clear(); m_sourceIndexMap.clear(); + m_checkedModulesCache.clear(); m_rootItem = new RootItem; endRemoveRows(); } @@ -225,6 +237,8 @@ void BtBookshelfTreeModel::setSourceModel(QAbstractItemModel *sourceModel) { typedef BtBookshelfModel::ModuleRole MRole; static const MRole HR(BtBookshelfModel::ModuleHiddenRole); static const MRole PR(BtBookshelfModel::ModulePointerRole); + static const MRole IR(BtBookshelfModel::ModuleHasIndexRole); + QModelIndex moduleIndex(sourceModel->index(i, 0)); CSwordModuleInfo *module( static_cast<CSwordModuleInfo *>( @@ -235,7 +249,11 @@ void BtBookshelfTreeModel::setSourceModel(QAbstractItemModel *sourceModel) { bool checked; if (m_defaultChecked == MODULE_HIDDEN) { checked = !sourceModel->data(moduleIndex, HR).toBool(); - } else { + } + else if (m_defaultChecked == MODULE_INDEXED) { + checked = !sourceModel->data(moduleIndex, IR).toBool(); + } + else { checked = (m_defaultChecked == CHECKED); } m_sourceIndexMap[module] = moduleIndex; @@ -249,32 +267,28 @@ void BtBookshelfTreeModel::setGroupingOrder(const Grouping &groupingOrder) { m_groupingOrder = groupingOrder; if (m_sourceModel != 0) { - QSet<CSwordModuleInfo*> checked(checkedModules().toSet()); + QSet<CSwordModuleInfo*> checked(m_checkedModulesCache); + m_checkedModulesCache.clear(); + 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, 0), - BtBookshelfModel::ModulePointerRole - ).value<void*>() - ) - ); - Q_ASSERT(module != 0); - addModule(module, checked.contains(module)); - } + for (int i(0); i < m_sourceModel->rowCount(); i++) { + QModelIndex sourceIndex(m_sourceModel->index(i, 0)); + CSwordModuleInfo *module( + static_cast<CSwordModuleInfo *>( + m_sourceModel->data( + sourceIndex, + BtBookshelfModel::ModulePointerRole + ).value<void*>() + ) + ); + Q_ASSERT(module != 0); + m_sourceIndexMap[module] = sourceIndex; + addModule(module, checked.contains(module)); } } } @@ -282,43 +296,24 @@ void BtBookshelfTreeModel::setGroupingOrder(const Grouping &groupingOrder) { 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); - } + if (m_sourceModel == 0) return; + + // Notify views that flags changed for all items: + 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; -} - -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); + while (!queue.isEmpty()); } void BtBookshelfTreeModel::addModule(CSwordModuleInfo *module, bool checked) { @@ -344,28 +339,36 @@ void BtBookshelfTreeModel::addModule(CSwordModuleInfo *module, 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; + case GROUP_INDEXING: + newIndex = getGroup<IndexingItem>(module, parentIndex); + break; } intermediateGrouping.pop_front(); addModule(module, newIndex, intermediateGrouping, checked); } else { Item *parentItem(getItem(parentIndex)); - ModuleItem *newItem(new ModuleItem(module)); + ModuleItem *newItem(new ModuleItem(module, this)); newItem->setCheckState(checked ? Qt::Checked : Qt::Unchecked); const int newIndex(parentItem->indexFor(newItem)); + + // Actually do the insertion: beginInsertRows(parentIndex, newIndex, newIndex); parentItem->insertChild(newIndex, newItem); m_modules.insert(module, newItem); + if (checked) { + // Add to checked modules cache + m_checkedModulesCache.insert(module); + } endInsertRows(); + + // Reset parent item check states, if needed: resetParentCheckStates(parentIndex); } } @@ -383,13 +386,18 @@ void BtBookshelfTreeModel::removeModule(CSwordModuleInfo *module) { Q_ASSERT(i != 0); Q_ASSERT(i->parent() != 0); - // Remove item: + // Calculate item indexes: int index(i->childIndex()); QModelIndex parentIndex(getIndex(i->parent())); + + // Actually remove the item: beginRemoveRows(parentIndex, index, index); - i->parent()->deleteChildAt(index); + delete i->parent()->children().takeAt(index); m_modules.remove(module); + m_checkedModulesCache.remove(module); endRemoveRows(); + + // Reset parent item check states, if needed: resetParentCheckStates(parentIndex); } @@ -431,7 +439,7 @@ void BtBookshelfTreeModel::resetParentCheckStates(QModelIndex parentIndex) { bool haveCheckedChildren(false); bool haveUncheckedChildren(false); for (int i(0); i < parentItem->children().size(); i++) { - Qt::CheckState state(parentItem->childAt(i)->checkState()); + Qt::CheckState state(parentItem->children().at(i)->checkState()); if (state == Qt::PartiallyChecked) { haveCheckedChildren = true; haveUncheckedChildren = true; @@ -491,7 +499,8 @@ void BtBookshelfTreeModel::moduleDataChanged(const QModelIndex &topLeft, do { itemIndex = itemIndex.parent(); emit dataChanged(itemIndex, itemIndex); - } while (itemIndex.isValid()); + } + while (itemIndex.isValid()); } } @@ -500,6 +509,7 @@ void BtBookshelfTreeModel::moduleInserted(const QModelIndex &parent, int start, typedef BtBookshelfModel BM; static const BM::ModuleRole PR(BM::ModulePointerRole); static const BM::ModuleRole HR(BM::ModuleHiddenRole); + static const BM::ModuleRole IR(BM::ModuleHasIndexRole); for (int i(start); i <= end; i++) { QModelIndex moduleIndex(m_sourceModel->index(i, 0, parent)); @@ -509,7 +519,11 @@ void BtBookshelfTreeModel::moduleInserted(const QModelIndex &parent, int start, bool checked; if (m_defaultChecked == MODULE_HIDDEN) { checked = !m_sourceModel->data(moduleIndex, HR).toBool(); - } else { + } + else if (m_defaultChecked == MODULE_INDEXED) { + checked = !m_sourceModel->data(moduleIndex, IR).toBool(); + } + else { checked = (m_defaultChecked == CHECKED); } m_sourceIndexMap[module] = moduleIndex; diff --git a/src/backend/bookshelfmodel/btbookshelftreemodel.h b/src/backend/bookshelfmodel/btbookshelftreemodel.h index e73b154..47ce672 100644 --- a/src/backend/bookshelfmodel/btbookshelftreemodel.h +++ b/src/backend/bookshelfmodel/btbookshelftreemodel.h @@ -15,8 +15,10 @@ #include <QAbstractItemModel> +#include <QList> #include <QMap> #include <QPersistentModelIndex> +#include <QSet> #include "backend/bookshelfmodel/btbookshelfmodel.h" #include "backend/bookshelfmodel/item.h" @@ -39,8 +41,17 @@ class BtBookshelfTreeModel: public QAbstractItemModel { CheckStateRole = BtBookshelfModel::UserRole, UserRole = BtBookshelfModel::UserRole + 100 }; - enum Group { GROUP_CATEGORY = 0, GROUP_LANGUAGE, GROUP_DISTRIBUTION }; - enum CheckedBehavior { CHECKED, UNCHECKED, MODULE_HIDDEN }; + enum Group { + GROUP_CATEGORY = 0, + GROUP_LANGUAGE = 1, + GROUP_INDEXING + }; + enum CheckedBehavior { + CHECKED, /**< Check all added modules by default. */ + UNCHECKED, /**< Uncheck all added modules by default. */ + MODULE_HIDDEN, /**< By default, check only added modules that are not hidden. */ + MODULE_INDEXED /**< By default, check only added modules that are indexed. */ + }; typedef QList<Group> Grouping; BtBookshelfTreeModel(QObject *parent = 0); @@ -56,7 +67,8 @@ class BtBookshelfTreeModel: public QAbstractItemModel { const QModelIndex &parent = QModelIndex()) const; virtual QModelIndex parent(const QModelIndex &index) const; - virtual QVariant data(const QModelIndex &index, int role) const; + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + QVariant data(CSwordModuleInfo *module, int role = Qt::DisplayRole) const; virtual Qt::ItemFlags flags(const QModelIndex &index) const; virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; @@ -82,7 +94,9 @@ class BtBookshelfTreeModel: public QAbstractItemModel { return m_defaultChecked; } - QList<CSwordModuleInfo*> checkedModules() const; + inline const QSet<CSwordModuleInfo*> &checkedModules() const { + return m_checkedModulesCache; + } protected: QVariant parentData(BookshelfModel::ModuleItem *item, int role) const; @@ -100,7 +114,7 @@ class BtBookshelfTreeModel: public QAbstractItemModel { QModelIndex parentIndex) { BookshelfModel::Item *parentItem(getItem(parentIndex)); int groupIndex; - T *groupItem(parentItem->getGroupItem<T>(module, &groupIndex)); + T *groupItem(parentItem->getGroupItem<T>(module, groupIndex)); if (groupItem == 0) { groupItem = new T(module); @@ -129,6 +143,8 @@ class BtBookshelfTreeModel: public QAbstractItemModel { Grouping m_groupingOrder; CheckedBehavior m_defaultChecked; bool m_checkable; + + QSet<CSwordModuleInfo*> m_checkedModulesCache; }; QDataStream &operator<<(QDataStream &os, const BtBookshelfTreeModel::Grouping &o); diff --git a/src/backend/bookshelfmodel/btcheckstatefilterproxymodel.cpp b/src/backend/bookshelfmodel/btcheckstatefilterproxymodel.cpp deleted file mode 100644 index 184bd39..0000000 --- a/src/backend/bookshelfmodel/btcheckstatefilterproxymodel.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/********* -* -* In the name of the Father, and of the Son, and of the Holy Spirit. -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-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 deleted file mode 100644 index 78d324d..0000000 --- a/src/backend/bookshelfmodel/btcheckstatefilterproxymodel.h +++ /dev/null @@ -1,53 +0,0 @@ -/********* -* -* In the name of the Father, and of the Son, and of the Holy Spirit. -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-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/btmodulecategoryfilterproxymodel.cpp b/src/backend/bookshelfmodel/btmodulecategoryfilterproxymodel.cpp deleted file mode 100644 index a969218..0000000 --- a/src/backend/bookshelfmodel/btmodulecategoryfilterproxymodel.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/********* -* -* In the name of the Father, and of the Son, and of the Holy Spirit. -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-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 deleted file mode 100644 index 7517986..0000000 --- a/src/backend/bookshelfmodel/btmodulecategoryfilterproxymodel.h +++ /dev/null @@ -1,49 +0,0 @@ -/********* -* -* In the name of the Father, and of the Son, and of the Holy Spirit. -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-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 deleted file mode 100644 index 3a50300..0000000 --- a/src/backend/bookshelfmodel/btmodulehiddenfilterproxymodel.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/********* -* -* In the name of the Father, and of the Son, and of the Holy Spirit. -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-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 deleted file mode 100644 index 8871930..0000000 --- a/src/backend/bookshelfmodel/btmodulehiddenfilterproxymodel.h +++ /dev/null @@ -1,48 +0,0 @@ -/********* -* -* In the name of the Father, and of the Son, and of the Holy Spirit. -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-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 deleted file mode 100644 index 1d20cdb..0000000 --- a/src/backend/bookshelfmodel/btmodulenamefilterproxymodel.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/********* -* -* In the name of the Father, and of the Son, and of the Holy Spirit. -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-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" - -#include "backend/bookshelfmodel/btbookshelfmodel.h" - - -BtModuleNameFilterProxyModel::BtModuleNameFilterProxyModel(QObject *parent) - : QSortFilterProxyModel(parent), m_enabled(true) { - setFilterRole(BtBookshelfModel::ModuleNameRole); - 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, filterKeyColumn(), 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 deleted file mode 100644 index 9b24dd6..0000000 --- a/src/backend/bookshelfmodel/btmodulenamefilterproxymodel.h +++ /dev/null @@ -1,37 +0,0 @@ -/********* -* -* In the name of the Father, and of the Son, and of the Holy Spirit. -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-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 index 1788dfc..46905d7 100644 --- a/src/backend/bookshelfmodel/categoryitem.cpp +++ b/src/backend/bookshelfmodel/categoryitem.cpp @@ -20,6 +20,17 @@ CategoryItem::CategoryItem(CSwordModuleInfo *module) // Intentionally empty } +QVariant CategoryItem::data(int role) const { + switch (role) { + case Qt::DisplayRole: + return BtBookshelfModel::categoryName(m_category); + case Qt::DecorationRole: + return BtBookshelfModel::categoryIcon(m_category); + default: + return Item::data(role); + } +} + bool CategoryItem::operator<(const Item &other) const { if (other.type() != ITEM_CATEGORY) { return ITEM_CATEGORY < other.type(); diff --git a/src/backend/bookshelfmodel/categoryitem.h b/src/backend/bookshelfmodel/categoryitem.h index fcff12b..879895f 100644 --- a/src/backend/bookshelfmodel/categoryitem.h +++ b/src/backend/bookshelfmodel/categoryitem.h @@ -34,13 +34,7 @@ class CategoryItem: public Item { return m_category; } - inline QString name() const { - return BtBookshelfModel::categoryName(m_category); - } - - inline QIcon icon() const { - return BtBookshelfModel::categoryIcon(m_category); - } + QVariant data(int role = Qt::DisplayRole) const; 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 deleted file mode 100644 index fee9c19..0000000 --- a/src/backend/bookshelfmodel/distributionitem.cpp +++ /dev/null @@ -1,23 +0,0 @@ -/********* -* -* In the name of the Father, and of the Son, and of the Holy Spirit. -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-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/indexingitem.cpp b/src/backend/bookshelfmodel/indexingitem.cpp new file mode 100644 index 0000000..898096f --- /dev/null +++ b/src/backend/bookshelfmodel/indexingitem.cpp @@ -0,0 +1,37 @@ +/********* +* +* In the name of the Father, and of the Son, and of the Holy Spirit. +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2009 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +#include "indexingitem.h" + + +namespace BookshelfModel { + +IndexingItem::IndexingItem(CSwordModuleInfo *module) + : Item(Item::ITEM_INDEXING), m_indexed(module->hasIndex()) { + // Intentionally empty +} + +QVariant IndexingItem::data(int role) const { + switch (role) { + case Qt::DisplayRole: + if (m_indexed) { + return QObject::tr("Indexed works"); + } + else { + return QObject::tr("Unindexed works"); + } + default: + return Item::data(role); + } +} + +} // namespace BookshelfModel diff --git a/src/backend/bookshelfmodel/distributionitem.h b/src/backend/bookshelfmodel/indexingitem.h index 4ae1197..f30fb2d 100644 --- a/src/backend/bookshelfmodel/distributionitem.h +++ b/src/backend/bookshelfmodel/indexingitem.h @@ -10,8 +10,8 @@ * **********/ -#ifndef DISTRIBUTIONITEM_H -#define DISTRIBUTIONITEM_H +#ifndef INDEXINGITEM_H +#define INDEXINGITEM_H #include "backend/bookshelfmodel/item.h" @@ -20,29 +20,22 @@ namespace BookshelfModel { -class DistributionItem: public Item { +class IndexingItem: public Item { public: - static const Item::Type GROUP_TYPE = Item::ITEM_DISTRIBUTION; + static const Item::Type GROUP_TYPE = Item::ITEM_INDEXING; - DistributionItem(CSwordModuleInfo *module); + IndexingItem(CSwordModuleInfo *module); - inline QString distribution() const { - return m_distribution; - } - - inline QString name() const { - return m_distribution; - } + QVariant data(int role = Qt::DisplayRole) const; inline bool fitFor(CSwordModuleInfo *module) const { - return module->config(CSwordModuleInfo::DistributionSource) - == m_distribution; + return module->hasIndex() == m_indexed; } protected: - QString m_distribution; + bool m_indexed; }; } // namespace BookshelfModel -#endif // DISTRIBUTIONITEM_H +#endif // INDEXINGITEM_H diff --git a/src/backend/bookshelfmodel/item.cpp b/src/backend/bookshelfmodel/item.cpp index ec2dcab..809021b 100644 --- a/src/backend/bookshelfmodel/item.cpp +++ b/src/backend/bookshelfmodel/item.cpp @@ -12,9 +12,7 @@ #include "backend/bookshelfmodel/item.h" -#include "backend/bookshelfmodel/categoryitem.h" -#include "backend/bookshelfmodel/distributionitem.h" -#include "backend/bookshelfmodel/languageitem.h" +#include "backend/bookshelfmodel/btbookshelfmodel.h" namespace BookshelfModel { @@ -47,19 +45,29 @@ int Item::indexFor(Item *newItem) { } } -bool Item::operator<(const Item &other) const { - if (m_type != other.type()) { - return m_type < other.type(); +QVariant Item::data(int role) const { + switch (role) { + case Qt::CheckStateRole: + return m_checkState; + case BtBookshelfModel::ModuleHiddenRole: + if (m_children.empty()) return true; + + foreach (Item *child, m_children) { + if (!child->data(role).toBool()) return false; + } + return true; + default: + return QVariant(); } - 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; +bool Item::operator<(const Item &other) const { + if (m_type != other.type()) { + return m_type < other.type(); } - return true; + QString first(data(Qt::DisplayRole).toString().toLower()); + QString second(other.data(Qt::DisplayRole).toString().toLower()); + return first.localeAwareCompare(second) < 0; } } // namespace BookshelfModel diff --git a/src/backend/bookshelfmodel/item.h b/src/backend/bookshelfmodel/item.h index 665343f..f10da04 100644 --- a/src/backend/bookshelfmodel/item.h +++ b/src/backend/bookshelfmodel/item.h @@ -17,6 +17,7 @@ #include <QList> #include <QString> #include <QtGlobal> +#include <QVariant> class CSwordModuleInfo; @@ -30,7 +31,7 @@ class Item { ITEM_CATEGORY = 1, ITEM_LANGUAGE = 2, ITEM_MODULE = 3, - ITEM_DISTRIBUTION = 4 + ITEM_INDEXING = 4 }; Item(Type type); @@ -54,21 +55,11 @@ class Item { /** \brief Returns the list of child items of this node. */ - inline const QList<Item*> &children() const { + inline QList<Item*> &children() { 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. */ @@ -97,18 +88,13 @@ class Item { 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) { + T *getGroupItem(CSwordModuleInfo *module, int &outIndex) { 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; + outIndex = i; return item; } } @@ -116,23 +102,14 @@ class Item { } /** - \brief Returns the visible name of the item. + \brief Returns data for this item. */ - inline virtual QString name() const { - return QString::null; - } - - /** - \brief Returns the visible icon of the item. - */ - inline virtual QIcon icon() const { - return QIcon(); - } + virtual QVariant data(int role = Qt::DisplayRole) const; /** \brief Returns the check state of this item. */ - inline const Qt::CheckState checkState() const { + inline Qt::CheckState checkState() const { return m_checkState; } @@ -148,7 +125,7 @@ class Item { \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. + \retval false This item is not a group or is a wrong group. */ inline virtual bool fitFor(CSwordModuleInfo *module) const { Q_UNUSED(module); @@ -160,8 +137,6 @@ 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 8d37891..547c953 100644 --- a/src/backend/bookshelfmodel/languageitem.cpp +++ b/src/backend/bookshelfmodel/languageitem.cpp @@ -20,4 +20,15 @@ LanguageItem::LanguageItem(CSwordModuleInfo *module) // Intentionally empty } +QVariant LanguageItem::data(int role) const { + switch (role) { + case Qt::DisplayRole: + return BtBookshelfModel::languageName(m_language); + case Qt::DecorationRole: + return util::directory::getIcon("flag.svg"); + default: + return Item::data(role); + } +} + } // namespace BookshelfModel diff --git a/src/backend/bookshelfmodel/languageitem.h b/src/backend/bookshelfmodel/languageitem.h index b5696d9..c6e4417 100644 --- a/src/backend/bookshelfmodel/languageitem.h +++ b/src/backend/bookshelfmodel/languageitem.h @@ -28,17 +28,7 @@ class LanguageItem: public Item { 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::directory::getIcon("flag.svg"); - } + QVariant data(int role = Qt::DisplayRole) const; 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 95e6f62..e7aff92 100644 --- a/src/backend/bookshelfmodel/moduleitem.cpp +++ b/src/backend/bookshelfmodel/moduleitem.cpp @@ -12,14 +12,22 @@ #include "backend/bookshelfmodel/moduleitem.h" +#include "backend/bookshelfmodel/btbookshelftreemodel.h" #include "util/cresmgr.h" namespace BookshelfModel { -ModuleItem::ModuleItem(CSwordModuleInfo *module) - : Item(ITEM_MODULE), m_moduleInfo(module) { +ModuleItem::ModuleItem(CSwordModuleInfo *module, + BtBookshelfTreeModel *parentModel) + : Item(ITEM_MODULE), m_moduleInfo(module), m_parentModel(parentModel) { Q_ASSERT(module != 0); + Q_ASSERT(parentModel != 0); +} + +QVariant ModuleItem::data(int role) const { + // Dispatch request to tree model: + return m_parentModel->data(m_moduleInfo, role); } } // namespace BookshelfModel diff --git a/src/backend/bookshelfmodel/moduleitem.h b/src/backend/bookshelfmodel/moduleitem.h index 9657423..006ae97 100644 --- a/src/backend/bookshelfmodel/moduleitem.h +++ b/src/backend/bookshelfmodel/moduleitem.h @@ -19,22 +19,27 @@ #include "backend/drivers/cswordmoduleinfo.h" +class BtBookshelfTreeModel; + namespace BookshelfModel { class ModuleItem: public Item { public: - ModuleItem(CSwordModuleInfo *module); + ModuleItem(CSwordModuleInfo *module, BtBookshelfTreeModel *parentModel); - CSwordModuleInfo *moduleInfo() const { - return m_moduleInfo; - } + /** + Reimplementation of \ref Item::data which dispatches all requests to + the \ref BtBookshelfTreeModel parent model. + */ + QVariant data(int role = Qt::DisplayRole) const; - inline bool isHidden() const { - return m_moduleInfo->isHidden(); + inline CSwordModuleInfo *moduleInfo() const { + return m_moduleInfo; } protected: - CSwordModuleInfo *m_moduleInfo; + CSwordModuleInfo *m_moduleInfo; + BtBookshelfTreeModel *m_parentModel; }; } // namespace BookshelfModel |