annotate widgets/SubdividingMenu.cpp @ 151:8f51db2434dc

* Pull alphabetical categorisation code out into a SubdividingMenu class
author Chris Cannam
date Mon, 25 Sep 2006 11:21:12 +0000
parents
children 6a3f3c13173f
rev   line source
Chris@151 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@151 2
Chris@151 3 /*
Chris@151 4 Sonic Visualiser
Chris@151 5 An audio file viewer and annotation editor.
Chris@151 6 Centre for Digital Music, Queen Mary, University of London.
Chris@151 7
Chris@151 8 This program is free software; you can redistribute it and/or
Chris@151 9 modify it under the terms of the GNU General Public License as
Chris@151 10 published by the Free Software Foundation; either version 2 of the
Chris@151 11 License, or (at your option) any later version. See the file
Chris@151 12 COPYING included with this distribution for more information.
Chris@151 13 */
Chris@151 14
Chris@151 15 #include "SubdividingMenu.h"
Chris@151 16
Chris@151 17 #include <iostream>
Chris@151 18
Chris@151 19 using std::set;
Chris@151 20 using std::map;
Chris@151 21
Chris@151 22 SubdividingMenu::SubdividingMenu(QWidget *parent) :
Chris@151 23 QMenu(parent)
Chris@151 24 {
Chris@151 25 }
Chris@151 26
Chris@151 27 SubdividingMenu::SubdividingMenu(const QString &title, QWidget *parent) :
Chris@151 28 QMenu(title, parent)
Chris@151 29 {
Chris@151 30 }
Chris@151 31
Chris@151 32 SubdividingMenu::~SubdividingMenu()
Chris@151 33 {
Chris@151 34 }
Chris@151 35
Chris@151 36 void
Chris@151 37 SubdividingMenu::setEntries(const std::set<QString> &entries)
Chris@151 38 {
Chris@151 39 size_t total = entries.size();
Chris@151 40 size_t chunk = 14;
Chris@151 41
Chris@151 42 if (total < (chunk * 3) / 2) return;
Chris@151 43
Chris@151 44 size_t count = 0;
Chris@151 45 QMenu *chunkMenu = new QMenu();
Chris@151 46
Chris@151 47 QString firstNameInChunk;
Chris@151 48 QChar firstInitialInChunk;
Chris@151 49 bool discriminateStartInitial = false;
Chris@151 50
Chris@151 51 for (set<QString>::const_iterator j = entries.begin();
Chris@151 52 j != entries.end();
Chris@151 53 ++j) {
Chris@151 54
Chris@151 55 std::cerr << "SubdividingMenu::setEntries: j -> " << j->toStdString() << std::endl;
Chris@151 56
Chris@151 57 m_nameToChunkMenuMap[*j] = chunkMenu;
Chris@151 58
Chris@151 59 set<QString>::iterator k = j;
Chris@151 60 ++k;
Chris@151 61
Chris@151 62 QChar initial = (*j)[0];
Chris@151 63
Chris@151 64 if (count == 0) {
Chris@151 65 firstNameInChunk = *j;
Chris@151 66 firstInitialInChunk = initial;
Chris@151 67 }
Chris@151 68
Chris@151 69 bool lastInChunk = (k == entries.end() ||
Chris@151 70 (count >= chunk-1 &&
Chris@151 71 (count == (5*chunk) / 2 ||
Chris@151 72 (*k)[0] != initial)));
Chris@151 73
Chris@151 74 ++count;
Chris@151 75
Chris@151 76 if (lastInChunk) {
Chris@151 77
Chris@151 78 bool discriminateEndInitial = (k != entries.end() &&
Chris@151 79 (*k)[0] == initial);
Chris@151 80
Chris@151 81 bool initialsEqual = (firstInitialInChunk == initial);
Chris@151 82
Chris@151 83 QString from = QString("%1").arg(firstInitialInChunk);
Chris@151 84 if (discriminateStartInitial ||
Chris@151 85 (discriminateEndInitial && initialsEqual)) {
Chris@151 86 from = firstNameInChunk.left(3);
Chris@151 87 }
Chris@151 88
Chris@151 89 QString to = QString("%1").arg(initial);
Chris@151 90 if (discriminateEndInitial ||
Chris@151 91 (discriminateStartInitial && initialsEqual)) {
Chris@151 92 to = j->left(3);
Chris@151 93 }
Chris@151 94
Chris@151 95 QString menuText;
Chris@151 96
Chris@151 97 if (from == to) menuText = from;
Chris@151 98 else menuText = tr("%1 - %2").arg(from).arg(to);
Chris@151 99
Chris@151 100 discriminateStartInitial = discriminateEndInitial;
Chris@151 101
Chris@151 102 chunkMenu->setTitle(menuText);
Chris@151 103
Chris@151 104 QMenu::addMenu(chunkMenu);
Chris@151 105
Chris@151 106 chunkMenu = new QMenu();
Chris@151 107
Chris@151 108 count = 0;
Chris@151 109 }
Chris@151 110 }
Chris@151 111
Chris@151 112 if (count == 0) delete chunkMenu;
Chris@151 113 }
Chris@151 114
Chris@151 115 void
Chris@151 116 SubdividingMenu::addAction(QAction *action)
Chris@151 117 {
Chris@151 118 QString name = action->text();
Chris@151 119
Chris@151 120 if (m_nameToChunkMenuMap.find(name) == m_nameToChunkMenuMap.end()) {
Chris@151 121 std::cerr << "SubdividingMenu::addAction(" << name.toStdString() << "): not found in name-to-chunk map, adding to main menu" << std::endl;
Chris@151 122 QMenu::addAction(action);
Chris@151 123 return;
Chris@151 124 }
Chris@151 125
Chris@151 126 std::cerr << "SubdividingMenu::addAction(" << name.toStdString() << "): found in name-to-chunk map for menu " << m_nameToChunkMenuMap[name]->title().toStdString() << std::endl;
Chris@151 127 m_nameToChunkMenuMap[name]->addAction(action);
Chris@151 128 }
Chris@151 129
Chris@151 130 QAction *
Chris@151 131 SubdividingMenu::addAction(const QString &name)
Chris@151 132 {
Chris@151 133 if (m_nameToChunkMenuMap.find(name) == m_nameToChunkMenuMap.end()) {
Chris@151 134 std::cerr << "SubdividingMenu::addAction(" << name.toStdString() << "): not found in name-to-chunk map, adding to main menu" << std::endl;
Chris@151 135 return QMenu::addAction(name);
Chris@151 136 }
Chris@151 137
Chris@151 138 std::cerr << "SubdividingMenu::addAction(" << name.toStdString() << "): found in name-to-chunk map for menu " << m_nameToChunkMenuMap[name]->title().toStdString() << std::endl;
Chris@151 139 return m_nameToChunkMenuMap[name]->addAction(name);
Chris@151 140 }
Chris@151 141
Chris@151 142 void
Chris@151 143 SubdividingMenu::addAction(const QString &name, QAction *action)
Chris@151 144 {
Chris@151 145 if (m_nameToChunkMenuMap.find(name) == m_nameToChunkMenuMap.end()) {
Chris@151 146 std::cerr << "SubdividingMenu::addAction(" << name.toStdString() << "): not found in name-to-chunk map, adding to main menu" << std::endl;
Chris@151 147 QMenu::addAction(action);
Chris@151 148 return;
Chris@151 149 }
Chris@151 150
Chris@151 151 std::cerr << "SubdividingMenu::addAction(" << name.toStdString() << "): found in name-to-chunk map for menu " << m_nameToChunkMenuMap[name]->title().toStdString() << std::endl;
Chris@151 152 m_nameToChunkMenuMap[name]->addAction(action);
Chris@151 153 }
Chris@151 154
Chris@151 155 void
Chris@151 156 SubdividingMenu::addMenu(QMenu *menu)
Chris@151 157 {
Chris@151 158 QString name = menu->title();
Chris@151 159
Chris@151 160 if (m_nameToChunkMenuMap.find(name) == m_nameToChunkMenuMap.end()) {
Chris@151 161 std::cerr << "SubdividingMenu::addMenu(" << name.toStdString() << "): not found in name-to-chunk map, adding to main menu" << std::endl;
Chris@151 162 QMenu::addMenu(menu);
Chris@151 163 return;
Chris@151 164 }
Chris@151 165
Chris@151 166 std::cerr << "SubdividingMenu::addMenu(" << name.toStdString() << "): found in name-to-chunk map for menu " << m_nameToChunkMenuMap[name]->title().toStdString() << std::endl;
Chris@151 167 m_nameToChunkMenuMap[name]->addMenu(menu);
Chris@151 168 }
Chris@151 169
Chris@151 170 QMenu *
Chris@151 171 SubdividingMenu::addMenu(const QString &name)
Chris@151 172 {
Chris@151 173 if (m_nameToChunkMenuMap.find(name) == m_nameToChunkMenuMap.end()) {
Chris@151 174 std::cerr << "SubdividingMenu::addMenu(" << name.toStdString() << "): not found in name-to-chunk map, adding to main menu" << std::endl;
Chris@151 175 return QMenu::addMenu(name);
Chris@151 176 }
Chris@151 177
Chris@151 178 std::cerr << "SubdividingMenu::addMenu(" << name.toStdString() << "): found in name-to-chunk map for menu " << m_nameToChunkMenuMap[name]->title().toStdString() << std::endl;
Chris@151 179 return m_nameToChunkMenuMap[name]->addMenu(name);
Chris@151 180 }
Chris@151 181
Chris@151 182 void
Chris@151 183 SubdividingMenu::addMenu(const QString &name, QMenu *menu)
Chris@151 184 {
Chris@151 185 if (m_nameToChunkMenuMap.find(name) == m_nameToChunkMenuMap.end()) {
Chris@151 186 std::cerr << "SubdividingMenu::addMenu(" << name.toStdString() << "): not found in name-to-chunk map, adding to main menu" << std::endl;
Chris@151 187 QMenu::addMenu(menu);
Chris@151 188 return;
Chris@151 189 }
Chris@151 190
Chris@151 191 std::cerr << "SubdividingMenu::addMenu(" << name.toStdString() << "): found in name-to-chunk map for menu " << m_nameToChunkMenuMap[name]->title().toStdString() << std::endl;
Chris@151 192 m_nameToChunkMenuMap[name]->addMenu(menu);
Chris@151 193 }
Chris@151 194