/*
* 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
}