X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fclient%2Ftreemodel.cpp;h=929622d6af3eb92ec81e5b6dfcce91027c217037;hp=a2d1183b4ce472f208b40b2d1ac509e06eeed255;hb=7df7429c009d2bea4c516e87f1ec4c956c722e09;hpb=4b45582f5d766e7324fe6d2abd260548ef0b9584 diff --git a/src/client/treemodel.cpp b/src/client/treemodel.cpp index a2d1183b..929622d6 100644 --- a/src/client/treemodel.cpp +++ b/src/client/treemodel.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2005-07 by the Quassel IRC Team * + * Copyright (C) 2005-08 by the Quassel Project * * devel@quassel-irc.org * * * * This program is free software; you can redistribute it and/or modify * @@ -27,15 +27,12 @@ *****************************************/ AbstractTreeItem::AbstractTreeItem(AbstractTreeItem *parent) : QObject(parent), - _parentItem(parent), _flags(Qt::ItemIsSelectable | Qt::ItemIsEnabled) { } AbstractTreeItem::~AbstractTreeItem() { - foreach(int key, _childItems.keys()) { - qDeleteAll(_childItems[key]); - } + removeAllChilds(); } quint64 AbstractTreeItem::id() const { @@ -45,7 +42,7 @@ quint64 AbstractTreeItem::id() const { int AbstractTreeItem::defaultColumn() const { // invalid QModelIndexes aka rootNodes get their Childs stuffed into column -1 // all others to 0 - if(_parentItem == 0) + if(parent() == 0) return -1; else return 0; @@ -71,17 +68,59 @@ void AbstractTreeItem::removeChild(int column, int row) { if(!_childItems.contains(column) || _childItems[column].size() <= row) return; + + if(column == defaultColumn()) + emit beginRemoveChilds(row, row); AbstractTreeItem *treeitem = _childItems[column].value(row); _childItems[column].removeAt(row); _childHash[column].remove(_childHash[column].key(treeitem)); + disconnect(treeitem, 0, this, 0); treeitem->deleteLater(); + + if(column == defaultColumn()) + emit endRemoveChilds(); } void AbstractTreeItem::removeChild(int row) { removeChild(defaultColumn(), row); } +void AbstractTreeItem::removeChildById(int column, const quint64 &id) { + if(!_childHash[column].contains(id)) + return; + + AbstractTreeItem *treeItem = _childHash[column][id]; + int row = _childItems[column].indexOf(treeItem); + Q_ASSERT(row >= 0); + removeChild(column, row); +} + +void AbstractTreeItem::removeChildById(const quint64 &id) { + removeChildById(defaultColumn(), id); +} + +void AbstractTreeItem::removeAllChilds() { + if(childCount() == 0) + return; + + emit beginRemoveChilds(0, childCount() - 1); + + AbstractTreeItem *child; + foreach(int column, _childItems.keys()) { + QList::iterator iter = _childItems[column].begin(); + while(iter != _childItems[column].end()) { + child = *iter; + _childHash[column].remove(_childHash[column].key(child)); + iter = _childItems[column].erase(iter); + disconnect(child, 0, this, 0); + child->removeAllChilds(); + child->deleteLater(); + } + } + emit endRemoveChilds(); +} + AbstractTreeItem *AbstractTreeItem::child(int column, int row) const { if(!_childItems.contains(column) || _childItems[column].size() <= row) @@ -94,7 +133,7 @@ AbstractTreeItem *AbstractTreeItem::child(int row) const { return child(defaultColumn(), row); } -AbstractTreeItem *AbstractTreeItem::childById(int column, const uint &id) const { +AbstractTreeItem *AbstractTreeItem::childById(int column, const quint64 &id) const { if(!_childHash.contains(column) || !_childHash[column].contains(id)) return 0; @@ -102,7 +141,7 @@ AbstractTreeItem *AbstractTreeItem::childById(int column, const uint &id) const return _childHash[column].value(id); } -AbstractTreeItem *AbstractTreeItem::childById(const uint &id) const { +AbstractTreeItem *AbstractTreeItem::childById(const quint64 &id) const { return childById(defaultColumn(), id); } @@ -118,31 +157,29 @@ int AbstractTreeItem::childCount() const { } int AbstractTreeItem::column() const { - if(!_parentItem) + if(!parent()) return -1; - QHash >::const_iterator iter = _parentItem->_childItems.constBegin(); - int pos; - while(iter != _parentItem->_childItems.constEnd()) { - pos = iter.value().indexOf(const_cast(this)); - if(pos != -1) + QHash >::const_iterator iter = parent()->_childItems.constBegin(); + while(iter != parent()->_childItems.constEnd()) { + if(iter.value().contains(const_cast(this))) return iter.key(); iter++; } // unable to find us o_O - return _parentItem->defaultColumn(); + return parent()->defaultColumn(); } int AbstractTreeItem::row() const { - if(!_parentItem) + if(!parent()) return -1; else - return _parentItem->_childItems[column()].indexOf(const_cast(this)); + return parent()->_childItems[column()].indexOf(const_cast(this)); } -AbstractTreeItem *AbstractTreeItem::parent() { - return _parentItem; +AbstractTreeItem *AbstractTreeItem::parent() const { + return qobject_cast(QObject::parent()); } Qt::ItemFlags AbstractTreeItem::flags() const { @@ -160,8 +197,27 @@ void AbstractTreeItem::childDestroyed() { qWarning() << "AbstractTreeItem::childDestroyed() received null pointer!"; return; } - _childItems[item->column()].removeAt(item->row()); - _childHash[item->column()].remove(_childHash[item->column()].key(item)); + + QHash >::const_iterator iter = _childItems.constBegin(); + int column, row = -1; + while(iter != _childItems.constEnd()) { + row = iter.value().indexOf(item); + if(row != -1) { + column = iter.key(); + break; + } + iter++; + } + + if(row == -1) { + qWarning() << "AbstractTreeItem::childDestroyed(): unknown Child died:" << item << "parent:" << this; + return; + } + + _childItems[column].removeAt(row); + _childHash[column].remove(_childHash[column].key(item)); + emit beginRemoveChilds(row, row); + emit endRemoveChilds(); } /***************************************** @@ -258,7 +314,7 @@ QModelIndex TreeModel::index(int row, int column, const QModelIndex &parent) con return QModelIndex(); } -QModelIndex TreeModel::indexById(uint id, const QModelIndex &parent) const { +QModelIndex TreeModel::indexById(quint64 id, const QModelIndex &parent) const { AbstractTreeItem *parentItem; if(!parent.isValid()) @@ -311,10 +367,23 @@ int TreeModel::rowCount(const QModelIndex &parent) const { } int TreeModel::columnCount(const QModelIndex &parent) const { - if(parent.isValid()) - return static_cast(parent.internalPointer())->columnCount(); - else - return rootItem->columnCount(); + Q_UNUSED(parent) + // 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(); } QVariant TreeModel::data(const QModelIndex &index, int role) const { @@ -343,19 +412,25 @@ QVariant TreeModel::headerData(int section, Qt::Orientation orientation, int rol void TreeModel::itemDataChanged(int column) { AbstractTreeItem *item = qobject_cast(sender()); - QModelIndex itemIndex; + QModelIndex leftIndex, rightIndex; - if(item == rootItem) - itemIndex = QModelIndex(); - else - itemIndex = createIndex(item->row(), column, item); + if(item == rootItem) + return; + + if(column == -1) { + leftIndex = createIndex(item->row(), 0, item); + rightIndex = createIndex(item->row(), item->columnCount()-1, item); + } else { + leftIndex = createIndex(item->row(), column, item); + rightIndex = leftIndex; + } - emit dataChanged(itemIndex, itemIndex); + emit dataChanged(leftIndex, rightIndex); } void TreeModel::appendChild(AbstractTreeItem *parent, AbstractTreeItem *child) { if(parent == 0 or child == 0) { - qWarning() << "TreeModel::apendChild(parent, child) parent and child have to be valid pointers!" << parent << child; + qWarning() << "TreeModel::appendChild(parent, child) parent and child have to be valid pointers!" << parent << child; return; } @@ -366,8 +441,29 @@ void TreeModel::appendChild(AbstractTreeItem *parent, AbstractTreeItem *child) { connect(child, SIGNAL(dataChanged(int)), this, SLOT(itemDataChanged(int))); + + connect(child, SIGNAL(newChild(AbstractTreeItem *)), + this, SLOT(newChild(AbstractTreeItem *))); + + connect(child, SIGNAL(beginRemoveChilds(int, int)), + this, SLOT(beginRemoveChilds(int, int))); + + connect(child, SIGNAL(endRemoveChilds()), + this, SLOT(endRemoveChilds())); +} + +void TreeModel::newChild(AbstractTreeItem *child) { + appendChild(static_cast(sender()), child); } +void TreeModel::beginRemoveChilds(int firstRow, int lastRow) { + QModelIndex parent = indexByItem(static_cast(sender())); + beginRemoveRows(parent, firstRow, lastRow); +} + +void TreeModel::endRemoveChilds() { + endRemoveRows(); +} bool TreeModel::removeRow(int row, const QModelIndex &parent) { if(row > rowCount(parent))