source: src/UIElements/Views/Qt4/MoleculeList/QtMoleculeList.cpp@ 6b474e

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 6b474e was 69b434, checked in by Frederik Heber <heber@…>, 10 years ago

QtMoleculeItem now uses moleculeId_t instead molecule*.

  • Property mode set to 100644
File size: 23.2 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2010-2012 University of Bonn. All rights reserved.
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/>.
21 */
22
23/*
24 * QtMoleculeList.cpp
25 *
26 * Created on: Jan 21, 2010
27 * Author: crueger
28 */
29
30// include config.h
31#ifdef HAVE_CONFIG_H
32#include <config.h>
33#endif
34
35#include "QtMoleculeList.hpp"
36
37#include <QModelIndex>
38#include <QDebug>
39
40#include "UIElements/Views/Qt4/MoleculeList/QtMoleculeItem.hpp"
41#include "UIElements/Views/Qt4/MoleculeList/QtMoleculeItemFactory.hpp"
42
43#include <boost/bind.hpp>
44#include <iostream>
45
46#include "CodePatterns/MemDebug.hpp"
47
48#include "CodePatterns/Log.hpp"
49#include "CodePatterns/Observer/Notification.hpp"
50
51#include "Atom/atom.hpp"
52#include "Descriptors/MoleculeIdDescriptor.hpp"
53#include "Formula.hpp"
54#include "molecule.hpp"
55#include "MoleculeListClass.hpp"
56
57using namespace std;
58
59const unsigned int QtMoleculeList::update_times_per_second = 20;
60
61QtMoleculeList::QtMoleculeList() :
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))
68{
69 setColumnCount(QtMoleculeItemFactory::COLUMNCOUNT);
70
71 World::getInstance().signOn(this, World::MoleculeInserted);
72 World::getInstance().signOn(this, World::MoleculeRemoved);
73
74 refill();
75
76// qRegisterMetaType<QItemSelection>("QItemSelection");
77 //connect(this,SIGNAL(cellChanged(int,int)),this,SLOT(moleculeChanged(int,int)));
78// connect(selectionModel(),SIGNAL(selectionChanged(QItemSelection, QItemSelection)),this,SLOT(rowsSelected(QItemSelection, QItemSelection)));
79 connect(this, SIGNAL(itemChanged(QStandardItem*)), this, SLOT(checkForVisibilityChange(QStandardItem*)));
80}
81
82QtMoleculeList::~QtMoleculeList()
83{
84 World::getInstance().signOff(this, World::MoleculeInserted);
85 World::getInstance().signOff(this, World::MoleculeRemoved);
86}
87
88QVariant QtMoleculeList::headerData(int section, Qt::Orientation orientation, int role) const
89{
90 if (role == Qt::DisplayRole) {
91 if (orientation == Qt::Horizontal) {
92 if (section < QtMoleculeItemFactory::COLUMNTYPES_MAX)
93 return QString(QtMoleculeItemFactory::COLUMNNAMES[section]);
94 }
95 }
96 return QVariant();
97}
98
99void QtMoleculeList::update(Observable *publisher) {
100 ASSERT(0,
101 "QtMoleculeList::update() - we did not sign up for any global updates.");
102}
103
104QtMoleculeItem * QtMoleculeList::MoleculeIdToItem(const moleculeId_t _molid) const
105{
106 MoleculeItemBiMap_t::left_const_iterator iter =
107 MoleculeItemBiMap.left.find(_molid);
108 if( iter != MoleculeItemBiMap.left.end())
109 return iter->second;
110 else
111 return NULL;
112}
113
114const moleculeId_t QtMoleculeList::ItemToMoleculeId(const QtMoleculeItem * const _item) const
115{
116 const MoleculeItemBiMap_t::right_const_iterator iter =
117 MoleculeItemBiMap.right.find(const_cast<QtMoleculeItem * const>(_item));
118 if (iter != MoleculeItemBiMap.right.end())
119 return iter->second;
120 else
121 return -1;
122}
123
124const moleculeId_t QtMoleculeList::IndexToMoleculeId(const QModelIndex &_index) const
125{
126 QtMoleculeItem * const item = dynamic_cast<QtMoleculeItem *>(itemFromIndex(_index));
127 if (item == NULL)
128 return -1;
129 else
130 return ItemToMoleculeId(item);
131}
132
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>();
140 while(list_accessing);
141 list_accessing = true;
142 newItems.push_back( mol );
143 list_accessing = false;
144 break;
145 }
146 case World::MoleculeRemoved:
147 {
148 const molecule * const mol = World::getInstance().lastChanged<molecule>();
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 = MoleculeIdToItem(mol->getId());
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 }
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 }
172}
173
174void QtMoleculeList::addGroupItem(
175 QStandardItem *&mainitem,
176 const std::string &_molecule_formula)
177{
178 QList<QStandardItem *> groupItems =
179 QtMoleculeItemFactory::getInstance().createGroupItems(_molecule_formula);
180 mainitem = groupItems.front();
181 formula.insert( std::make_pair(_molecule_formula, mainitem) );
182 invisibleRootItem()->appendRow(groupItems);
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;
192}
193
194void QtMoleculeList::addMoleculeItem(
195 QStandardItem *_groupitem,
196 const moleculeId_t _molid,
197 const std::string &_molecule_formula)
198{
199 QList<QStandardItem *> molItems =
200 QtMoleculeItemFactory::getInstance().createMoleculeItems(_molid, 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(_molid, mol_item) );
205// LOG(1, "Inserting molecule " << _mol->getId() << ": " << _mol);
206 _groupitem->appendRow(molItems);
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);
211}
212
213void QtMoleculeList::addMolecule(const molecule * const _mol)
214{
215 // find group if already in list
216 QStandardItem *groupItem = NULL;
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,
240 "QtMoleculeList::addMolecule() - item with id "+toString(_mol->getId())
241 +" has not parent?");
242
243 // add molecule
244 addMoleculeItem(groupItem, _mol->getId(), molecule_formula);
245}
246
247void QtMoleculeList::removeItem(QtMoleculeItem * const _item)
248{
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}
263
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();
272
273 changing = true;
274
275 const std::vector<molecule*> &molecules = World::getInstance().getAllMolecules();
276
277 clear();
278 formula.clear();
279 FormulaVisibilityCountMap.clear();
280// LOG(1, "Clearing list.");
281 MoleculeItemBiMap.clear();
282 dirtyItems.clear();
283 visibilityItems.clear();
284 toBeMovedItems.clear();
285 newItems.clear();
286 toBeRemovedItems.clear();
287 toBeSetOccurrenceItems.clear();
288 toBeSetVisibilityItems.clear();
289
290 for (std::vector<molecule*>::const_iterator iter = molecules.begin();
291 iter != molecules.end();
292 iter++)
293 addMolecule(*iter);
294
295 changing = false;
296
297 // activate timer
298 update_timer->start(1000/update_times_per_second);
299}
300
301bool QtMoleculeList::areAnyItemsDirty()
302{
303 // get whether any items are dirty
304 while (list_accessing);
305 list_accessing = true;
306 bool dirty = false;
307 dirty |= !dirtyItems.empty();
308 dirty |= !visibilityItems.empty();
309 dirty |= !newItems.empty();
310 dirty |= !toBeRemovedItems.empty();
311 dirty |= !toBeSetOccurrenceItems.empty();
312 dirty |= !toBeSetVisibilityItems.empty();
313 list_accessing = false;
314 return dirty;
315}
316
317void QtMoleculeList::checkState()
318{
319 const bool dirty = areAnyItemsDirty();
320 // update if required
321 if (dirty)
322 updateItemStates();
323}
324
325void QtMoleculeList::subjectKilled(Observable *publisher)
326{}
327
328void QtMoleculeList::checkForVisibilityChange(QStandardItem* _item)
329{
330// qDebug() << "Item changed called.";
331
332 if (_item->index().column() == QtMoleculeItemFactory::VISIBILITY) {
333// qDebug() << "visibilityItem changed: " << (_item->checkState() ? "checked" : "unchecked");
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}
343
344void QtMoleculeList::setVisibilityForMoleculeItem(QtMoleculeItem* _item)
345{
346 if (ChangingChildrensVisibility)
347 return;
348
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.");
354
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;
378
379 emit moleculesVisibilityChanged(_item->getMolecule()->getId(), visible);
380}
381
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);
401 }
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;
414}
415
416
417void QtMoleculeList::moleculeChanged() {
418 /*int idx = verticalHeaderItem(row)->data(Qt::UserRole).toInt();
419 molecule *mol = molecules->ReturnIndex(idx);
420 string cellValue = item(row,QtMoleculeItemFactory::NAME)->text().toStdString();
421 if(mol->getName() != cellValue && cellValue !="") {
422 mol->setName(cellValue);
423 }
424 else if(cellValue==""){
425 item(row,QtMoleculeItemFactory::NAME)->setText(QString(mol->getName().c_str()));
426 }*/
427}
428
429
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, if it's not a removal candidate
467 if (groupitem->rowCount() != 0)
468 addToBeSetOccurrence(groupitem);
469 // .. and re-add where new formula fits
470 const std::string molecule_formula = _molitem->getMolecule()->getFormula().toString();
471 FormulaTreeItemMap_t::iterator iter = formula.find(molecule_formula);
472 if (iter == formula.end()) {
473 // add new group item and formula entry
474 addGroupItem(groupitem, molecule_formula);
475 } else {
476 groupitem = iter->second;
477 }
478 ASSERT( groupitem != NULL,
479 "QtMoleculeList::readdItem() - failed to create a sensible new groupitem");
480 // finally add again
481 groupitem->appendRow(mol_row);
482 // call setOccurrence on the new group later
483 addToBeSetOccurrence(groupitem);
484}
485
486void QtMoleculeList::informDirtyState(
487 QtMoleculeItem *_item,
488 const QtMoleculeItem::MoveTypes _type)
489{
490 while (list_accessing);
491 list_accessing = true;
492
493 dirtyItems.insert(_item);
494 if (_type == QtMoleculeItem::NeedsMove) {
495 // we have to convert whatever item raised the dirty signal to the first
496 // item in the row as otherwise multiple items in the row are selected
497 // as to be moved, i.e. the same row is moved multiple times
498 QStandardItem *group_item = _item->parent();
499 QtMoleculeItem *mol_item =
500 dynamic_cast<QtMoleculeItem *>(group_item->child(_item->row(), 0));
501 toBeMovedItems.insert(mol_item);
502// // add group item, too
503// toBeSetOccurrenceItems.insert(group_item);
504 }
505
506 list_accessing = false;
507}
508
509void QtMoleculeList::updateItemStates()
510{
511 // wait till initial refill has been executed
512 if (changing)
513 return;
514
515 changing = true;
516
517 /// copy lists such that new signals for dirty/.. may come in right away
518 // TODO: if we had move semantics ...
519 while (list_accessing);
520 list_accessing = true;
521 list_of_items_t dirtyItems_copy = dirtyItems;
522 dirtyItems.clear();
523 list_of_items_t visibilityItems_copy = visibilityItems;
524 visibilityItems.clear();
525 list_of_items_t toBeMovedItems_copy = toBeMovedItems;
526 toBeMovedItems.clear();
527 std::vector<const molecule *> newItems_copy = newItems;
528 newItems.clear();
529 std::vector<const molecule *> toBeRemovedItems_copy = toBeRemovedItems;
530 toBeRemovedItems.clear();
531 std::set<QStandardItem*> toBeSetOccurrenceItems_copy = toBeSetOccurrenceItems;
532 toBeSetOccurrenceItems.clear();
533 std::set<QStandardItem*> toBeSetVisibilityItems_copy = toBeSetVisibilityItems;
534 toBeSetVisibilityItems.clear();
535 list_accessing = false;
536
537 /// first check consistency among the sets:
538 /// -# if we remove an item, we don't have to update it before anymore
539 /// -# if we remove an item, we don't have to move it before anymore
540 /// -# if we remove an item, we don't have to change its visibility
541 /// -# don't add molecule that are also removed
542
543 // // remove molecules added and removed immediately in both lists
544 std::vector<const molecule *> addedremoved;
545 std::sort(newItems_copy.begin(), newItems_copy.end());
546 std::sort(toBeRemovedItems_copy.begin(), toBeRemovedItems_copy.end());
547 std::set_intersection(
548 newItems_copy.begin(), newItems_copy.end(),
549 toBeRemovedItems_copy.begin(), toBeRemovedItems_copy.end(),
550 std::back_inserter(addedremoved));
551 {
552 std::vector<const molecule *>::iterator removeiter = std::set_difference(
553 newItems_copy.begin(), newItems_copy.end(),
554 addedremoved.begin(), addedremoved.end(),
555 newItems_copy.begin());
556 newItems_copy.erase(removeiter, newItems_copy.end());
557 }
558 {
559 std::vector<const molecule *>::iterator removeiter = std::set_difference(
560 toBeRemovedItems_copy.begin(), toBeRemovedItems_copy.end(),
561 addedremoved.begin(), addedremoved.end(),
562 toBeRemovedItems_copy.begin());
563 toBeRemovedItems_copy.erase(removeiter, toBeRemovedItems_copy.end());
564 }
565 addedremoved.clear();
566
567 for (std::vector<const molecule *>::iterator removeiter = toBeRemovedItems_copy.begin();
568 removeiter != toBeRemovedItems_copy.end(); ++removeiter) {
569 QtMoleculeItem *item = MoleculeIdToItem((*removeiter)->getId());
570 dirtyItems_copy.erase(item);
571 toBeMovedItems_copy.erase(item);
572 }
573 for (list_of_items_t::iterator visiter = visibilityItems_copy.begin();
574 visiter != visibilityItems_copy.end(); ) {
575 QtMoleculeItem * const _item = dynamic_cast<QtMoleculeItem *>(
576 (*visiter)->parent()->child(
577 (*visiter)->index().row(),
578 QtMoleculeItemFactory::NAME));
579 const moleculeId_t molid = ItemToMoleculeId(_item);
580 const molecule *mol = World::getInstance().getMolecule(MoleculeById(molid));
581 if (std::binary_search(
582 toBeRemovedItems_copy.begin(), toBeRemovedItems_copy.end(),
583 mol))
584 visibilityItems_copy.erase(visiter++);
585 else
586 ++visiter;
587 }
588
589 /// 1a. do the update for each dirty item
590 for (list_of_items_t::const_iterator dirtyiter = dirtyItems_copy.begin();
591 dirtyiter != dirtyItems_copy.end(); ++dirtyiter) {
592 LOG(1, "Updating item " << *dirtyiter);
593 (*dirtyiter)->updateState();
594 }
595
596 /// 1b. do the visibility update for each dirty item
597 for (list_of_items_t::const_iterator visiter = visibilityItems_copy.begin();
598 visiter != visibilityItems_copy.end(); ++visiter) {
599// LOG(1, "Updating visibility of item " << *visiter);
600 ASSERT(((*visiter)->parent() != NULL) && ((*visiter)->parent() != invisibleRootItem()),
601 "QtMoleculeList::updateItemStates() - a group item ended up in visibilityItems.");
602 setVisibilityForMoleculeItem(*visiter);
603 }
604
605 /// 2. move all items that need to be moved
606 for (list_of_items_t::const_iterator moveiter = toBeMovedItems_copy.begin();
607 moveiter != toBeMovedItems_copy.end(); ++moveiter) {
608// LOG(1, "Moving item " << *moveiter);
609 readdItem(*moveiter);
610 }
611
612 /// 3. remove all items whose molecules have been removed
613 for (std::vector<const molecule *>::const_iterator removeiter = toBeRemovedItems_copy.begin();
614 removeiter != toBeRemovedItems_copy.end(); ++removeiter) {
615// LOG(1, "Removing molecule " << *removeiter); // cannot access directly, molecule is gone
616 QtMoleculeItem *item = MoleculeIdToItem((*removeiter)->getId());
617 if (item != NULL)
618 removeItem(item);
619 }
620
621 /// 4. instantiate all new items
622 for (std::vector<const molecule *>::const_iterator moliter = newItems_copy.begin();
623 moliter != newItems_copy.end(); ++moliter) {
624// LOG(1, "Adding molecule " << (*moliter)->getName());
625 // check that World knows the molecule still
626 const molecule * const mol =
627 World::getInstance().getMolecule(MoleculeById((*moliter)->getId()));
628 if ((mol != NULL) && (mol == *moliter)) {
629 addMolecule(mol);
630 }
631 }
632
633 /// 5a. update the group item's occurrence and visibility
634 std::set<int> RowsToRemove;
635 for (std::set<QStandardItem*>::const_iterator groupiter = toBeSetOccurrenceItems_copy.begin();
636 groupiter != toBeSetOccurrenceItems_copy.end(); ++groupiter) {
637// LOG(1, "Updating group item " << *groupiter);
638 const int index = setOccurrence(*groupiter);
639 if (index != -1)
640 RowsToRemove.insert(index);
641 }
642
643 // remove all visibility updates whose row is removed
644 for (std::set<QStandardItem*>::iterator visiter = toBeSetVisibilityItems_copy.begin();
645 visiter != toBeSetVisibilityItems_copy.end(); ) {
646 if (RowsToRemove.count((*visiter)->index().row()) != 0)
647 toBeSetVisibilityItems_copy.erase(visiter++);
648 else
649 ++visiter;
650 }
651
652 // update visibility of all group items
653 for (std::set<QStandardItem*>::iterator visiter = toBeSetVisibilityItems_copy.begin();
654 visiter != toBeSetVisibilityItems_copy.end(); ++visiter) {
655// LOG(1, "Updating visibility of item " << *visiter);
656 setVisibilityForGroupItem(*visiter);
657 }
658
659 /// 5b. remove all rows with 0 occurrence starting from last
660 for (std::set<int>::reverse_iterator riter = RowsToRemove.rbegin();
661 riter != RowsToRemove.rend(); ++riter) {
662// LOG(1, "Removing group item at row " << *riter);
663 removeRows(*riter, 1, invisibleRootItem()->index());
664 }
665
666 // and done
667 changing = false;
668}
Note: See TracBrowser for help on using the repository browser.