source: src/UIElements/Views/Qt4/MoleculeList/QtMoleculeList.cpp@ 27e464

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
Last change on this file since 27e464 was 2050b2, checked in by Frederik Heber <heber@…>, 10 years ago

Commented-out all debugging messages in QtMoleculeList rewrite.

  • Property mode set to 100644
File size: 23.0 KB
RevLine 
[bcf653]1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
[0aa122]4 * Copyright (C) 2010-2012 University of Bonn. All rights reserved.
[94d5ac6]5 *
6 *
7 * This file is part of MoleCuilder.
8 *
9 * MoleCuilder is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * MoleCuilder is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with MoleCuilder. If not, see <http://www.gnu.org/licenses/>.
[bcf653]21 */
22
[b47bfc]23/*
[0eb7bf3]24 * QtMoleculeList.cpp
[b47bfc]25 *
26 * Created on: Jan 21, 2010
27 * Author: crueger
28 */
29
[bf3817]30// include config.h
31#ifdef HAVE_CONFIG_H
32#include <config.h>
33#endif
[bbbad5]34
[f62e60]35#include "QtMoleculeList.hpp"
[b47bfc]36
[53c1ff]37#include <QModelIndex>
[2696b1]38#include <QDebug>
[41815a3]39
[53c1ff]40#include "UIElements/Views/Qt4/MoleculeList/QtMoleculeItem.hpp"
41#include "UIElements/Views/Qt4/MoleculeList/QtMoleculeItemFactory.hpp"
42
43#include <boost/bind.hpp>
[b47bfc]44#include <iostream>
45
[ad011c]46#include "CodePatterns/MemDebug.hpp"
[bbbad5]47
[53c1ff]48#include "CodePatterns/Log.hpp"
[6770fa]49#include "CodePatterns/Observer/Notification.hpp"
50
[6f0841]51#include "Atom/atom.hpp"
[d2dbb5d]52#include "Descriptors/MoleculeIdDescriptor.hpp"
[26cf17]53#include "Formula.hpp"
[b47bfc]54#include "molecule.hpp"
[42127c]55#include "MoleculeListClass.hpp"
[b47bfc]56
57using namespace std;
58
[53c1ff]59const unsigned int QtMoleculeList::update_times_per_second = 20;
[b47bfc]60
[8ccf3b]61QtMoleculeList::QtMoleculeList() :
[53c1ff]62 Observer("QtMoleculeList"),
63 changing(false),
64 ChangingChildrensVisibility(false),
65 list_accessing(false),
66 update_timer(NULL),
67 callback_DirtyItems(boost::bind(&QtMoleculeList::informDirtyState, this, _1, _2))
[b47bfc]68{
[53c1ff]69 setColumnCount(QtMoleculeItemFactory::COLUMNCOUNT);
[b47bfc]70
[3eb91c]71 World::getInstance().signOn(this, World::MoleculeInserted);
72 World::getInstance().signOn(this, World::MoleculeRemoved);
[41815a3]73
[a39006]74 refill();
[b47bfc]75
[8ccf3b]76// qRegisterMetaType<QItemSelection>("QItemSelection");
[79b59b]77 //connect(this,SIGNAL(cellChanged(int,int)),this,SLOT(moleculeChanged(int,int)));
[8ccf3b]78// connect(selectionModel(),SIGNAL(selectionChanged(QItemSelection, QItemSelection)),this,SLOT(rowsSelected(QItemSelection, QItemSelection)));
[2696b1]79 connect(this, SIGNAL(itemChanged(QStandardItem*)), this, SLOT(checkForVisibilityChange(QStandardItem*)));
[b47bfc]80}
81
[0eb7bf3]82QtMoleculeList::~QtMoleculeList()
[b47bfc]83{
[3eb91c]84 World::getInstance().signOff(this, World::MoleculeInserted);
85 World::getInstance().signOff(this, World::MoleculeRemoved);
[b47bfc]86}
87
[1c3390]88QVariant QtMoleculeList::headerData(int section, Qt::Orientation orientation, int role) const
89{
90 if (role == Qt::DisplayRole) {
91 if (orientation == Qt::Horizontal) {
[53c1ff]92 if (section < QtMoleculeItemFactory::COLUMNTYPES_MAX)
93 return QString(QtMoleculeItemFactory::COLUMNNAMES[section]);
[1c3390]94 }
95 }
96 return QVariant();
97}
98
[0eb7bf3]99void QtMoleculeList::update(Observable *publisher) {
[3eb91c]100 ASSERT(0,
101 "QtMoleculeList::update() - we did not sign up for any global updates.");
102}
103
[53c1ff]104QtMoleculeItem * QtMoleculeList::MoleculeToItem(const molecule * const _mol) const
[8ccf3b]105{
106 MoleculeItemBiMap_t::left_const_iterator iter =
107 MoleculeItemBiMap.left.find(_mol);
[d2dbb5d]108 if( iter != MoleculeItemBiMap.left.end())
109 return iter->second;
110 else
111 return NULL;
[8ccf3b]112}
113
[53c1ff]114const molecule * const QtMoleculeList::ItemToMolecule(const QtMoleculeItem * const _item) const
115{
116 const MoleculeItemBiMap_t::right_const_iterator iter =
117 MoleculeItemBiMap.right.find(const_cast<QtMoleculeItem * const>(_item));
[d2dbb5d]118 if (iter != MoleculeItemBiMap.right.end())
119 return iter->second;
120 else
121 return NULL;
[53c1ff]122}
123
124const molecule * const QtMoleculeList::IndexToMolecule(const QModelIndex &_index) const
125{
126 QtMoleculeItem * const item = dynamic_cast<QtMoleculeItem *>(itemFromIndex(_index));
127 if (item == NULL)
128 return NULL;
129 else
130 return ItemToMolecule(item);
131}
132
[6770fa]133void QtMoleculeList::recieveNotification(Observable *publisher, Notification_ptr notification)
134{
135 if (dynamic_cast<World *>(publisher) != NULL) {
136 switch (notification->getChannelNo()) {
137 case World::MoleculeInserted:
138 {
139 const molecule * const mol = World::getInstance().lastChanged<molecule>();
[53c1ff]140 while(list_accessing);
141 list_accessing = true;
142 newItems.push_back( mol );
143 list_accessing = false;
[6770fa]144 break;
145 }
146 case World::MoleculeRemoved:
147 {
148 const molecule * const mol = World::getInstance().lastChanged<molecule>();
[53c1ff]149
150 while(list_accessing);
151 list_accessing = true;
152 toBeRemovedItems.push_back( mol ); // remove in any case, as we also got insert
153 list_accessing = false;
154
155 const QtMoleculeItem *mol_item = MoleculeToItem(mol);
156 if (mol_item != NULL) {
157 QStandardItem *parent_item = mol_item->parent();
158 if (parent_item != NULL)
159 addToBeSetOccurrence( parent_item );
160 else
161 ELOG(2, "QtMoleculeList::recieveNotification() - item to molecule "
162 +toString(mol)+" has no parent.");
163 }
[6770fa]164 break;
165 }
166 default:
167 ASSERT(0, "QtMoleculeList::recieveNotification() - cannot get here, not subscribed to channel "
168 +toString(notification->getChannelNo()));
169 break;
170 }
171 }
[a39006]172}
173
[6770fa]174void QtMoleculeList::addGroupItem(
[8ccf3b]175 QStandardItem *&mainitem,
[6770fa]176 const std::string &_molecule_formula)
177{
[53c1ff]178 QList<QStandardItem *> groupItems =
179 QtMoleculeItemFactory::getInstance().createGroupItems(_molecule_formula);
180 mainitem = groupItems.front();
[8ccf3b]181 formula.insert( std::make_pair(_molecule_formula, mainitem) );
182 invisibleRootItem()->appendRow(groupItems);
[53c1ff]183}
184
185void QtMoleculeList::addToBeSetOccurrence(
186 QStandardItem *_groupitem)
187{
188 while (list_accessing);
189 list_accessing = true;
190 toBeSetOccurrenceItems.insert( _groupitem );
191 list_accessing = false;
[6770fa]192}
193
194void QtMoleculeList::addMoleculeItem(
[8ccf3b]195 QStandardItem *_groupitem,
[53c1ff]196 const molecule * const _mol,
[6770fa]197 const std::string &_molecule_formula)
198{
[53c1ff]199 QList<QStandardItem *> molItems =
200 QtMoleculeItemFactory::getInstance().createMoleculeItems(_mol, callback_DirtyItems);
201 QtMoleculeItem *mol_item = dynamic_cast<QtMoleculeItem *>(molItems.front());
202 ASSERT( mol_item != NULL,
203 "QtMoleculeList::addMoleculeItem() - item from factory was not a QtMoleculeItem?");
204 MoleculeItemBiMap.left.insert( std::make_pair(_mol, mol_item) );
[2050b2]205// LOG(1, "Inserting molecule " << _mol->getId() << ": " << _mol);
[8ccf3b]206 _groupitem->appendRow(molItems);
[53c1ff]207
208 // here update for the occurence will happen "one tick" later, but we don't
209 // have the groupitem any time earlier
210 addToBeSetOccurrence(_groupitem);
[6770fa]211}
212
[53c1ff]213void QtMoleculeList::addMolecule(const molecule * const _mol)
[6770fa]214{
215 // find group if already in list
[8ccf3b]216 QStandardItem *groupItem = NULL;
[6770fa]217
218 const std::string &molecule_formula = _mol->getFormula().toString();
219 FormulaTreeItemMap_t::const_iterator formulaiter =
220 formula.find(molecule_formula);
221
222 // new molecule type -> create new group
223 if (formulaiter == formula.end()){
224 // insert new formula entry into visibility
225#ifndef NDEBUG
226 std::pair< FormulaVisibilityCountMap_t::iterator, bool> visibilityinserter =
227#endif
228 FormulaVisibilityCountMap.insert(
229 std::make_pair( molecule_formula, (unsigned int)0) );
230 ASSERT( visibilityinserter.second,
231 "QtMoleculeList::refill() - molecule with formula "
232 +molecule_formula+" already in FormulaVisibilityCountMap.");
233
234 // create item and place into Map with formula as key
235 addGroupItem(groupItem, molecule_formula);
236 } else {
237 groupItem = formulaiter->second;
238 }
239 ASSERT( groupItem != NULL,
[53c1ff]240 "QtMoleculeList::addMolecule() - item with id "+toString(_mol->getId())
[6770fa]241 +" has not parent?");
242
243 // add molecule
244 addMoleculeItem(groupItem, _mol, molecule_formula);
245}
246
[53c1ff]247void QtMoleculeList::removeItem(QtMoleculeItem * const _item)
[6770fa]248{
[53c1ff]249 const QModelIndex mol_index = indexFromItem(_item);
250 QStandardItem *groupitem = _item->parent();
251 const QModelIndex group_index = groupitem->index();
252 removeRows(mol_index.row(), 1, group_index);
253 MoleculeItemBiMap_t::right_iterator removeiter =
254 MoleculeItemBiMap.right.find(_item);
255 ASSERT( removeiter != MoleculeItemBiMap.right.end(),
256 "QtMoleculeList::removeItem() - could not find item in BiMap.");
257 LOG(1, "Erasing molecule " << (removeiter->second));
258 MoleculeItemBiMap.right.erase(removeiter);
259
260 // don't need to, groupitem is already present in toBeSetOccurrenceItems
261// addToBeSetOccurrence(_groupitem);
262}
[6770fa]263
[53c1ff]264void QtMoleculeList::refill()
265{
266 // check timer's presence
267 if (update_timer == NULL) {
268 update_timer = new QTimer(this);
269 connect( update_timer, SIGNAL(timeout()), this, SLOT(checkState()));
270 } else
271 update_timer->stop();
[6770fa]272
[53c1ff]273 changing = true;
[3eb91c]274
[41815a3]275 const std::vector<molecule*> &molecules = World::getInstance().getAllMolecules();
276
[79b59b]277 clear();
[3eb91c]278 formula.clear();
279 FormulaVisibilityCountMap.clear();
[2050b2]280// LOG(1, "Clearing list.");
[8ccf3b]281 MoleculeItemBiMap.clear();
[53c1ff]282 dirtyItems.clear();
[2696b1]283 visibilityItems.clear();
[53c1ff]284 toBeMovedItems.clear();
285 newItems.clear();
286 toBeRemovedItems.clear();
287 toBeSetOccurrenceItems.clear();
[2696b1]288 toBeSetVisibilityItems.clear();
[79b59b]289
[41815a3]290 for (std::vector<molecule*>::const_iterator iter = molecules.begin();
291 iter != molecules.end();
[53c1ff]292 iter++)
293 addMolecule(*iter);
[b47bfc]294
[53c1ff]295 changing = false;
296
297 // activate timer
298 update_timer->start(1000/update_times_per_second);
[a39006]299}
300
[53c1ff]301bool QtMoleculeList::areAnyItemsDirty()
[a39006]302{
[53c1ff]303 // get whether any items are dirty
304 while (list_accessing);
305 list_accessing = true;
306 bool dirty = false;
307 dirty |= !dirtyItems.empty();
[2696b1]308 dirty |= !visibilityItems.empty();
[53c1ff]309 dirty |= !newItems.empty();
310 dirty |= !toBeRemovedItems.empty();
311 dirty |= !toBeSetOccurrenceItems.empty();
[2696b1]312 dirty |= !toBeSetVisibilityItems.empty();
[53c1ff]313 list_accessing = false;
314 return dirty;
[b47bfc]315}
316
[53c1ff]317void QtMoleculeList::checkState()
318{
319 const bool dirty = areAnyItemsDirty();
320 // update if required
321 if (dirty)
322 updateItemStates();
[b47bfc]323}
324
[53c1ff]325void QtMoleculeList::subjectKilled(Observable *publisher)
326{}
327
[2696b1]328void QtMoleculeList::checkForVisibilityChange(QStandardItem* _item)
[739ee9]329{
[2050b2]330// qDebug() << "Item changed called.";
[2696b1]331
332 if (_item->index().column() == QtMoleculeItemFactory::VISIBILITY) {
[2050b2]333// qDebug() << "visibilityItem changed: " << (_item->checkState() ? "checked" : "unchecked");
[2696b1]334 while(list_accessing);
335 list_accessing = true;
336 if ((_item->parent() == NULL) || (_item->parent() == invisibleRootItem()))
337 toBeSetVisibilityItems.insert( _item );
338 else
339 visibilityItems.insert( dynamic_cast<QtMoleculeItem *>(_item) );
340 list_accessing = false;
341 }
342}
[3eb91c]343
[2696b1]344void QtMoleculeList::setVisibilityForMoleculeItem(QtMoleculeItem* _item)
345{
346 if (ChangingChildrensVisibility)
347 return;
[3eb91c]348
[2696b1]349 const bool visible = _item->checkState();
350 const std::string &molecule_formula = _item->getMolecule()->getFormula().toString();
351 ASSERT( FormulaVisibilityCountMap.count(molecule_formula) != 0,
352 "QtMoleculeList::setVisibilityForMoleculeItem() - molecule with formula " +molecule_formula
353 +" is not present in FormulaVisibilityCountMap.");
[3eb91c]354
[2696b1]355 // get parent
356 QStandardItem *groupItem = _item->parent();
357 QStandardItem *visgroupItem =
358 invisibleRootItem()->child(groupItem->index().row(), QtMoleculeItemFactory::VISIBILITY);
359 ASSERT( groupItem != NULL,
360 "QtMoleculeList::setVisibilityForMoleculeItem() - item with id "
361 +toString(_item->getMolecule()->getId())+" has not parent?");
362 // check whether we have to set the group item
363
364 ChangingChildrensVisibility = true;
365 if (visible) {
366 ++(FormulaVisibilityCountMap[molecule_formula]);
367 // compare with occurence/total number of molecules
368 if (FormulaVisibilityCountMap[molecule_formula] ==
369 (unsigned int)(groupItem->rowCount()))
370 visgroupItem->setCheckState(Qt::Checked);
371 } else {
372 --(FormulaVisibilityCountMap[molecule_formula]);
373 // none selected anymore?
374 if (FormulaVisibilityCountMap[molecule_formula] == 0)
375 visgroupItem->setCheckState(Qt::Unchecked);
376 }
377 ChangingChildrensVisibility = false;
[3eb91c]378
[2696b1]379 emit moleculesVisibilityChanged(_item->getMolecule()->getId(), visible);
380}
[3eb91c]381
[2696b1]382void QtMoleculeList::setVisibilityForGroupItem(QStandardItem* _item)
383{
384 if (ChangingChildrensVisibility)
385 return;
386
387 ChangingChildrensVisibility = true;
388
389 // go through all children, but don't enter for groupItem once more
390 const bool visible = _item->checkState();
391 QStandardItem *groupitem = invisibleRootItem()->child(
392 _item->index().row(), QtMoleculeItemFactory::NAME);
393 for (int i=0;i<groupitem->rowCount();++i) {
394 QtMoleculeItem *molItem = dynamic_cast<QtMoleculeItem *>(
395 groupitem->child(i, QtMoleculeItemFactory::VISIBILITY));
396 if (molItem->checkState() != visible) {
397 molItem->setCheckState(visible ? Qt::Checked : Qt::Unchecked);
398
399 // emit signal
400 emit moleculesVisibilityChanged(molItem->getMolecule()->getId(), visible);
[3eb91c]401 }
[2696b1]402 }
403 // set current number of visible children
404 const std::string molecule_formula =
405 invisibleRootItem()->child(_item->row(), QtMoleculeItemFactory::NAME)->text().toStdString();
406 FormulaVisibilityCountMap_t::iterator countiter =
407 FormulaVisibilityCountMap.find(molecule_formula);
408 ASSERT( countiter != FormulaVisibilityCountMap.end(),
409 "QtMoleculeList::setVisibilityForGroupItem() - molecules "+molecule_formula
410 +" have no entry in visibility count map?");
411 countiter->second = visible ? groupitem->rowCount() : 0;
412
413 ChangingChildrensVisibility = false;
[739ee9]414}
[2696b1]415
[739ee9]416
[0eb7bf3]417void QtMoleculeList::moleculeChanged() {
[79b59b]418 /*int idx = verticalHeaderItem(row)->data(Qt::UserRole).toInt();
[b47bfc]419 molecule *mol = molecules->ReturnIndex(idx);
[53c1ff]420 string cellValue = item(row,QtMoleculeItemFactory::NAME)->text().toStdString();
[b47bfc]421 if(mol->getName() != cellValue && cellValue !="") {
422 mol->setName(cellValue);
423 }
424 else if(cellValue==""){
[53c1ff]425 item(row,QtMoleculeItemFactory::NAME)->setText(QString(mol->getName().c_str()));
[79b59b]426 }*/
[b47bfc]427}
428
[b14efe]429
[53c1ff]430int QtMoleculeList::setOccurrence(QStandardItem * const _groupitem)
431{
432 QModelIndex modelindex = _groupitem->index();
433 ASSERT( modelindex.isValid(),
434 "QtMoleculeList::setOccurrence() - groupitem not associated to model anymore.");
435 const int index = modelindex.row();
436 QStandardItem *parent_item =
437 _groupitem->parent() == NULL ? invisibleRootItem() : _groupitem->parent();
438 ASSERT( parent_item != NULL,
439 "QtMoleculeList::setOccurrence() - group item at "+toString(index)
440 +" does not have a parent?");
441 QStandardItem *occ_item = parent_item->child(index, QtMoleculeItemFactory::OCCURRENCE);
442 ASSERT( occ_item != NULL,
443 "QtMoleculeList::setOccurrence() - group item at "+toString(index)
444 +" does not have an occurrence?");
445 const int count = _groupitem->rowCount();
446 if (count == 0) {
447 // we have to remove the group item completely
448 const std::string molecule_formula = _groupitem->text().toStdString();
449 formula.erase(molecule_formula);
450 FormulaVisibilityCountMap.erase(molecule_formula);
451 return index;
452 } else {
453 occ_item->setText(QString::number(count));
454 return -1;
455 }
456}
457
458void QtMoleculeList::readdItem(QtMoleculeItem *_molitem)
459{
460 // use takeRows of molecule ..
461 QStandardItem *groupitem = _molitem->parent();
462 ASSERT( groupitem != NULL,
463 "QtMoleculeList::readdItem() - mol item at "+toString(_molitem->index().row())
464 +" does not have a groupitem?");
465 QList<QStandardItem *> mol_row = _molitem->parent()->takeRow(_molitem->index().row());
466 // call setOccurrence on the old group later
467 addToBeSetOccurrence(groupitem);
468 // .. and re-add where new formula fits
469 const std::string molecule_formula = _molitem->getMolecule()->getFormula().toString();
470 FormulaTreeItemMap_t::iterator iter = formula.find(molecule_formula);
471 if (iter == formula.end()) {
472 // add new group item and formula entry
473 addGroupItem(groupitem, molecule_formula);
474 } else {
475 groupitem = iter->second;
476 }
477 ASSERT( groupitem != NULL,
478 "QtMoleculeList::readdItem() - failed to create a sensible new groupitem");
479 // finally add again
480 groupitem->appendRow(mol_row);
481 // call setOccurrence on the new group later
482 addToBeSetOccurrence(groupitem);
483}
484
485void QtMoleculeList::informDirtyState(
486 QtMoleculeItem *_item,
487 const QtMoleculeItem::MoveTypes _type)
488{
489 while (list_accessing);
490 list_accessing = true;
491
492 dirtyItems.insert(_item);
493 if (_type == QtMoleculeItem::NeedsMove) {
494 // we have to convert whatever item raised the dirty signal to the first
495 // item in the row as otherwise multiple items in the row are selected
496 // as to be moved, i.e. the same row is moved multiple times
497 QStandardItem *group_item = _item->parent();
498 QtMoleculeItem *mol_item =
499 dynamic_cast<QtMoleculeItem *>(group_item->child(_item->row(), 0));
500 toBeMovedItems.insert(mol_item);
501// // add group item, too
502// toBeSetOccurrenceItems.insert(group_item);
503 }
504
505 list_accessing = false;
506}
507
508void QtMoleculeList::updateItemStates()
509{
510 // wait till initial refill has been executed
511 if (changing)
[41815a3]512 return;
513
[53c1ff]514 changing = true;
515
516 /// copy lists such that new signals for dirty/.. may come in right away
517 // TODO: if we had move semantics ...
518 while (list_accessing);
519 list_accessing = true;
520 list_of_items_t dirtyItems_copy = dirtyItems;
521 dirtyItems.clear();
[2696b1]522 list_of_items_t visibilityItems_copy = visibilityItems;
523 visibilityItems.clear();
[53c1ff]524 list_of_items_t toBeMovedItems_copy = toBeMovedItems;
525 toBeMovedItems.clear();
526 std::vector<const molecule *> newItems_copy = newItems;
527 newItems.clear();
528 std::vector<const molecule *> toBeRemovedItems_copy = toBeRemovedItems;
529 toBeRemovedItems.clear();
530 std::set<QStandardItem*> toBeSetOccurrenceItems_copy = toBeSetOccurrenceItems;
531 toBeSetOccurrenceItems.clear();
[2696b1]532 std::set<QStandardItem*> toBeSetVisibilityItems_copy = toBeSetVisibilityItems;
533 toBeSetVisibilityItems.clear();
[53c1ff]534 list_accessing = false;
535
536 /// first check consistency among the sets:
537 /// -# if we remove an item, we don't have to update it before anymore
538 /// -# if we remove an item, we don't have to move it before anymore
539 /// -# if we remove an item, we don't have to change its visibility
540 /// -# don't add molecule that are also removed
541
542 // // remove molecules added and removed immediately in both lists
543 std::vector<const molecule *> addedremoved;
544 std::sort(newItems_copy.begin(), newItems_copy.end());
545 std::sort(toBeRemovedItems_copy.begin(), toBeRemovedItems_copy.end());
546 std::set_intersection(
547 newItems_copy.begin(), newItems_copy.end(),
548 toBeRemovedItems_copy.begin(), toBeRemovedItems_copy.end(),
549 std::back_inserter(addedremoved));
[d7cad1]550 {
[53c1ff]551 std::vector<const molecule *>::iterator removeiter = std::set_difference(
552 newItems_copy.begin(), newItems_copy.end(),
553 addedremoved.begin(), addedremoved.end(),
554 newItems_copy.begin());
555 newItems_copy.erase(removeiter, newItems_copy.end());
[d7cad1]556 }
557 {
[53c1ff]558 std::vector<const molecule *>::iterator removeiter = std::set_difference(
559 toBeRemovedItems_copy.begin(), toBeRemovedItems_copy.end(),
560 addedremoved.begin(), addedremoved.end(),
561 toBeRemovedItems_copy.begin());
562 toBeRemovedItems_copy.erase(removeiter, toBeRemovedItems_copy.end());
[d7cad1]563 }
[53c1ff]564 addedremoved.clear();
[41815a3]565
[53c1ff]566 for (std::vector<const molecule *>::iterator removeiter = toBeRemovedItems_copy.begin();
567 removeiter != toBeRemovedItems_copy.end(); ++removeiter) {
568 QtMoleculeItem *item = MoleculeToItem(*removeiter);
569 dirtyItems_copy.erase(item);
570 toBeMovedItems_copy.erase(item);
571 }
[2696b1]572 for (list_of_items_t::iterator visiter = visibilityItems_copy.begin();
573 visiter != visibilityItems_copy.end(); ) {
574 QtMoleculeItem * const _item = dynamic_cast<QtMoleculeItem *>(
575 (*visiter)->parent()->child(
576 (*visiter)->index().row(),
577 QtMoleculeItemFactory::NAME));
578 const molecule *mol = ItemToMolecule(_item);
579 if (std::binary_search(
580 toBeRemovedItems_copy.begin(), toBeRemovedItems_copy.end(),
581 mol))
582 visibilityItems_copy.erase(visiter++);
583 else
584 ++visiter;
585 }
[8ccf3b]586
[2696b1]587 /// 1a. do the update for each dirty item
[53c1ff]588 for (list_of_items_t::const_iterator dirtyiter = dirtyItems_copy.begin();
589 dirtyiter != dirtyItems_copy.end(); ++dirtyiter) {
590 LOG(1, "Updating item " << *dirtyiter);
591 (*dirtyiter)->updateState();
592 }
593
[2696b1]594 /// 1b. do the visibility update for each dirty item
595 for (list_of_items_t::const_iterator visiter = visibilityItems_copy.begin();
596 visiter != visibilityItems_copy.end(); ++visiter) {
[2050b2]597// LOG(1, "Updating visibility of item " << *visiter);
[2696b1]598 ASSERT(((*visiter)->parent() != NULL) && ((*visiter)->parent() != invisibleRootItem()),
599 "QtMoleculeList::updateItemStates() - a group item ended up in visibilityItems.");
600 setVisibilityForMoleculeItem(*visiter);
601 }
602
[53c1ff]603 /// 2. move all items that need to be moved
604 for (list_of_items_t::const_iterator moveiter = toBeMovedItems_copy.begin();
605 moveiter != toBeMovedItems_copy.end(); ++moveiter) {
[2050b2]606// LOG(1, "Moving item " << *moveiter);
[53c1ff]607 readdItem(*moveiter);
608 }
609
610 /// 3. remove all items whose molecules have been removed
611 for (std::vector<const molecule *>::const_iterator removeiter = toBeRemovedItems_copy.begin();
612 removeiter != toBeRemovedItems_copy.end(); ++removeiter) {
[2050b2]613// LOG(1, "Removing molecule " << *removeiter); // cannot access directly, molecule is gone
[53c1ff]614 QtMoleculeItem *item = MoleculeToItem(*removeiter);
615 if (item != NULL)
616 removeItem(item);
617 }
618
619 /// 4. instantiate all new items
620 for (std::vector<const molecule *>::const_iterator moliter = newItems_copy.begin();
621 moliter != newItems_copy.end(); ++moliter) {
[2050b2]622// LOG(1, "Adding molecule " << (*moliter)->getName());
[53c1ff]623 // check that World knows the molecule still
624 const molecule * const mol =
625 World::getInstance().getMolecule(MoleculeById((*moliter)->getId()));
626 if ((mol != NULL) && (mol == *moliter)) {
627 addMolecule(mol);
628 }
629 }
630
[2696b1]631 /// 5a. update the group item's occurrence and visibility
[53c1ff]632 std::set<int> RowsToRemove;
633 for (std::set<QStandardItem*>::const_iterator groupiter = toBeSetOccurrenceItems_copy.begin();
634 groupiter != toBeSetOccurrenceItems_copy.end(); ++groupiter) {
[2050b2]635// LOG(1, "Updating group item " << *groupiter);
[53c1ff]636 const int index = setOccurrence(*groupiter);
637 if (index != -1)
638 RowsToRemove.insert(index);
639 }
640
[2696b1]641 // remove all visibility updates whose row is removed
642 for (std::set<QStandardItem*>::iterator visiter = toBeSetVisibilityItems_copy.begin();
643 visiter != toBeSetVisibilityItems_copy.end(); ) {
644 if (RowsToRemove.count((*visiter)->index().row()) != 0)
645 toBeSetVisibilityItems_copy.erase(visiter++);
646 else
647 ++visiter;
648 }
649
650 // update visibility of all group items
651 for (std::set<QStandardItem*>::iterator visiter = toBeSetVisibilityItems_copy.begin();
652 visiter != toBeSetVisibilityItems_copy.end(); ++visiter) {
[2050b2]653// LOG(1, "Updating visibility of item " << *visiter);
[2696b1]654 setVisibilityForGroupItem(*visiter);
655 }
656
[53c1ff]657 /// 5b. remove all rows with 0 occurrence starting from last
658 for (std::set<int>::reverse_iterator riter = RowsToRemove.rbegin();
659 riter != RowsToRemove.rend(); ++riter) {
[2050b2]660// LOG(1, "Removing group item at row " << *riter);
[53c1ff]661 removeRows(*riter, 1, invisibleRootItem()->index());
662 }
663
664 // and done
665 changing = false;
666}
Note: See TracBrowser for help on using the repository browser.