/* * Project: MoleCuilder * Description: creates and alters molecular systems * Copyright (C) 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 . */ /* * BondRemoveAction.cpp * * Created on: Nov 14, 2012 * Author: heber */ // include config.h #ifdef HAVE_CONFIG_H #include #endif //#include "CodePatterns/MemDebug.hpp" #include "Atom/atom.hpp" #include "Bond/bond.hpp" #include "CodePatterns/Assert.hpp" #include "CodePatterns/Log.hpp" #include "CodePatterns/Verbose.hpp" #include "Descriptors/AtomIdDescriptor.hpp" #include "World.hpp" #include "WorldTime.hpp" #include #include #include "Actions/BondAction/BondRemoveAction.hpp" using namespace MoleCuilder; // and construct the stuff #include "BondRemoveAction.def" #include "Action_impl_pre.hpp" /** =========== define the function ====================== */ ActionState::ptr BondRemoveAction::performCall() { // check preconditions World& world = World::getInstance(); if (world.countSelectedAtoms() <= 1) { STATUS("At least two atoms must be selected for BondAction Remove."); return Action::failure; } bondPairIds_t bondPairIds; for (World::AtomSelectionConstIterator firstiter = world.beginAtomSelection(); firstiter != world.endAtomSelection(); ++firstiter) { for (World::AtomSelectionConstIterator seconditer = firstiter; seconditer != world.endAtomSelection(); ++seconditer) { if (firstiter == seconditer) continue; if ((firstiter->second)->IsBondedTo(WorldTime::getTime(), seconditer->second)) bondPairIds.push_back( std::make_pair((firstiter->second)->getId(), (seconditer->second)->getId())); } } if (bondPairIds.empty()) { STATUS("No bonds are present."); return Action::failure; } // create undo BondRemoveState *UndoState = new BondRemoveState(bondPairIds, params); // execute action for (bondPairIds_t::const_iterator iter = bondPairIds.begin(); iter != bondPairIds.end(); ++iter) { atom *firstatom = world.getAtom(AtomById(iter->first)); atom *secondatom = world.getAtom(AtomById(iter->second)); ASSERT((firstatom != NULL) && (secondatom != NULL), "BondAddAction::performCall() - at least one of the ids " +toString(iter->first)+" or "+toString(iter->second)+" is not present."); firstatom->removeBond(WorldTime::getTime(), secondatom); ASSERT( !firstatom->IsBondedTo(WorldTime::getTime(), secondatom), "BondAddAction::performCall() - adding bond in between " +toString(*firstatom)+" and "+toString(*secondatom)+" failed."); } return ActionState::ptr(UndoState); } ActionState::ptr BondRemoveAction::performUndo(ActionState::ptr _state) { BondRemoveState *state = assert_cast(_state.get()); World& world = World::getInstance(); for (bondPairIds_t::const_iterator iter = state->bondPairIds.begin(); iter != state->bondPairIds.end(); ++iter) { atom * const firstatom = world.getAtom(AtomById(iter->first)); atom * const secondatom = world.getAtom(AtomById(iter->second)); ASSERT((firstatom != NULL) && (secondatom != NULL), "BondAddAction::performCall() - at least one of the ids " +toString(iter->first)+" or "+toString(iter->second)+" is not present."); if (!firstatom->IsBondedTo(WorldTime::getTime(), secondatom)) { firstatom->addBond(WorldTime::getTime(), secondatom); } else { ELOG(2, "There is already a bond in between "+toString(iter->first) +" and "+toString(iter->second)+"."); } } return ActionState::ptr(_state); } ActionState::ptr BondRemoveAction::performRedo(ActionState::ptr _state){ BondRemoveState *state = assert_cast(_state.get()); World& world = World::getInstance(); for (bondPairIds_t::const_iterator iter = state->bondPairIds.begin(); iter != state->bondPairIds.end(); ++iter) { atom *firstatom = world.getAtom(AtomById(iter->first)); atom *secondatom = world.getAtom(AtomById(iter->second)); ASSERT((firstatom != NULL) && (secondatom != NULL), "BondAddAction::performCall() - at least one of the ids " +toString(iter->first)+" or "+toString(iter->second)+" is not present."); if (firstatom->IsBondedTo(WorldTime::getTime(), secondatom)) { firstatom->removeBond(WorldTime::getTime(), secondatom); } else { ELOG(2, "There is no bond in between "+toString(iter->first) +" and "+toString(iter->second)+"."); } } return ActionState::ptr(_state); } bool BondRemoveAction::canUndo() { return true; } bool BondRemoveAction::shouldUndo() { return true; } /** =========== end of function ====================== */