/* * 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. */ /* * Action.cpp * * Created on: Dec 8, 2009 * Author: crueger */ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include "CodePatterns/MemDebug.hpp" #include #include #include #include "Actions/Action.hpp" #include "Actions/ActionExceptions.hpp" #include "Actions/ActionRegistry.hpp" #include "Actions/ActionHistory.hpp" #include "Actions/OptionRegistry.hpp" #include "Actions/OptionTrait.hpp" //#include "Actions/ValueStorage.hpp" #include "UIElements/Dialog.hpp" #include "CodePatterns/Assert.hpp" #include "CodePatterns/MemDebug.hpp" #include "UIElements/UIFactory.hpp" #include "CodePatterns/Log.hpp" #include "CodePatterns/Verbose.hpp" using namespace MoleCuilder; Action::state_ptr getEmptyState() { return Action::state_ptr(Memory::ignore(new ActionState())); } // An empty state to indicate success Action::state_ptr Action::success = getEmptyState(); Action::state_ptr Action::failure = getEmptyState(); Action::Action(const ActionTraits &_Traits, bool _doRegister) : Traits(_Traits) { // register with ActionRegistry if(_doRegister){ ActionRegistry::getInstance().registerInstance(this); } // register with OptionRegistry for (ActionTraits::options_const_iterator optioniter = Traits.getBeginIter(); optioniter != Traits.getEndIter(); ++optioniter) { // options may have been re-used by other Actions, so check beforehand whether adding is needed if (!OptionRegistry::getInstance().isOptionPresentByName((optioniter->first))) { OptionRegistry::getInstance().registerInstance(optioniter->second); } else { // if present, ASSERT that types coincide #ifndef NDEBUG OptionTrait const * const PresentOption = OptionRegistry::getInstance().getOptionByName(optioniter->first); #endif ASSERT(PresentOption->getType() == optioniter->second->getType(), ("Action::Action() - option to add "+ std::string(optioniter->first)+ " of Action "+ std::string(getName())+ " is already present with different type: " +toString(PresentOption->getType())+" != "+toString(optioniter->second->getType()) ) ); ASSERT(PresentOption->getDefaultValue() == optioniter->second->getDefaultValue(), ("Action::Action() - option to add "+ std::string(optioniter->first)+ " of Action "+ std::string(getName())+ " is already present with different default value: " +PresentOption->getDefaultValue()+" != "+optioniter->second->getDefaultValue() ) ); ASSERT(PresentOption->getShortForm() == optioniter->second->getShortForm(), ("Action::Action() - option to add "+ std::string(optioniter->first)+ " of Action "+ std::string(getName())+ " is already present with different short form: " +PresentOption->getShortForm()+" != "+optioniter->second->getShortForm() ) ); } } } Action::~Action() {} const string Action::getName() const { return Traits.getName(); } const std::string Action::help() const { std::stringstream outputstream; outputstream << "Description for Action '" << getName() << "': " << Traits.getDescription() << std::endl; if (!Traits.hasOption(getName())) { outputstream << "\tNote that this Action does not take an argument." << std::endl; } outputstream << "Options available for action '" << getName() << "':" << std::endl; for (ActionTraits::options_const_iterator iter = Traits.getBeginIter(); iter != Traits.getEndIter(); ++iter) { outputstream << "Option '" << iter->first << "':" << std::endl; outputstream << "\tDescription: " << iter->second->getDescription() << "." << std::endl; outputstream << "\tArgument's type: " << iter->second->getTypeName() << "." << std::endl; outputstream << "\tDefault value: "; if (iter->second->hasDefaultValue()) { outputstream << "Yes, is '" << iter->second->getDefaultValue() << "'"; } else { outputstream << "None"; } outputstream << "." << std::endl; } return outputstream.str(); } void Action::removeStaticStateEntities() { success.reset(); failure.reset(); } Dialog * Action::createDialog(){ Dialog *dialog = UIFactory::getInstance().makeDialog(); return fillDialog(dialog); } void Action::call(enum QueryOptions flag){ if(!isActive()){ return; } // forward to private virtual if (flag == Interactive) { Dialog* dialog = createDialog(); if (dialog->hasQueries()) { dialog->display(); } delete(dialog); } state_ptr state = Action::failure; // try { state = performCall(); // } catch(MissingValueException&) { // DoeLog(0) && (eLog() << Verbose(0) << "There is a value missing for action " << getName() << endl); // }; if(shouldUndo() && state != failure){ if(canUndo()){ ActionHistory::getInstance().addElement(this,state); } else{ ActionHistory::getInstance().clear(); } } // throw an exception that can be caught in case of failure if (state == Action::failure) throw ActionFailureException() << ActionNameString(getName()); } Action::state_ptr Action::undo(state_ptr _state) { // forward to private virtual return performUndo(_state); } Action::state_ptr Action::redo(state_ptr _state) { // forward to private virtual return performRedo(_state); } bool Action::isActive(){ return true; }