Mercurial > hg > svapp
comparison framework/MainWindowBase.cpp @ 404:08a45e4cf1b1 tonioni
Update subrepos and merge from default branch
| author | Chris Cannam |
|---|---|
| date | Tue, 02 Sep 2014 16:23:48 +0100 |
| parents | eb84b06301da |
| children | 41242512d544 |
comparison
equal
deleted
inserted
replaced
| 384:ad33fdc4ad92 | 404:08a45e4cf1b1 |
|---|---|
| 153 m_abandoning(false), | 153 m_abandoning(false), |
| 154 m_labeller(0), | 154 m_labeller(0), |
| 155 m_lastPlayStatusSec(0), | 155 m_lastPlayStatusSec(0), |
| 156 m_initialDarkBackground(false), | 156 m_initialDarkBackground(false), |
| 157 m_defaultFfwdRwdStep(2, 0), | 157 m_defaultFfwdRwdStep(2, 0), |
| 158 m_statusLabel(0) | 158 m_statusLabel(0), |
| 159 m_menuShortcutMapper(0) | |
| 159 { | 160 { |
| 160 Profiler profiler("MainWindowBase::MainWindowBase"); | 161 Profiler profiler("MainWindowBase::MainWindowBase"); |
| 161 | 162 |
| 162 #ifdef Q_WS_X11 | 163 #ifdef Q_WS_X11 |
| 163 XSetErrorHandler(handle_x11_error); | 164 XSetErrorHandler(handle_x11_error); |
| 274 } | 275 } |
| 275 | 276 |
| 276 void | 277 void |
| 277 MainWindowBase::finaliseMenus() | 278 MainWindowBase::finaliseMenus() |
| 278 { | 279 { |
| 280 delete m_menuShortcutMapper; | |
| 281 m_menuShortcutMapper = 0; | |
| 282 | |
| 283 foreach (QShortcut *sc, m_appShortcuts) { | |
| 284 delete sc; | |
| 285 } | |
| 286 m_appShortcuts.clear(); | |
| 287 | |
| 279 QMenuBar *mb = menuBar(); | 288 QMenuBar *mb = menuBar(); |
| 280 QList<QMenu *> menus = mb->findChildren<QMenu *>(); | 289 |
| 290 // This used to find all children of QMenu type, and call | |
| 291 // finaliseMenu on those. But it seems we are getting hold of some | |
| 292 // menus that way that are not actually active in the menu bar and | |
| 293 // are not returned in their parent menu's actions() list, and if | |
| 294 // we finalise those, we end up with duplicate shortcuts in the | |
| 295 // app shortcut mapper. So we should do this by descending the | |
| 296 // menu tree through only those menus accessible via actions() | |
| 297 // from their parents instead. | |
| 298 | |
| 299 QList<QMenu *> menus = mb->findChildren<QMenu *> | |
| 300 (QString(), Qt::FindDirectChildrenOnly); | |
| 301 | |
| 281 foreach (QMenu *menu, menus) { | 302 foreach (QMenu *menu, menus) { |
| 282 if (menu) finaliseMenu(menu); | 303 if (menu) finaliseMenu(menu); |
| 283 } | 304 } |
| 284 } | 305 } |
| 285 | 306 |
| 321 // i.e. that will not otherwise work. The downside is that if this | 342 // i.e. that will not otherwise work. The downside is that if this |
| 322 // bug is fixed in a future Qt release, we will start getting | 343 // bug is fixed in a future Qt release, we will start getting |
| 323 // "ambiguous shortcut" errors from the menu entry actions and | 344 // "ambiguous shortcut" errors from the menu entry actions and |
| 324 // will need to update the code.) | 345 // will need to update the code.) |
| 325 | 346 |
| 326 QSignalMapper *mapper = new QSignalMapper(this); | 347 if (!m_menuShortcutMapper) { |
| 327 | 348 m_menuShortcutMapper = new QSignalMapper(this); |
| 328 connect(mapper, SIGNAL(mapped(QObject *)), | 349 connect(m_menuShortcutMapper, SIGNAL(mapped(QObject *)), |
| 329 this, SLOT(menuActionMapperInvoked(QObject *))); | 350 this, SLOT(menuActionMapperInvoked(QObject *))); |
| 351 } | |
| 330 | 352 |
| 331 foreach (QAction *a, menu->actions()) { | 353 foreach (QAction *a, menu->actions()) { |
| 332 QWidgetList ww = a->associatedWidgets(); | 354 |
| 333 bool hasButton = false; | 355 if (a->isSeparator()) { |
| 334 foreach (QWidget *w, ww) { | 356 continue; |
| 335 if (qobject_cast<QAbstractButton *>(w)) { | 357 } else if (a->menu()) { |
| 336 hasButton = true; | 358 finaliseMenu(a->menu()); |
| 337 break; | 359 } else { |
| 360 | |
| 361 QWidgetList ww = a->associatedWidgets(); | |
| 362 bool hasButton = false; | |
| 363 foreach (QWidget *w, ww) { | |
| 364 if (qobject_cast<QAbstractButton *>(w)) { | |
| 365 hasButton = true; | |
| 366 break; | |
| 367 } | |
| 338 } | 368 } |
| 339 } | 369 if (hasButton) continue; |
| 340 if (hasButton) continue; | 370 QKeySequence sc = a->shortcut(); |
| 341 QKeySequence sc = a->shortcut(); | 371 |
| 342 if (sc.count() == 1 && !(sc[0] & Qt::KeyboardModifierMask)) { | 372 // Note that the set of "single-key shortcuts" that aren't |
| 343 QShortcut *newSc = new QShortcut(sc, a->parentWidget()); | 373 // working and that we need to handle here includes those |
| 344 QObject::connect(newSc, SIGNAL(activated()), mapper, SLOT(map())); | 374 // with the Shift modifier mask as well as those with no |
| 345 mapper->setMapping(newSc, a); | 375 // modifier at all |
| 376 if (sc.count() == 1 && | |
| 377 ((sc[0] & Qt::KeyboardModifierMask) == Qt::NoModifier || | |
| 378 (sc[0] & Qt::KeyboardModifierMask) == Qt::ShiftModifier)) { | |
| 379 QShortcut *newSc = new QShortcut(sc, a->parentWidget()); | |
| 380 QObject::connect(newSc, SIGNAL(activated()), | |
| 381 m_menuShortcutMapper, SLOT(map())); | |
| 382 m_menuShortcutMapper->setMapping(newSc, a); | |
| 383 m_appShortcuts.push_back(newSc); | |
| 384 } | |
| 346 } | 385 } |
| 347 } | 386 } |
| 348 #endif | 387 #endif |
| 349 } | 388 } |
| 350 | 389 |
| 468 if (i > 0) havePrevPane = true; | 507 if (i > 0) havePrevPane = true; |
| 469 if (i < m_paneStack->getPaneCount()-1) haveNextPane = true; | 508 if (i < m_paneStack->getPaneCount()-1) haveNextPane = true; |
| 470 break; | 509 break; |
| 471 } | 510 } |
| 472 } | 511 } |
| 473 if (currentLayer) { | 512 // the prev/next layer commands actually include the pane |
| 474 for (int i = 0; i < currentPane->getLayerCount(); ++i) { | 513 // itself as one of the selectables -- so we always have a |
| 475 if (currentPane->getLayer(i) == currentLayer) { | 514 // prev and next layer, as long as we have a pane with at |
| 476 if (i > 0) havePrevLayer = true; | 515 // least one layer in it |
| 477 if (i < currentPane->getLayerCount()-1) haveNextLayer = true; | 516 if (currentPane->getLayerCount() > 0) { |
| 478 break; | 517 havePrevLayer = true; |
| 479 } | 518 haveNextLayer = true; |
| 480 } | |
| 481 } | 519 } |
| 482 } | 520 } |
| 483 | 521 |
| 484 bool haveCurrentPane = | 522 bool haveCurrentPane = |
| 485 (currentPane != 0); | 523 (currentPane != 0); |
| 652 // frame before switching to whichever one we decide we want to | 690 // frame before switching to whichever one we decide we want to |
| 653 // switch to, regardless of our efforts. | 691 // switch to, regardless of our efforts. |
| 654 | 692 |
| 655 int frame = m_playSource->getCurrentBufferedFrame(); | 693 int frame = m_playSource->getCurrentBufferedFrame(); |
| 656 | 694 |
| 657 // cerr << "currentPaneChanged: current frame (in ref model) = " << frame << endl; | 695 cerr << "currentPaneChanged: current frame (in ref model) = " << frame << endl; |
| 658 | 696 |
| 659 View::ModelSet soloModels = p->getModels(); | 697 View::ModelSet soloModels = p->getModels(); |
| 660 | 698 |
| 661 View::ModelSet sources; | 699 View::ModelSet sources; |
| 662 for (View::ModelSet::iterator mi = soloModels.begin(); | 700 for (View::ModelSet::iterator mi = soloModels.begin(); |
| 1218 | 1256 |
| 1219 MainWindowBase::FileOpenStatus | 1257 MainWindowBase::FileOpenStatus |
| 1220 MainWindowBase::openAudio(FileSource source, AudioFileOpenMode mode, | 1258 MainWindowBase::openAudio(FileSource source, AudioFileOpenMode mode, |
| 1221 QString templateName) | 1259 QString templateName) |
| 1222 { | 1260 { |
| 1223 SVDEBUG << "MainWindowBase::openAudio(" << source.getLocation() << ")" << endl; | 1261 SVDEBUG << "MainWindowBase::openAudio(" << source.getLocation() << ") with mode " << mode << " and template " << templateName << endl; |
| 1224 | 1262 |
| 1225 if (templateName == "") { | 1263 if (templateName == "") { |
| 1226 templateName = getDefaultSessionTemplate(); | 1264 templateName = getDefaultSessionTemplate(); |
| 1227 } | 1265 } |
| 1228 | 1266 |
| 1315 mode = CreateAdditionalModel; | 1353 mode = CreateAdditionalModel; |
| 1316 } | 1354 } |
| 1317 } | 1355 } |
| 1318 | 1356 |
| 1319 if (mode == CreateAdditionalModel && !getMainModel()) { | 1357 if (mode == CreateAdditionalModel && !getMainModel()) { |
| 1358 SVDEBUG << "Mode is CreateAdditionalModel but we have no main model, switching to ReplaceSession mode" << endl; | |
| 1320 mode = ReplaceSession; | 1359 mode = ReplaceSession; |
| 1321 } | 1360 } |
| 1322 | 1361 |
| 1323 bool loadedTemplate = false; | 1362 bool loadedTemplate = false; |
| 1324 | 1363 |
| 1325 if (mode == ReplaceSession) { | 1364 if (mode == ReplaceSession) { |
| 1326 | 1365 |
| 1327 if (!checkSaveModified()) return FileOpenCancelled; | 1366 if (!checkSaveModified()) return FileOpenCancelled; |
| 1328 | 1367 |
| 1329 cerr << "SV looking for template " << templateName << endl; | 1368 SVDEBUG << "SV looking for template " << templateName << endl; |
| 1330 if (templateName != "") { | 1369 if (templateName != "") { |
| 1331 FileOpenStatus tplStatus = openSessionTemplate(templateName); | 1370 FileOpenStatus tplStatus = openSessionTemplate(templateName); |
| 1332 if (tplStatus == FileOpenCancelled) { | 1371 if (tplStatus == FileOpenCancelled) { |
| 1333 cerr << "Template load cancelled" << endl; | 1372 cerr << "Template load cancelled" << endl; |
| 1334 return FileOpenCancelled; | 1373 return FileOpenCancelled; |
| 1338 loadedTemplate = true; | 1377 loadedTemplate = true; |
| 1339 } | 1378 } |
| 1340 } | 1379 } |
| 1341 | 1380 |
| 1342 if (!loadedTemplate) { | 1381 if (!loadedTemplate) { |
| 1382 SVDEBUG << "No template found: closing session, creating new empty document" << endl; | |
| 1343 closeSession(); | 1383 closeSession(); |
| 1344 createDocument(); | 1384 createDocument(); |
| 1345 } | 1385 } |
| 1346 | 1386 |
| 1387 SVDEBUG << "Now switching to ReplaceMainModel mode" << endl; | |
| 1347 mode = ReplaceMainModel; | 1388 mode = ReplaceMainModel; |
| 1348 } | 1389 } |
| 1349 | 1390 |
| 1350 emit activity(tr("Import audio file \"%1\"").arg(source.getLocation())); | 1391 emit activity(tr("Import audio file \"%1\"").arg(source.getLocation())); |
| 1351 | 1392 |
| 3008 } | 3049 } |
| 3009 | 3050 |
| 3010 void | 3051 void |
| 3011 MainWindowBase::previousLayer() | 3052 MainWindowBase::previousLayer() |
| 3012 { | 3053 { |
| 3013 //!!! Not right -- pane lists layers in stacking order | |
| 3014 | |
| 3015 if (!m_paneStack) return; | 3054 if (!m_paneStack) return; |
| 3016 | 3055 |
| 3017 Pane *currentPane = m_paneStack->getCurrentPane(); | 3056 Pane *currentPane = m_paneStack->getCurrentPane(); |
| 3018 if (!currentPane) return; | 3057 if (!currentPane) return; |
| 3019 | 3058 |
| 3059 int count = currentPane->getLayerCount(); | |
| 3060 if (count == 0) return; | |
| 3061 | |
| 3020 Layer *currentLayer = currentPane->getSelectedLayer(); | 3062 Layer *currentLayer = currentPane->getSelectedLayer(); |
| 3021 if (!currentLayer) return; | 3063 |
| 3022 | 3064 if (!currentLayer) { |
| 3023 for (int i = 0; i < currentPane->getLayerCount(); ++i) { | 3065 // The pane itself is current |
| 3024 if (currentPane->getLayer(i) == currentLayer) { | 3066 m_paneStack->setCurrentLayer |
| 3025 if (i == 0) return; | 3067 (currentPane, currentPane->getFixedOrderLayer(count-1)); |
| 3026 m_paneStack->setCurrentLayer(currentPane, | 3068 } else { |
| 3027 currentPane->getLayer(i-1)); | 3069 for (int i = 0; i < count; ++i) { |
| 3028 updateMenuStates(); | 3070 if (currentPane->getFixedOrderLayer(i) == currentLayer) { |
| 3029 return; | 3071 if (i == 0) { |
| 3030 } | 3072 m_paneStack->setCurrentLayer |
| 3031 } | 3073 (currentPane, 0); // pane |
| 3074 } else { | |
| 3075 m_paneStack->setCurrentLayer | |
| 3076 (currentPane, currentPane->getFixedOrderLayer(i-1)); | |
| 3077 } | |
| 3078 break; | |
| 3079 } | |
| 3080 } | |
| 3081 } | |
| 3082 | |
| 3083 updateMenuStates(); | |
| 3032 } | 3084 } |
| 3033 | 3085 |
| 3034 void | 3086 void |
| 3035 MainWindowBase::nextLayer() | 3087 MainWindowBase::nextLayer() |
| 3036 { | 3088 { |
| 3037 //!!! Not right -- pane lists layers in stacking order | |
| 3038 | |
| 3039 if (!m_paneStack) return; | 3089 if (!m_paneStack) return; |
| 3040 | 3090 |
| 3041 Pane *currentPane = m_paneStack->getCurrentPane(); | 3091 Pane *currentPane = m_paneStack->getCurrentPane(); |
| 3042 if (!currentPane) return; | 3092 if (!currentPane) return; |
| 3043 | 3093 |
| 3094 int count = currentPane->getLayerCount(); | |
| 3095 if (count == 0) return; | |
| 3096 | |
| 3044 Layer *currentLayer = currentPane->getSelectedLayer(); | 3097 Layer *currentLayer = currentPane->getSelectedLayer(); |
| 3045 if (!currentLayer) return; | 3098 |
| 3046 | 3099 if (!currentLayer) { |
| 3047 for (int i = 0; i < currentPane->getLayerCount(); ++i) { | 3100 // The pane itself is current |
| 3048 if (currentPane->getLayer(i) == currentLayer) { | 3101 m_paneStack->setCurrentLayer |
| 3049 if (i == currentPane->getLayerCount()-1) return; | 3102 (currentPane, currentPane->getFixedOrderLayer(0)); |
| 3050 m_paneStack->setCurrentLayer(currentPane, | 3103 } else { |
| 3051 currentPane->getLayer(i+1)); | 3104 for (int i = 0; i < count; ++i) { |
| 3052 updateMenuStates(); | 3105 if (currentPane->getFixedOrderLayer(i) == currentLayer) { |
| 3053 return; | 3106 if (i == currentPane->getLayerCount()-1) { |
| 3054 } | 3107 m_paneStack->setCurrentLayer |
| 3055 } | 3108 (currentPane, 0); // pane |
| 3109 } else { | |
| 3110 m_paneStack->setCurrentLayer | |
| 3111 (currentPane, currentPane->getFixedOrderLayer(i+1)); | |
| 3112 } | |
| 3113 break; | |
| 3114 } | |
| 3115 } | |
| 3116 } | |
| 3117 | |
| 3118 updateMenuStates(); | |
| 3056 } | 3119 } |
| 3057 | 3120 |
| 3058 void | 3121 void |
| 3059 MainWindowBase::playbackFrameChanged(int frame) | 3122 MainWindowBase::playbackFrameChanged(int frame) |
| 3060 { | 3123 { |
