Mercurial > hg > svgui
changeset 152:6a3f3c13173f
* Add a friendlier setup mechanism to SubdividingMenu, and use it for all the
plugin menus, not just the by-name and by-maker ones
author | Chris Cannam |
---|---|
date | Mon, 25 Sep 2006 12:05:41 +0000 |
parents | 8f51db2434dc |
children | aaa3a53dbb10 |
files | widgets/SubdividingMenu.cpp widgets/SubdividingMenu.h |
diffstat | 2 files changed, 116 insertions(+), 24 deletions(-) [+] |
line wrap: on
line diff
--- a/widgets/SubdividingMenu.cpp Mon Sep 25 11:21:12 2006 +0000 +++ b/widgets/SubdividingMenu.cpp Mon Sep 25 12:05:41 2006 +0000 @@ -19,27 +19,40 @@ using std::set; using std::map; -SubdividingMenu::SubdividingMenu(QWidget *parent) : - QMenu(parent) +SubdividingMenu::SubdividingMenu(size_t lowerLimit, size_t upperLimit, + QWidget *parent) : + QMenu(parent), + m_lowerLimit(lowerLimit ? lowerLimit : 14), + m_upperLimit(upperLimit ? upperLimit : (m_lowerLimit * 5) / 2), + m_entriesSet(false) { } -SubdividingMenu::SubdividingMenu(const QString &title, QWidget *parent) : - QMenu(title, parent) +SubdividingMenu::SubdividingMenu(const QString &title, size_t lowerLimit, + size_t upperLimit, QWidget *parent) : + QMenu(title, parent), + m_lowerLimit(lowerLimit ? lowerLimit : 14), + m_upperLimit(upperLimit ? upperLimit : (m_lowerLimit * 5) / 2), + m_entriesSet(false) { } SubdividingMenu::~SubdividingMenu() { + for (map<QString, QObject *>::iterator i = m_pendingEntries.begin(); + i != m_pendingEntries.end(); ++i) { + delete i->second; + } } void SubdividingMenu::setEntries(const std::set<QString> &entries) { + m_entriesSet = true; + size_t total = entries.size(); - size_t chunk = 14; - if (total < (chunk * 3) / 2) return; + if (total < m_upperLimit) return; size_t count = 0; QMenu *chunkMenu = new QMenu(); @@ -52,7 +65,7 @@ j != entries.end(); ++j) { - std::cerr << "SubdividingMenu::setEntries: j -> " << j->toStdString() << std::endl; +// std::cerr << "SubdividingMenu::setEntries: j -> " << j->toStdString() << std::endl; m_nameToChunkMenuMap[*j] = chunkMenu; @@ -66,9 +79,11 @@ firstInitialInChunk = initial; } +// std::cerr << "count = "<< count << ", upper limit = " << m_upperLimit << std::endl; + bool lastInChunk = (k == entries.end() || - (count >= chunk-1 && - (count == (5*chunk) / 2 || + (count >= m_lowerLimit-1 && + (count == m_upperLimit || (*k)[0] != initial))); ++count; @@ -113,42 +128,93 @@ } void +SubdividingMenu::entriesAdded() +{ + if (m_entriesSet) { + std::cerr << "ERROR: SubdividingMenu::entriesAdded: setEntries was also called -- should use one mechanism or the other, but not both" << std::endl; + return; + } + + set<QString> entries; + for (map<QString, QObject *>::const_iterator i = m_pendingEntries.begin(); + i != m_pendingEntries.end(); ++i) { + entries.insert(i->first); + } + + setEntries(entries); + + for (map<QString, QObject *>::iterator i = m_pendingEntries.begin(); + i != m_pendingEntries.end(); ++i) { + + QMenu *menu = dynamic_cast<QMenu *>(i->second); + if (menu) { + addMenu(i->first, menu); + continue; + } + + QAction *action = dynamic_cast<QAction *>(i->second); + if (action) { + addAction(i->first, action); + continue; + } + } + + m_pendingEntries.clear(); +} + +void SubdividingMenu::addAction(QAction *action) { QString name = action->text(); + if (!m_entriesSet) { + m_pendingEntries[name] = action; + return; + } + if (m_nameToChunkMenuMap.find(name) == m_nameToChunkMenuMap.end()) { - std::cerr << "SubdividingMenu::addAction(" << name.toStdString() << "): not found in name-to-chunk map, adding to main menu" << std::endl; +// std::cerr << "SubdividingMenu::addAction(" << name.toStdString() << "): not found in name-to-chunk map, adding to main menu" << std::endl; QMenu::addAction(action); return; } - std::cerr << "SubdividingMenu::addAction(" << name.toStdString() << "): found in name-to-chunk map for menu " << m_nameToChunkMenuMap[name]->title().toStdString() << std::endl; +// std::cerr << "SubdividingMenu::addAction(" << name.toStdString() << "): found in name-to-chunk map for menu " << m_nameToChunkMenuMap[name]->title().toStdString() << std::endl; m_nameToChunkMenuMap[name]->addAction(action); } QAction * SubdividingMenu::addAction(const QString &name) { + if (!m_entriesSet) { + QAction *action = new QAction(name, this); + m_pendingEntries[name] = action; + return action; + } + if (m_nameToChunkMenuMap.find(name) == m_nameToChunkMenuMap.end()) { - std::cerr << "SubdividingMenu::addAction(" << name.toStdString() << "): not found in name-to-chunk map, adding to main menu" << std::endl; +// std::cerr << "SubdividingMenu::addAction(" << name.toStdString() << "): not found in name-to-chunk map, adding to main menu" << std::endl; return QMenu::addAction(name); } - std::cerr << "SubdividingMenu::addAction(" << name.toStdString() << "): found in name-to-chunk map for menu " << m_nameToChunkMenuMap[name]->title().toStdString() << std::endl; +// std::cerr << "SubdividingMenu::addAction(" << name.toStdString() << "): found in name-to-chunk map for menu " << m_nameToChunkMenuMap[name]->title().toStdString() << std::endl; return m_nameToChunkMenuMap[name]->addAction(name); } void SubdividingMenu::addAction(const QString &name, QAction *action) { + if (!m_entriesSet) { + m_pendingEntries[name] = action; + return; + } + if (m_nameToChunkMenuMap.find(name) == m_nameToChunkMenuMap.end()) { - std::cerr << "SubdividingMenu::addAction(" << name.toStdString() << "): not found in name-to-chunk map, adding to main menu" << std::endl; +// std::cerr << "SubdividingMenu::addAction(" << name.toStdString() << "): not found in name-to-chunk map, adding to main menu" << std::endl; QMenu::addAction(action); return; } - std::cerr << "SubdividingMenu::addAction(" << name.toStdString() << "): found in name-to-chunk map for menu " << m_nameToChunkMenuMap[name]->title().toStdString() << std::endl; +// std::cerr << "SubdividingMenu::addAction(" << name.toStdString() << "): found in name-to-chunk map for menu " << m_nameToChunkMenuMap[name]->title().toStdString() << std::endl; m_nameToChunkMenuMap[name]->addAction(action); } @@ -157,38 +223,54 @@ { QString name = menu->title(); + if (!m_entriesSet) { + m_pendingEntries[name] = menu; + return; + } + if (m_nameToChunkMenuMap.find(name) == m_nameToChunkMenuMap.end()) { - std::cerr << "SubdividingMenu::addMenu(" << name.toStdString() << "): not found in name-to-chunk map, adding to main menu" << std::endl; +// std::cerr << "SubdividingMenu::addMenu(" << name.toStdString() << "): not found in name-to-chunk map, adding to main menu" << std::endl; QMenu::addMenu(menu); return; } - std::cerr << "SubdividingMenu::addMenu(" << name.toStdString() << "): found in name-to-chunk map for menu " << m_nameToChunkMenuMap[name]->title().toStdString() << std::endl; +// std::cerr << "SubdividingMenu::addMenu(" << name.toStdString() << "): found in name-to-chunk map for menu " << m_nameToChunkMenuMap[name]->title().toStdString() << std::endl; m_nameToChunkMenuMap[name]->addMenu(menu); } QMenu * SubdividingMenu::addMenu(const QString &name) { + if (!m_entriesSet) { + QMenu *menu = new QMenu(name, this); + m_pendingEntries[name] = menu; + return menu; + } + if (m_nameToChunkMenuMap.find(name) == m_nameToChunkMenuMap.end()) { - std::cerr << "SubdividingMenu::addMenu(" << name.toStdString() << "): not found in name-to-chunk map, adding to main menu" << std::endl; +// std::cerr << "SubdividingMenu::addMenu(" << name.toStdString() << "): not found in name-to-chunk map, adding to main menu" << std::endl; return QMenu::addMenu(name); } - std::cerr << "SubdividingMenu::addMenu(" << name.toStdString() << "): found in name-to-chunk map for menu " << m_nameToChunkMenuMap[name]->title().toStdString() << std::endl; +// std::cerr << "SubdividingMenu::addMenu(" << name.toStdString() << "): found in name-to-chunk map for menu " << m_nameToChunkMenuMap[name]->title().toStdString() << std::endl; return m_nameToChunkMenuMap[name]->addMenu(name); } void SubdividingMenu::addMenu(const QString &name, QMenu *menu) { + if (!m_entriesSet) { + m_pendingEntries[name] = menu; + return; + } + if (m_nameToChunkMenuMap.find(name) == m_nameToChunkMenuMap.end()) { - std::cerr << "SubdividingMenu::addMenu(" << name.toStdString() << "): not found in name-to-chunk map, adding to main menu" << std::endl; +// std::cerr << "SubdividingMenu::addMenu(" << name.toStdString() << "): not found in name-to-chunk map, adding to main menu" << std::endl; QMenu::addMenu(menu); return; } - std::cerr << "SubdividingMenu::addMenu(" << name.toStdString() << "): found in name-to-chunk map for menu " << m_nameToChunkMenuMap[name]->title().toStdString() << std::endl; +// std::cerr << "SubdividingMenu::addMenu(" << name.toStdString() << "): found in name-to-chunk map for menu " << m_nameToChunkMenuMap[name]->title().toStdString() << std::endl; m_nameToChunkMenuMap[name]->addMenu(menu); }
--- a/widgets/SubdividingMenu.h Mon Sep 25 11:21:12 2006 +0000 +++ b/widgets/SubdividingMenu.h Mon Sep 25 12:05:41 2006 +0000 @@ -29,17 +29,21 @@ * The menu needs to be told, before any of the actions are added, * what the set of entry strings will be, so it can determine a * reasonable categorisation. Do this by calling the setEntries() - * method. + * method. If it isn't practical to do this in advance, then add the + * entries and call entriesAdded() afterwards instead. */ class SubdividingMenu : public QMenu { public: - SubdividingMenu(QWidget *parent = 0); - SubdividingMenu(const QString &title, QWidget *parent = 0); + SubdividingMenu(size_t lowerLimit = 0, size_t upperLimit = 0, + QWidget *parent = 0); + SubdividingMenu(const QString &title, size_t lowerLimit = 0, + size_t upperLimit = 0, QWidget *parent = 0); virtual ~SubdividingMenu(); void setEntries(const std::set<QString> &entries); + void entriesAdded(); // Action names and strings passed to addAction and addMenu must // appear in the set previously given to setEntries. If you want @@ -57,6 +61,12 @@ protected: std::map<QString, QMenu *> m_nameToChunkMenuMap; + + size_t m_lowerLimit; + size_t m_upperLimit; + + bool m_entriesSet; + std::map<QString, QObject *> m_pendingEntries; }; #endif