comparison main/MainWindow.cpp @ 155:7310316bf74b

* Change a number of keyboard shortcuts -- get rid of all the Alt+ shortcuts and introduce a few more Ctrl+ ones instead, as well as a number of plain single keypresses * Add Playback menu * Add time-ruler support for snap to feature, use it in ffwd/rewind (rewind still needs fixing) * restore layer hierarchy window prior to making it work correctly
author Chris Cannam
date Thu, 28 Jun 2007 14:50:58 +0000
parents d2cc3b10e26f
children 63a9c88fbba9
comparison
equal deleted inserted replaced
154:f6ce5febc07f 155:7310316bf74b
115 m_recentTransforms("RecentTransforms", 20), 115 m_recentTransforms("RecentTransforms", 20),
116 m_mainMenusCreated(false), 116 m_mainMenusCreated(false),
117 m_paneMenu(0), 117 m_paneMenu(0),
118 m_layerMenu(0), 118 m_layerMenu(0),
119 m_transformsMenu(0), 119 m_transformsMenu(0),
120 m_playbackMenu(0),
120 m_existingLayersMenu(0), 121 m_existingLayersMenu(0),
121 m_sliceMenu(0), 122 m_sliceMenu(0),
122 m_recentFilesMenu(0), 123 m_recentFilesMenu(0),
123 m_recentTransformsMenu(0), 124 m_recentTransformsMenu(0),
124 m_rightButtonMenu(0), 125 m_rightButtonMenu(0),
125 m_rightButtonLayerMenu(0), 126 m_rightButtonLayerMenu(0),
126 m_rightButtonTransformsMenu(0), 127 m_rightButtonTransformsMenu(0),
128 m_rightButtonPlaybackMenu(0),
129 m_ffwdAction(0),
130 m_rwdAction(0),
127 m_documentModified(false), 131 m_documentModified(false),
128 m_openingAudioFile(false), 132 m_openingAudioFile(false),
129 m_abandoning(false), 133 m_abandoning(false),
130 m_preferencesDialog(0) 134 m_preferencesDialog(0)
131 { 135 {
288 oscTimer->start(1000); 292 oscTimer->start(1000);
289 } 293 }
290 294
291 setupMenus(); 295 setupMenus();
292 setupToolbars(); 296 setupToolbars();
297 setupHelpMenu();
293 298
294 statusBar(); 299 statusBar();
295 300
296 newSession(); 301 newSession();
297 } 302 }
405 setupFileMenu(); 410 setupFileMenu();
406 setupEditMenu(); 411 setupEditMenu();
407 setupViewMenu(); 412 setupViewMenu();
408 setupPaneAndLayerMenus(); 413 setupPaneAndLayerMenus();
409 setupTransformsMenu(); 414 setupTransformsMenu();
410 setupHelpMenu();
411 415
412 m_mainMenusCreated = true; 416 m_mainMenusCreated = true;
413 } 417 }
414 418
415 void 419 void
528 action = new QAction(tr("&Preferences..."), this); 532 action = new QAction(tr("&Preferences..."), this);
529 action->setStatusTip(tr("Adjust the application preferences")); 533 action->setStatusTip(tr("Adjust the application preferences"));
530 connect(action, SIGNAL(triggered()), this, SLOT(preferences())); 534 connect(action, SIGNAL(triggered()), this, SLOT(preferences()));
531 menu->addAction(action); 535 menu->addAction(action);
532 536
533 /*!!!
534 menu->addSeparator();
535
536 action = new QAction(tr("Play / Pause"), this);
537 action->setShortcut(tr("Space"));
538 action->setStatusTip(tr("Start or stop playback from the current position"));
539 connect(action, SIGNAL(triggered()), this, SLOT(play()));
540 menu->addAction(action);
541 */
542
543 menu->addSeparator(); 537 menu->addSeparator();
544 action = new QAction(QIcon(":/icons/exit.png"), 538 action = new QAction(QIcon(":/icons/exit.png"),
545 tr("&Quit"), this); 539 tr("&Quit"), this);
546 action->setShortcut(tr("Ctrl+Q")); 540 action->setShortcut(tr("Ctrl+Q"));
547 action->setStatusTip(tr("Exit Sonic Visualiser")); 541 action->setStatusTip(tr("Exit Sonic Visualiser"));
717 connect(this, SIGNAL(canZoom(bool)), action, SLOT(setEnabled(bool))); 711 connect(this, SIGNAL(canZoom(bool)), action, SLOT(setEnabled(bool)));
718 menu->addAction(action); 712 menu->addAction(action);
719 713
720 action = new QAction(QIcon(":/icons/zoom-fit.png"), 714 action = new QAction(QIcon(":/icons/zoom-fit.png"),
721 tr("Zoom to &Fit"), this); 715 tr("Zoom to &Fit"), this);
716 action->setShortcut(tr("F"));
722 action->setStatusTip(tr("Zoom to show the whole file")); 717 action->setStatusTip(tr("Zoom to show the whole file"));
723 connect(action, SIGNAL(triggered()), this, SLOT(zoomToFit())); 718 connect(action, SIGNAL(triggered()), this, SLOT(zoomToFit()));
724 connect(this, SIGNAL(canZoom(bool)), action, SLOT(setEnabled(bool))); 719 connect(this, SIGNAL(canZoom(bool)), action, SLOT(setEnabled(bool)));
725 menu->addAction(action); 720 menu->addAction(action);
726 721
796 action->setChecked(false); 791 action->setChecked(false);
797 statusBar()->hide(); 792 statusBar()->hide();
798 } 793 }
799 settings.endGroup(); 794 settings.endGroup();
800 795
801 /*!!! This one doesn't work properly yet
802
803 menu->addSeparator(); 796 menu->addSeparator();
804 797
805 action = new QAction(tr("Show La&yer Hierarchy"), this); 798 action = new QAction(tr("Show La&yer Hierarchy"), this);
806 action->setShortcut(tr("Alt+L")); 799 action->setShortcut(tr("H"));
807 action->setStatusTip(tr("Open a window displaying the hierarchy of panes and layers in this session")); 800 action->setStatusTip(tr("Open a window displaying the hierarchy of panes and layers in this session"));
808 connect(action, SIGNAL(triggered()), this, SLOT(showLayerTree())); 801 connect(action, SIGNAL(triggered()), this, SLOT(showLayerTree()));
809 menu->addAction(action); 802 menu->addAction(action);
810 */
811 } 803 }
812 804
813 void 805 void
814 MainWindow::setupPaneAndLayerMenus() 806 MainWindow::setupPaneAndLayerMenus()
815 { 807 {
830 } 822 }
831 823
832 QMenu *menu = m_paneMenu; 824 QMenu *menu = m_paneMenu;
833 825
834 QAction *action = new QAction(QIcon(":/icons/pane.png"), tr("Add &New Pane"), this); 826 QAction *action = new QAction(QIcon(":/icons/pane.png"), tr("Add &New Pane"), this);
835 action->setShortcut(tr("Alt+N")); 827 action->setShortcut(tr("N"));
836 action->setStatusTip(tr("Add a new pane containing only a time ruler")); 828 action->setStatusTip(tr("Add a new pane containing only a time ruler"));
837 connect(action, SIGNAL(triggered()), this, SLOT(addPane())); 829 connect(action, SIGNAL(triggered()), this, SLOT(addPane()));
838 connect(this, SIGNAL(canAddPane(bool)), action, SLOT(setEnabled(bool))); 830 connect(this, SIGNAL(canAddPane(bool)), action, SLOT(setEnabled(bool)));
839 m_paneActions[action] = PaneConfiguration(LayerFactory::TimeRuler); 831 m_paneActions[action] = PaneConfiguration(LayerFactory::TimeRuler);
840 menu->addAction(action); 832 menu->addAction(action);
864 856
865 action = new QAction(icon, mainText, this); 857 action = new QAction(icon, mainText, this);
866 action->setStatusTip(tipText); 858 action->setStatusTip(tipText);
867 859
868 if (type == LayerFactory::Text) { 860 if (type == LayerFactory::Text) {
869 action->setShortcut(tr("Alt+T")); 861 action->setShortcut(tr("T"));
870 } 862 }
871 863
872 connect(action, SIGNAL(triggered()), this, SLOT(addLayer())); 864 connect(action, SIGNAL(triggered()), this, SLOT(addLayer()));
873 connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); 865 connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool)));
874 m_layerActions[action] = type; 866 m_layerActions[action] = type;
913 905
914 case LayerFactory::Waveform: 906 case LayerFactory::Waveform:
915 icon = QIcon(":/icons/waveform.png"); 907 icon = QIcon(":/icons/waveform.png");
916 mainText = tr("Add &Waveform"); 908 mainText = tr("Add &Waveform");
917 if (menuType == 0) { 909 if (menuType == 0) {
918 shortcutText = tr("Alt+W"); 910 shortcutText = tr("W");
919 tipText = tr("Add a new pane showing a waveform view"); 911 tipText = tr("Add a new pane showing a waveform view");
920 } else { 912 } else {
921 tipText = tr("Add a new layer showing a waveform view"); 913 tipText = tr("Add a new layer showing a waveform view");
922 } 914 }
923 mono = false; 915 mono = false;
925 917
926 case LayerFactory::Spectrogram: 918 case LayerFactory::Spectrogram:
927 icon = QIcon(":/icons/spectrogram.png"); 919 icon = QIcon(":/icons/spectrogram.png");
928 mainText = tr("Add &Spectrogram"); 920 mainText = tr("Add &Spectrogram");
929 if (menuType == 0) { 921 if (menuType == 0) {
930 shortcutText = tr("Alt+S"); 922 shortcutText = tr("G");
931 tipText = tr("Add a new pane showing a spectrogram"); 923 tipText = tr("Add a new pane showing a spectrogram");
932 } else { 924 } else {
933 tipText = tr("Add a new layer showing a spectrogram"); 925 tipText = tr("Add a new layer showing a spectrogram");
934 } 926 }
935 break; 927 break;
936 928
937 case LayerFactory::MelodicRangeSpectrogram: 929 case LayerFactory::MelodicRangeSpectrogram:
938 icon = QIcon(":/icons/spectrogram.png"); 930 icon = QIcon(":/icons/spectrogram.png");
939 mainText = tr("Add &Melodic Range Spectrogram"); 931 mainText = tr("Add &Melodic Range Spectrogram");
940 if (menuType == 0) { 932 if (menuType == 0) {
941 shortcutText = tr("Alt+M"); 933 shortcutText = tr("M");
942 tipText = tr("Add a new pane showing a spectrogram set up for an overview of note pitches"); 934 tipText = tr("Add a new pane showing a spectrogram set up for an overview of note pitches");
943 } else { 935 } else {
944 tipText = tr("Add a new layer showing a spectrogram set up for an overview of note pitches"); 936 tipText = tr("Add a new layer showing a spectrogram set up for an overview of note pitches");
945 } 937 }
946 break; 938 break;
947 939
948 case LayerFactory::PeakFrequencySpectrogram: 940 case LayerFactory::PeakFrequencySpectrogram:
949 icon = QIcon(":/icons/spectrogram.png"); 941 icon = QIcon(":/icons/spectrogram.png");
950 mainText = tr("Add &Peak Frequency Spectrogram"); 942 mainText = tr("Add Pea&k Frequency Spectrogram");
951 if (menuType == 0) { 943 if (menuType == 0) {
952 shortcutText = tr("Alt+P"); 944 shortcutText = tr("K");
953 tipText = tr("Add a new pane showing a spectrogram set up for tracking frequencies"); 945 tipText = tr("Add a new pane showing a spectrogram set up for tracking frequencies");
954 } else { 946 } else {
955 tipText = tr("Add a new layer showing a spectrogram set up for tracking frequencies"); 947 tipText = tr("Add a new layer showing a spectrogram set up for tracking frequencies");
956 } 948 }
957 break; 949 break;
958 950
959 case LayerFactory::Spectrum: 951 case LayerFactory::Spectrum:
960 icon = QIcon(":/icons/spectrum.png"); 952 icon = QIcon(":/icons/spectrum.png");
961 mainText = tr("Add Spectr&um"); 953 mainText = tr("Add Spectr&um");
962 if (menuType == 0) { 954 if (menuType == 0) {
963 shortcutText = tr("Alt+U"); 955 shortcutText = tr("U");
964 tipText = tr("Add a new pane showing a frequency spectrum"); 956 tipText = tr("Add a new pane showing a frequency spectrum");
965 } else { 957 } else {
966 tipText = tr("Add a new layer showing a frequency spectrum"); 958 tipText = tr("Add a new layer showing a frequency spectrum");
967 } 959 }
968 break; 960 break;
1092 menu = m_paneMenu; 1084 menu = m_paneMenu;
1093 1085
1094 menu->addSeparator(); 1086 menu->addSeparator();
1095 1087
1096 action = new QAction(QIcon(":/icons/editdelete.png"), tr("&Delete Pane"), this); 1088 action = new QAction(QIcon(":/icons/editdelete.png"), tr("&Delete Pane"), this);
1097 action->setShortcut(tr("Alt+D")); 1089 action->setShortcut(tr("Ctrl+Shift+D"));
1098 action->setStatusTip(tr("Delete the currently active pane")); 1090 action->setStatusTip(tr("Delete the currently active pane"));
1099 connect(action, SIGNAL(triggered()), this, SLOT(deleteCurrentPane())); 1091 connect(action, SIGNAL(triggered()), this, SLOT(deleteCurrentPane()));
1100 connect(this, SIGNAL(canDeleteCurrentPane(bool)), action, SLOT(setEnabled(bool))); 1092 connect(this, SIGNAL(canDeleteCurrentPane(bool)), action, SLOT(setEnabled(bool)));
1101 menu->addAction(action); 1093 menu->addAction(action);
1102 1094
1123 1115
1124 m_rightButtonLayerMenu->addSeparator(); 1116 m_rightButtonLayerMenu->addSeparator();
1125 menu->addSeparator(); 1117 menu->addSeparator();
1126 1118
1127 action = new QAction(tr("&Rename Layer..."), this); 1119 action = new QAction(tr("&Rename Layer..."), this);
1128 action->setShortcut(tr("Alt+R")); 1120 action->setShortcut(tr("R"));
1129 action->setStatusTip(tr("Rename the currently active layer")); 1121 action->setStatusTip(tr("Rename the currently active layer"));
1130 connect(action, SIGNAL(triggered()), this, SLOT(renameCurrentLayer())); 1122 connect(action, SIGNAL(triggered()), this, SLOT(renameCurrentLayer()));
1131 connect(this, SIGNAL(canRenameLayer(bool)), action, SLOT(setEnabled(bool))); 1123 connect(this, SIGNAL(canRenameLayer(bool)), action, SLOT(setEnabled(bool)));
1132 menu->addAction(action); 1124 menu->addAction(action);
1133 m_rightButtonLayerMenu->addAction(action); 1125 m_rightButtonLayerMenu->addAction(action);
1134 1126
1135 action = new QAction(QIcon(":/icons/editdelete.png"), tr("&Delete Layer"), this); 1127 action = new QAction(QIcon(":/icons/editdelete.png"), tr("&Delete Layer"), this);
1136 action->setShortcut(tr("Alt+Shift+D")); 1128 action->setShortcut(tr("Ctrl+D"));
1137 action->setStatusTip(tr("Delete the currently active layer")); 1129 action->setStatusTip(tr("Delete the currently active layer"));
1138 connect(action, SIGNAL(triggered()), this, SLOT(deleteCurrentLayer())); 1130 connect(action, SIGNAL(triggered()), this, SLOT(deleteCurrentLayer()));
1139 connect(this, SIGNAL(canDeleteCurrentLayer(bool)), action, SLOT(setEnabled(bool))); 1131 connect(this, SIGNAL(canDeleteCurrentLayer(bool)), action, SLOT(setEnabled(bool)));
1140 menu->addAction(action); 1132 menu->addAction(action);
1141 m_rightButtonLayerMenu->addAction(action); 1133 m_rightButtonLayerMenu->addAction(action);
1345 } 1337 }
1346 1338
1347 void 1339 void
1348 MainWindow::setupHelpMenu() 1340 MainWindow::setupHelpMenu()
1349 { 1341 {
1350 if (m_mainMenusCreated) return;
1351
1352 QMenu *menu = menuBar()->addMenu(tr("&Help")); 1342 QMenu *menu = menuBar()->addMenu(tr("&Help"));
1353 menu->setTearOffEnabled(true); 1343 menu->setTearOffEnabled(true);
1354 1344
1355 QAction *action = new QAction(QIcon(":icons/help.png"), 1345 QAction *action = new QAction(QIcon(":icons/help.png"),
1356 tr("&Help Reference"), this); 1346 tr("&Help Reference"), this);
1375 m_recentFilesMenu->clear(); 1365 m_recentFilesMenu->clear();
1376 vector<QString> files = m_recentFiles.getRecent(); 1366 vector<QString> files = m_recentFiles.getRecent();
1377 for (size_t i = 0; i < files.size(); ++i) { 1367 for (size_t i = 0; i < files.size(); ++i) {
1378 QAction *action = new QAction(files[i], this); 1368 QAction *action = new QAction(files[i], this);
1379 connect(action, SIGNAL(triggered()), this, SLOT(openRecentFile())); 1369 connect(action, SIGNAL(triggered()), this, SLOT(openRecentFile()));
1370 if (i == 0) action->setShortcut(tr("Ctrl+R"));
1380 m_recentFilesMenu->addAction(action); 1371 m_recentFilesMenu->addAction(action);
1381 } 1372 }
1382 } 1373 }
1383 1374
1384 void 1375 void
1393 std::cerr << "WARNING: MainWindow::setupRecentTransformsMenu: " 1384 std::cerr << "WARNING: MainWindow::setupRecentTransformsMenu: "
1394 << "Unknown transform \"" << transforms[i].toStdString() 1385 << "Unknown transform \"" << transforms[i].toStdString()
1395 << "\" in recent transforms list" << std::endl; 1386 << "\" in recent transforms list" << std::endl;
1396 continue; 1387 continue;
1397 } 1388 }
1389 if (i == 0) ti->second->setShortcut(tr("Ctrl+T"));
1398 m_recentTransformsMenu->addAction(ti->second); 1390 m_recentTransformsMenu->addAction(ti->second);
1399 } 1391 }
1400 } 1392 }
1401 1393
1402 void 1394 void
1478 } 1470 }
1479 1471
1480 void 1472 void
1481 MainWindow::setupToolbars() 1473 MainWindow::setupToolbars()
1482 { 1474 {
1483 QToolBar *toolbar = addToolBar(tr("Transport Toolbar")); 1475 QMenu *menu = m_playbackMenu = menuBar()->addMenu(tr("Play&back"));
1484 1476 menu->setTearOffEnabled(true);
1485 QAction *action = toolbar->addAction(QIcon(":/icons/rewind-start.png"), 1477 m_rightButtonMenu->addSeparator();
1486 tr("Rewind to Start")); 1478 m_rightButtonPlaybackMenu = m_rightButtonMenu->addMenu(tr("Playback"));
1487 action->setShortcut(tr("Home")); 1479
1488 action->setStatusTip(tr("Rewind to the start")); 1480 QToolBar *toolbar = addToolBar(tr("Playback Toolbar"));
1489 connect(action, SIGNAL(triggered()), this, SLOT(rewindStart())); 1481
1490 connect(this, SIGNAL(canPlay(bool)), action, SLOT(setEnabled(bool))); 1482 QAction *rwdStartAction = toolbar->addAction(QIcon(":/icons/rewind-start.png"),
1491 1483 tr("Rewind to Start"));
1492 action = toolbar->addAction(QIcon(":/icons/rewind.png"), 1484 rwdStartAction->setShortcut(tr("Home"));
1493 tr("Rewind")); 1485 rwdStartAction->setStatusTip(tr("Rewind to the start"));
1494 action->setShortcut(tr("PageUp")); 1486 connect(rwdStartAction, SIGNAL(triggered()), this, SLOT(rewindStart()));
1495 action->setStatusTip(tr("Rewind to the previous time instant in the current layer")); 1487 connect(this, SIGNAL(canPlay(bool)), rwdStartAction, SLOT(setEnabled(bool)));
1496 connect(action, SIGNAL(triggered()), this, SLOT(rewind())); 1488
1497 connect(this, SIGNAL(canRewind(bool)), action, SLOT(setEnabled(bool))); 1489 QAction *m_rwdAction = toolbar->addAction(QIcon(":/icons/rewind.png"),
1498 1490 tr("Rewind"));
1499 action = toolbar->addAction(QIcon(":/icons/playpause.png"), 1491 m_rwdAction->setShortcut(tr("PgUp"));
1500 tr("Play / Pause")); 1492 connect(m_rwdAction, SIGNAL(triggered()), this, SLOT(rewind()));
1501 action->setCheckable(true); 1493 connect(this, SIGNAL(canRewind(bool)), m_rwdAction, SLOT(setEnabled(bool)));
1502 action->setShortcut(tr("Space")); 1494
1503 action->setStatusTip(tr("Start or stop playback from the current position")); 1495 QAction *playAction = toolbar->addAction(QIcon(":/icons/playpause.png"),
1504 connect(action, SIGNAL(triggered()), this, SLOT(play())); 1496 tr("Play / Pause"));
1497 playAction->setCheckable(true);
1498 playAction->setShortcut(tr("Space"));
1499 playAction->setStatusTip(tr("Start or stop playback from the current position"));
1500 connect(playAction, SIGNAL(triggered()), this, SLOT(play()));
1505 connect(m_playSource, SIGNAL(playStatusChanged(bool)), 1501 connect(m_playSource, SIGNAL(playStatusChanged(bool)),
1506 action, SLOT(setChecked(bool))); 1502 playAction, SLOT(setChecked(bool)));
1507 connect(this, SIGNAL(canPlay(bool)), action, SLOT(setEnabled(bool))); 1503 connect(this, SIGNAL(canPlay(bool)), playAction, SLOT(setEnabled(bool)));
1508 1504
1509 action = toolbar->addAction(QIcon(":/icons/ffwd.png"), 1505 m_ffwdAction = toolbar->addAction(QIcon(":/icons/ffwd.png"),
1510 tr("Fast Forward")); 1506 tr("Fast Forward"));
1511 action->setShortcut(tr("PageDown")); 1507 m_ffwdAction->setShortcut(tr("PgDown"));
1512 action->setStatusTip(tr("Fast forward to the next time instant in the current layer")); 1508 connect(m_ffwdAction, SIGNAL(triggered()), this, SLOT(ffwd()));
1513 connect(action, SIGNAL(triggered()), this, SLOT(ffwd())); 1509 connect(this, SIGNAL(canFfwd(bool)), m_ffwdAction, SLOT(setEnabled(bool)));
1514 connect(this, SIGNAL(canFfwd(bool)), action, SLOT(setEnabled(bool))); 1510
1515 1511 QAction *ffwdEndAction = toolbar->addAction(QIcon(":/icons/ffwd-end.png"),
1516 action = toolbar->addAction(QIcon(":/icons/ffwd-end.png"), 1512 tr("Fast Forward to End"));
1517 tr("Fast Forward to End")); 1513 ffwdEndAction->setShortcut(tr("End"));
1518 action->setShortcut(tr("End")); 1514 ffwdEndAction->setStatusTip(tr("Fast-forward to the end"));
1519 action->setStatusTip(tr("Fast-forward to the end")); 1515 connect(ffwdEndAction, SIGNAL(triggered()), this, SLOT(ffwdEnd()));
1520 connect(action, SIGNAL(triggered()), this, SLOT(ffwdEnd())); 1516 connect(this, SIGNAL(canPlay(bool)), ffwdEndAction, SLOT(setEnabled(bool)));
1521 connect(this, SIGNAL(canPlay(bool)), action, SLOT(setEnabled(bool)));
1522 1517
1523 toolbar = addToolBar(tr("Play Mode Toolbar")); 1518 toolbar = addToolBar(tr("Play Mode Toolbar"));
1524 1519
1525 action = toolbar->addAction(QIcon(":/icons/playselection.png"), 1520 QAction *psAction = toolbar->addAction(QIcon(":/icons/playselection.png"),
1526 tr("Constrain Playback to Selection")); 1521 tr("Constrain Playback to Selection"));
1527 action->setCheckable(true); 1522 psAction->setCheckable(true);
1528 action->setChecked(m_viewManager->getPlaySelectionMode()); 1523 psAction->setChecked(m_viewManager->getPlaySelectionMode());
1529 action->setShortcut(tr("s")); 1524 psAction->setShortcut(tr("s"));
1530 action->setStatusTip(tr("Constrain playback to the selected area")); 1525 psAction->setStatusTip(tr("Constrain playback to the selected area"));
1531 connect(m_viewManager, SIGNAL(playSelectionModeChanged(bool)), 1526 connect(m_viewManager, SIGNAL(playSelectionModeChanged(bool)),
1532 action, SLOT(setChecked(bool))); 1527 psAction, SLOT(setChecked(bool)));
1533 connect(action, SIGNAL(triggered()), this, SLOT(playSelectionToggled())); 1528 connect(psAction, SIGNAL(triggered()), this, SLOT(playSelectionToggled()));
1534 connect(this, SIGNAL(canPlaySelection(bool)), action, SLOT(setEnabled(bool))); 1529 connect(this, SIGNAL(canPlaySelection(bool)), psAction, SLOT(setEnabled(bool)));
1535 1530
1536 action = toolbar->addAction(QIcon(":/icons/playloop.png"), 1531 QAction *plAction = toolbar->addAction(QIcon(":/icons/playloop.png"),
1537 tr("Loop Playback")); 1532 tr("Loop Playback"));
1538 action->setCheckable(true); 1533 plAction->setCheckable(true);
1539 action->setChecked(m_viewManager->getPlayLoopMode()); 1534 plAction->setChecked(m_viewManager->getPlayLoopMode());
1540 action->setShortcut(tr("l")); 1535 plAction->setShortcut(tr("l"));
1541 action->setStatusTip(tr("Loop playback")); 1536 plAction->setStatusTip(tr("Loop playback"));
1542 connect(m_viewManager, SIGNAL(playLoopModeChanged(bool)), 1537 connect(m_viewManager, SIGNAL(playLoopModeChanged(bool)),
1543 action, SLOT(setChecked(bool))); 1538 plAction, SLOT(setChecked(bool)));
1544 connect(action, SIGNAL(triggered()), this, SLOT(playLoopToggled())); 1539 connect(plAction, SIGNAL(triggered()), this, SLOT(playLoopToggled()));
1545 connect(this, SIGNAL(canPlay(bool)), action, SLOT(setEnabled(bool))); 1540 connect(this, SIGNAL(canPlay(bool)), plAction, SLOT(setEnabled(bool)));
1541
1542 menu->addAction(playAction);
1543 menu->addAction(psAction);
1544 menu->addAction(plAction);
1545 menu->addSeparator();
1546 menu->addAction(m_rwdAction);
1547 menu->addAction(m_ffwdAction);
1548 menu->addSeparator();
1549 menu->addAction(rwdStartAction);
1550 menu->addAction(ffwdEndAction);
1551 menu->addSeparator();
1552
1553 m_rightButtonPlaybackMenu->addAction(playAction);
1554 m_rightButtonPlaybackMenu->addAction(psAction);
1555 m_rightButtonPlaybackMenu->addAction(plAction);
1556 m_rightButtonPlaybackMenu->addSeparator();
1557 m_rightButtonPlaybackMenu->addAction(m_rwdAction);
1558 m_rightButtonPlaybackMenu->addAction(m_ffwdAction);
1559 m_rightButtonPlaybackMenu->addSeparator();
1560 m_rightButtonPlaybackMenu->addAction(rwdStartAction);
1561 m_rightButtonPlaybackMenu->addAction(ffwdEndAction);
1562 m_rightButtonPlaybackMenu->addSeparator();
1563
1564 QAction *fastAction = menu->addAction(tr("Speed Up"));
1565 fastAction->setShortcut(tr("Ctrl+PgUp"));
1566 connect(fastAction, SIGNAL(triggered()), this, SLOT(speedUpPlayback()));
1567 connect(this, SIGNAL(canSpeedUpPlayback(bool)), fastAction, SLOT(setEnabled(bool)));
1568
1569 QAction *slowAction = menu->addAction(tr("Slow Down"));
1570 slowAction->setShortcut(tr("Ctrl+PgDown"));
1571 connect(slowAction, SIGNAL(triggered()), this, SLOT(slowDownPlayback()));
1572 connect(this, SIGNAL(canSlowDownPlayback(bool)), slowAction, SLOT(setEnabled(bool)));
1573
1574 QAction *normalAction = menu->addAction(tr("Restore Normal Speed"));
1575 normalAction->setShortcut(tr("Ctrl+Home"));
1576 connect(normalAction, SIGNAL(triggered()), this, SLOT(restoreNormalPlayback()));
1577 connect(this, SIGNAL(canChangePlaybackSpeed(bool)), normalAction, SLOT(setEnabled(bool)));
1578
1579 m_rightButtonPlaybackMenu->addAction(fastAction);
1580 m_rightButtonPlaybackMenu->addAction(slowAction);
1581 m_rightButtonPlaybackMenu->addAction(normalAction);
1546 1582
1547 toolbar = addToolBar(tr("Edit Toolbar")); 1583 toolbar = addToolBar(tr("Edit Toolbar"));
1548 CommandHistory::getInstance()->registerToolbar(toolbar); 1584 CommandHistory::getInstance()->registerToolbar(toolbar);
1549 1585
1550 toolbar = addToolBar(tr("Tools Toolbar")); 1586 toolbar = addToolBar(tr("Tools Toolbar"));
1551 QActionGroup *group = new QActionGroup(this); 1587 QActionGroup *group = new QActionGroup(this);
1552 1588
1553 action = toolbar->addAction(QIcon(":/icons/navigate.png"), 1589 QAction *action = toolbar->addAction(QIcon(":/icons/navigate.png"),
1554 tr("Navigate")); 1590 tr("Navigate"));
1555 action->setCheckable(true); 1591 action->setCheckable(true);
1556 action->setChecked(true); 1592 action->setChecked(true);
1557 action->setShortcut(tr("1")); 1593 action->setShortcut(tr("1"));
1558 action->setStatusTip(tr("Navigate")); 1594 action->setStatusTip(tr("Navigate"));
1559 connect(action, SIGNAL(triggered()), this, SLOT(toolNavigateSelected())); 1595 connect(action, SIGNAL(triggered()), this, SLOT(toolNavigateSelected()));
1659 emit canExportImage(haveMainModel && haveCurrentPane); 1695 emit canExportImage(haveMainModel && haveCurrentPane);
1660 emit canDeleteCurrentLayer(haveCurrentLayer); 1696 emit canDeleteCurrentLayer(haveCurrentLayer);
1661 emit canRenameLayer(haveCurrentLayer); 1697 emit canRenameLayer(haveCurrentLayer);
1662 emit canEditLayer(haveCurrentEditableLayer); 1698 emit canEditLayer(haveCurrentEditableLayer);
1663 emit canSelect(haveMainModel && haveCurrentPane); 1699 emit canSelect(haveMainModel && haveCurrentPane);
1664 emit canPlay(/*!!! haveMainModel && */ havePlayTarget); 1700 emit canPlay(havePlayTarget);
1665 emit canFfwd(haveCurrentTimeInstantsLayer || haveCurrentTimeValueLayer); 1701 emit canFfwd(true);
1666 emit canRewind(haveCurrentTimeInstantsLayer || haveCurrentTimeValueLayer); 1702 emit canRewind(true);
1667 emit canPaste(haveCurrentEditableLayer && haveClipboardContents); 1703 emit canPaste(haveCurrentEditableLayer && haveClipboardContents);
1668 emit canInsertInstant(haveCurrentPane); 1704 emit canInsertInstant(haveCurrentPane);
1669 emit canInsertInstantsAtBoundaries(haveCurrentPane && haveSelection); 1705 emit canInsertInstantsAtBoundaries(haveCurrentPane && haveSelection);
1670 emit canPlaySelection(haveMainModel && havePlayTarget && haveSelection); 1706 emit canPlaySelection(haveMainModel && havePlayTarget && haveSelection);
1671 emit canClearSelection(haveSelection); 1707 emit canClearSelection(haveSelection);
1672 emit canEditSelection(haveSelection && haveCurrentEditableLayer); 1708 emit canEditSelection(haveSelection && haveCurrentEditableLayer);
1673 emit canSave(m_sessionFile != "" && m_documentModified); 1709 emit canSave(m_sessionFile != "" && m_documentModified);
1710
1711 emit canChangePlaybackSpeed(true);
1712 int v = m_playSpeed->value();
1713 emit canSpeedUpPlayback(v < m_playSpeed->maximum());
1714 emit canSlowDownPlayback(v > m_playSpeed->minimum());
1715
1716 if (m_ffwdAction && m_rwdAction) {
1717 if (haveCurrentTimeInstantsLayer) {
1718 m_ffwdAction->setText(tr("Fast Forward to Next Instant"));
1719 m_ffwdAction->setStatusTip(tr("Fast forward to the next time instant in the current layer"));
1720 m_rwdAction->setText(tr("Rewind to Previous Instant"));
1721 m_rwdAction->setStatusTip(tr("Rewind to the previous time instant in the current layer"));
1722 } else if (haveCurrentTimeValueLayer) {
1723 m_ffwdAction->setText(tr("Fast Forward to Next Point"));
1724 m_ffwdAction->setStatusTip(tr("Fast forward to the next point in the current layer"));
1725 m_rwdAction->setText(tr("Rewind to Previous Point"));
1726 m_rwdAction->setStatusTip(tr("Rewind to the previous point in the current layer"));
1727 } else {
1728 m_ffwdAction->setText(tr("Fast Forward"));
1729 m_ffwdAction->setStatusTip(tr("Fast forward"));
1730 m_rwdAction->setText(tr("Rewind"));
1731 m_rwdAction->setStatusTip(tr("Rewind"));
1732 }
1733 }
1674 } 1734 }
1675 1735
1676 void 1736 void
1677 MainWindow::updateDescriptionLabel() 1737 MainWindow::updateDescriptionLabel()
1678 { 1738 {
3296 if (!getMainModel()) return; 3356 if (!getMainModel()) return;
3297 3357
3298 int frame = m_viewManager->getPlaybackFrame(); 3358 int frame = m_viewManager->getPlaybackFrame();
3299 ++frame; 3359 ++frame;
3300 3360
3301 Pane *pane = m_paneStack->getCurrentPane(); 3361 Layer *layer = getSnapLayer();
3302 if (!pane) return; 3362 size_t sr = getMainModel()->getSampleRate();
3303 3363
3304 Layer *layer = pane->getSelectedLayer(); 3364 if (!layer) {
3305 3365
3306 if (!dynamic_cast<TimeInstantLayer *>(layer) && 3366 frame = RealTime::realTime2Frame
3307 !dynamic_cast<TimeValueLayer *>(layer)) return; 3367 (RealTime::frame2RealTime(frame, sr) + RealTime(2, 0), sr);
3308 3368 if (frame > int(getMainModel()->getEndFrame())) {
3309 size_t resolution = 0; 3369 frame = getMainModel()->getEndFrame();
3310 if (!layer->snapToFeatureFrame(pane, frame, resolution, Layer::SnapRight)) { 3370 }
3311 frame = getMainModel()->getEndFrame(); 3371
3312 } 3372 } else {
3373
3374 size_t resolution = 0;
3375 if (!layer->snapToFeatureFrame(m_paneStack->getCurrentPane(),
3376 frame, resolution, Layer::SnapRight)) {
3377 frame = getMainModel()->getEndFrame();
3378 }
3379 }
3380
3381 if (frame < 0) frame = 0;
3313 3382
3314 if (m_viewManager->getPlaySelectionMode()) { 3383 if (m_viewManager->getPlaySelectionMode()) {
3315 MultiSelection::SelectionList sl = m_viewManager->getSelections(); 3384 frame = m_viewManager->constrainFrameToSelection(size_t(frame));
3316 if (!sl.empty()) {
3317 MultiSelection::SelectionList::iterator i = sl.end();
3318 --i;
3319 int selectionEndFrame = i->getEndFrame();
3320 if (frame > selectionEndFrame) frame = selectionEndFrame;
3321 }
3322 } 3385 }
3323 3386
3324 m_viewManager->setPlaybackFrame(frame); 3387 m_viewManager->setPlaybackFrame(frame);
3325 } 3388 }
3326 3389
3330 if (!getMainModel()) return; 3393 if (!getMainModel()) return;
3331 3394
3332 size_t frame = getMainModel()->getEndFrame(); 3395 size_t frame = getMainModel()->getEndFrame();
3333 3396
3334 if (m_viewManager->getPlaySelectionMode()) { 3397 if (m_viewManager->getPlaySelectionMode()) {
3335 MultiSelection::SelectionList sl = m_viewManager->getSelections(); 3398 frame = m_viewManager->constrainFrameToSelection(frame);
3336 if (!sl.empty()) {
3337 MultiSelection::SelectionList::iterator i = sl.end();
3338 --i;
3339 size_t selectionEndFrame = i->getEndFrame();
3340 if (frame > selectionEndFrame) frame = selectionEndFrame;
3341 }
3342 } 3399 }
3343 3400
3344 m_viewManager->setPlaybackFrame(frame); 3401 m_viewManager->setPlaybackFrame(frame);
3345 } 3402 }
3346 3403
3350 if (!getMainModel()) return; 3407 if (!getMainModel()) return;
3351 3408
3352 int frame = m_viewManager->getPlaybackFrame(); 3409 int frame = m_viewManager->getPlaybackFrame();
3353 if (frame > 0) --frame; 3410 if (frame > 0) --frame;
3354 3411
3412 Layer *layer = getSnapLayer();
3413 size_t sr = getMainModel()->getSampleRate();
3414
3415 if (!layer) {
3416
3417 frame = RealTime::realTime2Frame
3418 (RealTime::frame2RealTime(frame, sr) - RealTime(2, 0), sr);
3419 if (frame < int(getMainModel()->getStartFrame())) {
3420 frame = getMainModel()->getStartFrame();
3421 }
3422
3423 } else {
3424
3425 size_t resolution = 0;
3426 if (!layer->snapToFeatureFrame(m_paneStack->getCurrentPane(),
3427 frame, resolution, Layer::SnapLeft)) {
3428 frame = getMainModel()->getStartFrame();
3429 }
3430 }
3431
3432 if (frame < 0) frame = 0;
3433
3434 if (m_viewManager->getPlaySelectionMode()) {
3435 frame = m_viewManager->constrainFrameToSelection(size_t(frame));
3436 }
3437
3438 m_viewManager->setPlaybackFrame(frame);
3439 }
3440
3441 void
3442 MainWindow::rewindStart()
3443 {
3444 if (!getMainModel()) return;
3445
3446 size_t frame = getMainModel()->getStartFrame();
3447
3448 if (m_viewManager->getPlaySelectionMode()) {
3449 frame = m_viewManager->constrainFrameToSelection(frame);
3450 }
3451
3452 m_viewManager->setPlaybackFrame(frame);
3453 }
3454
3455 Layer *
3456 MainWindow::getSnapLayer() const
3457 {
3355 Pane *pane = m_paneStack->getCurrentPane(); 3458 Pane *pane = m_paneStack->getCurrentPane();
3356 if (!pane) return; 3459 if (!pane) return 0;
3357 3460
3358 Layer *layer = pane->getSelectedLayer(); 3461 Layer *layer = pane->getSelectedLayer();
3359 3462
3360 if (!dynamic_cast<TimeInstantLayer *>(layer) && 3463 if (!dynamic_cast<TimeInstantLayer *>(layer) &&
3361 !dynamic_cast<TimeValueLayer *>(layer)) return; 3464 !dynamic_cast<TimeValueLayer *>(layer) &&
3362 3465 !dynamic_cast<TimeRulerLayer *>(layer)) {
3363 size_t resolution = 0; 3466
3364 if (!layer->snapToFeatureFrame(pane, frame, resolution, Layer::SnapLeft)) { 3467 layer = 0;
3365 frame = getMainModel()->getEndFrame(); 3468
3366 } 3469 for (int i = pane->getLayerCount(); i > 0; --i) {
3367 3470 Layer *l = pane->getLayer(i-1);
3368 if (m_viewManager->getPlaySelectionMode()) { 3471 if (dynamic_cast<TimeRulerLayer *>(l)) {
3369 MultiSelection::SelectionList sl = m_viewManager->getSelections(); 3472 layer = l;
3370 if (!sl.empty()) { 3473 break;
3371 int selectionStartFrame = sl.begin()->getStartFrame(); 3474 }
3372 if (frame < selectionStartFrame) frame = selectionStartFrame; 3475 }
3373 } 3476 }
3374 } 3477
3375 3478 return layer;
3376 m_viewManager->setPlaybackFrame(frame);
3377 }
3378
3379 void
3380 MainWindow::rewindStart()
3381 {
3382 if (!getMainModel()) return;
3383
3384 size_t frame = getMainModel()->getStartFrame();
3385
3386 if (m_viewManager->getPlaySelectionMode()) {
3387 MultiSelection::SelectionList sl = m_viewManager->getSelections();
3388 if (!sl.empty()) {
3389 size_t selectionStartFrame = sl.begin()->getStartFrame();
3390 if (frame < selectionStartFrame) frame = selectionStartFrame;
3391 }
3392 }
3393
3394 m_viewManager->setPlaybackFrame(frame);
3395 } 3479 }
3396 3480
3397 void 3481 void
3398 MainWindow::stop() 3482 MainWindow::stop()
3399 { 3483 {
3781 MainWindow::playSpeedChanged(int position) 3865 MainWindow::playSpeedChanged(int position)
3782 { 3866 {
3783 PlaySpeedRangeMapper mapper(0, 200); 3867 PlaySpeedRangeMapper mapper(0, 200);
3784 3868
3785 float percent = m_playSpeed->mappedValue(); 3869 float percent = m_playSpeed->mappedValue();
3786
3787 float factor = mapper.getFactorForValue(percent); 3870 float factor = mapper.getFactorForValue(percent);
3788 3871
3789 // float factor = mapper.getFactorForPosition(position);
3790 // float percent = mapper.getValueForPosition(position);
3791
3792 std::cerr << "speed = " << position << " percent = " << percent << " factor = " << factor << std::endl; 3872 std::cerr << "speed = " << position << " percent = " << percent << " factor = " << factor << std::endl;
3793 3873
3794 //!!! bool slow = (position < 100);
3795 bool something = (position != 100); 3874 bool something = (position != 100);
3796 /*!!! 3875
3797 int pc = lrintf(percent); 3876 int pc = lrintf(percent);
3798 3877
3799 m_playSpeed->setToolTip(tr("Playback speed: %1%2%") 3878 if (!something) {
3800 .arg(!slow ? "+" : "") 3879 contextHelpChanged(tr("Playback speed: Normal"));
3801 .arg(pc)); 3880 } else {
3802 */ 3881 contextHelpChanged(tr("Playback speed: %1%2%")
3882 .arg(position > 100 ? "+" : "")
3883 .arg(pc));
3884 }
3885
3803 m_playSharpen->setEnabled(something); 3886 m_playSharpen->setEnabled(something);
3804 m_playMono->setEnabled(something); 3887 m_playMono->setEnabled(something);
3805 bool sharpen = (something && m_playSharpen->isChecked()); 3888 bool sharpen = (something && m_playSharpen->isChecked());
3806 bool mono = (something && m_playMono->isChecked()); 3889 bool mono = (something && m_playMono->isChecked());
3807 m_playSource->setTimeStretch(factor, sharpen, mono); 3890 m_playSource->setTimeStretch(factor, sharpen, mono);
3891
3892 updateMenuStates();
3808 } 3893 }
3809 3894
3810 void 3895 void
3811 MainWindow::playSharpenToggled() 3896 MainWindow::playSharpenToggled()
3812 { 3897 {
3826 settings.setValue("playmono", m_playMono->isChecked()); 3911 settings.setValue("playmono", m_playMono->isChecked());
3827 settings.endGroup(); 3912 settings.endGroup();
3828 3913
3829 playSpeedChanged(m_playSpeed->value()); 3914 playSpeedChanged(m_playSpeed->value());
3830 } 3915 }
3916
3917 void
3918 MainWindow::speedUpPlayback()
3919 {
3920 int value = m_playSpeed->value();
3921 value = value + m_playSpeed->pageStep();
3922 if (value > m_playSpeed->maximum()) value = m_playSpeed->maximum();
3923 m_playSpeed->setValue(value);
3924 }
3925
3926 void
3927 MainWindow::slowDownPlayback()
3928 {
3929 int value = m_playSpeed->value();
3930 value = value - m_playSpeed->pageStep();
3931 if (value < m_playSpeed->minimum()) value = m_playSpeed->minimum();
3932 m_playSpeed->setValue(value);
3933 }
3934
3935 void
3936 MainWindow::restoreNormalPlayback()
3937 {
3938 m_playSpeed->setValue(m_playSpeed->defaultValue());
3939 }
3831 3940
3832 void 3941 void
3833 MainWindow::playbackFrameChanged(unsigned long frame) 3942 MainWindow::playbackFrameChanged(unsigned long frame)
3834 { 3943 {
3835 if (!(m_playSource && m_playSource->isPlaying()) || !getMainModel()) return; 3944 if (!(m_playSource && m_playSource->isPlaying()) || !getMainModel()) return;
4104 void 4213 void
4105 MainWindow::showLayerTree() 4214 MainWindow::showLayerTree()
4106 { 4215 {
4107 QTreeView *view = new QTreeView(); 4216 QTreeView *view = new QTreeView();
4108 LayerTreeModel *tree = new LayerTreeModel(m_paneStack); 4217 LayerTreeModel *tree = new LayerTreeModel(m_paneStack);
4109 view->expand(tree->index(0, 0, QModelIndex()));
4110 view->setModel(tree); 4218 view->setModel(tree);
4219 // view->expand(tree->index(0, 0, QModelIndex()));
4220 view->expandAll();
4111 view->show(); 4221 view->show();
4112 } 4222 }
4113 4223
4114 void 4224 void
4115 MainWindow::pollOSC() 4225 MainWindow::pollOSC()