comparison widgets/SubdividingMenu.cpp @ 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 42118892f428
comparison
equal deleted inserted replaced
151:8f51db2434dc 152:6a3f3c13173f
17 #include <iostream> 17 #include <iostream>
18 18
19 using std::set; 19 using std::set;
20 using std::map; 20 using std::map;
21 21
22 SubdividingMenu::SubdividingMenu(QWidget *parent) : 22 SubdividingMenu::SubdividingMenu(size_t lowerLimit, size_t upperLimit,
23 QMenu(parent) 23 QWidget *parent) :
24 { 24 QMenu(parent),
25 } 25 m_lowerLimit(lowerLimit ? lowerLimit : 14),
26 26 m_upperLimit(upperLimit ? upperLimit : (m_lowerLimit * 5) / 2),
27 SubdividingMenu::SubdividingMenu(const QString &title, QWidget *parent) : 27 m_entriesSet(false)
28 QMenu(title, parent) 28 {
29 }
30
31 SubdividingMenu::SubdividingMenu(const QString &title, size_t lowerLimit,
32 size_t upperLimit, QWidget *parent) :
33 QMenu(title, parent),
34 m_lowerLimit(lowerLimit ? lowerLimit : 14),
35 m_upperLimit(upperLimit ? upperLimit : (m_lowerLimit * 5) / 2),
36 m_entriesSet(false)
29 { 37 {
30 } 38 }
31 39
32 SubdividingMenu::~SubdividingMenu() 40 SubdividingMenu::~SubdividingMenu()
33 { 41 {
42 for (map<QString, QObject *>::iterator i = m_pendingEntries.begin();
43 i != m_pendingEntries.end(); ++i) {
44 delete i->second;
45 }
34 } 46 }
35 47
36 void 48 void
37 SubdividingMenu::setEntries(const std::set<QString> &entries) 49 SubdividingMenu::setEntries(const std::set<QString> &entries)
38 { 50 {
51 m_entriesSet = true;
52
39 size_t total = entries.size(); 53 size_t total = entries.size();
40 size_t chunk = 14;
41 54
42 if (total < (chunk * 3) / 2) return; 55 if (total < m_upperLimit) return;
43 56
44 size_t count = 0; 57 size_t count = 0;
45 QMenu *chunkMenu = new QMenu(); 58 QMenu *chunkMenu = new QMenu();
46 59
47 QString firstNameInChunk; 60 QString firstNameInChunk;
50 63
51 for (set<QString>::const_iterator j = entries.begin(); 64 for (set<QString>::const_iterator j = entries.begin();
52 j != entries.end(); 65 j != entries.end();
53 ++j) { 66 ++j) {
54 67
55 std::cerr << "SubdividingMenu::setEntries: j -> " << j->toStdString() << std::endl; 68 // std::cerr << "SubdividingMenu::setEntries: j -> " << j->toStdString() << std::endl;
56 69
57 m_nameToChunkMenuMap[*j] = chunkMenu; 70 m_nameToChunkMenuMap[*j] = chunkMenu;
58 71
59 set<QString>::iterator k = j; 72 set<QString>::iterator k = j;
60 ++k; 73 ++k;
64 if (count == 0) { 77 if (count == 0) {
65 firstNameInChunk = *j; 78 firstNameInChunk = *j;
66 firstInitialInChunk = initial; 79 firstInitialInChunk = initial;
67 } 80 }
68 81
82 // std::cerr << "count = "<< count << ", upper limit = " << m_upperLimit << std::endl;
83
69 bool lastInChunk = (k == entries.end() || 84 bool lastInChunk = (k == entries.end() ||
70 (count >= chunk-1 && 85 (count >= m_lowerLimit-1 &&
71 (count == (5*chunk) / 2 || 86 (count == m_upperLimit ||
72 (*k)[0] != initial))); 87 (*k)[0] != initial)));
73 88
74 ++count; 89 ++count;
75 90
76 if (lastInChunk) { 91 if (lastInChunk) {
111 126
112 if (count == 0) delete chunkMenu; 127 if (count == 0) delete chunkMenu;
113 } 128 }
114 129
115 void 130 void
131 SubdividingMenu::entriesAdded()
132 {
133 if (m_entriesSet) {
134 std::cerr << "ERROR: SubdividingMenu::entriesAdded: setEntries was also called -- should use one mechanism or the other, but not both" << std::endl;
135 return;
136 }
137
138 set<QString> entries;
139 for (map<QString, QObject *>::const_iterator i = m_pendingEntries.begin();
140 i != m_pendingEntries.end(); ++i) {
141 entries.insert(i->first);
142 }
143
144 setEntries(entries);
145
146 for (map<QString, QObject *>::iterator i = m_pendingEntries.begin();
147 i != m_pendingEntries.end(); ++i) {
148
149 QMenu *menu = dynamic_cast<QMenu *>(i->second);
150 if (menu) {
151 addMenu(i->first, menu);
152 continue;
153 }
154
155 QAction *action = dynamic_cast<QAction *>(i->second);
156 if (action) {
157 addAction(i->first, action);
158 continue;
159 }
160 }
161
162 m_pendingEntries.clear();
163 }
164
165 void
116 SubdividingMenu::addAction(QAction *action) 166 SubdividingMenu::addAction(QAction *action)
117 { 167 {
118 QString name = action->text(); 168 QString name = action->text();
119 169
120 if (m_nameToChunkMenuMap.find(name) == m_nameToChunkMenuMap.end()) { 170 if (!m_entriesSet) {
121 std::cerr << "SubdividingMenu::addAction(" << name.toStdString() << "): not found in name-to-chunk map, adding to main menu" << std::endl; 171 m_pendingEntries[name] = action;
172 return;
173 }
174
175 if (m_nameToChunkMenuMap.find(name) == m_nameToChunkMenuMap.end()) {
176 // std::cerr << "SubdividingMenu::addAction(" << name.toStdString() << "): not found in name-to-chunk map, adding to main menu" << std::endl;
122 QMenu::addAction(action); 177 QMenu::addAction(action);
123 return; 178 return;
124 } 179 }
125 180
126 std::cerr << "SubdividingMenu::addAction(" << name.toStdString() << "): found in name-to-chunk map for menu " << m_nameToChunkMenuMap[name]->title().toStdString() << std::endl; 181 // 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); 182 m_nameToChunkMenuMap[name]->addAction(action);
128 } 183 }
129 184
130 QAction * 185 QAction *
131 SubdividingMenu::addAction(const QString &name) 186 SubdividingMenu::addAction(const QString &name)
132 { 187 {
133 if (m_nameToChunkMenuMap.find(name) == m_nameToChunkMenuMap.end()) { 188 if (!m_entriesSet) {
134 std::cerr << "SubdividingMenu::addAction(" << name.toStdString() << "): not found in name-to-chunk map, adding to main menu" << std::endl; 189 QAction *action = new QAction(name, this);
190 m_pendingEntries[name] = action;
191 return action;
192 }
193
194 if (m_nameToChunkMenuMap.find(name) == m_nameToChunkMenuMap.end()) {
195 // std::cerr << "SubdividingMenu::addAction(" << name.toStdString() << "): not found in name-to-chunk map, adding to main menu" << std::endl;
135 return QMenu::addAction(name); 196 return QMenu::addAction(name);
136 } 197 }
137 198
138 std::cerr << "SubdividingMenu::addAction(" << name.toStdString() << "): found in name-to-chunk map for menu " << m_nameToChunkMenuMap[name]->title().toStdString() << std::endl; 199 // 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); 200 return m_nameToChunkMenuMap[name]->addAction(name);
140 } 201 }
141 202
142 void 203 void
143 SubdividingMenu::addAction(const QString &name, QAction *action) 204 SubdividingMenu::addAction(const QString &name, QAction *action)
144 { 205 {
145 if (m_nameToChunkMenuMap.find(name) == m_nameToChunkMenuMap.end()) { 206 if (!m_entriesSet) {
146 std::cerr << "SubdividingMenu::addAction(" << name.toStdString() << "): not found in name-to-chunk map, adding to main menu" << std::endl; 207 m_pendingEntries[name] = action;
208 return;
209 }
210
211 if (m_nameToChunkMenuMap.find(name) == m_nameToChunkMenuMap.end()) {
212 // std::cerr << "SubdividingMenu::addAction(" << name.toStdString() << "): not found in name-to-chunk map, adding to main menu" << std::endl;
147 QMenu::addAction(action); 213 QMenu::addAction(action);
148 return; 214 return;
149 } 215 }
150 216
151 std::cerr << "SubdividingMenu::addAction(" << name.toStdString() << "): found in name-to-chunk map for menu " << m_nameToChunkMenuMap[name]->title().toStdString() << std::endl; 217 // 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); 218 m_nameToChunkMenuMap[name]->addAction(action);
153 } 219 }
154 220
155 void 221 void
156 SubdividingMenu::addMenu(QMenu *menu) 222 SubdividingMenu::addMenu(QMenu *menu)
157 { 223 {
158 QString name = menu->title(); 224 QString name = menu->title();
159 225
160 if (m_nameToChunkMenuMap.find(name) == m_nameToChunkMenuMap.end()) { 226 if (!m_entriesSet) {
161 std::cerr << "SubdividingMenu::addMenu(" << name.toStdString() << "): not found in name-to-chunk map, adding to main menu" << std::endl; 227 m_pendingEntries[name] = menu;
228 return;
229 }
230
231 if (m_nameToChunkMenuMap.find(name) == m_nameToChunkMenuMap.end()) {
232 // std::cerr << "SubdividingMenu::addMenu(" << name.toStdString() << "): not found in name-to-chunk map, adding to main menu" << std::endl;
162 QMenu::addMenu(menu); 233 QMenu::addMenu(menu);
163 return; 234 return;
164 } 235 }
165 236
166 std::cerr << "SubdividingMenu::addMenu(" << name.toStdString() << "): found in name-to-chunk map for menu " << m_nameToChunkMenuMap[name]->title().toStdString() << std::endl; 237 // 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); 238 m_nameToChunkMenuMap[name]->addMenu(menu);
168 } 239 }
169 240
170 QMenu * 241 QMenu *
171 SubdividingMenu::addMenu(const QString &name) 242 SubdividingMenu::addMenu(const QString &name)
172 { 243 {
173 if (m_nameToChunkMenuMap.find(name) == m_nameToChunkMenuMap.end()) { 244 if (!m_entriesSet) {
174 std::cerr << "SubdividingMenu::addMenu(" << name.toStdString() << "): not found in name-to-chunk map, adding to main menu" << std::endl; 245 QMenu *menu = new QMenu(name, this);
246 m_pendingEntries[name] = menu;
247 return menu;
248 }
249
250 if (m_nameToChunkMenuMap.find(name) == m_nameToChunkMenuMap.end()) {
251 // std::cerr << "SubdividingMenu::addMenu(" << name.toStdString() << "): not found in name-to-chunk map, adding to main menu" << std::endl;
175 return QMenu::addMenu(name); 252 return QMenu::addMenu(name);
176 } 253 }
177 254
178 std::cerr << "SubdividingMenu::addMenu(" << name.toStdString() << "): found in name-to-chunk map for menu " << m_nameToChunkMenuMap[name]->title().toStdString() << std::endl; 255 // 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); 256 return m_nameToChunkMenuMap[name]->addMenu(name);
180 } 257 }
181 258
182 void 259 void
183 SubdividingMenu::addMenu(const QString &name, QMenu *menu) 260 SubdividingMenu::addMenu(const QString &name, QMenu *menu)
184 { 261 {
185 if (m_nameToChunkMenuMap.find(name) == m_nameToChunkMenuMap.end()) { 262 if (!m_entriesSet) {
186 std::cerr << "SubdividingMenu::addMenu(" << name.toStdString() << "): not found in name-to-chunk map, adding to main menu" << std::endl; 263 m_pendingEntries[name] = menu;
264 return;
265 }
266
267 if (m_nameToChunkMenuMap.find(name) == m_nameToChunkMenuMap.end()) {
268 // std::cerr << "SubdividingMenu::addMenu(" << name.toStdString() << "): not found in name-to-chunk map, adding to main menu" << std::endl;
187 QMenu::addMenu(menu); 269 QMenu::addMenu(menu);
188 return; 270 return;
189 } 271 }
190 272
191 std::cerr << "SubdividingMenu::addMenu(" << name.toStdString() << "): found in name-to-chunk map for menu " << m_nameToChunkMenuMap[name]->title().toStdString() << std::endl; 273 // 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); 274 m_nameToChunkMenuMap[name]->addMenu(menu);
193 } 275 }
194 276