X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fclient%2Ftreemodel.cpp;h=c61cf9e83366b7bcba8973acfcb69ea6c2476a4b;hp=ad0706e188dec45c40dd8d5cfe3f481cd9fd48b7;hb=e8a5c49548759045b49c208c250c6f61c7fdfcd5;hpb=d5e69c3c89f674c4b033b5ff3469c547fd09f927 diff --git a/src/client/treemodel.cpp b/src/client/treemodel.cpp index ad0706e1..c61cf9e8 100644 --- a/src/client/treemodel.cpp +++ b/src/client/treemodel.cpp @@ -51,10 +51,40 @@ bool AbstractTreeItem::newChild(AbstractTreeItem *item) { return true; } +bool AbstractTreeItem::newChilds(const QList &items) { + if(items.isEmpty()) + return false; + + QList::const_iterator itemIter = items.constBegin(); + AbstractTreeItem *item; + while(itemIter != items.constEnd()) { + item = *itemIter; + if(childById(item->id()) != 0) { + qWarning() << "AbstractTreeItem::newChilds(): received child that is already attached" << item << item->id(); + return false; + } + itemIter++; + } + + int nextRow = childCount(); + int lastRow = nextRow + items.count() - 1; + + emit beginAppendChilds(nextRow, lastRow); + itemIter = items.constBegin(); + while(itemIter != items.constEnd()) { + _childItems.append(*itemIter); + itemIter++; + } + emit endAppendChilds(); + + return true; +} + bool AbstractTreeItem::removeChild(int row) { if(childCount() <= row) return false; + child(row)->removeAllChilds(); emit beginRemoveChilds(row, row); AbstractTreeItem *treeitem = _childItems.takeAt(row); treeitem->deleteLater(); @@ -82,8 +112,17 @@ void AbstractTreeItem::removeAllChilds() { AbstractTreeItem *child; + QList::iterator childIter; + + childIter = _childItems.begin(); + while(childIter != _childItems.end()) { + child = *childIter; + child->removeAllChilds(); + childIter++; + } + emit beginRemoveChilds(0, numChilds - 1); - QList::iterator childIter = _childItems.begin(); + childIter = _childItems.begin(); while(childIter != _childItems.end()) { child = *childIter; childIter = _childItems.erase(childIter); @@ -92,6 +131,31 @@ void AbstractTreeItem::removeAllChilds() { emit endRemoveChilds(); } +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."; + return false; + } + + int oldRow = row(); + if(oldRow == -1) + return false; + + emit parent()->beginRemoveChilds(oldRow, oldRow); + parent()->_childItems.removeAt(oldRow); + emit parent()->endRemoveChilds(); + + 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; + + return success; +} + AbstractTreeItem *AbstractTreeItem::child(int row) const { if(childCount() <= row) return 0; @@ -108,15 +172,23 @@ AbstractTreeItem *AbstractTreeItem::childById(const quint64 &id) const { return 0; } -int AbstractTreeItem::childCount() const { - return _childItems.count(); +int AbstractTreeItem::childCount(int column) const { + if(column > 0) + return 0; + else + return _childItems.count(); } int AbstractTreeItem::row() const { - if(!parent()) + if(!parent()) { + qWarning() << "AbstractTreeItem::row():" << this << "has no parent AbstractTreeItem as it's parent! parent is" << QObject::parent(); return -1; - else - return 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_; } AbstractTreeItem *AbstractTreeItem::parent() const { @@ -208,6 +280,7 @@ 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].toAscii()); default: return QVariant(); @@ -253,6 +326,8 @@ TreeModel::TreeModel(const QList &data, QObject *parent) 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 &))); } } @@ -330,27 +405,23 @@ int TreeModel::rowCount(const QModelIndex &parent) const { else parentItem = static_cast(parent.internalPointer()); - return parentItem->childCount(); + return parentItem->childCount(parent.column()); } int TreeModel::columnCount(const QModelIndex &parent) const { Q_UNUSED(parent) + return rootItem->columnCount(); // since there the Qt Views don't draw more columns than the header has columns // we can be lazy and simply return the count of header columns // 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 - -// if(parent.isValid()) { -// AbstractTreeItem *child; -// if(child = static_cast(parent.internalPointer())->child(parent.column(), parent.row())) -// return child->columnCount(); -// else -// return static_cast(parent.internalPointer())->columnCount(); -// } else { -// return rootItem->columnCount(); -// } - return rootItem->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 { @@ -370,12 +441,12 @@ bool TreeModel::setData(const QModelIndex &index, const QVariant &value, int rol } Qt::ItemFlags TreeModel::flags(const QModelIndex &index) const { - AbstractTreeItem *item; - if(!index.isValid()) - item = rootItem; - else - item = static_cast(index.internalPointer()); - return item->flags(); + if(!index.isValid()) { + return rootItem->flags() & Qt::ItemIsDropEnabled; + } else { + AbstractTreeItem *item = static_cast(index.internalPointer()); + return item->flags(); + } } QVariant TreeModel::headerData(int section, Qt::Orientation orientation, int role) const { @@ -458,29 +529,37 @@ void TreeModel::beginRemoveChilds(int firstRow, int lastRow) { qWarning() << "TreeModel::beginRemoveChilds(): cannot append Childs to unknown parent"; return; } + + for(int i = firstRow; i <= lastRow; i++) { + disconnect(parentItem->child(i), 0, this, 0); + } + + // consitency checks QModelIndex parent = indexByItem(parentItem); Q_ASSERT(firstRow <= lastRow); Q_ASSERT(parentItem->childCount() > lastRow); Q_ASSERT(!_aboutToRemoveOrInsert); - _aboutToRemoveOrInsert = true; _childStatus = ChildStatus(parent, rowCount(parent), firstRow, lastRow); + beginRemoveRows(parent, firstRow, lastRow); } void TreeModel::endRemoveChilds() { AbstractTreeItem *parentItem = qobject_cast(sender()); if(!parentItem) { - qWarning() << "TreeModel::endRemoveChilds(): cannot append Childs to unknown parent"; + qWarning() << "TreeModel::endRemoveChilds(): cannot remove Childs from unknown parent"; return; } + + // concistency checks Q_ASSERT(_aboutToRemoveOrInsert); ChildStatus cs = _childStatus; QModelIndex parent = indexByItem(parentItem); Q_ASSERT(cs.parent == parent); Q_ASSERT(rowCount(parent) == cs.childCount - cs.end + cs.start - 1); - _aboutToRemoveOrInsert = false; + endRemoveRows(); } @@ -489,7 +568,7 @@ void TreeModel::clear() { } 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) { @@ -497,7 +576,7 @@ void TreeModel::debug_rowsAboutToBeRemoved(const QModelIndex &parent, int start, parentItem = static_cast(parent.internalPointer()); if(!parentItem) parentItem = rootItem; - qDebug() << "#" << parent << parentItem << parent.data().toString() << rowCount(parent) << start << end; + qDebug() << "debug_rowsAboutToBeRemoved" << parent << parentItem << parent.data().toString() << rowCount(parent) << start << end; QModelIndex child; AbstractTreeItem *childItem; @@ -514,7 +593,7 @@ void TreeModel::debug_rowsInserted(const QModelIndex &parent, int start, int end parentItem = static_cast(parent.internalPointer()); if(!parentItem) parentItem = rootItem; - qDebug() << "#" << parent << parentItem << parent.data().toString() << rowCount(parent) << start << end; + qDebug() << "debug_rowsInserted:" << parent << parentItem << parent.data().toString() << rowCount(parent) << start << end; QModelIndex child; AbstractTreeItem *childItem; @@ -527,5 +606,17 @@ void TreeModel::debug_rowsInserted(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; + qDebug() << "debug_rowsRemoved" << parent << parent.internalPointer() << parent.data().toString() << rowCount(parent) << start << end; +} + +void TreeModel::debug_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) { + qDebug() << "debug_dataChanged" << topLeft << bottomRight; + QStringList displayData; + for(int row = topLeft.row(); row <= bottomRight.row(); row++) { + displayData = QStringList(); + for(int column = topLeft.column(); column <= bottomRight.column(); column++) { + displayData << data(topLeft.sibling(row, column), Qt::DisplayRole).toString(); + } + qDebug() << " row:" << row << displayData; + } }