/* * TextMenu.hpp * * Created on: Nov 5, 2010 * Author: heber */ #ifndef TEXTMENU_HPP_ #define TEXTMENU_HPP_ #include #include #include "Helpers/Log.hpp" #include "Helpers/Verbose.hpp" #include "Menu/Menu.hpp" #include "Menu/MenuInterface.hpp" #include "Actions/Action.hpp" #include "Actions/ActionRegistry.hpp" #include "Actions/ActionTraits.hpp" #include "Menu/TextMenu/TxMenu.hpp" #include "Menu/TextMenu/ActionMenuItem.hpp" #include "Menu/TextMenu/SeperatorItem.hpp" #include "Menu/TextMenu/SubMenuItem.hpp" /** TextMenu is a specialization of MenuInterface to access TxMenu-like menus. * \sa QtMenu. */ template class TextMenu : virtual public MenuInterface, public Menu { public: TextMenu(std::ostream &_outputter, const std::string &_token) : MenuInterface(_token), Menu(_token), MenuInstance(new T(_outputter, _token)), outputter(_outputter), deleteMenu(true) {} explicit TextMenu(T *_MenuInstance) : Menu(_MenuInstance->getTitle()), MenuInstance(_MenuInstance), outputter(_MenuInstance->getOutputter()), deleteMenu(false) {} virtual ~TextMenu() { if (deleteMenu) delete MenuInstance; } void display() { MenuInstance->display(); } T * const getMenuInstance() { return MenuInstance; } void reserveShortcut(char trigger, const std::string &name) { ShortcutMap.insert( std::pair < char, std::string> (trigger, name) ); } protected: // We need to have a reference of the Menu, as Qt returns reference to added menu as well T *MenuInstance; std::ostream &outputter; private: bool deleteMenu; typedef std::map MenuShortcutMap; MenuShortcutMap ShortcutMap; virtual void addActionItem(const std::string &token, const std::string &description) { new ActionMenuItem(getSuitableShortForm(description), description, MenuInstance, token); } virtual void addSeparatorItem() { new SeperatorItem(MenuInstance); } virtual void addSubmenuItem(const std::string &token, const std::string &description) { TextMenu *NewMenu = new TextMenu(outputter, token); new SubMenuItem(getSuitableShortForm(description), description, MenuInstance, NewMenu->getMenuInstance()); NewMenu->reserveShortcut('q',"leave"+token); ActionTraits leaveTrait( OptionTrait("leave"+token, &typeid(void), "leave menu "+token), token, ActionRegistry::getInstance().getLastPosition(token)+2); // have a separator in between new TxMenu::LeaveAction(NewMenu->getMenuInstance(), leaveTrait); NewMenu->init(); new ActionMenuItem('q',"leave"+token,NewMenu->getMenuInstance(),"leave"+token); } char getSuitableShortForm(const std::string &name) { for (std::string::const_iterator CharRunner = name.begin(); CharRunner != name.end(); ++CharRunner) { if (ShortcutMap.find(*CharRunner) == ShortcutMap.end()) { ShortcutMap.insert( std::pair < char, std::string> (*CharRunner, name) ); return *CharRunner; } } // if no letter matches, take digits int i=0; for (;i<10;++i) { if (ShortcutMap.find((char)i + '0') == ShortcutMap.end()) break; } if (i != 10) { ShortcutMap.insert( std::pair < char, std::string > ((char)i + '0', name)); return ((char)i + '0'); } else { DoeLog(1) && (eLog() << Verbose(1) << "Could not find a suitable shortform for " << name << "." << endl); return '#'; } } }; #endif /* TEXTMENU_HPP_ */