source: src/UIElements/Views/Qt4/MoleculeList/QtMoleculeList.cpp@ 9d4f964

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 9d4f964 was 1259df, checked in by Frederik Heber <heber@…>, 10 years ago

Replaced World::getAllMolecules() wherever possible by const version.

  • Property mode set to 100644
File size: 23.3 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<const molecule*> &molecules =
276 const_cast<const World &>(World::getInstance()).getAllMolecules();
277
278 clear();
279 formula.clear();
280 FormulaVisibilityCountMap.clear();
281// LOG(1, "Clearing list.");
282 MoleculeItemBiMap.clear();
283 dirtyItems.clear();
284 visibilityItems.clear();
285 toBeMovedItems.clear();
286 newItems.clear();
287 toBeRemovedItems.clear();
288 toBeSetOccurrenceItems.clear();
289 toBeSetVisibilityItems.clear();
290
291 for (std::vector<const molecule*>::const_iterator iter = molecules.begin();
292 iter != molecules.end();
293 iter++)
294 addMolecule(*iter);
295
296 changing = false;
297
298 // activate timer
299 update_timer->start(1000/update_times_per_second);
300}
301
302bool QtMoleculeList::areAnyItemsDirty()
303{
304 // get whether any items are dirty
305 while (list_accessing);
306 list_accessing = true;
307 bool dirty = false;
308 dirty |= !dirtyItems.empty();
309 dirty |= !visibilityItems.empty();
310 dirty |= !newItems.empty();
311 dirty |= !toBeRemovedItems.empty();
312 dirty |= !toBeSetOccurrenceItems.empty();
313 dirty |= !toBeSetVisibilityItems.empty();
314 list_accessing = false;
315 return dirty;
316}
317
318void QtMoleculeList::checkState()
319{
320 const bool dirty = areAnyItemsDirty();
321 // update if required
322 if (dirty)
323 updateItemStates();
324}
325
326void QtMoleculeList::subjectKilled(Observable *publisher)
327{}
328
329void QtMoleculeList::checkForVisibilityChange(QStandardItem* _item)
330{
331// qDebug() << "Item changed called.";
332
333 if (_item->index().column() == QtMoleculeItemFactory::VISIBILITY) {
334// qDebug() << "visibilityItem changed: " << (_item->checkState() ? "checked" : "unchecked");
335 while(list_accessing);
336 list_accessing = true;
337 if ((_item->parent() == NULL) || (_item->parent() == invisibleRootItem()))
338 toBeSetVisibilityItems.insert( _item );
339 else
340 visibilityItems.insert( dynamic_cast<QtMoleculeItem *>(_item) );
341 list_accessing = false;
342 }
343}
344
345void QtMoleculeList::setVisibilityForMoleculeItem(QtMoleculeItem* _item)
346{
347 if (ChangingChildrensVisibility)
348 return;
349
350 const bool visible = _item->checkState();
351 const std::string &molecule_formula = _item->getMolecule()->getFormula().toString();
352 ASSERT( FormulaVisibilityCountMap.count(molecule_formula) != 0,
353 "QtMoleculeList::setVisibilityForMoleculeItem() - molecule with formula " +molecule_formula
354 +" is not present in FormulaVisibilityCountMap.");
355
356 // get parent
357 QStandardItem *groupItem = _item->parent();
358 QStandardItem *visgroupItem =
359 invisibleRootItem()->child(groupItem->index().row(), QtMoleculeItemFactory::VISIBILITY);
360 ASSERT( groupItem != NULL,
361 "QtMoleculeList::setVisibilityForMoleculeItem() - item with id "
362 +toString(_item->getMolecule()->getId())+" has not parent?");
363 // check whether we have to set the group item
364
365 ChangingChildrensVisibility = true;
366 if (visible) {
367 ++(FormulaVisibilityCountMap[molecule_formula]);
368 // compare with occurence/total number of molecules
369 if (FormulaVisibilityCountMap[molecule_formula] ==
370 (unsigned int)(groupItem->rowCount()))
371 visgroupItem->setCheckState(Qt::Checked);
372 } else {
373 --(FormulaVisibilityCountMap[molecule_formula]);
374 // none selected anymore?
375 if (FormulaVisibilityCountMap[molecule_formula] == 0)
376 visgroupItem->setCheckState(Qt::Unchecked);
377 }
378 ChangingChildrensVisibility = false;
379
380 emit moleculesVisibilityChanged(_item->getMolecule()->getId(), visible);
381}
382
383void QtMoleculeList::setVisibilityForGroupItem(QStandardItem* _item)
384{
385 if (ChangingChildrensVisibility)
386 return;
387
388 ChangingChildrensVisibility = true;
389
390 // go through all children, but don't enter for groupItem once more
391 const bool visible = _item->checkState();
392 QStandardItem *groupitem = invisibleRootItem()->child(
393 _item->index().row(), QtMoleculeItemFactory::NAME);
394 for (int i=0;i<groupitem->rowCount();++i) {
395 QtMoleculeItem *molItem = dynamic_cast<QtMoleculeItem *>(
396 groupitem->child(i, QtMoleculeItemFactory::VISIBILITY));
397 if (molItem->checkState() != visible) {
398 molItem->setCheckState(visible ? Qt::Checked : Qt::Unchecked);
399
400 // emit signal
401 emit moleculesVisibilityChanged(molItem->getMolecule()->getId(), visible);
402 }
403 }
404 // set current number of visible children
405 const std::string molecule_formula =
406 invisibleRootItem()->child(_item->row(), QtMoleculeItemFactory::NAME)->text().toStdString();
407 FormulaVisibilityCountMap_t::iterator countiter =
408 FormulaVisibilityCountMap.find(molecule_formula);
409 ASSERT( countiter != FormulaVisibilityCountMap.end(),
410 "QtMoleculeList::setVisibilityForGroupItem() - molecules "+molecule_formula
411 +" have no entry in visibility count map?");
412 countiter->second = visible ? groupitem->rowCount() : 0;
413
414 ChangingChildrensVisibility = false;
415}
416
417
418void QtMoleculeList::moleculeChanged() {
419 /*int idx = verticalHeaderItem(row)->data(Qt::UserRole).toInt();
420 molecule *mol = molecules->ReturnIndex(idx);
421 string cellValue = item(row,QtMoleculeItemFactory::NAME)->text().toStdString();
422 if(mol->getName() != cellValue && cellValue !="") {
423 mol->setName(cellValue);
424 }
425 else if(cellValue==""){
426 item(row,QtMoleculeItemFactory::NAME)->setText(QString(mol->getName().c_str()));
427 }*/
428}
429
430
431int QtMoleculeList::setOccurrence(QStandardItem * const _groupitem)
432{
433 QModelIndex modelindex = _groupitem->index();
434 ASSERT( modelindex.isValid(),
435 "QtMoleculeList::setOccurrence() - groupitem not associated to model anymore.");
436 const int index = modelindex.row();
437 QStandardItem *parent_item =
438 _groupitem->parent() == NULL ? invisibleRootItem() : _groupitem->parent();
439 ASSERT( parent_item != NULL,
440 "QtMoleculeList::setOccurrence() - group item at "+toString(index)
441 +" does not have a parent?");
442 QStandardItem *occ_item = parent_item->child(index, QtMoleculeItemFactory::OCCURRENCE);
443 ASSERT( occ_item != NULL,
444 "QtMoleculeList::setOccurrence() - group item at "+toString(index)
445 +" does not have an occurrence?");
446 const int count = _groupitem->rowCount();
447 if (count == 0) {
448 // we have to remove the group item completely
449 const std::string molecule_formula = _groupitem->text().toStdString();
450 formula.erase(molecule_formula);
451 FormulaVisibilityCountMap.erase(molecule_formula);
452 return index;
453 } else {
454 occ_item->setText(QString::number(count));
455 return -1;
456 }
457}
458
459void QtMoleculeList::readdItem(QtMoleculeItem *_molitem)
460{
461 // use takeRows of molecule ..
462 QStandardItem *groupitem = _molitem->parent();
463 ASSERT( groupitem != NULL,
464 "QtMoleculeList::readdItem() - mol item at "+toString(_molitem->index().row())
465 +" does not have a groupitem?");
466 QList<QStandardItem *> mol_row = _molitem->parent()->takeRow(_molitem->index().row());
467 // call setOccurrence on the old group later, if it's not a removal candidate
468 if (groupitem->rowCount() != 0)
469 addToBeSetOccurrence(groupitem);
470 // .. and re-add where new formula fits
471 const std::string molecule_formula = _molitem->getMolecule()->getFormula().toString();
472 FormulaTreeItemMap_t::iterator iter = formula.find(molecule_formula);
473 if (iter == formula.end()) {
474 // add new group item and formula entry
475 addGroupItem(groupitem, molecule_formula);
476 } else {
477 groupitem = iter->second;
478 }
479 ASSERT( groupitem != NULL,
480 "QtMoleculeList::readdItem() - failed to create a sensible new groupitem");
481 // finally add again
482 groupitem->appendRow(mol_row);
483 // call setOccurrence on the new group later
484 addToBeSetOccurrence(groupitem);
485}
486
487void QtMoleculeList::informDirtyState(
488 QtMoleculeItem *_item,
489 const QtMoleculeItem::MoveTypes _type)
490{
491 while (list_accessing);
492 list_accessing = true;
493
494 dirtyItems.insert(_item);
495 if (_type == QtMoleculeItem::NeedsMove) {
496 // we have to convert whatever item raised the dirty signal to the first
497 // item in the row as otherwise multiple items in the row are selected
498 // as to be moved, i.e. the same row is moved multiple times
499 QStandardItem *group_item = _item->parent();
500 QtMoleculeItem *mol_item =
501 dynamic_cast<QtMoleculeItem *>(group_item->child(_item->row(), 0));
502 toBeMovedItems.insert(mol_item);
503// // add group item, too
504// toBeSetOccurrenceItems.insert(group_item);
505 }
506
507 list_accessing = false;
508}
509
510void QtMoleculeList::updateItemStates()
511{
512 // wait till initial refill has been executed
513 if (changing)
514 return;
515
516 changing = true;
517
518 /// copy lists such that new signals for dirty/.. may come in right away
519 // TODO: if we had move semantics ...
520 while (list_accessing);
521 list_accessing = true;
522 list_of_items_t dirtyItems_copy = dirtyItems;
523 dirtyItems.clear();
524 list_of_items_t visibilityItems_copy = visibilityItems;
525 visibilityItems.clear();
526 list_of_items_t toBeMovedItems_copy = toBeMovedItems;
527 toBeMovedItems.clear();
528 std::vector<const molecule *> newItems_copy = newItems;
529 newItems.clear();
530 std::vector<const molecule *> toBeRemovedItems_copy = toBeRemovedItems;
531 toBeRemovedItems.clear();
532 std::set<QStandardItem*> toBeSetOccurrenceItems_copy = toBeSetOccurrenceItems;
533 toBeSetOccurrenceItems.clear();
534 std::set<QStandardItem*> toBeSetVisibilityItems_copy = toBeSetVisibilityItems;
535 toBeSetVisibilityItems.clear();
536 list_accessing = false;
537
538 /// first check consistency among the sets:
539 /// -# if we remove an item, we don't have to update it before anymore
540 /// -# if we remove an item, we don't have to move it before anymore
541 /// -# if we remove an item, we don't have to change its visibility
542 /// -# don't add molecule that are also removed
543
544 // // remove molecules added and removed immediately in both lists
545 std::vector<const molecule *> addedremoved;
546 std::sort(newItems_copy.begin(), newItems_copy.end());
547 std::sort(toBeRemovedItems_copy.begin(), toBeRemovedItems_copy.end());
548 std::set_intersection(
549 newItems_copy.begin(), newItems_copy.end(),
550 toBeRemovedItems_copy.begin(), toBeRemovedItems_copy.end(),
551 std::back_inserter(addedremoved));
552 {
553 std::vector<const molecule *>::iterator removeiter = std::set_difference(
554 newItems_copy.begin(), newItems_copy.end(),
555 addedremoved.begin(), addedremoved.end(),
556 newItems_copy.begin());
557 newItems_copy.erase(removeiter, newItems_copy.end());
558 }
559 {
560 std::vector<const molecule *>::iterator removeiter = std::set_difference(
561 toBeRemovedItems_copy.begin(), toBeRemovedItems_copy.end(),
562 addedremoved.begin(), addedremoved.end(),
563 toBeRemovedItems_copy.begin());
564 toBeRemovedItems_copy.erase(removeiter, toBeRemovedItems_copy.end());
565 }
566 addedremoved.clear();
567
568 for (std::vector<const molecule *>::iterator removeiter = toBeRemovedItems_copy.begin();
569 removeiter != toBeRemovedItems_copy.end(); ++removeiter) {
570 QtMoleculeItem *item = MoleculeIdToItem((*removeiter)->getId());
571 dirtyItems_copy.erase(item);
572 toBeMovedItems_copy.erase(item);
573 }
574 for (list_of_items_t::iterator visiter = visibilityItems_copy.begin();
575 visiter != visibilityItems_copy.end(); ) {
576 QtMoleculeItem * const _item = dynamic_cast<QtMoleculeItem *>(
577 (*visiter)->parent()->child(
578 (*visiter)->index().row(),
579 QtMoleculeItemFactory::NAME));
580 const moleculeId_t molid = ItemToMoleculeId(_item);
581 const molecule *mol = const_cast<const World &>(World::getInstance()).
582 getMolecule(MoleculeById(molid));
583 if (std::binary_search(
584 toBeRemovedItems_copy.begin(), toBeRemovedItems_copy.end(),
585 mol))
586 visibilityItems_copy.erase(visiter++);
587 else
588 ++visiter;
589 }
590
591 /// 1a. do the update for each dirty item
592 for (list_of_items_t::const_iterator dirtyiter = dirtyItems_copy.begin();
593 dirtyiter != dirtyItems_copy.end(); ++dirtyiter) {
594 LOG(1, "Updating item " << *dirtyiter);
595 (*dirtyiter)->updateState();
596 }
597
598 /// 1b. do the visibility update for each dirty item
599 for (list_of_items_t::const_iterator visiter = visibilityItems_copy.begin();
600 visiter != visibilityItems_copy.end(); ++visiter) {
601// LOG(1, "Updating visibility of item " << *visiter);
602 ASSERT(((*visiter)->parent() != NULL) && ((*visiter)->parent() != invisibleRootItem()),
603 "QtMoleculeList::updateItemStates() - a group item ended up in visibilityItems.");
604 setVisibilityForMoleculeItem(*visiter);
605 }
606
607 /// 2. move all items that need to be moved
608 for (list_of_items_t::const_iterator moveiter = toBeMovedItems_copy.begin();
609 moveiter != toBeMovedItems_copy.end(); ++moveiter) {
610// LOG(1, "Moving item " << *moveiter);
611 readdItem(*moveiter);
612 }
613
614 /// 3. remove all items whose molecules have been removed
615 for (std::vector<const molecule *>::const_iterator removeiter = toBeRemovedItems_copy.begin();
616 removeiter != toBeRemovedItems_copy.end(); ++removeiter) {
617// LOG(1, "Removing molecule " << *removeiter); // cannot access directly, molecule is gone
618 QtMoleculeItem *item = MoleculeIdToItem((*removeiter)->getId());
619 if (item != NULL)
620 removeItem(item);
621 }
622
623 /// 4. instantiate all new items
624 for (std::vector<const molecule *>::const_iterator moliter = newItems_copy.begin();
625 moliter != newItems_copy.end(); ++moliter) {
626// LOG(1, "Adding molecule " << (*moliter)->getName());
627 // check that World knows the molecule still
628 const molecule * const mol = const_cast<const World &>(World::getInstance()).
629 getMolecule(MoleculeById((*moliter)->getId()));
630 if ((mol != NULL) && (mol == *moliter)) {
631 addMolecule(mol);
632 }
633 }
634
635 /// 5a. update the group item's occurrence and visibility
636 std::set<int> RowsToRemove;
637 for (std::set<QStandardItem*>::const_iterator groupiter = toBeSetOccurrenceItems_copy.begin();
638 groupiter != toBeSetOccurrenceItems_copy.end(); ++groupiter) {
639// LOG(1, "Updating group item " << *groupiter);
640 const int index = setOccurrence(*groupiter);
641 if (index != -1)
642 RowsToRemove.insert(index);
643 }
644
645 // remove all visibility updates whose row is removed
646 for (std::set<QStandardItem*>::iterator visiter = toBeSetVisibilityItems_copy.begin();
647 visiter != toBeSetVisibilityItems_copy.end(); ) {
648 if (RowsToRemove.count((*visiter)->index().row()) != 0)
649 toBeSetVisibilityItems_copy.erase(visiter++);
650 else
651 ++visiter;
652 }
653
654 // update visibility of all group items
655 for (std::set<QStandardItem*>::iterator visiter = toBeSetVisibilityItems_copy.begin();
656 visiter != toBeSetVisibilityItems_copy.end(); ++visiter) {
657// LOG(1, "Updating visibility of item " << *visiter);
658 setVisibilityForGroupItem(*visiter);
659 }
660
661 /// 5b. remove all rows with 0 occurrence starting from last
662 for (std::set<int>::reverse_iterator riter = RowsToRemove.rbegin();
663 riter != RowsToRemove.rend(); ++riter) {
664// LOG(1, "Removing group item at row " << *riter);
665 removeRows(*riter, 1, invisibleRootItem()->index());
666 }
667
668 // and done
669 changing = false;
670}
Note: See TracBrowser for help on using the repository browser.