File indexing completed on 2024-03-24 15:43:44

0001 //
0002 // C++ Implementation: cMenuManager
0003 //
0004 // Description: Menu manager.
0005 //
0006 /*
0007 Copyright 2006-2011 Tomas Mecir <kmuddy@kmuddy.com>
0008 
0009 This program is free software; you can redistribute it and/or
0010 modify it under the terms of the GNU General Public License as
0011 published by the Free Software Foundation; either version 2 of 
0012 the License, or (at your option) any later version.
0013 
0014 This program is distributed in the hope that it will be useful,
0015 but WITHOUT ANY WARRANTY; without even the implied warranty of
0016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0017 GNU General Public License for more details.
0018 
0019 You should have received a copy of the GNU General Public License
0020 along with this program.  If not, see <http://www.gnu.org/licenses/>.
0021 */
0022 
0023 #include "cmenumanager.h"
0024 
0025 #include <QAction>
0026 #include <QMenuBar>
0027 #include <QMenu>
0028 
0029 #include <list>
0030 #include <map>
0031 
0032 using namespace std;
0033 
0034 struct cMenuManagerPrivate {
0035   QMenuBar *menuBar;
0036   map<QString, QAction *> positions;  // where to place individual items
0037   map<QString, QMenu *> locations;    // which position is in which menu
0038   map<QMenu *, QString> lastPositionInMenu;
0039   map<QMenu *, QAction *> menuActions;
0040   map<QAction *, QMenu *> actionLocations;
0041 };
0042 
0043 cMenuManager *cMenuManager::_self = nullptr;
0044 
0045 cMenuManager::cMenuManager () : cActionBase ("menumanager", 0)
0046 {
0047   d = new cMenuManagerPrivate;
0048   d->menuBar = nullptr;
0049 }
0050 
0051 cMenuManager::~cMenuManager ()
0052 {
0053   delete d;
0054 }
0055 
0056 cMenuManager *cMenuManager::self ()
0057 {
0058   if (!_self) _self = new cMenuManager;
0059   return _self;
0060 }
0061 
0062 void cMenuManager::setMenuBar (QMenuBar *menuBar)
0063 {
0064   d->menuBar = menuBar;
0065 }
0066 
0067 void cMenuManager::addMenuPosition (const QString &name)
0068 {
0069   addItemPosition (name, nullptr);
0070 }
0071 
0072 void cMenuManager::addItemPosition (const QString &name, QMenu *menu)
0073 {
0074   if (d->positions.count (name)) return;
0075   
0076   // we are now the last position without a separator
0077   // so assign a separator to the previously old position
0078   if (d->lastPositionInMenu.count (menu)) {
0079     QString last = d->lastPositionInMenu[menu];
0080     d->positions[last] = menu ? menu->addSeparator () : d->menuBar->addSeparator();
0081   }
0082   d->positions[name] = nullptr;
0083   d->lastPositionInMenu[menu] = name;
0084   d->locations[name] = menu;
0085 }
0086 
0087 void cMenuManager::addMenu (QMenu *menu, const QString &label, const QString &position)
0088 {
0089   // nothing if there's no such position
0090   if (!d->positions.count (position)) return;
0091   
0092   // plug the actual item
0093   QAction *before = d->positions[position];
0094   QMenu *inMenu = d->locations[position];
0095   if (inMenu) return;
0096   if (before)
0097     d->menuBar->insertMenu (before, menu);
0098   else
0099     d->menuBar->addMenu (menu);
0100   menu->setTitle (label);
0101 }
0102 
0103 void cMenuManager::removeMenu (QMenu *menu)
0104 {
0105   d->menuBar->removeAction (d->menuActions[menu]);
0106   d->menuActions.erase (menu);
0107   d->lastPositionInMenu.erase (menu);
0108 
0109   // remove all positions tied to this menu
0110   QStringList pl;
0111   map<QString, QMenu *>::iterator it;
0112   for (it = d->locations.begin(); it != d->locations.end(); ++it)
0113     if (it->second == menu)
0114       pl << it->first;
0115   QStringList::iterator ii;
0116   for (ii = pl.begin(); ii != pl.end(); ++ii)
0117   {
0118     d->positions.erase (*ii);
0119     d->locations.erase (*ii);
0120   }
0121 }
0122 
0123 void cMenuManager::plug (QAction *action, QString position)
0124 {
0125   // nothing if there's no such position
0126   if (!d->positions.count (position)) return;
0127   
0128   // plug the actual item
0129   QAction *before = d->positions[position];
0130   QMenu *menu = d->locations[position];
0131   if (!menu) return;
0132   if (before)
0133     menu->insertAction (before, action);
0134   else
0135     menu->addAction (action);
0136   d->actionLocations[action] = menu;
0137 }
0138 
0139 void cMenuManager::unplug (QAction *action)
0140 {
0141   QMenu *menu = d->actionLocations[action];
0142   if (menu) 
0143     menu->removeAction (action);
0144   d->actionLocations.erase (action);
0145 }
0146 
0147