source: src/UIElements/Views/Qt4/MoleculeList/QtMoleculeList.cpp@ 5771e6

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 5771e6 was 5771e6, checked in by Frederik Heber <heber@…>, 9 years ago

Removed all mutexes and updateDirtyStates() in QtMoleculeList, replaced by simpler slots.

  • thanks to events we don't need this humonguous system of lists, update timers, and mutexes. We simply need to take action whenever an event comes in.
  • 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#include "UIElements/Qt4/InstanceBoard/QtObservedInstanceBoard.hpp"
43
44#include <boost/bind.hpp>
45#include <boost/thread/locks.hpp>
46#include <iostream>
47
48#include "CodePatterns/MemDebug.hpp"
49
50#include "CodePatterns/Log.hpp"
51#include "CodePatterns/Observer/Notification.hpp"
52
53#include "Atom/atom.hpp"
54#include "Actions/MoleculeAction/ChangeNameAction.hpp"
55#include "Actions/SelectionAction/Molecules/PopMoleculesAction.hpp"
56#include "Actions/SelectionAction/Molecules/PushMoleculesAction.hpp"
57#include "Actions/SelectionAction/Molecules/MoleculeByIdAction.hpp"
58#include "Actions/ActionQueue.hpp"
59#include "Actions/ActionSequence.hpp"
60#include "Actions/ActionTrait.hpp"
61#include "Actions/MakroAction.hpp"
62#include "Descriptors/MoleculeIdDescriptor.hpp"
63#include "Formula.hpp"
64#include "molecule.hpp"
65
66using namespace std;
67
68QtMoleculeList::QtMoleculeList(
69 QtObservedInstanceBoard *_board,
70 QObject *_parent) :
71 QStandardItemModel(_parent),
72 board(_board),
73 observer(_board)
74{
75 setColumnCount(QtMoleculeItemFactory::COLUMNCOUNT);
76
77 connect(this,SIGNAL(itemChanged(QStandardItem*)),
78 this,SLOT(moleculeNameChanged(QStandardItem*)));
79 connect(this, SIGNAL(itemChanged(QStandardItem*)),
80 this, SLOT(checkForVisibilityChange(QStandardItem*)));
81 connect(&observer, SIGNAL(MoleculeInserted(QtObservedMolecule::ptr)),
82 this, SLOT(moleculeInserted(QtObservedMolecule::ptr)));
83 connect(&observer, SIGNAL(MoleculeRemoved(const moleculeId_t)),
84 this, SLOT(moleculeRemoved(const moleculeId_t)));
85 connect(&observer, SIGNAL(FormulaChanged(const QtObservedMolecule::ptr)),
86 this, SLOT(formulaChanged(const QtObservedMolecule::ptr)));
87 connect(&observer, SIGNAL(NameChanged(const QtObservedMolecule::ptr)),
88 this, SLOT(nameChanged(const QtObservedMolecule::ptr)));
89 connect(board, SIGNAL(moleculeIndexChanged(const moleculeId_t,const moleculeId_t)),
90 this, SLOT(moleculeIndexChanged(const moleculeId_t, const moleculeId_t)));
91}
92
93QtMoleculeList::~QtMoleculeList()
94{}
95
96QVariant QtMoleculeList::headerData(int section, Qt::Orientation orientation, int role) const
97{
98 if (role == Qt::DisplayRole) {
99 if (orientation == Qt::Horizontal) {
100 if (section < QtMoleculeItem::COLUMNTYPES_MAX)
101 return QString(QtMoleculeItemFactory::COLUMNNAMES[section]);
102 }
103 }
104 return QVariant();
105}
106
107void QtMoleculeList::moleculeInserted(QtObservedMolecule::ptr _mol)
108{
109 LOG(1, "Adding molecule " << _mol->getMolName());
110 // check that World knows the molecule still
111 const std::string formula = addMolecule(_mol);
112 LOG(1, "Adding " << formula << " to toBeSetOccurrence.");
113 setOccurrence(FormulaToGroupItem(formula));
114}
115
116void QtMoleculeList::moleculeRemoved(const moleculeId_t _id)
117{
118 LOG(1, "Removing molecule " << _id);
119 if (!isMoleculeItemPresent(_id)) {
120 ELOG(1, "QtMoleculeItem to id " << _id << " has disappeared before removal.");
121 return;
122 }
123 QtMoleculeItem *item = MoleculeIdToItem(_id);
124 if (item != NULL) {
125 const std::string formula = item->parent()->text().toStdString();
126 LOG(1, "Adding " << formula << " to toBeSetOccurrence.");
127 const int removeindex = setOccurrence(FormulaToGroupItem(formula));
128 removeMoleculeItem(item);
129 if (removeindex != -1) {
130 LOG(1, "Removing row of group item to " << formula);
131 removeRows(removeindex, 1, invisibleRootItem()->index());
132 }
133 }
134}
135
136template<class T>
137void exchangeKeys(
138 T &_container,
139 const moleculeId_t _oldid,
140 const moleculeId_t _newid)
141{
142 typename T::iterator iter = _container.find(_oldid);
143 ASSERT(_container.find(_newid) == _container.end(),
144 "exchangeKeys() - new id "+toString(_newid)
145 +" already exists in container.");
146 _container.insert( std::make_pair(_newid, iter->second) );
147 _container.erase(iter);
148}
149
150template<class T>
151void exchangeKeysInSet(
152 T &_container,
153 const moleculeId_t _oldid,
154 const moleculeId_t _newid)
155{
156 typename T::iterator iter = _container.find(_oldid);
157 ASSERT(_container.find(_newid) == _container.end(),
158 "exchangeKeys() - new id "+toString(_newid)
159 +" already exists in container.");
160 _container.insert( _newid );
161 _container.erase(iter);
162}
163
164template<class T>
165void exchangeKeysOverAllColumns(
166 T &_container,
167 const moleculeId_t _oldid,
168 const moleculeId_t _newid)
169{
170 for (int i=0;i<QtMoleculeItem::COLUMNTYPES_MAX;++i) {
171 typename T::iterator iter =
172 _container.find( std::make_pair(_oldid, (enum QtMoleculeItem::COLUMNTYPES)i) );
173 if (iter == _container.end())
174 continue;
175 ASSERT(_container.find( std::make_pair(_newid,(enum QtMoleculeItem::COLUMNTYPES)i) ) == _container.end(),
176 "exchangeKeys() - new id "+toString(_newid)
177 +" already exists in container.");
178 _container.insert( std::make_pair(_newid, (enum QtMoleculeItem::COLUMNTYPES)i) );
179 _container.erase(iter);
180 }
181}
182
183void QtMoleculeList::moleculeIndexChanged(
184 const moleculeId_t _oldid,
185 const moleculeId_t _newid)
186{
187 // go through all list and change keys
188 exchangeKeys(MoleculeFormulaMap, _oldid, _newid);
189 {
190 MoleculeItemBiMap_t::left_iterator iter = MoleculeItemBiMap.left.find(_oldid);
191 ASSERT(MoleculeItemBiMap.left.count(_newid),
192 "QtMoleculeList::moleculeIndexChanged() - new id "+toString(_newid)
193 +" already exists in MoleculeItemBiMap.");
194 MoleculeItemBiMap.left.insert( std::make_pair(_newid, iter->second) );
195 MoleculeItemBiMap.left.erase(iter);
196 }
197}
198
199bool QtMoleculeList::isMoleculeItemPresent(const moleculeId_t _molid) const
200{
201 MoleculeItemBiMap_t::left_const_iterator iter =
202 MoleculeItemBiMap.left.find(_molid);
203 return ( iter != MoleculeItemBiMap.left.end());
204}
205
206QtMoleculeItem * QtMoleculeList::MoleculeIdToItem(const moleculeId_t _molid) const
207{
208 MoleculeItemBiMap_t::left_const_iterator iter =
209 MoleculeItemBiMap.left.find(_molid);
210 ASSERT( iter != MoleculeItemBiMap.left.end(),
211 "QtMoleculeList::MoleculeIdToItem() - could not find item to id "
212 +toString(_molid));
213 return iter->second;
214}
215
216const moleculeId_t QtMoleculeList::ItemToMoleculeId(const QtMoleculeItem * const _item) const
217{
218 const MoleculeItemBiMap_t::right_const_iterator iter =
219 MoleculeItemBiMap.right.find(const_cast<QtMoleculeItem * const>(_item));
220 if (iter != MoleculeItemBiMap.right.end())
221 return iter->second;
222 else
223 return -1;
224}
225
226QtMoleculeItem * QtMoleculeList::getSpecificMoleculeItem(
227 const QtMoleculeItem * const _item,
228 const enum QtMoleculeItem::COLUMNTYPES _type) const
229{
230 QStandardItem *parent_item = _item->parent();
231 ASSERT( parent_item != NULL,
232 "QtMoleculeList::getSpecificMoleculeItem() - parent of molecule item is NULL");
233 return static_cast<QtMoleculeItem *>(parent_item->child(_item->index().row(), _type));
234}
235
236bool QtMoleculeList::isGroupItemPresent(const std::string &_formula) const
237{
238 FormulaTreeItemBiMap_t::left_const_iterator iter =
239 FormulaItemBiMap.left.find(_formula);
240 return ( iter != FormulaItemBiMap.left.end());
241}
242
243QStandardItem * QtMoleculeList::FormulaToGroupItem(const std::string &_formula) const
244{
245 FormulaTreeItemBiMap_t::left_const_iterator iter =
246 FormulaItemBiMap.left.find(_formula);
247 ASSERT( iter != FormulaItemBiMap.left.end(),
248 "QtMoleculeList::FormulaToGroupItem() - could not find item to formula "
249 +toString(_formula));
250 return iter->second;
251}
252
253const std::string& QtMoleculeList::GroupItemToFormula(const QStandardItem * const _item) const
254{
255 static std::string emptystring;
256 const FormulaTreeItemBiMap_t::right_const_iterator iter =
257 FormulaItemBiMap.right.find(const_cast<QStandardItem * const>(_item));
258 if (iter != FormulaItemBiMap.right.end())
259 return iter->second;
260 else
261 return emptystring;
262}
263
264QStandardItem * QtMoleculeList::getSpecificGroupItem(
265 const QStandardItem * const _item,
266 const enum QtMoleculeItem::COLUMNTYPES _type) const
267{
268 return invisibleRootItem()->child(_item->index().row(), _type);
269}
270
271const QModelIndex QtMoleculeList::MoleculeIdToIndex(const moleculeId_t _id) const
272{
273 QtMoleculeItem * const item = MoleculeIdToItem(_id);
274 ASSERT(item != NULL,
275 "QtMoleculeList::MoleculeIdToIndex() - could not find item to "
276 +toString(_id));
277 return indexFromItem(item);
278}
279
280const moleculeId_t QtMoleculeList::IndexToMoleculeId(const QModelIndex &_index) const
281{
282 QtMoleculeItem * const item = dynamic_cast<QtMoleculeItem *>(itemFromIndex(_index));
283 if (item == NULL)
284 return -1;
285 else
286 return ItemToMoleculeId(item);
287}
288
289void QtMoleculeList::addGroupItem(
290 QStandardItem *&mainitem,
291 const std::string &_molecule_formula)
292{
293 QList<QStandardItem *> groupItems =
294 QtMoleculeItemFactory::getInstance().createGroupItems(_molecule_formula);
295 mainitem = groupItems.front();
296 FormulaItemBiMap.left.insert( std::make_pair(_molecule_formula, mainitem) );
297 invisibleRootItem()->appendRow(groupItems);
298}
299
300QList<QStandardItem *> QtMoleculeList::createMoleculeItems(
301 QtObservedMolecule::ptr &_ObservedMolecule,
302 std::string &_molecule_formula)
303{
304 QList<QStandardItem *> molItems =
305 QtMoleculeItemFactory::getInstance().createMoleculeItems(_ObservedMolecule);
306 QtMoleculeItem *mol_item = dynamic_cast<QtMoleculeItem *>(molItems.front());
307 ASSERT( mol_item != NULL,
308 "QtMoleculeList::createMoleculeItems() - item from factory was not a QtMoleculeItem?");
309 MoleculeItemBiMap.left.insert( std::make_pair(_ObservedMolecule->getMolIndex(), mol_item) );
310
311 QStandardItem *formulaitem = molItems.at(QtMoleculeItem::FORMULA);
312 ASSERT( formulaitem != NULL,
313 "QtMoleculeList::createMoleculeItems() - Formula item not created by factory?");
314 _molecule_formula = formulaitem->text().toStdString();
315
316 LOG(1, "Adding " << _molecule_formula << " for "
317 << _ObservedMolecule->getMolIndex() << " to MoleculeFormulaMap.");
318 MoleculeFormulaMap.insert( std::make_pair( _ObservedMolecule->getMolIndex(), _molecule_formula) );
319// LOG(1, "Inserting molecule " << _molid << ": " << _molecule_formula);
320 return molItems;
321}
322
323std::string QtMoleculeList::addMolecule(QtObservedMolecule::ptr &_ObservedMolecule)
324{
325 // find group if already in list
326 QStandardItem *groupItem = NULL;
327
328 // create molecule items and obtain the molecule's formula
329 std::string molecule_formula;
330 QList<QStandardItem *> molItems = createMoleculeItems(_ObservedMolecule, molecule_formula);
331
332 // new molecule type -> create new group
333 if (!isGroupItemPresent(molecule_formula)){
334 // insert new formula entry into visibility
335#ifndef NDEBUG
336 std::pair< FormulaVisibilityCountMap_t::iterator, bool> visibilityinserter =
337#endif
338 FormulaVisibilityCountMap.insert(
339 std::make_pair( molecule_formula, (unsigned int)0) );
340 ASSERT( visibilityinserter.second,
341 "QtMoleculeList::refill() - molecule with formula "
342 +molecule_formula+" already in FormulaVisibilityCountMap.");
343
344 // create item and place into Map with formula as key
345 addGroupItem(groupItem, molecule_formula);
346 } else {
347 groupItem = FormulaToGroupItem(molecule_formula);
348 }
349 ASSERT( groupItem != NULL,
350 "QtMoleculeList::addMolecule() - item with id "+toString(_ObservedMolecule->getMolIndex())
351 +" has no parent?");
352 groupItem->appendRow(molItems);
353
354 return molecule_formula;
355}
356
357void QtMoleculeList::removeMoleculeItem(QtMoleculeItem * const _item)
358{
359 const QModelIndex mol_index = indexFromItem(_item);
360 QStandardItem *groupitem = _item->parent();
361 const QModelIndex group_index = groupitem->index();
362 {
363 MoleculeItemBiMap_t::right_iterator removeiter =
364 MoleculeItemBiMap.right.find(_item);
365 ASSERT( removeiter != MoleculeItemBiMap.right.end(),
366 "QtMoleculeList::removeMoleculeItem() - could not find item in MoleculeBiMap.");
367 // LOG(1, "Erasing molecule " << (removeiter->second));
368 {
369 MoleculeFormulaMap_t::iterator removeformulaiter =
370 MoleculeFormulaMap.find(removeiter->second);
371 ASSERT( removeformulaiter != MoleculeFormulaMap.end(),
372 "QtMoleculeList::removeMoleculeItem() - could not find id "
373 +toString(removeiter->second)+" in MoleculeFormulaMap.");
374 LOG(1, "Removing " << removeformulaiter->second << " for "
375 << removeformulaiter->first << " from MoleculeFormulaMap.");
376 MoleculeFormulaMap.erase( removeformulaiter );
377 }
378 MoleculeItemBiMap.right.erase(removeiter);
379 }
380 removeRows(mol_index.row(), 1, group_index);
381}
382
383void QtMoleculeList::checkForVisibilityChange(QStandardItem* _item)
384{
385// qDebug() << "Item changed called.";
386
387 if (_item->index().column() == QtMoleculeItem::VISIBILITY) {
388// qDebug() << "visibilityItem changed: " << (_item->checkState() ? "checked" : "unchecked");
389 if ((_item->parent() == NULL) || (_item->parent() == invisibleRootItem())) {
390 LOG(1, "Updating visibility of group item " << _item);
391 setVisibilityForGroupItem(_item);
392 } else {
393 LOG(1, "Updating visibility of item " << _item);
394 setVisibilityForMoleculeItem( assert_cast<QtMoleculeItem *>(_item) );
395 }
396 }
397}
398
399void QtMoleculeList::setVisibilityForMoleculeItem(QtMoleculeItem* _item)
400{
401 const bool visible = _item->checkState();
402 const moleculeId_t molid = _item->getMoleculeId();
403 std::string molecule_formula("illegal");
404 {
405 const MoleculeFormulaMap_t::const_iterator formulaiter =
406 MoleculeFormulaMap.find(molid);
407 ASSERT( formulaiter != MoleculeFormulaMap.end(),
408 "QtMoleculeList::setVisibilityForMoleculeItem() - formula of molecule "
409 +toString(molid)+" unknown.");
410 molecule_formula = formulaiter->second;
411 }
412 ASSERT( FormulaVisibilityCountMap.count(molecule_formula) != 0,
413 "QtMoleculeList::setVisibilityForMoleculeItem() - molecule with formula " +molecule_formula
414 +" is not present in FormulaVisibilityCountMap.");
415
416 // get parent
417 QStandardItem *groupItem = _item->parent();
418 QStandardItem *visgroupItem = getSpecificGroupItem(groupItem, QtMoleculeItem::VISIBILITY);
419 ASSERT( groupItem != NULL,
420 "QtMoleculeList::setVisibilityForMoleculeItem() - item with id "
421 +toString(_item->getMoleculeId())+" has not parent?");
422 // check whether we have to set the group item
423
424 if (visible) {
425 ++(FormulaVisibilityCountMap[molecule_formula]);
426 // compare with occurence/total number of molecules
427 if (FormulaVisibilityCountMap[molecule_formula] ==
428 (unsigned int)(groupItem->rowCount()))
429 visgroupItem->setCheckState(Qt::Checked);
430 } else {
431 --(FormulaVisibilityCountMap[molecule_formula]);
432 // none selected anymore?
433 if (FormulaVisibilityCountMap[molecule_formula] == 0)
434 visgroupItem->setCheckState(Qt::Unchecked);
435 }
436
437 emit moleculesVisibilityChanged(_item->getMoleculeId(), visible);
438}
439
440void QtMoleculeList::setVisibilityForGroupItem(QStandardItem* _item)
441{
442 // go through all children, but don't enter for groupItem once more
443 const bool visible = _item->checkState();
444 QStandardItem *groupitem = getSpecificGroupItem(_item, QtMoleculeItem::NAME);
445 for (int i=0;i<groupitem->rowCount();++i) {
446 QtMoleculeItem * const molItem = dynamic_cast<QtMoleculeItem *>(
447 groupitem->child(i, QtMoleculeItem::VISIBILITY));
448 if (molItem->checkState() != visible) {
449 molItem->setCheckState(visible ? Qt::Checked : Qt::Unchecked);
450
451 // emit signal
452 emit moleculesVisibilityChanged(molItem->getMoleculeId(), visible);
453 }
454 }
455 // set current number of visible children
456 const std::string molecule_formula =
457 GroupItemToFormula( getSpecificGroupItem(_item, QtMoleculeItem::NAME) );
458 FormulaVisibilityCountMap_t::iterator countiter =
459 FormulaVisibilityCountMap.find(molecule_formula);
460 ASSERT( countiter != FormulaVisibilityCountMap.end(),
461 "QtMoleculeList::setVisibilityForGroupItem() - molecules "+molecule_formula
462 +" have no entry in visibility count map?");
463 countiter->second = visible ? groupitem->rowCount() : 0;
464}
465
466static
467MoleCuilder::MakroAction *constructMakroRenameAction(
468 MoleCuilder::ActionSequence &sequence,
469 const std::string &_new_name,
470 const moleculeId_t _molid
471 )
472{
473 MoleCuilder::ActionQueue &AQ = MoleCuilder::ActionQueue::getInstance();
474 MoleCuilder::ActionTrait trait("change-single-molecule-name");
475 sequence.addAction(AQ.getActionByName("push-molecule-selection").clone(MoleCuilder::Action::NonInteractive));
476 MoleCuilder::Action * const selectaction =
477 AQ.getActionByName("select-molecule-by-id").clone(MoleCuilder::Action::NonInteractive);
478 {
479 std::stringstream molid_string;
480 molid_string << toString(_molid);
481 selectaction->setOptionValue("select-molecule-by-id", molid_string.str());
482 }
483 sequence.addAction(selectaction);
484 MoleCuilder::Action * const changeaction =
485 AQ.getActionByName("change-molname").clone(MoleCuilder::Action::NonInteractive);
486 changeaction->setOptionValue("change-molname", _new_name);
487 sequence.addAction(changeaction);
488 sequence.addAction(AQ.getActionByName("pop-molecule-selection").clone(MoleCuilder::Action::NonInteractive));
489
490 MoleCuilder::MakroAction* makroaction =
491 new MoleCuilder::MakroAction(trait, sequence);
492 return makroaction;
493}
494
495void QtMoleculeList::moleculeNameChanged(QStandardItem* item)
496{
497 // obtain molecule id
498 if ( item->index().column() == QtMoleculeItem::NAME) {
499 QtMoleculeItem *molitem = assert_cast<QtMoleculeItem *>(item);
500 MoleculeItemBiMap_t::right_const_iterator iter = MoleculeItemBiMap.right.find(molitem);
501 ASSERT( iter != MoleculeItemBiMap.right.end(),
502 "QtMoleculeList::moleculeChanged() - name of unknown molecule changed.");
503 const moleculeId_t molid = iter->second;
504 // change the name
505 std::string cellValue = item->text().toStdString();
506 if (!cellValue.empty()) {
507 // create actions such that we may undo
508 static MoleCuilder::ActionSequence sequence;
509 MoleCuilder::MakroAction *makroaction =
510 constructMakroRenameAction(sequence, cellValue, molid);
511 MoleCuilder::ActionQueue &AQ = MoleCuilder::ActionQueue::getInstance();
512 AQ.registerAction(makroaction);
513 AQ.queueAction("change-single-molecule-name", MoleCuilder::Action::NonInteractive);
514 } else {
515 assert_cast<QtMoleculeItem *>(item)->updateState();
516 }
517 }
518}
519
520int QtMoleculeList::setOccurrence(QStandardItem * const _groupitem)
521{
522 ASSERT( _groupitem != NULL,
523 "QtMoleculeList::setOccurrence() - group item at "+toString(_groupitem)
524 +" is NULL");
525 QModelIndex modelindex = _groupitem->index();
526 ASSERT( modelindex.isValid(),
527 "QtMoleculeList::setOccurrence() - groupitem not associated to model anymore.");
528 const int index = modelindex.row();
529 QStandardItem *parent_item =
530 _groupitem->parent() == NULL ? invisibleRootItem() : _groupitem->parent();
531 ASSERT( parent_item != NULL,
532 "QtMoleculeList::setOccurrence() - group item at "+toString(index)
533 +" does not have a parent?");
534 QStandardItem *occ_item = parent_item->child(index, QtMoleculeItem::OCCURRENCE);
535 ASSERT( occ_item != NULL,
536 "QtMoleculeList::setOccurrence() - group item at "+toString(index)
537 +" does not have an occurrence?");
538 const int count = _groupitem->rowCount();
539 if (count == 0) {
540 // we have to remove the group item completely
541 const std::string molecule_formula = _groupitem->text().toStdString();
542 FormulaItemBiMap.left.erase(molecule_formula);
543 FormulaVisibilityCountMap.erase(molecule_formula);
544 return index;
545 } else {
546 occ_item->setText(QString::number(count));
547 return -1;
548 }
549}
550
551void QtMoleculeList::moveItem(
552 QtMoleculeItem *_molitem,
553 const std::string &_new_formula)
554{
555 // use takeRows of molecule ..
556 QStandardItem *groupitem = _molitem->parent();
557 ASSERT( groupitem != NULL,
558 "QtMoleculeList::readdItem() - mol item at "+toString(_molitem->index().row())
559 +" does not have a groupitem?");
560 // get updated formula from the item
561 QStandardItem *formulaitem =
562 _molitem->parent()->child(_molitem->index().row(), QtMoleculeItem::FORMULA);
563 QList<QStandardItem *> mol_row = _molitem->parent()->takeRow(_molitem->index().row());
564 // .. and re-add where new formula fits
565 if (!isGroupItemPresent(_new_formula)) {
566 // add new group item and formula entry
567 addGroupItem(groupitem, _new_formula);
568 } else {
569 groupitem = FormulaToGroupItem(_new_formula);
570 }
571 ASSERT( groupitem != NULL,
572 "QtMoleculeList::readdItem() - failed to create a sensible new groupitem");
573 // finally add again
574 groupitem->appendRow(mol_row);
575}
576
577
578void QtMoleculeList::formulaChanged(const QtObservedMolecule::ptr _mol)
579{
580 // we need the id as identifier to the items
581 const moleculeId_t molid = _mol->getMolIndex();
582 LOG(3, "DEBUG: Moving item to id " << molid);
583 const MoleculeFormulaMap_t::iterator formulaiter =
584 MoleculeFormulaMap.find(molid);
585 ASSERT( formulaiter != MoleculeFormulaMap.end(),
586 "QtMoleculeList::updateItemStates() - formula of molecule "
587 +toString(molid)+" unknown.");
588 // we get old formula from stored map and new formula from the ObservedMolecule
589 const std::string old_formula = formulaiter->second;
590 const std::string new_formula = _mol->getMolFormula();
591
592 // then we move the item if necessary
593 if (old_formula != new_formula) {
594 QtMoleculeItem *const molitem = MoleculeIdToItem(molid);
595 LOG(3, "DEBUG: Moving item " << molitem);
596 // remove from formula<->molecule bimap with old formula
597 LOG(4, "DEBUG: Removing " << old_formula << " for " << formulaiter->first << " from MoleculeFormulaMap.");
598 MoleculeFormulaMap.erase( formulaiter );
599 moveItem(molitem, new_formula);
600 // changing occurrences for old_formula with possible removal
601 const int removeindex = setOccurrence( FormulaToGroupItem(old_formula) );
602 if (removeindex != -1) {
603 LOG(3, "DEBUG: Removing row of group item to " << old_formula);
604 removeRows(removeindex, 1, invisibleRootItem()->index());
605 }
606 // and add to formula<->molecule bimap with updated new_formula
607 LOG(4, "DEBUG: Adding " << new_formula << " for " << molid << " to MoleculeFormulaMap.");
608 MoleculeFormulaMap.insert( std::make_pair(molid, new_formula) );
609 const int addindex = setOccurrence( FormulaToGroupItem(new_formula) );
610 ASSERT( addindex == -1,
611 "QtMoleculeList::formulaChanged() - add mol to new formula "+
612 toString(new_formula)+" made the row to be removed?");
613 }
614}
615
616void QtMoleculeList::nameChanged(const QtObservedMolecule::ptr _mol)
617{
618 // nothing to do, item updates itself
619 LOG(3, "DEBUG: QtMoleculeList got nameChangd for id " << _mol->getMolIndex());
620}
Note: See TracBrowser for help on using the repository browser.