Fixing Issues with the NetworkModel. Though the performance still
authorMarcus Eggenberger <egs@quassel-irc.org>
Sat, 19 Jan 2008 17:43:40 +0000 (17:43 +0000)
committerMarcus Eggenberger <egs@quassel-irc.org>
Sat, 19 Jan 2008 17:43:40 +0000 (17:43 +0000)
sucks when joining channels with many users (~ 1000)

src/client/networkmodel.cpp
src/client/treemodel.cpp
src/client/treemodel.h
version.inc

index 6d6792c..48a6b8c 100644 (file)
@@ -132,10 +132,7 @@ void BufferItem::attachIrcChannel(IrcChannel *ircChannel) {
 
 void BufferItem::ircChannelDestroyed() {
   emit dataChanged();
-  for(int i = 0; i < childCount(); i++) {
-    emit childDestroyed(i);
-    removeChild(i);
-  }
+  removeAllChilds();
 }
 
 QString BufferItem::bufferName() const {
@@ -203,6 +200,13 @@ void BufferItem::removeUserFromCategory(IrcUser *ircUser) {
 }
 
 void BufferItem::userModeChanged(IrcUser *ircUser) {
+  Q_ASSERT(_ircChannel);
+    
+  UserCategoryItem *categoryItem;
+  int categoryId = UserCategoryItem::categoryFromModes(_ircChannel->userModes(ircUser));
+  if((categoryItem = qobject_cast<UserCategoryItem *>(childById(qHash(categoryId)))))
+    return; // already in the right category;
+  
   removeUserFromCategory(ircUser);
   addUserToCategory(ircUser);
 }
@@ -319,7 +323,7 @@ UserCategoryItem::UserCategoryItem(int category, AbstractTreeItem *parent)
   : PropertyMapItem(QStringList() << "categoryId", parent),
     _category(category)
 {
-  connect(this, SIGNAL(childDestroyed(int)),
+  connect(this, SIGNAL(childRemoved(int)),
          this, SLOT(checkNoChilds()));
 }
 
index 10baa07..2983e5f 100644 (file)
  *****************************************/
 AbstractTreeItem::AbstractTreeItem(AbstractTreeItem *parent)
   : QObject(parent),
-    _parentItem(parent),
     _flags(Qt::ItemIsSelectable | Qt::ItemIsEnabled)
 {
 }
 
 AbstractTreeItem::~AbstractTreeItem() {
-  AbstractTreeItem *child;
-  foreach(int key, _childItems.keys()) {
-    QList<AbstractTreeItem *>::iterator iter = _childItems[key].begin();
-    while(iter != _childItems[key].end()) {
-      child = *iter;
-      iter = _childItems[key].erase(iter);
-      disconnect(child, 0, this, 0);
-      child->deleteLater();
-    }
-  }
+  removeAllChilds();
 }
 
 quint64 AbstractTreeItem::id() const {
@@ -52,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;
@@ -78,18 +68,41 @@ 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::removeAllChilds() {
+  emit beginRemoveChilds(0, childCount() - 1);
+
+  AbstractTreeItem *child;
+  foreach(int key, _childItems.keys()) {
+    QList<AbstractTreeItem *>::iterator iter = _childItems[key].begin();
+    while(iter != _childItems[key].end()) {
+      child = *iter;
+      iter = _childItems[key].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)
@@ -126,29 +139,29 @@ int AbstractTreeItem::childCount() const {
 }
 
 int AbstractTreeItem::column() const {
-  if(!_parentItem)
+  if(!parent())
     return -1;
 
-  QHash<int, QList<AbstractTreeItem*> >::const_iterator iter = _parentItem->_childItems.constBegin();
-  while(iter != _parentItem->_childItems.constEnd()) {
+  QHash<int, QList<AbstractTreeItem*> >::const_iterator iter = parent()->_childItems.constBegin();
+  while(iter != parent()->_childItems.constEnd()) {
     if(iter.value().contains(const_cast<AbstractTreeItem *>(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<AbstractTreeItem*>(this));
+    return parent()->_childItems[column()].indexOf(const_cast<AbstractTreeItem*>(this));
 }
 
 AbstractTreeItem *AbstractTreeItem::parent() const {
-  return _parentItem;
+  return qobject_cast<AbstractTreeItem *>(QObject::parent());
 }
 
 Qt::ItemFlags AbstractTreeItem::flags() const {
@@ -185,7 +198,8 @@ void AbstractTreeItem::childDestroyed() {
   
   _childItems[column].removeAt(row);
   _childHash[column].remove(_childHash[column].key(item));
-  emit childDestroyed(row);
+  emit beginRemoveChilds(row, row);
+  emit endRemoveChilds();
 }
   
 /*****************************************
@@ -413,20 +427,42 @@ void TreeModel::appendChild(AbstractTreeItem *parent, AbstractTreeItem *child) {
   connect(child, SIGNAL(newChild(AbstractTreeItem *)),
          this, SLOT(newChild(AbstractTreeItem *)));
 
-  connect(child, SIGNAL(childDestroyed(int)),
-         this, SLOT(childDestroyed(int)));
+//   connect(child, SIGNAL(childRemoved(int)),
+//       this, SLOT(childRemoved(int)));
+
+  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<AbstractTreeItem *>(sender()), child);
 }
 
-void TreeModel::childDestroyed(int row) {
+void TreeModel::beginRemoveChilds(int firstRow, int lastRow) {
+  QModelIndex parent = indexByItem(static_cast<AbstractTreeItem *>(sender()));
+  beginRemoveRows(parent, firstRow, lastRow);
+}
+
+void TreeModel::endRemoveChilds() {
+  endRemoveRows();
+}
+
+void TreeModel::childRemoved(int row) {
   QModelIndex parent = indexByItem(static_cast<AbstractTreeItem *>(sender()));
   beginRemoveRows(parent, row, row);
   endRemoveRows();
 }
 
+void TreeModel::childsRemoved(int firstRow, int lastRow) {
+  QModelIndex parent = indexByItem(static_cast<AbstractTreeItem *>(sender()));
+  beginRemoveRows(parent, firstRow, lastRow);
+  endRemoveRows();
+  
+}
+
 bool TreeModel::removeRow(int row, const QModelIndex &parent) {
   if(row > rowCount(parent))
     return false;
index da1f5fd..a8c8a99 100644 (file)
@@ -43,6 +43,7 @@ public:
   
   void removeChild(int column, int row);
   void removeChild(int row);
+  void removeAllChilds();
 
   virtual quint64 id() const;
 
@@ -69,7 +70,11 @@ public:
 signals:
   void dataChanged(int column = -1);
   void newChild(AbstractTreeItem *);
-  void childDestroyed(int row);
+  void childRemoved(int row);
+  void childsRemoved(int firstRow, int lastRow);
+
+  void beginRemoveChilds(int firstRow, int lastRow);
+  void endRemoveChilds();
                                       
 private slots:
   void childDestroyed();
@@ -77,7 +82,6 @@ private slots:
 private:
   QHash<int, QList<AbstractTreeItem *> > _childItems;
   QHash<int, QHash<quint64, AbstractTreeItem *> > _childHash; // uint to be compatible to qHash functions FIXME test this
-  AbstractTreeItem *_parentItem;
   Qt::ItemFlags _flags;
 
   int defaultColumn() const;
@@ -150,7 +154,12 @@ public:
 private slots:
   void itemDataChanged(int column = -1);
   void newChild(AbstractTreeItem *child);
-  void childDestroyed(int row);
+
+  void beginRemoveChilds(int firstRow, int lastRow);
+  void endRemoveChilds();
+  
+  void childRemoved(int row);
+  void childsRemoved(int firstRow, int lastRow);
 
 protected:
   void appendChild(AbstractTreeItem *parent, AbstractTreeItem *child);
index 3538bf3..4a88192 100644 (file)
@@ -5,7 +5,7 @@
 
   quasselVersion = "0.2.0-pre";
   quasselDate = "2008-01-19";
-  quasselBuild = 358;
+  quasselBuild = 360;
 
   //! Minimum client build number the core needs
   clientBuildNeeded = 358;