properly rewind oidentd config file
[quassel.git] / src / client / treemodel.cpp
index 13b97f9..b3f2613 100644 (file)
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2005-08 by the Quassel Project                          *
+ *   Copyright (C) 2005-09 by the Quassel Project                          *
  *   devel@quassel-irc.org                                                 *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  ***************************************************************************/
 
 #include "treemodel.h"
-#include "global.h"
 
-#include <QDebug>
 #include <QCoreApplication>
+#include <QDebug>
+
+#include "quassel.h"
+
+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
@@ -45,7 +55,7 @@ bool AbstractTreeItem::newChild(AbstractTreeItem *item) {
 bool AbstractTreeItem::newChilds(const QList<AbstractTreeItem *> &items) {
   if(items.isEmpty())
     return false;
-  
+
   int nextRow = childCount();
   int lastRow = nextRow + items.count() - 1;
 
@@ -57,26 +67,26 @@ 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;
 }
 
 void AbstractTreeItem::removeAllChilds() {
   const int numChilds = childCount();
-  
+
   if(numChilds == 0)
     return;
-  
+
   AbstractTreeItem *child;
 
   QList<AbstractTreeItem *>::iterator childIter;
@@ -94,13 +104,36 @@ 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;
+
+  // since we are called asynchronously we have to recheck if the item in question still has no childs
+  if(removeEvent->child()->childCount())
+    return;
+
+  removeChild(childRow);
+}
+
 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.
@@ -112,19 +145,21 @@ bool AbstractTreeItem::reParent(AbstractTreeItem *newParent) {
   int oldRow = row();
   if(oldRow == -1)
     return false;
-  
+
   emit parent()->beginRemoveChilds(oldRow, oldRow);
   parent()->_childItems.removeAt(oldRow);
   emit parent()->endRemoveChilds();
 
-  parent()->checkForDeletion();
-
+  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;
 }
 
@@ -147,7 +182,7 @@ int AbstractTreeItem::row() const {
     qWarning() << "AbstractTreeItem::row():" << this << "has no parent AbstractTreeItem as it's parent! parent is" << QObject::parent();
     return -1;
   }
-  
+
   int row_ = parent()->_childItems.indexOf(const_cast<AbstractTreeItem *>(this));
   if(row_ == -1)
     qWarning() << "AbstractTreeItem::row():" << this << "is not in the child list of" << QObject::parent();
@@ -165,7 +200,7 @@ void AbstractTreeItem::dumpChildList() {
       childIter++;
     }
   }
-  qDebug() << "==== End Of Childlist ====";  
+  qDebug() << "==== End Of Childlist ====";
 }
 
 /*****************************************
@@ -222,7 +257,7 @@ PropertyMapItem::PropertyMapItem(AbstractTreeItem *parent)
 
 PropertyMapItem::~PropertyMapItem() {
 }
-  
+
 QVariant PropertyMapItem::data(int column, int role) const {
   if(column >= columnCount())
     return QVariant();
@@ -236,7 +271,7 @@ QVariant PropertyMapItem::data(int column, int role) const {
   default:
     return QVariant();
   }
-  
+
 }
 
 bool PropertyMapItem::setData(int column, const QVariant &value, int role) {
@@ -250,7 +285,7 @@ bool PropertyMapItem::setData(int column, const QVariant &value, int role) {
 int PropertyMapItem::columnCount() const {
   return _propertyOrder.count();
 }
-  
+
 void PropertyMapItem::appendProperty(const QString &property) {
   _propertyOrder << property;
 }
@@ -268,17 +303,17 @@ TreeModel::TreeModel(const QList<QVariant> &data, QObject *parent)
   rootItem = new SimpleTreeItem(data, 0);
   connectItem(rootItem);
 
-  if(Global::parser.isSet("debugmodel")) {
+  if(Quassel::isOptionSet("debugmodel")) {
     connect(this, SIGNAL(rowsAboutToBeInserted(const QModelIndex &, int, int)),
-           this, SLOT(debug_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)));
+            this, SLOT(debug_rowsAboutToBeRemoved(const QModelIndex &, int, int)));
     connect(this, SIGNAL(rowsInserted(const QModelIndex &, int, int)),
-           this, SLOT(debug_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)));
+            this, SLOT(debug_rowsRemoved(const QModelIndex &, int, int)));
     connect(this, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)),
-           this, SLOT(debug_dataChanged(const QModelIndex &, const QModelIndex &)));
+            this, SLOT(debug_dataChanged(const QModelIndex &, const QModelIndex &)));
   }
 }
 
@@ -287,16 +322,16 @@ TreeModel::~TreeModel() {
 }
 
 QModelIndex TreeModel::index(int row, int column, const QModelIndex &parent) const {
-  if(!hasIndex(row, column, parent))
+  if(row < 0 || row >= rowCount(parent) || column < 0 || column >= columnCount(parent))
     return QModelIndex();
-  
+
   AbstractTreeItem *parentItem;
-  
+
   if(!parent.isValid())
     parentItem = rootItem;
   else
     parentItem = static_cast<AbstractTreeItem *>(parent.internalPointer());
-  
+
   AbstractTreeItem *childItem = parentItem->child(row);
 
   if(childItem)
@@ -310,7 +345,7 @@ QModelIndex TreeModel::indexByItem(AbstractTreeItem *item) const {
     qWarning() << "TreeModel::indexByItem(AbstractTreeItem *item) received NULL-Pointer";
     return QModelIndex();
   }
-  
+
   if(item == rootItem)
     return QModelIndex();
   else
@@ -319,17 +354,18 @@ QModelIndex TreeModel::indexByItem(AbstractTreeItem *item) const {
 
 QModelIndex TreeModel::parent(const QModelIndex &index) const {
   if(!index.isValid()) {
-    qWarning() << "TreeModel::parent(): has been asked for the rootItems Parent!";
+    // ModelTest does this
+    // qWarning() << "TreeModel::parent(): has been asked for the rootItems Parent!";
     return QModelIndex();
   }
-  
+
   AbstractTreeItem *childItem = static_cast<AbstractTreeItem *>(index.internalPointer());
   AbstractTreeItem *parentItem = childItem->parent();
 
   Q_ASSERT(parentItem);
   if(parentItem == rootItem)
     return QModelIndex();
-  
+
   return createIndex(parentItem->row(), 0, parentItem);
 }
 
@@ -411,29 +447,29 @@ void TreeModel::itemDataChanged(int column) {
 
 void TreeModel::connectItem(AbstractTreeItem *item) {
   connect(item, SIGNAL(dataChanged(int)),
-         this, SLOT(itemDataChanged(int)));
-  
+          this, SLOT(itemDataChanged(int)));
+
   connect(item, SIGNAL(beginAppendChilds(int, int)),
-         this, SLOT(beginAppendChilds(int, int)));
+          this, SLOT(beginAppendChilds(int, int)));
   connect(item, SIGNAL(endAppendChilds()),
-         this, SLOT(endAppendChilds()));
-  
+          this, SLOT(endAppendChilds()));
+
   connect(item, SIGNAL(beginRemoveChilds(int, int)),
-         this, SLOT(beginRemoveChilds(int, int)));
+          this, SLOT(beginRemoveChilds(int, int)));
   connect(item, SIGNAL(endRemoveChilds()),
-         this, SLOT(endRemoveChilds()));
+          this, SLOT(endRemoveChilds()));
 }
 
 void TreeModel::beginAppendChilds(int firstRow, int lastRow) {
   AbstractTreeItem *parentItem = qobject_cast<AbstractTreeItem *>(sender());
   if(!parentItem) {
-    qWarning() << "TreeModel::beginAppendChilds(): cannot append Childs to unknown parent";
+    qWarning() << "TreeModel::beginAppendChilds(): cannot append Children to unknown parent";
     return;
   }
 
   QModelIndex parent = indexByItem(parentItem);
   Q_ASSERT(!_aboutToRemoveOrInsert);
-  
+
   _aboutToRemoveOrInsert = true;
   _childStatus = ChildStatus(parent, rowCount(parent), firstRow, lastRow);
   beginInsertRows(parent, firstRow, lastRow);
@@ -442,7 +478,7 @@ void TreeModel::beginAppendChilds(int firstRow, int lastRow) {
 void TreeModel::endAppendChilds() {
   AbstractTreeItem *parentItem = qobject_cast<AbstractTreeItem *>(sender());
   if(!parentItem) {
-    qWarning() << "TreeModel::endAppendChilds(): cannot append Childs to unknown parent";
+    qWarning() << "TreeModel::endAppendChilds(): cannot append Children to unknown parent";
     return;
   }
   Q_ASSERT(_aboutToRemoveOrInsert);
@@ -461,14 +497,14 @@ void TreeModel::endAppendChilds() {
 void TreeModel::beginRemoveChilds(int firstRow, int lastRow) {
   AbstractTreeItem *parentItem = qobject_cast<AbstractTreeItem *>(sender());
   if(!parentItem) {
-    qWarning() << "TreeModel::beginRemoveChilds(): cannot append Childs to unknown parent";
+    qWarning() << "TreeModel::beginRemoveChilds(): cannot append Children 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);
@@ -483,7 +519,7 @@ void TreeModel::beginRemoveChilds(int firstRow, int lastRow) {
 void TreeModel::endRemoveChilds() {
   AbstractTreeItem *parentItem = qobject_cast<AbstractTreeItem *>(sender());
   if(!parentItem) {
-    qWarning() << "TreeModel::endRemoveChilds(): cannot remove Childs from unknown parent";
+    qWarning() << "TreeModel::endRemoveChilds(): cannot remove Children from unknown parent";
     return;
   }
 
@@ -514,11 +550,9 @@ void TreeModel::debug_rowsAboutToBeRemoved(const QModelIndex &parent, int start,
   qDebug() << "debug_rowsAboutToBeRemoved" << parent << parentItem << parent.data().toString() << rowCount(parent) << start << end;
 
   QModelIndex child;
-  AbstractTreeItem *childItem;
   for(int i = end; i >= start; i--) {
     child = parent.child(i, 0);
-    childItem = parentItem->child(i);
-    Q_ASSERT(childItem);
+    Q_ASSERT(parentItem->child(i));
     qDebug() << ">>>" << i << child << child.data().toString();
   }
 }
@@ -531,11 +565,9 @@ void TreeModel::debug_rowsInserted(const QModelIndex &parent, int start, int end
   qDebug() << "debug_rowsInserted:" << parent << parentItem << parent.data().toString() << rowCount(parent) << start << end;
 
   QModelIndex child;
-  AbstractTreeItem *childItem;
   for(int i = start; i <= end; i++) {
     child = parent.child(i, 0);
-    childItem = parentItem->child(i);
-    Q_ASSERT(childItem);
+    Q_ASSERT(parentItem->child(i));
     qDebug() << "<<<" << i << child << child.data().toString();
   }
 }