Index: src/UIElements/Views/Qt4/Qt3D/GLMoleculeObject_molecule.cpp
===================================================================
--- src/UIElements/Views/Qt4/Qt3D/GLMoleculeObject_molecule.cpp	(revision a2a2f74e1b5173a3e4d4090d8ec2a57e0f765552)
+++ src/UIElements/Views/Qt4/Qt3D/GLMoleculeObject_molecule.cpp	(revision 8c001aeb40538cff3bf30540d0cc0b8359472d75)
@@ -56,10 +56,15 @@
 #include "World.hpp"
 
+#include "GLMoleculeObject_atom.hpp"
+
 GLMoleculeObject_molecule::GLMoleculeObject_molecule(QGLSceneNode *mesh[], QObject *parent, const molecule *molref) :
   GLMoleculeObject(mesh, parent),
   Observer(std::string("GLMoleculeObject_molecule")+toString(molref->getId())),
-  _molecule(molref)
+  _molecule(molref),
+  hoverAtom(NULL)
 {
   // sign on as observer (obtain non-const instance before)
+  _molecule->signOn(this, molecule::AtomInserted);
+  _molecule->signOn(this, molecule::AtomRemoved);
   /*molref->signOn(this, AtomObservable::IndexChanged);
   molref->signOn(this, AtomObservable::PositionChanged);
@@ -69,8 +74,12 @@
   World::getInstance().signOn(this, World::SelectionChanged);
   updateBoundingBox();
+
+  init();
 }
 
 GLMoleculeObject_molecule::~GLMoleculeObject_molecule()
 {
+  _molecule->signOff(this, molecule::AtomInserted);
+  _molecule->signOff(this, molecule::AtomRemoved);
   /*_atom->signOff(this, AtomObservable::IndexChanged);
   _atom->signOff(this, AtomObservable::PositionChanged);
@@ -78,4 +87,91 @@
   _atom->signOff(this, AtomObservable::BondsAdded);*/
   World::getInstance().signOff(this, World::SelectionChanged);
+}
+
+/** Initialise the WorldScene with molecules and atoms from World.
+ *
+ */
+void GLMoleculeObject_molecule::init()
+{
+  if (_molecule->begin() != _molecule->end()) {
+    for (molecule::const_iterator atomiter = _molecule->begin();
+        atomiter != _molecule->end();
+        atomiter++) {
+      // create atom objects in scene
+      atomInserted((*atomiter)->getId());
+
+      // create bond objects in scene
+      const BondList &bondlist = (*atomiter)->getListOfBonds();
+      for (BondList::const_iterator bonditer = bondlist.begin();
+          bonditer != bondlist.end();
+          ++bonditer) {
+        const bond::ptr _bond = *bonditer;
+        const GLMoleculeObject_bond::SideOfBond side = (_bond->leftatom == *atomiter) ?
+            GLMoleculeObject_bond::left : GLMoleculeObject_bond::right;
+        bondInserted(_bond, side);
+      }
+    }
+  }
+}
+
+void GLMoleculeObject_molecule::addAtomBonds(
+    const bond::ptr &_bond,
+    const GLMoleculeObject_bond::SideOfBond _side
+    )
+{
+  bool bond_present = false;
+  const BondIds ids = getBondIds(_bond, _side);
+  // check whether bond is not present already
+  bond_present = BondsinSceneMap.count(ids);
+  if (!bond_present)
+    bondInserted(_bond, _side);
+  else {
+    BondsinSceneMap[ids]->resetPosition();
+    BondsinSceneMap[ids]->resetWidth();
+  }
+}
+
+void GLMoleculeObject_molecule::addAtomBonds(
+    const atom *_atom)
+{
+  const bool atom_present = AtomsinSceneMap.count(_atom->getId());
+  const BondList &bondlist = _atom->getListOfBonds();
+  for (BondList::const_iterator bonditer = bondlist.begin();
+      (bonditer != bondlist.end()) && atom_present;
+      ++bonditer) {
+    const bond::ptr _bond = *bonditer;
+    // check if OtherAtom's sphere is already present
+    const atom *OtherAtom = _bond->GetOtherAtom(_atom);
+    const bool otheratom_present = AtomsinSceneMap.count(OtherAtom->getId());
+    if (otheratom_present && atom_present) {
+      const GLMoleculeObject_bond::SideOfBond side = (_bond->leftatom == _atom) ?
+          GLMoleculeObject_bond::left : GLMoleculeObject_bond::right;
+      const GLMoleculeObject_bond::SideOfBond otherside = (_bond->leftatom == _atom) ?
+          GLMoleculeObject_bond::right : GLMoleculeObject_bond::left;
+      addAtomBonds(_bond, side);
+      addAtomBonds(_bond, otherside);
+    }
+  }
+}
+
+void GLMoleculeObject_molecule::reinit()
+{
+  if (_molecule->getAtomCount() > 0) {
+    for (molecule::const_iterator atomiter = _molecule->begin();
+        atomiter != _molecule->end();
+        atomiter++) {
+      // check whether atom already exists
+      const atomId_t atomid = (*atomiter)->getId();
+      const bool atom_present = AtomsinSceneMap.count(atomid);
+      if (!atom_present)
+        atomInserted((*atomiter)->getId());
+      else
+        AtomsinSceneMap[atomid]->resetPosition();
+
+
+      // create bond objects in scene
+      addAtomBonds(*atomiter);
+    }
+  }
 }
 
@@ -108,4 +204,26 @@
           << notification->getChannelNo() << ".";
 #endif
+    switch (notification->getChannelNo()) {
+      case molecule::AtomInserted:
+      {
+        const atomId_t _id = _molecule->lastChanged()->getId();
+  #ifdef LOG_OBSERVER
+        observerLog().addMessage() << "++ Observer " << observerLog().getName(static_cast<Observer *>(this)) << " received notification that atom "+toString(_id)+" has been inserted.";
+  #endif
+        atomInserted(_id);
+        break;
+      }
+      case World::AtomRemoved:
+      {
+        const atomId_t _id = _molecule->lastChanged()->getId();
+  #ifdef LOG_OBSERVER
+        observerLog().addMessage() << "++ Observer " << observerLog().getName(static_cast<Observer *>(this)) << " received notification that atom "+toString(_id)+" has been removed.";
+  #endif
+        atomRemoved(_id);
+        break;
+      }
+      default:
+        break;
+    }
   }else{
     // notification from world
@@ -125,2 +243,172 @@
 }
 
+void GLMoleculeObject_molecule::initialize(QGLView *view, QGLPainter *painter)
+{
+  // Initialize all of the mesh objects that we have as children.
+//  GLMoleculeObject::initialize(view, painter);
+   foreach (QObject *obj, children()) {
+     GLMoleculeObject *meshobj = qobject_cast<GLMoleculeObject *>(obj);
+       if (meshobj)
+         meshobj->initialize(view, painter);
+   }
+}
+
+void GLMoleculeObject_molecule::draw(QGLPainter *painter, const QVector4D &cameraPlane)
+{
+   // Draw all of the mesh objects that we have as children.
+  GLMoleculeObject::draw(painter, cameraPlane);
+   foreach (QObject *obj, children()) {
+     GLMoleculeObject *meshobj = qobject_cast<GLMoleculeObject *>(obj);
+       if (meshobj)
+         meshobj->draw(painter, cameraPlane);
+   }
+}
+
+/** Adds an atom of this molecule to the scene.
+ *
+ * @param _atom atom to add
+ */
+void GLMoleculeObject_molecule::atomInserted(const atomicNumber_t _id)
+{
+  LOG(3, "INFO: GLWorldScene: Received signal atomInserted for atom "+toString(_id)+".");
+  GLMoleculeObject_atom *atomObject = new GLMoleculeObject_atom(GLMoleculeObject::meshSphere, this, _id);
+  AtomNodeMap::iterator iter = AtomsinSceneMap.find(_id);
+  ASSERT(iter == AtomsinSceneMap.end(),
+      "GLWorldScene::atomAdded() - same atom with id "+toString(_id)+" added again.");
+  AtomsinSceneMap.insert( make_pair(_id, atomObject) );
+
+  qRegisterMetaType<atomId_t>("atomId_t");
+  qRegisterMetaType<bond::ptr>("bond::ptr");
+  qRegisterMetaType<GLMoleculeObject_bond::SideOfBond>("GLMoleculeObject_bond::SideOfBond");
+  connect (atomObject, SIGNAL(clicked(atomId_t)), this, SIGNAL(atomClicked(atomId_t)));
+  connect (atomObject, SIGNAL(changed()), this, SIGNAL(changed()));
+  connect (atomObject, SIGNAL(hoverChanged(GLMoleculeObject *)), this, SIGNAL(changed()));
+  connect (atomObject, SIGNAL(hoverChanged(GLMoleculeObject *)), this, SLOT(hoverChangedSignalled(GLMoleculeObject *)));
+  connect (atomObject, SIGNAL(selectionChanged()), this, SIGNAL(changed()));
+  connect (atomObject, SIGNAL(BondsInserted(const bond::ptr , const GLMoleculeObject_bond::SideOfBond)), this, SLOT(bondInserted(const bond::ptr , const GLMoleculeObject_bond::SideOfBond)));
+  connect (atomObject, SIGNAL(indexChanged(GLMoleculeObject_atom*, int, int)), this, SIGNAL(changeAtomId(GLMoleculeObject_atom*, int, int)));
+
+  updateBoundingBox();
+
+  //bondsChanged(_atom);
+  emit changeOccured();
+}
+
+/** Removes an atom of this molecule from the scene.
+ *
+ * We just the id as the atom might have already been destroyed.
+ *
+ * @param _id id of atom to remove
+ */
+void GLMoleculeObject_molecule::atomRemoved(const atomicNumber_t _id)
+{
+  LOG(3, "INFO: GLWorldScene: Received signal atomRemoved for atom "+toString(_id)+".");
+  // bonds are removed by signal coming from ~bond
+  // remove atoms
+  AtomNodeMap::iterator iter = AtomsinSceneMap.find(_id);
+  ASSERT(iter != AtomsinSceneMap.end(),
+      "GLWorldScene::atomRemoved() - atom "+toString(_id)+" not on display.");
+  GLMoleculeObject_atom *atomObject = iter->second;
+  atomObject->disconnect();
+  AtomsinSceneMap.erase(iter);
+  delete atomObject;
+
+  updateBoundingBox();
+
+  emit changeOccured();
+}
+
+void GLMoleculeObject_molecule::hoverChangedSignalled(GLMoleculeObject *ob)
+{
+  // Find the atom, ob corresponds to.
+  hoverAtom = NULL;
+  GLMoleculeObject_atom *atomObject = dynamic_cast<GLMoleculeObject_atom *>(ob);
+  if (atomObject){
+    for (AtomNodeMap::iterator iter = AtomsinSceneMap.begin();iter != AtomsinSceneMap.end(); ++ iter){
+      if (iter->second == atomObject)
+        hoverAtom = World::getInstance().getAtom(AtomById(iter->first));
+    }
+  }
+
+  // Propagate signal.
+  emit hoverChanged(hoverAtom);
+}
+
+
+/** Helper function to get bond ids in the correct order for BondNodeMap.
+ *
+ * \return pair of ids in correct order.
+ */
+GLMoleculeObject_molecule::BondIds GLMoleculeObject_molecule::getBondIds(
+    const bond::ptr _bond,
+    const enum GLMoleculeObject_bond::SideOfBond _side)
+{
+  BondIds ids;
+  switch (_side) {
+    case GLMoleculeObject_bond::left:
+      ids = std::make_pair(_bond->leftatom->getId(), _bond->rightatom->getId());
+      break;
+    case GLMoleculeObject_bond::right:
+      ids = std::make_pair(_bond->rightatom->getId(), _bond->leftatom->getId());
+      break;
+  }
+  return ids;
+}
+
+/** Adds a bond to the scene.
+ *
+ * @param _bond bond to add
+ * @param side which side of the bond (left or right)
+ */
+void GLMoleculeObject_molecule::bondInserted(const bond::ptr _bond, const enum GLMoleculeObject_bond::SideOfBond _side)
+{
+  LOG(3, "INFO: GLWorldScene::bondInserted() - Adding bond "+toString(*_bond)+".");
+  //LOG(4, "INFO: Currently present bonds " << BondsinSceneMap << ".");
+
+  const BondIds ids = getBondIds(_bond, _side);
+  BondNodeMap::iterator iter = BondsinSceneMap.find(ids);
+  if (iter == BondsinSceneMap.end()) {
+    GLMoleculeObject_bond * bondObject =
+        new GLMoleculeObject_bond(GLMoleculeObject::meshCylinder, this, _bond, _side);
+    connect (
+        bondObject, SIGNAL(BondRemoved(const atomId_t, const atomId_t)),
+        this, SLOT(bondRemoved(const atomId_t, const atomId_t)));
+    connect (bondObject, SIGNAL(changed()), this, SIGNAL(changed()));
+    BondsinSceneMap.insert( make_pair(ids, bondObject) );
+  //    BondIdsinSceneMap.insert( Leftids );
+  } else {
+    iter->second->resetPosition();
+    iter->second->resetWidth();
+  }
+  emit changeOccured();
+}
+
+/** Removes a bond from the scene.
+ *
+ * @param _bond bond to remove
+ */
+void GLMoleculeObject_molecule::bondRemoved(const atomId_t leftnr, const atomId_t rightnr)
+{
+  LOG(3, "INFO: GLWorldScene::bondRemoved() - Removing bond between "+toString(leftnr)+" and "+toString(rightnr)+".");
+  {
+    // left bond
+    const BondIds Leftids( make_pair(leftnr, rightnr) );
+    BondNodeMap::iterator leftiter = BondsinSceneMap.find( Leftids );
+    ASSERT(leftiter != BondsinSceneMap.end(),
+        "GLWorldScene::bondRemoved() - bond "+toString(leftnr)+"-"
+        +toString(rightnr)+" not on display.");
+    GLMoleculeObject_bond *bondObject = leftiter->second;
+    bondObject->disconnect();
+    BondsinSceneMap.erase(leftiter);
+    delete bondObject; // is done by signal from bond itself
+    //LOG(4, "INFO: Still present bonds " << BondsinSceneMap << ".");
+  }
+
+  emit changeOccured();
+}
+
+std::ostream &operator<<(std::ostream &ost, const GLMoleculeObject_molecule::BondIds &t)
+{
+  ost << t.first << "," << t.second;
+  return ost;
+}
