/*
* Project: MoleCuilder
* Description: creates and alters molecular systems
* Copyright (C) 2010-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 .
*/
/*
* Menu.cpp
*
* Created on: Dec 10, 2009
* Author: crueger
*/
// include config.h
#ifdef HAVE_CONFIG_H
#include
#endif
#include "CodePatterns/MemDebug.hpp"
#include
#include "Actions/Action.hpp"
#include "Actions/ActionQueue.hpp"
#include "Actions/ActionTrait.hpp"
#include "Menu/Menu.hpp"
using namespace MoleCuilder;
/** Constructor of class Menu.
* \param &_name name of menu
*/
Menu::Menu(const std::string &_name) :
MenuInterface(_name),
name(_name),
TopPosition(0),
LastItem(NoItem)
{}
/** Destructor of class Menu.
*
*/
Menu::~Menu()
{
DuplicatesList.clear();
}
/** Initialiser for class Menu.
* Fills menus with items.
*/
void Menu::init()
{
populate();
populateActions();
}
/** Initializing function.
* Inserts Menus and Actions obtained from MenuDescription and
* ActionRegistry.
*/
void Menu::populate()
{
// go through all menus and create them
bool CompleteFlag = false; // indicates whether all menus have been added
bool PossibleMissingFlag = false; // indicates whether a separator is missing
while (!CompleteFlag) {
CompleteFlag = true;
PossibleMissingFlag = false;
for(MenuDescription::const_iterator iter = MenuDescription::getInstance().getBeginIter();
iter != MenuDescription::getInstance().getEndIter();
++iter) {
// skip when already present
if (!isPresent(iter->first)) {
// have some short refs to infos
const std::string &MenuName = iter->first;
const std::string &TopName = iter->second.first;
const int &MenuPosition = iter->second.second;
// std::cout << "MenuName is " << MenuName
// << ", TopName is " << TopName
// << " and Position is " << MenuPosition
// << std::endl;
// does it belong to us?
if (TopName == name) {
if (MenuPosition-1 == TopPosition) {
Menu::addSubmenu(MenuName, MenuPosition);
CompleteFlag = false;
}
// is there a menuposition specified that we have not reached yet?
if (MenuPosition-1 > TopPosition)
PossibleMissingFlag = true;
}
}
}
if (PossibleMissingFlag && (CompleteFlag)) {
Menu::addSeparator();
CompleteFlag = false; // pass once more as there should be a menu to come
}
}
}
/** Fills this menu with all Actions that belong to it.
*/
void Menu::populateActions()
{
// go through all actions and add those belonging to this menu
ActionQueue &AQ = ActionQueue::getInstance();
ActionQueue::ActionTokens_t tokens = AQ.getListOfActions();
for (ActionQueue::ActionTokens_t::const_iterator iter = tokens.begin();
iter != tokens.end(); ++iter) {
const ActionTrait &CurrentTrait = AQ.getActionsTrait(*iter);
const std::string &MenuName = CurrentTrait.getMenuName();
if (MenuName == name) {
const std::string &ActionName = *iter;
const std::string &ActionDescription = CurrentTrait.getDescription();
Menu::addAction(ActionName, ActionDescription);
}
}
}
void Menu::addAction(const std::string &ActionName, const std::string &ActionDescription)
{
LastItem = ActionItem;
addActionItem(ActionName, ActionDescription);
}
void Menu::addSeparator()
{
// std::cout << "Creating separator at position " << TopPosition << std::endl;
ASSERT( LastItem != SeparatorItem,
"Menu::populate() - adding another separator after a separator!");
LastItem = SeparatorItem;
addSeparatorItem();
TopPosition++;
}
void Menu::addSubmenu(const std::string &MenuName, const int MenuPosition)
{
// std::cout << "Creating top-level menu " << MenuName
// << " at position " << TopPosition << std::endl;
ASSERT (!isPresent(MenuName),
"Menu::addSubmenu() - trying to add menu "+MenuName+" with already present token!");
addSubmenuItem(MenuName, MenuDescription::getInstance().getDescription(MenuName));
DuplicatesList.insert(MenuName);
LastItem = MenuItem;
TopPosition = MenuPosition;
}
bool Menu::isPresent(const std::string &token)
{
return (DuplicatesList.find(token) != DuplicatesList.end());
}