comparison main/MainWindow.cpp @ 1150:5e6e1e074080 3.0-plus-imaf

Merge branches 3.0-integration and imaf_enc to 3.0-plus-imaf
author Chris Cannam
date Wed, 20 Apr 2016 12:06:28 +0100
parents b3b5885e7c2c b987cc23a26c
children
comparison
equal deleted inserted replaced
1149:3ba5bee2ace0 1150:5e6e1e074080
3 /* 3 /*
4 Sonic Visualiser 4 Sonic Visualiser
5 An audio file viewer and annotation editor. 5 An audio file viewer and annotation editor.
6 Centre for Digital Music, Queen Mary, University of London. 6 Centre for Digital Music, Queen Mary, University of London.
7 This file copyright 2006-2007 Chris Cannam and QMUL. 7 This file copyright 2006-2007 Chris Cannam and QMUL.
8 8
9 This program is free software; you can redistribute it and/or 9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License as 10 modify it under the terms of the GNU General Public License as
11 published by the Free Software Foundation; either version 2 of the 11 published by the Free Software Foundation; either version 2 of the
12 License, or (at your option) any later version. See the file 12 License, or (at your option) any later version. See the file
13 COPYING included with this distribution for more information. 13 COPYING included with this distribution for more information.
14 */ 14 */
15
15 16
16 #include "../version.h" 17 #include "../version.h"
17 18
18 #include "MainWindow.h" 19 #include "MainWindow.h"
19 #include "PreferencesDialog.h" 20 #include "PreferencesDialog.h"
129 130
130 using std::vector; 131 using std::vector;
131 using std::map; 132 using std::map;
132 using std::set; 133 using std::set;
133 134
135 //IMAF REQUIRED LIBRARIES AND VARIABLES
136 #include "IMAFencoder.c"
137 #include "checkbox.h"
138 #include <QFileDialog>
139 #include "imafdecoder.cpp"
140
141 QString ImafFileName,ImageFileName,TextFileName; //name of the files
142 QString files_paths[maxtracks]; // change maxtracks in IMAFencoder.h
143 int ImafVolumeValues[maxtracks];
144 int numtracks;
145 bool has_image, has_lyrics;
146 int selrule_type, selrule_par1, selrule_par2;
147 int mixrule_type, mixrule_par1, mixrule_par2, mixrule_par3, mixrule_par4;
148 int group_tracks[maxtracks], group_volume;
149 QString group_descr, group_name;
150 int preset_type, fade_in;
151
152 bool isIMAF;
134 153
135 MainWindow::MainWindow(SoundOptions options, bool withOSCSupport) : 154 MainWindow::MainWindow(SoundOptions options, bool withOSCSupport) :
136 MainWindowBase(options), 155 MainWindowBase(options),
137 m_overview(0), 156 m_overview(0),
138 m_mainMenusCreated(false), 157 m_mainMenusCreated(false),
248 m_playSpeed->setObjectName(tr("Playback Speed")); 267 m_playSpeed->setObjectName(tr("Playback Speed"));
249 m_playSpeed->setRangeMapper(new PlaySpeedRangeMapper); 268 m_playSpeed->setRangeMapper(new PlaySpeedRangeMapper);
250 m_playSpeed->setDefaultValue(60); 269 m_playSpeed->setDefaultValue(60);
251 m_playSpeed->setShowToolTip(true); 270 m_playSpeed->setShowToolTip(true);
252 connect(m_playSpeed, SIGNAL(valueChanged(int)), 271 connect(m_playSpeed, SIGNAL(valueChanged(int)),
253 this, SLOT(playSpeedChanged(int))); 272 this, SLOT(playSpeedChanged(int)));
254 connect(m_playSpeed, SIGNAL(mouseEntered()), this, SLOT(mouseEnteredWidget())); 273 connect(m_playSpeed, SIGNAL(mouseEntered()), this, SLOT(mouseEnteredWidget()));
255 connect(m_playSpeed, SIGNAL(mouseLeft()), this, SLOT(mouseLeftWidget())); 274 connect(m_playSpeed, SIGNAL(mouseLeft()), this, SLOT(mouseLeftWidget()));
256 275
257 IconLoader il; 276 IconLoader il;
258 277
263 layout->addWidget(m_overview, 1, 1); 282 layout->addWidget(m_overview, 1, 1);
264 layout->addWidget(m_playControlsSpacer, 1, 2); 283 layout->addWidget(m_playControlsSpacer, 1, 2);
265 layout->addWidget(m_playSpeed, 1, 3); 284 layout->addWidget(m_playSpeed, 1, 3);
266 layout->addWidget(m_fader, 1, 4); 285 layout->addWidget(m_fader, 1, 4);
267 286
268 m_playControlsWidth = 287 m_playControlsWidth =
269 m_fader->width() + m_playSpeed->width() + layout->spacing() * 2; 288 m_fader->width() + m_playSpeed->width() + layout->spacing() * 2;
270 289
271 layout->setColumnMinimumWidth(0, 14); 290 layout->setColumnMinimumWidth(0, 14);
272 layout->setColumnStretch(0, 0); 291 layout->setColumnStretch(0, 0);
273 292
318 if (networkPermission) { 337 if (networkPermission) {
319 if (withOSCSupport) { 338 if (withOSCSupport) {
320 startOSCQueue(); 339 startOSCQueue();
321 } 340 }
322 TransformFactory::getInstance()->startPopulationThread(); 341 TransformFactory::getInstance()->startPopulationThread();
342 m_surveyer = 0;
343 m_versionTester = 0;
344 /*
323 m_surveyer = new Surveyer 345 m_surveyer = new Surveyer
324 ("sonicvisualiser.org", "survey23-present.txt", "survey23.php"); 346 ("sonicvisualiser.org", "survey23-present.txt", "survey23.php");
325 m_versionTester = new VersionTester 347 m_versionTester = new VersionTester
326 ("sonicvisualiser.org", "latest-version.txt", SV_VERSION); 348 ("sonicvisualiser.org", "latest-version.txt", SV_VERSION);
327 connect(m_versionTester, SIGNAL(newerVersionAvailable(QString)), 349 connect(m_versionTester, SIGNAL(newerVersionAvailable(QString)),
328 this, SLOT(newerVersionAvailable(QString))); 350 this, SLOT(newerVersionAvailable(QString)));
351 */
329 } else { 352 } else {
330 m_surveyer = 0; 353 m_surveyer = 0;
331 m_versionTester = 0; 354 m_versionTester = 0;
332 } 355 }
333 356
525 connect(action, SIGNAL(triggered()), this, SLOT(saveSession())); 548 connect(action, SIGNAL(triggered()), this, SLOT(saveSession()));
526 connect(this, SIGNAL(canSave(bool)), action, SLOT(setEnabled(bool))); 549 connect(this, SIGNAL(canSave(bool)), action, SLOT(setEnabled(bool)));
527 m_keyReference->registerShortcut(action); 550 m_keyReference->registerShortcut(action);
528 menu->addAction(action); 551 menu->addAction(action);
529 toolbar->addAction(action); 552 toolbar->addAction(action);
530 553
531 icon = il.load("filesaveas"); 554 icon = il.load("filesaveas");
532 action = new QAction(icon, tr("Save Session &As..."), this); 555 action = new QAction(icon, tr("Save Session &As..."), this);
533 action->setShortcut(tr("Ctrl+Shift+S")); 556 action->setShortcut(tr("Ctrl+Shift+S"));
534 action->setStatusTip(tr("Save the current session into a new %1 session file").arg(QApplication::applicationName())); 557 action->setStatusTip(tr("Save the current session into a new %1 session file").arg(QApplication::applicationName()));
535 connect(action, SIGNAL(triggered()), this, SLOT(saveSessionAs())); 558 connect(action, SIGNAL(triggered()), this, SLOT(saveSessionAs()));
564 action->setStatusTip(tr("Export audio from selection into a data file")); 587 action->setStatusTip(tr("Export audio from selection into a data file"));
565 connect(action, SIGNAL(triggered()), this, SLOT(exportAudioData())); 588 connect(action, SIGNAL(triggered()), this, SLOT(exportAudioData()));
566 connect(this, SIGNAL(canExportAudio(bool)), action, SLOT(setEnabled(bool))); 589 connect(this, SIGNAL(canExportAudio(bool)), action, SLOT(setEnabled(bool)));
567 menu->addAction(action); 590 menu->addAction(action);
568 591
592 QAction *actionCreateIMAF = new QAction(tr("Export IMAF File..."), this);
593 actionCreateIMAF->setStatusTip(tr("Export selection as an IMAF file"));
594 menu->addAction(actionCreateIMAF);
595 connect(actionCreateIMAF,SIGNAL(triggered()),this,SLOT(exportIMAF()));
596
597 QAction *actionOpenIMAF = new QAction(tr("Import IMAF File..."), this);
598 actionOpenIMAF->setStatusTip(tr("Import IMAF file"));
599 menu->addAction(actionOpenIMAF);
600 connect(actionOpenIMAF,SIGNAL(triggered()),this,SLOT(importIMAF()));
601
569 menu->addSeparator(); 602 menu->addSeparator();
570 603
571 action = new QAction(tr("Import Annotation &Layer..."), this); 604 action = new QAction(tr("Import Annotation &Layer..."), this);
572 action->setShortcut(tr("Ctrl+L")); 605 action->setShortcut(tr("Ctrl+L"));
573 action->setStatusTip(tr("Import layer data from an existing file")); 606 action->setStatusTip(tr("Import layer data from an existing file"));
625 658
626 action = new QAction(tr("&Preferences..."), this); 659 action = new QAction(tr("&Preferences..."), this);
627 action->setStatusTip(tr("Adjust the application preferences")); 660 action->setStatusTip(tr("Adjust the application preferences"));
628 connect(action, SIGNAL(triggered()), this, SLOT(preferences())); 661 connect(action, SIGNAL(triggered()), this, SLOT(preferences()));
629 menu->addAction(action); 662 menu->addAction(action);
630 663
631 menu->addSeparator(); 664 menu->addSeparator();
632 action = new QAction(il.load("exit"), 665 action = new QAction(il.load("exit"),
633 tr("&Quit"), this); 666 tr("&Quit"), this);
634 action->setShortcut(tr("Ctrl+Q")); 667 action->setShortcut(tr("Ctrl+Q"));
635 action->setStatusTip(tr("Exit %1").arg(QApplication::applicationName())); 668 action->setStatusTip(tr("Exit %1").arg(QApplication::applicationName()));
712 connect(action, SIGNAL(triggered()), this, SLOT(selectAll())); 745 connect(action, SIGNAL(triggered()), this, SLOT(selectAll()));
713 connect(this, SIGNAL(canSelect(bool)), action, SLOT(setEnabled(bool))); 746 connect(this, SIGNAL(canSelect(bool)), action, SLOT(setEnabled(bool)));
714 m_keyReference->registerShortcut(action); 747 m_keyReference->registerShortcut(action);
715 menu->addAction(action); 748 menu->addAction(action);
716 m_rightButtonMenu->addAction(action); 749 m_rightButtonMenu->addAction(action);
717 750
718 action = new QAction(tr("Select &Visible Range"), this); 751 action = new QAction(tr("Select &Visible Range"), this);
719 action->setShortcut(tr("Ctrl+Shift+A")); 752 action->setShortcut(tr("Ctrl+Shift+A"));
720 action->setStatusTip(tr("Select the time range corresponding to the current window width")); 753 action->setStatusTip(tr("Select the time range corresponding to the current window width"));
721 connect(action, SIGNAL(triggered()), this, SLOT(selectVisible())); 754 connect(action, SIGNAL(triggered()), this, SLOT(selectVisible()));
722 connect(this, SIGNAL(canSelect(bool)), action, SLOT(setEnabled(bool))); 755 connect(this, SIGNAL(canSelect(bool)), action, SLOT(setEnabled(bool)));
723 m_keyReference->registerShortcut(action); 756 m_keyReference->registerShortcut(action);
724 menu->addAction(action); 757 menu->addAction(action);
725 758
726 action = new QAction(tr("Select to &Start"), this); 759 action = new QAction(tr("Select to &Start"), this);
727 action->setShortcut(tr("Shift+Left")); 760 action->setShortcut(tr("Shift+Left"));
728 action->setStatusTip(tr("Select from the start of the session to the current playback position")); 761 action->setStatusTip(tr("Select from the start of the session to the current playback position"));
729 connect(action, SIGNAL(triggered()), this, SLOT(selectToStart())); 762 connect(action, SIGNAL(triggered()), this, SLOT(selectToStart()));
730 connect(this, SIGNAL(canSelect(bool)), action, SLOT(setEnabled(bool))); 763 connect(this, SIGNAL(canSelect(bool)), action, SLOT(setEnabled(bool)));
731 m_keyReference->registerShortcut(action); 764 m_keyReference->registerShortcut(action);
732 menu->addAction(action); 765 menu->addAction(action);
733 766
734 action = new QAction(tr("Select to &End"), this); 767 action = new QAction(tr("Select to &End"), this);
735 action->setShortcut(tr("Shift+Right")); 768 action->setShortcut(tr("Shift+Right"));
736 action->setStatusTip(tr("Select from the current playback position to the end of the session")); 769 action->setStatusTip(tr("Select from the current playback position to the end of the session"));
737 connect(action, SIGNAL(triggered()), this, SLOT(selectToEnd())); 770 connect(action, SIGNAL(triggered()), this, SLOT(selectToEnd()));
738 connect(this, SIGNAL(canSelect(bool)), action, SLOT(setEnabled(bool))); 771 connect(this, SIGNAL(canSelect(bool)), action, SLOT(setEnabled(bool)));
833 866
834 action = new QAction(tr("Set Numbering Counters..."), this); 867 action = new QAction(tr("Set Numbering Counters..."), this);
835 action->setStatusTip(tr("Set the counters used for counter-based labelling")); 868 action->setStatusTip(tr("Set the counters used for counter-based labelling"));
836 connect(action, SIGNAL(triggered()), this, SLOT(setInstantsCounters())); 869 connect(action, SIGNAL(triggered()), this, SLOT(setInstantsCounters()));
837 menu->addAction(action); 870 menu->addAction(action);
838 871
839 action = new QAction(tr("Renumber Selected Instants"), this); 872 action = new QAction(tr("Renumber Selected Instants"), this);
840 action->setStatusTip(tr("Renumber the selected instants using the current labelling scheme")); 873 action->setStatusTip(tr("Renumber the selected instants using the current labelling scheme"));
841 connect(action, SIGNAL(triggered()), this, SLOT(renumberInstants())); 874 connect(action, SIGNAL(triggered()), this, SLOT(renumberInstants()));
842 connect(this, SIGNAL(canRenumberInstants(bool)), action, SLOT(setEnabled(bool))); 875 connect(this, SIGNAL(canRenumberInstants(bool)), action, SLOT(setEnabled(bool)));
843 // m_keyReference->registerShortcut(action); 876 // m_keyReference->registerShortcut(action);
862 m_scrollLeftAction->setStatusTip(tr("Scroll the current pane to the left")); 895 m_scrollLeftAction->setStatusTip(tr("Scroll the current pane to the left"));
863 connect(m_scrollLeftAction, SIGNAL(triggered()), this, SLOT(scrollLeft())); 896 connect(m_scrollLeftAction, SIGNAL(triggered()), this, SLOT(scrollLeft()));
864 connect(this, SIGNAL(canScroll(bool)), m_scrollLeftAction, SLOT(setEnabled(bool))); 897 connect(this, SIGNAL(canScroll(bool)), m_scrollLeftAction, SLOT(setEnabled(bool)));
865 m_keyReference->registerShortcut(m_scrollLeftAction); 898 m_keyReference->registerShortcut(m_scrollLeftAction);
866 menu->addAction(m_scrollLeftAction); 899 menu->addAction(m_scrollLeftAction);
867 900
868 m_scrollRightAction = new QAction(tr("Scroll &Right"), this); 901 m_scrollRightAction = new QAction(tr("Scroll &Right"), this);
869 m_scrollRightAction->setShortcut(tr("Right")); 902 m_scrollRightAction->setShortcut(tr("Right"));
870 m_scrollRightAction->setStatusTip(tr("Scroll the current pane to the right")); 903 m_scrollRightAction->setStatusTip(tr("Scroll the current pane to the right"));
871 connect(m_scrollRightAction, SIGNAL(triggered()), this, SLOT(scrollRight())); 904 connect(m_scrollRightAction, SIGNAL(triggered()), this, SLOT(scrollRight()));
872 connect(this, SIGNAL(canScroll(bool)), m_scrollRightAction, SLOT(setEnabled(bool))); 905 connect(this, SIGNAL(canScroll(bool)), m_scrollRightAction, SLOT(setEnabled(bool)));
873 m_keyReference->registerShortcut(m_scrollRightAction); 906 m_keyReference->registerShortcut(m_scrollRightAction);
874 menu->addAction(m_scrollRightAction); 907 menu->addAction(m_scrollRightAction);
875 908
876 action = new QAction(tr("&Jump Left"), this); 909 action = new QAction(tr("&Jump Left"), this);
877 action->setShortcut(tr("Ctrl+Left")); 910 action->setShortcut(tr("Ctrl+Left"));
878 action->setStatusTip(tr("Scroll the current pane a big step to the left")); 911 action->setStatusTip(tr("Scroll the current pane a big step to the left"));
879 connect(action, SIGNAL(triggered()), this, SLOT(jumpLeft())); 912 connect(action, SIGNAL(triggered()), this, SLOT(jumpLeft()));
880 connect(this, SIGNAL(canScroll(bool)), action, SLOT(setEnabled(bool))); 913 connect(this, SIGNAL(canScroll(bool)), action, SLOT(setEnabled(bool)));
881 m_keyReference->registerShortcut(action); 914 m_keyReference->registerShortcut(action);
882 menu->addAction(action); 915 menu->addAction(action);
883 916
884 action = new QAction(tr("J&ump Right"), this); 917 action = new QAction(tr("J&ump Right"), this);
885 action->setShortcut(tr("Ctrl+Right")); 918 action->setShortcut(tr("Ctrl+Right"));
886 action->setStatusTip(tr("Scroll the current pane a big step to the right")); 919 action->setStatusTip(tr("Scroll the current pane a big step to the right"));
887 connect(action, SIGNAL(triggered()), this, SLOT(jumpRight())); 920 connect(action, SIGNAL(triggered()), this, SLOT(jumpRight()));
888 connect(this, SIGNAL(canScroll(bool)), action, SLOT(setEnabled(bool))); 921 connect(this, SIGNAL(canScroll(bool)), action, SLOT(setEnabled(bool)));
894 action->setStatusTip(tr("Scroll the current pane to the left without moving the playback cursor or other panes")); 927 action->setStatusTip(tr("Scroll the current pane to the left without moving the playback cursor or other panes"));
895 connect(action, SIGNAL(triggered()), this, SLOT(peekLeft())); 928 connect(action, SIGNAL(triggered()), this, SLOT(peekLeft()));
896 connect(this, SIGNAL(canScroll(bool)), action, SLOT(setEnabled(bool))); 929 connect(this, SIGNAL(canScroll(bool)), action, SLOT(setEnabled(bool)));
897 m_keyReference->registerShortcut(action); 930 m_keyReference->registerShortcut(action);
898 menu->addAction(action); 931 menu->addAction(action);
899 932
900 action = new QAction(tr("Peek Right"), this); 933 action = new QAction(tr("Peek Right"), this);
901 action->setShortcut(tr("Alt+Right")); 934 action->setShortcut(tr("Alt+Right"));
902 action->setStatusTip(tr("Scroll the current pane to the right without moving the playback cursor or other panes")); 935 action->setStatusTip(tr("Scroll the current pane to the right without moving the playback cursor or other panes"));
903 connect(action, SIGNAL(triggered()), this, SLOT(peekRight())); 936 connect(action, SIGNAL(triggered()), this, SLOT(peekRight()));
904 connect(this, SIGNAL(canScroll(bool)), action, SLOT(setEnabled(bool))); 937 connect(this, SIGNAL(canScroll(bool)), action, SLOT(setEnabled(bool)));
915 m_zoomInAction->setStatusTip(tr("Increase the zoom level")); 948 m_zoomInAction->setStatusTip(tr("Increase the zoom level"));
916 connect(m_zoomInAction, SIGNAL(triggered()), this, SLOT(zoomIn())); 949 connect(m_zoomInAction, SIGNAL(triggered()), this, SLOT(zoomIn()));
917 connect(this, SIGNAL(canZoom(bool)), m_zoomInAction, SLOT(setEnabled(bool))); 950 connect(this, SIGNAL(canZoom(bool)), m_zoomInAction, SLOT(setEnabled(bool)));
918 m_keyReference->registerShortcut(m_zoomInAction); 951 m_keyReference->registerShortcut(m_zoomInAction);
919 menu->addAction(m_zoomInAction); 952 menu->addAction(m_zoomInAction);
920 953
921 m_zoomOutAction = new QAction(il.load("zoom-out"), 954 m_zoomOutAction = new QAction(il.load("zoom-out"),
922 tr("Zoom &Out"), this); 955 tr("Zoom &Out"), this);
923 m_zoomOutAction->setShortcut(tr("Down")); 956 m_zoomOutAction->setShortcut(tr("Down"));
924 m_zoomOutAction->setStatusTip(tr("Decrease the zoom level")); 957 m_zoomOutAction->setStatusTip(tr("Decrease the zoom level"));
925 connect(m_zoomOutAction, SIGNAL(triggered()), this, SLOT(zoomOut())); 958 connect(m_zoomOutAction, SIGNAL(triggered()), this, SLOT(zoomOut()));
926 connect(this, SIGNAL(canZoom(bool)), m_zoomOutAction, SLOT(setEnabled(bool))); 959 connect(this, SIGNAL(canZoom(bool)), m_zoomOutAction, SLOT(setEnabled(bool)));
927 m_keyReference->registerShortcut(m_zoomOutAction); 960 m_keyReference->registerShortcut(m_zoomOutAction);
928 menu->addAction(m_zoomOutAction); 961 menu->addAction(m_zoomOutAction);
929 962
930 action = new QAction(tr("Restore &Default Zoom"), this); 963 action = new QAction(tr("Restore &Default Zoom"), this);
931 action->setStatusTip(tr("Restore the zoom level to the default")); 964 action->setStatusTip(tr("Restore the zoom level to the default"));
932 connect(action, SIGNAL(triggered()), this, SLOT(zoomDefault())); 965 connect(action, SIGNAL(triggered()), this, SLOT(zoomDefault()));
933 connect(this, SIGNAL(canZoom(bool)), action, SLOT(setEnabled(bool))); 966 connect(this, SIGNAL(canZoom(bool)), action, SLOT(setEnabled(bool)));
934 menu->addAction(action); 967 menu->addAction(action);
975 action->setCheckable(true); 1008 action->setCheckable(true);
976 action->setChecked(mode == ViewManager::NoOverlays); 1009 action->setChecked(mode == ViewManager::NoOverlays);
977 overlayGroup->addAction(action); 1010 overlayGroup->addAction(action);
978 m_keyReference->registerShortcut(action); 1011 m_keyReference->registerShortcut(action);
979 menu->addAction(action); 1012 menu->addAction(action);
980 1013
981 action = new QAction(tr("Show &Minimal Overlays"), this); 1014 action = new QAction(tr("Show &Minimal Overlays"), this);
982 action->setShortcut(tr("9")); 1015 action->setShortcut(tr("9"));
983 action->setStatusTip(tr("Show times and basic scale")); 1016 action->setStatusTip(tr("Show times and basic scale"));
984 connect(action, SIGNAL(triggered()), this, SLOT(showMinimalOverlays())); 1017 connect(action, SIGNAL(triggered()), this, SLOT(showMinimalOverlays()));
985 action->setCheckable(true); 1018 action->setCheckable(true);
986 action->setChecked(mode == ViewManager::StandardOverlays); 1019 action->setChecked(mode == ViewManager::StandardOverlays);
987 overlayGroup->addAction(action); 1020 overlayGroup->addAction(action);
988 m_keyReference->registerShortcut(action); 1021 m_keyReference->registerShortcut(action);
989 menu->addAction(action); 1022 menu->addAction(action);
990 1023
991 action = new QAction(tr("Show &All Overlays"), this); 1024 action = new QAction(tr("Show &All Overlays"), this);
992 action->setShortcut(tr("8")); 1025 action->setShortcut(tr("8"));
993 action->setStatusTip(tr("Show times, layer names, and scale")); 1026 action->setStatusTip(tr("Show times, layer names, and scale"));
994 connect(action, SIGNAL(triggered()), this, SLOT(showAllOverlays())); 1027 connect(action, SIGNAL(triggered()), this, SLOT(showAllOverlays()));
995 action->setCheckable(true); 1028 action->setCheckable(true);
997 overlayGroup->addAction(action); 1030 overlayGroup->addAction(action);
998 m_keyReference->registerShortcut(action); 1031 m_keyReference->registerShortcut(action);
999 menu->addAction(action); 1032 menu->addAction(action);
1000 1033
1001 menu->addSeparator(); 1034 menu->addSeparator();
1002 1035
1003 action = new QAction(tr("Show &Zoom Wheels"), this); 1036 action = new QAction(tr("Show &Zoom Wheels"), this);
1004 action->setShortcut(tr("Z")); 1037 action->setShortcut(tr("Z"));
1005 action->setStatusTip(tr("Show thumbwheels for zooming horizontally and vertically")); 1038 action->setStatusTip(tr("Show thumbwheels for zooming horizontally and vertically"));
1006 connect(action, SIGNAL(triggered()), this, SLOT(toggleZoomWheels())); 1039 connect(action, SIGNAL(triggered()), this, SLOT(toggleZoomWheels()));
1007 action->setCheckable(true); 1040 action->setCheckable(true);
1065 1098
1066 void 1099 void
1067 MainWindow::setupPaneAndLayerMenus() 1100 MainWindow::setupPaneAndLayerMenus()
1068 { 1101 {
1069 if (m_paneMenu) { 1102 if (m_paneMenu) {
1070 m_paneActions.clear(); 1103 m_paneActions.clear();
1071 m_paneMenu->clear(); 1104 m_paneMenu->clear();
1072 } else { 1105 } else {
1073 m_paneMenu = menuBar()->addMenu(tr("&Pane")); 1106 m_paneMenu = menuBar()->addMenu(tr("&Pane"));
1074 m_paneMenu->setTearOffEnabled(true); 1107 m_paneMenu->setTearOffEnabled(true);
1075 } 1108 }
1076 1109
1077 if (m_layerMenu) { 1110 if (m_layerMenu) {
1078 m_layerActions.clear(); 1111 m_layerActions.clear();
1079 m_layerMenu->clear(); 1112 m_layerMenu->clear();
1080 } else { 1113 } else {
1081 m_layerMenu = menuBar()->addMenu(tr("&Layer")); 1114 m_layerMenu = menuBar()->addMenu(tr("&Layer"));
1082 m_layerMenu->setTearOffEnabled(true); 1115 m_layerMenu->setTearOffEnabled(true);
1083 } 1116 }
1084 1117
1085 if (m_rightButtonLayerMenu) { 1118 if (m_rightButtonLayerMenu) {
1086 m_rightButtonLayerMenu->clear(); 1119 m_rightButtonLayerMenu->clear();
1110 menu = m_layerMenu; 1143 menu = m_layerMenu;
1111 1144
1112 // menu->addSeparator(); 1145 // menu->addSeparator();
1113 1146
1114 LayerFactory::LayerTypeSet emptyLayerTypes = 1147 LayerFactory::LayerTypeSet emptyLayerTypes =
1115 LayerFactory::getInstance()->getValidEmptyLayerTypes(); 1148 LayerFactory::getInstance()->getValidEmptyLayerTypes();
1116 1149
1117 for (LayerFactory::LayerTypeSet::iterator i = emptyLayerTypes.begin(); 1150 for (LayerFactory::LayerTypeSet::iterator i = emptyLayerTypes.begin();
1118 i != emptyLayerTypes.end(); ++i) { 1151 i != emptyLayerTypes.end(); ++i) {
1119 1152
1120 QIcon icon; 1153 QIcon icon;
1121 QString mainText, tipText, channelText; 1154 QString mainText, tipText, channelText;
1122 LayerFactory::LayerType type = *i; 1155 LayerFactory::LayerType type = *i;
1123 QString name = LayerFactory::getInstance()->getLayerPresentationName(type); 1156 QString name = LayerFactory::getInstance()->getLayerPresentationName(type);
1124 1157
1125 icon = il.load(LayerFactory::getInstance()->getLayerIconName(type)); 1158 icon = il.load(LayerFactory::getInstance()->getLayerIconName(type));
1126 1159
1127 mainText = tr("Add New %1 Layer").arg(name); 1160 mainText = tr("Add New %1 Layer").arg(name);
1128 tipText = tr("Add a new empty layer of type %1").arg(name); 1161 tipText = tr("Add a new empty layer of type %1").arg(name);
1129 1162
1130 action = new QAction(icon, mainText, this); 1163 action = new QAction(icon, mainText, this);
1131 action->setStatusTip(tipText); 1164 action->setStatusTip(tipText);
1132 1165
1133 if (type == LayerFactory::Text) { 1166 if (type == LayerFactory::Text) {
1134 action->setShortcut(tr("T")); 1167 action->setShortcut(tr("T"));
1135 m_keyReference->registerShortcut(action); 1168 m_keyReference->registerShortcut(action);
1136 } 1169 }
1137 1170 connect(action, SIGNAL(triggered()), this, SLOT(addLayer()));
1138 connect(action, SIGNAL(triggered()), this, SLOT(addLayer())); 1171 connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool)));
1139 connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); 1172 m_layerActions[action] = LayerConfiguration(type);
1140 m_layerActions[action] = LayerConfiguration(type); 1173 menu->addAction(action);
1141 menu->addAction(action); 1174 m_rightButtonLayerMenu->addAction(action);
1142 m_rightButtonLayerMenu->addAction(action); 1175 }
1143 } 1176
1144
1145 m_rightButtonLayerMenu->addSeparator(); 1177 m_rightButtonLayerMenu->addSeparator();
1146 menu->addSeparator(); 1178 menu->addSeparator();
1147 1179
1148 LayerFactory::LayerType backgroundTypes[] = { 1180 LayerFactory::LayerType backgroundTypes[] = {
1149 LayerFactory::Waveform, 1181 LayerFactory::Waveform,
1150 LayerFactory::Spectrogram, 1182 LayerFactory::Spectrogram,
1151 LayerFactory::MelodicRangeSpectrogram, 1183 LayerFactory::MelodicRangeSpectrogram,
1152 LayerFactory::PeakFrequencySpectrogram, 1184 LayerFactory::PeakFrequencySpectrogram,
1153 LayerFactory::Spectrum 1185 LayerFactory::Spectrum
1154 }; 1186 };
1155 1187
1156 std::vector<Model *> models; 1188 std::vector<Model *> models;
1157 if (m_document) models = m_document->getTransformInputModels(); 1189 if (m_document) models = m_document->getTransformInputModels();
1159 if (models.empty()) { 1191 if (models.empty()) {
1160 models.push_back(getMainModel()); // probably 0 1192 models.push_back(getMainModel()); // probably 0
1161 } 1193 }
1162 1194
1163 for (unsigned int i = 0; 1195 for (unsigned int i = 0;
1164 i < sizeof(backgroundTypes)/sizeof(backgroundTypes[0]); ++i) { 1196 i < sizeof(backgroundTypes)/sizeof(backgroundTypes[0]); ++i) {
1165 1197
1166 const int paneMenuType = 0, layerMenuType = 1; 1198 const int paneMenuType = 0, layerMenuType = 1;
1167 1199
1168 for (int menuType = paneMenuType; menuType <= layerMenuType; ++menuType) { 1200 for (int menuType = paneMenuType; menuType <= layerMenuType; ++menuType) {
1169 1201
1170 if (menuType == paneMenuType) menu = m_paneMenu; 1202 if (menuType == paneMenuType) menu = m_paneMenu;
1171 else menu = m_layerMenu; 1203 else menu = m_layerMenu;
1172 1204
1173 QMenu *submenu = 0; 1205 QMenu *submenu = 0;
1174 1206
1175 QIcon icon; 1207 QIcon icon;
1176 QString mainText, shortcutText, tipText, channelText; 1208 QString mainText, shortcutText, tipText, channelText;
1177 LayerFactory::LayerType type = backgroundTypes[i]; 1209 LayerFactory::LayerType type = backgroundTypes[i];
1178 bool mono = true; 1210 bool mono = true;
1181 // handling all layer types (-Wall is OK with this because of the 1213 // handling all layer types (-Wall is OK with this because of the
1182 // default but the stricter level insists) 1214 // default but the stricter level insists)
1183 #pragma GCC diagnostic ignored "-Wswitch-enum" 1215 #pragma GCC diagnostic ignored "-Wswitch-enum"
1184 1216
1185 switch (type) { 1217 switch (type) {
1186 1218
1187 case LayerFactory::Waveform: 1219 case LayerFactory::Waveform:
1188 icon = il.load("waveform"); 1220 icon = il.load("waveform");
1189 mainText = tr("Add &Waveform"); 1221 mainText = tr("Add &Waveform");
1190 if (menuType == paneMenuType) { 1222 if (menuType == paneMenuType) {
1191 shortcutText = tr("W"); 1223 shortcutText = tr("W");
1194 shortcutText = tr("Shift+W"); 1226 shortcutText = tr("Shift+W");
1195 tipText = tr("Add a new layer showing a waveform view"); 1227 tipText = tr("Add a new layer showing a waveform view");
1196 } 1228 }
1197 mono = false; 1229 mono = false;
1198 break; 1230 break;
1199 1231
1200 case LayerFactory::Spectrogram: 1232 case LayerFactory::Spectrogram:
1201 icon = il.load("spectrogram"); 1233 icon = il.load("spectrogram");
1202 mainText = tr("Add Spectro&gram"); 1234 mainText = tr("Add Spectro&gram");
1203 if (menuType == paneMenuType) { 1235 if (menuType == paneMenuType) {
1204 shortcutText = tr("G"); 1236 shortcutText = tr("G");
1206 } else { 1238 } else {
1207 shortcutText = tr("Shift+G"); 1239 shortcutText = tr("Shift+G");
1208 tipText = tr("Add a new layer showing a spectrogram"); 1240 tipText = tr("Add a new layer showing a spectrogram");
1209 } 1241 }
1210 break; 1242 break;
1211 1243
1212 case LayerFactory::MelodicRangeSpectrogram: 1244 case LayerFactory::MelodicRangeSpectrogram:
1213 icon = il.load("spectrogram"); 1245 icon = il.load("spectrogram");
1214 mainText = tr("Add &Melodic Range Spectrogram"); 1246 mainText = tr("Add &Melodic Range Spectrogram");
1215 if (menuType == paneMenuType) { 1247 if (menuType == paneMenuType) {
1216 shortcutText = tr("M"); 1248 shortcutText = tr("M");
1218 } else { 1250 } else {
1219 shortcutText = tr("Shift+M"); 1251 shortcutText = tr("Shift+M");
1220 tipText = tr("Add a new layer showing a spectrogram set up for an overview of note pitches"); 1252 tipText = tr("Add a new layer showing a spectrogram set up for an overview of note pitches");
1221 } 1253 }
1222 break; 1254 break;
1223 1255
1224 case LayerFactory::PeakFrequencySpectrogram: 1256 case LayerFactory::PeakFrequencySpectrogram:
1225 icon = il.load("spectrogram"); 1257 icon = il.load("spectrogram");
1226 mainText = tr("Add Pea&k Frequency Spectrogram"); 1258 mainText = tr("Add Pea&k Frequency Spectrogram");
1227 if (menuType == paneMenuType) { 1259 if (menuType == paneMenuType) {
1228 shortcutText = tr("K"); 1260 shortcutText = tr("K");
1230 } else { 1262 } else {
1231 shortcutText = tr("Shift+K"); 1263 shortcutText = tr("Shift+K");
1232 tipText = tr("Add a new layer showing a spectrogram set up for tracking frequencies"); 1264 tipText = tr("Add a new layer showing a spectrogram set up for tracking frequencies");
1233 } 1265 }
1234 break; 1266 break;
1235 1267
1236 case LayerFactory::Spectrum: 1268 case LayerFactory::Spectrum:
1237 icon = il.load("spectrum"); 1269 icon = il.load("spectrum");
1238 mainText = tr("Add Spectr&um"); 1270 mainText = tr("Add Spectr&um");
1239 if (menuType == paneMenuType) { 1271 if (menuType == paneMenuType) {
1240 shortcutText = tr("U"); 1272 shortcutText = tr("U");
1242 } else { 1274 } else {
1243 shortcutText = tr("Shift+U"); 1275 shortcutText = tr("Shift+U");
1244 tipText = tr("Add a new layer showing a frequency spectrum"); 1276 tipText = tr("Add a new layer showing a frequency spectrum");
1245 } 1277 }
1246 break; 1278 break;
1247 1279
1248 default: break; 1280 default: break;
1249 } 1281 }
1250 1282
1251 std::vector<Model *> candidateModels = models; 1283 std::vector<Model *> candidateModels = models;
1252 1284
1253 for (std::vector<Model *>::iterator mi = 1285 for (std::vector<Model *>::iterator mi =
1254 candidateModels.begin(); 1286 candidateModels.begin();
1255 mi != candidateModels.end(); ++mi) { 1287 mi != candidateModels.end(); ++mi) {
1256 1288
1257 Model *model = *mi; 1289 Model *model = *mi;
1258 1290
1259 int channels = 0; 1291 int channels = 0;
1260 if (model) { 1292 if (model) {
1261 DenseTimeValueModel *dtvm = 1293 DenseTimeValueModel *dtvm =
1296 } 1328 }
1297 if (shortcutText != "") { 1329 if (shortcutText != "") {
1298 m_keyReference->registerShortcut(action); 1330 m_keyReference->registerShortcut(action);
1299 } 1331 }
1300 menu->addAction(action); 1332 menu->addAction(action);
1301 1333
1302 } else { 1334 } else {
1303 1335
1304 if (!submenu) { 1336 if (!submenu) {
1305 submenu = menu->addMenu(mainText); 1337 submenu = menu->addMenu(mainText);
1306 submenu->setTearOffEnabled(true); 1338 submenu->setTearOffEnabled(true);
1307 } else if (isDefault) { 1339 } else if (isDefault) {
1308 submenu->addSeparator(); 1340 submenu->addSeparator();
1326 } 1358 }
1327 1359
1328 if (isDefault) { 1360 if (isDefault) {
1329 action = new QAction(icon, actionText, this); 1361 action = new QAction(icon, actionText, this);
1330 if (!model || model == getMainModel()) { 1362 if (!model || model == getMainModel()) {
1331 action->setShortcut(shortcutText); 1363 action->setShortcut(shortcutText);
1332 } 1364 }
1333 } else { 1365 } else {
1334 action = new QAction(actionText, this); 1366 action = new QAction(actionText, this);
1335 } 1367 }
1336 1368
1367 connect(this, SIGNAL(canAddLayer(bool)), 1399 connect(this, SIGNAL(canAddLayer(bool)),
1368 action, SLOT(setEnabled(bool))); 1400 action, SLOT(setEnabled(bool)));
1369 m_layerActions[action] = LayerConfiguration(type, 0, 0); 1401 m_layerActions[action] = LayerConfiguration(type, 0, 0);
1370 m_rightButtonLayerMenu->addAction(action); 1402 m_rightButtonLayerMenu->addAction(action);
1371 } 1403 }
1372 } 1404 }
1373 } 1405 }
1374 } 1406 }
1375 } 1407 }
1376 1408
1377 m_rightButtonLayerMenu->addSeparator(); 1409 m_rightButtonLayerMenu->addSeparator();
1378 1410
1379 menu = m_paneMenu; 1411 menu = m_paneMenu;
1484 if (m_transformsMenu) { 1516 if (m_transformsMenu) {
1485 m_transformActions.clear(); 1517 m_transformActions.clear();
1486 m_transformActionsReverse.clear(); 1518 m_transformActionsReverse.clear();
1487 m_transformsMenu->clear(); 1519 m_transformsMenu->clear();
1488 } else { 1520 } else {
1489 m_transformsMenu = menuBar()->addMenu(tr("&Transform")); 1521 m_transformsMenu = menuBar()->addMenu(tr("&Transform"));
1490 m_transformsMenu->setTearOffEnabled(true); 1522 m_transformsMenu->setTearOffEnabled(true);
1491 m_transformsMenu->setSeparatorsCollapsible(true); 1523 m_transformsMenu->setSeparatorsCollapsible(true);
1492 } 1524 }
1493 1525
1494 TransformFactory *factory = TransformFactory::getInstance(); 1526 TransformFactory *factory = TransformFactory::getInstance();
1510 connect(&m_recentTransforms, SIGNAL(recentChanged()), 1542 connect(&m_recentTransforms, SIGNAL(recentChanged()),
1511 this, SLOT(setupRecentTransformsMenu())); 1543 this, SLOT(setupRecentTransformsMenu()));
1512 1544
1513 m_transformsMenu->addSeparator(); 1545 m_transformsMenu->addSeparator();
1514 m_rightButtonTransformsMenu->addSeparator(); 1546 m_rightButtonTransformsMenu->addSeparator();
1515 1547
1516 for (vector<TransformDescription::Type>::iterator i = types.begin(); 1548 for (vector<TransformDescription::Type>::iterator i = types.begin();
1517 i != types.end(); ++i) { 1549 i != types.end(); ++i) {
1518 1550
1519 if (i != types.begin()) { 1551 if (i != types.begin()) {
1520 m_transformsMenu->addSeparator(); 1552 m_transformsMenu->addSeparator();
1612 seenNames.insert(name); 1644 seenNames.insert(name);
1613 } 1645 }
1614 } 1646 }
1615 1647
1616 for (unsigned int i = 0; i < transforms.size(); ++i) { 1648 for (unsigned int i = 0; i < transforms.size(); ++i) {
1617 1649
1618 QString name = transforms[i].name; 1650 QString name = transforms[i].name;
1619 if (name == "") name = transforms[i].identifier; 1651 if (name == "") name = transforms[i].identifier;
1620 1652
1621 // cerr << "Plugin Name: " << name << endl; 1653 // cerr << "Plugin Name: " << name << endl;
1622 1654
1623 TransformDescription::Type type = transforms[i].type; 1655 TransformDescription::Type type = transforms[i].type;
1624 QString typeStr = factory->getTransformTypeName(type); 1656 QString typeStr = factory->getTransformTypeName(type);
1641 else name = QString("%1: %2") 1673 else name = QString("%1: %2")
1642 .arg(pluginName) 1674 .arg(pluginName)
1643 .arg(output); 1675 .arg(output);
1644 } 1676 }
1645 1677
1646 QAction *action = new QAction(tr("%1...").arg(name), this); 1678 QAction *action = new QAction(tr("%1...").arg(name), this);
1647 connect(action, SIGNAL(triggered()), this, SLOT(addLayer())); 1679 connect(action, SIGNAL(triggered()), this, SLOT(addLayer()));
1648 m_transformActions[action] = transforms[i].identifier; 1680 m_transformActions[action] = transforms[i].identifier;
1649 m_transformActionsReverse[transforms[i].identifier] = action; 1681 m_transformActionsReverse[transforms[i].identifier] = action;
1650 connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); 1682 connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool)));
1651 1683
1652 action->setStatusTip(transforms[i].longDescription); 1684 action->setStatusTip(transforms[i].longDescription);
1653 1685
1654 if (categoryMenus[type].find(category) == categoryMenus[type].end()) { 1686 if (categoryMenus[type].find(category) == categoryMenus[type].end()) {
1655 cerr << "WARNING: MainWindow::setupMenus: Internal error: " 1687 cerr << "WARNING: MainWindow::setupMenus: Internal error: "
1684 parentMenu->setTearOffEnabled(true); 1716 parentMenu->setTearOffEnabled(true);
1685 1717
1686 if (output == "") { 1718 if (output == "") {
1687 parentMenu->addAction(pluginName, action); 1719 parentMenu->addAction(pluginName, action);
1688 } else { 1720 } else {
1689 pluginNameMenus[type][pluginName] = 1721 pluginNameMenus[type][pluginName] =
1690 parentMenu->addMenu(pluginName); 1722 parentMenu->addMenu(pluginName);
1691 connect(this, SIGNAL(canAddLayer(bool)), 1723 connect(this, SIGNAL(canAddLayer(bool)),
1692 pluginNameMenus[type][pluginName], 1724 pluginNameMenus[type][pluginName],
1693 SLOT(setEnabled(bool))); 1725 SLOT(setEnabled(bool)));
1694 } 1726 }
1723 void 1755 void
1724 MainWindow::setupHelpMenu() 1756 MainWindow::setupHelpMenu()
1725 { 1757 {
1726 QMenu *menu = menuBar()->addMenu(tr("&Help")); 1758 QMenu *menu = menuBar()->addMenu(tr("&Help"));
1727 menu->setTearOffEnabled(true); 1759 menu->setTearOffEnabled(true);
1728 1760
1729 m_keyReference->setCategory(tr("Help")); 1761 m_keyReference->setCategory(tr("Help"));
1730 1762
1731 IconLoader il; 1763 IconLoader il;
1732 1764
1733 QString name = QApplication::applicationName(); 1765 QString name = QApplication::applicationName();
1734 1766
1735 QAction *action = new QAction(il.load("help"), 1767 QAction *action = new QAction(il.load("help"),
1736 tr("&Help Reference"), this); 1768 tr("&Help Reference"), this);
1737 action->setShortcut(tr("F1")); 1769 action->setShortcut(tr("F1"));
1738 action->setStatusTip(tr("Open the %1 reference manual").arg(name)); 1770 action->setStatusTip(tr("Open the %1 reference manual").arg(name));
1739 connect(action, SIGNAL(triggered()), this, SLOT(help())); 1771 connect(action, SIGNAL(triggered()), this, SLOT(help()));
1740 m_keyReference->registerShortcut(action); 1772 m_keyReference->registerShortcut(action);
1741 menu->addAction(action); 1773 menu->addAction(action);
1742 1774
1743 action = new QAction(tr("&Key and Mouse Reference"), this); 1775 action = new QAction(tr("&Key and Mouse Reference"), this);
1744 action->setShortcut(tr("F2")); 1776 action->setShortcut(tr("F2"));
1745 action->setStatusTip(tr("Open a window showing the keystrokes you can use in %1").arg(name)); 1777 action->setStatusTip(tr("Open a window showing the keystrokes you can use in %1").arg(name));
1746 connect(action, SIGNAL(triggered()), this, SLOT(keyReference())); 1778 connect(action, SIGNAL(triggered()), this, SLOT(keyReference()));
1747 m_keyReference->registerShortcut(action); 1779 m_keyReference->registerShortcut(action);
1748 menu->addAction(action); 1780 menu->addAction(action);
1749 1781
1750 action = new QAction(tr("%1 on the &Web").arg(name), this); 1782 action = new QAction(tr("%1 on the &Web").arg(name), this);
1751 action->setStatusTip(tr("Open the %1 website").arg(name)); 1783 action->setStatusTip(tr("Open the %1 website").arg(name));
1752 connect(action, SIGNAL(triggered()), this, SLOT(website())); 1784 connect(action, SIGNAL(triggered()), this, SLOT(website()));
1753 menu->addAction(action); 1785 menu->addAction(action);
1754 1786
1755 action = new QAction(tr("&About %1").arg(name), this); 1787 action = new QAction(tr("&About %1").arg(name), this);
1756 action->setStatusTip(tr("Show information about %1").arg(name)); 1788 action->setStatusTip(tr("Show information about %1").arg(name));
1757 connect(action, SIGNAL(triggered()), this, SLOT(about())); 1789 connect(action, SIGNAL(triggered()), this, SLOT(about()));
1758 menu->addAction(action); 1790 menu->addAction(action);
1759 } 1791 }
1760 1792
1761 void 1793 void
1762 MainWindow::setupRecentFilesMenu() 1794 MainWindow::setupRecentFilesMenu()
1763 { 1795 {
1764 m_recentFilesMenu->clear(); 1796 m_recentFilesMenu->clear();
1765 vector<QString> files = m_recentFiles.getRecent(); 1797 vector<QString> files = m_recentFiles.getRecent();
1766 for (size_t i = 0; i < files.size(); ++i) { 1798 for (size_t i = 0; i < files.size(); ++i) {
1767 QAction *action = new QAction(files[i], this); 1799 QAction *action = new QAction(files[i], this);
1768 connect(action, SIGNAL(triggered()), this, SLOT(openRecentFile())); 1800 connect(action, SIGNAL(triggered()), this, SLOT(openRecentFile()));
1769 if (i == 0) { 1801 if (i == 0) {
1770 action->setShortcut(tr("Ctrl+R")); 1802 action->setShortcut(tr("Ctrl+R"));
1771 m_keyReference->registerShortcut 1803 m_keyReference->registerShortcut
1772 (tr("Re-open"), 1804 (tr("Re-open"),
1773 action->shortcut().toString(), 1805 action->shortcut().toString(),
1774 tr("Re-open the current or most recently opened file")); 1806 tr("Re-open the current or most recently opened file"));
1775 } 1807 }
1776 m_recentFilesMenu->addAction(action); 1808 m_recentFilesMenu->addAction(action);
1777 } 1809 }
1778 } 1810 }
1779 1811
1780 void 1812 void
1781 MainWindow::setupTemplatesMenu() 1813 MainWindow::setupTemplatesMenu()
1849 ti->second->shortcut().toString(), 1881 ti->second->shortcut().toString(),
1850 tr("Re-select the most recently run transform")); 1882 tr("Re-select the most recently run transform"));
1851 } else { 1883 } else {
1852 ti->second->setShortcut(QString("")); 1884 ti->second->setShortcut(QString(""));
1853 } 1885 }
1854 m_recentTransformsMenu->addAction(ti->second); 1886 m_recentTransformsMenu->addAction(ti->second);
1855 } 1887 }
1856 } 1888 }
1857 1889
1858 void 1890 void
1859 MainWindow::setupExistingLayersMenus() 1891 MainWindow::setupExistingLayersMenus()
1890 continue; 1922 continue;
1891 } 1923 }
1892 1924
1893 // cerr << "found new layer " << layer << " (name = " 1925 // cerr << "found new layer " << layer << " (name = "
1894 // << layer->getLayerPresentationName() << ")" << endl; 1926 // << layer->getLayerPresentationName() << ")" << endl;
1895 1927
1896 orderedLayers.push_back(layer); 1928 orderedLayers.push_back(layer);
1897 observedLayers.insert(layer); 1929 observedLayers.insert(layer);
1898 1930
1899 if (factory->isLayerSliceable(layer)) { 1931 if (factory->isLayerSliceable(layer)) {
1900 sliceableLayers.insert(layer); 1932 sliceableLayers.insert(layer);
1901 } 1933 }
1902 } 1934 }
1903 } 1935 }
1904 1936
1905 map<QString, int> observedNames; 1937 map<QString, int> observedNames;
1906 1938
1907 for (size_t i = 0; i < orderedLayers.size(); ++i) { 1939 for (size_t i = 0; i < orderedLayers.size(); ++i) {
1908 1940
1909 Layer *layer = orderedLayers[i]; 1941 Layer *layer = orderedLayers[i];
1910 1942
1911 QString name = layer->getLayerPresentationName(); 1943 QString name = layer->getLayerPresentationName();
1912 int n = ++observedNames[name]; 1944 int n = ++observedNames[name];
1913 if (n > 1) name = QString("%1 <%2>").arg(name).arg(n); 1945 if (n > 1) name = QString("%1 <%2>").arg(name).arg(n);
1914 1946
1915 QIcon icon = il.load(factory->getLayerIconName 1947 QIcon icon = il.load(factory->getLayerIconName
1916 (factory->getLayerType(layer))); 1948 (factory->getLayerType(layer)));
1917 1949
1918 QAction *action = new QAction(icon, name, this); 1950 QAction *action = new QAction(icon, name, this);
1919 connect(action, SIGNAL(triggered()), this, SLOT(addLayer())); 1951 connect(action, SIGNAL(triggered()), this, SLOT(addLayer()));
1920 connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); 1952 connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool)));
1921 m_existingLayerActions[action] = layer; 1953 m_existingLayerActions[action] = layer;
1922 1954
1923 m_existingLayersMenu->addAction(action); 1955 m_existingLayersMenu->addAction(action);
1924 1956
1925 if (sliceableLayers.find(layer) != sliceableLayers.end()) { 1957 if (sliceableLayers.find(layer) != sliceableLayers.end()) {
1926 action = new QAction(icon, name, this); 1958 action = new QAction(icon, name, this);
1927 connect(action, SIGNAL(triggered()), this, SLOT(addLayer())); 1959 connect(action, SIGNAL(triggered()), this, SLOT(addLayer()));
1928 connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); 1960 connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool)));
1972 m_playAction->setCheckable(true); 2004 m_playAction->setCheckable(true);
1973 m_playAction->setShortcut(tr("Space")); 2005 m_playAction->setShortcut(tr("Space"));
1974 m_playAction->setStatusTip(tr("Start or stop playback from the current position")); 2006 m_playAction->setStatusTip(tr("Start or stop playback from the current position"));
1975 connect(m_playAction, SIGNAL(triggered()), this, SLOT(play())); 2007 connect(m_playAction, SIGNAL(triggered()), this, SLOT(play()));
1976 connect(m_playSource, SIGNAL(playStatusChanged(bool)), 2008 connect(m_playSource, SIGNAL(playStatusChanged(bool)),
1977 m_playAction, SLOT(setChecked(bool))); 2009 m_playAction, SLOT(setChecked(bool)));
1978 connect(m_playSource, SIGNAL(playStatusChanged(bool)), 2010 connect(m_playSource, SIGNAL(playStatusChanged(bool)),
1979 this, SLOT(playStatusChanged(bool))); 2011 this, SLOT(playStatusChanged(bool)));
1980 connect(this, SIGNAL(canPlay(bool)), m_playAction, SLOT(setEnabled(bool))); 2012 connect(this, SIGNAL(canPlay(bool)), m_playAction, SLOT(setEnabled(bool)));
1981 2013
1982 m_ffwdAction = toolbar->addAction(il.load("ffwd"), 2014 m_ffwdAction = toolbar->addAction(il.load("ffwd"),
2110 QAction *fastAction = menu->addAction(tr("Speed Up")); 2142 QAction *fastAction = menu->addAction(tr("Speed Up"));
2111 fastAction->setShortcut(tr("Ctrl+PgUp")); 2143 fastAction->setShortcut(tr("Ctrl+PgUp"));
2112 fastAction->setStatusTip(tr("Time-stretch playback to speed it up without changing pitch")); 2144 fastAction->setStatusTip(tr("Time-stretch playback to speed it up without changing pitch"));
2113 connect(fastAction, SIGNAL(triggered()), this, SLOT(speedUpPlayback())); 2145 connect(fastAction, SIGNAL(triggered()), this, SLOT(speedUpPlayback()));
2114 connect(this, SIGNAL(canSpeedUpPlayback(bool)), fastAction, SLOT(setEnabled(bool))); 2146 connect(this, SIGNAL(canSpeedUpPlayback(bool)), fastAction, SLOT(setEnabled(bool)));
2115 2147
2116 QAction *slowAction = menu->addAction(tr("Slow Down")); 2148 QAction *slowAction = menu->addAction(tr("Slow Down"));
2117 slowAction->setShortcut(tr("Ctrl+PgDown")); 2149 slowAction->setShortcut(tr("Ctrl+PgDown"));
2118 slowAction->setStatusTip(tr("Time-stretch playback to slow it down without changing pitch")); 2150 slowAction->setStatusTip(tr("Time-stretch playback to slow it down without changing pitch"));
2119 connect(slowAction, SIGNAL(triggered()), this, SLOT(slowDownPlayback())); 2151 connect(slowAction, SIGNAL(triggered()), this, SLOT(slowDownPlayback()));
2120 connect(this, SIGNAL(canSlowDownPlayback(bool)), slowAction, SLOT(setEnabled(bool))); 2152 connect(this, SIGNAL(canSlowDownPlayback(bool)), slowAction, SLOT(setEnabled(bool)));
2167 (tr("Edit"), tr("Double-Click Left"), 2199 (tr("Edit"), tr("Double-Click Left"),
2168 tr("Double-click left button on an item to edit it")); 2200 tr("Double-click left button on an item to edit it"));
2169 2201
2170 m_keyReference->setCategory(tr("Tool Selection")); 2202 m_keyReference->setCategory(tr("Tool Selection"));
2171 action = toolbar->addAction(il.load("select"), 2203 action = toolbar->addAction(il.load("select"),
2172 tr("Select")); 2204 tr("Select"));
2173 action->setCheckable(true); 2205 action->setCheckable(true);
2174 action->setShortcut(tr("2")); 2206 action->setShortcut(tr("2"));
2175 action->setStatusTip(tr("Select ranges")); 2207 action->setStatusTip(tr("Select ranges"));
2176 connect(action, SIGNAL(triggered()), this, SLOT(toolSelectSelected())); 2208 connect(action, SIGNAL(triggered()), this, SLOT(toolSelectSelected()));
2177 group->addAction(action); 2209 group->addAction(action);
2196 (tr("Fine Select"), tr("Shift+Left"), 2228 (tr("Fine Select"), tr("Shift+Left"),
2197 tr("Shift-click left button and drag to select without snapping to items or grid")); 2229 tr("Shift-click left button and drag to select without snapping to items or grid"));
2198 2230
2199 m_keyReference->setCategory(tr("Tool Selection")); 2231 m_keyReference->setCategory(tr("Tool Selection"));
2200 action = toolbar->addAction(il.load("move"), 2232 action = toolbar->addAction(il.load("move"),
2201 tr("Edit")); 2233 tr("Edit"));
2202 action->setCheckable(true); 2234 action->setCheckable(true);
2203 action->setShortcut(tr("3")); 2235 action->setShortcut(tr("3"));
2204 action->setStatusTip(tr("Edit items in layer")); 2236 action->setStatusTip(tr("Edit items in layer"));
2205 connect(action, SIGNAL(triggered()), this, SLOT(toolEditSelected())); 2237 connect(action, SIGNAL(triggered()), this, SLOT(toolEditSelected()));
2206 connect(this, SIGNAL(canEditLayer(bool)), action, SLOT(setEnabled(bool))); 2238 connect(this, SIGNAL(canEditLayer(bool)), action, SLOT(setEnabled(bool)));
2217 (tr("Edit"), tr("Double-Click Left"), 2249 (tr("Edit"), tr("Double-Click Left"),
2218 tr("Double-click left button on an item to edit it")); 2250 tr("Double-click left button on an item to edit it"));
2219 2251
2220 m_keyReference->setCategory(tr("Tool Selection")); 2252 m_keyReference->setCategory(tr("Tool Selection"));
2221 action = toolbar->addAction(il.load("draw"), 2253 action = toolbar->addAction(il.load("draw"),
2222 tr("Draw")); 2254 tr("Draw"));
2223 action->setCheckable(true); 2255 action->setCheckable(true);
2224 action->setShortcut(tr("4")); 2256 action->setShortcut(tr("4"));
2225 action->setStatusTip(tr("Draw new items in layer")); 2257 action->setStatusTip(tr("Draw new items in layer"));
2226 connect(action, SIGNAL(triggered()), this, SLOT(toolDrawSelected())); 2258 connect(action, SIGNAL(triggered()), this, SLOT(toolDrawSelected()));
2227 connect(this, SIGNAL(canEditLayer(bool)), action, SLOT(setEnabled(bool))); 2259 connect(this, SIGNAL(canEditLayer(bool)), action, SLOT(setEnabled(bool)));
2235 (tr("Draw"), tr("Left"), 2267 (tr("Draw"), tr("Left"),
2236 tr("Click left button and drag to create new item")); 2268 tr("Click left button and drag to create new item"));
2237 2269
2238 m_keyReference->setCategory(tr("Tool Selection")); 2270 m_keyReference->setCategory(tr("Tool Selection"));
2239 action = toolbar->addAction(il.load("erase"), 2271 action = toolbar->addAction(il.load("erase"),
2240 tr("Erase")); 2272 tr("Erase"));
2241 action->setCheckable(true); 2273 action->setCheckable(true);
2242 action->setShortcut(tr("5")); 2274 action->setShortcut(tr("5"));
2243 action->setStatusTip(tr("Erase items from layer")); 2275 action->setStatusTip(tr("Erase items from layer"));
2244 connect(action, SIGNAL(triggered()), this, SLOT(toolEraseSelected())); 2276 connect(action, SIGNAL(triggered()), this, SLOT(toolEraseSelected()));
2245 connect(this, SIGNAL(canEditLayer(bool)), action, SLOT(setEnabled(bool))); 2277 connect(this, SIGNAL(canEditLayer(bool)), action, SLOT(setEnabled(bool)));
2315 (m_playTarget != 0 || m_audioIO != 0); 2347 (m_playTarget != 0 || m_audioIO != 0);
2316 bool haveSelection = 2348 bool haveSelection =
2317 (m_viewManager && 2349 (m_viewManager &&
2318 !m_viewManager->getSelections().empty()); 2350 !m_viewManager->getSelections().empty());
2319 bool haveCurrentEditableLayer = 2351 bool haveCurrentEditableLayer =
2320 (haveCurrentLayer && 2352 (haveCurrentLayer &&
2321 currentLayer->isLayerEditable()); 2353 currentLayer->isLayerEditable());
2322 bool haveCurrentTimeInstantsLayer = 2354 bool haveCurrentTimeInstantsLayer =
2323 (haveCurrentLayer && 2355 (haveCurrentLayer &&
2324 dynamic_cast<TimeInstantLayer *>(currentLayer)); 2356 dynamic_cast<TimeInstantLayer *>(currentLayer));
2325 bool haveCurrentTimeValueLayer = 2357 bool haveCurrentTimeValueLayer =
2326 (haveCurrentLayer && 2358 (haveCurrentLayer &&
2327 dynamic_cast<TimeValueLayer *>(currentLayer)); 2359 dynamic_cast<TimeValueLayer *>(currentLayer));
2328 2360
2329 bool alignMode = m_viewManager && m_viewManager->getAlignMode(); 2361 bool alignMode = m_viewManager && m_viewManager->getAlignMode();
2330 emit canChangeSolo(havePlayTarget && !alignMode); 2362 emit canChangeSolo(havePlayTarget && !alignMode);
2331 emit canAlign(havePlayTarget && m_document && m_document->canAlign()); 2363 emit canAlign(havePlayTarget && m_document && m_document->canAlign());
2332 2364
2333 emit canChangePlaybackSpeed(true); 2365 emit canChangePlaybackSpeed(true);
2334 int v = m_playSpeed->value(); 2366 int v = m_playSpeed->value();
2335 emit canSpeedUpPlayback(v < m_playSpeed->maximum()); 2367 emit canSpeedUpPlayback(v < m_playSpeed->maximum());
2336 emit canSlowDownPlayback(v > m_playSpeed->minimum()); 2368 emit canSlowDownPlayback(v > m_playSpeed->minimum());
2337 2369
2338 if (m_viewManager && 2370 if (m_viewManager &&
2339 (m_viewManager->getToolMode() == ViewManager::MeasureMode)) { 2371 (m_viewManager->getToolMode() == ViewManager::MeasureMode)) {
2340 emit canDeleteSelection(haveCurrentLayer); 2372 emit canDeleteSelection(haveCurrentLayer);
2341 m_deleteSelectedAction->setText(tr("&Delete Current Measurement")); 2373 m_deleteSelectedAction->setText(tr("&Delete Current Measurement"));
2342 m_deleteSelectedAction->setStatusTip(tr("Delete the measurement currently under the mouse pointer")); 2374 m_deleteSelectedAction->setStatusTip(tr("Delete the measurement currently under the mouse pointer"));
2343 } else { 2375 } else {
2368 2400
2369 void 2401 void
2370 MainWindow::updateDescriptionLabel() 2402 MainWindow::updateDescriptionLabel()
2371 { 2403 {
2372 if (!getMainModel()) { 2404 if (!getMainModel()) {
2373 m_descriptionLabel->setText(tr("No audio file loaded.")); 2405 m_descriptionLabel->setText(tr("No audio file loaded."));
2374 return; 2406 return;
2375 } 2407 }
2376 2408
2377 QString description; 2409 QString description;
2378 2410
2379 sv_samplerate_t ssr = getMainModel()->getSampleRate(); 2411 sv_samplerate_t ssr = getMainModel()->getSampleRate();
2380 sv_samplerate_t tsr = ssr; 2412 sv_samplerate_t tsr = ssr;
2381 if (m_playSource) tsr = m_playSource->getTargetSampleRate(); 2413 if (m_playSource) tsr = m_playSource->getTargetSampleRate();
2382 2414
2383 if (ssr != tsr) { 2415 if (ssr != tsr) {
2384 description = tr("%1Hz (resampling to %2Hz)").arg(ssr).arg(tsr); 2416 description = tr("%1Hz (resampling to %2Hz)").arg(ssr).arg(tsr);
2385 } else { 2417 } else {
2386 description = QString("%1Hz").arg(ssr); 2418 description = QString("%1Hz").arg(ssr);
2387 } 2419 }
2388 2420
2389 description = QString("%1 - %2") 2421 description = QString("%1 - %2")
2390 .arg(RealTime::frame2RealTime(getMainModel()->getEndFrame(), ssr) 2422 .arg(RealTime::frame2RealTime(getMainModel()->getEndFrame(), ssr)
2391 .toText(false).c_str()) 2423 .toText(false).c_str())
2392 .arg(description); 2424 .arg(description);
2393 2425
2394 m_descriptionLabel->setText(description); 2426 m_descriptionLabel->setText(description);
2395 } 2427 }
2396 2428
2397 void 2429 void
2448 MainWindow::importAudio() 2480 MainWindow::importAudio()
2449 { 2481 {
2450 QString path = getOpenFileName(FileFinder::AudioFile); 2482 QString path = getOpenFileName(FileFinder::AudioFile);
2451 2483
2452 if (path != "") { 2484 if (path != "") {
2453 if (openAudio(path, ReplaceSession) == FileOpenFailed) { 2485 if (openAudio(path, ReplaceSession) == FileOpenFailed) {
2454 emit hideSplash(); 2486 emit hideSplash();
2455 QMessageBox::critical(this, tr("Failed to open file"), 2487 QMessageBox::critical(this, tr("Failed to open file"),
2456 tr("<b>File open failed</b><p>Audio file \"%1\" could not be opened").arg(path)); 2488 tr("<b>File open failed</b><p>Audio file \"%1\" could not be opened").arg(path));
2457 } 2489 }
2458 } 2490 }
2459 } 2491 }
2460 2492
2461 void 2493 void
2462 MainWindow::importMoreAudio() 2494 MainWindow::importMoreAudio()
2463 { 2495 {
2464 QString path = getOpenFileName(FileFinder::AudioFile); 2496 QString path = getOpenFileName(FileFinder::AudioFile);
2465 2497
2466 if (path != "") { 2498 if (path != "") {
2467 if (openAudio(path, CreateAdditionalModel) == FileOpenFailed) { 2499 if (openAudio(path, CreateAdditionalModel) == FileOpenFailed) {
2468 emit hideSplash(); 2500 emit hideSplash();
2469 QMessageBox::critical(this, tr("Failed to open file"), 2501 QMessageBox::critical(this, tr("Failed to open file"),
2470 tr("<b>File open failed</b><p>Audio file \"%1\" could not be opened").arg(path)); 2502 tr("<b>File open failed</b><p>Audio file \"%1\" could not be opened").arg(path));
2471 } 2503 }
2472 } 2504 }
2505
2506 files_paths[int(m_paneStack->getPaneCount())-1] = path;
2473 } 2507 }
2474 2508
2475 void 2509 void
2476 MainWindow::replaceMainAudio() 2510 MainWindow::replaceMainAudio()
2477 { 2511 {
2478 QString path = getOpenFileName(FileFinder::AudioFile); 2512 QString path = getOpenFileName(FileFinder::AudioFile);
2479 2513
2480 if (path != "") { 2514 if (path != "") {
2481 if (openAudio(path, ReplaceMainModel) == FileOpenFailed) { 2515 if (openAudio(path, ReplaceMainModel) == FileOpenFailed) {
2482 emit hideSplash(); 2516 emit hideSplash();
2483 QMessageBox::critical(this, tr("Failed to open file"), 2517 QMessageBox::critical(this, tr("Failed to open file"),
2484 tr("<b>File open failed</b><p>Audio file \"%1\" could not be opened").arg(path)); 2518 tr("<b>File open failed</b><p>Audio file \"%1\" could not be opened").arg(path));
2485 } 2519 }
2486 } 2520 }
2487 } 2521 }
2488 2522
2489 void 2523 void
2490 MainWindow::exportAudio() 2524 MainWindow::exportAudio()
2513 for (int j = 0; j < pane->getLayerCount(); ++j) { 2547 for (int j = 0; j < pane->getLayerCount(); ++j) {
2514 Layer *layer = pane->getLayer(j); 2548 Layer *layer = pane->getLayer(j);
2515 if (!layer) continue; 2549 if (!layer) continue;
2516 cerr << "layer = " << layer->objectName() << endl; 2550 cerr << "layer = " << layer->objectName() << endl;
2517 Model *m = layer->getModel(); 2551 Model *m = layer->getModel();
2518 RangeSummarisableTimeValueModel *wm = 2552 RangeSummarisableTimeValueModel *wm =
2519 dynamic_cast<RangeSummarisableTimeValueModel *>(m); 2553 dynamic_cast<RangeSummarisableTimeValueModel *>(m);
2520 if (wm) { 2554 if (wm) {
2521 cerr << "found: " << wm->objectName() << endl; 2555 cerr << "found: " << wm->objectName() << endl;
2522 otherModels.insert(wm); 2556 otherModels.insert(wm);
2523 if (pane == m_paneStack->getCurrentPane()) { 2557 if (pane == m_paneStack->getCurrentPane()) {
2580 2614
2581 MultiSelection *selectionToWrite = 0; 2615 MultiSelection *selectionToWrite = 0;
2582 2616
2583 if (selections.size() == 1) { 2617 if (selections.size() == 1) {
2584 2618
2585 QStringList items; 2619 QStringList items;
2586 items << tr("Export the selected region only") 2620 items << tr("Export the selected region only")
2587 << tr("Export the whole audio file"); 2621 << tr("Export the whole audio file");
2588 2622
2589 bool ok = false; 2623 bool ok = false;
2590 QString item = ListInputDialog::getItem 2624 QString item = ListInputDialog::getItem
2591 (this, tr("Select region to export"), 2625 (this, tr("Select region to export"),
2592 tr("Which region from the original audio file do you want to export?"), 2626 tr("Which region from the original audio file do you want to export?"),
2593 items, 0, &ok); 2627 items, 0, &ok);
2594 2628
2595 if (!ok || item.isEmpty()) return; 2629 if (!ok || item.isEmpty()) return;
2596 2630
2597 if (item == items[0]) selectionToWrite = &ms; 2631 if (item == items[0]) selectionToWrite = &ms;
2598 2632
2599 } else if (selections.size() > 1) { 2633 } else if (selections.size() > 1) {
2600 2634
2601 if (!asData) { // Multi-file export not supported for data 2635 if (!asData) { // Multi-file export not supported for data
2602 2636
2615 if (item == items[0]) { 2649 if (item == items[0]) {
2616 selectionToWrite = &ms; 2650 selectionToWrite = &ms;
2617 } else if (item == items[1]) { 2651 } else if (item == items[1]) {
2618 multiple = true; 2652 multiple = true;
2619 } 2653 }
2620
2621 } else { // asData 2654 } else { // asData
2622 selectionToWrite = &ms; 2655 selectionToWrite = &ms;
2623 } 2656 }
2624 2657
2625 if (multiple) { // Can only happen when asData false 2658 if (multiple) { // Can only happen when asData false
2626 2659
2627 int n = 1; 2660 int n = 1;
2628 QString base = path; 2661 QString base = path;
2629 base.replace(".wav", ""); 2662 base.replace(".wav", "");
2630 2663
2631 for (MultiSelection::SelectionList::iterator i = selections.begin(); 2664 for (MultiSelection::SelectionList::iterator i = selections.begin();
2632 i != selections.end(); ++i) { 2665 i != selections.end(); ++i) {
2633 2666
2634 MultiSelection subms; 2667 MultiSelection subms;
2635 subms.setSelection(*i); 2668 subms.setSelection(*i);
2636 2669
2637 QString subpath = QString("%1.%2.wav").arg(base).arg(n); 2670 QString subpath = QString("%1.%2.wav").arg(base).arg(n);
2638 ++n; 2671 ++n;
2639 2672
2640 if (QFileInfo(subpath).exists()) { 2673 if (QFileInfo(subpath).exists()) {
2641 error = tr("Fragment file %1 already exists, aborting").arg(subpath); 2674 error = tr("Fragment file %1 already exists, aborting").arg(subpath);
2642 break; 2675 break;
2643 } 2676 }
2644 2677
2645 WavFileWriter subwriter(subpath, 2678 WavFileWriter subwriter(subpath,
2646 model->getSampleRate(), 2679 model->getSampleRate(),
2647 model->getChannelCount(), 2680 model->getChannelCount(),
2648 WavFileWriter::WriteToTemporary); 2681 WavFileWriter::WriteToTemporary);
2649 subwriter.writeModel(model, &subms); 2682 subwriter.writeModel(model, &subms);
2650 ok = subwriter.isOK(); 2683 ok = subwriter.isOK();
2651 2684
2652 if (!ok) { 2685 if (!ok) {
2653 error = subwriter.getError(); 2686 error = subwriter.getError();
2654 break; 2687 break;
2655 } 2688 }
2656 } 2689 }
2657 } 2690 }
2658 } 2691 }
2659 2692
2660 if (!multiple) { 2693 if (!multiple) {
2661 if (asData) { 2694 if (asData) {
2662 CSVFileWriter writer(path, model, 2695 CSVFileWriter writer(path, model,
2686 } else { 2719 } else {
2687 emit activity(tr("Export audio to \"%1\"").arg(path)); 2720 emit activity(tr("Export audio to \"%1\"").arg(path));
2688 m_recentFiles.addFile(path); 2721 m_recentFiles.addFile(path);
2689 } 2722 }
2690 } else { 2723 } else {
2691 QMessageBox::critical(this, tr("Failed to write file"), error); 2724 QMessageBox::critical(this, tr("Failed to write file"), error);
2692 } 2725 }
2693 } 2726 }
2727
2728
2729
2694 2730
2695 void 2731 void
2696 MainWindow::importLayer() 2732 MainWindow::importLayer()
2697 { 2733 {
2698 Pane *pane = m_paneStack->getCurrentPane(); 2734 Pane *pane = m_paneStack->getCurrentPane();
2699 2735
2700 if (!pane) { 2736 if (!pane) {
2701 // shouldn't happen, as the menu action should have been disabled 2737 // shouldn't happen, as the menu action should have been disabled
2702 cerr << "WARNING: MainWindow::importLayer: no current pane" << endl; 2738 cerr << "WARNING: MainWindow::importLayer: no current pane" << endl;
2703 return; 2739 return;
2704 } 2740 }
2712 QString path = getOpenFileName(FileFinder::LayerFile); 2748 QString path = getOpenFileName(FileFinder::LayerFile);
2713 2749
2714 if (path != "") { 2750 if (path != "") {
2715 2751
2716 FileOpenStatus status = openLayer(path); 2752 FileOpenStatus status = openLayer(path);
2717 2753
2718 if (status == FileOpenFailed) { 2754 if (status == FileOpenFailed) {
2719 emit hideSplash(); 2755 emit hideSplash();
2720 QMessageBox::critical(this, tr("Failed to open file"), 2756 QMessageBox::critical(this, tr("Failed to open file"),
2721 tr("<b>File open failed</b><p>Layer file %1 could not be opened.").arg(path)); 2757 tr("<b>File open failed</b><p>Layer file %1 could not be opened.").arg(path));
2722 return; 2758 return;
2826 void 2862 void
2827 MainWindow::exportImage() 2863 MainWindow::exportImage()
2828 { 2864 {
2829 Pane *pane = m_paneStack->getCurrentPane(); 2865 Pane *pane = m_paneStack->getCurrentPane();
2830 if (!pane) return; 2866 if (!pane) return;
2831 2867
2832 QString path = getSaveFileName(FileFinder::ImageFile); 2868 QString path = getSaveFileName(FileFinder::ImageFile);
2833 2869
2834 if (path == "") return; 2870 if (path == "") return;
2835 2871
2836 if (QFileInfo(path).suffix() == "") path += ".png"; 2872 if (QFileInfo(path).suffix() == "") path += ".png";
2885 } 2921 }
2886 2922
2887 bool ok = lid->exec(); 2923 bool ok = lid->exec();
2888 QString item = lid->getCurrentString(); 2924 QString item = lid->getCurrentString();
2889 delete lid; 2925 delete lid;
2890 2926
2891 if (!ok || item.isEmpty()) return; 2927 if (!ok || item.isEmpty()) return;
2892 2928
2893 settings.setValue("lastimageexportregion", deflt); 2929 settings.setValue("lastimageexportregion", deflt);
2894 2930
2895 QImage *image = 0; 2931 QImage *image = 0;
2907 2943
2908 if (!image->save(path, "PNG")) { 2944 if (!image->save(path, "PNG")) {
2909 QMessageBox::critical(this, tr("Failed to save image file"), 2945 QMessageBox::critical(this, tr("Failed to save image file"),
2910 tr("Failed to save image file %1").arg(path)); 2946 tr("Failed to save image file %1").arg(path));
2911 } 2947 }
2912 2948
2913 delete image; 2949 delete image;
2914 } 2950 }
2915 2951
2916 void 2952 void
2917 MainWindow::browseRecordedAudio() 2953 MainWindow::browseRecordedAudio()
2936 2972
2937 connect(pane, SIGNAL(contextHelpChanged(const QString &)), 2973 connect(pane, SIGNAL(contextHelpChanged(const QString &)),
2938 this, SLOT(contextHelpChanged(const QString &))); 2974 this, SLOT(contextHelpChanged(const QString &)));
2939 2975
2940 if (!m_timeRulerLayer) { 2976 if (!m_timeRulerLayer) {
2941 m_timeRulerLayer = m_document->createMainModelLayer 2977 m_timeRulerLayer = m_document->createMainModelLayer
2942 (LayerFactory::TimeRuler); 2978 (LayerFactory::TimeRuler);
2943 } 2979 }
2944 2980
2945 m_document->addLayerToView(pane, m_timeRulerLayer); 2981 m_document->addLayerToView(pane, m_timeRulerLayer);
2946 2982
2947 Layer *waveform = m_document->createMainModelLayer(LayerFactory::Waveform); 2983 Layer *waveform = m_document->createMainModelLayer(LayerFactory::Waveform);
2969 { 3005 {
2970 if (!checkSaveModified()) return; 3006 if (!checkSaveModified()) return;
2971 3007
2972 while (m_paneStack->getPaneCount() > 0) { 3008 while (m_paneStack->getPaneCount() > 0) {
2973 3009
2974 Pane *pane = m_paneStack->getPane(m_paneStack->getPaneCount() - 1); 3010 Pane *pane = m_paneStack->getPane(m_paneStack->getPaneCount() - 1);
2975 3011
2976 while (pane->getLayerCount() > 0) { 3012 while (pane->getLayerCount() > 0) {
2977 m_document->removeLayerFromView 3013 m_document->removeLayerFromView
2978 (pane, pane->getLayer(pane->getLayerCount() - 1)); 3014 (pane, pane->getLayer(pane->getLayerCount() - 1));
2979 } 3015 }
2980 3016
2981 m_overview->unregisterView(pane); 3017 m_overview->unregisterView(pane);
2982 m_paneStack->deletePane(pane); 3018 m_paneStack->deletePane(pane);
2983 } 3019 }
2984 3020
2985 while (m_paneStack->getHiddenPaneCount() > 0) { 3021 while (m_paneStack->getHiddenPaneCount() > 0) {
2986 3022
2987 Pane *pane = m_paneStack->getHiddenPane 3023 Pane *pane = m_paneStack->getHiddenPane
2988 (m_paneStack->getHiddenPaneCount() - 1); 3024 (m_paneStack->getHiddenPaneCount() - 1);
2989 3025
2990 while (pane->getLayerCount() > 0) { 3026 while (pane->getLayerCount() > 0) {
2991 m_document->removeLayerFromView 3027 m_document->removeLayerFromView
2992 (pane, pane->getLayer(pane->getLayerCount() - 1)); 3028 (pane, pane->getLayer(pane->getLayerCount() - 1));
2993 } 3029 }
2994 3030
2995 m_overview->unregisterView(pane); 3031 m_overview->unregisterView(pane);
2996 m_paneStack->deletePane(pane); 3032 m_paneStack->deletePane(pane);
2997 } 3033 }
2998 3034
2999 delete m_layerTreeDialog.data(); 3035 delete m_layerTreeDialog.data();
3000 delete m_preferencesDialog.data(); 3036 delete m_preferencesDialog.data();
3001 3037
3023 if (orig == "") orig = "."; 3059 if (orig == "") orig = ".";
3024 else orig = QFileInfo(orig).absoluteDir().canonicalPath(); 3060 else orig = QFileInfo(orig).absoluteDir().canonicalPath();
3025 3061
3026 QString path = getOpenFileName(FileFinder::AnyFile); 3062 QString path = getOpenFileName(FileFinder::AnyFile);
3027 3063
3028 if (path.isEmpty()) return; 3064 if (path.isEmpty()) return;
3029 3065
3030 FileOpenStatus status = openPath(path, ReplaceSession); 3066 FileOpenStatus status = openPath(path, ReplaceSession);
3031 3067
3032 if (status == FileOpenFailed) { 3068 if (status == FileOpenFailed) {
3033 emit hideSplash(); 3069 emit hideSplash();
3036 } else if (status == FileOpenWrongMode) { 3072 } else if (status == FileOpenWrongMode) {
3037 emit hideSplash(); 3073 emit hideSplash();
3038 QMessageBox::critical(this, tr("Failed to open file"), 3074 QMessageBox::critical(this, tr("Failed to open file"),
3039 tr("<b>Audio required</b><p>Unable to load layer data from \"%1\" without an audio file.<br>Please load at least one audio file before importing annotations.").arg(path)); 3075 tr("<b>Audio required</b><p>Unable to load layer data from \"%1\" without an audio file.<br>Please load at least one audio file before importing annotations.").arg(path));
3040 } 3076 }
3077
3078 files_paths[0] = path;
3079 QTextStream out(stdout);
3080 out << path;
3081
3041 } 3082 }
3042 3083
3043 void 3084 void
3044 MainWindow::openLocation() 3085 MainWindow::openLocation()
3045 { 3086 {
3075 void 3116 void
3076 MainWindow::openRecentFile() 3117 MainWindow::openRecentFile()
3077 { 3118 {
3078 QObject *obj = sender(); 3119 QObject *obj = sender();
3079 QAction *action = dynamic_cast<QAction *>(obj); 3120 QAction *action = dynamic_cast<QAction *>(obj);
3080 3121
3081 if (!action) { 3122 if (!action) {
3082 cerr << "WARNING: MainWindow::openRecentFile: sender is not an action" 3123 cerr << "WARNING: MainWindow::openRecentFile: sender is not an action"
3083 << endl; 3124 << endl;
3084 return; 3125 return;
3085 } 3126 }
3144 0, 0); 3185 0, 0);
3145 QLineEdit *lineEdit = new QLineEdit; 3186 QLineEdit *lineEdit = new QLineEdit;
3146 layout->addWidget(lineEdit, 1, 0); 3187 layout->addWidget(lineEdit, 1, 0);
3147 QCheckBox *makeDefault = new QCheckBox(tr("Set as default template for future audio files")); 3188 QCheckBox *makeDefault = new QCheckBox(tr("Set as default template for future audio files"));
3148 layout->addWidget(makeDefault, 2, 0); 3189 layout->addWidget(makeDefault, 2, 0);
3149 3190
3150 QDialogButtonBox *bb = new QDialogButtonBox(QDialogButtonBox::Ok | 3191 QDialogButtonBox *bb = new QDialogButtonBox(QDialogButtonBox::Ok |
3151 QDialogButtonBox::Cancel); 3192 QDialogButtonBox::Cancel);
3152 layout->addWidget(bb, 3, 0); 3193 layout->addWidget(bb, 3, 0);
3153 connect(bb, SIGNAL(accepted()), d, SLOT(accept())); 3194 connect(bb, SIGNAL(accepted()), d, SLOT(accept()));
3154 connect(bb, SIGNAL(accepted()), d, SLOT(accept())); 3195 connect(bb, SIGNAL(accepted()), d, SLOT(accept()));
3155 connect(bb, SIGNAL(rejected()), d, SLOT(reject())); 3196 connect(bb, SIGNAL(rejected()), d, SLOT(reject()));
3156 3197
3157 if (d->exec() == QDialog::Accepted) { 3198 if (d->exec() == QDialog::Accepted) {
3158 3199
3159 QString name = lineEdit->text(); 3200 QString name = lineEdit->text();
3160 name.replace(QRegExp("[^\\w\\s\\.\"'-]"), "_"); 3201 name.replace(QRegExp("[^\\w\\s\\.\"'-]"), "_");
3161 3202
3189 3230
3190 void 3231 void
3191 MainWindow::paneAdded(Pane *pane) 3232 MainWindow::paneAdded(Pane *pane)
3192 { 3233 {
3193 if (m_overview) m_overview->registerView(pane); 3234 if (m_overview) m_overview->registerView(pane);
3194 } 3235 }
3195 3236
3196 void 3237 void
3197 MainWindow::paneHidden(Pane *pane) 3238 MainWindow::paneHidden(Pane *pane)
3198 { 3239 {
3199 if (m_overview) m_overview->unregisterView(pane); 3240 if (m_overview) m_overview->unregisterView(pane);
3200 } 3241 }
3201 3242
3202 void 3243 void
3203 MainWindow::paneAboutToBeDeleted(Pane *pane) 3244 MainWindow::paneAboutToBeDeleted(Pane *pane)
3204 { 3245 {
3205 if (m_overview) m_overview->unregisterView(pane); 3246 if (m_overview) m_overview->unregisterView(pane);
3206 } 3247 }
3207 3248
3208 void 3249 void
3209 MainWindow::paneDropAccepted(Pane *pane, QStringList uriList) 3250 MainWindow::paneDropAccepted(Pane *pane, QStringList uriList)
3210 { 3251 {
3211 if (pane) m_paneStack->setCurrentPane(pane); 3252 if (pane) m_paneStack->setCurrentPane(pane);
3240 MainWindow::paneDropAccepted(Pane *pane, QString text) 3281 MainWindow::paneDropAccepted(Pane *pane, QString text)
3241 { 3282 {
3242 if (pane) m_paneStack->setCurrentPane(pane); 3283 if (pane) m_paneStack->setCurrentPane(pane);
3243 3284
3244 QUrl testUrl(text); 3285 QUrl testUrl(text);
3245 if (testUrl.scheme() == "file" || 3286 if (testUrl.scheme() == "file" ||
3246 testUrl.scheme() == "http" || 3287 testUrl.scheme() == "http" ||
3247 testUrl.scheme() == "ftp") { 3288 testUrl.scheme() == "ftp") {
3248 QStringList list; 3289 QStringList list;
3249 list.push_back(text); 3290 list.push_back(text);
3250 paneDropAccepted(pane, list); 3291 paneDropAccepted(pane, list);
3251 return; 3292 return;
3323 if (!QFileInfo(svDir).exists()) { 3364 if (!QFileInfo(svDir).exists()) {
3324 if (!QDir::home().mkdir(svDirBase)) return false; 3365 if (!QDir::home().mkdir(svDirBase)) return false;
3325 } else { 3366 } else {
3326 if (!QFileInfo(svDir).isDir()) return false; 3367 if (!QFileInfo(svDir).isDir()) return false;
3327 } 3368 }
3328 3369
3329 // This name doesn't have to be unguessable 3370 // This name doesn't have to be unguessable
3330 #ifndef _WIN32 3371 #ifndef _WIN32
3331 QString fname = QString("tmp-%1-%2.sv") 3372 QString fname = QString("tmp-%1-%2.sv")
3332 .arg(QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz")) 3373 .arg(QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz"))
3333 .arg(QProcess().pid()); 3374 .arg(QProcess().pid());
3355 3396
3356 if (!m_documentModified) return true; 3397 if (!m_documentModified) return true;
3357 3398
3358 emit hideSplash(); 3399 emit hideSplash();
3359 3400
3360 int button = 3401 int button =
3361 QMessageBox::warning(this, 3402 QMessageBox::warning(this,
3362 tr("Session modified"), 3403 tr("Session modified"),
3363 tr("<b>Session modified</b><p>The current session has been modified.<br>Do you want to save it?"), 3404 tr("<b>Session modified</b><p>The current session has been modified.<br>Do you want to save it?"),
3364 QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel, 3405 QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel,
3365 QMessageBox::Yes); 3406 QMessageBox::Yes);
3366 3407
3367 if (button == QMessageBox::Yes) { 3408 if (button == QMessageBox::Yes) {
3368 saveSession(); 3409 saveSession();
3369 if (m_documentModified) { // save failed -- don't proceed! 3410 if (m_documentModified) { // save failed -- don't proceed!
3370 return false; 3411 return false;
3371 } else { 3412 } else {
3372 return true; // saved, so it's safe to continue now 3413 return true; // saved, so it's safe to continue now
3373 } 3414 }
3374 } else if (button == QMessageBox::No) { 3415 } else if (button == QMessageBox::No) {
3375 m_documentModified = false; // so we know to abandon it 3416 m_documentModified = false; // so we know to abandon it
3376 return true; 3417 return true;
3377 } 3418 }
3378 3419
3379 // else cancel 3420 // else cancel
3380 return false; 3421 return false;
3381 } 3422 }
3389 QSettings settings; 3430 QSettings settings;
3390 settings.beginGroup("MainWindow"); 3431 settings.beginGroup("MainWindow");
3391 bool prevNewSession = settings.value("newsessionforrdfaudio", true).toBool(); 3432 bool prevNewSession = settings.value("newsessionforrdfaudio", true).toBool();
3392 settings.endGroup(); 3433 settings.endGroup();
3393 bool newSession = true; 3434 bool newSession = true;
3394 3435
3395 QStringList items; 3436 QStringList items;
3396 items << tr("Close the current session and create a new one") 3437 items << tr("Close the current session and create a new one")
3397 << tr("Add this data to the current session"); 3438 << tr("Add this data to the current session");
3398 3439
3399 bool ok = false; 3440 bool ok = false;
3400 QString item = ListInputDialog::getItem 3441 QString item = ListInputDialog::getItem
3401 (this, tr("Select target for import"), 3442 (this, tr("Select target for import"),
3402 tr("<b>Select a target for import</b><p>This RDF document refers to one or more audio files.<br>You already have an audio waveform loaded.<br>What would you like to do with the new data?"), 3443 tr("<b>Select a target for import</b><p>This RDF document refers to one or more audio files.<br>You already have an audio waveform loaded.<br>What would you like to do with the new data?"),
3403 items, prevNewSession ? 0 : 1, &ok); 3444 items, prevNewSession ? 0 : 1, &ok);
3404 3445
3405 if (!ok || item.isEmpty()) { 3446 if (!ok || item.isEmpty()) {
3406 *cancel = true; 3447 *cancel = true;
3407 return false; 3448 return false;
3408 } 3449 }
3409 3450
3410 newSession = (item == items[0]); 3451 newSession = (item == items[0]);
3411 settings.beginGroup("MainWindow"); 3452 settings.beginGroup("MainWindow");
3412 settings.setValue("newsessionforrdfaudio", newSession); 3453 settings.setValue("newsessionforrdfaudio", newSession);
3413 settings.endGroup(); 3454 settings.endGroup();
3414 3455
3418 3459
3419 void 3460 void
3420 MainWindow::saveSession() 3461 MainWindow::saveSession()
3421 { 3462 {
3422 if (m_sessionFile != "") { 3463 if (m_sessionFile != "") {
3423 if (!saveSessionFile(m_sessionFile)) { 3464 if (!saveSessionFile(m_sessionFile)) {
3424 QMessageBox::critical(this, tr("Failed to save file"), 3465 QMessageBox::critical(this, tr("Failed to save file"),
3425 tr("<b>Save failed</b><p>Session file \"%1\" could not be saved.").arg(m_sessionFile)); 3466 tr("<b>Save failed</b><p>Session file \"%1\" could not be saved.").arg(m_sessionFile));
3426 } else {
3427 CommandHistory::getInstance()->documentSaved();
3428 documentRestored();
3429 }
3430 } else { 3467 } else {
3431 saveSessionAs(); 3468 CommandHistory::getInstance()->documentSaved();
3469 documentRestored();
3470 }
3471 } else {
3472 saveSessionAs();
3432 } 3473 }
3433 } 3474 }
3434 3475
3435 void 3476 void
3436 MainWindow::saveSessionAs() 3477 MainWindow::saveSessionAs()
3442 QString path = getSaveFileName(FileFinder::SessionFile); 3483 QString path = getSaveFileName(FileFinder::SessionFile);
3443 3484
3444 if (path == "") return; 3485 if (path == "") return;
3445 3486
3446 if (!saveSessionFile(path)) { 3487 if (!saveSessionFile(path)) {
3447 QMessageBox::critical(this, tr("Failed to save file"), 3488 QMessageBox::critical(this, tr("Failed to save file"),
3448 tr("<b>Save failed</b><p>Session file \"%1\" could not be saved.").arg(path)); 3489 tr("<b>Save failed</b><p>Session file \"%1\" could not be saved.").arg(path));
3449 } else { 3490 } else {
3450 setWindowTitle(tr("%1: %2") 3491 setWindowTitle(tr("%1: %2")
3451 .arg(QApplication::applicationName()) 3492 .arg(QApplication::applicationName())
3452 .arg(QFileInfo(path).fileName())); 3493 .arg(QFileInfo(path).fileName()));
3453 m_sessionFile = path; 3494 m_sessionFile = path;
3454 CommandHistory::getInstance()->documentSaved(); 3495 CommandHistory::getInstance()->documentSaved();
3455 documentRestored(); 3496 documentRestored();
3456 m_recentFiles.addFile(path); 3497 m_recentFiles.addFile(path);
3457 emit activity(tr("Save session as \"%1\"").arg(path)); 3498 emit activity(tr("Save session as \"%1\"").arg(path));
3458 } 3499 }
3459 } 3500 }
3460 3501
3468 m_panLayer->setBaseColour 3509 m_panLayer->setBaseColour
3469 (ColourDatabase::getInstance()->getColourIndex(tr("Bright Green"))); 3510 (ColourDatabase::getInstance()->getColourIndex(tr("Bright Green")));
3470 } else { 3511 } else {
3471 m_panLayer->setBaseColour 3512 m_panLayer->setBaseColour
3472 (ColourDatabase::getInstance()->getColourIndex(tr("Green"))); 3513 (ColourDatabase::getInstance()->getColourIndex(tr("Green")));
3473 } 3514 }
3474 } 3515 }
3475 } 3516 }
3476 3517
3477 void 3518 void
3478 MainWindow::propertyStacksResized(int width) 3519 MainWindow::propertyStacksResized(int width)
3479 { 3520 {
3480 // SVDEBUG << "MainWindow::propertyStacksResized(" << width << ")" << endl; 3521 // SVDEBUG << "MainWindow::propertyStacksResized(" << width << ")" << endl;
3481 3522
3482 if (!m_playControlsSpacer) return; 3523 if (!m_playControlsSpacer) return;
3483 3524
3484 int spacerWidth = width - m_playControlsWidth - 4; 3525 int spacerWidth = width - m_playControlsWidth - 4;
3485 3526
3486 // SVDEBUG << "resizing spacer from " << m_playControlsSpacer->width() << " to " << spacerWidth << endl; 3527 // SVDEBUG << "resizing spacer from " << m_playControlsSpacer->width() << " to " << spacerWidth << endl;
3487 3528
3488 m_playControlsSpacer->setFixedSize(QSize(spacerWidth, 2)); 3529 m_playControlsSpacer->setFixedSize(QSize(spacerWidth, 2));
3489 } 3530 }
3490 3531
3543 (LayerFactory::TimeRuler); 3584 (LayerFactory::TimeRuler);
3544 } 3585 }
3545 3586
3546 // SVDEBUG << "adding time ruler layer " << m_timeRulerLayer << endl; 3587 // SVDEBUG << "adding time ruler layer " << m_timeRulerLayer << endl;
3547 3588
3548 m_document->addLayerToView(pane, m_timeRulerLayer); 3589 m_document->addLayerToView(pane, m_timeRulerLayer);
3549 } 3590 }
3550 3591
3551 Layer *newLayer = m_document->createLayer(configuration.layer); 3592 Layer *newLayer = m_document->createLayer(configuration.layer);
3552 3593
3553 Model *suggestedModel = configuration.sourceModel; 3594 Model *suggestedModel = configuration.sourceModel;
3595 void 3636 void
3596 MainWindow::addLayer() 3637 MainWindow::addLayer()
3597 { 3638 {
3598 QObject *s = sender(); 3639 QObject *s = sender();
3599 QAction *action = dynamic_cast<QAction *>(s); 3640 QAction *action = dynamic_cast<QAction *>(s);
3600 3641
3601 if (!action) { 3642 if (!action) {
3602 cerr << "WARNING: MainWindow::addLayer: sender is not an action" 3643 cerr << "WARNING: MainWindow::addLayer: sender is not an action"
3603 << endl; 3644 << endl;
3604 return; 3645 return;
3605 } 3646 }
3606 3647
3607 Pane *pane = m_paneStack->getCurrentPane(); 3648 Pane *pane = m_paneStack->getCurrentPane();
3608 3649
3609 if (!pane) { 3650 if (!pane) {
3610 cerr << "WARNING: MainWindow::addLayer: no current pane" << endl; 3651 cerr << "WARNING: MainWindow::addLayer: no current pane" << endl;
3611 return; 3652 return;
3612 } 3653 }
3613 3654
3614 ExistingLayerActionMap::iterator ei = m_existingLayerActions.find(action); 3655 ExistingLayerActionMap::iterator ei = m_existingLayerActions.find(action);
3615 3656
3616 if (ei != m_existingLayerActions.end()) { 3657 if (ei != m_existingLayerActions.end()) {
3617 Layer *newLayer = ei->second; 3658 Layer *newLayer = ei->second;
3618 m_document->addLayerToView(pane, newLayer); 3659 m_document->addLayerToView(pane, newLayer);
3619 m_paneStack->setCurrentLayer(pane, newLayer); 3660 m_paneStack->setCurrentLayer(pane, newLayer);
3620 return; 3661 return;
3621 } 3662 }
3622 3663
3623 ei = m_sliceActions.find(action); 3664 ei = m_sliceActions.find(action);
3624 3665
3625 if (ei != m_sliceActions.end()) { 3666 if (ei != m_sliceActions.end()) {
3632 dest->setSliceableModel(source->getSliceableModel()); 3673 dest->setSliceableModel(source->getSliceableModel());
3633 connect(source, SIGNAL(sliceableModelReplaced(const Model *, const Model *)), 3674 connect(source, SIGNAL(sliceableModelReplaced(const Model *, const Model *)),
3634 dest, SLOT(sliceableModelReplaced(const Model *, const Model *))); 3675 dest, SLOT(sliceableModelReplaced(const Model *, const Model *)));
3635 connect(m_document, SIGNAL(modelAboutToBeDeleted(Model *)), 3676 connect(m_document, SIGNAL(modelAboutToBeDeleted(Model *)),
3636 dest, SLOT(modelAboutToBeDeleted(Model *))); 3677 dest, SLOT(modelAboutToBeDeleted(Model *)));
3637 } 3678
3638 m_document->addLayerToView(pane, newLayer); 3679 }
3639 m_paneStack->setCurrentLayer(pane, newLayer); 3680 m_document->addLayerToView(pane, newLayer);
3640 return; 3681 m_paneStack->setCurrentLayer(pane, newLayer);
3682 return;
3641 } 3683 }
3642 3684
3643 TransformActionMap::iterator i = m_transformActions.find(action); 3685 TransformActionMap::iterator i = m_transformActions.find(action);
3644 3686
3645 if (i == m_transformActions.end()) { 3687 if (i == m_transformActions.end()) {
3660 Layer *newLayer = 0; 3702 Layer *newLayer = 0;
3661 3703
3662 if (emptyTypes.find(type) != emptyTypes.end()) { 3704 if (emptyTypes.find(type) != emptyTypes.end()) {
3663 3705
3664 newLayer = m_document->createEmptyLayer(type); 3706 newLayer = m_document->createEmptyLayer(type);
3707
3665 if (newLayer) { 3708 if (newLayer) {
3666 m_toolActions[ViewManager::DrawMode]->trigger(); 3709 m_toolActions[ViewManager::DrawMode]->trigger();
3667 } 3710 }
3668 3711
3669 } else { 3712 } else {
3670 3713
3671 Model *model = i->second.sourceModel; 3714 Model *model = i->second.sourceModel;
3672 3715
3673 cerr << "model = "<< model << endl; 3716 cerr << "model = "<< model << endl;
3674 3717
3709 if (newLayer) { 3752 if (newLayer) {
3710 m_document->addLayerToView(pane, newLayer); 3753 m_document->addLayerToView(pane, newLayer);
3711 m_paneStack->setCurrentLayer(pane, newLayer); 3754 m_paneStack->setCurrentLayer(pane, newLayer);
3712 } 3755 }
3713 3756
3714 return; 3757 return;
3715 } 3758 }
3716 3759
3717 //!!! want to do something like this, but it's not supported in 3760 //!!! want to do something like this, but it's not supported in
3718 //ModelTransformerFactory yet 3761 //ModelTransformerFactory yet
3719 /* 3762 /*
3720 int channel = -1; 3763 int channel = -1;
3721 // pick up the default channel from any existing layers on the same pane 3764 // pick up the default channel from any existing layers on the same pane
3722 for (int j = 0; j < pane->getLayerCount(); ++j) { 3765 for (int j = 0; j < pane->getLayerCount(); ++j) {
3723 int c = LayerFactory::getInstance()->getChannel(pane->getLayer(j)); 3766 int c = LayerFactory::getInstance()->getChannel(pane->getLayer(j));
3724 if (c != -1) { 3767 if (c != -1) {
3725 channel = c; 3768 channel = c;
3726 break; 3769 break;
3727 } 3770 }
3728 } 3771 }
3729 */ 3772 */
3730 3773
3731 // We always ask for configuration, even if the plugin isn't 3774 // We always ask for configuration, even if the plugin isn't
3732 // supposed to be configurable, because we need to let the user 3775 // supposed to be configurable, because we need to let the user
3736 3779
3737 addLayer(transformId); 3780 addLayer(transformId);
3738 } 3781 }
3739 3782
3740 void 3783 void
3741 MainWindow::addLayer(QString transformId) 3784 MainWindow:: addLayer(QString transformId)
3742 { 3785 {
3743 Pane *pane = m_paneStack->getCurrentPane(); 3786 Pane *pane = m_paneStack->getCurrentPane();
3744 if (!pane) { 3787 if (!pane) {
3745 cerr << "WARNING: MainWindow::addLayer: no current pane" << endl; 3788 cerr << "WARNING: MainWindow::addLayer: no current pane" << endl;
3746 return; 3789 return;
3794 } 3837 }
3795 } 3838 }
3796 3839
3797 sv_frame_t startFrame = 0, duration = 0; 3840 sv_frame_t startFrame = 0, duration = 0;
3798 sv_frame_t endFrame = 0; 3841 sv_frame_t endFrame = 0;
3842
3799 m_viewManager->getSelection().getExtents(startFrame, endFrame); 3843 m_viewManager->getSelection().getExtents(startFrame, endFrame);
3800 if (endFrame > startFrame) duration = endFrame - startFrame; 3844 if (endFrame > startFrame) duration = endFrame - startFrame;
3801 else startFrame = 0; 3845 else startFrame = 0;
3802 3846
3803 TransformUserConfigurator configurator; 3847 TransformUserConfigurator configurator;
3831 void 3875 void
3832 MainWindow::renameCurrentLayer() 3876 MainWindow::renameCurrentLayer()
3833 { 3877 {
3834 Pane *pane = m_paneStack->getCurrentPane(); 3878 Pane *pane = m_paneStack->getCurrentPane();
3835 if (pane) { 3879 if (pane) {
3836 Layer *layer = pane->getSelectedLayer(); 3880 Layer *layer = pane->getSelectedLayer();
3837 if (layer) { 3881 if (layer) {
3838 bool ok = false; 3882 bool ok = false;
3839 QString newName = QInputDialog::getText 3883 QString newName = QInputDialog::getText
3840 (this, tr("Rename Layer"), 3884 (this, tr("Rename Layer"),
3841 tr("New name for this layer:"), 3885 tr("New name for this layer:"),
3842 QLineEdit::Normal, layer->objectName(), &ok); 3886 QLineEdit::Normal, layer->objectName(), &ok);
3843 if (ok) { 3887 if (ok) {
3844 layer->setPresentationName(newName); 3888 layer->setPresentationName(newName);
3845 setupExistingLayersMenus(); 3889 setupExistingLayersMenus();
3846 } 3890 }
3847 } 3891 }
3848 } 3892 }
3849 } 3893 }
3850 3894
3851 void 3895 void
3852 MainWindow::findTransform() 3896 MainWindow::findTransform()
3856 delete finder; 3900 delete finder;
3857 return; 3901 return;
3858 } 3902 }
3859 TransformId transform = finder->getTransform(); 3903 TransformId transform = finder->getTransform();
3860 delete finder; 3904 delete finder;
3861 3905
3862 if (getMainModel() != 0 && m_paneStack->getCurrentPane() != 0) { 3906 if (getMainModel() != 0 && m_paneStack->getCurrentPane() != 0) {
3863 addLayer(transform); 3907 addLayer(transform);
3864 } 3908 }
3865 } 3909 }
3866 3910
3873 3917
3874 void 3918 void
3875 MainWindow::alignToggled() 3919 MainWindow::alignToggled()
3876 { 3920 {
3877 QAction *action = dynamic_cast<QAction *>(sender()); 3921 QAction *action = dynamic_cast<QAction *>(sender());
3878 3922
3879 if (!m_viewManager) return; 3923 if (!m_viewManager) return;
3880 3924
3881 if (action) { 3925 if (action) {
3882 m_viewManager->setAlignMode(action->isChecked()); 3926 m_viewManager->setAlignMode(action->isChecked());
3883 } else { 3927 } else {
3884 m_viewManager->setAlignMode(!m_viewManager->getAlignMode()); 3928 m_viewManager->setAlignMode(!m_viewManager->getAlignMode());
3885 } 3929 }
3886 3930
3887 if (m_viewManager->getAlignMode()) { 3931 if (m_viewManager->getAlignMode()) {
3888 m_prevSolo = m_soloAction->isChecked(); 3932 m_prevSolo = m_soloAction->isChecked();
3889 if (!m_soloAction->isChecked()) { 3933 if (!m_soloAction->isChecked()) {
3905 m_document->setAutoAlignment(false); 3949 m_document->setAutoAlignment(false);
3906 } 3950 }
3907 3951
3908 for (int i = 0; i < m_paneStack->getPaneCount(); ++i) { 3952 for (int i = 0; i < m_paneStack->getPaneCount(); ++i) {
3909 3953
3910 Pane *pane = m_paneStack->getPane(i); 3954 Pane *pane = m_paneStack->getPane(i);
3911 if (!pane) continue; 3955 if (!pane) continue;
3912 3956
3913 pane->update(); 3957 pane->update();
3914 } 3958 }
3915 } 3959 }
3916 3960
4009 for (int i = pane->getLayerCount(); i > 0; ) { 4053 for (int i = pane->getLayerCount(); i > 0; ) {
4010 --i; 4054 --i;
4011 Layer *layer = pane->getLayer(i); 4055 Layer *layer = pane->getLayer(i);
4012 if (LayerFactory::getInstance()->getLayerType(layer) == 4056 if (LayerFactory::getInstance()->getLayerType(layer) ==
4013 LayerFactory::Waveform) { 4057 LayerFactory::Waveform) {
4014 RangeSummarisableTimeValueModel *tvm = 4058 RangeSummarisableTimeValueModel *tvm =
4015 dynamic_cast<RangeSummarisableTimeValueModel *>(layer->getModel()); 4059 dynamic_cast<RangeSummarisableTimeValueModel *>(layer->getModel());
4016 if (tvm) { 4060 if (tvm) {
4017 m_panLayer->setModel(tvm); 4061 m_panLayer->setModel(tvm);
4018 return; 4062 return;
4019 } 4063 }
4117 emit hideSplash(); 4161 emit hideSplash();
4118 QMessageBox::information 4162 QMessageBox::information
4119 (this, tr("Sample rate mismatch"), 4163 (this, tr("Sample rate mismatch"),
4120 tr("<b>Wrong sample rate</b><p>The sample rate of this audio file (%1 Hz) does not match\nthe current playback rate (%2 Hz).<p>The file will play at the wrong speed and pitch.<p>Change the <i>Resample mismatching files on import</i> option under <i>File</i> -> <i>Preferences</i> if you want to alter this behaviour.") 4164 tr("<b>Wrong sample rate</b><p>The sample rate of this audio file (%1 Hz) does not match\nthe current playback rate (%2 Hz).<p>The file will play at the wrong speed and pitch.<p>Change the <i>Resample mismatching files on import</i> option under <i>File</i> -> <i>Preferences</i> if you want to alter this behaviour.")
4121 .arg(requested).arg(actual)); 4165 .arg(requested).arg(actual));
4122 } 4166 }
4123 4167
4124 updateDescriptionLabel(); 4168 updateDescriptionLabel();
4125 } 4169 }
4126 4170
4127 void 4171 void
4237 // layer that may be insertable-into 4281 // layer that may be insertable-into
4238 4282
4239 if (!noteOn) continue; 4283 if (!noteOn) continue;
4240 insertInstantAt(ev.getTime()); 4284 insertInstantAt(ev.getTime());
4241 } 4285 }
4242 } 4286 }
4243 4287
4244 void 4288 void
4245 MainWindow::playStatusChanged(bool ) 4289 MainWindow::playStatusChanged(bool )
4246 { 4290 {
4247 Pane *currentPane = 0; 4291 Pane *currentPane = 0;
4321 { 4365 {
4322 QAction *a = dynamic_cast<QAction *>(sender()); 4366 QAction *a = dynamic_cast<QAction *>(sender());
4323 if (!a) return; 4367 if (!a) return;
4324 4368
4325 int type = m_numberingActions[a]; 4369 int type = m_numberingActions[a];
4326 4370
4327 if (m_labeller) m_labeller->setType(Labeller::ValueType(type)); 4371 if (m_labeller) m_labeller->setType(Labeller::ValueType(type));
4328 4372
4329 QSettings settings; 4373 QSettings settings;
4330 settings.beginGroup("MainWindow"); 4374 settings.beginGroup("MainWindow");
4331 settings.setValue("labellertype", type); 4375 settings.setValue("labellertype", type);
4335 void 4379 void
4336 MainWindow::setInstantsCounterCycle() 4380 MainWindow::setInstantsCounterCycle()
4337 { 4381 {
4338 QAction *a = dynamic_cast<QAction *>(sender()); 4382 QAction *a = dynamic_cast<QAction *>(sender());
4339 if (!a) return; 4383 if (!a) return;
4340 4384
4341 int cycle = a->text().toInt(); 4385 int cycle = a->text().toInt();
4342 if (cycle == 0) return; 4386 if (cycle == 0) return;
4343 4387
4344 if (m_labeller) m_labeller->setCounterCycleSize(cycle); 4388 if (m_labeller) m_labeller->setCounterCycleSize(cycle);
4345 4389
4346 QSettings settings; 4390 QSettings settings;
4347 settings.beginGroup("MainWindow"); 4391 settings.beginGroup("MainWindow");
4348 settings.setValue("labellercycle", cycle); 4392 settings.setValue("labellercycle", cycle);
4349 settings.endGroup(); 4393 settings.endGroup();
4350 } 4394 }
4678 "<p><small>This program is free software; you can redistribute it and/or " 4722 "<p><small>This program is free software; you can redistribute it and/or "
4679 "modify it under the terms of the GNU General Public License as " 4723 "modify it under the terms of the GNU General Public License as "
4680 "published by the Free Software Foundation; either version 2 of the " 4724 "published by the Free Software Foundation; either version 2 of the "
4681 "License, or (at your option) any later version.<br>See the file " 4725 "License, or (at your option) any later version.<br>See the file "
4682 "COPYING included with this distribution for more information.</small></p>"; 4726 "COPYING included with this distribution for more information.</small></p>";
4683 4727
4684 QMessageBox::about(this, tr("About Sonic Visualiser"), aboutText); 4728 QMessageBox::about(this, tr("About Sonic Visualiser"), aboutText);
4685 } 4729 }
4686 4730
4687 void 4731 void
4688 MainWindow::keyReference() 4732 MainWindow::keyReference()
4704 } 4748 }
4705 settings.endGroup(); 4749 settings.endGroup();
4706 } 4750 }
4707 4751
4708 4752
4753
4754 CheckBox::CheckBox(QWidget *parent)
4755 : QWidget(parent)
4756 {
4757 // SELECTION RULES
4758 QGroupBox *selrule_box = new QGroupBox(QString::fromUtf8("SELECTION RULES"),this);
4759 selrule_box->setFont(QFont("Times", 9, QFont::Bold));
4760 selrule_box->move(5,5);
4761 selrule_box->resize(235,130);
4762 QButtonGroup *selrule_group = new QButtonGroup(this);
4763 selrule_group->setObjectName("Selection Rule");
4764
4765 QRadioButton *minmax_rule = new QRadioButton(QString::fromUtf8("Min/Max Rule"),this);
4766 minmax_rule->move(20,25);
4767 minmax_rule->setObjectName("0");
4768 QRadioButton *exclusion_rule = new QRadioButton(QString::fromUtf8("Exclusion Rule"),this);
4769 exclusion_rule->move(20,45);
4770 exclusion_rule->setObjectName("1");
4771 QRadioButton *notmute_rule = new QRadioButton(QString::fromUtf8("Not Mute Rule"),this);
4772 notmute_rule->move(130,25);
4773 notmute_rule->setObjectName("2");
4774 QRadioButton *implication_rule = new QRadioButton(QString::fromUtf8("Implication Rule"),this);
4775 implication_rule->move(130,45);
4776 implication_rule->setObjectName("3");
4777
4778 selrule_group->addButton(minmax_rule);
4779 selrule_group->addButton(exclusion_rule);
4780 selrule_group->addButton(notmute_rule);
4781 selrule_group->addButton(implication_rule);
4782
4783 QSpinBox *sel_par1 = new QSpinBox(this);
4784 sel_par1->setEnabled(true);
4785 sel_par1->setGeometry(QRect(20, 75, 40, 20));
4786 sel_par1->setMinimum(1);
4787 sel_par1->setMaximum(numtracks);
4788 selrule_par1 = sel_par1->value();
4789
4790 sel_rule1 = new QLabel(this);
4791 sel_rule1->setText("Parameter 1");
4792 sel_rule1->setGeometry(70, 75, 100, 20);
4793
4794 QSpinBox *sel_par2 = new QSpinBox(this);
4795 sel_par2->setEnabled(true);
4796 sel_par2->setGeometry(QRect(20, 100, 40, 20));
4797 sel_par2->setMinimum(1);
4798 sel_par2->setMaximum(numtracks);
4799 selrule_par2 = sel_par2->value();
4800
4801 sel_rule2 = new QLabel(this);
4802 sel_rule2->setText("Parameter 2");
4803 sel_rule2->setGeometry(70, 100, 100, 20);
4804
4805 connect(selrule_group, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(set_selruleType(QAbstractButton*)));
4806 connect(sel_par1, SIGNAL(valueChanged(int)), this, SLOT(set_selrulePAR1(int)));
4807 connect(sel_par2, SIGNAL(valueChanged(int)), this, SLOT(set_selrulePAR2(int)));
4808
4809 // MIXING RULES (yet to implement)
4810 QGroupBox *mixrule_box = new QGroupBox(QString::fromUtf8("MIXING RULES"),this);
4811 mixrule_box->setFont(QFont("Times", 9, QFont::Bold));
4812 mixrule_box->move(255,5);
4813 mixrule_box->resize(330,130);
4814 QButtonGroup *mixrule_group = new QButtonGroup(this);
4815 mixrule_group->setObjectName("Mixing Rule");
4816
4817 QRadioButton *equivalence_rule = new QRadioButton(QString::fromUtf8("Equivalence Rule"),this);
4818 equivalence_rule->move(270,25);
4819 equivalence_rule->setObjectName("0");
4820 QRadioButton *upper_rule = new QRadioButton(QString::fromUtf8("Upper Rule"),this);
4821 upper_rule->move(270,45);
4822 upper_rule->setObjectName("1");
4823 QRadioButton *lower_rule = new QRadioButton(QString::fromUtf8("Lower Rule"),this);
4824 lower_rule->move(380,25);
4825 lower_rule->setObjectName("2");
4826 QRadioButton *limit_rule = new QRadioButton(QString::fromUtf8("Limit Rule"),this);
4827 limit_rule->move(380,45);
4828 limit_rule->setObjectName("3");
4829
4830 mixrule_group->addButton(equivalence_rule);
4831 mixrule_group->addButton(upper_rule);
4832 mixrule_group->addButton(lower_rule);
4833 mixrule_group->addButton(limit_rule);
4834
4835 QSpinBox *mix_par1 = new QSpinBox(this);
4836 mix_par1->setEnabled(true);
4837 mix_par1->setGeometry(QRect(270, 75, 40, 20));
4838 mix_par1->setMinimum(1);
4839 mix_par1->setMaximum(numtracks);
4840 mixrule_par1 = mix_par1->value();
4841
4842 mix_rule1 = new QLabel(this);
4843 mix_rule1->setText("Parameter 1");
4844 mix_rule1->setGeometry(320, 75, 100, 20);
4845
4846 QSpinBox *mix_par2 = new QSpinBox(this);
4847 mix_par2->setEnabled(true);
4848 mix_par2->setGeometry(QRect(270, 100, 40, 20));
4849 mix_par2->setMinimum(1);
4850 mix_par2->setMaximum(numtracks);
4851 mixrule_par2 = mix_par2->value();
4852
4853 mix_rule2 = new QLabel(this);
4854 mix_rule2->setText("Parameter 2");
4855 mix_rule2->setGeometry(320, 100, 100, 20);
4856
4857 QSpinBox *mix_par3 = new QSpinBox(this);
4858 mix_par3->setEnabled(true);
4859 mix_par3->setGeometry(QRect(410, 75, 40, 20));
4860 mix_par3->setMinimum(0);
4861 mix_par3->setMaximum(100);
4862 mixrule_par3 = mix_par3->value();
4863
4864 mix_rule3 = new QLabel(this);
4865 mix_rule3->setText("Parameter 3");
4866 mix_rule3->setGeometry(460, 75, 100, 20);
4867
4868 QSpinBox *mix_par4 = new QSpinBox(this);
4869 mix_par4->setEnabled(true);
4870 mix_par4->setGeometry(QRect(410, 100, 40, 20));
4871 mix_par4->setMinimum(0);
4872 mix_par4->setMaximum(100);
4873 mixrule_par4 = mix_par4->value();
4874
4875 mix_rule4 = new QLabel(this);
4876 mix_rule4->setText("Parameter 4");
4877 mix_rule4->setGeometry(460, 100, 100, 20);
4878
4879 connect(mixrule_group, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(set_mixruleType(QAbstractButton*)));
4880 connect(mix_par1, SIGNAL(valueChanged(int)), this, SLOT(set_mixrulePAR1(int)));
4881 connect(mix_par2, SIGNAL(valueChanged(int)), this, SLOT(set_mixrulePAR2(int)));
4882 connect(mix_par3, SIGNAL(valueChanged(int)), this, SLOT(set_mixrulePAR3(int)));
4883 connect(mix_par4, SIGNAL(valueChanged(int)), this, SLOT(set_mixrulePAR4(int)));
4884 // connect(equivalence_rule, SIGNAL(toggled(bool)), mix_rule1, SLOT()
4885
4886 // GROUPS
4887 QGroupBox *group_box = new QGroupBox(QString::fromUtf8("GROUPS"),this);
4888 group_box->setFont(QFont("Times", 9, QFont::Bold));
4889 group_box->move(5,150);
4890 group_box->resize(580,100);
4891
4892 group_label = new QLabel(this);
4893 group_label->setText("Select tracks for the group:");
4894 group_label->setGeometry(20, 165, 200, 20);
4895
4896 QButtonGroup *group_cb = new QButtonGroup(this);
4897 group_cb->setObjectName("Group");
4898
4899 for (int i=1; i<=numtracks; i++) {
4900 QCheckBox *track_cb = new QCheckBox(QString::number(i), this);
4901 track_cb->setGeometry(80*i,185,95,30);
4902 track_cb->setObjectName(QString::number(i));
4903 group_cb->setExclusive(false);
4904 group_cb->addButton(track_cb);
4905 }
4906
4907 QSpinBox *group_vol = new QSpinBox(this);
4908 group_vol->setEnabled(true);
4909 group_vol->setGeometry(QRect(280, 220, 40, 20));
4910 group_vol->setMinimum(0);
4911 group_vol->setMaximum(100);
4912 group_vol->setValue(100);
4913 group_volume = group_vol->value();
4914
4915 grp_vol = new QLabel(this);
4916 grp_vol->setText("Group Volume");
4917 grp_vol->setGeometry(330, 220, 100, 20);
4918
4919 group_name_line = new QLineEdit(this);
4920 group_name_line->setGeometry(25,220,150,20);
4921 group_name_line->setText("Insert a name");
4922 group_name_line->setMaxLength(20);
4923
4924 grp_name = new QLabel(this);
4925 grp_name->setText("Group Name");
4926 grp_name->setGeometry(180,220,100,20);
4927
4928 connect(group_cb, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(set_TrackInGroup(QAbstractButton*)));
4929 connect(group_name_line, SIGNAL(textChanged(QString)), this, SLOT(set_GroupName(QString)));
4930 connect(group_vol, SIGNAL(valueChanged(int)), this, SLOT(set_GroupVolume(int)));
4931
4932 // PRESETS
4933 QGroupBox *preset_box = new QGroupBox(QString::fromUtf8("PRESETS"),this);
4934 preset_box->setFont(QFont("Times", 9, QFont::Bold));
4935 preset_box->move(5,270);
4936 preset_box->resize(580,90);
4937
4938 QButtonGroup *preset_group = new QButtonGroup(this);
4939 preset_group->setObjectName("Presets");
4940
4941 QRadioButton *static_preset = new QRadioButton(QString::fromUtf8("Static Volume"),this);
4942 static_preset->move(20,290);
4943 static_preset->setObjectName("0");
4944
4945 QRadioButton *dynamic_preset = new QRadioButton(QString::fromUtf8("Dynamic Volume"),this);
4946 dynamic_preset->move(150,290);
4947 dynamic_preset->setObjectName("4");
4948
4949 preset_group->addButton(static_preset);
4950 preset_group->addButton(dynamic_preset);
4951
4952 QButtonGroup *fade_group = new QButtonGroup(this);
4953 fade_group->setObjectName("Fade IN/OUT");
4954
4955 QRadioButton *fade_in = new QRadioButton(QString::fromUtf8("Fade IN"),this);
4956 fade_in->move(170,310);
4957 fade_in->setObjectName("1");
4958 fade_in->setDisabled(true);
4959
4960 QRadioButton *fade_out = new QRadioButton(QString::fromUtf8("Fade OUT"),this);
4961 fade_out->move(170,330);
4962 fade_out->setObjectName("0");
4963 fade_out->setDisabled(true);
4964
4965 fade_group->addButton(fade_in);
4966 fade_group->addButton(fade_out);
4967
4968 connect(preset_group, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(set_presetType(QAbstractButton*)));
4969 connect(dynamic_preset, SIGNAL(toggled(bool)), fade_in, SLOT(setEnabled(bool)));
4970 connect(dynamic_preset, SIGNAL(toggled(bool)), fade_out, SLOT(setEnabled(bool)));
4971 connect(fade_group, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(set_fade(QAbstractButton*)));
4972
4973
4974 // IMAGE AND LYRICS
4975 QCheckBox *text_cb = new QCheckBox("Include lyrics", this);
4976 text_cb->setGeometry(20, 380, 95, 30);
4977 QCheckBox *jpeg_cb = new QCheckBox("Include picture", this);
4978 jpeg_cb->setGeometry(20, 430, 95, 30);
4979
4980 line->setGeometry(120, 380, 320, 30);
4981 line2->setGeometry(120, 430, 320, 30);
4982
4983 QPushButton *create = new QPushButton("Export", this);
4984 create->setGeometry(20, 500, 95, 30);
4985
4986 QPushButton *TextFilePath = new QPushButton("Select text file", this);
4987 TextFilePath->setGeometry(460, 380, 95, 30);
4988 TextFilePath->setDisabled(true);
4989
4990 QPushButton *JpegFilePath = new QPushButton("Select JPEG file", this);
4991 JpegFilePath->setGeometry(460, 430, 95, 30);
4992 JpegFilePath->setDisabled(true);
4993
4994 // Enable/disable push buttons
4995 connect(text_cb, SIGNAL(toggled(bool)), TextFilePath, SLOT(setEnabled(bool)));
4996 connect(jpeg_cb, SIGNAL(toggled(bool)), JpegFilePath, SLOT(setEnabled(bool)));
4997 // Check the inclusion of image and text
4998 connect(text_cb, SIGNAL(stateChanged(int)), this, SLOT(insertLyrics(int))); // yet to implement
4999 connect(jpeg_cb, SIGNAL(stateChanged(int)), this, SLOT(insertImage(int)));
5000 // Set image and text paths
5001 connect(TextFilePath, SIGNAL(clicked()), this , SLOT(defineImafTextFile()));
5002 connect(JpegFilePath, SIGNAL(clicked()), this , SLOT(defineImafImageFile()));
5003 // Create the file
5004 connect(create, SIGNAL(clicked()), this , SLOT(saveImafFile()));
5005 connect(create, SIGNAL(clicked()), this, SLOT(close()));
5006 }
5007
5008 void CheckBox::insertImage(int state)
5009 {
5010 if (state) {
5011 has_image = true;
5012 } else{
5013 has_image = false;
5014 }
5015 }
5016
5017 void CheckBox::insertLyrics(int state)
5018 {
5019 if (state) {
5020 has_lyrics = true;
5021 } else{
5022 has_lyrics = false;
5023 }
5024 }
5025
5026 void CheckBox::saveImafFile()
5027 {
5028 ImafFileName = QFileDialog::getSaveFileName(this, tr("Save IMAF"), "/", tr("IMAF (*.ima)"));
5029
5030 group_descr = "Thisgroup";
5031
5032 if( ImafFileName != "" ){ //if the user press cancel the function mainIMAFencoder won´t be called
5033 mainIMAFencoder(numtracks, files_paths, ImafFileName, ImageFileName, TextFileName,
5034 ImafVolumeValues, has_image, has_lyrics, selrule_type, selrule_par1, selrule_par2,
5035 mixrule_type, mixrule_par1, mixrule_par2, mixrule_par3, mixrule_par4,
5036 group_tracks, group_volume, group_name, group_descr, preset_type, fade_in);
5037 }
5038 }
5039
5040 void CheckBox::defineImafImageFile()
5041 {
5042 ImageFileName = QFileDialog::getOpenFileName(this, tr("Select JPEG"), "/", tr("JPEG (*.jpg)"));
5043 line2->setText(ImageFileName);
5044 }
5045
5046 void CheckBox::defineImafTextFile()
5047 {
5048 TextFileName = QFileDialog::getOpenFileName(this, tr("Select text file"), "/", tr("Text File (*.3gp)"));
5049 line->setText(TextFileName);
5050 }
5051
5052 void
5053 MainWindow::exportIMAF()
5054 {
5055 numtracks = m_paneStack->getPaneCount();
5056
5057 for (int i = 0; i < numtracks; ++i) {
5058 //ImafVolumeValues[i] = int(m_paneStack->getPane(i)->getLayer(0)->getPlayParameters()->getVolImaf())/2;
5059 }
5060
5061 CheckBox *imaf_window = new CheckBox();
5062
5063 imaf_window->resize(600,540);
5064 imaf_window->move(100,100);
5065 imaf_window->setWindowTitle("Export IMAF");
5066 imaf_window->show();
5067 }
5068
5069
5070
5071 void MainWindow::insertLyrics(size_t frame, QString text){
5072 Pane *pane = m_paneStack->getCurrentPane();
5073
5074
5075 pane = m_paneStack->getCurrentPane();
5076 if (!pane) {
5077 return;
5078 }
5079
5080 frame = pane->alignFromReference(frame);
5081
5082 Layer *layer = dynamic_cast<TimeInstantLayer *>
5083 (pane->getSelectedLayer());
5084
5085 if (!layer) {
5086 for (int i = pane->getLayerCount(); i > 0; --i) {
5087 layer = dynamic_cast<TimeInstantLayer *>(pane->getLayer(i - 1));
5088 if (layer) break;
5089 }
5090
5091 if (!layer) {
5092 CommandHistory::getInstance()->startCompoundOperation
5093 (tr("Add Point"), true);
5094 layer = m_document->createEmptyLayer(LayerFactory::TimeInstants);
5095 if (layer) {
5096 m_document->addLayerToView(pane, layer);
5097 m_paneStack->setCurrentLayer(pane, layer);
5098 }
5099 CommandHistory::getInstance()->endCompoundOperation();
5100 }
5101 }
5102
5103 if (layer) {
5104
5105 Model *model = layer->getModel();
5106 SparseOneDimensionalModel *sodm = dynamic_cast<SparseOneDimensionalModel *>
5107 (model);
5108
5109 if (sodm) {
5110 SparseOneDimensionalModel::Point point(frame, "");
5111
5112 SparseOneDimensionalModel::Point prevPoint(0);
5113 bool havePrevPoint = false;
5114
5115 SparseOneDimensionalModel::EditCommand *command =
5116 new SparseOneDimensionalModel::EditCommand(sodm, tr("Add Point"));
5117
5118 if (m_labeller->requiresPrevPoint()) {
5119
5120 SparseOneDimensionalModel::PointList prevPoints =
5121 sodm->getPreviousPoints(frame);
5122
5123 if (!prevPoints.empty()) {
5124 prevPoint = *prevPoints.begin();
5125 havePrevPoint = true;
5126 }
5127 }
5128
5129 if (m_labeller) {
5130
5131 m_labeller->setSampleRate(sodm->getSampleRate());
5132
5133 if (m_labeller->actingOnPrevPoint()) {
5134 command->deletePoint(prevPoint);
5135 }
5136
5137 m_labeller->label<SparseOneDimensionalModel::Point>
5138 (point, havePrevPoint ? &prevPoint : 0);
5139
5140 if (m_labeller->actingOnPrevPoint()) {
5141 command->addPoint(prevPoint);
5142 }
5143 }
5144 point.label=text;
5145 command->addPoint(point);
5146
5147 command->setName(tr("Add Point at %1 s")
5148 .arg(RealTime::frame2RealTime
5149 (frame,
5150 sodm->getSampleRate())
5151 .toText(false).c_str()));
5152
5153 Command *c = command->finish();
5154 if (c) CommandHistory::getInstance()->addCommand(c, false);
5155 }
5156 }
5157
5158 }
5159
5160 void MainWindow::importIMAF()
5161 {
5162
5163 int haslyrics; // if this variable != 2 -> there are lyrics
5164 QString path = getOpenFileName(FileFinder::IMAFile);
5165
5166 if (path.isEmpty()) return;
5167 isIMAF = true;
5168
5169 haslyrics = mainIMAFdecoder(path);
5170
5171 openMP3IMAF();
5172
5173 if (haslyrics!=2){
5174 addPaneToStack();//it creates a new pane to show the lyrics
5175
5176 Pane *pane = m_paneStack->getCurrentPane();
5177 LayerFactory::LayerType type ; //set the type of layer
5178 type = LayerFactory::TimeInstants;
5179 //create a new layer
5180 Layer *newLayer = 0;
5181 newLayer = m_document->createEmptyLayer(type);
5182 m_toolActions[ViewManager::DrawMode]->trigger();
5183 m_document->addLayerToView(pane, newLayer);
5184
5185 //create a new layer
5186 Layer *newLayer1 = 0;
5187 newLayer1 = m_document->createEmptyLayer(type);
5188 m_toolActions[ViewManager::DrawMode]->trigger();
5189 m_document->addLayerToView(pane, newLayer1);
5190 m_paneStack->setCurrentLayer(pane, newLayer);
5191
5192 //editCurrentLayer();
5193
5194 //text decoder
5195 unsigned char dat,dat1,dat2,dat3;
5196 FILE *imf;
5197 imf = fopen (path.toStdString().c_str(),"rb");
5198
5199 fseek (imf,0,SEEK_SET);
5200 fseek (imf,24,SEEK_CUR); //jump to 'mdat'
5201 fread(&dat, sizeof(unsigned char), 1, imf);
5202 fread(&dat1, sizeof(unsigned char), 1, imf);
5203 fread(&dat2, sizeof(unsigned char), 1, imf);
5204 fread(&dat3, sizeof(unsigned char), 1, imf);
5205 int sizemdat = (dat<<24) | (dat1<<16) | (dat2<<8) | (dat3);
5206 fseek(imf, sizemdat-4, SEEK_CUR); // -4 because we have to sub the 4 bytes of size
5207
5208 fseek (imf,16,SEEK_CUR);
5209 fseek (imf,96,SEEK_CUR); // next track id is placed 96 bytes after the last byte of type 'mvhd'
5210
5211 fread(&dat, sizeof(unsigned char), 1, imf);
5212 fread(&dat1, sizeof(unsigned char), 1, imf);
5213 fread(&dat2, sizeof(unsigned char), 1, imf);
5214 fread(&dat3, sizeof(unsigned char), 1, imf);
5215
5216
5217 audiotracks = ((dat<<24) | (dat1<<16) | (dat2<<8) | (dat3)) -1 ; //read the number of audio tracks.It is ´-1´ because the field indicates the number of tracks +1
5218
5219 fread(&dat, sizeof(unsigned char), 1, imf);//read the size of trak.Every track must be the same size
5220 fread(&dat1, sizeof(unsigned char), 1, imf);
5221 fread(&dat2, sizeof(unsigned char), 1, imf);
5222 fread(&dat3, sizeof(unsigned char), 1, imf);
5223
5224 int sizetrak = ((dat<<24) | (dat1<<16) | (dat2<<8) | (dat3));
5225
5226 fseek(imf, (sizetrak-4)*audiotracks, SEEK_CUR);
5227
5228 int d=0;
5229 while (d==0){
5230
5231 fread(&dat, sizeof(unsigned char), 1, imf);
5232 fread(&dat1, sizeof(unsigned char), 1, imf);
5233 fread(&dat2, sizeof(unsigned char), 1, imf);
5234 fread(&dat3, sizeof(unsigned char), 1, imf);
5235
5236
5237 if (dat == 0x73 && dat1 == 0x74 && dat2 == 0x74 && dat3 == 0x73) { // 73 74 74 73 = s t t s
5238 d=1;
5239 }
5240
5241 else{
5242 fseek(imf, -3, SEEK_CUR); //if we have not readen ´stts´
5243 }
5244
5245 } //close while
5246
5247 fread(&dat, sizeof(unsigned char), 1, imf);//avanzamos 4 bytes (son los 4 bytes de version)
5248 fread(&dat, sizeof(unsigned char), 1, imf);
5249 fread(&dat, sizeof(unsigned char), 1, imf);
5250 fread(&dat, sizeof(unsigned char), 1, imf);
5251
5252 fread(&dat, sizeof(unsigned char), 1, imf);//estos 4 bytes son los de número de entradas de la tabla (entry_count)
5253 fread(&dat1, sizeof(unsigned char), 1, imf);
5254 fread(&dat2, sizeof(unsigned char), 1, imf);
5255 fread(&dat3, sizeof(unsigned char), 1, imf);
5256
5257 int entry_count = ((dat<<24) | (dat1<<16) | (dat2<<8) | (dat3));
5258
5259 int sample_count [entry_count];
5260 int sample_delta [entry_count];
5261
5262 for (int i=0;i<entry_count;i++){
5263
5264
5265 fread(&dat, sizeof(unsigned char), 1, imf);
5266 fread(&dat1, sizeof(unsigned char), 1, imf);
5267 fread(&dat2, sizeof(unsigned char), 1, imf);
5268 fread(&dat3, sizeof(unsigned char), 1, imf);
5269
5270 sample_count[i] = ((dat<<24) | (dat1<<16) | (dat2<<8) | (dat3));
5271
5272 fread(&dat, sizeof(unsigned char), 1, imf);
5273 fread(&dat1, sizeof(unsigned char), 1, imf);
5274 fread(&dat2, sizeof(unsigned char), 1, imf);
5275 fread(&dat3, sizeof(unsigned char), 1, imf);
5276
5277
5278 sample_delta[i] = ((dat<<24) | (dat1<<16) | (dat2<<8) | (dat3));
5279
5280 }
5281
5282 d=0;
5283 while (d==0){
5284
5285 fread(&dat, sizeof(unsigned char), 1, imf);
5286 fread(&dat1, sizeof(unsigned char), 1, imf);
5287 fread(&dat2, sizeof(unsigned char), 1, imf);
5288 fread(&dat3, sizeof(unsigned char), 1, imf);
5289
5290 if (dat == 0x73 && dat1 == 0x74 && dat2 == 0x73 && dat3 == 0x7A) { // 73 74 73 7A = s t s z
5291 d=1;
5292 }
5293
5294 else{
5295 fseek(imf, -3, SEEK_CUR); //if we have not readen ´stts´
5296 }
5297
5298 } //close while
5299
5300 for (int i=1;i<=8;i++){ //avanzamos 8 posiciones
5301
5302 fread(&dat, sizeof(unsigned char), 1, imf);
5303
5304 }
5305
5306 fread(&dat, sizeof(unsigned char), 1, imf); //read sample_count
5307 fread(&dat1, sizeof(unsigned char), 1, imf);
5308 fread(&dat2, sizeof(unsigned char), 1, imf);
5309 fread(&dat3, sizeof(unsigned char), 1, imf);
5310
5311 int samplecount = ((dat<<24) | (dat1<<16) | (dat2<<8) | (dat3));
5312 int sample_size[samplecount];
5313 for (int i=0;i<samplecount;i++){
5314
5315 fread(&dat, sizeof(unsigned char), 1, imf);
5316 fread(&dat1, sizeof(unsigned char), 1, imf);
5317 fread(&dat2, sizeof(unsigned char), 1, imf);
5318 fread(&dat3, sizeof(unsigned char), 1, imf);
5319
5320 sample_size[i] = ((dat<<24) | (dat1<<16) | (dat2<<8) | (dat3));// the size of every string including modifiers
5321
5322 }
5323
5324 d=0;
5325 while (d==0){
5326
5327 fread(&dat, sizeof(unsigned char), 1, imf);
5328 fread(&dat1, sizeof(unsigned char), 1, imf);
5329 fread(&dat2, sizeof(unsigned char), 1, imf);
5330 fread(&dat3, sizeof(unsigned char), 1, imf);
5331
5332 if (dat == 0x63 && dat1 == 0x6F && dat2 == 0x36 && dat3 == 0x34) { // 63 6F 36 34 = c o 6 4
5333 d=1;
5334 }
5335
5336 else{
5337 fseek(imf, -3, SEEK_CUR); //if we have not readen ´stts´
5338 }
5339
5340 } //close while
5341
5342 for (int i=1;i<=12;i++){ //advance 12 memory bytes
5343
5344 fread(&dat, sizeof(unsigned char), 1, imf);
5345
5346 }
5347
5348 fread(&dat, sizeof(unsigned char), 1, imf); //read co64 box
5349 fread(&dat1, sizeof(unsigned char), 1, imf);
5350 fread(&dat2, sizeof(unsigned char), 1, imf);
5351 fread(&dat3, sizeof(unsigned char), 1, imf);
5352
5353 int chunk_offset = ((dat<<24) | (dat1<<16) | (dat2<<8) | (dat3));
5354
5355 fseek (imf,0,SEEK_SET);
5356 fseek (imf,chunk_offset,SEEK_CUR); //jump to the position where starts text strings
5357
5358 int num_modifiers;
5359 float duration1;
5360 for (int j=0;j<samplecount;j++){
5361
5362 fread(&dat, sizeof(unsigned char), 1, imf); // read sizestring
5363 fread(&dat1, sizeof(unsigned char), 1, imf);
5364
5365 int sizestring = ((dat<<8) | (dat1));
5366
5367 char text [sizestring+1];
5368
5369 for (int i=0;i<sizestring;i++){
5370 fread(&dat, sizeof(unsigned char), 1, imf);
5371 text [i] = dat;
5372 }
5373 text[sizestring]= '\0';// indicates the end of the char string.If we don´t add this character, the conversion to QString does not work
5374 num_modifiers = sample_size[j]-sizestring-2;
5375
5376 for (int i=0;i<num_modifiers;i++){
5377 fread(&dat, sizeof(unsigned char), 1, imf);
5378 }
5379 QString result (text);//convert string char to QString
5380 duration1=0;
5381 for (int h=0;h<j;h++){
5382 duration1 = sample_delta[h]+duration1;
5383 }
5384 float duration2 = duration1 / 1000;
5385 int duration3 = duration2 * 44100;
5386 if (sizestring >1){ //sizestring = 1 when there is only a blank space.We do not want to add a blank space alone.
5387
5388 if (samplecount%2==0){//to avoid overlapping
5389 m_paneStack->setCurrentLayer(pane, newLayer);
5390 insertLyrics (duration3, result);
5391 }
5392 else{
5393 m_paneStack->setCurrentLayer(pane, newLayer1);
5394 insertLyrics (duration3, result);
5395 }
5396
5397
5398 } // close if
5399 } //close for
5400 } // close if haslyrics
5401
5402 }
5403 void
5404 MainWindow::openMP3IMAF()
5405 {
5406 FileOpenStatus status;
5407
5408 for (int i=0;i<audiotracks;i++){
5409
5410 char buf[2];
5411 sprintf(buf, "%d", i); //convert int to char
5412 status = openPath(buf, CreateAdditionalModel);
5413 remove (buf);
5414
5415 }
5416
5417 }
5418
5419 void CheckBox::set_selruleType(QAbstractButton *button)
5420 {
5421 selrule_type = button->objectName().toInt();
5422
5423 if( (selrule_type == 0) || (selrule_type == 1) || (selrule_type == 3) ){
5424 sel_rule1->setText("Track A");
5425 sel_rule1->setDisabled(false);
5426 sel_rule2->setText("Track B");
5427 sel_rule2->setDisabled(false);
5428 }else{
5429 sel_rule1->setText("Track A");
5430 sel_rule1->setDisabled(false);
5431 sel_rule2->setDisabled(true);
5432 }
5433 }
5434
5435 void CheckBox::set_selrulePAR1(int value)
5436 {
5437 selrule_par1 = value; // TRACK A
5438 }
5439
5440 void CheckBox::set_selrulePAR2(int value)
5441 {
5442 selrule_par2 = value; // TRACK B
5443 }
5444
5445 void CheckBox::set_mixruleType(QAbstractButton *button)
5446 {
5447 mixrule_type = button->objectName().toInt();
5448
5449 if( (mixrule_type == 0) || (mixrule_type == 1) || (mixrule_type == 2) ){
5450 mix_rule1->setText("Track A");
5451 mix_rule1->setDisabled(false);
5452 mix_rule2->setText("Track B");
5453 mix_rule2->setDisabled(false);
5454 mix_rule3->setDisabled(true);
5455 mix_rule4->setDisabled(true);
5456 }else{
5457 mix_rule1->setText("Track A");
5458 mix_rule1->setDisabled(false);
5459 mix_rule2->setDisabled(true);
5460 mix_rule3->setText("Min Volume");
5461 mix_rule3->setDisabled(false);
5462 mix_rule4->setText("Max Volume");
5463 mix_rule4->setDisabled(false);
5464 }
5465 }
5466
5467 void CheckBox::set_mixrulePAR1(int value)
5468 {
5469 mixrule_par1 = value; // TRACK A
5470 }
5471
5472 void CheckBox::set_mixrulePAR2(int value)
5473 {
5474 mixrule_par2 = value; // TRACK B
5475 }
5476
5477 void CheckBox::set_mixrulePAR3(int value)
5478 {
5479 mixrule_par3 = value; // MIN VOL for Limit Rule
5480 }
5481
5482 void CheckBox::set_mixrulePAR4(int value)
5483 {
5484 mixrule_par4 = value; // MAX VOL for Limit Rule
5485 }
5486
5487 void CheckBox::set_TrackInGroup(QAbstractButton *button)
5488 {
5489 int temp = button->objectName().toInt();
5490
5491 if (button->isChecked()){
5492 group_tracks[temp-1] = 1;
5493 }else{
5494 group_tracks[temp-1] = 0;
5495 }
5496 }
5497
5498 void CheckBox::set_GroupName(QString name)
5499 {
5500 group_name = name;
5501 }
5502
5503 void CheckBox::set_GroupVolume(int value)
5504 {
5505 group_volume = value;
5506 }
5507
5508 void CheckBox::set_presetType(QAbstractButton *button)
5509 {
5510 preset_type = button->objectName().toInt();
5511 }
5512
5513 void CheckBox::set_fade(QAbstractButton *button)
5514 {
5515 fade_in = button->objectName().toInt();
5516 }