/* * Project: MoleCuilder * Description: creates and alters molecular systems * Copyright (C) 2010 University of Bonn. All rights reserved. * Please see the LICENSE file or "Copyright notice" in builder.cpp for details. */ /* * AddAction.cpp * * Created on: May 9, 2010 * Author: heber */ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include "Helpers/MemDebug.hpp" #include "Actions/AtomAction/AddAction.hpp" #include "Actions/ActionRegistry.hpp" #include "Descriptors/AtomIdDescriptor.hpp" #include "atom.hpp" #include "element.hpp" #include "Helpers/Log.hpp" #include "molecule.hpp" #include "LinearAlgebra/Vector.hpp" #include "Helpers/Verbose.hpp" #include "World.hpp" #include #include using namespace std; #include "UIElements/UIFactory.hpp" #include "UIElements/Dialog.hpp" #include "Actions/ValueStorage.hpp" // memento to remember the state when undoing class AtomAddState : public ActionState { public: AtomAddState(const Vector &_position, const element *_elemental, const atomId_t _id) : position(_position), elemental(_elemental), id(_id) {} Vector position; const element *elemental; atomId_t id; }; const char AtomAddAction::NAME[] = "add-atom"; AtomAddAction::AtomAddAction() : Action(NAME) {} AtomAddAction::~AtomAddAction() {} void AtomAdd(element *elemental, Vector &position) { ValueStorage::getInstance().setCurrentValue(AtomAddAction::NAME, elemental); ValueStorage::getInstance().setCurrentValue("position", elemental); ActionRegistry::getInstance().getActionByName(AtomAddAction::NAME)->call(Action::NonInteractive); }; Dialog * AtomAddAction::fillDialog(Dialog *dialog) { ASSERT(dialog,"No Dialog given when filling action dialog"); dialog->queryElement(NAME, ValueStorage::getInstance().getDescription(NAME)); dialog->queryVector("position", true, ValueStorage::getInstance().getDescription("position")); return dialog; } Action::state_ptr AtomAddAction::performCall() { const element * elemental = NULL; Vector position; // obtain information ValueStorage::getInstance().queryCurrentValue(NAME, elemental); ValueStorage::getInstance().queryCurrentValue("position", position); // execute action atom * first = World::getInstance().createAtom(); first->setType(elemental); first->setPosition(position); DoLog(1) && (Log() << Verbose(1) << "Adding new atom with element " << first->getType()->getName() << " at " << (first->getPosition()) << "." << endl); // TODO: remove when all of World's atoms are stored. std::vector molecules = World::getInstance().getAllMolecules(); if (!molecules.empty()) { std::vector::iterator iter = molecules.begin(); (*iter)->AddAtom(first); } return Action::state_ptr(new AtomAddState(position, elemental, first->getId())); } Action::state_ptr AtomAddAction::performUndo(Action::state_ptr _state) { AtomAddState *state = assert_cast(_state.get()); DoLog(1) && (Log() << Verbose(1) << "Removing atom with id " << state->id << "." << endl); World::getInstance().destroyAtom(state->id); return Action::state_ptr(_state); } Action::state_ptr AtomAddAction::performRedo(Action::state_ptr _state){ AtomAddState *state = assert_cast(_state.get()); atom * first = World::getInstance().createAtom(); first->setType(state->elemental); first->setPosition(state->position); DoLog(1) && (Log() << Verbose(1) << "Re-adding new atom with element " << state->elemental->getName() << " at " << state->position << "." << endl); // TODO: remove when all of World's atoms are stored. std::vector molecules = World::getInstance().getAllMolecules(); if (!molecules.empty()) { std::vector::iterator iter = molecules.begin(); (*iter)->AddAtom(first); } if (first->getId() != state->id) if (!first->changeId(state->id)) return Action::failure; return Action::state_ptr(_state); } bool AtomAddAction::canUndo() { return true; } bool AtomAddAction::shouldUndo() { return true; } const string AtomAddAction::getName() { return NAME; }