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