Index: src/UIElements/Views/Qt4/MoleculeList/QtMoleculeList.cpp
===================================================================
--- src/UIElements/Views/Qt4/MoleculeList/QtMoleculeList.cpp	(revision d2dbb5d0e44b22b8ce90269637cb0083893cd951)
+++ src/UIElements/Views/Qt4/MoleculeList/QtMoleculeList.cpp	(revision 2696b18ee037df67c33588e50eedff4bd5d454dd)
@@ -36,4 +36,5 @@
 
 #include <QModelIndex>
+#include <QDebug>
 
 #include "UIElements/Views/Qt4/MoleculeList/QtMoleculeItem.hpp"
@@ -76,5 +77,5 @@
   //connect(this,SIGNAL(cellChanged(int,int)),this,SLOT(moleculeChanged(int,int)));
 //  connect(selectionModel(),SIGNAL(selectionChanged(QItemSelection, QItemSelection)),this,SLOT(rowsSelected(QItemSelection, QItemSelection)));
-//  connect(this, SIGNAL(itemChanged(QStandardItem*, int)), this, SLOT(visibilityChanged(QStandardItem*, int)));
+  connect(this, SIGNAL(itemChanged(QStandardItem*)), this, SLOT(checkForVisibilityChange(QStandardItem*)));
 }
 
@@ -280,8 +281,10 @@
   MoleculeItemBiMap.clear();
   dirtyItems.clear();
+  visibilityItems.clear();
   toBeMovedItems.clear();
   newItems.clear();
   toBeRemovedItems.clear();
   toBeSetOccurrenceItems.clear();
+  toBeSetVisibilityItems.clear();
 
   for (std::vector<molecule*>::const_iterator iter = molecules.begin();
@@ -303,7 +306,9 @@
   bool dirty = false;
   dirty |= !dirtyItems.empty();
+  dirty |= !visibilityItems.empty();
   dirty |= !newItems.empty();
   dirty |= !toBeRemovedItems.empty();
   dirty |= !toBeSetOccurrenceItems.empty();
+  dirty |= !toBeSetVisibilityItems.empty();
   list_accessing = false;
   return dirty;
@@ -321,73 +326,92 @@
 {}
 
-/*
-void QtMoleculeList::visibilityChanged(QStandardItem* item, int column)
-{
-  if ((!changing) && (!clearing) && (!ChangingChildrensVisibility))
-    if (column == QtMoleculeItemFactory::VISIBILITY) {
-      const moleculeId_t molid = item->data(0, Qt::UserRole).toInt();
-      const bool visible = item->checkState(QtMoleculeItemFactory::VISIBILITY);
-      if (molid != (unsigned int)-1) { // molecule item
-        World::MoleculeConstIterator moliter =
-            const_cast<const World &>(World::getInstance()).getMoleculeIter(MoleculeById(molid));
-        const molecule * const _molecule = *moliter;
-        ASSERT( _molecule != NULL,
-            "QtMoleculeList::visibilityChanged() - molecule with id "
-            +toString(molid)+" is not known to World.");
-        const std::string &molecule_formula = _molecule->getFormula().toString();
-        ASSERT( FormulaVisibilityCountMap.count(molecule_formula) != 0,
-            "QtMoleculeList::visibilityChanged() - molecule with formula " +molecule_formula
-            +" is not present in FormulaVisibilityCountMap.");
-
-        // get parent
-        QTreeWidgetItem *groupItem = item->parent();
-        ASSERT( groupItem != NULL,
-            "QtMoleculeList::visibilityChanged() - item with id "+toString(molid)
-            +" has not parent?");
-        // check whether we have to set the group item
-
-        ChangingChildrensVisibility = true;
-        if (visible) {
-          ++(FormulaVisibilityCountMap[molecule_formula]);
-          // compare with occurence/total number of molecules
-          if (FormulaVisibilityCountMap[molecule_formula] ==
-              (unsigned int)(groupItem->text(OCCURRENCE).toInt()))
-            groupItem->setCheckState(QtMoleculeItemFactory::VISIBILITY, Qt::Checked);
-        } else {
-          --(FormulaVisibilityCountMap[molecule_formula]);
-          // none selected anymore?
-          if (FormulaVisibilityCountMap[molecule_formula] == 0)
-            groupItem->setCheckState(QtMoleculeItemFactory::VISIBILITY, Qt::Unchecked);
-        }
-        ChangingChildrensVisibility = false;
-
-        emit moleculesVisibilityChanged(molid, visible);
-
-      } else { // group item
-
-        // go through all children, but don't enter for groupItem once more
-        ChangingChildrensVisibility = true;
-        for (int i=0;i<item->childCount();++i) {
-          QTreeWidgetItem *molItem = item->child(i);
-          const moleculeId_t molid = molItem->data(0, Qt::UserRole).toInt();
-          ASSERT( molid != (unsigned int)-1,
-              "QtMoleculeList::visibilityChanged() - to child with index"
-              +toString(i)+" there is no molecule?");
-          molItem->setCheckState(QtMoleculeItemFactory::VISIBILITY, visible ? Qt::Checked : Qt::Unchecked);
-
-          // emit signal
-          emit moleculesVisibilityChanged(molid, visible);
-        }
-        // set current number of visible children
-        const std::string molecule_formula =
-            item->text(FORMULA).toStdString();
-        FormulaVisibilityCountMap[molecule_formula] =
-            visible ? item->text(QtMoleculeItemFactory::OCCURRENCE).toInt() : 0;
-
-        ChangingChildrensVisibility = false;
-      }
+void QtMoleculeList::checkForVisibilityChange(QStandardItem* _item)
+{
+  qDebug() << "Item changed called.";
+
+  if (_item->index().column() == QtMoleculeItemFactory::VISIBILITY) {
+    qDebug() << "visibilityItem changed: " << (_item->checkState() ? "checked" : "unchecked");
+    while(list_accessing);
+    list_accessing = true;
+    if ((_item->parent() == NULL) || (_item->parent() == invisibleRootItem()))
+      toBeSetVisibilityItems.insert( _item );
+    else
+      visibilityItems.insert( dynamic_cast<QtMoleculeItem *>(_item) );
+    list_accessing = false;
+  }
+}
+
+void QtMoleculeList::setVisibilityForMoleculeItem(QtMoleculeItem* _item)
+{
+  if (ChangingChildrensVisibility)
+    return;
+
+  const bool visible = _item->checkState();
+  const std::string &molecule_formula = _item->getMolecule()->getFormula().toString();
+  ASSERT( FormulaVisibilityCountMap.count(molecule_formula) != 0,
+      "QtMoleculeList::setVisibilityForMoleculeItem() - molecule with formula " +molecule_formula
+      +" is not present in FormulaVisibilityCountMap.");
+
+  // get parent
+  QStandardItem *groupItem = _item->parent();
+  QStandardItem *visgroupItem =
+      invisibleRootItem()->child(groupItem->index().row(), QtMoleculeItemFactory::VISIBILITY);
+  ASSERT( groupItem != NULL,
+      "QtMoleculeList::setVisibilityForMoleculeItem() - item with id "
+      +toString(_item->getMolecule()->getId())+" has not parent?");
+  // check whether we have to set the group item
+
+  ChangingChildrensVisibility = true;
+  if (visible) {
+    ++(FormulaVisibilityCountMap[molecule_formula]);
+    // compare with occurence/total number of molecules
+    if (FormulaVisibilityCountMap[molecule_formula] ==
+        (unsigned int)(groupItem->rowCount()))
+      visgroupItem->setCheckState(Qt::Checked);
+  } else {
+    --(FormulaVisibilityCountMap[molecule_formula]);
+    // none selected anymore?
+    if (FormulaVisibilityCountMap[molecule_formula] == 0)
+      visgroupItem->setCheckState(Qt::Unchecked);
+  }
+  ChangingChildrensVisibility = false;
+
+  emit moleculesVisibilityChanged(_item->getMolecule()->getId(), visible);
+}
+
+void QtMoleculeList::setVisibilityForGroupItem(QStandardItem* _item)
+{
+  if (ChangingChildrensVisibility)
+    return;
+
+  ChangingChildrensVisibility = true;
+
+  // go through all children, but don't enter for groupItem once more
+  const bool visible = _item->checkState();
+  QStandardItem *groupitem = invisibleRootItem()->child(
+      _item->index().row(), QtMoleculeItemFactory::NAME);
+  for (int i=0;i<groupitem->rowCount();++i) {
+    QtMoleculeItem *molItem = dynamic_cast<QtMoleculeItem *>(
+        groupitem->child(i, QtMoleculeItemFactory::VISIBILITY));
+    if (molItem->checkState() != visible) {
+      molItem->setCheckState(visible ? Qt::Checked : Qt::Unchecked);
+
+      // emit signal
+      emit moleculesVisibilityChanged(molItem->getMolecule()->getId(), visible);
     }
-}
-*/
+  }
+  // set current number of visible children
+  const std::string molecule_formula =
+      invisibleRootItem()->child(_item->row(), QtMoleculeItemFactory::NAME)->text().toStdString();
+  FormulaVisibilityCountMap_t::iterator countiter =
+      FormulaVisibilityCountMap.find(molecule_formula);
+  ASSERT( countiter != FormulaVisibilityCountMap.end(),
+      "QtMoleculeList::setVisibilityForGroupItem() - molecules "+molecule_formula
+      +" have no entry in visibility count map?");
+  countiter->second = visible ? groupitem->rowCount() : 0;
+
+  ChangingChildrensVisibility = false;
+}
+
 
 void QtMoleculeList::moleculeChanged() {
@@ -496,4 +520,6 @@
   list_of_items_t dirtyItems_copy = dirtyItems;
   dirtyItems.clear();
+  list_of_items_t visibilityItems_copy = visibilityItems;
+  visibilityItems.clear();
   list_of_items_t toBeMovedItems_copy = toBeMovedItems;
   toBeMovedItems.clear();
@@ -504,4 +530,6 @@
   std::set<QStandardItem*> toBeSetOccurrenceItems_copy = toBeSetOccurrenceItems;
   toBeSetOccurrenceItems.clear();
+  std::set<QStandardItem*> toBeSetVisibilityItems_copy = toBeSetVisibilityItems;
+  toBeSetVisibilityItems.clear();
   list_accessing = false;
 
@@ -542,10 +570,33 @@
     toBeMovedItems_copy.erase(item);
   }
-
-  /// 1. do the update for each dirty item
+  for (list_of_items_t::iterator visiter = visibilityItems_copy.begin();
+      visiter != visibilityItems_copy.end(); ) {
+    QtMoleculeItem * const _item = dynamic_cast<QtMoleculeItem *>(
+        (*visiter)->parent()->child(
+            (*visiter)->index().row(),
+            QtMoleculeItemFactory::NAME));
+    const molecule *mol = ItemToMolecule(_item);
+    if (std::binary_search(
+            toBeRemovedItems_copy.begin(), toBeRemovedItems_copy.end(),
+            mol))
+      visibilityItems_copy.erase(visiter++);
+    else
+      ++visiter;
+  }
+
+  /// 1a. do the update for each dirty item
   for (list_of_items_t::const_iterator dirtyiter = dirtyItems_copy.begin();
       dirtyiter != dirtyItems_copy.end(); ++dirtyiter) {
     LOG(1, "Updating item " << *dirtyiter);
     (*dirtyiter)->updateState();
+  }
+
+  /// 1b. do the visibility update for each dirty item
+  for (list_of_items_t::const_iterator visiter = visibilityItems_copy.begin();
+      visiter != visibilityItems_copy.end(); ++visiter) {
+    LOG(1, "Updating visibility of item " << *visiter);
+    ASSERT(((*visiter)->parent() != NULL) && ((*visiter)->parent() != invisibleRootItem()),
+        "QtMoleculeList::updateItemStates() - a group item ended up in visibilityItems.");
+    setVisibilityForMoleculeItem(*visiter);
   }
 
@@ -578,5 +629,5 @@
   }
 
-  /// 5a. update the group item's occurrence
+  /// 5a. update the group item's occurrence and visibility
   std::set<int> RowsToRemove;
   for (std::set<QStandardItem*>::const_iterator groupiter = toBeSetOccurrenceItems_copy.begin();
@@ -588,4 +639,20 @@
   }
 
+  // remove all visibility updates whose row is removed
+  for (std::set<QStandardItem*>::iterator visiter = toBeSetVisibilityItems_copy.begin();
+      visiter != toBeSetVisibilityItems_copy.end(); ) {
+    if (RowsToRemove.count((*visiter)->index().row()) != 0)
+      toBeSetVisibilityItems_copy.erase(visiter++);
+    else
+      ++visiter;
+  }
+
+  // update visibility of all group items
+  for (std::set<QStandardItem*>::iterator visiter = toBeSetVisibilityItems_copy.begin();
+      visiter != toBeSetVisibilityItems_copy.end(); ++visiter) {
+    LOG(1, "Updating visibility of item " << *visiter);
+    setVisibilityForGroupItem(*visiter);
+  }
+
   /// 5b. remove all rows with 0 occurrence starting from last
   for (std::set<int>::reverse_iterator riter = RowsToRemove.rbegin();
