Ignore:
Timestamp:
Aug 5, 2015, 5:32:09 PM (10 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, 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:
52c5d4
Parents:
95f49f
git-author:
Frederik Heber <heber@…> (07/14/15 13:55:47)
git-committer:
Frederik Heber <heber@…> (08/05/15 17:32:09)
Message:

Fixing QtMoleculeList with list containing only formulas and ids.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/UIElements/Views/Qt4/MoleculeList/QtMoleculeList.cpp

    r95f49f rfcdf05  
    4242
    4343#include <boost/bind.hpp>
     44#include <boost/thread/locks.hpp>
    4445#include <iostream>
    4546
     
    6364  ChangingChildrensVisibility(false),
    6465  update_timer(NULL),
    65   callback_DirtyItems(boost::bind(&QtMoleculeList::informDirtyState, this, _1, _2))
     66  callback_DirtyItems(boost::bind(&QtMoleculeList::informDirtyState, this, _1, _2, _3))
    6667{
    6768  setColumnCount(QtMoleculeItemFactory::COLUMNCOUNT);
     
    7576  //connect(this,SIGNAL(cellChanged(int,int)),this,SLOT(moleculeChanged(int,int)));
    7677//  connect(selectionModel(),SIGNAL(selectionChanged(QItemSelection, QItemSelection)),this,SLOT(rowsSelected(QItemSelection, QItemSelection)));
    77   connect(this, SIGNAL(itemChanged(QStandardItem*)), this, SLOT(checkForVisibilityChange(QStandardItem*)));
     78  connect(this, SIGNAL(itemChanged(QStandardItem*)), this, SLOT(checkForVisibilityChange(QStandardItem*)), Qt::DirectConnection);
    7879}
    7980
     
    8889  if (role == Qt::DisplayRole) {
    8990    if (orientation == Qt::Horizontal) {
    90       if (section < QtMoleculeItemFactory::COLUMNTYPES_MAX)
     91      if (section < QtMoleculeItem::COLUMNTYPES_MAX)
    9192        return QString(QtMoleculeItemFactory::COLUMNNAMES[section]);
    9293    }
     
    100101}
    101102
    102 QtMoleculeItem * QtMoleculeList::MoleculeIdToItem(const moleculeId_t _molid) const
    103 {
     103bool QtMoleculeList::isMoleculeItemPresent(const moleculeId_t _molid) const
     104{
     105  boost::recursive_mutex::scoped_lock lock(map_mutex);
    104106  MoleculeItemBiMap_t::left_const_iterator iter =
    105107      MoleculeItemBiMap.left.find(_molid);
    106   if( iter != MoleculeItemBiMap.left.end())
    107     return iter->second;
    108   else
    109     return NULL;
     108  return ( iter != MoleculeItemBiMap.left.end());
     109}
     110
     111QtMoleculeItem * QtMoleculeList::MoleculeIdToItem(const moleculeId_t _molid) const
     112{
     113  boost::recursive_mutex::scoped_lock lock(map_mutex);
     114  MoleculeItemBiMap_t::left_const_iterator iter =
     115      MoleculeItemBiMap.left.find(_molid);
     116  ASSERT( iter != MoleculeItemBiMap.left.end(),
     117      "QtMoleculeList::MoleculeIdToItem() - could not find item to id "
     118      +toString(_molid));
     119  return iter->second;
    110120}
    111121
    112122const moleculeId_t QtMoleculeList::ItemToMoleculeId(const QtMoleculeItem * const _item) const
    113123{
     124  boost::recursive_mutex::scoped_lock lock(map_mutex);
    114125  const MoleculeItemBiMap_t::right_const_iterator iter =
    115126      MoleculeItemBiMap.right.find(const_cast<QtMoleculeItem * const>(_item));
     
    120131}
    121132
     133QtMoleculeItem * QtMoleculeList::getSpecificMoleculeItem(
     134    const QtMoleculeItem * const _item,
     135    const enum QtMoleculeItem::COLUMNTYPES _type) const
     136{
     137  QStandardItem *parent_item = _item->parent();
     138  ASSERT( parent_item != NULL,
     139      "QtMoleculeList::getSpecificMoleculeItem() - parent of molecule item is NULL");
     140  return static_cast<QtMoleculeItem *>(parent_item->child(_item->index().row(), _type));
     141}
     142
     143bool QtMoleculeList::isGroupItemPresent(const std::string &_formula) const
     144{
     145  boost::recursive_mutex::scoped_lock lock(map_mutex);
     146  FormulaTreeItemBiMap_t::left_const_iterator iter =
     147      FormulaItemBiMap.left.find(_formula);
     148  return ( iter != FormulaItemBiMap.left.end());
     149}
     150
     151QStandardItem * QtMoleculeList::FormulaToGroupItem(const std::string &_formula) const
     152{
     153  boost::recursive_mutex::scoped_lock lock(map_mutex);
     154  FormulaTreeItemBiMap_t::left_const_iterator iter =
     155      FormulaItemBiMap.left.find(_formula);
     156  ASSERT( iter != FormulaItemBiMap.left.end(),
     157      "QtMoleculeList::FormulaToGroupItem() - could not find item to formula "
     158      +toString(_formula));
     159  return iter->second;
     160}
     161
     162const std::string& QtMoleculeList::GroupItemToFormula(const QStandardItem * const _item) const
     163{
     164  boost::recursive_mutex::scoped_lock lock(map_mutex);
     165  static std::string emptystring;
     166  const FormulaTreeItemBiMap_t::right_const_iterator iter =
     167      FormulaItemBiMap.right.find(const_cast<QStandardItem * const>(_item));
     168  if (iter != FormulaItemBiMap.right.end())
     169    return iter->second;
     170  else
     171    return emptystring;
     172}
     173
     174QStandardItem * QtMoleculeList::getSpecificGroupItem(
     175    const QStandardItem * const _item,
     176    const enum QtMoleculeItem::COLUMNTYPES _type) const
     177{
     178  return invisibleRootItem()->child(_item->index().row(), _type);
     179}
     180
     181
    122182const moleculeId_t QtMoleculeList::IndexToMoleculeId(const QModelIndex &_index) const
    123183{
     184  boost::recursive_mutex::scoped_lock lock(refill_mutex);
    124185  QtMoleculeItem * const item = dynamic_cast<QtMoleculeItem *>(itemFromIndex(_index));
    125186  if (item == NULL)
     
    136197      {
    137198        const molecule * const mol = World::getInstance().lastChanged<molecule>();
    138         listAccessing_mutex.lock();
    139         newItems.push_back( mol );
    140         listAccessing_mutex.unlock();
     199        boost::recursive_mutex::scoped_lock lock(listAccessing_mutex);
     200        const moleculeId_t molid = mol->getId();
     201        if (molid != (unsigned int )-1)
     202          newMolecules.push_back( molid );
    141203        break;
    142204      }
     
    145207        const molecule * const mol = World::getInstance().lastChanged<molecule>();
    146208
    147         listAccessing_mutex.lock();
    148         toBeRemovedItems.push_back( mol ); // remove in any case, as we also got insert
    149         listAccessing_mutex.unlock();
    150 
    151         const QtMoleculeItem *mol_item = MoleculeIdToItem(mol->getId());
    152         if (mol_item != NULL) {
    153           QStandardItem *parent_item = mol_item->parent();
    154           if (parent_item != NULL)
    155             addToBeSetOccurrence( parent_item );
    156           else
    157             ELOG(2, "QtMoleculeList::recieveNotification() - item to molecule "
    158                 +toString(mol)+" has no parent.");
    159         }
     209        boost::recursive_mutex::scoped_lock lock(listAccessing_mutex);
     210        const moleculeId_t molid = mol->getId();
     211        if (molid != (unsigned int )-1)
     212          removedMolecules.push_back( molid ); // remove in any case, as we also got insert
    160213        break;
    161214      }
     
    175228      QtMoleculeItemFactory::getInstance().createGroupItems(_molecule_formula);
    176229  mainitem = groupItems.front();
    177   formula.insert( std::make_pair(_molecule_formula, mainitem) );
     230  {
     231    boost::recursive_mutex::scoped_lock lock(map_mutex);
     232    FormulaItemBiMap.left.insert( std::make_pair(_molecule_formula, mainitem) );
     233  }
    178234  invisibleRootItem()->appendRow(groupItems);
    179 }
    180 
    181 void QtMoleculeList::addToBeSetOccurrence(
    182     QStandardItem *_groupitem)
    183 {
    184   listAccessing_mutex.lock();
    185   toBeSetOccurrenceItems.insert( _groupitem );
    186   listAccessing_mutex.unlock();
    187235}
    188236
     
    197245  ASSERT( mol_item != NULL,
    198246      "QtMoleculeList::addMoleculeItem() - item from factory was not a QtMoleculeItem?");
    199   MoleculeItemBiMap.left.insert( std::make_pair(_molid, mol_item) );
     247  {
     248    boost::recursive_mutex::scoped_lock lock(map_mutex);
     249    MoleculeItemBiMap.left.insert( std::make_pair(_molid, mol_item) );
     250    LOG(1, "Adding" << _molecule_formula << " for " << _molid << " to MoleculeFormulaMap.");
     251    MoleculeFormulaMap.insert( std::make_pair( _molid, _molecule_formula) );
     252  }
    200253//  LOG(1, "Inserting molecule " << _mol->getId() << ": " << _mol);
    201254  _groupitem->appendRow(molItems);
    202 
    203   // here update for the occurence will happen "one tick" later, but we don't
    204   // have the groupitem any time earlier
    205   addToBeSetOccurrence(_groupitem);
    206 }
    207 
    208 void QtMoleculeList::addMolecule(const molecule * const _mol)
     255}
     256
     257std::string QtMoleculeList::addMolecule(const molecule * const _mol)
    209258{
    210259  // find group if already in list
    211260  QStandardItem *groupItem = NULL;
    212261
    213   const std::string &molecule_formula = _mol->getFormula().toString();
    214   FormulaTreeItemMap_t::const_iterator formulaiter =
    215       formula.find(molecule_formula);
     262  const std::string molecule_formula = _mol->getFormula().toString();
    216263
    217264  // new molecule type -> create new group
    218   if (formulaiter == formula.end()){
     265  if (!isGroupItemPresent(molecule_formula)){
    219266    // insert new formula entry into visibility
    220267#ifndef NDEBUG
     
    230277    addGroupItem(groupItem, molecule_formula);
    231278  } else {
    232     groupItem = formulaiter->second;
     279    groupItem = FormulaToGroupItem(molecule_formula);
    233280  }
    234281  ASSERT( groupItem != NULL,
    235282      "QtMoleculeList::addMolecule() - item with id "+toString(_mol->getId())
    236       +" has not parent?");
     283      +" has no parent?");
    237284
    238285  // add molecule
    239286  addMoleculeItem(groupItem, _mol->getId(), molecule_formula);
    240 }
    241 
    242 void QtMoleculeList::removeItem(QtMoleculeItem * const _item)
    243 {
     287
     288  return molecule_formula;
     289}
     290
     291void QtMoleculeList::removeMoleculeItem(QtMoleculeItem * const _item)
     292{
     293  boost::recursive_mutex::scoped_lock lock(refill_mutex);
    244294  const QModelIndex mol_index = indexFromItem(_item);
    245295  QStandardItem *groupitem = _item->parent();
    246296  const QModelIndex group_index = groupitem->index();
     297  {
     298    boost::recursive_mutex::scoped_lock lock(map_mutex);
     299    MoleculeItemBiMap_t::right_iterator removeiter =
     300        MoleculeItemBiMap.right.find(_item);
     301    ASSERT( removeiter != MoleculeItemBiMap.right.end(),
     302        "QtMoleculeList::removeMoleculeItem() - could not find item in MoleculeBiMap.");
     303  //  LOG(1, "Erasing molecule " << (removeiter->second));
     304    {
     305      MoleculeFormulaMap_t::iterator removeformulaiter =
     306          MoleculeFormulaMap.find(removeiter->second);
     307      ASSERT( removeformulaiter != MoleculeFormulaMap.end(),
     308          "QtMoleculeList::removeMoleculeItem() - could not find id "
     309          +toString(removeiter->second)+" in MoleculeFormulaMap.");
     310      LOG(1, "Removing " << removeformulaiter->second << " for "
     311          << removeformulaiter->first << " from MoleculeFormulaMap.");
     312      MoleculeFormulaMap.erase( removeformulaiter );
     313    }
     314    MoleculeItemBiMap.right.erase(removeiter);
     315  }
    247316  removeRows(mol_index.row(), 1, group_index);
    248   MoleculeItemBiMap_t::right_iterator removeiter =
    249       MoleculeItemBiMap.right.find(_item);
    250   ASSERT( removeiter != MoleculeItemBiMap.right.end(),
    251       "QtMoleculeList::removeItem() - could not find item in BiMap.");
    252   LOG(1, "Erasing molecule " << (removeiter->second));
    253   MoleculeItemBiMap.right.erase(removeiter);
    254 
    255   // don't need to, groupitem is already present in toBeSetOccurrenceItems
    256 //  addToBeSetOccurrence(_groupitem);
    257317}
    258318
     
    266326    update_timer->stop();
    267327
    268   refill_mutex.lock();
     328  {
     329    boost::recursive_mutex::scoped_lock refill_lock(refill_mutex);
     330    boost::recursive_mutex::scoped_lock listAccessing_lock(listAccessing_mutex);
     331
     332    //  LOG(1, "Clearing list.");
     333
     334    clear();
     335    FormulaVisibilityCountMap.clear();
     336    {
     337      boost::recursive_mutex::scoped_lock lock(map_mutex);
     338      FormulaItemBiMap.clear();
     339      MoleculeFormulaMap.clear();
     340      MoleculeItemBiMap.clear();
     341    }
     342    dirtyMolItems.clear();
     343    visibilityMolItems.clear();
     344    visibilityGroupItems.clear();
     345    newMolecules.clear();
     346    removedMolecules.clear();
     347    toBeMovedItems.clear();
     348  }
    269349
    270350  const std::vector<const molecule*> &molecules =
    271351      const_cast<const World &>(World::getInstance()).getAllMolecules();
    272 
    273   clear();
    274   formula.clear();
    275   FormulaVisibilityCountMap.clear();
    276 //  LOG(1, "Clearing list.");
    277   MoleculeItemBiMap.clear();
    278   dirtyItems.clear();
    279   visibilityItems.clear();
    280   toBeMovedItems.clear();
    281   newItems.clear();
    282   toBeRemovedItems.clear();
    283   toBeSetOccurrenceItems.clear();
    284   toBeSetVisibilityItems.clear();
    285 
    286352  for (std::vector<const molecule*>::const_iterator iter = molecules.begin();
    287353      iter != molecules.end();
     
    289355    addMolecule(*iter);
    290356
    291   refill_mutex.unlock();
    292 
    293357  // activate timer
    294358  update_timer->start(1000/update_times_per_second);
     
    298362{
    299363  // get whether any items are dirty
    300   listAccessing_mutex.lock();
     364  boost::recursive_mutex::scoped_lock lock(listAccessing_mutex);
    301365  bool dirty = false;
    302   dirty |= !dirtyItems.empty();
    303   dirty |= !visibilityItems.empty();
    304   dirty |= !newItems.empty();
    305   dirty |= !toBeRemovedItems.empty();
    306   dirty |= !toBeSetOccurrenceItems.empty();
    307   dirty |= !toBeSetVisibilityItems.empty();
    308   listAccessing_mutex.unlock();
     366  dirty |= !dirtyMolItems.empty();
     367  dirty |= !visibilityMolItems.empty();
     368  dirty |= !dirtyGroupItems.empty();
     369  dirty |= !visibilityGroupItems.empty();
     370  dirty |= !newMolecules.empty();
     371  dirty |= !removedMolecules.empty();
     372  dirty |= !toBeMovedItems.empty();
    309373  return dirty;
    310374}
     
    325389//  qDebug() << "Item changed called.";
    326390
    327   if (_item->index().column() == QtMoleculeItemFactory::VISIBILITY) {
     391  boost::recursive_mutex::scoped_lock lock(refill_mutex);
     392  if (_item->index().column() == QtMoleculeItem::VISIBILITY) {
    328393//    qDebug() << "visibilityItem changed: " << (_item->checkState() ? "checked" : "unchecked");
    329     listAccessing_mutex.lock();
     394    boost::recursive_mutex::scoped_lock lock(listAccessing_mutex);
    330395    if ((_item->parent() == NULL) || (_item->parent() == invisibleRootItem()))
    331       toBeSetVisibilityItems.insert( _item );
     396      visibilityGroupItems.insert( std::make_pair(
     397          GroupItemToFormula(_item->parent()), QtMoleculeItem::VISIBILITY) );
    332398    else
    333       visibilityItems.insert( dynamic_cast<QtMoleculeItem *>(_item) );
    334     listAccessing_mutex.unlock();
     399      visibilityMolItems.insert(
     400          static_cast<QtMoleculeItem *>(_item)->getMoleculeId()
     401          );
    335402  }
    336403}
     
    341408    return;
    342409
     410  boost::recursive_mutex::scoped_lock lock(refill_mutex);
    343411  const bool visible = _item->checkState();
    344   const molecule * const mol = _item->getMolecule();
    345   std::string molecule_formula;
    346   if (mol != NULL) {
    347     molecule_formula = mol->getFormula().toString();
    348     ASSERT( FormulaVisibilityCountMap.count(molecule_formula) != 0,
     412  const moleculeId_t molid = _item->getMoleculeId();
     413  std::string molecule_formula("illegal");
     414  {
     415    boost::recursive_mutex::scoped_lock lock(map_mutex);
     416    MoleculeFormulaMap_t::const_iterator formulaiter =
     417        MoleculeFormulaMap.find(molid);
     418    ASSERT( formulaiter != MoleculeFormulaMap.end(),
     419        "QtMoleculeList::setVisibilityForMoleculeItem() - formula of molecule "
     420        +toString(molid)+" unknown.");
     421    molecule_formula = formulaiter->second;
     422  }
     423  ASSERT( FormulaVisibilityCountMap.count(molecule_formula) != 0,
    349424        "QtMoleculeList::setVisibilityForMoleculeItem() - molecule with formula " +molecule_formula
    350425        +" is not present in FormulaVisibilityCountMap.");
    351   }
    352426
    353427  // get parent
    354428  QStandardItem *groupItem = _item->parent();
    355   QStandardItem *visgroupItem =
    356       invisibleRootItem()->child(groupItem->index().row(), QtMoleculeItemFactory::VISIBILITY);
     429  QStandardItem *visgroupItem = getSpecificGroupItem(groupItem, QtMoleculeItem::VISIBILITY);
    357430  ASSERT( groupItem != NULL,
    358431      "QtMoleculeList::setVisibilityForMoleculeItem() - item with id "
     
    385458  ChangingChildrensVisibility = true;
    386459
     460  boost::recursive_mutex::scoped_lock lock(refill_mutex);
    387461  // go through all children, but don't enter for groupItem once more
    388462  const bool visible = _item->checkState();
    389   QStandardItem *groupitem = invisibleRootItem()->child(
    390       _item->index().row(), QtMoleculeItemFactory::NAME);
     463  QStandardItem *groupitem = getSpecificGroupItem(_item, QtMoleculeItem::NAME);
    391464  for (int i=0;i<groupitem->rowCount();++i) {
    392465    QtMoleculeItem *molItem = dynamic_cast<QtMoleculeItem *>(
    393         groupitem->child(i, QtMoleculeItemFactory::VISIBILITY));
     466        groupitem->child(i, QtMoleculeItem::VISIBILITY));
    394467    if (molItem->checkState() != visible) {
    395468      molItem->setCheckState(visible ? Qt::Checked : Qt::Unchecked);
     
    401474  // set current number of visible children
    402475  const std::string molecule_formula =
    403       invisibleRootItem()->child(_item->row(), QtMoleculeItemFactory::NAME)->text().toStdString();
     476      GroupItemToFormula( getSpecificGroupItem(_item, QtMoleculeItem::NAME) );
    404477  FormulaVisibilityCountMap_t::iterator countiter =
    405478      FormulaVisibilityCountMap.find(molecule_formula);
     
    416489  /*int idx = verticalHeaderItem(row)->data(Qt::UserRole).toInt();
    417490  molecule *mol = molecules->ReturnIndex(idx);
    418   string cellValue = item(row,QtMoleculeItemFactory::NAME)->text().toStdString();
     491  string cellValue = item(row,QtMoleculeItem::NAME)->text().toStdString();
    419492  if(mol->getName() != cellValue && cellValue !="") {
    420493    mol->setName(cellValue);
    421494  }
    422495  else if(cellValue==""){
    423     item(row,QtMoleculeItemFactory::NAME)->setText(QString(mol->getName().c_str()));
     496    item(row,QtMoleculeItem::NAME)->setText(QString(mol->getName().c_str()));
    424497  }*/
    425498}
     
    428501int QtMoleculeList::setOccurrence(QStandardItem * const _groupitem)
    429502{
     503  boost::recursive_mutex::scoped_lock lock(refill_mutex);
    430504  QModelIndex modelindex = _groupitem->index();
    431505  ASSERT( modelindex.isValid(),
     
    437511      "QtMoleculeList::setOccurrence() - group item at "+toString(index)
    438512      +" does not have a parent?");
    439   QStandardItem *occ_item = parent_item->child(index, QtMoleculeItemFactory::OCCURRENCE);
     513  QStandardItem *occ_item = parent_item->child(index, QtMoleculeItem::OCCURRENCE);
    440514  ASSERT( occ_item != NULL,
    441515      "QtMoleculeList::setOccurrence() - group item at "+toString(index)
     
    444518  if (count == 0) {
    445519    // we have to remove the group item completely
     520    boost::recursive_mutex::scoped_lock lock(map_mutex);
    446521    const std::string molecule_formula = _groupitem->text().toStdString();
    447     formula.erase(molecule_formula);
     522    FormulaItemBiMap.left.erase(molecule_formula);
    448523    FormulaVisibilityCountMap.erase(molecule_formula);
    449524    return index;
     
    454529}
    455530
    456 void QtMoleculeList::readdItem(QtMoleculeItem *_molitem)
    457 {
     531std::string QtMoleculeList::readdItem(QtMoleculeItem *_molitem)
     532{
     533  boost::recursive_mutex::scoped_lock lock(refill_mutex);
    458534  // use takeRows of molecule ..
    459535  QStandardItem *groupitem = _molitem->parent();
     
    461537      "QtMoleculeList::readdItem() - mol item at "+toString(_molitem->index().row())
    462538      +" does not have a groupitem?");
     539  const molecule * const mol = _molitem->getMolecule();
    463540  QList<QStandardItem *> mol_row = _molitem->parent()->takeRow(_molitem->index().row());
    464   // call setOccurrence on the old group later, if it's not a removal candidate
    465   if (groupitem->rowCount() != 0)
    466     addToBeSetOccurrence(groupitem);
    467541  // ..  and re-add where new formula fits
    468   const molecule * const mol = _molitem->getMolecule();
    469542  std::string molecule_formula;
    470543  if (mol != NULL) {
    471544    molecule_formula = mol->getFormula().toString();
    472     FormulaTreeItemMap_t::iterator iter = formula.find(molecule_formula);
    473     if (iter == formula.end()) {
     545    if (!isGroupItemPresent(molecule_formula)) {
    474546      // add new group item and formula entry
    475547       addGroupItem(groupitem, molecule_formula);
    476548    } else {
    477       groupitem = iter->second;
     549      groupitem = FormulaToGroupItem(molecule_formula);
    478550    }
    479551    ASSERT( groupitem != NULL,
     
    481553    // finally add again
    482554    groupitem->appendRow(mol_row);
    483   }
    484   // call setOccurrence on the new group later
    485   addToBeSetOccurrence(groupitem);
     555  } else {
     556    for (QList<QStandardItem *>::iterator iter = mol_row.begin();
     557        iter != mol_row.end(); ++iter)
     558      delete *iter;
     559  }
     560
     561  return molecule_formula;
    486562}
    487563
    488564void QtMoleculeList::informDirtyState(
    489     QtMoleculeItem *_item,
    490     const QtMoleculeItem::MoveTypes _type)
     565    const moleculeId_t _id,
     566    const QtMoleculeItem::COLUMNTYPES _type,
     567    const QtMoleculeItem::MoveTypes _movetype)
    491568{
    492569  listAccessing_mutex.lock();
    493   dirtyItems.insert(_item);
     570  dirtyMolItems.insert( std::make_pair(_id, _type) );
    494571  listAccessing_mutex.unlock();
    495572
    496   if (_type == QtMoleculeItem::NeedsMove) {
     573  if (_movetype == QtMoleculeItem::NeedsMove) {
    497574    // we have to convert whatever item raised the dirty signal to the first
    498575    // item in the row as otherwise multiple items in the row are selected
    499576    // as to be moved, i.e. the same row is moved multiple times
    500577    listAccessing_mutex.lock();
    501     toBeMovedItems.insert(_item);
     578    toBeMovedItems.insert(_id);
    502579    listAccessing_mutex.unlock();
    503 //    // add group item, too
    504 //    toBeSetOccurrenceItems.insert(group_item);
    505   }
    506 
     580  }
    507581}
    508582
     
    512586  // TODO: if we had move semantics ...
    513587  listAccessing_mutex.lock();
    514   list_of_items_t dirtyItems_copy = dirtyItems;
    515   dirtyItems.clear();
    516   list_of_items_t visibilityItems_copy = visibilityItems;
    517   visibilityItems.clear();
    518   list_of_items_t toBeMovedItems_copy = toBeMovedItems;
     588  list_of_molecule_items_t dirtyMolItems_copy = dirtyMolItems;
     589  dirtyMolItems.clear();
     590  list_of_molecules_t visibilityMolItems_copy = visibilityMolItems;
     591  visibilityMolItems.clear();
     592  list_of_group_items_t dirtyGroupItems_copy = dirtyGroupItems;
     593  dirtyGroupItems.clear();
     594  list_of_group_items_t visibilityGroupItems_copy = visibilityGroupItems;
     595  visibilityGroupItems.clear();
     596  std::vector<moleculeId_t> newMolecules_copy = newMolecules;
     597  newMolecules.clear();
     598  std::vector<moleculeId_t> removedMolecules_copy = removedMolecules;
     599  removedMolecules.clear();
     600  list_of_molecules_t toBeMovedItems_copy = toBeMovedItems;
    519601  toBeMovedItems.clear();
    520   std::vector<const molecule *> newItems_copy = newItems;
    521   newItems.clear();
    522   std::vector<const molecule *> toBeRemovedItems_copy = toBeRemovedItems;
    523   toBeRemovedItems.clear();
    524   std::set<QStandardItem*> toBeSetOccurrenceItems_copy = toBeSetOccurrenceItems;
    525   toBeSetOccurrenceItems.clear();
    526   std::set<QStandardItem*> toBeSetVisibilityItems_copy = toBeSetVisibilityItems;
    527   toBeSetVisibilityItems.clear();
    528602  listAccessing_mutex.unlock();
    529603
     
    534608  /// -# don't add molecule that are also removed
    535609
    536   //  // remove molecules added and removed immediately in both lists
    537   std::vector<const molecule *> addedremoved;
    538   std::sort(newItems_copy.begin(), newItems_copy.end());
    539   std::sort(toBeRemovedItems_copy.begin(), toBeRemovedItems_copy.end());
    540   std::set_intersection(
    541       newItems_copy.begin(), newItems_copy.end(),
    542       toBeRemovedItems_copy.begin(), toBeRemovedItems_copy.end(),
    543       std::back_inserter(addedremoved));
     610  // remove molecules added and removed immediately in both lists
     611  // note that newMolecules are all those where a moleculeInserted callback
     612  // has been received but not action has been taken (i.e. it is not contained
     613  // in any other list so far), toBeRemoved is inserted on moleculeRemoved
     614  // and other lists (toBeSetOccurrenceItems) are only filled if the molecule
     615  // item has already been instantiated.
    544616  {
    545     std::vector<const molecule *>::iterator removeiter = std::set_difference(
    546         newItems_copy.begin(), newItems_copy.end(),
    547         addedremoved.begin(), addedremoved.end(),
    548         newItems_copy.begin());
    549     newItems_copy.erase(removeiter, newItems_copy.end());
    550   }
    551   {
    552     std::vector<const molecule *>::iterator removeiter = std::set_difference(
    553         toBeRemovedItems_copy.begin(), toBeRemovedItems_copy.end(),
    554         addedremoved.begin(), addedremoved.end(),
    555         toBeRemovedItems_copy.begin());
    556     toBeRemovedItems_copy.erase(removeiter, toBeRemovedItems_copy.end());
    557   }
    558   addedremoved.clear();
     617    std::vector<moleculeId_t> addedremoved;
     618    std::sort(newMolecules_copy.begin(), newMolecules_copy.end());
     619    std::sort(removedMolecules_copy.begin(), removedMolecules_copy.end());
     620    std::set_intersection(
     621        newMolecules_copy.begin(), newMolecules_copy.end(),
     622        removedMolecules_copy.begin(), removedMolecules_copy.end(),
     623        std::back_inserter(addedremoved));
     624    {
     625      std::vector<moleculeId_t>::iterator removeiter = std::set_difference(
     626          newMolecules_copy.begin(), newMolecules_copy.end(),
     627          addedremoved.begin(), addedremoved.end(),
     628          newMolecules_copy.begin());
     629      newMolecules_copy.erase(removeiter, newMolecules_copy.end());
     630    }
     631    {
     632      std::vector<moleculeId_t>::iterator removeiter = std::set_difference(
     633          removedMolecules_copy.begin(), removedMolecules_copy.end(),
     634          addedremoved.begin(), addedremoved.end(),
     635          removedMolecules_copy.begin());
     636      removedMolecules_copy.erase(removeiter, removedMolecules_copy.end());
     637    }
     638  }
    559639
    560640  // wait till initial refill has been executed
    561   refill_mutex.lock();
    562 
    563   // convert ToBeMoved items from any position to first position item
    564   {
    565     list_of_items_t toBeMovedItems_copy_fronts;
    566     for (list_of_items_t::const_iterator moveiter = toBeMovedItems_copy.begin();
    567         moveiter != toBeMovedItems_copy.end(); ++moveiter) {
    568       QStandardItem *group_item = (*moveiter)->parent();
    569       QtMoleculeItem *mol_item =
    570           dynamic_cast<QtMoleculeItem *>(group_item->child((*moveiter)->row(), 0));
    571       toBeMovedItems_copy_fronts.insert( mol_item );
    572     }
    573     toBeMovedItems_copy = toBeMovedItems_copy_fronts;
    574   }
    575 
    576   for (std::vector<const molecule *>::iterator removeiter = toBeRemovedItems_copy.begin();
    577       removeiter != toBeRemovedItems_copy.end(); ++removeiter) {
    578     QtMoleculeItem *item = MoleculeIdToItem((*removeiter)->getId());
    579     dirtyItems_copy.erase(item);
    580     toBeMovedItems_copy.erase(item);
    581   }
    582   for (list_of_items_t::iterator visiter = visibilityItems_copy.begin();
    583       visiter != visibilityItems_copy.end(); ) {
    584     QtMoleculeItem * const _item = dynamic_cast<QtMoleculeItem *>(
    585         (*visiter)->parent()->child(
    586             (*visiter)->index().row(),
    587             QtMoleculeItemFactory::NAME));
    588     const moleculeId_t molid = ItemToMoleculeId(_item);
    589     const molecule *mol = const_cast<const World &>(World::getInstance()).
    590         getMolecule(MoleculeById(molid));
    591     if (std::binary_search(
    592             toBeRemovedItems_copy.begin(), toBeRemovedItems_copy.end(),
    593             mol))
    594       visibilityItems_copy.erase(visiter++);
    595     else
    596       ++visiter;
     641  boost::recursive_mutex::scoped_lock lock(refill_mutex);
     642
     643//  LOG(1, "Starting update.");
     644
     645  // remove removedMolecules from other lists.
     646  for (std::vector<moleculeId_t>::const_iterator removeiter = removedMolecules_copy.begin();
     647      removeiter != removedMolecules_copy.end(); ++removeiter) {
     648    for (unsigned int i=0;i< QtMoleculeItem::COLUMNTYPES_MAX; ++i)
     649        dirtyMolItems_copy.erase( std::make_pair(*removeiter,(QtMoleculeItem::COLUMNTYPES)i) );
     650    toBeMovedItems_copy.erase(*removeiter);
     651    visibilityMolItems_copy.erase(*removeiter);
    597652  }
    598653
    599654  /// 1a. do the update for each dirty item
    600   for (list_of_items_t::const_iterator dirtyiter = dirtyItems_copy.begin();
    601       dirtyiter != dirtyItems_copy.end(); ++dirtyiter) {
    602     LOG(1, "Updating item " << *dirtyiter);
    603     (*dirtyiter)->updateState();
     655  for (list_of_molecule_items_t::const_iterator dirtyiter = dirtyMolItems_copy.begin();
     656      dirtyiter != dirtyMolItems_copy.end(); ++dirtyiter) {
     657    if (!isMoleculeItemPresent(dirtyiter->first))
     658      continue;
     659    QtMoleculeItem * const mol_item =
     660        getSpecificMoleculeItem(
     661            MoleculeIdToItem(dirtyiter->first),
     662            dirtyiter->second);
     663//    LOG(1, "Updating item " << mol_item);
     664    mol_item->updateState();
    604665  }
    605666
    606667  /// 1b. do the visibility update for each dirty item
    607   for (list_of_items_t::const_iterator visiter = visibilityItems_copy.begin();
    608       visiter != visibilityItems_copy.end(); ++visiter) {
    609 //    LOG(1, "Updating visibility of item " << *visiter);
    610     ASSERT(((*visiter)->parent() != NULL) && ((*visiter)->parent() != invisibleRootItem()),
    611         "QtMoleculeList::updateItemStates() - a group item ended up in visibilityItems.");
    612     setVisibilityForMoleculeItem(*visiter);
     668  for (list_of_molecules_t::const_iterator visiter = visibilityMolItems_copy.begin();
     669      visiter != visibilityMolItems_copy.end(); ++visiter) {
     670    if (!isMoleculeItemPresent(*visiter))
     671      continue;
     672    QtMoleculeItem * const visitem =
     673      getSpecificMoleculeItem(
     674          MoleculeIdToItem(*visiter),
     675          QtMoleculeItem::VISIBILITY );
     676//    LOG(1, "Updating visibility of item " << visitem);
     677    setVisibilityForMoleculeItem(visitem);
    613678  }
    614679
    615680  /// 2. move all items that need to be moved
    616   for (list_of_items_t::const_iterator moveiter = toBeMovedItems_copy.begin();
     681  typedef std::set<std::string> formulas_t;
     682  formulas_t toBeSetOccurrence;
     683  for (list_of_molecules_t::const_iterator moveiter = toBeMovedItems_copy.begin();
    617684      moveiter != toBeMovedItems_copy.end(); ++moveiter) {
    618 //    LOG(1, "Moving item " << *moveiter);
    619     readdItem(*moveiter);
    620   }
     685    boost::recursive_mutex::scoped_lock lock(map_mutex);
     686//    LOG(1, "Moving item " << molitem);
     687    MoleculeFormulaMap_t::iterator formulaiter =
     688        MoleculeFormulaMap.find(*moveiter);
     689    ASSERT( formulaiter != MoleculeFormulaMap.end(),
     690        "QtMoleculeList::updateItemStates() - formula of molecule "
     691        +toString(*moveiter)+" unknown.");
     692//    LOG(1, "Adding " << formulaiter->second << " to toBeSetOccurrence.");
     693    toBeSetOccurrence.insert( formulaiter->second );
     694    if (!isMoleculeItemPresent(*moveiter))
     695      continue;
     696    QtMoleculeItem *const molitem = MoleculeIdToItem(*moveiter);
     697    LOG(1, "Moving item " << molitem);
     698    const molecule *mol = molitem->getMolecule();
     699    if (mol == NULL) {
     700      // removeMolecule will remove also from formula<->molecule bimap
     701      removeMoleculeItem(molitem);
     702    } else {
     703      // remove from formula<->molecule bimap with old formula
     704      LOG(1, "Removing " << formulaiter->second << " for " << formulaiter->first << " from MoleculeFormulaMap.");
     705      MoleculeFormulaMap.erase( formulaiter );
     706      const std::string formula = readdItem(molitem);
     707      // and add to formula<->molecule bimap with updated formula
     708      LOG(1, "Adding " << formula << " for " << *moveiter << " to MoleculeFormulaMap.");
     709      MoleculeFormulaMap.insert( std::make_pair(*moveiter, formula) );
     710//      LOG(1, "Adding " << formula << " to toBeSetOccurrence.");
     711      toBeSetOccurrence.insert( formula );
     712    }
     713  }
     714
     715  // throw out items that we added by an update() while we are in this function
     716  listAccessing_mutex.lock();
     717  for (std::vector<moleculeId_t>::const_iterator removeiter = removedMolecules_copy.begin();
     718      removeiter != removedMolecules_copy.end(); ++removeiter) {
     719    for (unsigned int i=0;i< QtMoleculeItem::COLUMNTYPES_MAX; ++i)
     720        dirtyMolItems.erase( std::make_pair(*removeiter,(QtMoleculeItem::COLUMNTYPES)i) );
     721    toBeMovedItems.erase(*removeiter);
     722    visibilityMolItems.erase(*removeiter);
     723  }
     724  listAccessing_mutex.unlock();
     725  // after that it is not a problem as items have been removed (hence signOff() was called)
    621726
    622727  /// 3. remove all items whose molecules have been removed
    623   for (std::vector<const molecule *>::const_iterator removeiter = toBeRemovedItems_copy.begin();
    624       removeiter != toBeRemovedItems_copy.end(); ++removeiter) {
    625 //    LOG(1, "Removing molecule " << *removeiter); // cannot access directly, molecule is gone
    626     QtMoleculeItem *item = MoleculeIdToItem((*removeiter)->getId());
    627     if (item != NULL)
    628       removeItem(item);
     728  for (std::vector<moleculeId_t>::const_iterator removeiter = removedMolecules_copy.begin();
     729      removeiter != removedMolecules_copy.end(); ++removeiter) {
     730//    LOG(1, "Removing molecule " << *removeiter);
     731    if (!isMoleculeItemPresent(*removeiter))
     732      continue;
     733    QtMoleculeItem *item = MoleculeIdToItem(*removeiter);
     734    if (item != NULL) {
     735      const std::string formula = item->parent()->text().toStdString();
     736//      LOG(1, "Adding " << formula << " to toBeSetOccurrence.");
     737      toBeSetOccurrence.insert( formula );
     738      removeMoleculeItem(item);
     739    }
    629740  }
    630741
    631742  /// 4. instantiate all new items
    632   for (std::vector<const molecule *>::const_iterator moliter = newItems_copy.begin();
    633       moliter != newItems_copy.end(); ++moliter) {
    634 //    LOG(1, "Adding molecule " << (*moliter)->getName());
     743  for (std::vector<moleculeId_t>::const_iterator moliter = newMolecules_copy.begin();
     744      moliter != newMolecules_copy.end(); ++moliter) {
     745//    LOG(1, "Adding molecule " << *moliter);
    635746    // check that World knows the molecule still
    636747    const molecule * const mol = const_cast<const World &>(World::getInstance()).
    637         getMolecule(MoleculeById((*moliter)->getId()));
    638     if ((mol != NULL) && (mol == *moliter)) {
    639       addMolecule(mol);
     748        getMolecule(MoleculeById(*moliter));
     749    if ((mol != NULL) && (mol->getId() == *moliter)) {
     750      const std::string formula = addMolecule(mol);;
     751//      LOG(1, "Adding " << formula << " to toBeSetOccurrence.");
     752      toBeSetOccurrence.insert( formula );
     753    } else {
     754      ELOG(2, "Molecule " << *moliter
     755          << " disappeared before we could render it in QtMoleculeList.");
    640756    }
    641757  }
     
    643759  /// 5a. update the group item's occurrence and visibility
    644760  std::set<int> RowsToRemove;
    645   for (std::set<QStandardItem*>::const_iterator groupiter = toBeSetOccurrenceItems_copy.begin();
    646       groupiter != toBeSetOccurrenceItems_copy.end(); ++groupiter) {
    647 //    LOG(1, "Updating group item " << *groupiter);
    648     const int index = setOccurrence(*groupiter);
    649     if (index != -1)
     761  for (std::set<std::string>::const_iterator groupiter = toBeSetOccurrence.begin();
     762      groupiter != toBeSetOccurrence.end(); ++groupiter) {
     763//    LOG(1, "Updating group item's occurence " << *groupiter);
     764    QStandardItem *groupitem = FormulaToGroupItem(*groupiter);
     765    const int index = setOccurrence(groupitem);
     766    if (index != -1) {
     767//      LOG(1, "Removing row of group item " << groupitem);
    650768      RowsToRemove.insert(index);
    651   }
     769    }
     770  }
     771  toBeSetOccurrence.clear();
    652772
    653773  // remove all visibility updates whose row is removed
    654   for (std::set<QStandardItem*>::iterator visiter = toBeSetVisibilityItems_copy.begin();
    655       visiter != toBeSetVisibilityItems_copy.end(); ) {
    656     if (RowsToRemove.count((*visiter)->index().row()) != 0)
    657       toBeSetVisibilityItems_copy.erase(visiter++);
    658     else
     774  for (list_of_group_items_t::iterator visiter = visibilityGroupItems_copy.begin();
     775      visiter != visibilityGroupItems_copy.end(); ) {
     776      QStandardItem * const groupitem = FormulaToGroupItem(visiter->first);
     777    if (RowsToRemove.count(groupitem->index().row()) != 0) {
     778//      LOG(1, "Removing vis item " << *visiter << " because of removed group item.");
     779      visibilityGroupItems_copy.erase(visiter++);
     780    } else
    659781      ++visiter;
    660782  }
    661783
    662784  // update visibility of all group items
    663   for (std::set<QStandardItem*>::iterator visiter = toBeSetVisibilityItems_copy.begin();
    664       visiter != toBeSetVisibilityItems_copy.end(); ++visiter) {
     785  for (list_of_group_items_t::iterator visiter = visibilityGroupItems_copy.begin();
     786      visiter != visibilityGroupItems_copy.end(); ++visiter) {
    665787//    LOG(1, "Updating visibility of item " << *visiter);
    666     setVisibilityForGroupItem(*visiter);
     788    QStandardItem * const groupitem =
     789        getSpecificGroupItem(FormulaToGroupItem(visiter->first),
     790        visiter->second);
     791    setVisibilityForGroupItem(groupitem);
    667792  }
    668793
     
    675800
    676801  // and done
    677   refill_mutex.unlock();
    678 }
     802//  LOG(1, "Done with update.");
     803}
Note: See TracChangeset for help on using the changeset viewer.