/* * Project: MoleCuilder * Description: creates and alters molecular systems * Copyright (C) 2010-2012 University of Bonn. All rights reserved. * * * This file is part of MoleCuilder. * * MoleCuilder is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * MoleCuilder is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with MoleCuilder. If not, see . */ /* * QtElementList.cpp * * Created on: Mar 6, 2012 * Author: ankele */ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include "Views/Qt4/QtElementList.hpp" #include #include "CodePatterns/MemDebug.hpp" #include "Atom/atom.hpp" #include "Atom/AtomObserver.hpp" #include "Element/element.hpp" #include "Element/periodentafel.hpp" #include "Descriptors/AtomTypeDescriptor.hpp" #include #include "Actions/SelectionAction/Atoms/AtomByElementAction.hpp" #include "Actions/SelectionAction/Atoms/NotAtomByElementAction.hpp" using namespace std; const int QtElementList::COLUMNCOUNT = COLUMNTYPES_MAX; const char *QtElementList::COLUMNNAMES[QtElementList::COLUMNCOUNT]={"Number","Name","Symbol","Mass","Occurrence"}; QtElementList::QtElementList(QWidget * _parent) : QTreeWidget (_parent), Observer("QtElementList") { setColumnCount(COLUMNCOUNT); setSelectionMode(QAbstractItemView::MultiSelection); QStringList header; for(int i=0; ibegin(),i=0; iter != periode->end(); ++i,++iter) { const element *e = iter->second; int count = 0; count = const_cast(World::getInstance()). getAllAtoms(AtomByType(e)).size(); QTreeWidgetItem *treeItem = new QTreeWidgetItem(this); treeItem->setText(NUMBER, QString::number(e->getAtomicNumber())); treeItem->setText(NAME, QString(e->getName().c_str())); treeItem->setText(SYMBOL, QString(e->getSymbol().c_str())); treeItem->setText(MASS, QString::number(e->getMass())); setOccurrence(*treeItem, count); elementSelection.push_back(treeItem->isSelected()); // insertTopLevelItem(e->getAtomicNumber()-1, treeItem); } } dirty = true; AtomObserver::getInstance().signOn(this, atom::ElementChanged); connect(this,SIGNAL(itemSelectionChanged()),this,SLOT(rowSelected())); connect(this,SIGNAL(needsRefill(const atomId_t)),this,SLOT(refill(const atomId_t)), Qt::QueuedConnection); // connect(this,SIGNAL(changed()),this,SLOT(update())); } QtElementList::~QtElementList() { AtomObserver::getInstance().signOff(this, atom::ElementChanged); } void QtElementList::update(Observable *publisher) { ASSERT(0, "QtElementList::update() - is not enlisted to any general update."); } void QtElementList::recieveNotification(Observable *publisher, Notification_ptr notification) { if (notification->getChannelNo() == atom::ElementChanged) { dirty = true; emit needsRefill(dynamic_cast(publisher)->getId()); } else ASSERT(0, "QtElementList::recieveNotification() - we are not enlisted to any other instance's channel."); } void QtElementList::updateElement(const atom &_atom) { const atomicNumber_t newelement = _atom.getElementNo(); atomicNumber_t oldelement = -1; QTreeWidgetItem *newtreeItem = topLevelItem(newelement-1); ASSERT( newtreeItem != NULL, "QtElementList::updateElement() - new element item not present."); // if (newtreeItem == NULL) { // // add new item // const element& e = _atom.getElement(); // newtreeItem = new QTreeWidgetItem(); // newtreeItem->setText(NUMBER, QString::number(e.getAtomicNumber())); // newtreeItem->setText(NAME, QString(e.getName().c_str())); // newtreeItem->setText(SYMBOL, QString(e.getSymbol().c_str())); // newtreeItem->setText(MASS, QString::number(e.getMass())); // setOccurrence(*newtreeItem, 0); // elementSelection.push_back(newtreeItem->isSelected()); // insertTopLevelItem(newelement-1, newtreeItem); // } AtomElementMap_t::iterator iter = AtomElementMap.find(_atom.getId()); if (iter == AtomElementMap.end()) { AtomElementMap.insert( std::make_pair(_atom.getId(), -1)); iter = AtomElementMap.find(_atom.getId()); } else oldelement = iter->second; iter->second = newelement; // reduce old occurence if (oldelement != (atomicNumber_t)-1) { QTreeWidgetItem *oldtreeItem = topLevelItem(oldelement-1); ASSERT( oldtreeItem != NULL, "QtElementList::updateElement() - old element item not present."); const int count_old = oldtreeItem->text(OCCURRENCE).toInt(); setOccurrence(*oldtreeItem, count_old-1); } // increase new occurence const int count_new = newtreeItem->text(OCCURRENCE).toInt(); setOccurrence(*newtreeItem, count_new+1); } void QtElementList::setOccurrence(QTreeWidgetItem &_item, const int count) { ASSERT (count >= 0, "QtElementList::setOccurrence() - count for an elment < 0."); if (count > 0) { _item.setText(OCCURRENCE, QString::number(count)); if (_item.isDisabled()) _item.setDisabled(false); } else { _item.setText(OCCURRENCE, "none"); _item.setDisabled(true); } } void QtElementList::refill(const atomId_t _atomid) { refill_mutex.lock(); const atom * const walker = const_cast(World::getInstance()). getAtom(AtomById(_atomid)); if (walker != NULL) updateElement(*walker); else { AtomElementMap_t::iterator iter = AtomElementMap.find(_atomid); if (iter != AtomElementMap.end()) { QTreeWidgetItem *oldtreeItem = topLevelItem(iter->second-1); const int count_old = oldtreeItem->text(OCCURRENCE).toInt(); setOccurrence(*oldtreeItem, count_old-1); AtomElementMap.erase(iter); } } refill_mutex.unlock(); } void QtElementList::paintEvent(QPaintEvent * event) { // if (dirty) // refill(); QTreeWidget::paintEvent(event); } void QtElementList::subjectKilled(Observable *publisher) { } void QtElementList::rowSelected() { //std::cout << "rowSelected\n"; periodentafel *&periode = World::getInstance().getPeriode(); for (int i=0;iisSelected(); if (newSelection != elementSelection[i]){ elementSelection[i] = newSelection; int atomicNumber = item->text(NUMBER).toInt(); const element *e = periode->FindElement(atomicNumber); if (newSelection) MoleCuilder::SelectionAtomByElement(e); else MoleCuilder::SelectionNotAtomByElement(e); } } }