/* * 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. */ /* * QtMainWindow.cpp * * Created on: Jan 14, 2010 * Author: crueger */ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include "QtMainWindow.hpp" #include #include #include #include #include #include #include #include #include "Helpers/MemDebug.hpp" #include "atom.hpp" #include "molecule.hpp" #include "Helpers/Verbose.hpp" #include "Actions/Action.hpp" #include "Actions/ActionRegistry.hpp" #include "Actions/ValueStorage.hpp" #include "Menu/MenuDescription.hpp" #include "Menu/Menu.hpp" #include "Menu/Qt4/QtMenu.hpp" #include "Menu/ActionMenuItem.hpp" #include "Menu/SubMenuItem.hpp" #include "Views/Qt4/QtWorldView.hpp" #include "Views/Qt4/GLMoleculeView.hpp" #include "Views/Qt4/QtMoleculeView.hpp" #include "Views/Qt4/QtStatusBar.hpp" QtMainWindow::QtMainWindow(QApplication *_theApp) : theApp(_theApp) { QSplitter *splitter1 = new QSplitter (Qt::Horizontal, this ); QSplitter *splitter2 = new QSplitter (Qt::Vertical, splitter1 ); worldDisplay = new QtWorldView(splitter2); moleculeDisplay = new QtMoleculeView(); molecule3dDisplay = new GLMoleculeView(); MenuBar = menuBar(); // populate menus and add actions { QtMenuReferenceMap NametoTextMenuMap; // contains token to menu reference map MenuShortcutMap ShortcutMap; populateMenu(NametoTextMenuMap, ShortcutMap); populateMenuWithActions(NametoTextMenuMap, ShortcutMap); } setCentralWidget(splitter1); splitter1->addWidget(splitter2); splitter1->addWidget(moleculeDisplay); splitter2->addWidget(molecule3dDisplay); splitter2->addWidget(worldDisplay); statusBar = new QtStatusBar(this); setStatusBar(statusBar); connect(worldDisplay,SIGNAL(moleculeSelected(molecule*)),moleculeDisplay,SLOT(moleculeSelected(molecule*))); connect(worldDisplay,SIGNAL(moleculeUnSelected(molecule*)),moleculeDisplay,SLOT(moleculeUnSelected(molecule*))); } QtMainWindow::~QtMainWindow() { menuBar()->clear(); } void QtMainWindow::display() { this->show(); theApp->exec(); } /** Puts Qt's token, the ampersand, in front of the accelerator char in the menu name. * \param ShortcutMap map to all already present accelerator keys * \param MenuName Action of menu * \param ActionName Action of menu * \return name with ampersand added at the right place */ std::string QtMainWindow::getNameWithAccelerator(MenuShortcutMap &ShortcutMap, const std::string &MenuName, const std::string &ActionName) const { std::string newname; bool Inserted = false; std::pair < MenuShortcutMap::iterator, bool > Inserter; for (std::string::const_iterator CharRunner = ActionName.begin(); CharRunner != ActionName.end(); ++CharRunner) { if (!Inserted) { Inserter = ShortcutMap.insert( std::pair (MenuName, *CharRunner) ); if (Inserter.second) { newname += '&'; Inserted = true; } } newname += *CharRunner; } return newname; } /** Instantiate all menus. * \param NametoTextMenuMap lookup for token to menu reference */ void QtMainWindow::populateMenu(QtMenuReferenceMap &NametoTextMenuMap, MenuShortcutMap &ShortcutMap) { // go through all menus and create them std::map TopPositions; TopPositions.insert( std::pair ("", 0) ); // contains which position was added last QtMenu *Menu = NULL; MenuDescription menudescriptions; std::set ShortcutList; bool CompleteFlag = false; while (!CompleteFlag) { CompleteFlag = true; for(MenuDescription::const_iterator iter = menudescriptions.getBeginIter(); iter != menudescriptions.getEndIter(); ++iter) { // skip when already present if (NametoTextMenuMap.find(iter->first) == NametoTextMenuMap.end()) { // 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; // is it top level? if (TopName == "") { ASSERT(TopPositions.find(TopName) != TopPositions.end(), "QtMainWindow::QtMainWindow() - "+TopName+" not present in TopPositions."); if (MenuPosition-1 == TopPositions[TopName]) { std::cout << "Creating top-level menu " << MenuName << " at position " << MenuPosition << std::endl; Menu = new QtMenu(getNameWithAccelerator(ShortcutMap, TopName, MenuName).c_str()); MenuBar->addMenu(Menu); NametoTextMenuMap.insert( pair (MenuName, Menu) ); CompleteFlag = false; TopPositions[TopName] = MenuPosition; TopPositions[MenuName] = 0; } } // is it a submenu and the top-level menu is present? else if (NametoTextMenuMap.find(TopName) != NametoTextMenuMap.end()) { ASSERT(TopPositions.find(TopName) != TopPositions.end(), "QtMainWindow::QtMainWindow() - "+TopName+" not present in TopPositions."); if (MenuPosition-1 == TopPositions[TopName]) { QtMenu *& TopMenu = NametoTextMenuMap[TopName]; std::cout << "Creating submenu " << MenuName << " to menu " << TopName << " at position " << MenuPosition << std::endl; Menu = new QtMenu(getNameWithAccelerator(ShortcutMap, TopName, MenuName).c_str()); TopMenu->addMenu(Menu); NametoTextMenuMap.insert( pair (MenuName, Menu) ); CompleteFlag = false; TopPositions[TopName] = MenuPosition; } } } } } } /** Instantiate all actions within the menus. * \param NametoTextMenuMap lookup for token to menu reference * \param ShortcutMap map for all shortcuts within one menu */ void QtMainWindow::populateMenuWithActions(QtMenuReferenceMap &NametoTextMenuMap, MenuShortcutMap &ShortcutMap) { typedef std::multimap MenuMap; // go through all menus MenuDescription md; MenuMap MenuItems = md.getMenuItemsMap(); QtMenu *Menu = NULL; Action *ActionItem = NULL; std::string OldMenuName; for (MenuMap::const_iterator MenuRunner = MenuItems.begin(); MenuRunner != MenuItems.end(); ++MenuRunner) { const std::string &ActionName = MenuRunner->second; const std::string &MenuName = MenuRunner->first; // add the actions to this menu std::cout << " Adding " << ActionName << " to submenu " << MenuName << std::endl; ActionItem = ActionRegistry::getInstance().getActionByName(ActionName); ASSERT(NametoTextMenuMap.find(MenuName) != NametoTextMenuMap.end(), "QtMainWindow::populateMenu() - cannot find reference for menu "+MenuName+" in NametoTextMenuMap."); Menu = NametoTextMenuMap[MenuName]; //ASSERT(ShortcutMap.find(MenuName) != ShortcutMap.end(), // "QtMainWindow::populateMenuWithActions() - missing "+MenuName+" in ShortcutMap."); new ActionMenuItem( 'a', ActionItem->Traits.getDescription().c_str(), Menu, ActionItem); } }