Mercurial > hg > sonic-visualiser
comparison main/MainWindow.cpp @ 2550:a004f981f6f5 startup-timing
Some work to try to get the main window up & functioning quicker - without waiting for the transforms to be populated first. Needs a lot more testing, not to be merged until after 4.1.
author | Chris Cannam |
---|---|
date | Wed, 03 Jun 2020 14:12:14 +0100 |
parents | 7df56e260845 |
children | 59aa2fb55523 |
comparison
equal
deleted
inserted
replaced
2549:8ac67c315afa | 2550:a004f981f6f5 |
---|---|
174 m_preferencesDialog(nullptr), | 174 m_preferencesDialog(nullptr), |
175 m_layerTreeDialog(nullptr), | 175 m_layerTreeDialog(nullptr), |
176 m_activityLog(new ActivityLog()), | 176 m_activityLog(new ActivityLog()), |
177 m_unitConverter(new UnitConverter()), | 177 m_unitConverter(new UnitConverter()), |
178 m_keyReference(new KeyReference()), | 178 m_keyReference(new KeyReference()), |
179 m_templateWatcher(nullptr) | 179 m_templateWatcher(nullptr), |
180 m_transformPopulater(nullptr) | |
180 { | 181 { |
181 Profiler profiler("MainWindow::MainWindow"); | 182 Profiler profiler("MainWindow::MainWindow"); |
182 | 183 |
183 SVDEBUG << "MainWindow: " << getReleaseText() << endl; | 184 SVDEBUG << "MainWindow: " << getReleaseText() << endl; |
184 | 185 |
332 SVDEBUG << "MainWindow: Creating network permission tester" << endl; | 333 SVDEBUG << "MainWindow: Creating network permission tester" << endl; |
333 | 334 |
334 NetworkPermissionTester tester(withOSCSupport); | 335 NetworkPermissionTester tester(withOSCSupport); |
335 bool networkPermission = tester.havePermission(); | 336 bool networkPermission = tester.havePermission(); |
336 if (networkPermission) { | 337 if (networkPermission) { |
337 SVDEBUG << "MainWindow: Starting transform population thread" << endl; | 338 SVDEBUG << "MainWindow: Starting uninstalled-transform population thread" << endl; |
338 TransformFactory::getInstance()->startPopulationThread(); | 339 TransformFactory::getInstance()->startPopulationThread(); |
339 | 340 |
340 m_surveyer = nullptr; | 341 m_surveyer = nullptr; |
341 | 342 |
342 #ifdef WITH_FEEDBACK_REQUEST | 343 #ifdef WITH_FEEDBACK_REQUEST |
380 SVDEBUG << "MainWindow: Creating internal-only OSC queue without port" | 381 SVDEBUG << "MainWindow: Creating internal-only OSC queue without port" |
381 << endl; | 382 << endl; |
382 startOSCQueue(false); | 383 startOSCQueue(false); |
383 } | 384 } |
384 | 385 |
385 QTimer::singleShot(500, this, SLOT(betaReleaseWarning())); | 386 // QTimer::singleShot(500, this, SLOT(betaReleaseWarning())); |
386 | 387 |
387 QString warning = PluginScan::getInstance()->getStartupFailureReport(); | |
388 if (warning != "") { | |
389 QTimer::singleShot(500, this, SLOT(pluginPopulationWarning())); | |
390 } | |
391 | |
392 SVDEBUG << "MainWindow: Constructor done" << endl; | 388 SVDEBUG << "MainWindow: Constructor done" << endl; |
393 } | 389 } |
394 | 390 |
395 MainWindow::~MainWindow() | 391 MainWindow::~MainWindow() |
396 { | 392 { |
397 // SVDEBUG << "MainWindow::~MainWindow" << endl; | 393 // SVDEBUG << "MainWindow::~MainWindow" << endl; |
394 | |
395 if (m_transformPopulater) { | |
396 m_transformPopulater->wait(); | |
397 delete m_transformPopulater; | |
398 } | |
399 | |
398 delete m_keyReference; | 400 delete m_keyReference; |
399 delete m_activityLog; | 401 delete m_activityLog; |
400 delete m_unitConverter; | 402 delete m_unitConverter; |
401 delete m_preferencesDialog; | 403 delete m_preferencesDialog; |
402 delete m_layerTreeDialog; | 404 delete m_layerTreeDialog; |
407 } | 409 } |
408 | 410 |
409 void | 411 void |
410 MainWindow::setupMenus() | 412 MainWindow::setupMenus() |
411 { | 413 { |
414 SVDEBUG << "MainWindow::setupMenus" << endl; | |
415 | |
412 if (!m_mainMenusCreated) { | 416 if (!m_mainMenusCreated) { |
413 | 417 |
414 #ifdef Q_OS_LINUX | 418 #ifdef Q_OS_LINUX |
415 // In Ubuntu 14.04 the window's menu bar goes missing entirely | 419 // In Ubuntu 14.04 the window's menu bar goes missing entirely |
416 // if the user is running any desktop environment other than Unity | 420 // if the user is running any desktop environment other than Unity |
457 | 461 |
458 setupFileMenu(); | 462 setupFileMenu(); |
459 setupEditMenu(); | 463 setupEditMenu(); |
460 setupViewMenu(); | 464 setupViewMenu(); |
461 setupPaneAndLayerMenus(); | 465 setupPaneAndLayerMenus(); |
462 setupTransformsMenu(); | 466 prepareTransformsMenu(); |
463 | 467 |
464 m_mainMenusCreated = true; | 468 m_mainMenusCreated = true; |
469 | |
470 SVDEBUG << "MainWindow::setupMenus: done" << endl; | |
465 } | 471 } |
466 | 472 |
467 void | 473 void |
468 MainWindow::goFullScreen() | 474 MainWindow::goFullScreen() |
469 { | 475 { |
511 } | 517 } |
512 | 518 |
513 void | 519 void |
514 MainWindow::setupFileMenu() | 520 MainWindow::setupFileMenu() |
515 { | 521 { |
522 SVDEBUG << "MainWindow::setupFileMenu" << endl; | |
523 | |
516 if (m_mainMenusCreated) return; | 524 if (m_mainMenusCreated) return; |
517 | 525 |
518 QMenu *menu = menuBar()->addMenu(tr("&File")); | 526 QMenu *menu = menuBar()->addMenu(tr("&File")); |
519 menu->setTearOffEnabled(true); | 527 menu->setTearOffEnabled(true); |
520 QToolBar *toolbar = addToolBar(tr("File Toolbar")); | 528 QToolBar *toolbar = addToolBar(tr("File Toolbar")); |
684 action->setStatusTip(tr("Adjust the application preferences")); | 692 action->setStatusTip(tr("Adjust the application preferences")); |
685 connect(action, SIGNAL(triggered()), this, SLOT(preferences())); | 693 connect(action, SIGNAL(triggered()), this, SLOT(preferences())); |
686 menu->addAction(action); | 694 menu->addAction(action); |
687 | 695 |
688 menu->addSeparator(); | 696 menu->addSeparator(); |
689 action = new QAction(il.load("exit"), | 697 action = new QAction(il.load("exit"), tr("&Quit"), this); |
690 tr("&Quit"), this); | |
691 action->setShortcut(tr("Ctrl+Q")); | 698 action->setShortcut(tr("Ctrl+Q")); |
692 action->setStatusTip(tr("Exit %1").arg(QApplication::applicationName())); | 699 action->setStatusTip(tr("Exit %1").arg(QApplication::applicationName())); |
693 connect(action, SIGNAL(triggered()), qApp, SLOT(closeAllWindows())); | 700 connect(action, SIGNAL(triggered()), qApp, SLOT(closeAllWindows())); |
694 m_keyReference->registerShortcut(action); | 701 m_keyReference->registerShortcut(action); |
695 menu->addAction(action); | 702 menu->addAction(action); |
696 } | 703 } |
697 | 704 |
698 void | 705 void |
699 MainWindow::setupEditMenu() | 706 MainWindow::setupEditMenu() |
700 { | 707 { |
708 SVDEBUG << "MainWindow::setupEditMenu" << endl; | |
709 | |
701 if (m_mainMenusCreated) return; | 710 if (m_mainMenusCreated) return; |
702 | 711 |
703 QMenu *menu = menuBar()->addMenu(tr("&Edit")); | 712 QMenu *menu = menuBar()->addMenu(tr("&Edit")); |
704 menu->setTearOffEnabled(true); | 713 menu->setTearOffEnabled(true); |
705 CommandHistory::getInstance()->registerMenu(menu); | 714 CommandHistory::getInstance()->registerMenu(menu); |
944 } | 953 } |
945 | 954 |
946 void | 955 void |
947 MainWindow::setupViewMenu() | 956 MainWindow::setupViewMenu() |
948 { | 957 { |
958 SVDEBUG << "MainWindow::setupViewMenu" << endl; | |
959 | |
949 if (m_mainMenusCreated) return; | 960 if (m_mainMenusCreated) return; |
950 | 961 |
951 IconLoader il; | 962 IconLoader il; |
952 | 963 |
953 QAction *action = nullptr; | 964 QAction *action = nullptr; |
1224 } | 1235 } |
1225 | 1236 |
1226 void | 1237 void |
1227 MainWindow::setupPaneAndLayerMenus() | 1238 MainWindow::setupPaneAndLayerMenus() |
1228 { | 1239 { |
1240 SVDEBUG << "MainWindow::setupPaneAndLayerMenus" << endl; | |
1241 | |
1229 Profiler profiler("MainWindow::setupPaneAndLayerMenus"); | 1242 Profiler profiler("MainWindow::setupPaneAndLayerMenus"); |
1230 | 1243 |
1231 if (m_paneMenu) { | 1244 if (m_paneMenu) { |
1232 m_paneMenu->clear(); | 1245 m_paneMenu->clear(); |
1233 for (auto a: m_paneActions) { | 1246 for (auto a: m_paneActions) { |
1688 } | 1701 } |
1689 } | 1702 } |
1690 } | 1703 } |
1691 | 1704 |
1692 void | 1705 void |
1693 MainWindow::setupTransformsMenu() | 1706 MainWindow::prepareTransformsMenu() |
1694 { | 1707 { |
1708 SVDEBUG << "MainWindow::prepareTransformsMenu" << endl; | |
1709 | |
1710 if (m_transformsMenu) { | |
1711 return; | |
1712 } | |
1713 | |
1714 m_transformsMenu = menuBar()->addMenu(tr("&Transform")); | |
1715 m_transformsMenu->setTearOffEnabled(true); | |
1716 m_transformsMenu->setSeparatorsCollapsible(true); | |
1717 | |
1718 SVDEBUG << "MainWindow::prepareTransformsMenu: Starting installed-transform population thread" << endl; | |
1719 m_transformPopulater = new TransformPopulater(this); | |
1720 m_transformPopulater->start(); | |
1721 } | |
1722 | |
1723 void | |
1724 MainWindow::TransformPopulater::run() | |
1725 { | |
1726 usleep(200000); | |
1727 | |
1728 TransformFactory *tf = TransformFactory::getInstance(); | |
1729 if (!tf) return; | |
1730 | |
1731 connect(tf, SIGNAL(transformsPopulated()), | |
1732 m_mw, SLOT(populateTransformsMenu())); | |
1733 | |
1734 SVDEBUG << "MainWindow::TransformPopulater::run: scanning" << endl; | |
1735 | |
1736 PluginScan::getInstance()->scan(); | |
1737 | |
1738 QString warning = PluginScan::getInstance()->getStartupFailureReport(); | |
1739 if (warning != "") { | |
1740 QTimer::singleShot(500, m_mw, SLOT(pluginPopulationWarning())); | |
1741 } | |
1742 | |
1743 SVDEBUG << "MainWindow::TransformPopulater::run: populating" << endl; | |
1744 | |
1745 (void)tf->haveTransform({}); // populate! | |
1746 | |
1747 SVDEBUG << "MainWindow::TransformPopulater::run: done" << endl; | |
1748 } | |
1749 | |
1750 void | |
1751 MainWindow::populateTransformsMenu() | |
1752 { | |
1753 SVDEBUG << "MainWindow::populateTransformsMenu" << endl; | |
1754 | |
1695 if (m_transformsMenu) { | 1755 if (m_transformsMenu) { |
1696 m_transformsMenu->clear(); | 1756 m_transformsMenu->clear(); |
1697 m_recentTransformsMenu->clear(); | 1757 m_rightButtonTransformsMenu->clear(); |
1698 m_transformActionsReverse.clear(); | 1758 m_transformActionsReverse.clear(); |
1699 m_transformActions.clear(); | 1759 m_transformActions.clear(); |
1700 for (auto a: m_transformActions) { | 1760 for (auto a: m_transformActions) { |
1701 delete a.first; | 1761 delete a.first; |
1702 } | 1762 } |
1939 m_keyReference->registerShortcut(action); | 1999 m_keyReference->registerShortcut(action); |
1940 m_transformsMenu->addAction(action); | 2000 m_transformsMenu->addAction(action); |
1941 m_rightButtonTransformsMenu->addAction(action); | 2001 m_rightButtonTransformsMenu->addAction(action); |
1942 | 2002 |
1943 setupRecentTransformsMenu(); | 2003 setupRecentTransformsMenu(); |
2004 | |
2005 updateMenuStates(); | |
1944 } | 2006 } |
1945 | 2007 |
1946 void | 2008 void |
1947 MainWindow::setupHelpMenu() | 2009 MainWindow::setupHelpMenu() |
1948 { | 2010 { |
2011 SVDEBUG << "MainWindow::setupHelpMenu" << endl; | |
2012 | |
1949 QMenu *menu = menuBar()->addMenu(tr("&Help")); | 2013 QMenu *menu = menuBar()->addMenu(tr("&Help")); |
1950 menu->setTearOffEnabled(true); | 2014 menu->setTearOffEnabled(true); |
1951 | 2015 |
1952 m_keyReference->setCategory(tr("Help")); | 2016 m_keyReference->setCategory(tr("Help")); |
1953 | 2017 |
1982 } | 2046 } |
1983 | 2047 |
1984 void | 2048 void |
1985 MainWindow::setupRecentFilesMenu() | 2049 MainWindow::setupRecentFilesMenu() |
1986 { | 2050 { |
2051 SVDEBUG << "MainWindow::setupRecentFilesMenu" << endl; | |
2052 | |
1987 m_recentFilesMenu->clear(); | 2053 m_recentFilesMenu->clear(); |
1988 vector<QString> files = m_recentFiles.getRecent(); | 2054 vector<QString> files = m_recentFiles.getRecent(); |
1989 for (size_t i = 0; i < files.size(); ++i) { | 2055 for (size_t i = 0; i < files.size(); ++i) { |
1990 QString path = files[i]; | 2056 QString path = files[i]; |
1991 QAction *action = m_recentFilesMenu->addAction(path); | 2057 QAction *action = m_recentFilesMenu->addAction(path); |
2002 } | 2068 } |
2003 | 2069 |
2004 void | 2070 void |
2005 MainWindow::setupTemplatesMenu() | 2071 MainWindow::setupTemplatesMenu() |
2006 { | 2072 { |
2073 SVDEBUG << "MainWindow::setupTemplatesMenu" << endl; | |
2074 | |
2007 m_templatesMenu->clear(); | 2075 m_templatesMenu->clear(); |
2008 | 2076 |
2009 QAction *defaultAction = m_templatesMenu->addAction(tr("Standard Waveform")); | 2077 QAction *defaultAction = m_templatesMenu->addAction(tr("Standard Waveform")); |
2010 defaultAction->setObjectName("default"); | 2078 defaultAction->setObjectName("default"); |
2011 connect(defaultAction, SIGNAL(triggered()), this, SLOT(applyTemplate())); | 2079 connect(defaultAction, SIGNAL(triggered()), this, SLOT(applyTemplate())); |
2051 | 2119 |
2052 | 2120 |
2053 void | 2121 void |
2054 MainWindow::setupRecentTransformsMenu() | 2122 MainWindow::setupRecentTransformsMenu() |
2055 { | 2123 { |
2124 SVDEBUG << "MainWindow::setupRecentTransformsMenu" << endl; | |
2125 | |
2056 m_recentTransformsMenu->clear(); | 2126 m_recentTransformsMenu->clear(); |
2057 vector<QString> transforms = m_recentTransforms.getRecent(); | 2127 vector<QString> transforms = m_recentTransforms.getRecent(); |
2058 for (size_t i = 0; i < transforms.size(); ++i) { | 2128 for (size_t i = 0; i < transforms.size(); ++i) { |
2059 TransformActionReverseMap::iterator ti = | 2129 TransformActionReverseMap::iterator ti = |
2060 m_transformActionsReverse.find(transforms[i]); | 2130 m_transformActionsReverse.find(transforms[i]); |
2078 } | 2148 } |
2079 | 2149 |
2080 void | 2150 void |
2081 MainWindow::setupExistingLayersMenus() | 2151 MainWindow::setupExistingLayersMenus() |
2082 { | 2152 { |
2153 SVDEBUG << "MainWindow::setupExistingLayersMenus" << endl; | |
2154 | |
2083 if (!m_existingLayersMenu) return; // should have been created by setupMenus | 2155 if (!m_existingLayersMenu) return; // should have been created by setupMenus |
2084 | 2156 |
2085 // SVDEBUG << "MainWindow::setupExistingLayersMenu" << endl; | 2157 // SVDEBUG << "MainWindow::setupExistingLayersMenu" << endl; |
2086 | 2158 |
2087 Profiler profiler1("MainWindow::setupExistingLayersMenu"); | 2159 Profiler profiler1("MainWindow::setupExistingLayersMenu"); |
2167 } | 2239 } |
2168 | 2240 |
2169 void | 2241 void |
2170 MainWindow::setupToolbars() | 2242 MainWindow::setupToolbars() |
2171 { | 2243 { |
2244 SVDEBUG << "MainWindow::setupToolbars" << endl; | |
2245 | |
2172 m_keyReference->setCategory(tr("Playback and Transport Controls")); | 2246 m_keyReference->setCategory(tr("Playback and Transport Controls")); |
2173 | 2247 |
2174 IconLoader il; | 2248 IconLoader il; |
2175 | 2249 |
2176 QMenu *menu = m_playbackMenu = menuBar()->addMenu(tr("Play&back")); | 2250 QMenu *menu = m_playbackMenu = menuBar()->addMenu(tr("Play&back")); |
2283 connect(m_viewManager, SIGNAL(playSoloModeChanged(bool)), | 2357 connect(m_viewManager, SIGNAL(playSoloModeChanged(bool)), |
2284 m_soloAction, SLOT(setChecked(bool))); | 2358 m_soloAction, SLOT(setChecked(bool))); |
2285 connect(m_soloAction, SIGNAL(triggered()), this, SLOT(playSoloToggled())); | 2359 connect(m_soloAction, SIGNAL(triggered()), this, SLOT(playSoloToggled())); |
2286 connect(this, SIGNAL(canChangeSolo(bool)), m_soloAction, SLOT(setEnabled(bool))); | 2360 connect(this, SIGNAL(canChangeSolo(bool)), m_soloAction, SLOT(setEnabled(bool))); |
2287 | 2361 |
2288 QAction *alAction = nullptr; | 2362 QAction *alAction = toolbar->addAction(il.load("align"), |
2289 if (Document::canAlign()) { | 2363 tr("Align File Timelines")); |
2290 alAction = toolbar->addAction(il.load("align"), | 2364 alAction->setCheckable(true); |
2291 tr("Align File Timelines")); | 2365 alAction->setChecked(m_viewManager->getAlignMode()); |
2292 alAction->setCheckable(true); | 2366 alAction->setStatusTip(tr("Treat multiple audio files as versions of the same work, and align their timelines")); |
2293 alAction->setChecked(m_viewManager->getAlignMode()); | 2367 alAction->setEnabled(false); // until canAlign emitted |
2294 alAction->setStatusTip(tr("Treat multiple audio files as versions of the same work, and align their timelines")); | 2368 connect(m_viewManager, SIGNAL(alignModeChanged(bool)), |
2295 connect(m_viewManager, SIGNAL(alignModeChanged(bool)), | 2369 alAction, SLOT(setChecked(bool))); |
2296 alAction, SLOT(setChecked(bool))); | 2370 connect(alAction, SIGNAL(triggered()), this, SLOT(alignToggled())); |
2297 connect(alAction, SIGNAL(triggered()), this, SLOT(alignToggled())); | 2371 connect(this, SIGNAL(canAlign(bool)), alAction, SLOT(setEnabled(bool))); |
2298 connect(this, SIGNAL(canAlign(bool)), alAction, SLOT(setEnabled(bool))); | |
2299 } | |
2300 | 2372 |
2301 m_keyReference->registerShortcut(m_playAction); | 2373 m_keyReference->registerShortcut(m_playAction); |
2302 m_keyReference->registerShortcut(m_recordAction); | 2374 m_keyReference->registerShortcut(m_recordAction); |
2303 m_keyReference->registerShortcut(m_playSelectionAction); | 2375 m_keyReference->registerShortcut(m_playSelectionAction); |
2304 m_keyReference->registerShortcut(m_playLoopAction); | 2376 m_keyReference->registerShortcut(m_playLoopAction); |
2305 m_keyReference->registerShortcut(m_soloAction); | 2377 m_keyReference->registerShortcut(m_soloAction); |
2306 if (alAction) m_keyReference->registerShortcut(alAction); | 2378 m_keyReference->registerShortcut(alAction); |
2307 m_keyReference->registerShortcut(m_rwdAction); | 2379 m_keyReference->registerShortcut(m_rwdAction); |
2308 m_keyReference->registerShortcut(m_ffwdAction); | 2380 m_keyReference->registerShortcut(m_ffwdAction); |
2309 m_keyReference->registerShortcut(m_rwdSimilarAction); | 2381 m_keyReference->registerShortcut(m_rwdSimilarAction); |
2310 m_keyReference->registerShortcut(m_ffwdSimilarAction); | 2382 m_keyReference->registerShortcut(m_ffwdSimilarAction); |
2311 m_keyReference->registerShortcut(m_rwdStartAction); | 2383 m_keyReference->registerShortcut(m_rwdStartAction); |
2314 menu->addAction(m_playAction); | 2386 menu->addAction(m_playAction); |
2315 menu->addAction(m_recordAction); | 2387 menu->addAction(m_recordAction); |
2316 menu->addAction(m_playSelectionAction); | 2388 menu->addAction(m_playSelectionAction); |
2317 menu->addAction(m_playLoopAction); | 2389 menu->addAction(m_playLoopAction); |
2318 menu->addAction(m_soloAction); | 2390 menu->addAction(m_soloAction); |
2319 if (alAction) menu->addAction(alAction); | 2391 menu->addAction(alAction); |
2320 menu->addSeparator(); | 2392 menu->addSeparator(); |
2321 menu->addAction(m_rwdAction); | 2393 menu->addAction(m_rwdAction); |
2322 menu->addAction(m_ffwdAction); | 2394 menu->addAction(m_ffwdAction); |
2323 menu->addSeparator(); | 2395 menu->addSeparator(); |
2324 menu->addAction(m_rwdSimilarAction); | 2396 menu->addAction(m_rwdSimilarAction); |
2530 } | 2602 } |
2531 | 2603 |
2532 void | 2604 void |
2533 MainWindow::updateMenuStates() | 2605 MainWindow::updateMenuStates() |
2534 { | 2606 { |
2607 SVDEBUG << "MainWindow::updateMenuStates" << endl; | |
2608 | |
2535 MainWindowBase::updateMenuStates(); | 2609 MainWindowBase::updateMenuStates(); |
2536 | 2610 |
2537 Pane *currentPane = nullptr; | 2611 Pane *currentPane = nullptr; |
2538 Layer *currentLayer = nullptr; | 2612 Layer *currentLayer = nullptr; |
2539 | 2613 |
2560 (haveCurrentLayer && | 2634 (haveCurrentLayer && |
2561 dynamic_cast<TimeValueLayer *>(currentLayer)); | 2635 dynamic_cast<TimeValueLayer *>(currentLayer)); |
2562 | 2636 |
2563 bool alignMode = m_viewManager && m_viewManager->getAlignMode(); | 2637 bool alignMode = m_viewManager && m_viewManager->getAlignMode(); |
2564 emit canChangeSolo(havePlayTarget && !alignMode); | 2638 emit canChangeSolo(havePlayTarget && !alignMode); |
2565 emit canAlign(havePlayTarget && m_document && m_document->canAlign()); | 2639 |
2640 if (TransformFactory::getInstance()->havePopulated()) { | |
2641 emit canAlign(havePlayTarget && m_document && m_document->canAlign()); | |
2642 } | |
2566 | 2643 |
2567 emit canChangePlaybackSpeed(true); | 2644 emit canChangePlaybackSpeed(true); |
2568 int v = m_playSpeed->value(); | 2645 int v = m_playSpeed->value(); |
2569 emit canSpeedUpPlayback(v < m_playSpeed->maximum()); | 2646 emit canSpeedUpPlayback(v < m_playSpeed->maximum()); |
2570 emit canSlowDownPlayback(v > m_playSpeed->minimum()); | 2647 emit canSlowDownPlayback(v > m_playSpeed->minimum()); |