Index: src/UIElements/Views/Qt4/Qt3D/GLMoleculeObject_bond.cpp
===================================================================
--- src/UIElements/Views/Qt4/Qt3D/GLMoleculeObject_bond.cpp	(revision f01769bf04baacedde88443ce16ab2f2dd809f30)
+++ src/UIElements/Views/Qt4/Qt3D/GLMoleculeObject_bond.cpp	(revision 95f49f80844c3103ded5d5940874d5342ce246a6)
@@ -57,79 +57,89 @@
 #include "World.hpp"
 
-GLMoleculeObject_bond::GLMoleculeObject_bond(QGLSceneNode *mesh[], QObject *parent, const bond::ptr bondref, const enum SideOfBond side) :
+
+// static entities
+const Observable::channels_t
+GLMoleculeObject_bond::BondPositionChannels(1, AtomObservable::PositionChanged);
+const Observable::channels_t
+GLMoleculeObject_bond::BondDegreeChannels(1, BondObservable::DegreeChanged);
+const Observable::channels_t
+GLMoleculeObject_bond::BondElementChannels(1, AtomObservable::ElementChanged);
+
+GLMoleculeObject_bond::GLMoleculeObject_bond(
+    QGLSceneNode *mesh[],
+    QObject *parent,
+    const bondIds_t bondIds,
+    const enum SideOfBond side) :
   GLMoleculeObject(mesh, parent),
   Observer(std::string("GLMoleculeObject_bond")
-      +toString(bondref->leftatom->getId())
+      +toString(bondIds.first)
       +std::string("-")
-      +toString(bondref->rightatom->getId())),
-  _bond(*bondref),
-  leftobservable(bondref->leftatom),
-  rightobservable(bondref->rightatom),
-  leftatomId(bondref->leftatom->getId()),
-  rightatomId(bondref->rightatom->getId()),
+      +toString(bondIds.second)),
+  leftatomId(bondIds.first),
+  rightatomId(bondIds.second),
+  leftatomref(getAtom(leftatomId)),
+  rightatomref(getAtom(rightatomId)),
+  bondref(*leftatomref->getBond(rightatomref)),
   BondSide(side),
+  leftPosition(
+      leftatomref,
+      boost::bind(&GLMoleculeObject_bond::updateLeftPosition, this),
+      "BondleftPosition_"+toString(leftatomId),
+      updateLeftPosition(),
+      BondPositionChannels),
+  rightPosition(
+      rightatomref,
+      boost::bind(&GLMoleculeObject_bond::updateRightPosition, this),
+      "BondrightPosition_"+toString(rightatomId),
+      updateRightPosition(),
+      BondPositionChannels),
+  leftElement(
+      leftatomref,
+      boost::bind(&GLMoleculeObject_bond::updateLeftElement, this),
+      "BondleftElement"+toString(leftatomId),
+      updateLeftElement(),
+      BondElementChannels),
+  rightElement(
+      rightatomref,
+      boost::bind(&GLMoleculeObject_bond::updateRightElement, this),
+      "BondrightElement"+toString(rightatomId),
+      updateRightElement(),
+      BondElementChannels),
+  Degree(
+      &bondref,
+      boost::bind(&GLMoleculeObject_bond::updateDegree, this),
+      "BondDegree"+toString(leftatomId)+"_"+toString(rightatomId),
+      updateDegree(),
+      BondDegreeChannels),
   leftobservable_enabled(false),
-  rightobservable_enabled(false),
-  bond_enabled(false)
+  rightobservable_enabled(false)
 {
   // sign on as observer (obtain non-const instance before)
-  _bond.signOn(this);
-  _bond.signOn(this, BondObservable::BondRemoved);
-  _bond.signOn(this, BondObservable::DegreeChanged);
+  bondref.signOn(this, BondObservable::BondRemoved);
+  bondref.signOn(this, BondObservable::DegreeChanged);
   bond_enabled = true;
-  leftobservable->signOn(this);
-  leftobservable->signOn(this, AtomObservable::PositionChanged);
-  leftobservable->signOn(this, AtomObservable::ElementChanged);
+  leftatomref->signOn(this, AtomObservable::PositionChanged);
+  leftatomref->signOn(this, AtomObservable::ElementChanged);
   leftobservable_enabled = true;
-  rightobservable->signOn(this);
-  rightobservable->signOn(this, AtomObservable::PositionChanged);
-  rightobservable->signOn(this, AtomObservable::ElementChanged);
+  rightatomref->signOn(this, AtomObservable::PositionChanged);
+  rightatomref->signOn(this, AtomObservable::ElementChanged);
   rightobservable_enabled = true;
 
-  size_t elementno = 0;
-  switch (BondSide) {
-    case left:
-    {
-      const atom * const _rightatom = const_cast<const World &>(World::getInstance()).
-          getAtom(AtomById(rightatomId));
-      if (_rightatom->getType() != NULL) {
-        elementno = _rightatom->getType()->getAtomicNumber();
-      } else { // if not element yet set, set to hydrogen
-        elementno = 1;
-      }
-      break;
-    }
-    case right:
-    {
-      const atom * const _leftatom = const_cast<const World &>(World::getInstance()).
-          getAtom(AtomById(leftatomId));
-      if (_leftatom->getType() != NULL) {
-        elementno = _leftatom->getType()->getAtomicNumber();
-      } else { // if not element yet set, set to hydrogen
-        elementno = 1;
-      }
-
-      break;
-    }
-    default:
-      ASSERT(0,
-          "GLMoleculeObject_bond::GLMoleculeObject_bond() - side is not a valid argument: "+toString(BondSide)+".");
-      break;
-  }
-
-  QGLMaterial *elementmaterial = getMaterial(elementno);
-  setMaterial(elementmaterial);
-
+  resetElement();
   resetPosition();
   resetWidth();
+
+  connect(this, SIGNAL(elementChanged()), this, SLOT(resetElement()), Qt::QueuedConnection);
+  connect(this, SIGNAL(positionChanged()), this, SLOT(resetPosition()), Qt::QueuedConnection);
+  connect(this, SIGNAL(degreeChanged()), this, SLOT(resetWidth()), Qt::QueuedConnection);
 }
 
 GLMoleculeObject_bond::~GLMoleculeObject_bond()
 {
-  LOG(3, "DEBUG: Destroying  GLMoleculeObject_bond to bond " << &_bond << " and side " << BondSide << ".");
+  LOG(3, "DEBUG: Destroying  GLMoleculeObject_bond to bond [" <<
+      leftatomId << "," << rightatomId << "] and side " << BondSide << ".");
   // signOff() if not already done
   removeLeftAtom();
   removeRightAtom();
-  removeBond();
   removeChannels();
 }
@@ -163,10 +173,4 @@
     }
   }
-}
-
-void GLMoleculeObject_bond::removeBond()
-{
-  if (bond_enabled)
-    _bond.signOff(this);
 }
 
@@ -198,10 +202,18 @@
   }
   if (bond_enabled) {
-    _bond.signOff(this, BondObservable::BondRemoved);
-    _bond.signOff(this, BondObservable::DegreeChanged);
+    const atom * const _leftatom = const_cast<const World &>(World::getInstance()).
+        getAtom(AtomById(leftatomId));
+    const atom * const _rightatom = const_cast<const World &>(World::getInstance()).
+        getAtom(AtomById(rightatomId));
+    if ((_leftatom != NULL) && (_rightatom != NULL)) {
+      bond::ptr _bond = _leftatom->getBond(_rightatom);
+      if (_bond != NULL) {
+        _bond->signOff(this, BondObservable::BondRemoved);
+        _bond->signOff(this, BondObservable::DegreeChanged);
+      }
+    }
     bond_enabled = false;
   }
 }
-
 
 void GLMoleculeObject_bond::removeMe()
@@ -217,5 +229,5 @@
     default:
       ASSERT(0,
-          "GLMoleculeObject_bond::subjectKilled() - side is not a valid argument: "
+          "GLMoleculeObject_bond::removeMe() - side is not a valid argument: "
           +toString(BondSide)+".");
       break;
@@ -225,21 +237,5 @@
 void GLMoleculeObject_bond::update(Observable *publisher)
 {
-#ifdef LOG_OBSERVER
-  if (publisher == static_cast<const Observable *>(&_bond)) {
-    observerLog().addMessage() << "++ Update of Observer "
-        << observerLog().getName(static_cast<Observer*>(this))
-        << " from bond.";
-  } else if (publisher == leftobservable) {
-    observerLog().addMessage() << "++ Update of Observer "
-        << observerLog().getName(static_cast<Observer*>(this))
-        << " from leftatom " << leftatomId << ".";
-  } else if (publisher == rightobservable) {
-    observerLog().addMessage() << "++ Update of Observer " <<
-        observerLog().getName(static_cast<Observer*>(this))
-        << " from rightatom " << rightatomId << ".";
-  } else
-    observerLog().addMessage() << "++ Update of Observer " <<
-    observerLog().getName(static_cast<Observer*>(this)) << " from unknown source.";
-#endif
+  ASSERT(0, "GLMoleculeObject_bond::update() - we are not signed on for any global updates.");
 }
 
@@ -248,5 +244,5 @@
   // assume subjectKilled() is from Observable's own subjectKilled(), not notifications
   // but we must always signOff from all other sources!
-  if (publisher == static_cast<const Observable *>(&_bond)) {
+  if (publisher == static_cast<const Observable*>(&bondref)) {
 #ifdef LOG_OBSERVER
     observerLog().addMessage() << "++ subjectKilled of Observer "
@@ -256,5 +252,5 @@
     removeLeftAtom();
     removeRightAtom();
-  } else if (publisher == leftobservable) {
+  } else if (publisher == static_cast<const Observable*>(leftatomref)) {
 #ifdef LOG_OBSERVER
     observerLog().addMessage() << "++ subjectKilled of Observer "
@@ -263,6 +259,5 @@
 #endif
     removeRightAtom();
-    removeBond();
-  } else if (publisher == rightobservable) {
+  } else   if (publisher == static_cast<const Observable*>(rightatomref)) {
 #ifdef LOG_OBSERVER
     observerLog().addMessage() << "++ subjectKilled of Observer " <<
@@ -271,10 +266,11 @@
 #endif
     removeLeftAtom();
-    removeBond();
   } else {
 #ifdef LOG_OBSERVER
-    observerLog().addMessage() << "++ subjectKilled of Observer " <<
-    observerLog().getName(static_cast<Observer*>(this)) << " from unknown source.";
-#endif
+    observerLog().addMessage() << "++ subjectKilled of Observer "
+        << observerLog().getName(static_cast<Observer*>(this))
+        << " from unknown source.";
+#endif
+    ASSERT(0, "GLMoleculeObject_bond::recieveNotification() - notification from unknown source.");
   }
   // then indicate to remove us
@@ -286,15 +282,15 @@
 {
 #ifdef LOG_OBSERVER
-  if (publisher == static_cast<const Observable *>(&_bond)) {
+  if (publisher == static_cast<const Observable *>(&bondref)) {
     observerLog().addMessage() << "++ Update of Observer "
         << observerLog().getName(static_cast<Observer*>(this))
         << " received notification from bond for channel "
         << notification->getChannelNo() << ".";
-  } else if (publisher == leftobservable) {
+  } else if (publisher == static_cast<const Observable * const>(leftatomref)) {
     observerLog().addMessage() << "++ Update of Observer "
         << observerLog().getName(static_cast<Observer*>(this))
         << " received notification from leftatom " << leftatomId << " for channel "
         << notification->getChannelNo() << ".";
-  } else if (publisher == rightobservable) {
+  } else if (publisher == static_cast<const Observable * const>(rightatomref)) {
     observerLog().addMessage() << "++ Update of Observer "
         << observerLog().getName(static_cast<Observer*>(this))
@@ -306,7 +302,5 @@
         << " received notification from unknown source.";
 #endif
-  bool DoResetPosition = false;
-  bool DoResetWidth = false;
-  if (publisher == static_cast<const Observable *>(&_bond)){
+  if (publisher == static_cast<const Observable *>(&bondref)){
     switch (notification->getChannelNo()) {
     case BondObservable::BondRemoved:
@@ -314,5 +308,5 @@
       break;
     case BondObservable::DegreeChanged:
-      DoResetWidth = true;
+      emit degreeChanged();
       break;
     default:
@@ -325,9 +319,9 @@
     case AtomObservable::PositionChanged:
       LOG(2, "INFO: Received notification of PositionChanged.");
-      DoResetPosition = true;
+      emit positionChanged();
       break;
     case AtomObservable::ElementChanged:
       LOG(2, "INFO: Received notification of ElementChanged.");
-      DoResetPosition = true;
+      emit elementChanged();
       break;
     default:
@@ -335,44 +329,65 @@
     }
   }
-  if (DoResetPosition)
-    resetPosition();
-  if (DoResetWidth)
-    resetWidth();
-  if ((DoResetPosition) || (DoResetWidth))
-    emit changed();
+}
+
+Vector GLMoleculeObject_bond::updateLeftPosition() const
+{
+  const atom * const _atom = getAtomConst(leftatomId);
+  return _atom->getPosition();
+}
+
+Vector GLMoleculeObject_bond::updateRightPosition() const
+{
+  const atom * const _atom = getAtomConst(rightatomId);
+  return _atom->getPosition();
+}
+
+atomicNumber_t GLMoleculeObject_bond::updateLeftElement() const
+{
+  const atom * const _atom = getAtomConst(leftatomId);
+  return _atom->getElementNo();
+}
+
+atomicNumber_t GLMoleculeObject_bond::updateRightElement() const
+{
+  const atom * const _atom = getAtomConst(rightatomId);
+  return _atom->getElementNo();
+}
+
+int GLMoleculeObject_bond::updateDegree() const
+{
+  const atom * const _leftatom = const_cast<const World &>(World::getInstance()).
+      getAtom(AtomById(leftatomId));
+  const atom * const _rightatom = const_cast<const World &>(World::getInstance()).
+      getAtom(AtomById(rightatomId));
+  if ((_leftatom != NULL) && (_rightatom != NULL)) {
+    bond::ptr _bond = _leftatom->getBond(_rightatom);
+    return _bond->getDegree();
+  } else {
+    return 1;
+  }
+}
+
+void GLMoleculeObject_bond::resetElement()
+{
+  size_t elementno = rightElement.get();
+  QGLMaterial *elementmaterial = getMaterial(elementno);
+  setMaterial(elementmaterial);
 }
 
 void GLMoleculeObject_bond::resetWidth()
 {
-  const double factor = 1.0f+.5f*(_bond.getDegree()-1);
+  const double factor = 1.0f+.5f*(Degree.get()-1);
   LOG(2, "DEBUG: GLMoleculeObject_bond::resetWidth() - setting bond's width to " << factor << ".");
   setScaleX(factor);
   setScaleY(factor);
+
+  emit changed();
 }
 
 void GLMoleculeObject_bond::resetPosition()
 {
-  Vector Position;
-  Vector OtherPosition;
-  const atom * const _leftatom = const_cast<const World &>(World::getInstance()).
-      getAtom(AtomById(leftatomId));
-  Vector LeftPos = _leftatom->getPosition();
-  const atom * const _rightatom = const_cast<const World &>(World::getInstance()).
-      getAtom(AtomById(rightatomId));
-  Vector RightPos = _rightatom->getPosition();
-  switch (BondSide) {
-    case left:
-      Position = LeftPos;
-      OtherPosition = RightPos;
-      break;
-    case right:
-      Position = RightPos; 
-      OtherPosition = LeftPos;
-      break;
-    default:
-      ASSERT(0,
-          "GLMoleculeObject_bond::resetPosition() - side is not a valid argument: "+toString(BondSide)+".");
-      break;
-  }
+  Vector Position = leftPosition.get();
+  Vector OtherPosition = rightPosition.get();
   const double distance =
       Position.distance(OtherPosition)/2.;
@@ -408,3 +423,18 @@
   setRotationVector(QVector3D(b[0], b[1], b[2]));
   setRotationAngle(alpha/M_PI*180.);
-}
+
+  emit changed();
+}
+
+atom * const GLMoleculeObject_bond::getAtom(const atomId_t _id)
+{
+  atom * const _atom = World::getInstance().getAtom(AtomById(_id));
+  return _atom;
+}
+
+const atom * const GLMoleculeObject_bond::getAtomConst(const atomId_t _id)
+{
+  const atom * const _atom = const_cast<const World &>(World::getInstance()).
+      getAtom(AtomById(_id));
+  return _atom;
+}
