Introducing fast backlog replay! Thanks sph_ for the help!
[quassel.git] / src / client / treemodel.cpp
index 5c23063..4933f0d 100644 (file)
 #include <QDebug>
 #include <QCoreApplication>
 
+class RemoveChildLaterEvent : public QEvent {
+public:
+  RemoveChildLaterEvent(AbstractTreeItem *child) : QEvent(QEvent::User), _child(child) {};
+  inline AbstractTreeItem *child() { return _child; }
+private:
+  AbstractTreeItem *_child;
+};
+
+
 /*****************************************
  *  Abstract Items of a TreeModel
  *****************************************/
 AbstractTreeItem::AbstractTreeItem(AbstractTreeItem *parent)
   : QObject(parent),
-    _flags(Qt::ItemIsSelectable | Qt::ItemIsEnabled)
+    _flags(Qt::ItemIsSelectable | Qt::ItemIsEnabled),
+    _treeItemFlags(0)
 {
 }
 
-AbstractTreeItem::~AbstractTreeItem() {
-}
-
 bool AbstractTreeItem::newChild(AbstractTreeItem *item) {
   int newRow = childCount();
   emit beginAppendChilds(newRow, newRow);
@@ -59,15 +66,17 @@ bool AbstractTreeItem::newChilds(const QList<AbstractTreeItem *> &items) {
 }
 
 bool AbstractTreeItem::removeChild(int row) {
-  if(childCount() <= row)
+  if(row < 0 || childCount() <= row)
     return false;
 
   child(row)->removeAllChilds();
   emit beginRemoveChilds(row, row);
   AbstractTreeItem *treeitem = _childItems.takeAt(row);
-  treeitem->deleteLater();
+  delete treeitem;
   emit endRemoveChilds();
 
+  checkForDeletion();
+  
   return true;
 }
 
@@ -84,6 +93,7 @@ void AbstractTreeItem::removeAllChilds() {
   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->removeAllChilds();
     childIter++;
   }
@@ -93,9 +103,30 @@ void AbstractTreeItem::removeAllChilds() {
   while(childIter != _childItems.end()) {
     child = *childIter;
     childIter = _childItems.erase(childIter);
-    child->deleteLater();
+    delete child;
   }
   emit endRemoveChilds();
+
+  checkForDeletion();
+}
+
+void AbstractTreeItem::removeChildLater(AbstractTreeItem *child) {
+  Q_ASSERT(child);
+  QCoreApplication::postEvent(this, new RemoveChildLaterEvent(child));
+}
+
+void AbstractTreeItem::customEvent(QEvent *event) {
+  if(event->type() != QEvent::User)
+    return;
+
+  event->accept();
+
+  RemoveChildLaterEvent *removeEvent = static_cast<RemoveChildLaterEvent *>(event);
+  int childRow = _childItems.indexOf(removeEvent->child());
+  if(childRow == -1)
+    return;
+
+  removeChild(childRow);
 }
 
 bool AbstractTreeItem::reParent(AbstractTreeItem *newParent) {
@@ -114,12 +145,16 @@ bool AbstractTreeItem::reParent(AbstractTreeItem *newParent) {
   parent()->_childItems.removeAt(oldRow);
   emit parent()->endRemoveChilds();
 
+  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;
 
+  if(oldParent)
+    oldParent->checkForDeletion();
+
   return success;
 }