summaryrefslogtreecommitdiff
path: root/src/backend/bookshelfmodel/btbookshelftreemodel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/bookshelfmodel/btbookshelftreemodel.cpp')
-rw-r--r--src/backend/bookshelfmodel/btbookshelftreemodel.cpp196
1 files changed, 105 insertions, 91 deletions
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;