X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fclient%2Ftreemodel.cpp;h=3e243a42023924d4357bc43b7e47ff0133c89fea;hp=b2f61f566b2615c209ef97d26843ffd7ae446c32;hb=a700bd999215313b075ced5a1e3ba4ea8917fbbc;hpb=0a43227b8cd44625f4881cc1545d42c8c8a4876c diff --git a/src/client/treemodel.cpp b/src/client/treemodel.cpp index b2f61f56..3e243a42 100644 --- a/src/client/treemodel.cpp +++ b/src/client/treemodel.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2005-2016 by the Quassel Project * + * Copyright (C) 2005-2020 by the Quassel Project * * devel@quassel-irc.org * * * * This program is free software; you can redistribute it and/or modify * @@ -20,6 +20,8 @@ #include "treemodel.h" +#include + #include #include @@ -28,25 +30,24 @@ class RemoveChildLaterEvent : public QEvent { public: - RemoveChildLaterEvent(AbstractTreeItem *child) : QEvent(QEvent::User), _child(child) {}; - inline AbstractTreeItem *child() { return _child; } + RemoveChildLaterEvent(AbstractTreeItem* child) + : QEvent(QEvent::User) + , _child(child){}; + inline AbstractTreeItem* child() { return _child; } + private: - AbstractTreeItem *_child; + AbstractTreeItem* _child; }; - /***************************************** * Abstract Items of a TreeModel *****************************************/ -AbstractTreeItem::AbstractTreeItem(AbstractTreeItem *parent) - : QObject(parent), - _flags(Qt::ItemIsSelectable | Qt::ItemIsEnabled), - _treeItemFlags(0) -{ -} +AbstractTreeItem::AbstractTreeItem(AbstractTreeItem* parent) + : QObject(parent) + , _flags(Qt::ItemIsSelectable | Qt::ItemIsEnabled) +{} - -bool AbstractTreeItem::newChild(AbstractTreeItem *item) +bool AbstractTreeItem::newChild(AbstractTreeItem* item) { int newRow = childCount(); emit beginAppendChilds(newRow, newRow); @@ -55,8 +56,7 @@ bool AbstractTreeItem::newChild(AbstractTreeItem *item) return true; } - -bool AbstractTreeItem::newChilds(const QList &items) +bool AbstractTreeItem::newChilds(const QList& items) { if (items.isEmpty()) return false; @@ -71,7 +71,6 @@ bool AbstractTreeItem::newChilds(const QList &items) return true; } - bool AbstractTreeItem::removeChild(int row) { if (row < 0 || childCount() <= row) @@ -79,7 +78,7 @@ bool AbstractTreeItem::removeChild(int row) child(row)->removeAllChilds(); emit beginRemoveChilds(row, row); - AbstractTreeItem *treeitem = _childItems.takeAt(row); + AbstractTreeItem* treeitem = _childItems.takeAt(row); delete treeitem; emit endRemoveChilds(); @@ -88,7 +87,6 @@ bool AbstractTreeItem::removeChild(int row) return true; } - void AbstractTreeItem::removeAllChilds() { const int numChilds = childCount(); @@ -96,14 +94,14 @@ void AbstractTreeItem::removeAllChilds() if (numChilds == 0) return; - AbstractTreeItem *child; + AbstractTreeItem* child; - QList::iterator childIter; + QList::iterator childIter; childIter = _childItems.begin(); while (childIter != _childItems.end()) { child = *childIter; - child->setTreeItemFlags(0); // disable self deletion, as this would only fuck up consitency and the child gets deleted anyways + child->setTreeItemFlags({}); // disable self deletion, as this would only fuck up consitency and the child gets deleted anyways child->removeAllChilds(); ++childIter; } @@ -120,22 +118,20 @@ void AbstractTreeItem::removeAllChilds() checkForDeletion(); } - -void AbstractTreeItem::removeChildLater(AbstractTreeItem *child) +void AbstractTreeItem::removeChildLater(AbstractTreeItem* child) { Q_ASSERT(child); QCoreApplication::postEvent(this, new RemoveChildLaterEvent(child)); } - -void AbstractTreeItem::customEvent(QEvent *event) +void AbstractTreeItem::customEvent(QEvent* event) { if (event->type() != QEvent::User) return; event->accept(); - RemoveChildLaterEvent *removeEvent = static_cast(event); + auto* removeEvent = static_cast(event); int childRow = _childItems.indexOf(removeEvent->child()); if (childRow == -1) return; @@ -147,13 +143,12 @@ void AbstractTreeItem::customEvent(QEvent *event) removeChild(childRow); } - -bool AbstractTreeItem::reParent(AbstractTreeItem *newParent) +bool AbstractTreeItem::reParent(AbstractTreeItem* newParent) { // currently we support only re parenting if the child that's about to be // adopted does not have any children itself. if (childCount() != 0) { - qDebug() << "AbstractTreeItem::reParent(): cannot reparent" << this << "with children."; + qDebug() << "AbstractTreeItem::reParent(): cannot reparent" << this << "with children."; return false; } @@ -165,12 +160,13 @@ bool AbstractTreeItem::reParent(AbstractTreeItem *newParent) parent()->_childItems.removeAt(oldRow); emit parent()->endRemoveChilds(); - AbstractTreeItem *oldParent = parent(); + AbstractTreeItem* oldParent = parent(); setParent(newParent); bool success = newParent->newChild(this); if (!success) - qWarning() << "AbstractTreeItem::reParent(): failed to attach to new parent after removing from old parent! this:" << this << "new parent:" << newParent; + qWarning() << "AbstractTreeItem::reParent(): failed to attach to new parent after removing from old parent! this:" << this + << "new parent:" << newParent; if (oldParent) oldParent->checkForDeletion(); @@ -178,16 +174,14 @@ bool AbstractTreeItem::reParent(AbstractTreeItem *newParent) return success; } - -AbstractTreeItem *AbstractTreeItem::child(int row) const +AbstractTreeItem* AbstractTreeItem::child(int row) const { if (childCount() <= row) - return 0; + return nullptr; else return _childItems[row]; } - int AbstractTreeItem::childCount(int column) const { if (column > 0) @@ -196,7 +190,6 @@ int AbstractTreeItem::childCount(int column) const return _childItems.count(); } - int AbstractTreeItem::row() const { if (!parent()) { @@ -204,19 +197,18 @@ int AbstractTreeItem::row() const return -1; } - int row_ = parent()->_childItems.indexOf(const_cast(this)); + int row_ = parent()->_childItems.indexOf(const_cast(this)); if (row_ == -1) qWarning() << "AbstractTreeItem::row():" << this << "is not in the child list of" << QObject::parent(); return row_; } - void AbstractTreeItem::dumpChildList() { qDebug() << "==== Childlist for Item:" << this << "===="; if (childCount() > 0) { - AbstractTreeItem *child; - QList::const_iterator childIter = _childItems.constBegin(); + AbstractTreeItem* child; + QList::const_iterator childIter = _childItems.constBegin(); while (childIter != _childItems.constEnd()) { child = *childIter; qDebug() << "Row:" << child->row() << child << child->data(0, Qt::DisplayRole); @@ -226,21 +218,13 @@ void AbstractTreeItem::dumpChildList() qDebug() << "==== End Of Childlist ===="; } - /***************************************** * SimpleTreeItem *****************************************/ -SimpleTreeItem::SimpleTreeItem(const QList &data, AbstractTreeItem *parent) - : AbstractTreeItem(parent), - _itemData(data) -{ -} - - -SimpleTreeItem::~SimpleTreeItem() -{ -} - +SimpleTreeItem::SimpleTreeItem(QList data, AbstractTreeItem* parent) + : AbstractTreeItem(parent) + , _itemData(std::move(data)) +{} QVariant SimpleTreeItem::data(int column, int role) const { @@ -250,8 +234,7 @@ QVariant SimpleTreeItem::data(int column, int role) const return _itemData[column]; } - -bool SimpleTreeItem::setData(int column, const QVariant &value, int role) +bool SimpleTreeItem::setData(int column, const QVariant& value, int role) { if (column > columnCount() || role != Qt::DisplayRole) return false; @@ -265,34 +248,17 @@ bool SimpleTreeItem::setData(int column, const QVariant &value, int role) return true; } - int SimpleTreeItem::columnCount() const { return _itemData.count(); } - /***************************************** * PropertyMapItem *****************************************/ -PropertyMapItem::PropertyMapItem(const QStringList &propertyOrder, AbstractTreeItem *parent) - : AbstractTreeItem(parent), - _propertyOrder(propertyOrder) -{ -} - - -PropertyMapItem::PropertyMapItem(AbstractTreeItem *parent) - : AbstractTreeItem(parent), - _propertyOrder(QStringList()) -{ -} - - -PropertyMapItem::~PropertyMapItem() -{ -} - +PropertyMapItem::PropertyMapItem(AbstractTreeItem* parent) + : AbstractTreeItem(parent) +{} QVariant PropertyMapItem::data(int column, int role) const { @@ -303,135 +269,121 @@ QVariant PropertyMapItem::data(int column, int role) const case Qt::ToolTipRole: return toolTip(column); case Qt::DisplayRole: - case TreeModel::SortRole: // fallthrough, since SortRole should default to DisplayRole - return property(_propertyOrder[column].toLatin1()); + case TreeModel::SortRole: // fallthrough, since SortRole should default to DisplayRole + return property(propertyOrder()[column].toLatin1()); default: return QVariant(); } } - -bool PropertyMapItem::setData(int column, const QVariant &value, int role) +bool PropertyMapItem::setData(int column, const QVariant& value, int role) { if (column >= columnCount() || role != Qt::DisplayRole) return false; + setProperty(propertyOrder()[column].toLatin1(), value); emit dataChanged(column); - return setProperty(_propertyOrder[column].toLatin1(), value); + return true; } - int PropertyMapItem::columnCount() const { - return _propertyOrder.count(); -} - - -void PropertyMapItem::appendProperty(const QString &property) -{ - _propertyOrder << property; + return propertyOrder().count(); } - /***************************************** * TreeModel *****************************************/ -TreeModel::TreeModel(const QList &data, QObject *parent) - : QAbstractItemModel(parent), - _childStatus(QModelIndex(), 0, 0, 0), - _aboutToRemoveOrInsert(false) +TreeModel::TreeModel(const QList& data, QObject* parent) + : QAbstractItemModel(parent) + , _childStatus(QModelIndex(), 0, 0, 0) + , _aboutToRemoveOrInsert(false) { - rootItem = new SimpleTreeItem(data, 0); + rootItem = new SimpleTreeItem(data, nullptr); connectItem(rootItem); if (Quassel::isOptionSet("debugmodel")) { - connect(this, SIGNAL(rowsAboutToBeInserted(const QModelIndex &, int, int)), - this, SLOT(debug_rowsAboutToBeInserted(const QModelIndex &, int, int))); - connect(this, SIGNAL(rowsAboutToBeRemoved(const QModelIndex &, int, int)), - this, SLOT(debug_rowsAboutToBeRemoved(const QModelIndex &, int, int))); - connect(this, SIGNAL(rowsInserted(const QModelIndex &, int, int)), - this, SLOT(debug_rowsInserted(const QModelIndex &, int, int))); - connect(this, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), - this, SLOT(debug_rowsRemoved(const QModelIndex &, int, int))); - connect(this, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), - this, SLOT(debug_dataChanged(const QModelIndex &, const QModelIndex &))); + connect(this, &QAbstractItemModel::rowsAboutToBeInserted, this, &TreeModel::debug_rowsAboutToBeInserted); + connect(this, &QAbstractItemModel::rowsAboutToBeRemoved, this, &TreeModel::debug_rowsAboutToBeRemoved); + connect(this, &QAbstractItemModel::rowsInserted, this, &TreeModel::debug_rowsInserted); + connect(this, &QAbstractItemModel::rowsRemoved, this, &TreeModel::debug_rowsRemoved); + connect(this, &QAbstractItemModel::dataChanged, this, &TreeModel::debug_dataChanged); } } - TreeModel::~TreeModel() { delete rootItem; } +AbstractTreeItem* TreeModel::root() const +{ + return rootItem; +} -QModelIndex TreeModel::index(int row, int column, const QModelIndex &parent) const +QModelIndex TreeModel::index(int row, int column, const QModelIndex& parent) const { if (row < 0 || row >= rowCount(parent) || column < 0 || column >= columnCount(parent)) - return QModelIndex(); + return {}; - AbstractTreeItem *parentItem; + AbstractTreeItem* parentItem; if (!parent.isValid()) parentItem = rootItem; else - parentItem = static_cast(parent.internalPointer()); + parentItem = static_cast(parent.internalPointer()); - AbstractTreeItem *childItem = parentItem->child(row); + AbstractTreeItem* childItem = parentItem->child(row); if (childItem) return createIndex(row, column, childItem); else - return QModelIndex(); + return {}; } - -QModelIndex TreeModel::indexByItem(AbstractTreeItem *item) const +QModelIndex TreeModel::indexByItem(AbstractTreeItem* item) const { - if (item == 0) { + if (item == nullptr) { qWarning() << "TreeModel::indexByItem(AbstractTreeItem *item) received NULL-Pointer"; - return QModelIndex(); + return {}; } if (item == rootItem) - return QModelIndex(); + return {}; else return createIndex(item->row(), 0, item); } - -QModelIndex TreeModel::parent(const QModelIndex &index) const +QModelIndex TreeModel::parent(const QModelIndex& index) const { if (!index.isValid()) { // ModelTest does this // qWarning() << "TreeModel::parent(): has been asked for the rootItems Parent!"; - return QModelIndex(); + return {}; } - AbstractTreeItem *childItem = static_cast(index.internalPointer()); - AbstractTreeItem *parentItem = childItem->parent(); + auto* childItem = static_cast(index.internalPointer()); + AbstractTreeItem* parentItem = childItem->parent(); Q_ASSERT(parentItem); if (parentItem == rootItem) - return QModelIndex(); + return {}; return createIndex(parentItem->row(), 0, parentItem); } - -int TreeModel::rowCount(const QModelIndex &parent) const +int TreeModel::rowCount(const QModelIndex& parent) const { - AbstractTreeItem *parentItem; + AbstractTreeItem* parentItem; if (!parent.isValid()) parentItem = rootItem; else - parentItem = static_cast(parent.internalPointer()); + parentItem = static_cast(parent.internalPointer()); return parentItem->childCount(parent.column()); } - -int TreeModel::columnCount(const QModelIndex &parent) const +int TreeModel::columnCount(const QModelIndex& parent) const { Q_UNUSED(parent) return rootItem->columnCount(); @@ -440,47 +392,43 @@ int TreeModel::columnCount(const QModelIndex &parent) const // actually this gives us more freedom cause we don't have to ensure that a rows parent // has equal or more columns than that row -// AbstractTreeItem *parentItem; -// if(!parent.isValid()) -// parentItem = rootItem; -// else -// parentItem = static_cast(parent.internalPointer()); -// return parentItem->columnCount(); + // AbstractTreeItem *parentItem; + // if(!parent.isValid()) + // parentItem = rootItem; + // else + // parentItem = static_cast(parent.internalPointer()); + // return parentItem->columnCount(); } - -QVariant TreeModel::data(const QModelIndex &index, int role) const +QVariant TreeModel::data(const QModelIndex& index, int role) const { if (!index.isValid()) return QVariant(); - AbstractTreeItem *item = static_cast(index.internalPointer()); + auto* item = static_cast(index.internalPointer()); return item->data(index.column(), role); } - -bool TreeModel::setData(const QModelIndex &index, const QVariant &value, int role) +bool TreeModel::setData(const QModelIndex& index, const QVariant& value, int role) { if (!index.isValid()) return false; - AbstractTreeItem *item = static_cast(index.internalPointer()); + auto* item = static_cast(index.internalPointer()); return item->setData(index.column(), value, role); } - -Qt::ItemFlags TreeModel::flags(const QModelIndex &index) const +Qt::ItemFlags TreeModel::flags(const QModelIndex& index) const { if (!index.isValid()) { return rootItem->flags() & Qt::ItemIsDropEnabled; } else { - AbstractTreeItem *item = static_cast(index.internalPointer()); + auto* item = static_cast(index.internalPointer()); return item->flags(); } } - QVariant TreeModel::headerData(int section, Qt::Orientation orientation, int role) const { if (orientation == Qt::Horizontal && role == Qt::DisplayRole) @@ -489,10 +437,9 @@ QVariant TreeModel::headerData(int section, Qt::Orientation orientation, int rol return QVariant(); } - void TreeModel::itemDataChanged(int column) { - AbstractTreeItem *item = qobject_cast(sender()); + auto* item = qobject_cast(sender()); QModelIndex leftIndex, rightIndex; if (item == rootItem) @@ -510,27 +457,20 @@ void TreeModel::itemDataChanged(int column) emit dataChanged(leftIndex, rightIndex); } - -void TreeModel::connectItem(AbstractTreeItem *item) +void TreeModel::connectItem(AbstractTreeItem* item) { - connect(item, SIGNAL(dataChanged(int)), - this, SLOT(itemDataChanged(int))); + connect(item, &AbstractTreeItem::dataChanged, this, &TreeModel::itemDataChanged); - connect(item, SIGNAL(beginAppendChilds(int, int)), - this, SLOT(beginAppendChilds(int, int))); - connect(item, SIGNAL(endAppendChilds()), - this, SLOT(endAppendChilds())); + connect(item, &AbstractTreeItem::beginAppendChilds, this, &TreeModel::beginAppendChilds); + connect(item, &AbstractTreeItem::endAppendChilds, this, &TreeModel::endAppendChilds); - connect(item, SIGNAL(beginRemoveChilds(int, int)), - this, SLOT(beginRemoveChilds(int, int))); - connect(item, SIGNAL(endRemoveChilds()), - this, SLOT(endRemoveChilds())); + connect(item, &AbstractTreeItem::beginRemoveChilds, this, &TreeModel::beginRemoveChilds); + connect(item, &AbstractTreeItem::endRemoveChilds, this, &TreeModel::endRemoveChilds); } - void TreeModel::beginAppendChilds(int firstRow, int lastRow) { - AbstractTreeItem *parentItem = qobject_cast(sender()); + auto* parentItem = qobject_cast(sender()); if (!parentItem) { qWarning() << "TreeModel::beginAppendChilds(): cannot append Children to unknown parent"; return; @@ -544,10 +484,9 @@ void TreeModel::beginAppendChilds(int firstRow, int lastRow) beginInsertRows(parent, firstRow, lastRow); } - void TreeModel::endAppendChilds() { - AbstractTreeItem *parentItem = qobject_cast(sender()); + auto* parentItem = qobject_cast(sender()); if (!parentItem) { qWarning() << "TreeModel::endAppendChilds(): cannot append Children to unknown parent"; return; @@ -566,17 +505,16 @@ void TreeModel::endAppendChilds() endInsertRows(); } - void TreeModel::beginRemoveChilds(int firstRow, int lastRow) { - AbstractTreeItem *parentItem = qobject_cast(sender()); + auto* parentItem = qobject_cast(sender()); if (!parentItem) { qWarning() << "TreeModel::beginRemoveChilds(): cannot append Children to unknown parent"; return; } for (int i = firstRow; i <= lastRow; i++) { - disconnect(parentItem->child(i), 0, this, 0); + disconnect(parentItem->child(i), nullptr, this, nullptr); } // consitency checks @@ -590,10 +528,9 @@ void TreeModel::beginRemoveChilds(int firstRow, int lastRow) beginRemoveRows(parent, firstRow, lastRow); } - void TreeModel::endRemoveChilds() { - AbstractTreeItem *parentItem = qobject_cast(sender()); + auto* parentItem = qobject_cast(sender()); if (!parentItem) { qWarning() << "TreeModel::endRemoveChilds(): cannot remove Children from unknown parent"; return; @@ -612,60 +549,67 @@ void TreeModel::endRemoveChilds() endRemoveRows(); } - void TreeModel::clear() { rootItem->removeAllChilds(); } - -void TreeModel::debug_rowsAboutToBeInserted(const QModelIndex &parent, int start, int end) +void TreeModel::debug_rowsAboutToBeInserted(const QModelIndex& parent, int start, int end) { - qDebug() << "debug_rowsAboutToBeInserted" << parent << parent.internalPointer() << parent.data().toString() << rowCount(parent) << start << end; + qDebug() << "debug_rowsAboutToBeInserted" << parent << parent.internalPointer() << parent.data().toString() << rowCount(parent) << start + << end; } - -void TreeModel::debug_rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) +void TreeModel::debug_rowsAboutToBeRemoved(const QModelIndex& parent, int start, int end) { - AbstractTreeItem *parentItem; - parentItem = static_cast(parent.internalPointer()); + AbstractTreeItem* parentItem; + parentItem = static_cast(parent.internalPointer()); if (!parentItem) parentItem = rootItem; qDebug() << "debug_rowsAboutToBeRemoved" << parent << parentItem << parent.data().toString() << rowCount(parent) << start << end; + // Make sure model is valid first + if (!parent.model()) { + qDebug() << "Parent model is not valid!" << end; + return; + } + QModelIndex child; for (int i = end; i >= start; i--) { - child = parent.child(i, 0); + child = parent.model()->index(i, 0, parent); Q_ASSERT(parentItem->child(i)); qDebug() << ">>>" << i << child << child.data().toString(); } } - -void TreeModel::debug_rowsInserted(const QModelIndex &parent, int start, int end) +void TreeModel::debug_rowsInserted(const QModelIndex& parent, int start, int end) { - AbstractTreeItem *parentItem; - parentItem = static_cast(parent.internalPointer()); + AbstractTreeItem* parentItem; + parentItem = static_cast(parent.internalPointer()); if (!parentItem) parentItem = rootItem; qDebug() << "debug_rowsInserted:" << parent << parentItem << parent.data().toString() << rowCount(parent) << start << end; + // Make sure model is valid first + if (!parent.model()) { + qDebug() << "Parent model is not valid!" << end; + return; + } + QModelIndex child; for (int i = start; i <= end; i++) { - child = parent.child(i, 0); + child = parent.model()->index(i, 0, parent); Q_ASSERT(parentItem->child(i)); qDebug() << "<<<" << i << child << child.data().toString(); } } - -void TreeModel::debug_rowsRemoved(const QModelIndex &parent, int start, int end) +void TreeModel::debug_rowsRemoved(const QModelIndex& parent, int start, int end) { qDebug() << "debug_rowsRemoved" << parent << parent.internalPointer() << parent.data().toString() << rowCount(parent) << start << end; } - -void TreeModel::debug_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) +void TreeModel::debug_dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) { qDebug() << "debug_dataChanged" << topLeft << bottomRight; QStringList displayData;