Index: src/UIElements/Qt4/InstanceBoard/QtObservedAtom.cpp
===================================================================
--- src/UIElements/Qt4/InstanceBoard/QtObservedAtom.cpp	(revision 98c35cae2ab1845620fc345902fa7bd0a1ab5d53)
+++ src/UIElements/Qt4/InstanceBoard/QtObservedAtom.cpp	(revision 65c3231ff9731698df9e1c840c3c6b5d4c56b2cf)
@@ -36,23 +36,291 @@
 #include "QtObservedAtom.hpp"
 
+#include "UIElements/Qt4/InstanceBoard/QtObservedInstanceBoard.hpp"
+
 #include "CodePatterns/MemDebug.hpp"
 
+#include <boost/assign.hpp>
+
+#include "Atom/atom.hpp"
+#include "Bond/bond.hpp"
+#include "Descriptors/AtomIdDescriptor.hpp"
+#include "Element/element.hpp"
+#include "World.hpp"
+
+#include "UIElements/Views/Qt4/Qt3D/ObservedValue_wCallback.hpp"
+
+using namespace boost::assign;
+
+static const Observable::channels_t getAtomBondsChannels()
+{
+  Observable::channels_t channels;
+  channels += AtomObservable::BondsAdded, AtomObservable::BondsRemoved;
+  return channels;
+}
+
+static const Observable::channels_t getAllObservedChannels()
+{
+  Observable::channels_t channels;
+  channels +=
+      AtomObservable::IndexChanged,
+      AtomObservable::PositionChanged,
+      AtomObservable::ElementChanged,
+      AtomObservable::BondsAdded,
+      AtomObservable::BondsRemoved;
+  return channels;
+}
+
+// static entities
+const Observable::channels_t
+QtObservedAtom::AtomIndexChannels(1, AtomObservable::IndexChanged);
+const Observable::channels_t
+QtObservedAtom::AtomPositionChannels(1, AtomObservable::PositionChanged);
+const Observable::channels_t
+QtObservedAtom::AtomElementChannels(1, AtomObservable::ElementChanged);
+const Observable::channels_t
+QtObservedAtom::AtomBondsChannels(getAtomBondsChannels());
+
 QtObservedAtom::QtObservedAtom(
-    const ObservedValues_t &_obsvalues,
+    const ObservedValues_t &_ObservedValues,
+    QtObservedInstanceBoard &_board,
     QWidget * _parent) :
   QWidget(_parent),
   Observer("QtObservedAtom"),
-  obsvalues(_obsvalues)
-{}
+  subjectKilledCount(0),
+  AllsignedOnChannels(getAllObservedChannels().size()),
+  signedOffChannels(0),
+  owner(NULL),
+  board(_board),
+  ObservedValues(_ObservedValues)
+{
+  activateObserver();
+}
 
 QtObservedAtom::~QtObservedAtom()
-{}
+{
+  deactivateObserver();
+}
+
+const atom * const QtObservedAtom::getAtomConst(const atomId_t _id)
+{
+  const atom * const _atom = const_cast<const World &>(World::getInstance()).
+      getAtom(AtomById(_id));
+  return _atom;
+}
+
+atom * const QtObservedAtom::getAtom(const atomId_t _id)
+{
+  atom * const _atom = World::getInstance().getAtom(AtomById(_id));
+  return _atom;
+}
+
+atomId_t QtObservedAtom::updateIndex()
+{
+  return const_cast<const World &>(World::getInstance()).lastChangedAtomId();
+}
+
+Vector QtObservedAtom::updatePosition(
+    const boost::function<const atomId_t ()> &_getAtomIndex)
+{
+  const atom * const _atom = getAtomConst(_getAtomIndex());
+  if (_atom != NULL) {
+    return _atom->getPosition();
+  } else {
+    return zeroVec;
+  }
+}
+
+atomicNumber_t QtObservedAtom::updateElement(
+    const boost::function<const atomId_t ()> &_getAtomIndex)
+{
+  const atom * const _atom = getAtomConst(_getAtomIndex());
+  if (_atom != NULL) {
+    return _atom->getElementNo();
+  } else {
+    return (atomicNumber_t)-1;
+  }
+}
+
+QtObservedAtom::ListOfBonds_t QtObservedAtom::updateBonds(
+    const boost::function<const atomId_t ()> &_getAtomIndex)
+{
+  ListOfBonds_t ListOfBonds;
+  const atom * const _atom = getAtomConst(_getAtomIndex());
+  if (_atom != NULL) {
+    // make sure bonds is up-to-date
+    const BondList ListBonds = _atom->getListOfBonds();
+    for (BondList::const_iterator iter = ListBonds.begin();
+        iter != ListBonds.end();
+        ++iter)
+      ListOfBonds.insert( ListOfBonds.end(), std::make_pair(
+          (*iter)->leftatom->getId(),
+          (*iter)->rightatom->getId()) );
+  }
+  return ListOfBonds;
+}
 
 void QtObservedAtom::update(Observable *publisher)
-{}
+{
+  ASSERT(0, "QtObservedAtom::update() - we are not signed on for global updates.");
+}
 
 void QtObservedAtom::subjectKilled(Observable *publisher)
-{}
+{
+  ++signedOffChannels;
+
+  if (signedOffChannels == AllsignedOnChannels) {
+    // remove owner: no more signOff needed
+    owner = NULL;
+
+    board.atomcountsubjectKilled(getAtomIndex());
+  }
+}
 
 void QtObservedAtom::recieveNotification(Observable *publisher, Notification_ptr notification)
-{}
+{
+  // ObservedValues have been updated before, hence convert updates to Qt's signals
+  switch (notification->getChannelNo()) {
+    case AtomObservable::IndexChanged:
+      emit indexChanged();
+      break;
+    case AtomObservable::PositionChanged:
+      emit positionChanged();
+      break;
+    case AtomObservable::ElementChanged:
+      emit elementChanged();
+      break;
+    case AtomObservable::BondsAdded:
+    case AtomObservable::BondsRemoved:
+      emit bondsChanged();
+      break;
+    default:
+      ASSERT(0, "QtObservedAtom::recieveNotification() - we are not signed on to channel "
+          +toString(notification->getChannelNo())+" of the atom.");
+      break;
+  }
+}
+
+void QtObservedAtom::activateObserver()
+{
+  atom * atomref = getAtom(getAtomIndex());
+  if (atomref != NULL) {
+    Observable::channels_t channels = getAllObservedChannels();
+    owner = static_cast<const Observable *>(atomref);
+    for (Observable::channels_t::const_iterator iter = channels.begin();
+        iter != channels.end(); ++iter)
+      owner->signOn(this, *iter);
+  } else
+    signedOffChannels = getAllObservedChannels().size();
+}
+
+void QtObservedAtom::deactivateObserver()
+{
+  // sign Off
+  if (owner != NULL) {
+    Observable::channels_t channels = getAllObservedChannels();
+    for (Observable::channels_t::const_iterator iter = channels.begin();
+        iter != channels.end(); ++iter)
+      owner->signOff(this, *iter);
+    owner = NULL;
+    signedOffChannels = AllsignedOnChannels;
+  }
+}
+
+void QtObservedAtom::initObservedValues(
+    ObservedValues_t &_ObservedValues,
+    const atomId_t _id,
+    const atom * const _atomref,
+    const boost::function<void(const atomId_t)> &_subjectKilled)
+{
+  /* This is an old note from when the code was still part of cstor's initializer body.
+   * TODO: Probably does not apply anymore but has not yet been tested.
+   *
+   * We must not use boost::cref(this) as "this" has not been properly constructed and seemingly
+   * boost::cref tries to do some magic to grasp the inheritance hierarchy which fails because
+   * the class has not been fully constructed yet. "This" itself seems to be working fine.
+   */
+
+  ASSERT( _ObservedValues.size() == MAX_ObservedTypes,
+      "QtObservedAtom::initObservedValues() - given ObservedValues has not correct size.");
+
+  // fill ObservedValues: index first
+  const boost::function<atomId_t ()> AtomIndexUpdater(
+      boost::bind(&QtObservedAtom::updateIndex));
+
+  ObservedValue_wCallback<atomId_t> * const IndexObservable =
+      new ObservedValue_wCallback<atomId_t>(
+          _atomref,
+          boost::bind(&QtObservedAtom::updateIndex),
+          "AtomIndex_"+toString(_id),
+          _id,
+          AtomIndexChannels,
+          _subjectKilled);
+  _ObservedValues[AtomIndex] = IndexObservable;
+
+  const boost::function<const atomId_t ()> AtomIndexGetter =
+      boost::bind(&ObservedValue_wCallback<atomId_t>::get,
+          IndexObservable);
+
+  // fill ObservedValues: then all the other that need index
+  const boost::function<Vector ()> AtomPositionUpdater(
+      boost::bind(&QtObservedAtom::updatePosition, AtomIndexGetter));
+  const boost::function<atomicNumber_t ()> AtomElementUpdater(
+      boost::bind(&QtObservedAtom::updateElement, AtomIndexGetter));
+  const boost::function<ListOfBonds_t ()> AtomBondsUpdater(
+      boost::bind(&QtObservedAtom::updateBonds, AtomIndexGetter));
+
+  _ObservedValues[AtomPosition] = new ObservedValue_wCallback<Vector, atomId_t>(
+      _atomref,
+      AtomPositionUpdater,
+      "AtomPosition_"+toString(_id),
+      AtomPositionUpdater(),
+      AtomPositionChannels,
+      _subjectKilled,
+      AtomIndexGetter);
+  _ObservedValues[AtomElement] = new ObservedValue_wCallback<atomicNumber_t, atomId_t>(
+      _atomref,
+      AtomElementUpdater,
+      "AtomElement"+toString(_id),
+      AtomElementUpdater(),
+      AtomElementChannels,
+      _subjectKilled,
+      AtomIndexGetter);
+  _ObservedValues[AtomBonds] = new ObservedValue_wCallback<ListOfBonds_t, atomId_t>(
+      _atomref,
+      AtomBondsUpdater,
+      "AtomBonds_"+toString(_id),
+      AtomBondsUpdater(),
+      AtomBondsChannels,
+      _subjectKilled,
+      AtomIndexGetter);
+}
+
+void QtObservedAtom::destroyObservedValues(
+    std::vector<boost::any> &_ObservedValues)
+{
+  delete boost::any_cast<ObservedValue_wCallback<atomId_t> *>(_ObservedValues[AtomIndex]);
+  delete boost::any_cast<ObservedValue_wCallback<Vector, atomId_t> *>(_ObservedValues[AtomPosition]);
+  delete boost::any_cast<ObservedValue_wCallback<atomicNumber_t, atomId_t> *>(_ObservedValues[AtomElement]);
+  delete boost::any_cast<ObservedValue_wCallback<ListOfBonds_t, atomId_t> *>(_ObservedValues[AtomBonds]);
+  _ObservedValues.clear();
+}
+
+atomId_t QtObservedAtom::getAtomIndex() const
+{
+  return boost::any_cast<ObservedValue_wCallback<atomId_t> *>(ObservedValues[AtomIndex])->get();
+}
+
+Vector QtObservedAtom::getAtomPosition() const
+{
+  return boost::any_cast<ObservedValue_wCallback<Vector, atomId_t> *>(ObservedValues[AtomPosition])->get();
+}
+
+atomicNumber_t QtObservedAtom::getAtomElement() const
+{
+  return boost::any_cast<ObservedValue_wCallback<atomicNumber_t, atomId_t> *>(ObservedValues[AtomElement])->get();
+}
+
+QtObservedAtom::ListOfBonds_t QtObservedAtom::getAtomBonds() const
+{
+  return boost::any_cast<ObservedValue_wCallback<ListOfBonds_t, atomId_t> *>(ObservedValues[AtomBonds])->get();
+}
