Index: src/UIElements/Views/Qt4/MoleculeList/QtMoleculeList.cpp
===================================================================
--- src/UIElements/Views/Qt4/MoleculeList/QtMoleculeList.cpp	(revision f62e60b49352956721b98a4106d50c6f681b3f7d)
+++ src/UIElements/Views/Qt4/MoleculeList/QtMoleculeList.cpp	(revision f62e60b49352956721b98a4106d50c6f681b3f7d)
@@ -0,0 +1,405 @@
+/*
+ * Project: MoleCuilder
+ * Description: creates and alters molecular systems
+ * Copyright (C)  2010-2012 University of Bonn. All rights reserved.
+ * 
+ *
+ *   This file is part of MoleCuilder.
+ *
+ *    MoleCuilder is free software: you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    MoleCuilder is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with MoleCuilder.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * QtMoleculeList.cpp
+ *
+ *  Created on: Jan 21, 2010
+ *      Author: crueger
+ */
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "QtMoleculeList.hpp"
+
+#include <QMetaMethod>
+
+#include <iostream>
+
+#include "CodePatterns/MemDebug.hpp"
+
+#include "CodePatterns/Observer/Notification.hpp"
+
+#include "Atom/atom.hpp"
+#include "Formula.hpp"
+#include "molecule.hpp"
+#include "MoleculeListClass.hpp"
+#include "Actions/SelectionAction/Molecules/MoleculeByIdAction.hpp"
+#include "Actions/SelectionAction/Molecules/NotMoleculeByIdAction.hpp"
+
+using namespace std;
+
+// maybe this should go with the definition of molecules
+
+// some attributes need to be easier to find for molecules
+// these attributes are skipped so far
+const int QtMoleculeList::COLUMNCOUNT = COLUMNTYPES_MAX;
+const char *QtMoleculeList::COLUMNNAMES[QtMoleculeList::COLUMNCOUNT]={"Name","Visibility", "Atoms","Formula","Occurrence"/*,"Size"*/};
+
+QtMoleculeList::QtMoleculeList() :
+  Observer("QtMoleculeList")
+{
+  setColumnCount(COLUMNCOUNT);
+//  setSelectionMode(QAbstractItemView::MultiSelection);
+
+  World::getInstance().signOn(this, World::MoleculeInserted);
+  World::getInstance().signOn(this, World::MoleculeRemoved);
+
+  dirty = true;
+  clearing = false;
+  selecting = false;
+  changing = false;
+  ChangingChildrensVisibility = false;
+  refill();
+
+//  qRegisterMetaType<QItemSelection>("QItemSelection");
+  //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)));
+}
+
+QtMoleculeList::~QtMoleculeList()
+{
+  World::getInstance().signOff(this, World::MoleculeInserted);
+  World::getInstance().signOff(this, World::MoleculeRemoved);
+}
+
+QVariant QtMoleculeList::headerData(int section, Qt::Orientation orientation, int role) const
+{
+  if (role == Qt::DisplayRole) {
+    if (orientation == Qt::Horizontal) {
+      if (section < COLUMNTYPES_MAX)
+        return QString(COLUMNNAMES[section]);
+    }
+  }
+  return QVariant();
+}
+
+void QtMoleculeList::update(Observable *publisher) {
+  ASSERT(0,
+      "QtMoleculeList::update() - we did not sign up for any global updates.");
+}
+
+QStandardItem * QtMoleculeList::MoleculeToItem(const molecule * const _mol)
+{
+  MoleculeItemBiMap_t::left_const_iterator iter =
+      MoleculeItemBiMap.left.find(_mol);
+  ASSERT( iter != MoleculeItemBiMap.left.end(),
+      "QtMoleculeList - could not find molecule "+_mol->getName()+" in my list.");
+  return iter->second;
+}
+
+void QtMoleculeList::recieveNotification(Observable *publisher, Notification_ptr notification)
+{
+  if (dynamic_cast<World *>(publisher) != NULL) {
+    switch (notification->getChannelNo()) {
+      case World::MoleculeInserted:
+      {
+        const molecule * const mol = World::getInstance().lastChanged<molecule>();
+        addItem( mol );
+        break;
+      }
+      case World::MoleculeRemoved:
+      {
+        const molecule * const mol = World::getInstance().lastChanged<molecule>();
+        removeItem(  mol );
+        break;
+      }
+      default:
+        ASSERT(0, "QtMoleculeList::recieveNotification() - cannot get here, not subscribed to channel "
+            +toString(notification->getChannelNo()));
+        break;
+    }
+  }
+
+  if (selecting)
+    return;
+
+  dirty = true;
+}
+
+void QtMoleculeList::addGroupItem(
+    QStandardItem *&mainitem,
+    const std::string &_molecule_formula)
+{
+  QList<QStandardItem *> groupItems;
+  // fill item list
+  mainitem = new QStandardItem(QString("default"));
+  mainitem->setFlags(mainitem->flags() ^ Qt::ItemIsSelectable);
+  formula.insert( std::make_pair(_molecule_formula, mainitem) );
+  groupItems << mainitem;
+  QStandardItem *visitem = new QStandardItem;
+  visitem->setCheckState(Qt::Unchecked);
+  visitem->setFlags(mainitem->flags() | Qt::ItemIsUserCheckable);
+  groupItems << visitem;
+  groupItems << new QStandardItem(QString::number(0));
+  groupItems << new QStandardItem(QString(""));
+  groupItems << new QStandardItem(QString::number(0));
+  invisibleRootItem()->appendRow(groupItems);
+//  _groupItem->setData(0, Qt::UserRole, QVariant(-1));
+}
+
+void QtMoleculeList::addMoleculeItem(
+    QStandardItem *_groupitem,
+    const molecule *_mol,
+    const std::string &_molecule_formula)
+{
+  QList<QStandardItem *> molItems;
+  QStandardItem *mainitem = new QStandardItem(QString(_mol->getName().c_str()));
+  mainitem->setFlags(mainitem->flags() | Qt::ItemIsSelectable);
+//  mainitem->setSelected(World::getInstance().isSelected(_mol));
+  MoleculeItemBiMap.left.insert( std::make_pair(_mol, mainitem) );
+  molItems << mainitem;
+  QStandardItem *visitem = new QStandardItem();
+  visitem->setCheckState(Qt::Unchecked);
+  visitem->setFlags(mainitem->flags() | Qt::ItemIsUserCheckable);
+  molItems << visitem;
+  molItems << new QStandardItem(QString::number(_mol->getAtomCount()));
+  molItems << new QStandardItem(QString(_molecule_formula.c_str()));
+  molItems << new QStandardItem(QString::number(0));
+//  const int index = _mol->getId();
+//  molItem->setData(0, Qt::UserRole, QVariant(index));
+  _groupitem->appendRow(molItems);
+}
+
+void QtMoleculeList::addItem(const molecule *_mol)
+{
+  if (changing)
+    return;
+  changing = true;
+  // find group if already in list
+  QStandardItem *groupItem = NULL;
+
+  const std::string &molecule_formula = _mol->getFormula().toString();
+  FormulaTreeItemMap_t::const_iterator formulaiter =
+      formula.find(molecule_formula);
+
+  // new molecule type -> create new group
+  if (formulaiter == formula.end()){
+    // insert new formula entry into visibility
+#ifndef NDEBUG
+    std::pair< FormulaVisibilityCountMap_t::iterator, bool> visibilityinserter =
+#endif
+        FormulaVisibilityCountMap.insert(
+            std::make_pair( molecule_formula, (unsigned int)0) );
+    ASSERT( visibilityinserter.second,
+        "QtMoleculeList::refill() - molecule with formula "
+        +molecule_formula+" already in FormulaVisibilityCountMap.");
+
+    // create item and place into Map with formula as key
+    addGroupItem(groupItem, molecule_formula);
+  } else {
+    groupItem = formulaiter->second;
+  }
+  ASSERT( groupItem != NULL,
+      "QtMoleculeList::addItem() - item with id "+toString(_mol->getId())
+      +" has not parent?");
+
+  // add molecule
+  addMoleculeItem(groupItem, _mol, molecule_formula);
+
+  // increase group occurrence
+  const int index = groupItem->index().row();
+  QStandardItem *occ_item = invisibleRootItem()->child(index, OCCURRENCE);
+  int count = occ_item->text().toInt() + 1;
+  occ_item->setText(QString::number(count));
+
+  changing = false;
+}
+
+void QtMoleculeList::removeItem(const molecule *_mol)
+{
+  if (changing)
+    return;
+  changing = true;
+
+  dirty = true;
+  // TODO: We have to get some Model into the Table in order to "find" items right
+  // away
+//  QTreeWidgetItem *molItem = itemFromIndex(mol->getId());
+//  delete molItem1;
+
+  changing = false;
+}
+
+void QtMoleculeList::refill() {
+  clearing = true;
+  const std::vector<molecule*> &molecules = World::getInstance().getAllMolecules();
+
+  clear();
+  formula.clear();
+  FormulaVisibilityCountMap.clear();
+  MoleculeItemBiMap.clear();
+
+  for (std::vector<molecule*>::const_iterator iter = molecules.begin();
+      iter != molecules.end();
+      iter++) {
+
+    addItem(*iter);
+  }
+  dirty = false;
+  clearing = false;
+}
+
+/*
+void QtMoleculeList::paintEvent(QPaintEvent * event)
+{
+  if (dirty)
+    refill();
+  QTreeWidget::paintEvent(event);
+}
+*/
+
+void QtMoleculeList::subjectKilled(Observable *publisher) {
+}
+
+/*
+void QtMoleculeList::visibilityChanged(QStandardItem* item, int column)
+{
+  if ((!changing) && (!clearing) && (!ChangingChildrensVisibility))
+    if (column == VISIBILITY) {
+      const moleculeId_t molid = item->data(0, Qt::UserRole).toInt();
+      const bool visible = item->checkState(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(VISIBILITY, Qt::Checked);
+        } else {
+          --(FormulaVisibilityCountMap[molecule_formula]);
+          // none selected anymore?
+          if (FormulaVisibilityCountMap[molecule_formula] == 0)
+            groupItem->setCheckState(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(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(OCCURRENCE).toInt() : 0;
+
+        ChangingChildrensVisibility = false;
+      }
+    }
+}
+*/
+
+void QtMoleculeList::moleculeChanged() {
+  /*int idx = verticalHeaderItem(row)->data(Qt::UserRole).toInt();
+  molecule *mol = molecules->ReturnIndex(idx);
+  string cellValue = item(row,NAME)->text().toStdString();
+  if(mol->getName() != cellValue && cellValue !="") {
+    mol->setName(cellValue);
+  }
+  else if(cellValue==""){
+    item(row,NAME)->setText(QString(mol->getName().c_str()));
+  }*/
+}
+
+/*
+void QtMoleculeList::rowsSelected(const QItemSelection & selected, const QItemSelection & deselected){
+
+  if (clearing)
+    return;
+  if (selecting)
+    return;
+  selecting = true;
+
+  // Select all molecules which belong to newly selected rows.
+  QModelIndex index;
+  {
+    QModelIndexList items = selected.indexes();
+    molids_t ids;
+    ids.reserve(items.size());
+    foreach (index, items)
+      if (index.column() == 0){
+        int mol_id = model()->data(index, Qt::UserRole).toInt();
+        if (mol_id < 0)
+          continue;
+        ids.push_back(mol_id);
+        //std::cout << "select molecule" << std::endl;
+      }
+    MoleCuilder::SelectionMoleculeById(ids);
+  }
+
+  // Unselect all molecules which belong to newly unselected rows.
+  {
+    QModelIndexList items = deselected.indexes();
+    molids_t ids;
+    ids.reserve(items.size());
+    foreach (index, items)
+      if (index.column() == 0){
+        int mol_id = model()->data(index, Qt::UserRole).toInt();
+        if (mol_id < 0)
+          continue;
+        //std::cout << "unselect molecule" << std::endl;
+        ids.push_back(mol_id);
+      }
+    MoleCuilder::SelectionNotMoleculeById(ids);
+  }
+
+  selecting = false;
+}
+
+*/
Index: src/UIElements/Views/Qt4/MoleculeList/QtMoleculeList.hpp
===================================================================
--- src/UIElements/Views/Qt4/MoleculeList/QtMoleculeList.hpp	(revision f62e60b49352956721b98a4106d50c6f681b3f7d)
+++ src/UIElements/Views/Qt4/MoleculeList/QtMoleculeList.hpp	(revision f62e60b49352956721b98a4106d50c6f681b3f7d)
@@ -0,0 +1,90 @@
+/*
+ * QtMoleculeList.hpp
+ *
+ *  Created on: Jan 21, 2010
+ *      Author: crueger
+ */
+
+#ifndef QTMOLECULELIST_HPP_
+#define QTMOLECULELIST_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <QtGui/QStandardItem>
+#include <QtGui/QStandardItemModel>
+
+#include <boost/bimap.hpp>
+#include <map>
+#include <string>
+
+#include "CodePatterns/Observer/Observer.hpp"
+
+#include "types.hpp"
+
+class molecule;
+class MoleculeListClass;
+class QtMoleculeListView;
+
+class QtMoleculeList : public QStandardItemModel, public Observer
+{
+  Q_OBJECT
+
+public:
+  QtMoleculeList();
+  virtual ~QtMoleculeList();
+
+protected:
+  virtual void update(Observable *publisher);
+  virtual void recieveNotification(Observable *publisher, Notification_ptr notification);
+  virtual void subjectKilled(Observable *publisher);
+//  virtual void paintEvent(QPaintEvent * event);
+  void refill();
+
+  static const int COLUMNCOUNT;
+  enum {NAME,VISIBILITY,ATOMCOUNT,FORMULA,OCCURRENCE,COLUMNTYPES_MAX} COLUMNTYPES;
+  static const char *COLUMNNAMES[];
+
+  QVariant headerData(int section, Qt::Orientation orientation, int role) const;
+
+private slots:
+  void moleculeChanged();
+//  void visibilityChanged(QStandardItem*, int);
+
+//  void rowsSelected(const QItemSelection & selected, const QItemSelection & deselected);
+
+
+signals:
+  void moleculeSelected(molecule*);
+  void moleculeUnSelected(molecule*);
+  void moleculesVisibilityChanged(const moleculeId_t, bool);
+
+private:
+  bool dirty;
+  bool clearing;
+  bool selecting;
+  bool changing;
+  bool ChangingChildrensVisibility;
+
+  friend class QtMoleculeListView;
+  QStandardItem * MoleculeToItem(const molecule * const _mol);
+
+  void addItem(const molecule * const _mol);
+  void addGroupItem(QStandardItem *&mainitem, const std::string &_molecule_formula);
+  void addMoleculeItem(QStandardItem *_groupitem, const molecule *_mol, const std::string &molecule_formula);
+  void removeItem(const molecule * const _mol);
+
+  typedef std::map<std::string, unsigned int> FormulaVisibilityCountMap_t;
+  FormulaVisibilityCountMap_t FormulaVisibilityCountMap;
+
+  typedef std::map<std::string, QStandardItem*> FormulaTreeItemMap_t;
+  //!> map of (unique) formulas in the world
+  FormulaTreeItemMap_t formula;
+
+  typedef boost::bimap<const molecule *, QStandardItem*> MoleculeItemBiMap_t;
+  MoleculeItemBiMap_t MoleculeItemBiMap;
+};
+
+#endif /* QTMOLECULELIST_HPP_ */
Index: src/UIElements/Views/Qt4/MoleculeList/QtMoleculeListView.cpp
===================================================================
--- src/UIElements/Views/Qt4/MoleculeList/QtMoleculeListView.cpp	(revision f62e60b49352956721b98a4106d50c6f681b3f7d)
+++ src/UIElements/Views/Qt4/MoleculeList/QtMoleculeListView.cpp	(revision f62e60b49352956721b98a4106d50c6f681b3f7d)
@@ -0,0 +1,113 @@
+/*
+ * Project: MoleCuilder
+ * Description: creates and alters molecular systems
+ * Copyright (C)  2015 Frederik Heber. All rights reserved.
+ *
+ *
+ *   This file is part of MoleCuilder.
+ *
+ *    MoleCuilder is free software: you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    MoleCuilder is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with MoleCuilder.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * QtMoleculeListView.cpp
+ *
+ *  Created on: Jan 17, 2015
+ *      Author: heber
+ */
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "QtMoleculeListView.hpp"
+
+#include "UIElements/Views/Qt4/MoleculeList/QtMoleculeList.hpp"
+
+#include "CodePatterns/MemDebug.hpp"
+
+#include "CodePatterns/Observer/Notification.hpp"
+
+#include "World.hpp"
+
+QtMoleculeListView::QtMoleculeListView(QWidget * _parent) :
+QTreeView(_parent),
+  Observer("QtMoleculeListView")
+{
+  setSelectionMode(QAbstractItemView::MultiSelection);
+
+  World::getInstance().signOn(this, World::SelectionChanged);
+}
+
+QtMoleculeListView::~QtMoleculeListView()
+{
+  World::getInstance().signOff(this, World::SelectionChanged);
+}
+
+void QtMoleculeListView::setModel(QtMoleculeList *_moleculelist)
+{
+  QTreeView::setModel(_moleculelist);
+  connect(
+      selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)),
+      _moleculelist, SLOT(rowsSelected(const QItemSelection &, const QItemSelection &)));
+}
+
+void QtMoleculeListView::update(Observable *publisher)
+{}
+
+void QtMoleculeListView::recieveNotification(Observable *publisher, Notification_ptr notification)
+{
+  if (dynamic_cast<World *>(publisher) != NULL) {
+    switch (notification->getChannelNo()) {
+      case World::SelectionChanged:
+      {
+        // obtain molecule selection from World and go through our selection step by step
+        const std::vector<molecule *> selectedMolecules =
+            const_cast<const World &>(World::getInstance()).getSelectedMolecules();
+        QItemSelection currently_selected = selectionModel()->selection();
+        QtMoleculeList *moleculelist = static_cast<QtMoleculeList *>(model());
+        QItemSelection selected;
+        QItemSelection deselected;
+        std::set<QModelIndex> already_selected_indices;
+        for (std::vector<molecule *>::const_iterator iter = selectedMolecules.begin();
+            iter != selectedMolecules.begin(); ++iter) {
+          QModelIndex mol_index = moleculelist->MoleculeToItem(*iter)->index();
+          if (!currently_selected.contains(mol_index))
+              selected.select(mol_index, mol_index);
+          else
+            already_selected_indices.insert(mol_index);
+        }
+        {
+          QModelIndex mol_index;
+          foreach(mol_index, currently_selected.indexes()) {
+            std::set<QModelIndex>::const_iterator iter =
+                already_selected_indices.find(mol_index);
+            if (iter == already_selected_indices.end())
+              deselected.select(mol_index, mol_index);
+          }
+        }
+        selectionChanged(selected, deselected);
+        break;
+      }
+      default:
+        ASSERT(0, "QtMoleculeListView::recieveNotification() - cannot get here, not subscribed to channel "
+            +toString(notification->getChannelNo()));
+        break;
+    }
+  }
+}
+
+void QtMoleculeListView::subjectKilled(Observable *publisher)
+{}
Index: src/UIElements/Views/Qt4/MoleculeList/QtMoleculeListView.hpp
===================================================================
--- src/UIElements/Views/Qt4/MoleculeList/QtMoleculeListView.hpp	(revision f62e60b49352956721b98a4106d50c6f681b3f7d)
+++ src/UIElements/Views/Qt4/MoleculeList/QtMoleculeListView.hpp	(revision f62e60b49352956721b98a4106d50c6f681b3f7d)
@@ -0,0 +1,39 @@
+/*
+ * QtMoleculeListView.hpp
+ *
+ *  Created on: Jan 17, 2015
+ *      Author: heber
+ */
+
+#ifndef QTMOLECULELISTVIEW_HPP_
+#define QTMOLECULELISTVIEW_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <QTreeView>
+
+#include "CodePatterns/Observer/Observer.hpp"
+
+class QtMoleculeList;
+
+class QtMoleculeListView : public QTreeView, public Observer
+{
+  Q_OBJECT
+
+public:
+  QtMoleculeListView(QWidget * _parent);
+  virtual ~QtMoleculeListView();
+
+  void setModel(QtMoleculeList *_moleculelist);
+
+protected:
+  virtual void update(Observable *publisher);
+  virtual void recieveNotification(Observable *publisher, Notification_ptr notification);
+  virtual void subjectKilled(Observable *publisher);
+};
+
+
+#endif /* QTMOLECULELISTVIEW_HPP_ */
