Changeset 0ac85c3 for src/UIElements


Ignore:
Timestamp:
Jan 29, 2015, 7:37:57 AM (11 years ago)
Author:
Frederik Heber <heber@…>
Branches:
Action_Thermostats, Add_AtomRandomPerturbation, Add_FitFragmentPartialChargesAction, Add_RotateAroundBondAction, Add_SelectAtomByNameAction, Added_ParseSaveFragmentResults, AddingActions_SaveParseParticleParameters, Adding_Graph_to_ChangeBondActions, Adding_MD_integration_tests, Adding_ParticleName_to_Atom, Adding_StructOpt_integration_tests, AtomFragments, Automaking_mpqc_open, AutomationFragmentation_failures, Candidate_v1.5.4, Candidate_v1.6.0, Candidate_v1.6.1, Candidate_v1.7.0, Candidate_v1.7.1, ChangeBugEmailaddress, ChangingTestPorts, ChemicalSpaceEvaluator, CombiningParticlePotentialParsing, Combining_Subpackages, Debian_Package_split, Debian_package_split_molecuildergui_only, Disabling_MemDebug, Docu_Python_wait, EmpiricalPotential_contain_HomologyGraph, EmpiricalPotential_contain_HomologyGraph_documentation, Enable_parallel_make_install, Enhance_userguide, Enhanced_StructuralOptimization, Enhanced_StructuralOptimization_continued, Example_ManyWaysToTranslateAtom, Exclude_Hydrogens_annealWithBondGraph, FitPartialCharges_GlobalError, Fix_BoundInBox_CenterInBox_MoleculeActions, Fix_ChargeSampling_PBC, Fix_ChronosMutex, Fix_FitPartialCharges, Fix_FitPotential_needs_atomicnumbers, Fix_ForceAnnealing, Fix_IndependentFragmentGrids, Fix_ParseParticles, Fix_ParseParticles_split_forward_backward_Actions, Fix_PopActions, Fix_QtFragmentList_sorted_selection, Fix_Restrictedkeyset_FragmentMolecule, Fix_StatusMsg, Fix_StepWorldTime_single_argument, Fix_Verbose_Codepatterns, Fix_fitting_potentials, Fixes, ForceAnnealing_goodresults, ForceAnnealing_oldresults, ForceAnnealing_tocheck, ForceAnnealing_with_BondGraph, ForceAnnealing_with_BondGraph_continued, ForceAnnealing_with_BondGraph_continued_betteresults, ForceAnnealing_with_BondGraph_contraction-expansion, FragmentAction_writes_AtomFragments, FragmentMolecule_checks_bonddegrees, GeometryObjects, Gui_Fixes, Gui_displays_atomic_force_velocity, ImplicitCharges, IndependentFragmentGrids, IndependentFragmentGrids_IndividualZeroInstances, IndependentFragmentGrids_IntegrationTest, IndependentFragmentGrids_Sole_NN_Calculation, JobMarket_RobustOnKillsSegFaults, JobMarket_StableWorkerPool, JobMarket_unresolvable_hostname_fix, MoreRobust_FragmentAutomation, ODR_violation_mpqc_open, PartialCharges_OrthogonalSummation, PdbParser_setsAtomName, PythonUI_with_named_parameters, QtGui_reactivate_TimeChanged_changes, Recreated_GuiChecks, Rewrite_FitPartialCharges, RotateToPrincipalAxisSystem_UndoRedo, SaturateAtoms_findBestMatching, SaturateAtoms_singleDegree, StoppableMakroAction, Subpackage_CodePatterns, Subpackage_JobMarket, Subpackage_LinearAlgebra, Subpackage_levmar, Subpackage_mpqc_open, Subpackage_vmg, Switchable_LogView, ThirdParty_MPQC_rebuilt_buildsystem, TrajectoryDependenant_MaxOrder, TremoloParser_IncreasedPrecision, TremoloParser_MultipleTimesteps, TremoloParser_setsAtomName, Ubuntu_1604_changes, stable
Children:
27e464
Parents:
7b38d3 (diff), 4f2895 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'GUI_TesselatedLargeMolecules' into Candidate_v1.4.10

Location:
src/UIElements
Files:
21 edited

Legend:

Unmodified
Added
Removed
  • src/UIElements/CommandLineUI/CommandLineParser.cpp

    r7b38d3 r0ac85c3  
    443443    // force action queue to stop thread
    444444    ActionQueue::getInstance().stop();
     445    ActionQueue::getInstance().clearTempQueue();
    445446#endif
    446447    ActionQueue::getInstance().clearQueue();
  • src/UIElements/Qt4/QtMainWindow.cpp

    r7b38d3 r0ac85c3  
    146146  settings.endGroup();
    147147
    148   connect(glWorldView,SIGNAL(hoverChanged(const atom*)), infoBox,SLOT(atomHover(const atom*)));
     148  qRegisterMetaType<moleculeId_t>("moleculeId_t");
     149
     150  connect(glWorldView,SIGNAL(hoverChanged(const atom&)), infoBox,SLOT(atomHover(const atom&)));
     151  connect(glWorldView,SIGNAL(hoverChanged(const molecule&, int)), infoBox,SLOT(moleculeHover(const molecule&)));
     152  connect(moleculeList,SIGNAL(moleculesVisibilityChanged(const moleculeId_t,bool)), glWorldView, SIGNAL(moleculesVisibilityChanged(const moleculeId_t,bool)));
    149153}
    150154
  • src/UIElements/Views/Qt4/Qt3D/GLMoleculeObject.cpp

    r7b38d3 r0ac85c3  
    6262QGLMaterial *GLMoleculeObject::m_selectionBoxMaterial = NULL;
    6363
     64QGLSceneNode *GLMoleculeObject::meshEmpty[GLMoleculeObject::DETAILTYPES_MAX];
     65QGLSceneNode *GLMoleculeObject::meshSphere[GLMoleculeObject::DETAILTYPES_MAX];
     66QGLSceneNode *GLMoleculeObject::meshCylinder[GLMoleculeObject::DETAILTYPES_MAX];
    6467
    6568double GLMoleculeObject::detailMinDistance[GLMoleculeObject::DETAILTYPES_MAX] = {0, 15, 30, 42};
     
    6972{
    7073   //mesh->setParent(this);
    71    for (int i=0;i<DETAILTYPES_MAX;i++)
    72      m_mesh[i] = mesh[i];
     74  for (int i=0;i<DETAILTYPES_MAX;i++)
     75    m_mesh[i] = mesh[i];
     76  MeshFreeType = free_none;
     77   m_scaleX = 1.0f;
     78   m_scaleY = 1.0f;
     79   m_scaleZ = 1.0f;
     80   m_rotationAngle = 0.0f;
     81   m_effect = 0;
     82   m_objectId = -1;
     83   m_hovering = false;
     84   m_selected = false;
     85   m_visible = true;
     86   m_material = 0;
     87   initStaticMaterials();
     88}
     89
     90GLMoleculeObject::GLMoleculeObject(QGLSceneNode *mesh, QObject *parent)
     91   : QObject(parent)
     92{
     93   //mesh->setParent(this);
     94  for (int i=0;i<DETAILTYPES_MAX;i++)
     95    m_mesh[i] = mesh;
     96  MeshFreeType = free_none;
    7397   m_scaleX = 1.0f;
    7498   m_scaleY = 1.0f;
     
    83107}
    84108
    85 GLMoleculeObject::GLMoleculeObject(QGLSceneNode *mesh, QObject *parent)
     109GLMoleculeObject::GLMoleculeObject(QGLAbstractScene *scene, QObject *parent)
    86110   : QObject(parent)
    87111{
    88    //mesh->setParent(this);
    89    for (int i=0;i<DETAILTYPES_MAX;i++)
    90      m_mesh[i] = mesh;
     112  for (int i=0;i<DETAILTYPES_MAX;i++)
     113    m_mesh[i] = scene->mainNode();
     114  MeshFreeType = free_none;
    91115   m_scaleX = 1.0f;
    92116   m_scaleY = 1.0f;
     
    101125}
    102126
    103 GLMoleculeObject::GLMoleculeObject(QGLAbstractScene *scene, QObject *parent)
    104    : QObject(parent)
    105 {
    106    scene->setParent(this);
    107    for (int i=0;i<DETAILTYPES_MAX;i++)
    108      m_mesh[i] = scene->mainNode();
    109    m_scaleX = 1.0f;
    110    m_scaleY = 1.0f;
    111    m_scaleZ = 1.0f;
    112    m_rotationAngle = 0.0f;
    113    m_effect = 0;
    114    m_objectId = -1;
    115    m_hovering = false;
    116    m_selected = false;
    117    m_material = 0;
    118    initStaticMaterials();
    119 }
    120 
    121127GLMoleculeObject::~GLMoleculeObject()
    122128{
     
    163169   painter->modelViewMatrix().push();
    164170   painter->modelViewMatrix().translate(m_position);
     171   if ((m_scaleX != 1.0f) || (m_scaleY != 1.0f) || (m_scaleZ != 1.0f))
     172     painter->modelViewMatrix().scale(m_scaleX, m_scaleY, m_scaleZ);
    165173   if (m_rotationAngle != 0.0f)
    166174     painter->modelViewMatrix().rotate(m_rotationAngle, m_rotationVector);
    167    painter->modelViewMatrix().scale(m_scaleX, m_scaleY, m_scaleZ);
    168175
    169176   // Apply the material and effect to the painter.
     
    325332  }
    326333}
     334
     335void GLMoleculeObject::setVisible(bool value)
     336{
     337  if (value != m_visible){
     338    m_visible = value;
     339    emit changed();
     340  }
     341}
     342
     343void GLMoleculeObject::updateMesh(QGLSceneNode *mesh)
     344{
     345  if (m_mesh[0] != NULL) {
     346    switch(MeshFreeType) {
     347    case free_all:
     348      for (int i=0;i<DETAILTYPES_MAX;i++)
     349        delete m_mesh[i];
     350      break;
     351    case free_single:
     352      delete m_mesh[0];
     353      break;
     354    default:
     355    case free_none:
     356      break;
     357    }
     358  }
     359  MeshFreeType = free_single;
     360  for (int i=0;i<DETAILTYPES_MAX;i++)
     361    m_mesh[i] = mesh;
     362}
  • src/UIElements/Views/Qt4/Qt3D/GLMoleculeObject.hpp

    r7b38d3 r0ac85c3  
    7474   void setSelected(bool value);
    7575
     76   bool visible() const { return m_visible; }
     77   virtual void setVisible(bool value);
     78
    7679   void initStaticMaterials();
    77    void initialize(QGLView *view, QGLPainter *painter);
     80   virtual void initialize(QGLView *view, QGLPainter *painter);
    7881   virtual void draw(QGLPainter *painter, const QVector4D &cameraPlane);
    7982   void drawSelectionBox(QGLPainter *painter);
     
    9497   static void cleanMaterialMap();
    9598
     99   void updateMesh(QGLSceneNode *scene);
     100
    96101   typedef std::map< size_t, QGLMaterial *> ElementMaterialMap;
    97102   static ElementMaterialMap ElementNoMaterialMap;
     
    100105   enum{DETAIL_HIGHEST, DETAIL_HIGH, DETAIL_MEDIUM, DETAIL_LOW, DETAILTYPES_MAX} DetailType;
    101106
     107   static QGLSceneNode *meshEmpty[DETAILTYPES_MAX];
     108   static QGLSceneNode *meshSphere[DETAILTYPES_MAX];
     109   static QGLSceneNode *meshCylinder[DETAILTYPES_MAX];
     110
    102111protected:
    103112
     
    105114
    106115   QGLSceneNode *m_mesh[DETAILTYPES_MAX];
     116   enum enum_MeshFreeType {
     117     free_all,
     118     free_single,
     119     free_none
     120   } MeshFreeType;
    107121   QGLAbstractScene *m_scene;
    108122   QVector3D m_position;
     
    120134   bool m_hovering;
    121135   bool m_selected;
     136   bool m_visible;
    122137};
    123138
  • src/UIElements/Views/Qt4/Qt3D/GLMoleculeObject_atom.cpp

    r7b38d3 r0ac85c3  
    5656  GLMoleculeObject(mesh, parent),
    5757  Observer(std::string("GLMoleculeObject_atom")+toString(_id)),
    58   atomicid(_id)
     58  atomicid(_id),
     59  uptodatePosition(false),
     60  uptodateElement(false)
    5961{
    6062  // sign on as observer (obtain non-const instance before)
     
    108110    ELOG(2, "Atom with id "+toString(atomicid)+" is already gone.");
    109111  }
     112  uptodatePosition = true;
    110113}
    111114
     
    141144  }
    142145  setScale( radius / 4. );
     146
     147  uptodateElement = true;
    143148}
    144149
     
    165170  // selected?
    166171  setSelected(World::getInstance().isAtomSelected(atomicid));
     172}
     173
     174void GLMoleculeObject_atom::draw(QGLPainter *painter, const QVector4D &cameraPlane)
     175{
     176  // hook to update prior to painting
     177  if (!uptodatePosition)
     178    resetPosition();
     179  if (!uptodateElement)
     180    resetElement();
     181
     182  // call old hook to do the actual paining
     183  GLMoleculeObject::draw(painter, cameraPlane);
    167184}
    168185
     
    185202    switch (notification->getChannelNo()) {
    186203      case AtomObservable::ElementChanged:
    187         resetElement();
    188         emit changed();
     204        uptodateElement = false;
    189205        break;
    190206      case AtomObservable::IndexChanged:
     
    192208        break;
    193209      case AtomObservable::PositionChanged:
    194         resetPosition();
    195         emit changed();
     210        uptodatePosition = false;
    196211        break;
    197212      case AtomObservable::BondsAdded:
     
    199214        const atom *_atom = World::getInstance().getAtom(AtomById(atomicid));
    200215        if (_atom != NULL) {
     216          // make sure position is up-to-date
     217          if (!uptodatePosition)
     218            resetPosition();
    201219          ASSERT(!_atom->getListOfBonds().empty(),
    202220              "GLMoleculeObject_atom::recieveNotification() - received BondsAdded but ListOfBonds is empty.");
  • src/UIElements/Views/Qt4/Qt3D/GLMoleculeObject_atom.hpp

    r7b38d3 r0ac85c3  
    3131  virtual ~GLMoleculeObject_atom();
    3232
     33  void draw(QGLPainter *painter, const QVector4D &cameraPlane);
     34
    3335  // Observer functions
    3436  void update(Observable *publisher);
     
    4547
    4648private:
    47   //!> grant GLWorldScene acess to reset functions
    48   friend class GLWorldScene;
     49  //!> grant GLMoleculeObject_molecule acess to reset functions
     50  friend class GLMoleculeObject_molecule;
    4951
    5052  void resetPosition();
     
    5658
    5759  const atomId_t atomicid;
     60
     61  bool uptodatePosition;
     62  bool uptodateElement;
    5863};
    5964
  • src/UIElements/Views/Qt4/Qt3D/GLMoleculeObject_bond.hpp

    r7b38d3 r0ac85c3  
    4343
    4444private:
    45   //!> grant WorldScene access to reset functions
    46   friend class GLWorldScene;
     45  //!> grant GLMoleculeObject_molecule acess to reset functions
     46  friend class GLMoleculeObject_molecule;
    4747
    4848  /** Recalculates the position of the cylinder representing the bond.
  • src/UIElements/Views/Qt4/Qt3D/GLMoleculeObject_molecule.cpp

    r7b38d3 r0ac85c3  
    4141
    4242#include <Qt3D/qglscenenode.h>
     43#include <Qt3D/qglbuilder.h>
    4344
    4445#include "CodePatterns/MemDebug.hpp"
     
    5455#include "Element/element.hpp"
    5556#include "LinearAlgebra/Vector.hpp"
     57#include "LinkedCell/PointCloudAdaptor.hpp"
     58#include "LinkedCell/linkedcell.hpp"
     59#include "Tesselation/tesselation.hpp"
     60#include "Tesselation/BoundaryLineSet.hpp"
     61#include "Tesselation/BoundaryTriangleSet.hpp"
     62#include "Tesselation/CandidateForTesselation.hpp"
     63#include "Atom/TesselPoint.hpp"
    5664#include "World.hpp"
    5765
    58 GLMoleculeObject_molecule::GLMoleculeObject_molecule(QGLSceneNode *mesh[], QObject *parent, const molecule *molref) :
    59   GLMoleculeObject(mesh, parent),
     66#include "GLMoleculeObject_atom.hpp"
     67
     68static QGLSceneNode *createMoleculeMesh(const molecule *molref, QObject *parent)
     69{
     70//  Shape shape = molref->getBoundingSphere();
     71  double minradius = 2.; // TODO: set to maximum bond length value
     72  LOG(3, "DEBUG: Molecule fits into sphere of radius " << minradius);
     73  if (minradius < 1.)
     74    minradius = 1.;
     75
     76  QGeometryData geo;
     77  // we need at least three points for tesselation
     78  if (molref->getAtomCount() >= 3) {
     79    // Tesselate the points.
     80    Tesselation T;
     81    PointCloudAdaptor<molecule> cloud(const_cast<molecule *>(molref), molref->getName());
     82    T(cloud, minradius);
     83
     84    // Fill the points into a Qt geometry.
     85    LinkedCell_deprecated LinkedList(cloud, minradius);
     86    std::map<int, int> indices;
     87    std::map<int, Vector> normals;
     88    int index = 0;
     89    for (PointMap::const_iterator piter = T.PointsOnBoundary.begin();
     90        piter != T.PointsOnBoundary.end(); ++piter) {
     91      const Vector &point = piter->second->getPosition();
     92      // add data to the primitive
     93      geo.appendVertex(QVector3D(point[0], point[1], point[2]));
     94      Vector normalvector;
     95      for (LineMap::const_iterator lineiter = piter->second->lines.begin();
     96          lineiter != piter->second->lines.end(); ++lineiter)
     97        for (TriangleMap::const_iterator triangleiter = lineiter->second->triangles.begin();
     98            triangleiter != lineiter->second->triangles.end(); ++triangleiter)
     99          normalvector +=
     100              triangleiter->second->NormalVector;
     101      normalvector.Normalize();
     102      geo.appendNormal(QVector3D(normalvector[0], normalvector[1], normalvector[2]));
     103      geo.appendColor(QColor(1, 1, 1, 1));
     104      geo.appendTexCoord(QVector2D(0, 0));
     105      indices.insert( std::make_pair( piter->second->getNr(), index++));
     106    }
     107
     108    // Fill the tesselated triangles into the geometry.
     109    for (TriangleMap::const_iterator runner = T.TrianglesOnBoundary.begin();
     110        runner != T.TrianglesOnBoundary.end(); runner++) {
     111      int v[3];
     112      for (size_t i=0; i<3; ++i)
     113        v[i] = runner->second->endpoints[i]->getNr();
     114
     115      // Sort the vertices so the triangle is clockwise (relative to the normal vector).
     116      Vector cross = T.PointsOnBoundary[v[1]]->getPosition() - T.PointsOnBoundary[v[0]]->getPosition();
     117      cross.VectorProduct(T.PointsOnBoundary[v[2]]->getPosition() - T.PointsOnBoundary[v[0]]->getPosition());
     118      if (cross.ScalarProduct(runner->second->NormalVector) > 0)
     119        geo.appendIndices(indices[v[0]], indices[v[1]], indices[v[2]]);
     120      else
     121        geo.appendIndices(indices[v[0]], indices[v[2]], indices[v[1]]);
     122    }
     123  }
     124
     125  // Build a mesh from the geometry.
     126  QGLBuilder builder;
     127  builder.addTriangles(geo);
     128  QGLSceneNode *mesh = builder.finalizedSceneNode();
     129  return mesh;
     130}
     131
     132GLMoleculeObject_molecule::GLMoleculeObject_molecule(QObject *parent, const molecule *molref) :
     133  GLMoleculeObject(createMoleculeMesh(molref, parent), parent),
    60134  Observer(std::string("GLMoleculeObject_molecule")+toString(molref->getId())),
    61   _molecule(molref)
     135  isBoundingBoxUptodate(true),
     136  isSignedOn(false),
     137  _molecule(molref),
     138  TesselationHullUptodate(true),
     139  hoverAtom(NULL)
    62140{
    63141  // sign on as observer (obtain non-const instance before)
     142  _molecule->signOn(this, molecule::AtomInserted);
     143  _molecule->signOn(this, molecule::AtomRemoved);
     144  _molecule->signOn(this, molecule::AtomMoved);
     145  isSignedOn = true;
    64146  /*molref->signOn(this, AtomObservable::IndexChanged);
    65147  molref->signOn(this, AtomObservable::PositionChanged);
     
    69151  World::getInstance().signOn(this, World::SelectionChanged);
    70152  updateBoundingBox();
     153
     154  // initially, atoms and bonds should be visible
     155  m_visible = false;
     156
     157  init();
     158
     159  connect (this, SIGNAL(hoverChanged(GLMoleculeObject *)), this, SLOT(hoverChangedSignalled(GLMoleculeObject *)));
     160  connect (this, SIGNAL(hoverChanged(GLMoleculeObject *)), this, SIGNAL(changed()));
     161
     162  connect( this, SIGNAL(clicked()), this, SLOT(wasClicked()));
     163}
     164
     165GLMoleculeObject_molecule::GLMoleculeObject_molecule(QGLSceneNode *mesh[], QObject *parent, const molecule *molref) :
     166  GLMoleculeObject(mesh, parent),
     167  Observer(std::string("GLMoleculeObject_molecule")+toString(molref->getId())),
     168  isBoundingBoxUptodate(true),
     169  isSignedOn(false),
     170  _molecule(molref),
     171  TesselationHullUptodate(true),
     172  hoverAtom(NULL)
     173{
     174  // sign on as observer (obtain non-const instance before)
     175  _molecule->signOn(this, molecule::AtomInserted);
     176  _molecule->signOn(this, molecule::AtomRemoved);
     177  _molecule->signOn(this, molecule::AtomMoved);
     178  isSignedOn = true;
     179  /*molref->signOn(this, AtomObservable::IndexChanged);
     180  molref->signOn(this, AtomObservable::PositionChanged);
     181  molref->signOn(this, AtomObservable::ElementChanged);
     182  molref->signOn(this, AtomObservable::BondsAdded);*/
     183  setMaterial(getMaterial(1));
     184  World::getInstance().signOn(this, World::SelectionChanged);
     185  updateBoundingBox();
     186
     187  // initially, atoms and bonds should be visible
     188  m_visible = false;
     189
     190  init();
     191
     192  connect (this, SIGNAL(hoverChanged(GLMoleculeObject *)), this, SLOT(hoverChangedSignalled(GLMoleculeObject *)));
     193  connect (this, SIGNAL(hoverChanged(GLMoleculeObject *)), this, SIGNAL(changed()));
     194
     195  connect( this, SIGNAL(clicked()), this, SLOT(wasClicked()));
    71196}
    72197
    73198GLMoleculeObject_molecule::~GLMoleculeObject_molecule()
    74199{
     200  if (isSignedOn) {
     201    _molecule->signOff(this, molecule::AtomInserted);
     202    _molecule->signOff(this, molecule::AtomRemoved);
     203    _molecule->signOff(this, molecule::AtomMoved);
     204  }
    75205  /*_atom->signOff(this, AtomObservable::IndexChanged);
    76206  _atom->signOff(this, AtomObservable::PositionChanged);
     
    80210}
    81211
     212/** Initialise the WorldScene with molecules and atoms from World.
     213 *
     214 */
     215void GLMoleculeObject_molecule::init()
     216{
     217  if (_molecule->begin() != _molecule->end()) {
     218    int atomicid = -1;
     219    for (molecule::const_iterator atomiter = _molecule->begin();
     220        atomiter != _molecule->end();
     221        atomiter++) {
     222      // create atom objects in scene
     223      atomicid = (*atomiter)->getId();
     224      atomInserted(atomicid);
     225
     226      // create bond objects in scene
     227      const BondList &bondlist = (*atomiter)->getListOfBonds();
     228      for (BondList::const_iterator bonditer = bondlist.begin();
     229          bonditer != bondlist.end();
     230          ++bonditer) {
     231        const bond::ptr _bond = *bonditer;
     232        const GLMoleculeObject_bond::SideOfBond side = (_bond->leftatom == *atomiter) ?
     233            GLMoleculeObject_bond::left : GLMoleculeObject_bond::right;
     234        bondInserted(_bond, side);
     235      }
     236    }
     237    // set id to one of the atom's as either mol or atoms is present at the same time
     238    setObjectId(atomicid);
     239  }
     240}
     241
     242void GLMoleculeObject_molecule::addAtomBonds(
     243    const bond::ptr &_bond,
     244    const GLMoleculeObject_bond::SideOfBond _side
     245    )
     246{
     247  bool bond_present = false;
     248  const BondIds ids = getBondIds(_bond, _side);
     249  // check whether bond is not present already
     250  bond_present = BondsinSceneMap.count(ids);
     251  if (!bond_present)
     252    bondInserted(_bond, _side);
     253  else {
     254    BondsinSceneMap[ids]->resetPosition();
     255    BondsinSceneMap[ids]->resetWidth();
     256  }
     257}
     258
     259void GLMoleculeObject_molecule::addAtomBonds(
     260    const atom *_atom)
     261{
     262  const bool atom_present = AtomsinSceneMap.count(_atom->getId());
     263  const BondList &bondlist = _atom->getListOfBonds();
     264  for (BondList::const_iterator bonditer = bondlist.begin();
     265      (bonditer != bondlist.end()) && atom_present;
     266      ++bonditer) {
     267    const bond::ptr _bond = *bonditer;
     268    // check if OtherAtom's sphere is already present
     269    const atom *OtherAtom = _bond->GetOtherAtom(_atom);
     270    const bool otheratom_present = AtomsinSceneMap.count(OtherAtom->getId());
     271    if (otheratom_present && atom_present) {
     272      const GLMoleculeObject_bond::SideOfBond side = (_bond->leftatom == _atom) ?
     273          GLMoleculeObject_bond::left : GLMoleculeObject_bond::right;
     274      const GLMoleculeObject_bond::SideOfBond otherside = (_bond->leftatom == _atom) ?
     275          GLMoleculeObject_bond::right : GLMoleculeObject_bond::left;
     276      addAtomBonds(_bond, side);
     277      addAtomBonds(_bond, otherside);
     278    }
     279  }
     280}
     281
     282void GLMoleculeObject_molecule::reinit()
     283{
     284  if (_molecule->getAtomCount() > 0) {
     285    for (molecule::const_iterator atomiter = _molecule->begin();
     286        atomiter != _molecule->end();
     287        atomiter++) {
     288      // check whether atom already exists
     289      const atomId_t atomid = (*atomiter)->getId();
     290      const bool atom_present = AtomsinSceneMap.count(atomid);
     291      if (!atom_present)
     292        atomInserted((*atomiter)->getId());
     293      else
     294        AtomsinSceneMap[atomid]->resetPosition();
     295
     296
     297      // create bond objects in scene
     298      addAtomBonds(*atomiter);
     299    }
     300  }
     301}
     302
    82303void GLMoleculeObject_molecule::updateBoundingBox()
    83304{
     305  isBoundingBoxUptodate = true;
    84306  Shape shape = _molecule->getBoundingSphere();
    85307  Vector v = shape.getCenter();
     
    97319
    98320void GLMoleculeObject_molecule::subjectKilled(Observable *publisher)
    99 {}
     321{
     322  isSignedOn = false;
     323}
    100324
    101325void GLMoleculeObject_molecule::recieveNotification(Observable *publisher, Notification_ptr notification)
     
    108332          << notification->getChannelNo() << ".";
    109333#endif
     334    switch (notification->getChannelNo()) {
     335      case molecule::AtomInserted:
     336      {
     337        const atomId_t _id = _molecule->lastChanged()->getId();
     338  #ifdef LOG_OBSERVER
     339        observerLog().addMessage() << "++ Observer " << observerLog().getName(static_cast<Observer *>(this)) << " received notification that atom "+toString(_id)+" has been inserted.";
     340  #endif
     341        TesselationHullUptodate = false;
     342        isBoundingBoxUptodate = false;
     343        atomInserted(_id);
     344        break;
     345      }
     346      case World::AtomRemoved:
     347      {
     348        const atomId_t _id = _molecule->lastChanged()->getId();
     349  #ifdef LOG_OBSERVER
     350        observerLog().addMessage() << "++ Observer " << observerLog().getName(static_cast<Observer *>(this)) << " received notification that atom "+toString(_id)+" has been removed.";
     351  #endif
     352        TesselationHullUptodate = false;
     353        isBoundingBoxUptodate = false;
     354        atomRemoved(_id);
     355        break;
     356      }
     357      case molecule::AtomMoved:
     358      {
     359  #ifdef LOG_OBSERVER
     360        const atomId_t _id = _molecule->lastChanged()->getId();
     361        observerLog().addMessage() << "++ Observer " << observerLog().getName(static_cast<Observer *>(this)) << " received notification that atom "+toString(_id)+" has been inserted.";
     362  #endif
     363        TesselationHullUptodate = false;
     364        isBoundingBoxUptodate = false;
     365        break;
     366      }
     367      default:
     368        break;
     369    }
    110370  }else{
    111371    // notification from world
     
    125385}
    126386
     387void GLMoleculeObject_molecule::initialize(QGLView *view, QGLPainter *painter)
     388{
     389  // Initialize all of the mesh objects that we have as children.
     390  if (m_visible) {
     391    GLMoleculeObject::initialize(view, painter);
     392  } else {
     393   foreach (QObject *obj, children()) {
     394     GLMoleculeObject *meshobj = qobject_cast<GLMoleculeObject *>(obj);
     395       if (meshobj)
     396         meshobj->initialize(view, painter);
     397   }
     398  }
     399}
     400
     401void GLMoleculeObject_molecule::draw(QGLPainter *painter, const QVector4D &cameraPlane)
     402{
     403  // draw either molecule's mesh or all atoms and bonds
     404  if (m_visible) {
     405    updateTesselationHull();
     406
     407    painter->modelViewMatrix().push();
     408
     409    // Apply the material and effect to the painter.
     410    QGLMaterial *material;
     411    if (m_hovering)
     412        material = m_hoverMaterial;
     413    else if (m_selected)
     414        material = m_selectionMaterial;
     415    else
     416        material = m_material;
     417
     418    ASSERT(material, "GLMoleculeObject::draw: chosen material is NULL");
     419
     420    painter->setColor(material->diffuseColor());
     421    painter->setFaceMaterial(QGL::AllFaces, material);
     422    if (m_effect)
     423        painter->setUserEffect(m_effect);
     424    else
     425        painter->setStandardEffect(QGL::LitMaterial);
     426
     427    // Mark the object for object picking purposes.
     428    int prevObjectId = painter->objectPickId();
     429    if (m_objectId != -1)
     430        painter->setObjectPickId(m_objectId);
     431
     432    m_mesh[0]->draw(painter);
     433
     434    // Turn off the user effect, if present.
     435    if (m_effect)
     436        painter->setStandardEffect(QGL::LitMaterial);
     437
     438    // Revert to the previous object identifier.
     439    painter->setObjectPickId(prevObjectId);
     440
     441    // Restore the modelview matrix.
     442    painter->modelViewMatrix().pop();
     443
     444    //    GLMoleculeObject::draw(painter, cameraPlane);
     445  } else {
     446    // Draw all of the mesh objects that we have as children.
     447    foreach (QObject *obj, children()) {
     448      GLMoleculeObject *meshobj = qobject_cast<GLMoleculeObject *>(obj);
     449      if (meshobj)
     450        meshobj->draw(painter, cameraPlane);
     451    }
     452
     453    // update bounding box prior to selection
     454    if (!isBoundingBoxUptodate)
     455      updateBoundingBox();
     456
     457    painter->modelViewMatrix().push();
     458    painter->modelViewMatrix().translate(m_position);
     459    if ((m_scaleX != 1.0f) || (m_scaleY != 1.0f) || (m_scaleZ != 1.0f))
     460      painter->modelViewMatrix().scale(m_scaleX, m_scaleY, m_scaleZ);
     461    if (m_rotationAngle != 0.0f)
     462      painter->modelViewMatrix().rotate(m_rotationAngle, m_rotationVector);
     463
     464    // Draw a box around the mesh, if selected.
     465    if (m_selected)
     466      drawSelectionBox(painter);
     467
     468    // Restore the modelview matrix.
     469    painter->modelViewMatrix().pop();
     470  }
     471}
     472
     473/** Adds an atom of this molecule to the scene.
     474 *
     475 * @param _atom atom to add
     476 */
     477void GLMoleculeObject_molecule::atomInserted(const atomicNumber_t _id)
     478{
     479  LOG(3, "INFO: GLWorldScene: Received signal atomInserted for atom "+toString(_id)+".");
     480  GLMoleculeObject_atom *atomObject = new GLMoleculeObject_atom(GLMoleculeObject::meshSphere, this, _id);
     481  AtomNodeMap::iterator iter = AtomsinSceneMap.find(_id);
     482  ASSERT(iter == AtomsinSceneMap.end(),
     483      "GLWorldScene::atomAdded() - same atom with id "+toString(_id)+" added again.");
     484  AtomsinSceneMap.insert( make_pair(_id, atomObject) );
     485
     486  qRegisterMetaType<atomId_t>("atomId_t");
     487  qRegisterMetaType<bond::ptr>("bond::ptr");
     488  qRegisterMetaType<GLMoleculeObject_bond::SideOfBond>("GLMoleculeObject_bond::SideOfBond");
     489  connect (atomObject, SIGNAL(clicked(atomId_t)), this, SIGNAL(atomClicked(atomId_t)));
     490  connect (atomObject, SIGNAL(changed()), this, SIGNAL(changed()));
     491  connect (atomObject, SIGNAL(hoverChanged(GLMoleculeObject *)), this, SIGNAL(changed()));
     492  connect (atomObject, SIGNAL(hoverChanged(GLMoleculeObject *)), this, SLOT(hoverChangedSignalled(GLMoleculeObject *)));
     493  connect (atomObject, SIGNAL(selectionChanged()), this, SIGNAL(changed()));
     494  connect (atomObject, SIGNAL(BondsInserted(const bond::ptr , const GLMoleculeObject_bond::SideOfBond)), this, SLOT(bondInserted(const bond::ptr , const GLMoleculeObject_bond::SideOfBond)));
     495  connect (atomObject, SIGNAL(indexChanged(GLMoleculeObject_atom*, int, int)), this, SIGNAL(changeAtomId(GLMoleculeObject_atom*, int, int)));
     496
     497  isBoundingBoxUptodate = false;
     498
     499  if (m_objectId  == -1)
     500    setObjectId(_id);
     501
     502  // add all bonds
     503  const atom *Walker = World::getInstance().getAtom(AtomById(_id));
     504  addAtomBonds(Walker);
     505
     506  emit changeOccured();
     507}
     508
     509/** Removes an atom of this molecule from the scene.
     510 *
     511 * We just the id as the atom might have already been destroyed.
     512 *
     513 * @param _id id of atom to remove
     514 */
     515void GLMoleculeObject_molecule::atomRemoved(const atomicNumber_t _id)
     516{
     517  LOG(3, "INFO: GLWorldScene: Received signal atomRemoved for atom "+toString(_id)+".");
     518  // bonds are removed by signal coming from ~bond
     519
     520  if (m_objectId == _id)
     521    setObjectId(-1);
     522
     523  // remove atoms
     524  AtomNodeMap::iterator iter = AtomsinSceneMap.find(_id);
     525  ASSERT(iter != AtomsinSceneMap.end(),
     526      "GLWorldScene::atomRemoved() - atom "+toString(_id)+" not on display.");
     527  GLMoleculeObject_atom *atomObject = iter->second;
     528  atomObject->disconnect();
     529  AtomsinSceneMap.erase(iter);
     530  delete atomObject;
     531
     532  isBoundingBoxUptodate = false;
     533
     534  emit changeOccured();
     535}
     536
     537void GLMoleculeObject_molecule::hoverChangedSignalled(GLMoleculeObject *ob)
     538{
     539  // Find the atom, ob corresponds to.
     540  hoverAtom = NULL;
     541  GLMoleculeObject_atom *atomObject = dynamic_cast<GLMoleculeObject_atom *>(ob);
     542  if (atomObject){
     543    for (AtomNodeMap::iterator iter = AtomsinSceneMap.begin();iter != AtomsinSceneMap.end(); ++ iter){
     544      if (iter->second == atomObject)
     545        hoverAtom = World::getInstance().getAtom(AtomById(iter->first));
     546    }
     547
     548    // Propagate signal.
     549    emit hoverChanged(*hoverAtom);
     550  } else {
     551    // Find the atom, ob corresponds to.
     552    GLMoleculeObject_molecule *moleculeObject = dynamic_cast<GLMoleculeObject_molecule *>(ob);
     553    if (moleculeObject == this){
     554      // Propagate signal.
     555      emit hoverChanged(*_molecule, 0);
     556    }
     557  }
     558}
     559
     560
     561/** Helper function to get bond ids in the correct order for BondNodeMap.
     562 *
     563 * \return pair of ids in correct order.
     564 */
     565GLMoleculeObject_molecule::BondIds GLMoleculeObject_molecule::getBondIds(
     566    const bond::ptr _bond,
     567    const enum GLMoleculeObject_bond::SideOfBond _side)
     568{
     569  BondIds ids;
     570  switch (_side) {
     571    case GLMoleculeObject_bond::left:
     572      ids = std::make_pair(_bond->leftatom->getId(), _bond->rightatom->getId());
     573      break;
     574    case GLMoleculeObject_bond::right:
     575      ids = std::make_pair(_bond->rightatom->getId(), _bond->leftatom->getId());
     576      break;
     577  }
     578  return ids;
     579}
     580
     581/** Adds a bond to the scene.
     582 *
     583 * @param _bond bond to add
     584 * @param side which side of the bond (left or right)
     585 */
     586void GLMoleculeObject_molecule::bondInserted(const bond::ptr _bond, const enum GLMoleculeObject_bond::SideOfBond _side)
     587{
     588  LOG(3, "INFO: GLWorldScene::bondInserted() - Adding bond "+toString(*_bond)+".");
     589  //LOG(4, "INFO: Currently present bonds " << BondsinSceneMap << ".");
     590
     591  const BondIds ids = getBondIds(_bond, _side);
     592  BondNodeMap::iterator iter = BondsinSceneMap.find(ids);
     593  if (iter == BondsinSceneMap.end()) {
     594    GLMoleculeObject_bond * bondObject =
     595        new GLMoleculeObject_bond(GLMoleculeObject::meshCylinder, this, _bond, _side);
     596    connect (
     597        bondObject, SIGNAL(BondRemoved(const atomId_t, const atomId_t)),
     598        this, SLOT(bondRemoved(const atomId_t, const atomId_t)));
     599    connect (bondObject, SIGNAL(changed()), this, SIGNAL(changed()));
     600    BondsinSceneMap.insert( make_pair(ids, bondObject) );
     601  //    BondIdsinSceneMap.insert( Leftids );
     602  } else {
     603    iter->second->resetPosition();
     604    iter->second->resetWidth();
     605  }
     606  emit changeOccured();
     607}
     608
     609/** Removes a bond from the scene.
     610 *
     611 * @param _bond bond to remove
     612 */
     613void GLMoleculeObject_molecule::bondRemoved(const atomId_t leftnr, const atomId_t rightnr)
     614{
     615  LOG(3, "INFO: GLWorldScene::bondRemoved() - Removing bond between "+toString(leftnr)+" and "+toString(rightnr)+".");
     616  {
     617    // left bond
     618    const BondIds Leftids( make_pair(leftnr, rightnr) );
     619    BondNodeMap::iterator leftiter = BondsinSceneMap.find( Leftids );
     620    ASSERT(leftiter != BondsinSceneMap.end(),
     621        "GLWorldScene::bondRemoved() - bond "+toString(leftnr)+"-"
     622        +toString(rightnr)+" not on display.");
     623    GLMoleculeObject_bond *bondObject = leftiter->second;
     624    bondObject->disconnect();
     625    BondsinSceneMap.erase(leftiter);
     626    delete bondObject; // is done by signal from bond itself
     627    //LOG(4, "INFO: Still present bonds " << BondsinSceneMap << ".");
     628  }
     629
     630  emit changeOccured();
     631}
     632
     633void GLMoleculeObject_molecule::setVisible(bool value)
     634{
     635  // first update the mesh if we are going to be visible now
     636  if (value)
     637    updateTesselationHull();
     638  // then emit onward
     639  GLMoleculeObject::setVisible(value);
     640}
     641
     642void GLMoleculeObject_molecule::updateTesselationHull()
     643{
     644  if (!TesselationHullUptodate) {
     645    updateMesh(createMoleculeMesh(_molecule, parent()));
     646    TesselationHullUptodate = true;
     647  }
     648}
     649
     650std::ostream &operator<<(std::ostream &ost, const GLMoleculeObject_molecule::BondIds &t)
     651{
     652  ost << t.first << "," << t.second;
     653  return ost;
     654}
     655
     656void GLMoleculeObject_molecule::wasClicked()
     657{
     658  LOG(4, "INFO: GLMoleculeObject_molecule: atom " << _molecule->getId() << " has been clicked");
     659  emit moleculeClicked(_molecule->getId());
     660}
  • src/UIElements/Views/Qt4/Qt3D/GLMoleculeObject_molecule.hpp

    r7b38d3 r0ac85c3  
    2222class atom;
    2323class bond;
     24class GLMoleculeObject_atom;
     25class GLWorldScene;
    2426class molecule;
    2527
     
    2830  Q_OBJECT
    2931public:
     32  GLMoleculeObject_molecule(QObject *parent, const molecule *molref);
    3033  GLMoleculeObject_molecule(QGLSceneNode *mesh[], QObject *parent, const molecule *molref);
    3134  virtual ~GLMoleculeObject_molecule();
     
    3841  void recieveNotification(Observable *publisher, Notification_ptr notification);
    3942
     43  void initialize(QGLView *view, QGLPainter *painter);
     44  void draw(QGLPainter *painter, const QVector4D &cameraPlane);
     45
     46  typedef std::pair< atomId_t, atomId_t> BondIds;
     47  friend std::ostream &operator<<(std::ostream &ost, const BondIds &t);
     48
     49  static BondIds getBondIds(
     50      const bond::ptr _bond,
     51      const enum GLMoleculeObject_bond::SideOfBond side);
     52
     53  void selected(const bool _isSelected)
     54  { isSelected = _isSelected; }
     55
     56signals:
     57  void changed();
     58  void changeOccured();
     59  void hoverChanged(const atom&);
     60  void hoverChanged(const molecule&, int);
     61  void atomClicked(atomId_t no);
     62  void moleculeClicked(moleculeId_t no);
     63  void changeAtomId(GLMoleculeObject_atom *, int, int);
     64
     65private slots:
     66  //!> grant GLWorldScene access to private slots
     67  friend class GLWorldScene;
     68
     69  void wasClicked();
     70  void atomInserted(const atomicNumber_t _id);
     71  void atomRemoved(const atomicNumber_t _id);
     72  void bondInserted(const bond::ptr _bond, const GLMoleculeObject_bond::SideOfBond side);
     73  void bondRemoved(const atomId_t leftnr, const atomId_t rightnr);
     74  void hoverChangedSignalled(GLMoleculeObject *ob);
     75
     76  void setVisible(bool value);
     77
    4078private:
     79  void init();
     80  void reinit();
     81
     82  void addAtomBonds(
     83      const bond::ptr &_bond,
     84      const GLMoleculeObject_bond::SideOfBond _side
     85      );
     86  void addAtomBonds(const atom *_atom);
     87
     88  void updateTesselationHull();
     89
     90  //!> states whether selection box is additionally drawn or not
     91  bool isSelected;
     92  bool isBoundingBoxUptodate;
     93
     94  //!> whether we are signed on to the associated molecule
     95  bool isSignedOn;
    4196
    4297  const molecule *_molecule;
     98
     99  bool TesselationHullUptodate;
     100
     101  typedef std::map< atomId_t, GLMoleculeObject_atom* > AtomNodeMap;
     102  typedef std::map< BondIds , GLMoleculeObject_bond* > BondNodeMap;
     103  AtomNodeMap AtomsinSceneMap;
     104  BondNodeMap BondsinSceneMap;
     105
     106  const atom *hoverAtom;
    43107};
    44108
     109std::ostream &operator<<(std::ostream &ost, const GLMoleculeObject_molecule::BondIds &t);
    45110
    46111
  • src/UIElements/Views/Qt4/Qt3D/GLMoleculeObject_shape.cpp

    r7b38d3 r0ac85c3  
    6363typedef QGLSceneNode *MeshList[GLMoleculeObject::DETAILTYPES_MAX];
    6464
    65 QGLSceneNode *createShapeMesh(Shape &shape, QObject *parent)
     65static QGLSceneNode *createShapeMesh(Shape &shape, QObject *parent)
    6666{
    6767  size_t NumPointsonSurface = 200;
  • src/UIElements/Views/Qt4/Qt3D/GLWorldScene.cpp

    r7b38d3 r0ac85c3  
    6060#include "Bond/bond.hpp"
    6161#include "Descriptors/AtomIdDescriptor.hpp"
     62#include "Descriptors/MoleculeIdDescriptor.hpp"
    6263#include "Helpers/helpers.hpp"
    6364#include "Shapes/ShapeRegistry.hpp"
     
    6970using namespace MoleCuilder;
    7071
    71 std::ostream &operator<<(std::ostream &ost, const GLWorldScene::BondIds &t)
    72 {
    73   ost << t.first << "," << t.second;
    74   return ost;
    75 }
    76 
    7772GLWorldScene::GLWorldScene(QObject *parent)
    78    : QObject(parent),
    79      hoverAtom(NULL)
     73   : QObject(parent)
    8074{
    8175  int sphereDetails[] = {5, 3, 2, 0};
     
    8377  for (int i=0;i<GLMoleculeObject::DETAILTYPES_MAX;i++){
    8478    QGLBuilder emptyBuilder;
    85     meshEmpty[i] = emptyBuilder.finalizedSceneNode();
     79    GLMoleculeObject::meshEmpty[i] = emptyBuilder.finalizedSceneNode();
    8680    QGLBuilder sphereBuilder;
    8781    sphereBuilder << QGLSphere(2.0, sphereDetails[i]);
    88     meshSphere[i] = sphereBuilder.finalizedSceneNode();
    89     meshSphere[i]->setOption(QGLSceneNode::CullBoundingBox, true);
     82    GLMoleculeObject::meshSphere[i] = sphereBuilder.finalizedSceneNode();
     83    GLMoleculeObject::meshSphere[i]->setOption(QGLSceneNode::CullBoundingBox, true);
    9084    QGLBuilder cylinderBuilder;
    9185    cylinderBuilder << QGLCylinder(.25,.25,1.0,cylinderDetails[i]);
    92     meshCylinder[i] = cylinderBuilder.finalizedSceneNode();
    93     meshCylinder[i]->setOption(QGLSceneNode::CullBoundingBox, true);
     86    GLMoleculeObject::meshCylinder[i] = cylinderBuilder.finalizedSceneNode();
     87    GLMoleculeObject::meshCylinder[i]->setOption(QGLSceneNode::CullBoundingBox, true);
    9488  }
    9589
    9690  connect(this, SIGNAL(updated()), this, SLOT(update()));
     91
    9792
    9893  setSelectionMode(SelectAtom);
     
    112107void GLWorldScene::init()
    113108{
    114   const std::vector<atom*> &atoms = World::getInstance().getAllAtoms();
    115 
    116   if (atoms.size() > 0) {
    117     for (std::vector<atom*>::const_iterator atomiter = atoms.begin();
    118         atomiter != atoms.end();
    119         atomiter++) {
    120       // create atom objects in scene
    121       atomInserted((*atomiter)->getId());
    122 
    123       // create bond objects in scene
    124       const BondList &bondlist = (*atomiter)->getListOfBonds();
    125       for (BondList::const_iterator bonditer = bondlist.begin();
    126           bonditer != bondlist.end();
    127           ++bonditer) {
    128         const bond::ptr _bond = *bonditer;
    129         const GLMoleculeObject_bond::SideOfBond side = (_bond->leftatom == *atomiter) ?
    130             GLMoleculeObject_bond::left : GLMoleculeObject_bond::right;
    131         bondInserted(_bond, side);
    132       }
    133     }
     109  const std::vector<molecule *> &molecules = World::getInstance().getAllMolecules();
     110
     111  for (std::vector<molecule*>::const_iterator moliter = molecules.begin();
     112      moliter != molecules.end();
     113      moliter++) {
     114    // create molecule objects in scene
     115    moleculeInserted(*moliter);
    134116  }
    135117}
     
    143125void GLWorldScene::update()
    144126{
    145   const std::vector<atom*> &atoms = World::getInstance().getAllAtoms();
    146 
    147   if (atoms.size() > 0) {
    148     for (std::vector<atom*>::const_iterator atomiter = atoms.begin();
    149         atomiter != atoms.end();
    150         atomiter++) {
    151       // check whether atom already exists
    152       const atomId_t atomid = (*atomiter)->getId();
    153       const bool atom_present = AtomsinSceneMap.count(atomid);
    154       if (!atom_present)
    155         atomInserted((*atomiter)->getId());
    156       else
    157         AtomsinSceneMap[atomid]->resetPosition();
    158 
    159 
    160       // create bond objects in scene
    161       const BondList &bondlist = (*atomiter)->getListOfBonds();
    162       for (BondList::const_iterator bonditer = bondlist.begin();
    163           bonditer != bondlist.end();
    164           ++bonditer) {
    165         const bond::ptr _bond = *bonditer;
    166         const GLMoleculeObject_bond::SideOfBond side = (_bond->leftatom == *atomiter) ?
    167             GLMoleculeObject_bond::left : GLMoleculeObject_bond::right;
    168         bool bond_present = false;
    169         const BondIds ids = getBondIds(_bond,side);
    170         if (atom_present) {
    171           // check whether bond is not present already
    172           bond_present = BondsinSceneMap.count(ids);
    173         }
    174         if (!bond_present)
    175           bondInserted(_bond, side);
    176         else {
    177           BondsinSceneMap[ids]->resetPosition();
    178           BondsinSceneMap[ids]->resetWidth();
    179         }
    180       }
    181     }
    182   }
    183 }
    184 
    185 /** Adds an atom to the scene.
    186  *
    187  * @param _atom atom to add
    188  */
    189 void GLWorldScene::atomInserted(const atomicNumber_t _id)
    190 {
    191   LOG(3, "INFO: GLWorldScene: Received signal atomInserted for atom "+toString(_id)+".");
    192   GLMoleculeObject_atom *atomObject = new GLMoleculeObject_atom(meshSphere, this, _id);
    193   AtomNodeMap::iterator iter = AtomsinSceneMap.find(_id);
    194   ASSERT(iter == AtomsinSceneMap.end(),
    195       "GLWorldScene::atomAdded() - same atom with id "+toString(_id)+" added again.");
    196   AtomsinSceneMap.insert( make_pair(_id, atomObject) );
    197 
    198   qRegisterMetaType<atomId_t>("atomId_t");
    199   qRegisterMetaType<bond::ptr>("bond::ptr");
    200   qRegisterMetaType<GLMoleculeObject_bond::SideOfBond>("GLMoleculeObject_bond::SideOfBond");
    201   connect (atomObject, SIGNAL(clicked(atomId_t)), this, SLOT(atomClicked(atomId_t)));
    202   connect (atomObject, SIGNAL(changed()), this, SIGNAL(changed()));
    203   connect (atomObject, SIGNAL(hoverChanged(GLMoleculeObject *)), this, SIGNAL(changed()));
    204   connect (atomObject, SIGNAL(hoverChanged(GLMoleculeObject *)), this, SLOT(hoverChangedSignalled(GLMoleculeObject *)));
    205   connect (atomObject, SIGNAL(selectionChanged()), this, SIGNAL(changed()));
    206   connect (atomObject, SIGNAL(BondsInserted(const bond::ptr , const GLMoleculeObject_bond::SideOfBond)), this, SLOT(bondInserted(const bond::ptr , const GLMoleculeObject_bond::SideOfBond)));
    207   connect (atomObject, SIGNAL(indexChanged(GLMoleculeObject_atom*, int, int)), this, SLOT(changeAtomId(GLMoleculeObject_atom*, int, int)));
    208   //bondsChanged(_atom);
    209   emit changeOccured();
    210 }
    211 
    212 /** Removes an atom from the scene.
    213  *
    214  * We just the id as the atom might have already been destroyed.
    215  *
    216  * @param _id id of atom to remove
    217  */
    218 void GLWorldScene::atomRemoved(const atomicNumber_t _id)
    219 {
    220   LOG(3, "INFO: GLWorldScene: Received signal atomRemoved for atom "+toString(_id)+".");
    221   // bonds are removed by signal coming from ~bond
    222   // remove atoms
    223   AtomNodeMap::iterator iter = AtomsinSceneMap.find(_id);
    224   ASSERT(iter != AtomsinSceneMap.end(),
    225       "GLWorldScene::atomRemoved() - atom "+toString(_id)+" not on display.");
    226   GLMoleculeObject_atom *atomObject = iter->second;
    227   atomObject->disconnect();
    228   AtomsinSceneMap.erase(iter);
    229   delete atomObject;
    230   emit changeOccured();
    231 }
    232 
    233 /** ....
    234  *
    235  */
    236 void GLWorldScene::worldSelectionChanged()
    237 {
    238   LOG(3, "INFO: GLWorldScene: Received signal selectionChanged.");
    239 
    240   const std::vector<molecule*> &molecules = World::getInstance().getAllMolecules();
    241 
    242   if (molecules.size() > 0) {
    243     for (std::vector<molecule*>::const_iterator Runner = molecules.begin();
    244         Runner != molecules.end();
    245         Runner++) {
    246 
    247       MoleculeNodeMap::iterator iter = MoleculesinSceneMap.find((*Runner)->getId());
    248       bool isSelected = World::getInstance().isSelected(*Runner);
    249 
    250       // molecule selected but not in scene?
    251       if (isSelected && (iter == MoleculesinSceneMap.end())){
    252         // -> create new mesh
    253         GLMoleculeObject_molecule *molObject = new GLMoleculeObject_molecule(meshEmpty, this, *Runner);
    254         MoleculesinSceneMap.insert( make_pair((*Runner)->getId(), molObject) );
    255         connect (molObject, SIGNAL(changed()), this, SIGNAL(changed()));
    256         connect (molObject, SIGNAL(selectionChanged()), this, SIGNAL(changed()));
    257         connect (molObject, SIGNAL(selectionChanged()), this, SIGNAL(changed()));
    258         emit changed();
    259         emit changeOccured();
    260       }
    261 
    262       // molecule not selected but in scene?
    263       if (!isSelected && (iter != MoleculesinSceneMap.end())){
    264         // -> remove from scene
    265         moleculeRemoved(*Runner);
    266       }
    267 
    268     }
    269   }
    270 }
    271 
    272 /** Removes a molecule from the scene.
    273  *
    274  * @param _molecule molecule to remove
    275  */
    276 void GLWorldScene::moleculeRemoved(const molecule *_molecule)
    277 {
    278   LOG(3, "INFO: GLWorldScene: Received signal moleculeRemoved for molecule "+toString(_molecule->getId())+".");
    279   MoleculeNodeMap::iterator iter = MoleculesinSceneMap.find(_molecule->getId());
    280 
    281   // only remove if the molecule is in the scene
    282   //  (= is selected)
    283   if (iter != MoleculesinSceneMap.end()){
    284     GLMoleculeObject_molecule *molObject = iter->second;
    285     molObject->disconnect();
    286     MoleculesinSceneMap.erase(iter);
    287     delete molObject;
    288     emit changed();
    289     emit changeOccured();
    290   }
    291 }
    292 
    293 /** Helper function to get bond ids in the correct order for BondNodeMap.
    294  *
    295  * \return pair of ids in correct order.
    296  */
    297 GLWorldScene::BondIds GLWorldScene::getBondIds(
    298     const bond::ptr _bond,
    299     const enum GLMoleculeObject_bond::SideOfBond _side) const
    300 {
    301   BondIds ids;
    302   switch (_side) {
    303     case GLMoleculeObject_bond::left:
    304       ids = std::make_pair(_bond->leftatom->getId(), _bond->rightatom->getId());
    305       break;
    306     case GLMoleculeObject_bond::right:
    307       ids = std::make_pair(_bond->rightatom->getId(), _bond->leftatom->getId());
    308       break;
    309   }
    310   return ids;
    311 }
    312 
    313 /** Adds a bond to the scene.
    314  *
    315  * @param _bond bond to add
    316  * @param side which side of the bond (left or right)
    317  */
    318 void GLWorldScene::bondInserted(const bond::ptr _bond, const enum GLMoleculeObject_bond::SideOfBond _side)
    319 {
    320   LOG(3, "INFO: GLWorldScene::bondInserted() - Adding bond "+toString(*_bond)+".");
    321   //LOG(4, "INFO: Currently present bonds " << BondsinSceneMap << ".");
    322 
    323   const BondIds ids = getBondIds(_bond, _side);
    324   BondNodeMap::iterator iter = BondsinSceneMap.find(ids);
    325   if (iter == BondsinSceneMap.end()) {
    326     GLMoleculeObject_bond * bondObject =
    327         new GLMoleculeObject_bond(meshCylinder, this, _bond, _side);
    328     connect (
    329         bondObject, SIGNAL(BondRemoved(const atomId_t, const atomId_t)),
    330         this, SLOT(bondRemoved(const atomId_t, const atomId_t)));
    331     connect (bondObject, SIGNAL(changed()), this, SIGNAL(changed()));
    332     BondsinSceneMap.insert( make_pair(ids, bondObject) );
    333   //    BondIdsinSceneMap.insert( Leftids );
    334   } else {
    335     iter->second->resetPosition();
    336     iter->second->resetWidth();
    337   }
    338   emit changeOccured();
    339 }
    340 
    341 /** Removes a bond from the scene.
    342  *
    343  * @param _bond bond to remove
    344  */
    345 void GLWorldScene::bondRemoved(const atomId_t leftnr, const atomId_t rightnr)
    346 {
    347   LOG(3, "INFO: GLWorldScene::bondRemoved() - Removing bond between "+toString(leftnr)+" and "+toString(rightnr)+".");
    348   {
    349     // left bond
    350     const BondIds Leftids( make_pair(leftnr, rightnr) );
    351     BondNodeMap::iterator leftiter = BondsinSceneMap.find( Leftids );
    352     ASSERT(leftiter != BondsinSceneMap.end(),
    353         "GLWorldScene::bondRemoved() - bond "+toString(leftnr)+"-"
    354         +toString(rightnr)+" not on display.");
    355     GLMoleculeObject_bond *bondObject = leftiter->second;
    356     BondsinSceneMap.erase(leftiter);
    357     delete bondObject; // is done by signal from bond itself
    358     //LOG(4, "INFO: Still present bonds " << BondsinSceneMap << ".");
    359   }
    360 
    361   emit changeOccured();
    362 }
    363 
    364 /** Adds a shape to the scene.
    365  *
    366  * uses ShapeRegistry::lastChanged()
    367  *
    368  */
    369 void GLWorldScene::addShape()
    370 {
    371   Shape &shape = *ShapeRegistry::getInstance().lastChanged();
    372   GLMoleculeObject_shape *shapeObject = new GLMoleculeObject_shape(shape, this);
    373   ShapeNodeMap::iterator iter = ShapesinSceneMap.find(shape.getName());
    374   ASSERT(iter == ShapesinSceneMap.end(),
    375       "GLWorldScene::addShape() - same shape "+shape.getName()+" added again.");
    376   ShapesinSceneMap.insert( make_pair(shape.getName(), shapeObject) );
    377 }
    378 
    379 void GLWorldScene::removeShape()
    380 {
    381   Shape &shape = *ShapeRegistry::getInstance().lastChanged();
    382   ShapeNodeMap::iterator iter = ShapesinSceneMap.find(shape.getName());
    383   ASSERT(iter != ShapesinSceneMap.end(),
    384       "GLWorldScene::removeShape() - shape "+shape.getName()+" not in scene.");
    385   ShapesinSceneMap.erase(iter);
    386   delete(iter->second);
    387 }
    388 
    389 void GLWorldScene::updateSelectedShapes()
    390 {
    391   foreach (QObject *obj, children()) {
    392     GLMoleculeObject_shape *shapeobj = qobject_cast<GLMoleculeObject_shape *>(obj);
    393       if (shapeobj){
    394         shapeobj->enable(ShapeRegistry::getInstance().isSelected(shapeobj->getShape()));
    395       }
    396   }
    397 }
    398 
    399 void GLWorldScene::initialize(QGLView *view, QGLPainter *painter) const
    400 {
    401   // Initialize all of the mesh objects that we have as children.
    402    foreach (QObject *obj, children()) {
    403      GLMoleculeObject *meshobj = qobject_cast<GLMoleculeObject *>(obj);
    404        if (meshobj)
    405          meshobj->initialize(view, painter);
    406    }
    407 }
    408 
    409 void GLWorldScene::draw(QGLPainter *painter, const QVector4D &cameraPlane) const
    410 {
    411    // Draw all of the mesh objects that we have as children.
    412    foreach (QObject *obj, children()) {
    413      GLMoleculeObject *meshobj = qobject_cast<GLMoleculeObject *>(obj);
    414        if (meshobj)
    415          meshobj->draw(painter, cameraPlane);
    416    }
     127  const std::vector<molecule *> &molecules = World::getInstance().getAllMolecules();
     128
     129  for (std::vector<molecule*>::const_iterator moliter = molecules.begin();
     130      moliter != molecules.end();
     131      moliter++) {
     132    // check whether molecule already exists
     133    const moleculeId_t molid = (*moliter)->getId();
     134    const bool mol_present = MoleculesinSceneMap.count(molid);
     135    if (!mol_present)
     136      moleculeInserted(*moliter);
     137  }
    417138}
    418139
    419140void GLWorldScene::atomClicked(atomId_t no)
    420141{
    421    LOG(3, "INFO: GLWorldScene - atom " << no << " has been clicked.");
     142   LOG(3, "INFO: GLMoleculeObject_molecule - atom " << no << " has been clicked.");
    422143   const atom *Walker = World::getInstance().getAtom(AtomById(no));
    423144   if (selectionMode == SelectAtom){
     
    429150     const molecule *mol = Walker->getMolecule();
    430151     ASSERT(mol, "Atom without molecule has been clicked.");
     152     molids_t ids(1, mol->getId());
    431153     if (!World::getInstance().isSelected(mol))
    432        SelectionMoleculeById(mol->getId());
     154       SelectionMoleculeById(ids);
    433155     else
    434        SelectionNotMoleculeById(mol->getId());
     156       SelectionNotMoleculeById(ids);
    435157   }
    436158   emit clicked(no);
    437159}
    438160
     161void GLWorldScene::moleculeClicked(moleculeId_t no)
     162{
     163   LOG(3, "INFO: GLMoleculeObject_molecule - mol " << no << " has been clicked.");
     164   const molecule *mol= World::getInstance().getMolecule(MoleculeById(no));
     165   ASSERT(mol, "Atom without molecule has been clicked.");
     166   molids_t ids(1, mol->getId());
     167   if (!World::getInstance().isSelected(mol))
     168     SelectionMoleculeById(ids);
     169   else
     170     SelectionNotMoleculeById(ids);
     171   emit clicked(no);
     172}
     173
     174
     175/** Adds an atom to the scene.
     176 *
     177 * @param _atom atom to add
     178 */
     179void GLWorldScene::atomInserted(const atomId_t _id)
     180{
     181  LOG(3, "INFO: GLWorldScene: Received signal atomInserted for atom "+toString(_id)+".");
     182  // find associated molecule
     183  const moleculeId_t molid = World::getInstance().getAtom(AtomById(_id))->getMolecule()->getId();
     184  MoleculeNodeMap::const_iterator moliter = MoleculesinSceneMap.find(molid );
     185  ASSERT(moliter != MoleculesinSceneMap.end(),
     186      "GLWorldScene::atomAdded() - molecule with id of "+toString(molid)
     187      +" atom with id "+toString(_id)+" is unknown.");
     188  GLMoleculeObject_molecule *molObject = moliter->second;
     189
     190  // add atom to internal list
     191#ifndef NDEBUG
     192  AtomMoleculeMap::const_iterator atomiter = AtomsinSceneMap.find(_id);
     193    ASSERT(atomiter == AtomsinSceneMap.end(),
     194        "GLWorldScene::atomRemoved() - atom "+toString(_id)+" already known.");
     195#endif
     196  AtomsinSceneMap.insert( std::make_pair( _id, molObject ));
     197
     198  // inform its GlMoleculeObject_molecule.
     199  molObject->atomInserted(_id);
     200
     201  // emit change
     202  emit changeOccured();
     203}
     204
     205/** Removes an atom from the scene.
     206 *
     207 * We just the id as the atom might have already been destroyed.
     208 *
     209 * @param _id id of atom to remove
     210 */
     211void GLWorldScene::atomRemoved(const atomId_t _id)
     212{
     213  LOG(3, "INFO: GLWorldScene: Received signal atomRemoved for atom "+toString(_id)+".");
     214  // find associated molecule
     215  AtomMoleculeMap::iterator iter = AtomsinSceneMap.find(_id);
     216  ASSERT(iter != AtomsinSceneMap.end(),
     217      "GLWorldScene::atomRemoved() - atom "+toString(_id)+" not on display.");
     218  GLMoleculeObject_molecule *molObject = iter->second;
     219
     220  // remove from internal list
     221  AtomsinSceneMap.erase(iter);
     222
     223  // inform its GlMoleculeObject_molecule.
     224  molObject->atomRemoved(_id);
     225
     226  // emit change
     227  emit changeOccured();
     228}
     229
     230/** ....
     231 *
     232 */
     233void GLWorldScene::worldSelectionChanged()
     234{
     235  LOG(3, "INFO: GLWorldScene: Received signal selectionChanged.");
     236
     237  const std::vector<molecule*> &molecules = World::getInstance().getAllMolecules();
     238
     239  if (molecules.size() > 0) {
     240    for (std::vector<molecule*>::const_iterator Runner = molecules.begin();
     241        Runner != molecules.end();
     242        Runner++) {
     243
     244      // molecule selected but not in scene?
     245      const bool isSelected = World::getInstance().isSelected(*Runner);
     246      if (isSelected){
     247        MoleculeNodeMap::iterator iter = MoleculesinSceneMap.find((*Runner)->getId());
     248        ASSERT( iter != MoleculesinSceneMap.end(),
     249            "GLWorldScene::worldSelectionChanged() - selected molecule is unknown.");
     250        GLMoleculeObject_molecule *molObject = iter->second;
     251        // inform molecule object
     252        molObject->selected(isSelected);
     253      }
     254    }
     255  }
     256}
     257
     258/** Inserts a molecule into the scene.
     259 *
     260 * @param _mol molecule to insert
     261 */
     262void GLWorldScene::moleculeInserted(const molecule * _mol)
     263{
     264  LOG(3, "INFO: GLWorldScene: Received signal moleculeRemoved for molecule "+toString(_mol->getId())+".");
     265  MoleculeNodeMap::const_iterator iter = MoleculesinSceneMap.find(_mol->getId());
     266  ASSERT( iter == MoleculesinSceneMap.end(),
     267      "GLWorldScene::moleculeInserted() - molecule's id "+toString(_mol->getId())+" already present.");
     268
     269  // add new object
     270  GLMoleculeObject_molecule *molObject = new GLMoleculeObject_molecule(GLMoleculeObject::meshEmpty, this, _mol);
     271  MoleculesinSceneMap.insert( make_pair(_mol->getId(), molObject) );
     272  connect (molObject, SIGNAL(changed()), this, SIGNAL(changed()));
     273  connect (molObject, SIGNAL(changeOccured()), this, SIGNAL(changeOccured()));
     274  connect (molObject, SIGNAL(atomClicked(atomId_t)), this, SLOT(atomClicked(atomId_t)));
     275  connect (molObject, SIGNAL(moleculeClicked(moleculeId_t)), this, SLOT(moleculeClicked(moleculeId_t)));
     276  connect (molObject, SIGNAL(changeAtomId(GLMoleculeObject_atom *, int, int)), this, SLOT(changeAtomId(GLMoleculeObject_atom *, int, int)));
     277  connect (molObject, SIGNAL(selectionChanged()), this, SIGNAL(changed()));
     278  connect (molObject, SIGNAL(selectionChanged()), this, SIGNAL(changed()));
     279  connect (molObject, SIGNAL(hoverChanged(const atom &)), this, SIGNAL(hoverChanged(const atom &)));
     280  connect (molObject, SIGNAL(hoverChanged(const molecule &, int)), this, SIGNAL(hoverChanged(const molecule &, int)));
     281  emit changed();
     282  emit changeOccured();
     283}
     284
     285/** Removes a molecule from the scene.
     286 *
     287 * @param _id id of molecule to remove
     288 */
     289void GLWorldScene::moleculeRemoved(const moleculeId_t _id)
     290{
     291  LOG(3, "INFO: GLWorldScene: Received signal moleculeRemoved for molecule "+toString(_id)+".");
     292  MoleculeNodeMap::iterator iter = MoleculesinSceneMap.find(_id);
     293  ASSERT( iter != MoleculesinSceneMap.end(),
     294      "GLWorldScene::moleculeInserted() - molecule's id "+toString(_id)+" is unknown.");
     295
     296  GLMoleculeObject_molecule *molObject = iter->second;
     297  molObject->disconnect();
     298  MoleculesinSceneMap.erase(iter);
     299  delete molObject;
     300  emit changed();
     301  emit changeOccured();
     302}
     303
     304void GLWorldScene::moleculesVisibilityChanged(const moleculeId_t _id, bool _visible)
     305{
     306  MoleculeNodeMap::iterator iter = MoleculesinSceneMap.find(_id);
     307  ASSERT( iter != MoleculesinSceneMap.end(),
     308      "GLWorldScene::moleculeInserted() - molecule's id "+toString(_id)+" is unknown.");
     309
     310  GLMoleculeObject_molecule *molObject = iter->second;
     311  molObject->setVisible(_visible);
     312
     313  emit changed();
     314  emit changeOccured();
     315}
     316
     317/** Adds a bond to the scene.
     318 *
     319 * @param _bond bond to add
     320 * @param side which side of the bond (left or right)
     321 */
     322void GLWorldScene::bondInserted(const bond::ptr _bond, const enum GLMoleculeObject_bond::SideOfBond _side)
     323{
     324  LOG(3, "INFO: GLWorldScene::bondInserted() - Adding bond "+toString(*_bond)+".");
     325  //LOG(4, "INFO: Currently present bonds " << BondsinSceneMap << ".");
     326  // bond partners must both belong to same atom
     327  ASSERT( _bond->leftatom->getMolecule() == _bond->rightatom->getMolecule(),
     328      "GLWorldScene::bondInserted() - bond partners do not belong to same molecule.");
     329
     330  // find associated molecule object
     331  const moleculeId_t molid = _bond->leftatom->getMolecule()->getId();
     332  MoleculeNodeMap::const_iterator moliter = MoleculesinSceneMap.find(molid );
     333  ASSERT(moliter != MoleculesinSceneMap.end(),
     334      "GLWorldScene::bondInserted() - molecule with id of "+toString(molid)
     335      +" atom with id "+toString(_bond->leftatom->getId())+" is unknown.");
     336  GLMoleculeObject_molecule *molObject = moliter->second;
     337
     338  // add to internal list
     339  const GLMoleculeObject_molecule::BondIds ids =
     340      GLMoleculeObject_molecule::getBondIds(_bond, _side);
     341  BondMoleculeMap::const_iterator iter = BondsinSceneMap.find(ids);
     342  ASSERT(iter == BondsinSceneMap.end(),
     343      "GLWorldScene::bondInserted() - bond with ids "+toString(ids.first)
     344      +","+toString(ids.second)+" already present.");
     345  BondsinSceneMap.insert( std::make_pair( ids, molObject ));
     346
     347  // inform its GlMoleculeObject_molecule.
     348  molObject->bondInserted(_bond, _side);
     349
     350  // emit change
     351  emit changeOccured();
     352}
     353
     354/** Removes a bond from the scene.
     355 *
     356 * @param _bond bond to remove
     357 */
     358void GLWorldScene::bondRemoved(const atomId_t leftnr, const atomId_t rightnr)
     359{
     360  LOG(3, "INFO: GLWorldScene::bondRemoved() - Removing bond between "+toString(leftnr)+" and "+toString(rightnr)+".");
     361  {
     362    // left bond
     363    const GLMoleculeObject_molecule::BondIds Leftids( make_pair(leftnr, rightnr) );
     364    BondMoleculeMap::iterator leftiter = BondsinSceneMap.find( Leftids );
     365    ASSERT(leftiter != BondsinSceneMap.end(),
     366        "GLWorldScene::bondRemoved() - bond "+toString(leftnr)+"-"
     367        +toString(rightnr)+" not on display.");
     368    GLMoleculeObject_molecule *molObject = leftiter->second;
     369
     370    // remove from internal list
     371    BondsinSceneMap.erase(leftiter);
     372
     373    // inform its GlMoleculeObject_molecule.
     374    molObject->bondRemoved( leftnr, rightnr );
     375  }
     376
     377  // emit change
     378  emit changeOccured();
     379}
     380
     381/** Adds a shape to the scene.
     382 *
     383 * uses ShapeRegistry::lastChanged()
     384 *
     385 */
     386void GLWorldScene::addShape()
     387{
     388  Shape &shape = *ShapeRegistry::getInstance().lastChanged();
     389  GLMoleculeObject_shape *shapeObject = new GLMoleculeObject_shape(shape, this);
     390  ShapeNodeMap::iterator iter = ShapesinSceneMap.find(shape.getName());
     391  ASSERT(iter == ShapesinSceneMap.end(),
     392      "GLWorldScene::addShape() - same shape "+shape.getName()+" added again.");
     393  ShapesinSceneMap.insert( make_pair(shape.getName(), shapeObject) );
     394}
     395
     396void GLWorldScene::removeShape()
     397{
     398  Shape &shape = *ShapeRegistry::getInstance().lastChanged();
     399  ShapeNodeMap::iterator iter = ShapesinSceneMap.find(shape.getName());
     400  ASSERT(iter != ShapesinSceneMap.end(),
     401      "GLWorldScene::removeShape() - shape "+shape.getName()+" not in scene.");
     402  ShapesinSceneMap.erase(iter);
     403  delete(iter->second);
     404}
     405
     406void GLWorldScene::updateSelectedShapes()
     407{
     408  foreach (QObject *obj, children()) {
     409    GLMoleculeObject_shape *shapeobj = qobject_cast<GLMoleculeObject_shape *>(obj);
     410      if (shapeobj){
     411        shapeobj->enable(ShapeRegistry::getInstance().isSelected(shapeobj->getShape()));
     412      }
     413  }
     414}
     415
     416void GLWorldScene::initialize(QGLView *view, QGLPainter *painter) const
     417{
     418  // Initialize all of the mesh objects that we have as children.
     419   foreach (QObject *obj, children()) {
     420     GLMoleculeObject *meshobj = qobject_cast<GLMoleculeObject *>(obj);
     421       if (meshobj)
     422         meshobj->initialize(view, painter);
     423   }
     424}
     425
     426void GLWorldScene::draw(QGLPainter *painter, const QVector4D &cameraPlane) const
     427{
     428   // Draw all of the mesh objects that we have as children.
     429   foreach (QObject *obj, children()) {
     430     GLMoleculeObject *meshobj = qobject_cast<GLMoleculeObject *>(obj);
     431       if (meshobj)
     432         meshobj->draw(painter, cameraPlane);
     433   }
     434}
     435
    439436void GLWorldScene::setSelectionMode(SelectionModeType mode)
    440437{
     
    453450}
    454451
    455 void GLWorldScene::hoverChangedSignalled(GLMoleculeObject *ob)
    456 {
    457   // Find the atom, ob corresponds to.
    458   hoverAtom = NULL;
    459   GLMoleculeObject_atom *atomObject = dynamic_cast<GLMoleculeObject_atom *>(ob);
    460   if (atomObject){
    461     for (AtomNodeMap::iterator iter = AtomsinSceneMap.begin();iter != AtomsinSceneMap.end(); ++ iter){
    462       if (iter->second == atomObject)
    463         hoverAtom = World::getInstance().getAtom(AtomById(iter->first));
    464     }
    465   }
    466 
    467   // Propagate signal.
    468   emit hoverChanged(hoverAtom);
    469 }
    470 
    471452void GLWorldScene::changeAtomId(GLMoleculeObject_atom *ob, int oldId, int newId)
    472453{
    473454  LOG(3, "INFO: GLWorldScene - change atom id " << oldId << " to " << newId << ".");
    474455  // Remove from map.
    475   AtomNodeMap::iterator iter = AtomsinSceneMap.find(oldId);
     456  AtomMoleculeMap::iterator iter = AtomsinSceneMap.find(oldId);
    476457  ASSERT(iter != AtomsinSceneMap.end(),
    477         "GLWorldScene::objectIdChangedSignalled() - atom with id "+toString(oldId)+" not on display.");
    478   GLMoleculeObject_atom *atomObject = iter->second;
     458        "GLWorldScene::changeAtomId() - atom with old id "+toString(oldId)+" not on display.");
     459  GLMoleculeObject_molecule *molObject = iter->second;
     460
     461  // erase by signalling removal
     462  molObject->atomRemoved(oldId);
     463
     464  // remove from internal list
    479465  AtomsinSceneMap.erase(iter);
    480466
    481467  // Reinsert with new id.
    482   AtomsinSceneMap.insert( make_pair(newId, atomObject) );
    483 }
    484 
     468  {
     469    AtomMoleculeMap::iterator iter = AtomsinSceneMap.find(newId);
     470    ASSERT(iter == AtomsinSceneMap.end(),
     471          "GLWorldScene::changeAtomId() - atom with new id "+toString(newId)+" already known.");
     472  }
     473  AtomsinSceneMap.insert( make_pair(newId, molObject) );
     474
     475  // inform molecule object
     476  molObject->atomInserted(oldId);
     477}
  • src/UIElements/Views/Qt4/Qt3D/GLWorldScene.hpp

    r7b38d3 r0ac85c3  
    7575  void clicked(atomId_t);
    7676  void doubleClicked();
    77   void hoverChanged(const atom*);
     77  void hoverChanged(const atom &);
     78  void hoverChanged(const molecule &, int);
    7879
    7980private slots:
    8081  void atomClicked(atomId_t no);
    81   void atomInserted(const atomicNumber_t _id);
    82   void atomRemoved(const atomicNumber_t _id);
    83   void moleculeRemoved(const molecule *_molecule);
     82  void atomInserted(const atomId_t _id);
     83  void atomRemoved(const atomId_t _id);
     84  void moleculeClicked(moleculeId_t no);
     85  void moleculeRemoved(const moleculeId_t _id);
     86  void moleculeInserted(const molecule * _mol);
    8487  void worldSelectionChanged();
    8588  void bondInserted(const bond::ptr _bond, const GLMoleculeObject_bond::SideOfBond side);
     
    8790  void setSelectionModeAtom();
    8891  void setSelectionModeMolecule();
    89   void hoverChangedSignalled(GLMoleculeObject *ob);
    9092  void changeAtomId(GLMoleculeObject_atom *ob, int oldId, int newOd);
    9193  void addShape();
    9294  void removeShape();
    9395  void update();
     96  void moleculesVisibilityChanged(const moleculeId_t _id, bool _visible);
    9497
    9598public:
     
    100103
    101104private:
    102   typedef std::pair< atomId_t, atomId_t> BondIds;
    103   friend std::ostream &operator<<(std::ostream &ost, const BondIds &t);
    104105
    105   BondIds getBondIds(
    106       const bond::ptr _bond,
    107       const enum GLMoleculeObject_bond::SideOfBond side) const;
    108 
    109   typedef std::map< atomId_t, GLMoleculeObject_atom* > AtomNodeMap;
    110   typedef std::map< BondIds , GLMoleculeObject_bond* > BondNodeMap;
     106  typedef std::map< atomId_t, GLMoleculeObject_molecule* > AtomMoleculeMap;
     107  typedef std::map< GLMoleculeObject_molecule::BondIds , GLMoleculeObject_molecule* > BondMoleculeMap;
    111108  typedef std::map< moleculeId_t , GLMoleculeObject_molecule* > MoleculeNodeMap;
    112109  typedef std::map< std::string , GLMoleculeObject_shape* > ShapeNodeMap;
    113   AtomNodeMap AtomsinSceneMap;
    114   BondNodeMap BondsinSceneMap;
     110  AtomMoleculeMap AtomsinSceneMap;
     111  BondMoleculeMap BondsinSceneMap;
    115112  MoleculeNodeMap MoleculesinSceneMap;
    116113  ShapeNodeMap ShapesinSceneMap;
    117114
    118   QGLSceneNode *meshEmpty[GLMoleculeObject::DETAILTYPES_MAX];
    119   QGLSceneNode *meshSphere[GLMoleculeObject::DETAILTYPES_MAX];
    120   QGLSceneNode *meshCylinder[GLMoleculeObject::DETAILTYPES_MAX];
    121 
    122115  SelectionModeType selectionMode;
    123   const atom *hoverAtom;
    124116};
    125117
    126 std::ostream &operator<<(std::ostream &ost, const GLWorldScene::BondIds &t);
    127 
    128118#endif /* GLWORLDSCENE_HPP_ */
  • src/UIElements/Views/Qt4/Qt3D/GLWorldView.cpp

    r7b38d3 r0ac85c3  
    7171  setOption(QGLView::ObjectPicking, true);
    7272  setOption(QGLView::CameraNavigation, false);
     73  setFocusPolicy(Qt::StrongFocus);
    7374  setCameraControlMode(Rotate);
    7475  defaultEyeSeparation = 4.0;
     
    7879  //changeMaterials(false);
    7980
    80   qRegisterMetaType<atomicNumber_t>("atomicNumber_t");
     81  qRegisterMetaType<atomId_t>("atomId_t");
     82  qRegisterMetaType<moleculeId_t>("moleculeId_t");
    8183
    8284  connect(this, SIGNAL(ShapeAdded()), worldscene, SLOT(addShape()));
     
    8587  connect(worldscene, SIGNAL(changeOccured()), this, SLOT(changeSignalled()));
    8688  connect(worldscene, SIGNAL(changed()), this, SIGNAL(changed()));
    87   connect(worldscene, SIGNAL(hoverChanged(const atom *)), this, SLOT(sceneHoverSignalled(const atom *)));
    88   connect(this, SIGNAL(atomInserted(const atomicNumber_t)), worldscene, SLOT(atomInserted(const atomicNumber_t)));
    89   connect(this, SIGNAL(atomRemoved(const atomicNumber_t)), worldscene, SLOT(atomRemoved(const atomicNumber_t)));
     89  connect(worldscene, SIGNAL(hoverChanged(const atom &)), this, SLOT(sceneHoverSignalled(const atom &)));
     90  connect(worldscene, SIGNAL(hoverChanged(const molecule &, int)), this, SLOT(sceneHoverSignalled(const molecule &, int)));
    9091  connect(this, SIGNAL(worldSelectionChanged()), worldscene, SLOT(worldSelectionChanged()));
    91   connect(this, SIGNAL(moleculeRemoved(const molecule *)), worldscene, SLOT(moleculeRemoved(const molecule *)));
    92   //connect(this, SIGNAL(moleculeInserted(const molecule *)), worldscene, SLOT(moleculeInserted(const molecule *)));
     92  connect(this, SIGNAL(moleculeRemoved(const moleculeId_t)), worldscene, SLOT(moleculeRemoved(const moleculeId_t)));
     93  connect(this, SIGNAL(moleculeInserted(const molecule *)), worldscene, SLOT(moleculeInserted(const molecule *)));
    9394  //connect(this, SIGNAL(changed()), this, SLOT(updateGL()));
    9495  connect(this, SIGNAL(changed()), this, SLOT(sceneChangeSignalled()));
     96  connect(this, SIGNAL(moleculesVisibilityChanged(const moleculeId_t,bool)), worldscene, SLOT(moleculesVisibilityChanged(const moleculeId_t,bool)));
    9597
    9698  // sign on to changes in the world
    9799  World::getInstance().signOn(this);
    98   World::getInstance().signOn(this, World::AtomInserted);
    99   World::getInstance().signOn(this, World::AtomRemoved);
    100100  World::getInstance().signOn(this, World::MoleculeInserted);
    101101  World::getInstance().signOn(this, World::MoleculeRemoved);
     
    338338  if (static_cast<World *>(publisher) == World::getPointer()) {
    339339    switch (notification->getChannelNo()) {
    340       case World::AtomInserted:
    341       {
    342         const atomicNumber_t _id = World::getInstance().lastChanged<atom>()->getId();
    343   #ifdef LOG_OBSERVER
    344         observerLog().addMessage() << "++ Observer " << observerLog().getName(static_cast<Observer *>(this)) << " received notification that atom "+toString(_id)+" has been inserted.";
    345   #endif
    346         emit atomInserted(_id);
    347         break;
    348       }
    349       case World::AtomRemoved:
    350       {
    351         const atomicNumber_t _id = World::getInstance().lastChanged<atom>()->getId();
    352   #ifdef LOG_OBSERVER
    353         observerLog().addMessage() << "++ Observer " << observerLog().getName(static_cast<Observer *>(this)) << " received notification that atom "+toString(_id)+" has been removed.";
    354   #endif
    355         emit atomRemoved(_id);
    356         break;
    357       }
    358340      case World::SelectionChanged:
    359341      {
     
    366348      case World::MoleculeInserted:
    367349      {
    368         const molecule *_molecule = World::getInstance().lastChanged<molecule>();
     350        const molecule * _mol = World::getInstance().lastChanged<molecule>();
    369351  #ifdef LOG_OBSERVER
    370         observerLog().addMessage() << "++ Observer " << observerLog().getName(static_cast<Observer *>(this)) << " received notification that molecule "+toString(_molecule->getId())+" has been removed.";
     352        observerLog().addMessage() << "++ Observer " << observerLog().getName(static_cast<Observer *>(this)) << " received notification that molecule "+toString(_mol->getId())+" has been removed.";
    371353  #endif
    372         emit moleculeInserted(_molecule);
     354        emit moleculeInserted(_mol);
    373355        break;
    374356      }
    375357      case World::MoleculeRemoved:
    376358      {
    377         const molecule *_molecule = World::getInstance().lastChanged<molecule>();
     359        const moleculeId_t _id = World::getInstance().lastChanged<molecule>()->getId();
    378360  #ifdef LOG_OBSERVER
    379         observerLog().addMessage() << "++ Observer " << observerLog().getName(static_cast<Observer *>(this)) << " received notification that molecule "+toString(_molecule->getId())+" has been removed.";
     361        observerLog().addMessage() << "++ Observer " << observerLog().getName(static_cast<Observer *>(this)) << " received notification that molecule "+toString(_id)+" has been removed.";
    380362  #endif
    381         emit moleculeRemoved(_molecule);
     363        emit moleculeRemoved(_id);
    382364        break;
    383365      }
     
    518500void GLWorldView::keyPressEvent(QKeyEvent *e)
    519501{
     502  // Find the distance between the eye and focus point.
     503  QVector3D d = camera()->eye() - camera()->center();
     504//  LOG(1, "Distance vector eye and center is "
     505//      << d.x() << "," << d.y() << "," << d.z());
     506  // scale the move unit by the eye <-> domain center distance
     507  const double key_move_unit = 0.04*(d.length()/50.);
     508
    520509  if (e->key() == Qt::Key_Tab) {
    521510    // The Tab key turns the ShowPicking option on and off,
     
    523512    setOption(QGLView::ShowPicking, ((options() & QGLView::ShowPicking) == 0));
    524513    updateGL();
     514  } else if ((e->key() == Qt::Key_Minus) || (e->key() == Qt::Key_Plus)) {
     515    // Scale the distance.
     516    if (e->key() == Qt::Key_Minus)
     517      d *= 1.2;
     518    else if (e->key() == Qt::Key_Plus)
     519      d /= 1.2;
     520    // Set new eye position.
     521    camera()->setEye(camera()->center() + d);
     522  } else if ((e->key() == Qt::Key_Left) || (e->key() == Qt::Key_Right)) {
     523    // Translate the camera.
     524    const double d = (e->key() == Qt::Key_Left) ? -key_move_unit : key_move_unit;
     525    camera()->translateCenter( d, 0., 0);
     526    camera()->translateEye( d, 0., 0);
     527  } else if ((e->key() == Qt::Key_Up) || (e->key() == Qt::Key_Down)) {
     528    // Translate the camera.
     529    const double d = (e->key() == Qt::Key_Up) ? -key_move_unit : key_move_unit;
     530    camera()->translateCenter( 0., d, 0);
     531    camera()->translateEye( 0., d, 0);
     532  } else if ((e->key() == Qt::Key_PageUp) || (e->key() == Qt::Key_PageDown)) {
     533    // Translate the camera.
     534    const double d = (e->key() == Qt::Key_PageUp) ? -key_move_unit : key_move_unit;
     535    camera()->translateCenter( 0., 0., d);
     536    camera()->translateEye( 0., 0., d);
    525537  }
    526538  QGLView::keyPressEvent(e);
     
    750762}
    751763
    752 void GLWorldView::sceneHoverSignalled(const atom *_atom)
     764void GLWorldView::sceneHoverSignalled(const atom &_atom)
    753765{
    754766  emit hoverChanged(_atom);
    755767}
     768
     769void GLWorldView::sceneHoverSignalled(const molecule &_mol, int _i)
     770{
     771  emit hoverChanged(_mol, _i);
     772}
  • src/UIElements/Views/Qt4/Qt3D/GLWorldView.hpp

    r7b38d3 r0ac85c3  
    5151  void checkChanges();
    5252  void sceneChangeSignalled();
    53   void sceneHoverSignalled(const atom *_atom);
     53  void sceneHoverSignalled(const atom &_atom);
     54  void sceneHoverSignalled(const molecule &_mol, int);
    5455  void changeDreiBein();
    5556  void changeDomain();
     
    5859  void changed();
    5960  void TimeChanged();
    60   void atomInserted(const atomicNumber_t _id);
    61   void atomRemoved(const atomicNumber_t _id);
    62   void moleculeInserted(const molecule *_molecule);
    63   void moleculeRemoved(const molecule *_molecule);
     61  void moleculeInserted(const molecule * _mol);
     62  void moleculeRemoved(const moleculeId_t _id);
    6463  void worldSelectionChanged();
    65   void hoverChanged(const atom *_atom);
     64  void hoverChanged(const atom &_atom);
     65  void hoverChanged(const molecule &_mol, int);
    6666  void ShapeAdded();
    6767  void ShapeRemoved();
     68  void moleculesVisibilityChanged(const moleculeId_t,bool);
    6869
    6970protected:
  • src/UIElements/Views/Qt4/QtInfoBox.cpp

    r7b38d3 r0ac85c3  
    5050    QTabWidget(),
    5151    curAtom(NULL), nextAtom(NULL),
     52    curMolecule(NULL), nextMolecule(NULL),
    5253    page_mol(NULL), page_atom(NULL)
    5354{
     
    6768}
    6869
    69 void QtInfoBox::atomHover(const atom *_atom)
    70 {
    71   nextAtom = _atom;
     70void QtInfoBox::atomHover(const atom &_atom)
     71{
     72  nextAtom = &_atom;
     73  timer->start(500);
     74}
     75
     76void QtInfoBox::moleculeHover(const molecule &_mol)
     77{
     78  nextMolecule = &_mol;
    7279  timer->start(500);
    7380}
     
    7784  if (nextAtom)
    7885    showAtom(nextAtom);
     86  if (nextMolecule)
     87    showMolecule(nextMolecule);
    7988}
    8089
     
    101110
    102111  curAtom = _atom;
     112  nextAtom = NULL;
     113  nextMolecule = NULL;
    103114
    104115  // Show new tabs.
     
    116127        setCurrentIndex(currentPage);
    117128    }
     129  }
     130}
     131
     132void QtInfoBox::showMolecule(const molecule *_mol)
     133{
     134  currentPage = currentIndex();
     135
     136  // Remove old tabs.
     137  clearTabs();
     138
     139  curMolecule = _mol;
     140  nextAtom = NULL;
     141  nextMolecule = NULL;
     142
     143  // Show new tabs.
     144  if (curMolecule){
     145    page_mol = new QtMoleculeInfoPage(curMolecule, this);
     146    addTab(page_mol, "Molecule");
     147    connect(page_mol, SIGNAL(moleculeKilled()), this, SLOT(clearTabs()));
     148
     149    if (currentPage > 0)
     150      setCurrentIndex(currentPage);
    118151  }
    119152}
  • src/UIElements/Views/Qt4/QtInfoBox.hpp

    r7b38d3 r0ac85c3  
    3636
    3737  void showAtom(const atom *_atom);
     38  void showMolecule(const molecule *_mol);
    3839
    3940public slots:
    40   void atomHover(const atom *_atom);
     41  void atomHover(const atom &_atom);
     42  void moleculeHover(const molecule &_mol);
    4143  void timerTimeout();
    4244
     
    4648  const atom *curAtom;
    4749  const atom *nextAtom;
     50  const molecule *curMolecule;
     51  const molecule *nextMolecule;
    4852  QtMoleculeInfoPage *page_mol;
    4953  QtAtomInfoPage *page_atom;
  • src/UIElements/Views/Qt4/QtMoleculeList.cpp

    r7b38d3 r0ac85c3  
    5555// these attributes are skipped so far
    5656const int QtMoleculeList::COLUMNCOUNT = COLUMNTYPES_MAX;
    57 const char *QtMoleculeList::COLUMNNAMES[QtMoleculeList::COLUMNCOUNT]={"Name","Atoms","Formula","Occurrence"/*,"Size"*/};
     57const char *QtMoleculeList::COLUMNNAMES[QtMoleculeList::COLUMNCOUNT]={"Name","Visibility", "Atoms","Formula","Occurrence"/*,"Size"*/};
    5858
    5959QtMoleculeList::QtMoleculeList(QWidget * _parent) :
     
    6969  setHeaderLabels(header);
    7070
    71   World::getInstance().signOn(this);//, World::MoleculeInserted);
    72   //World::getInstance().signOn(this, World::MoleculeRemoved);
     71  World::getInstance().signOn(this, World::MoleculeInserted);
     72  World::getInstance().signOn(this, World::MoleculeRemoved);
    7373
    7474
     
    7676  clearing = false;
    7777  selecting = false;
     78  ChangingChildrensVisibility = false;
    7879  refill();
    7980
     
    8182  //connect(this,SIGNAL(cellChanged(int,int)),this,SLOT(moleculeChanged(int,int)));
    8283  connect(selectionModel(),SIGNAL(selectionChanged(QItemSelection, QItemSelection)),this,SLOT(rowsSelected(QItemSelection, QItemSelection)));
    83 
     84  connect(this, SIGNAL(itemChanged(QTreeWidgetItem*, int)), this, SLOT(visibilityChanged(QTreeWidgetItem*, int)));
    8485}
    8586
    8687QtMoleculeList::~QtMoleculeList()
    8788{
    88   World::getInstance().signOff(this);//, World::MoleculeInserted);
    89   //World::getInstance().signOff(this, World::MoleculeRemoved);
     89  World::getInstance().signOff(this, World::MoleculeInserted);
     90  World::getInstance().signOff(this, World::MoleculeRemoved);
    9091}
    9192
    9293void QtMoleculeList::update(Observable *publisher) {
     94  ASSERT(0,
     95      "QtMoleculeList::update() - we did not sign up for any global updates.");
     96}
     97
     98void QtMoleculeList::recieveNotification(Observable *publisher, Notification_ptr notification) {
    9399
    94100  if (selecting)
     
    96102
    97103  dirty = true;
    98 
    99   // force an update from Qt...
    100   clearing = true;
    101   clear();
    102   clearing = false;
    103 }
     104}
     105
    104106
    105107void QtMoleculeList::refill() {
     
    108110
    109111  clear();
    110 
    111   // list of (unique) formulas in the world
    112   std::vector<Formula> formula;
     112  formula.clear();
     113  FormulaVisibilityCountMap.clear();
    113114
    114115  for (std::vector<molecule*>::const_iterator iter = molecules.begin();
     
    118119    // find group if already in list
    119120    QTreeWidgetItem *groupItem = NULL;
    120     for (unsigned int j=0;j<formula.size();j++)
    121       if ((*iter)->getFormula() == formula[j]){
    122         groupItem = topLevelItem(j);
    123         break;
    124       }
     121    const std::string &molecule_formula = (*iter)->getFormula().toString();
     122    FormulaTreeItemMap_t::const_iterator formulaiter =
     123        formula.find(molecule_formula);
    125124
    126125    // new molecule type -> create new group
    127     if (!groupItem){
    128       formula.push_back((*iter)->getFormula());
     126    if (formulaiter == formula.end()){
     127      // insert new formula entry into visibility
     128#ifndef NDEBUG
     129      std::pair< FormulaVisibilityCountMap_t::iterator, bool> visibilityinserter =
     130#endif
     131          FormulaVisibilityCountMap.insert(
     132              std::make_pair( molecule_formula, (unsigned int)0) );
     133      ASSERT( visibilityinserter.second,
     134          "QtMoleculeList::refill() - molecule with formula "
     135          +molecule_formula+" already in FormulaVisibilityCountMap.");
     136
     137      // create item and place into Map with formula as key
    129138      groupItem = new QTreeWidgetItem(this);
    130       groupItem->setText(0, QString("default"));
    131       groupItem->setText(1, QString::number(0));
    132       groupItem->setText(2, QString(""));
    133       groupItem->setText(3, "0");
     139      formula.insert( std::make_pair(molecule_formula, groupItem) );
     140      // fill item
     141      groupItem->setText(NAME, QString("default"));
     142      groupItem->setFlags((groupItem->flags() | Qt::ItemIsUserCheckable) ^ Qt::ItemIsSelectable);
     143      groupItem->setCheckState(VISIBILITY, Qt::Unchecked);
     144      groupItem->setText(ATOMCOUNT, QString::number(0));
     145      groupItem->setText(FORMULA, QString(""));
     146      groupItem->setText(OCCURRENCE, "0");
    134147      groupItem->setData(0, Qt::UserRole, QVariant(-1));
     148    } else {
     149      groupItem = formulaiter->second;
    135150    }
    136151
    137152    // add molecule
    138153    QTreeWidgetItem *molItem = new QTreeWidgetItem(groupItem);
    139     molItem->setText(0, QString((*iter)->getName().c_str()));
    140     molItem->setText(1, QString::number((*iter)->getAtomCount()));
    141     molItem->setText(2, QString((*iter)->getFormula().toString().c_str()));
     154    molItem->setText(NAME, QString((*iter)->getName().c_str()));
     155    molItem->setFlags(molItem->flags() | Qt::ItemIsUserCheckable | Qt::ItemIsSelectable);
     156    molItem->setCheckState(VISIBILITY, Qt::Unchecked);
     157    molItem->setText(ATOMCOUNT, QString::number((*iter)->getAtomCount()));
     158    molItem->setText(FORMULA, QString(molecule_formula.c_str()));
    142159    const int index = (*iter)->getId();
    143160    molItem->setData(0, Qt::UserRole, QVariant(index));
    144161    molItem->setSelected(World::getInstance().isSelected(*iter));
    145162
    146 
    147163    // increase group occurrence
    148     int count = groupItem->text(3).toInt() + 1;
    149     groupItem->setText(3, QString::number(count));
     164    int count = groupItem->text(OCCURRENCE).toInt() + 1;
     165    groupItem->setText(OCCURRENCE, QString::number(count));
    150166  }
    151167  dirty = false;
     
    161177
    162178void QtMoleculeList::subjectKilled(Observable *publisher) {
     179}
     180
     181void QtMoleculeList::visibilityChanged(QTreeWidgetItem* item, int column)
     182{
     183  if ((!clearing) && (!ChangingChildrensVisibility))
     184    if (column == VISIBILITY) {
     185      const moleculeId_t molid = item->data(0, Qt::UserRole).toInt();
     186      const bool visible = item->checkState(VISIBILITY);
     187      if (molid != (unsigned int)-1) { // molecule item
     188        const molecule * const _molecule =
     189            World::getInstance().getMolecule(MoleculeById(molid));
     190        ASSERT( _molecule != NULL,
     191            "QtMoleculeList::visibilityChanged() - molecule with id "
     192            +toString(molid)+" is not known to World.");
     193        const std::string &molecule_formula = _molecule->getFormula().toString();
     194        ASSERT( FormulaVisibilityCountMap.count(molecule_formula) != 0,
     195            "QtMoleculeList::visibilityChanged() - molecule with formula " +molecule_formula
     196            +" is not present in FormulaVisibilityCountMap.");
     197
     198        // get parent
     199        QTreeWidgetItem *groupItem = item->parent();
     200        ASSERT( groupItem != NULL,
     201            "QtMoleculeList::visibilityChanged() - item with id "+toString(molid)
     202            +" has not parent?");
     203        // check whether we have to set the group item
     204
     205        ChangingChildrensVisibility = true;
     206        if (visible) {
     207          ++(FormulaVisibilityCountMap[molecule_formula]);
     208          // compare with occurence/total number of molecules
     209          if (FormulaVisibilityCountMap[molecule_formula] ==
     210              (unsigned int)(groupItem->text(OCCURRENCE).toInt()))
     211            groupItem->setCheckState(VISIBILITY, Qt::Checked);
     212        } else {
     213          --(FormulaVisibilityCountMap[molecule_formula]);
     214          // none selected anymore?
     215          if (FormulaVisibilityCountMap[molecule_formula] == 0)
     216            groupItem->setCheckState(VISIBILITY, Qt::Unchecked);
     217        }
     218        ChangingChildrensVisibility = false;
     219
     220        emit moleculesVisibilityChanged(molid, visible);
     221
     222      } else { // group item
     223
     224        // go through all children, but don't enter for groupItem once more
     225        ChangingChildrensVisibility = true;
     226        for (int i=0;i<item->childCount();++i) {
     227          QTreeWidgetItem *molItem = item->child(i);
     228          const moleculeId_t molid = molItem->data(0, Qt::UserRole).toInt();
     229          ASSERT( molid != (unsigned int)-1,
     230              "QtMoleculeList::visibilityChanged() - to child with index"
     231              +toString(i)+" there is no molecule?");
     232          molItem->setCheckState(VISIBILITY, visible ? Qt::Checked : Qt::Unchecked);
     233
     234          // emit signal
     235          emit moleculesVisibilityChanged(molid, visible);
     236        }
     237        // set current number of visible children
     238        const std::string molecule_formula =
     239            item->text(FORMULA).toStdString();
     240        FormulaVisibilityCountMap[molecule_formula] =
     241            visible ? item->text(OCCURRENCE).toInt() : 0;
     242
     243        ChangingChildrensVisibility = false;
     244      }
     245    }
    163246}
    164247
     
    185268  // Select all molecules which belong to newly selected rows.
    186269  QModelIndex index;
    187   QModelIndexList items = selected.indexes();
    188   foreach (index, items)
    189     if (index.column() == 0){
    190       int mol_id = model()->data(index, Qt::UserRole).toInt();
    191       if (mol_id < 0)
    192         continue;
    193       //std::cout << "select molecule" << std::endl;
    194       MoleCuilder::SelectionMoleculeById(mol_id);
    195     }
     270  {
     271    QModelIndexList items = selected.indexes();
     272    molids_t ids;
     273    ids.reserve(items.size());
     274    foreach (index, items)
     275      if (index.column() == 0){
     276        int mol_id = model()->data(index, Qt::UserRole).toInt();
     277        if (mol_id < 0)
     278          continue;
     279        ids.push_back(mol_id);
     280        //std::cout << "select molecule" << std::endl;
     281      }
     282    MoleCuilder::SelectionMoleculeById(ids);
     283  }
    196284
    197285  // Unselect all molecules which belong to newly unselected rows.
    198   items = deselected.indexes();
    199   foreach (index, items)
    200     if (index.column() == 0){
    201       int mol_id = model()->data(index, Qt::UserRole).toInt();
    202       if (mol_id < 0)
    203         continue;
    204       //std::cout << "unselect molecule" << std::endl;
    205       MoleCuilder::SelectionNotMoleculeById(mol_id);
    206     }
     286  {
     287    QModelIndexList items = deselected.indexes();
     288    molids_t ids;
     289    ids.reserve(items.size());
     290    foreach (index, items)
     291      if (index.column() == 0){
     292        int mol_id = model()->data(index, Qt::UserRole).toInt();
     293        if (mol_id < 0)
     294          continue;
     295        //std::cout << "unselect molecule" << std::endl;
     296        ids.push_back(mol_id);
     297      }
     298    MoleCuilder::SelectionNotMoleculeById(ids);
     299  }
    207300
    208301  selecting = false;
  • src/UIElements/Views/Qt4/QtMoleculeList.hpp

    r7b38d3 r0ac85c3  
    1414#endif
    1515
     16#include <QtGui/QTreeWidget>
    1617
    17 #include <QtGui/QTreeWidget>
     18#include <map>
     19#include <string>
     20
    1821#include "CodePatterns/Observer/Observer.hpp"
     22
     23#include "types.hpp"
    1924
    2025class molecule;
     
    3136protected:
    3237  virtual void update(Observable *publisher);
     38  virtual void recieveNotification(Observable *publisher, Notification_ptr notification);
    3339  virtual void subjectKilled(Observable *publisher);
    3440  virtual void paintEvent(QPaintEvent * event);
     
    3642
    3743  static const int COLUMNCOUNT;
    38   enum {NAME,ATOMCOUNT,FORMULA,OCCURRENCE,COLUMNTYPES_MAX} COLUMNTYPES;
     44  enum {NAME,VISIBILITY,ATOMCOUNT,FORMULA,OCCURRENCE,COLUMNTYPES_MAX} COLUMNTYPES;
    3945  static const char *COLUMNNAMES[];
    4046
    4147private slots:
    4248  void moleculeChanged();
     49  void visibilityChanged(QTreeWidgetItem*, int);
    4350
    4451  void rowsSelected(const QItemSelection & selected, const QItemSelection & deselected);
     
    4754  void moleculeSelected(molecule*);
    4855  void moleculeUnSelected(molecule*);
     56  void moleculesVisibilityChanged(const moleculeId_t, bool);
    4957
    5058private:
     
    5260  bool clearing;
    5361  bool selecting;
     62  bool ChangingChildrensVisibility;
     63
     64  typedef std::map<std::string, unsigned int> FormulaVisibilityCountMap_t;
     65  FormulaVisibilityCountMap_t FormulaVisibilityCountMap;
     66
     67  typedef std::map<std::string, QTreeWidgetItem*> FormulaTreeItemMap_t;
     68  //!> map of (unique) formulas in the world
     69  FormulaTreeItemMap_t formula;
    5470};
    5571
  • src/UIElements/Views/Qt4/QtToolBar.cpp

    r7b38d3 r0ac85c3  
    2828 */
    2929
    30 
    31 
    32 
    3330// include config.h
    3431#ifdef HAVE_CONFIG_H
     
    3633#endif
    3734
    38 
    3935#include "QtToolBar.hpp"
    4036
    4137#include "CodePatterns/MemDebug.hpp"
    4238
     39#include "CodePatterns/Observer/Notification.hpp"
     40
     41#include "Actions/ActionQueue.hpp"
     42
    4343QtToolBar::QtToolBar(QWidget * _parent) :
    44   QToolBar(_parent)
     44  QToolBar(_parent),
     45  Observer("QToolBar"),
     46  ActionQueue_observing(false),
     47  undoaction(addActionItem("undo", "undo the last Action", "edit-undo")),
     48  redoaction(addActionItem("redo", "redo the last Action", "edit-redo"))
    4549{
    46   addActionItem("undo", "undo the last Action", "edit-undo");
    47   addActionItem("redo", "redo the last Action", "edit-redo");
     50  // gray out undo/redo buttons initially
     51  undoaction->setEnabled(false);
     52  redoaction->setEnabled(false);
     53
     54  // sign in
     55  MoleCuilder::ActionQueue::getInstance().signOn(this, MoleCuilder::ActionQueue::ActionQueued);
     56  ActionQueue_observing = true;
    4857}
    4958
     
    5160QtToolBar::~QtToolBar()
    5261{
     62  // sign off
     63  if (ActionQueue_observing)
     64    MoleCuilder::ActionQueue::getInstance().signOff(this, MoleCuilder::ActionQueue::ActionQueued);
    5365}
    5466
    5567
    56 void QtToolBar::addActionItem(const std::string &token, const std::string &description, const std::string &icon_name)
     68QAction * QtToolBar::addActionItem(
     69    const std::string &token,
     70    const std::string &description,
     71    const std::string &icon_name)
    5772{
    5873  QAction *action = addAction(QString(description.c_str()));
     
    6378  plumbing.push_back(pipe);
    6479  present_actions.insert( token );
     80  return action;
    6581}
    6682
     
    7288}
    7389
     90void QtToolBar::update(Observable *publisher)
     91{
     92  ASSERT(0, "QtToolBar::update() - this should never be called, we are only subscribed to channels.");
     93}
     94
     95void QtToolBar::subjectKilled(Observable *publisher)
     96{
     97  ActionQueue_observing = false;
     98}
     99
     100void QtToolBar::recieveNotification(Observable *publisher, Notification_ptr notification)
     101{
     102  if (dynamic_cast<MoleCuilder::ActionQueue *>(publisher) != NULL) {
     103    switch(notification->getChannelNo()) {
     104      case MoleCuilder::ActionQueue::ActionQueued:
     105        undoaction->setEnabled(MoleCuilder::ActionQueue::getInstance().canUndo());
     106        redoaction->setEnabled(MoleCuilder::ActionQueue::getInstance().canRedo());
     107        break;
     108      default:
     109        ASSERT(0, "QtToolBar::recieveNotification() - cannot get here, not subscribed to channel "
     110            +toString(notification->getChannelNo()));
     111        break;
     112    }
     113  } else {
     114    ASSERT(0, "QtToolBar::recieveNotification() - cannot get here, we are only subscribed to ActionQueue.");
     115  }
     116}
  • src/UIElements/Views/Qt4/QtToolBar.hpp

    r7b38d3 r0ac85c3  
    2727
    2828
    29 class QtToolBar : public QToolBar
     29class QtToolBar : public QToolBar, public Observer
    3030{
    3131  Q_OBJECT
     
    3939   * @param description description to appear as tooltip
    4040   * @param icon_name name of icon
     41   * @return ref to newly created action
    4142   */
    42   void addActionItem(const std::string &token, const std::string &description, const std::string &icon_name);
     43  QAction * addActionItem(
     44      const std::string &token,
     45      const std::string &description,
     46      const std::string &icon_name);
    4347
    4448  /** Function to add a set of favorite actions.
     
    5761  const present_actions_t & getPresentActions() const
    5862  { return present_actions; }
     63
     64  void update(Observable *publisher);
     65  void subjectKilled(Observable *publisher);
     66  void recieveNotification(Observable *publisher, Notification_ptr notification);
    5967
    6068private:
     
    105113  //!> set of already present action icons
    106114  present_actions_t present_actions;
     115
     116  //!> sign in to ActionQueue?
     117  bool ActionQueue_observing;
     118  //!> ref to undoaction to gray out
     119  QAction *undoaction;
     120  //!> ref to redoaction to gray out
     121  QAction *redoaction;
    107122};
    108123
  • src/UIElements/Views/Qt4/QtToolBar_QtFavoriteActions.cpp

    r7b38d3 r0ac85c3  
    4646#include "CodePatterns/Assert.hpp"
    4747#include "CodePatterns/Log.hpp"
    48 #include "CodePatterns/Observer/Observer.hpp"
    4948
    5049#include "Actions/Action.hpp"
Note: See TracChangeset for help on using the changeset viewer.