/* * Project: MoleCuilder * Description: creates and alters molecular systems * Copyright (C) 2015 Frederik Heber. 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 . */ /* * QtSelectionChangedAgent.cpp * * Created on: Jul 17, 2015 * Author: heber */ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include "QtSelectionChangedAgent.hpp" #include "CodePatterns/MemDebug.hpp" #include "CodePatterns/Assert.hpp" #include "CodePatterns/Log.hpp" #include "CodePatterns/Observer/Notification.hpp" #include #include #include "Atom/atom.hpp" #include "Descriptors/AtomIdDescriptor.hpp" #include "molecule.hpp" #include "World.hpp" QtSelectionChangedAgent::QtSelectionChangedAgent(QObject *_parent) : QObject(_parent), Observable("QtSelectionChangedAgent") { World::getInstance().signOn(this, World::SelectionChanged); } QtSelectionChangedAgent::~QtSelectionChangedAgent() { World::getInstance().signOff(this, World::SelectionChanged); } void QtSelectionChangedAgent::update(Observable *publisher) { ASSERT(0, "QtSelectionChangedAgent::update() - we are not signed on for general updates."); } template std::pair, typename std::vector > getSelectedUnselectedDifference( typename std::vector &_oldselecteditems, typename std::vector &_newselecteditems) { std::pair, typename std::vector > SelectedUnselected; std::sort(_oldselecteditems.begin(), _oldselecteditems.end()); std::sort(_newselecteditems.begin(), _newselecteditems.end()); // first but not in second: all newly selected std::set_difference( _newselecteditems.begin(), _newselecteditems.end(), _oldselecteditems.begin(), _oldselecteditems.end(), std::back_inserter(SelectedUnselected.first)); // first but not in second: all before selected but now no longer std::set_difference( _oldselecteditems.begin(), _oldselecteditems.end(), _newselecteditems.begin(), _newselecteditems.end(), std::back_inserter(SelectedUnselected.second)); return SelectedUnselected; } void QtSelectionChangedAgent::recieveNotification(Observable *publisher, Notification_ptr notification) { if (dynamic_cast(publisher) != NULL) { switch (notification->getChannelNo()) { case World::SelectionChanged: { boost::recursive_mutex::scoped_lock lock(mutex); // check what changed and propagated changes specifically selectedAtoms_t newlyselectedatoms = const_cast(World::getInstance()).getSelectedAtomIds(); std::pair< selectedAtoms_t, selectedAtoms_t> AtomSelectionDifference = getSelectedUnselectedDifference(selectedAtoms, newlyselectedatoms); for (selectedAtoms_t::const_iterator selectediter = AtomSelectionDifference.first.begin(); selectediter != AtomSelectionDifference.first.end(); ++selectediter) { const atom * const _atom = const_cast(World::getInstance()).getAtom(AtomById(*selectediter)); if (_atom != NULL) { const molecule * const _mol = _atom->getMolecule(); if (_mol != NULL) emit atomSelected(_mol->getId(), *selectediter); else ELOG(2, "QtSelectionChangedAgent::recieveNotification() - selected atom " << *selectediter << " has no molecule."); } else ELOG(2, "QtSelectionChangedAgent::recieveNotification() - selected atom " << *selectediter << " has disappeared."); } for (selectedAtoms_t::const_iterator unselectediter = AtomSelectionDifference.second.begin(); unselectediter != AtomSelectionDifference.second.end(); ++unselectediter) { const atom * const _atom = const_cast(World::getInstance()).getAtom(AtomById(*unselectediter)); if (_atom != NULL) { const molecule * const _mol = _atom->getMolecule(); if (_mol != NULL) emit atomUnselected(_mol->getId(), *unselectediter); else ELOG(2, "QtSelectionChangedAgent::recieveNotification() - unselected atom " << *unselectediter << " has no molecule ."); } else ELOG(2, "QtSelectionChangedAgent::recieveNotification() - unselected atom " << *unselectediter << " has disappeared."); } selectedAtoms = newlyselectedatoms; selectedMolecules_t newlyselectedmolecules = const_cast(World::getInstance()).getSelectedMoleculeIds(); std::pair< selectedMolecules_t, selectedMolecules_t> MoleculeSelectionDifference = getSelectedUnselectedDifference(selectedMolecules, newlyselectedmolecules); for (selectedMolecules_t::const_iterator selectediter = MoleculeSelectionDifference.first.begin(); selectediter != MoleculeSelectionDifference.first.end(); ++selectediter) emit moleculeSelected(*selectediter); for (selectedMolecules_t::const_iterator unselectediter = MoleculeSelectionDifference.second.begin(); unselectediter != MoleculeSelectionDifference.second.end(); ++unselectediter) emit moleculeUnselected(*unselectediter); selectedMolecules = newlyselectedmolecules; break; } default: ASSERT(0, "QtSelectionChangedAgent::recieveNotification() - received notification from unexpected channel."); } } } void QtSelectionChangedAgent::subjectKilled(Observable *publisher) { // World is killed last anyway }