source: src/UIElements/Views/Qt4/QtMoleculeList.cpp@ 6770fa

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 6770fa was 6770fa, checked in by Frederik Heber <heber@…>, 10 years ago

Extracted add/removeItem in QtMoleculeList, no more complete refilling on update.

  • this is unfinished as we can't find the item to a molecule that is about to be removed. We have to switch to Qt's Model/View ... argh.
  • Property mode set to 100644
File size: 11.8 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 "Views/Qt4/QtMoleculeList.hpp"
36
37#include <QMetaMethod>
38
39#include <iostream>
40
41#include "CodePatterns/MemDebug.hpp"
42
43#include "CodePatterns/Observer/Notification.hpp"
44
45#include "Atom/atom.hpp"
46#include "Formula.hpp"
47#include "molecule.hpp"
48#include "MoleculeListClass.hpp"
49#include "Actions/SelectionAction/Molecules/MoleculeByIdAction.hpp"
50#include "Actions/SelectionAction/Molecules/NotMoleculeByIdAction.hpp"
51
52using namespace std;
53
54// maybe this should go with the definition of molecules
55
56// some attributes need to be easier to find for molecules
57// these attributes are skipped so far
58const int QtMoleculeList::COLUMNCOUNT = COLUMNTYPES_MAX;
59const char *QtMoleculeList::COLUMNNAMES[QtMoleculeList::COLUMNCOUNT]={"Name","Visibility", "Atoms","Formula","Occurrence"/*,"Size"*/};
60
61QtMoleculeList::QtMoleculeList(QWidget * _parent) :
62 QTreeWidget (_parent),
63 Observer("QtMoleculeList")
64{
65 setColumnCount(COLUMNCOUNT);
66 setSelectionMode(QAbstractItemView::MultiSelection);
67
68 QStringList header;
69 for(int i=0; i<COLUMNCOUNT;++i)
70 header << COLUMNNAMES[i];
71 setHeaderLabels(header);
72
73 World::getInstance().signOn(this, World::MoleculeInserted);
74 World::getInstance().signOn(this, World::MoleculeRemoved);
75
76
77 dirty = true;
78 clearing = false;
79 selecting = false;
80 changing = false;
81 ChangingChildrensVisibility = false;
82 refill();
83
84 qRegisterMetaType<QItemSelection>("QItemSelection");
85 //connect(this,SIGNAL(cellChanged(int,int)),this,SLOT(moleculeChanged(int,int)));
86 connect(selectionModel(),SIGNAL(selectionChanged(QItemSelection, QItemSelection)),this,SLOT(rowsSelected(QItemSelection, QItemSelection)));
87 connect(this, SIGNAL(itemChanged(QTreeWidgetItem*, int)), this, SLOT(visibilityChanged(QTreeWidgetItem*, int)));
88}
89
90QtMoleculeList::~QtMoleculeList()
91{
92 World::getInstance().signOff(this, World::MoleculeInserted);
93 World::getInstance().signOff(this, World::MoleculeRemoved);
94}
95
96void QtMoleculeList::update(Observable *publisher) {
97 ASSERT(0,
98 "QtMoleculeList::update() - we did not sign up for any global updates.");
99}
100
101void QtMoleculeList::recieveNotification(Observable *publisher, Notification_ptr notification)
102{
103 if (dynamic_cast<World *>(publisher) != NULL) {
104 switch (notification->getChannelNo()) {
105 case World::MoleculeInserted:
106 {
107 const molecule * const mol = World::getInstance().lastChanged<molecule>();
108 addItem(mol);
109 break;
110 }
111 case World::MoleculeRemoved:
112 {
113 const molecule * const mol = World::getInstance().lastChanged<molecule>();
114 removeItem(mol);
115 break;
116 }
117 default:
118 ASSERT(0, "QtMoleculeList::recieveNotification() - cannot get here, not subscribed to channel "
119 +toString(notification->getChannelNo()));
120 break;
121 }
122 }
123
124 if (selecting)
125 return;
126
127 dirty = true;
128}
129
130void QtMoleculeList::addGroupItem(
131 QTreeWidgetItem *&_groupItem,
132 const std::string &_molecule_formula)
133{
134 _groupItem = new QTreeWidgetItem(this);
135 formula.insert( std::make_pair(_molecule_formula, _groupItem) );
136 // fill item
137 _groupItem->setText(NAME, QString("default"));
138 _groupItem->setFlags((_groupItem->flags() | Qt::ItemIsUserCheckable) ^ Qt::ItemIsSelectable);
139 _groupItem->setCheckState(VISIBILITY, Qt::Unchecked);
140 _groupItem->setText(ATOMCOUNT, QString::number(0));
141 _groupItem->setText(FORMULA, QString(""));
142 _groupItem->setText(OCCURRENCE, "0");
143 _groupItem->setData(0, Qt::UserRole, QVariant(-1));
144}
145
146void QtMoleculeList::addMoleculeItem(
147 QTreeWidgetItem *&_groupItem,
148 const molecule *_mol,
149 const std::string &_molecule_formula)
150{
151 QTreeWidgetItem *molItem = new QTreeWidgetItem(_groupItem);
152 molItem->setText(NAME, QString(_mol->getName().c_str()));
153 molItem->setFlags(molItem->flags() | Qt::ItemIsUserCheckable | Qt::ItemIsSelectable);
154 molItem->setCheckState(VISIBILITY, Qt::Unchecked);
155 molItem->setText(ATOMCOUNT, QString::number(_mol->getAtomCount()));
156 molItem->setText(FORMULA, QString(_molecule_formula.c_str()));
157 const int index = _mol->getId();
158 molItem->setData(0, Qt::UserRole, QVariant(index));
159 molItem->setSelected(World::getInstance().isSelected(_mol));
160}
161
162void QtMoleculeList::addItem(const molecule *_mol)
163{
164 if (changing)
165 return;
166 changing = true;
167 // find group if already in list
168 QTreeWidgetItem *groupItem = NULL;
169
170 const std::string &molecule_formula = _mol->getFormula().toString();
171 FormulaTreeItemMap_t::const_iterator formulaiter =
172 formula.find(molecule_formula);
173
174 // new molecule type -> create new group
175 if (formulaiter == formula.end()){
176 // insert new formula entry into visibility
177#ifndef NDEBUG
178 std::pair< FormulaVisibilityCountMap_t::iterator, bool> visibilityinserter =
179#endif
180 FormulaVisibilityCountMap.insert(
181 std::make_pair( molecule_formula, (unsigned int)0) );
182 ASSERT( visibilityinserter.second,
183 "QtMoleculeList::refill() - molecule with formula "
184 +molecule_formula+" already in FormulaVisibilityCountMap.");
185
186 // create item and place into Map with formula as key
187 addGroupItem(groupItem, molecule_formula);
188 } else {
189 groupItem = formulaiter->second;
190 }
191 ASSERT( groupItem != NULL,
192 "QtMoleculeList::addItem() - item with id "+toString(_mol->getId())
193 +" has not parent?");
194
195 // add molecule
196 addMoleculeItem(groupItem, _mol, molecule_formula);
197
198 // increase group occurrence
199 int count = groupItem->text(OCCURRENCE).toInt() + 1;
200 groupItem->setText(OCCURRENCE, QString::number(count));
201
202 changing = false;
203}
204
205void QtMoleculeList::removeItem(const molecule *_mol)
206{
207 if (changing)
208 return;
209 changing = true;
210
211 dirty = true;
212 // TODO: We have to get some Model into the Table in order to "find" items right
213 // away
214// QTreeWidgetItem *molItem = itemFromIndex(mol->getId());
215// delete molItem1;
216
217 changing = false;
218}
219
220void QtMoleculeList::refill() {
221 clearing = true;
222 const std::vector<molecule*> &molecules = World::getInstance().getAllMolecules();
223
224 clear();
225 formula.clear();
226 FormulaVisibilityCountMap.clear();
227
228 for (std::vector<molecule*>::const_iterator iter = molecules.begin();
229 iter != molecules.end();
230 iter++) {
231
232 addItem(*iter);
233 }
234 dirty = false;
235 clearing = false;
236}
237
238void QtMoleculeList::paintEvent(QPaintEvent * event)
239{
240 if (dirty)
241 refill();
242 QTreeWidget::paintEvent(event);
243}
244
245void QtMoleculeList::subjectKilled(Observable *publisher) {
246}
247
248void QtMoleculeList::visibilityChanged(QTreeWidgetItem* item, int column)
249{
250 if ((!changing) && (!clearing) && (!ChangingChildrensVisibility))
251 if (column == VISIBILITY) {
252 const moleculeId_t molid = item->data(0, Qt::UserRole).toInt();
253 const bool visible = item->checkState(VISIBILITY);
254 if (molid != (unsigned int)-1) { // molecule item
255 World::MoleculeConstIterator moliter =
256 const_cast<const World &>(World::getInstance()).getMoleculeIter(MoleculeById(molid));
257 const molecule * const _molecule = *moliter;
258 ASSERT( _molecule != NULL,
259 "QtMoleculeList::visibilityChanged() - molecule with id "
260 +toString(molid)+" is not known to World.");
261 const std::string &molecule_formula = _molecule->getFormula().toString();
262 ASSERT( FormulaVisibilityCountMap.count(molecule_formula) != 0,
263 "QtMoleculeList::visibilityChanged() - molecule with formula " +molecule_formula
264 +" is not present in FormulaVisibilityCountMap.");
265
266 // get parent
267 QTreeWidgetItem *groupItem = item->parent();
268 ASSERT( groupItem != NULL,
269 "QtMoleculeList::visibilityChanged() - item with id "+toString(molid)
270 +" has not parent?");
271 // check whether we have to set the group item
272
273 ChangingChildrensVisibility = true;
274 if (visible) {
275 ++(FormulaVisibilityCountMap[molecule_formula]);
276 // compare with occurence/total number of molecules
277 if (FormulaVisibilityCountMap[molecule_formula] ==
278 (unsigned int)(groupItem->text(OCCURRENCE).toInt()))
279 groupItem->setCheckState(VISIBILITY, Qt::Checked);
280 } else {
281 --(FormulaVisibilityCountMap[molecule_formula]);
282 // none selected anymore?
283 if (FormulaVisibilityCountMap[molecule_formula] == 0)
284 groupItem->setCheckState(VISIBILITY, Qt::Unchecked);
285 }
286 ChangingChildrensVisibility = false;
287
288 emit moleculesVisibilityChanged(molid, visible);
289
290 } else { // group item
291
292 // go through all children, but don't enter for groupItem once more
293 ChangingChildrensVisibility = true;
294 for (int i=0;i<item->childCount();++i) {
295 QTreeWidgetItem *molItem = item->child(i);
296 const moleculeId_t molid = molItem->data(0, Qt::UserRole).toInt();
297 ASSERT( molid != (unsigned int)-1,
298 "QtMoleculeList::visibilityChanged() - to child with index"
299 +toString(i)+" there is no molecule?");
300 molItem->setCheckState(VISIBILITY, visible ? Qt::Checked : Qt::Unchecked);
301
302 // emit signal
303 emit moleculesVisibilityChanged(molid, visible);
304 }
305 // set current number of visible children
306 const std::string molecule_formula =
307 item->text(FORMULA).toStdString();
308 FormulaVisibilityCountMap[molecule_formula] =
309 visible ? item->text(OCCURRENCE).toInt() : 0;
310
311 ChangingChildrensVisibility = false;
312 }
313 }
314}
315
316void QtMoleculeList::moleculeChanged() {
317 /*int idx = verticalHeaderItem(row)->data(Qt::UserRole).toInt();
318 molecule *mol = molecules->ReturnIndex(idx);
319 string cellValue = item(row,NAME)->text().toStdString();
320 if(mol->getName() != cellValue && cellValue !="") {
321 mol->setName(cellValue);
322 }
323 else if(cellValue==""){
324 item(row,NAME)->setText(QString(mol->getName().c_str()));
325 }*/
326}
327
328void QtMoleculeList::rowsSelected(const QItemSelection & selected, const QItemSelection & deselected){
329
330 if (clearing)
331 return;
332 if (selecting)
333 return;
334 selecting = true;
335
336 // Select all molecules which belong to newly selected rows.
337 QModelIndex index;
338 {
339 QModelIndexList items = selected.indexes();
340 molids_t ids;
341 ids.reserve(items.size());
342 foreach (index, items)
343 if (index.column() == 0){
344 int mol_id = model()->data(index, Qt::UserRole).toInt();
345 if (mol_id < 0)
346 continue;
347 ids.push_back(mol_id);
348 //std::cout << "select molecule" << std::endl;
349 }
350 MoleCuilder::SelectionMoleculeById(ids);
351 }
352
353 // Unselect all molecules which belong to newly unselected rows.
354 {
355 QModelIndexList items = deselected.indexes();
356 molids_t ids;
357 ids.reserve(items.size());
358 foreach (index, items)
359 if (index.column() == 0){
360 int mol_id = model()->data(index, Qt::UserRole).toInt();
361 if (mol_id < 0)
362 continue;
363 //std::cout << "unselect molecule" << std::endl;
364 ids.push_back(mol_id);
365 }
366 MoleCuilder::SelectionNotMoleculeById(ids);
367 }
368
369 selecting = false;
370}
Note: See TracBrowser for help on using the repository browser.