Index: src/documentation/constructs/qt-gui.dox
===================================================================
--- src/documentation/constructs/qt-gui.dox	(revision c307ba4e4b46954d39964089972d5cb1f29a6f40)
+++ src/documentation/constructs/qt-gui.dox	(revision fb95a5645025c4f145cfcbf9ef41a1f12c86a506)
@@ -20,72 +20,199 @@
  * In the following we want to explain some of the details that are involved.
  *
+ * \section qt-gui-general General Concepts
+ *
+ * Let us first discuss about the general concepts.
+ *
+ * MoleCuilder is about atoms, bonds and the molecules made up by them. But
+ * there is more: There are fragments, potentials, shapes, and so on.
+ *
+ * In the Qt GUI all of these are displayed in certain areas of the screen
+ * and also in a certain manner:
+ * -# the 3D view represents a three-dimensional representation of all atoms,
+ *    and their bonds or possibly the molecules they form alone. Also the
+ *    bounding box is shown and all selected shapes. Atoms or molecules can
+ *    be selected by clicking. The view can be manipulated through rotation
+ *    and translation.
+ * -# an element list shows all available elements of the period table.
+ * -# a molecule list shows all present molecules sorted by their formula.
+ * -# a fragment list shows all fragments with their energies and contributions
+ * -# a potential list shows all currently instantiated potentials and
+ *    gives a 2D plot.
+ * -# a shape list displays all currently available shapes, allows to select
+ *    them and buttons allow to combine them via boolean operation.
+ * -# an info box informs about the current atom/molecule the mouse pointer
+ *    is hovering over.
+ *
+ * So, there are many objects that need to be filled with information and
+ * they need to access the World and other singletons in order to obtain
+ * this information.
+ *
+ * One major obstacle, or rather THE major obstacle, is that Qt is threaded,
+ * i.e. the Actions are processed in one thread and the Gui does its event
+ * processing in another one. Qt's Signal/Slot system is handled via this
+ * event system, i.e. a signal launched by one thread may be handled by
+ * the slot function in another thread. The Observer/Observable system
+ * of the CodePatterns which we used internally/outside Qt's scope does
+ * not do this.
+ *
+ * Also, signals may get delayed. This can happen either deliberately, e.g.
+ * there is a QTimer that only updates an object in regular intervals, or
+ * because of asynchronous threads. Elsewhen, the slot callback for a
+ * certain signal is called directly. For all of these cases we have to
+ * accommodate. This is especially problematic with the instantiation and
+ * destruction of objects.
+ *
+ * A clarifying example: Imagine an atom is constructed, the AtomObserver
+ * notifies about it, but the information is not processed immediately.
+ * Shortly after, the atom is destroyed again before its representation is
+ * instantiated in the GUI. Afterwards the GUI attempts to instantiate it
+ * but can not longer access the atom for its position and element.
+ *
+ * The only possible way out is to duplicate information. This is the usual
+ * way how to deal with environments with multiple threads. I.e. all the
+ * information that the GUI representants of information inside the World
+ * needs to be doubled such that when the original information is destroyed
+ * the representant can still be accessed as long as needed.
+ *
+ * \subsection qt-gui-general-observedvalue Observed Value
+ *
+ * These representants are called \a ObservedValue in CodePatterns and they
+ * are used everywhere in the Qt Gui.
+ *
+ * They contain an internal information, e.g. a boolean, a Vector or even
+ * a complex structure such as a Tesselation. They require an updater
+ * function to obtain the derived information from the original source. And
+ * they signOn to the source in order to be notified either generally on
+ * updates or for specific channels only.
+ *
+ * The ObservedValue will automatically and immediately update its internal
+ * representation of the derived information by calling the updater function
+ * as soon as it has been informed about the update. Hence, the internal
+ * information is always up-to-date and lives beyond the scope of the
+ * source of the information until its own destruction. As updates are
+ * processed immediately, this pattern only makes sense for "small" pieces
+ * of information, i.e. when the updater function is very light-weight and
+ * does not do much in terms of using computing resources.
+ *
+ * Note that there is another concept that is opposite to the observed value,
+ * namely the Cacheable. This pattern will update itself only when requested,
+ * referred to as "lazy evaluation". Hence, this pattern is used for "large"
+ * pieces of information that require more computing resources within the
+ * updater. Also, the Cacheable's information can only be obtained as long
+ * as the source of information is still alive.
+ *
+ * Both concepts can be used in threaded environments as mutexed are used to
+ * protect read and write accesses.
+ *
+ * \subsection qt-gui-general-signalslot Observer/Observable and Signal/Slot
+ *
+ * In the following we refer to Observer/Observable as "O/O" and to Signal/Slot
+ * as "S/S".
+ *
+ * One thing we need to do is to translate between update() or
+ * recieveNotification() calls from an Observable and subsequent signal/slot
+ * calls. The general idea is to use these ObservedValues as translation
+ * points for small pieces of information and Cacheables for larger pieces.
+ *
+ * However, we need more of these translation points:
+ * -# GLWorldView checks for
+ *   -# World's MoleculeInserted
+ *   -# World's SelectionChanged
+ *   -# WorldTime's TimeChanged
+ *   -# each molecule's AtomInserted and AtomRemoved
+ *   -# AtomObservable's AtomChanged.
+ *   -# ShapeRegistry's ShapedAdded, ShapeRemoved, and SelectionChanged
+ * -# GLMoleculeObject_molecule checks for
+ *   -# molecule's AtomInserted, AtomRemoved, AtomMoved, IndexChanged
+ *   -# World's SelectionChanged
+ *
  * \section qt-gui-qt3d Qt3D and the way to get atoms and bonds displayed
  *
- * Atoms and Bonds have to displayed, the widget for this is GLWorldView. To
- * this class belongs GLWorldScene that contains lots of GLMoleculeObject's or
- * nodes in the speak of Qt3D. We have four derived class for these kind of
- * objects:
- * -# GLMoleculeObject_atom: for each atom,
- * -# GLMoleculeObject_bond: for each "side" of the bond (each represents half of
- *     the bond that join in the middle between the two atoms),
- * -# GLMoleculeObject_molecule: for each molecule (shows a box is selected),
- * -# GLMoleculeObject_shape: shows the shapes in the ShapeRegistry.
- *
- * We can only add new nodes to the Qt3D scene at the level of GLWorldScene,
- * hence all insertion go through this instance to add new nodes. Destruction
- * may occur anywhere as the new nodes are parentized to the scene.
- *
- * \subsection qt-gui-qt3d-atoms How atom object are constructed/destroyed.
- *
- * Atoms are rendered as spheres, see createAtom(). GLWorldView gets notified
- * by the World about new and removed atoms via the Channel's World::AtomInserted
- * and World::AtomRemoved. It translates these into Qt signals with the correct
- * affected atom, by looking at
- * \code
- *   const atom *_atom = World::getInstance().lastChanged<atom>();
- * \endcode
- * These signals call slots of GLWorldScene that has a map of all contained
- * GLMoleculeObject, one for either of the two kinds:
- * -# GLWorldScene::atomInserted(): create a new node and connect its signals
- *  with us, add to map
- * -# GLWorldScene::atomRemoved(): disconnect, remove from map, destroy
- *
- * We do not need to destroy the node itself as it is connected via the Observer
- * mechanism to the associated atom
- *
- * \subsection qt-gui-qt3d-bonds How bond object are constructed/destroyed.
- *
- * Bonds are displayed as cylinders that elongate from one atom to the midpoint
- * of the bond (i.e. the spot in between the two atoms). That is we have always
- * two cylinders per bond. That's why we need to distinguish
- * GLMoleculeObject_bond::SideOfBond to get the right node.
- *
- * Bonds are not as easy as atoms: The World does not know about bonds being
- * created or destroyed, only the atoms themselves know about them.
- *
- * That's way the atom node object GLMoleculeObject_atom is an Observer of is
- * associated atom and listens to the Channel AtomObservable::BondsAdded. It then
- * translates this into a Qt signal that calls a slot GLWorldScene:BondInserted.
- *
- *
- * Bonds themselves are also Observables, as are atoms. Hence,
- * GLMoleculeObject_bond connect via the Observer mechanism to their associated
- * bond and are thus notified when they are destroyed.
- *
- * Additionally, we use GLWorldScene to do some bookkeeping about all bond nodes.
- * This is not strictly required but might in general be useful. Hence, signals
- * notify GLWorldScene also about GLWorldScene::bondRemoved that are emitted by
- * the node itself.
+ * By far the most difficult component of the Qt GUI is the 3D view. So,
+ * let us explain it in detail.
+ *
+ * The general widget making up the view is called \a GLWorldView. It contains
+ * the GLWorldScene (i.e. all atoms, bonds, molecules, and shapes). Also
+ * the "dreibein" and the domain. It processes key presses and mouse events
+ * to manipulate the view. And it also serves as the translator O/O to S/S
+ * system.
+ *
+ * The GLWorldScene contains the actual nodes of the molecular system, i.e.
+ * the atoms, bonds, molecules, and shapes. All of these are derived from
+ * GLMoleculeObject and have their parent to the instance of the GLWorldScene
+ * which goes through its list of children and to call draw() on them.
+ *
+ * The bottom-most structure is GLMoleculeObject_atom displaying a sphere
+ * of an element-specific color at the atom's position. The atom relies
+ * on its representants to be contain all required information but it
+ * is also signOn() to the atom itself whose O/O are translated to S/S
+ * for processing whenever desired.
+ *
+ * Next comes the GLMoleculeObject_bond which displays a cylinder between
+ * two atoms. Actual, a true bond consists of two of these objects. If the
+ * bond is between heterogeneous atoms each half will be displayed in the
+ * color of the closer atom. These bond objects are not associated with
+ * the atoms directly as the are linked to two atoms at the same time. They
+ * rely on ObservedValues for position and element of either atom and for
+ * the degree of the bond itself.
+ *
+ * Parallel to these are GLMoleculeObject_shape which display the surface
+ * of a selected shape. A shape in general does not change after instantation,
+ * hence the shape lives with the information it gets on instantiation till
+ * it dies.
+ *
+ * Finally, the GLMoleculeObject_molecule owns both atoms and bonds. This
+ * allows for switching the view between the classical ball-and-stick model
+ * and the tesselated surface of the molecule. The latter uses a lot less
+ * triangles and thus is faster. Also, it is especially suited for large
+ * molecules. The molecule also needs ObservedValues for its bounding box
+ * (used to show when it's selected), the index, the selection status,
+ * and the list of atom ids. As Cacheable we use the tesselation structure.
+ *
+ * \section qt-gui-cases Sample cases
+ *
+ * Let us discuss some cases and how the different instances interact.
+ *
+ * \section qt-gui-cases-start Start
+ *
+ * When molecuilder is started, several singletons such as the World and
+ * others are instantiated. No atoms are yet present, no bonds, no molecules.
+ * Hence, nothing to display yet.
+ *
+ * Before launching any Action the ActionQueue is forced to wait till the
+ * GUI is finished instantiating. This is to ensure that GLWorldView and
+ * others are in place to receive signals from the O/O system.
+ *
+ * When a molecule is loaded, the instantiation of a GLMoleculeObject_molecule
+ * does not happen immediately. Hence, GLWorldView listens to the World's
+ * MoleculeInserted. On receiving it, it also signOn()s to the molecule
+ * to get its subjectKilled(). It translates then these and also all
+ * AtomInserted and AtomRemoved to the S/S system as moleculeInserted,
+ * moleculeRemoved and atomInserted/atomRemoved respectively, which are
+ * processed by the GLWorldScene.
+ *
+ * The GLWorldScene records any atomInserted/atomRemoved until the molecule
+ * has been instantiated. On instantiation all recorded events are played.
+ * This is to ensure that there is no overlap in instantiation and signOn()
+ * to the molecule. If we would simply get all atoms which are present
+ * on processing the molecule's instantiation we might stumble over a signal
+ * of a molecule of a just added atom. This occurs frequently as both
+ * are very much correlated.
+ *
+ * GLWorldView keep track of all ObservedMolecules. And GLWorldScene keeps
+ * track of all shapes and molecules in the scene. Each
+ * GLMoleculeObject_molecule in turn keeps track of all atoms and bonds in
+ * its part of the scene.
  *
  * \section QtElementList
  *
- * Lists for each element how often it occures in the world. Selecting an entry
+ * Lists for each element how often it occurs in the world. Selecting an entry
  * calls SelectionAtomByElementAction to select all atoms of that particular
  * element.
  *
- * It observes the World and performs a complete refill on any message. To reduce
- * performance issues it marks the list as dirty and refills it the next time the
- * GUI is idle. This way many successive changes to the world only lead to a
- * single refill.
+ * Initially, it fills itself by looking at all elements in the World's
+ * periodentafel. It also listens to AtomObserver's ElementChanged to know
+ * when to update a certain element in its list. By using an internal list
+ * for each atom's element, it can update each element's occurrence.
  *
  * \section QtMoleculeList
@@ -94,5 +221,29 @@
  * Selecting an entry calls the SelectionMoleculeByIdAction.
  *
- * It observes the World the same way QtElementList does.
+ * The QtMoleculeList is also a rather complex beast. It is a tree of
+ * rows and each row consists of a number of elements. There are two
+ * levels, the group level where the common formula for all molecules
+ * is given, and the molecule level where are molecules of this specific
+ * formula are summarized.
+ *
+ * The group items are QStandardItems. Sadly, they are not derived from
+ * QObject and hence do not use the S/S system. The group items are
+ * directly controlled by the QtMoleculeList.
+ *
+ * However, the molecule items are different. They are derived from
+ * QtMoleculeList and use an ObservedValue internally to contain an always
+ * valid copy of the required information. They inform the QtMoleculeList on
+ * updates via a callback (as QStandardItem, from which they are also derived,
+ * does not use the S/S system). The callback takes care of then also updating
+ * the group items and possibly moving the molecule items around, e.g. if
+ * their formula has changed they suddenly belong to another group.
+ *
+ * All items are instantiated by the QtMoleculeItemFactory.
+ *
+ * QtMoleculeList uses an internal QTimer to only update itself at regular
+ * intervals. Hence, updates are processed rather lazily. We keep lists
+ * of changes, separated for group and molecule items. And these are processed
+ * one after the other at the intervals dictated by the QTimer in
+ * updateItemStates().
  *
  * \section QtShapeController
@@ -119,4 +270,4 @@
  * they automatically clear the info box.
  *
- * \date 2013-02-22
+ * \date 2015-07-15
  */
