comparison main/MainWindow.cpp @ 634:ba338234c001 imaf_enc

IMAF load code from Jesus Corral Garcia
author Chris Cannam
date Mon, 04 Nov 2013 17:15:52 +0000
parents 0b094b0fdcc4
children 767789a78984
comparison
equal deleted inserted replaced
633:a8da6db5a2c9 634:ba338234c001
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"
125 126
126 using std::vector; 127 using std::vector;
127 using std::map; 128 using std::map;
128 using std::set; 129 using std::set;
129 130
131 //IMAF REQUIRED LIBRARIES AND VARIABLES
132 #include "IMAFencoder.c"
133 #include "checkbox.h"
134 #include <QFileDialog>
135 #include "imafdecoder.cpp"
136
137 QString ImafFileName,ImageFileName,TextFileName; //name of the files
138 QString files_paths[maxtracks]; // change maxtracks in IMAFencoder.h
139 int ImafVolumeValues[maxtracks];
140 int numtracks;
141 bool has_image, has_lyrics;
142 int selrule_type, selrule_par1, selrule_par2;
143 int mixrule_type, mixrule_par1, mixrule_par2, mixrule_par3, mixrule_par4;
144 int group_tracks[maxtracks], group_volume;
145 QString group_descr, group_name;
146 int preset_type, fade_in;
147
130 148
131 MainWindow::MainWindow(bool withAudioOutput, bool withOSCSupport) : 149 MainWindow::MainWindow(bool withAudioOutput, bool withOSCSupport) :
132 MainWindowBase(withAudioOutput, withOSCSupport, true), 150 MainWindowBase(withAudioOutput, withOSCSupport, true),
133 m_overview(0), 151 m_overview(0),
134 m_mainMenusCreated(false), 152 m_mainMenusCreated(false),
242 m_playSpeed->setObjectName(tr("Playback Speedup")); 260 m_playSpeed->setObjectName(tr("Playback Speedup"));
243 m_playSpeed->setDefaultValue(100); 261 m_playSpeed->setDefaultValue(100);
244 m_playSpeed->setRangeMapper(new PlaySpeedRangeMapper(0, 200)); 262 m_playSpeed->setRangeMapper(new PlaySpeedRangeMapper(0, 200));
245 m_playSpeed->setShowToolTip(true); 263 m_playSpeed->setShowToolTip(true);
246 connect(m_playSpeed, SIGNAL(valueChanged(int)), 264 connect(m_playSpeed, SIGNAL(valueChanged(int)),
247 this, SLOT(playSpeedChanged(int))); 265 this, SLOT(playSpeedChanged(int)));
248 connect(m_playSpeed, SIGNAL(mouseEntered()), this, SLOT(mouseEnteredWidget())); 266 connect(m_playSpeed, SIGNAL(mouseEntered()), this, SLOT(mouseEnteredWidget()));
249 connect(m_playSpeed, SIGNAL(mouseLeft()), this, SLOT(mouseLeftWidget())); 267 connect(m_playSpeed, SIGNAL(mouseLeft()), this, SLOT(mouseLeftWidget()));
250 268
251 IconLoader il; 269 IconLoader il;
252 270
261 layout->addWidget(m_overview, 1, 1); 279 layout->addWidget(m_overview, 1, 1);
262 layout->addWidget(m_playControlsSpacer, 1, 2); 280 layout->addWidget(m_playControlsSpacer, 1, 2);
263 layout->addWidget(m_playSpeed, 1, 3); 281 layout->addWidget(m_playSpeed, 1, 3);
264 layout->addWidget(m_fader, 1, 4); 282 layout->addWidget(m_fader, 1, 4);
265 283
266 m_playControlsWidth = 284 m_playControlsWidth =
267 m_fader->width() + m_playSpeed->width() + layout->spacing() * 2; 285 m_fader->width() + m_playSpeed->width() + layout->spacing() * 2;
268 286
269 layout->setColumnMinimumWidth(0, 14); 287 layout->setColumnMinimumWidth(0, 14);
270 layout->setColumnStretch(0, 0); 288 layout->setColumnStretch(0, 0);
271 289
301 319
302 newSession(); 320 newSession();
303 321
304 connect(m_midiInput, SIGNAL(eventsAvailable()), 322 connect(m_midiInput, SIGNAL(eventsAvailable()),
305 this, SLOT(midiEventsAvailable())); 323 this, SLOT(midiEventsAvailable()));
306 324
307 TransformFactory::getInstance()->startPopulationThread(); 325 TransformFactory::getInstance()->startPopulationThread();
308 326
309 m_versionTester = new VersionTester 327 VersionTester *vt = new VersionTester
310 ("sonicvisualiser.org", "/latest-version.txt", SV_VERSION); 328 ("sonicvisualiser.org", "/latest-version.txt", SV_VERSION);
311 connect(m_versionTester, SIGNAL(newerVersionAvailable(QString)), 329 connect(vt, SIGNAL(newerVersionAvailable(QString)),
312 this, SLOT(newerVersionAvailable(QString))); 330 this, SLOT(newerVersionAvailable(QString)));
313 } 331 }
314 332
315 MainWindow::~MainWindow() 333 MainWindow::~MainWindow()
316 { 334 {
317 // SVDEBUG << "MainWindow::~MainWindow" << endl; 335 // SVDEBUG << "MainWindow::~MainWindow" << endl;
318 delete m_keyReference; 336 delete m_keyReference;
319 delete m_activityLog; 337 delete m_activityLog;
320 delete m_preferencesDialog; 338 delete m_preferencesDialog;
321 delete m_layerTreeDialog; 339 delete m_layerTreeDialog;
322 delete m_versionTester;
323 Profiles::getInstance()->dump(); 340 Profiles::getInstance()->dump();
324 // SVDEBUG << "MainWindow::~MainWindow finishing" << endl; 341 // SVDEBUG << "MainWindow::~MainWindow finishing" << endl;
325 } 342 }
326 343
327 void 344 void
483 connect(action, SIGNAL(triggered()), this, SLOT(saveSession())); 500 connect(action, SIGNAL(triggered()), this, SLOT(saveSession()));
484 connect(this, SIGNAL(canSave(bool)), action, SLOT(setEnabled(bool))); 501 connect(this, SIGNAL(canSave(bool)), action, SLOT(setEnabled(bool)));
485 m_keyReference->registerShortcut(action); 502 m_keyReference->registerShortcut(action);
486 menu->addAction(action); 503 menu->addAction(action);
487 toolbar->addAction(action); 504 toolbar->addAction(action);
488 505
489 icon = il.load("filesaveas"); 506 icon = il.load("filesaveas");
490 icon.addPixmap(il.loadPixmap("filesaveas-22")); 507 icon.addPixmap(il.loadPixmap("filesaveas-22"));
491 action = new QAction(icon, tr("Save Session &As..."), this); 508 action = new QAction(icon, tr("Save Session &As..."), this);
492 action->setShortcut(tr("Ctrl+Shift+S")); 509 action->setShortcut(tr("Ctrl+Shift+S"));
493 action->setStatusTip(tr("Save the current session into a new %1 session file").arg(QApplication::applicationName())); 510 action->setStatusTip(tr("Save the current session into a new %1 session file").arg(QApplication::applicationName()));
517 action->setStatusTip(tr("Export selection as an audio file")); 534 action->setStatusTip(tr("Export selection as an audio file"));
518 connect(action, SIGNAL(triggered()), this, SLOT(exportAudio())); 535 connect(action, SIGNAL(triggered()), this, SLOT(exportAudio()));
519 connect(this, SIGNAL(canExportAudio(bool)), action, SLOT(setEnabled(bool))); 536 connect(this, SIGNAL(canExportAudio(bool)), action, SLOT(setEnabled(bool)));
520 menu->addAction(action); 537 menu->addAction(action);
521 538
539 QAction *actionCreateIMAF = new QAction(tr("&Export IMAF File..."), this);
540 actionCreateIMAF->setStatusTip(tr("Export selection as an IMAF file"));
541 menu->addAction(actionCreateIMAF);
542 connect(actionCreateIMAF,SIGNAL(triggered()),this,SLOT(exportIMAF()));
543
544 QAction *actionOpenIMAF = new QAction(tr("&Import IMAF File..."), this);
545 actionOpenIMAF->setStatusTip(tr("Import IMAF file"));
546 menu->addAction(actionOpenIMAF);
547 connect(actionOpenIMAF,SIGNAL(triggered()),this,SLOT(importIMAF()));
548
549
550
551
522 menu->addSeparator(); 552 menu->addSeparator();
523 553
524 action = new QAction(tr("Import Annotation &Layer..."), this); 554 action = new QAction(tr("Import Annotation &Layer..."), this);
525 action->setShortcut(tr("Ctrl+L")); 555 action->setShortcut(tr("Ctrl+L"));
526 action->setStatusTip(tr("Import layer data from an existing file")); 556 action->setStatusTip(tr("Import layer data from an existing file"));
569 599
570 action = new QAction(tr("&Preferences..."), this); 600 action = new QAction(tr("&Preferences..."), this);
571 action->setStatusTip(tr("Adjust the application preferences")); 601 action->setStatusTip(tr("Adjust the application preferences"));
572 connect(action, SIGNAL(triggered()), this, SLOT(preferences())); 602 connect(action, SIGNAL(triggered()), this, SLOT(preferences()));
573 menu->addAction(action); 603 menu->addAction(action);
574 604
575 menu->addSeparator(); 605 menu->addSeparator();
576 action = new QAction(il.load("exit"), 606 action = new QAction(il.load("exit"),
577 tr("&Quit"), this); 607 tr("&Quit"), this);
578 action->setShortcut(tr("Ctrl+Q")); 608 action->setShortcut(tr("Ctrl+Q"));
579 action->setStatusTip(tr("Exit %1").arg(QApplication::applicationName())); 609 action->setStatusTip(tr("Exit %1").arg(QApplication::applicationName()));
656 connect(action, SIGNAL(triggered()), this, SLOT(selectAll())); 686 connect(action, SIGNAL(triggered()), this, SLOT(selectAll()));
657 connect(this, SIGNAL(canSelect(bool)), action, SLOT(setEnabled(bool))); 687 connect(this, SIGNAL(canSelect(bool)), action, SLOT(setEnabled(bool)));
658 m_keyReference->registerShortcut(action); 688 m_keyReference->registerShortcut(action);
659 menu->addAction(action); 689 menu->addAction(action);
660 m_rightButtonMenu->addAction(action); 690 m_rightButtonMenu->addAction(action);
661 691
662 action = new QAction(tr("Select &Visible Range"), this); 692 action = new QAction(tr("Select &Visible Range"), this);
663 action->setShortcut(tr("Ctrl+Shift+A")); 693 action->setShortcut(tr("Ctrl+Shift+A"));
664 action->setStatusTip(tr("Select the time range corresponding to the current window width")); 694 action->setStatusTip(tr("Select the time range corresponding to the current window width"));
665 connect(action, SIGNAL(triggered()), this, SLOT(selectVisible())); 695 connect(action, SIGNAL(triggered()), this, SLOT(selectVisible()));
666 connect(this, SIGNAL(canSelect(bool)), action, SLOT(setEnabled(bool))); 696 connect(this, SIGNAL(canSelect(bool)), action, SLOT(setEnabled(bool)));
667 m_keyReference->registerShortcut(action); 697 m_keyReference->registerShortcut(action);
668 menu->addAction(action); 698 menu->addAction(action);
669 699
670 action = new QAction(tr("Select to &Start"), this); 700 action = new QAction(tr("Select to &Start"), this);
671 action->setShortcut(tr("Shift+Left")); 701 action->setShortcut(tr("Shift+Left"));
672 action->setStatusTip(tr("Select from the start of the session to the current playback position")); 702 action->setStatusTip(tr("Select from the start of the session to the current playback position"));
673 connect(action, SIGNAL(triggered()), this, SLOT(selectToStart())); 703 connect(action, SIGNAL(triggered()), this, SLOT(selectToStart()));
674 connect(this, SIGNAL(canSelect(bool)), action, SLOT(setEnabled(bool))); 704 connect(this, SIGNAL(canSelect(bool)), action, SLOT(setEnabled(bool)));
675 m_keyReference->registerShortcut(action); 705 m_keyReference->registerShortcut(action);
676 menu->addAction(action); 706 menu->addAction(action);
677 707
678 action = new QAction(tr("Select to &End"), this); 708 action = new QAction(tr("Select to &End"), this);
679 action->setShortcut(tr("Shift+Right")); 709 action->setShortcut(tr("Shift+Right"));
680 action->setStatusTip(tr("Select from the current playback position to the end of the session")); 710 action->setStatusTip(tr("Select from the current playback position to the end of the session"));
681 connect(action, SIGNAL(triggered()), this, SLOT(selectToEnd())); 711 connect(action, SIGNAL(triggered()), this, SLOT(selectToEnd()));
682 connect(this, SIGNAL(canSelect(bool)), action, SLOT(setEnabled(bool))); 712 connect(this, SIGNAL(canSelect(bool)), action, SLOT(setEnabled(bool)));
771 801
772 action = new QAction(tr("Set Numbering Counters..."), this); 802 action = new QAction(tr("Set Numbering Counters..."), this);
773 action->setStatusTip(tr("Set the counters used for counter-based labelling")); 803 action->setStatusTip(tr("Set the counters used for counter-based labelling"));
774 connect(action, SIGNAL(triggered()), this, SLOT(resetInstantsCounters())); 804 connect(action, SIGNAL(triggered()), this, SLOT(resetInstantsCounters()));
775 menu->addAction(action); 805 menu->addAction(action);
776 806
777 action = new QAction(tr("Renumber Selected Instants"), this); 807 action = new QAction(tr("Renumber Selected Instants"), this);
778 action->setStatusTip(tr("Renumber the selected instants using the current labelling scheme")); 808 action->setStatusTip(tr("Renumber the selected instants using the current labelling scheme"));
779 connect(action, SIGNAL(triggered()), this, SLOT(renumberInstants())); 809 connect(action, SIGNAL(triggered()), this, SLOT(renumberInstants()));
780 connect(this, SIGNAL(canRenumberInstants(bool)), action, SLOT(setEnabled(bool))); 810 connect(this, SIGNAL(canRenumberInstants(bool)), action, SLOT(setEnabled(bool)));
781 // m_keyReference->registerShortcut(action); 811 // m_keyReference->registerShortcut(action);
800 m_scrollLeftAction->setStatusTip(tr("Scroll the current pane to the left")); 830 m_scrollLeftAction->setStatusTip(tr("Scroll the current pane to the left"));
801 connect(m_scrollLeftAction, SIGNAL(triggered()), this, SLOT(scrollLeft())); 831 connect(m_scrollLeftAction, SIGNAL(triggered()), this, SLOT(scrollLeft()));
802 connect(this, SIGNAL(canScroll(bool)), m_scrollLeftAction, SLOT(setEnabled(bool))); 832 connect(this, SIGNAL(canScroll(bool)), m_scrollLeftAction, SLOT(setEnabled(bool)));
803 m_keyReference->registerShortcut(m_scrollLeftAction); 833 m_keyReference->registerShortcut(m_scrollLeftAction);
804 menu->addAction(m_scrollLeftAction); 834 menu->addAction(m_scrollLeftAction);
805 835
806 m_scrollRightAction = new QAction(tr("Scroll &Right"), this); 836 m_scrollRightAction = new QAction(tr("Scroll &Right"), this);
807 m_scrollRightAction->setShortcut(tr("Right")); 837 m_scrollRightAction->setShortcut(tr("Right"));
808 m_scrollRightAction->setStatusTip(tr("Scroll the current pane to the right")); 838 m_scrollRightAction->setStatusTip(tr("Scroll the current pane to the right"));
809 connect(m_scrollRightAction, SIGNAL(triggered()), this, SLOT(scrollRight())); 839 connect(m_scrollRightAction, SIGNAL(triggered()), this, SLOT(scrollRight()));
810 connect(this, SIGNAL(canScroll(bool)), m_scrollRightAction, SLOT(setEnabled(bool))); 840 connect(this, SIGNAL(canScroll(bool)), m_scrollRightAction, SLOT(setEnabled(bool)));
811 m_keyReference->registerShortcut(m_scrollRightAction); 841 m_keyReference->registerShortcut(m_scrollRightAction);
812 menu->addAction(m_scrollRightAction); 842 menu->addAction(m_scrollRightAction);
813 843
814 action = new QAction(tr("&Jump Left"), this); 844 action = new QAction(tr("&Jump Left"), this);
815 action->setShortcut(tr("Ctrl+Left")); 845 action->setShortcut(tr("Ctrl+Left"));
816 action->setStatusTip(tr("Scroll the current pane a big step to the left")); 846 action->setStatusTip(tr("Scroll the current pane a big step to the left"));
817 connect(action, SIGNAL(triggered()), this, SLOT(jumpLeft())); 847 connect(action, SIGNAL(triggered()), this, SLOT(jumpLeft()));
818 connect(this, SIGNAL(canScroll(bool)), action, SLOT(setEnabled(bool))); 848 connect(this, SIGNAL(canScroll(bool)), action, SLOT(setEnabled(bool)));
819 m_keyReference->registerShortcut(action); 849 m_keyReference->registerShortcut(action);
820 menu->addAction(action); 850 menu->addAction(action);
821 851
822 action = new QAction(tr("J&ump Right"), this); 852 action = new QAction(tr("J&ump Right"), this);
823 action->setShortcut(tr("Ctrl+Right")); 853 action->setShortcut(tr("Ctrl+Right"));
824 action->setStatusTip(tr("Scroll the current pane a big step to the right")); 854 action->setStatusTip(tr("Scroll the current pane a big step to the right"));
825 connect(action, SIGNAL(triggered()), this, SLOT(jumpRight())); 855 connect(action, SIGNAL(triggered()), this, SLOT(jumpRight()));
826 connect(this, SIGNAL(canScroll(bool)), action, SLOT(setEnabled(bool))); 856 connect(this, SIGNAL(canScroll(bool)), action, SLOT(setEnabled(bool)));
832 action->setStatusTip(tr("Scroll the current pane to the left without moving the playback cursor or other panes")); 862 action->setStatusTip(tr("Scroll the current pane to the left without moving the playback cursor or other panes"));
833 connect(action, SIGNAL(triggered()), this, SLOT(peekLeft())); 863 connect(action, SIGNAL(triggered()), this, SLOT(peekLeft()));
834 connect(this, SIGNAL(canScroll(bool)), action, SLOT(setEnabled(bool))); 864 connect(this, SIGNAL(canScroll(bool)), action, SLOT(setEnabled(bool)));
835 m_keyReference->registerShortcut(action); 865 m_keyReference->registerShortcut(action);
836 menu->addAction(action); 866 menu->addAction(action);
837 867
838 action = new QAction(tr("Peek Right"), this); 868 action = new QAction(tr("Peek Right"), this);
839 action->setShortcut(tr("Alt+Right")); 869 action->setShortcut(tr("Alt+Right"));
840 action->setStatusTip(tr("Scroll the current pane to the right without moving the playback cursor or other panes")); 870 action->setStatusTip(tr("Scroll the current pane to the right without moving the playback cursor or other panes"));
841 connect(action, SIGNAL(triggered()), this, SLOT(peekRight())); 871 connect(action, SIGNAL(triggered()), this, SLOT(peekRight()));
842 connect(this, SIGNAL(canScroll(bool)), action, SLOT(setEnabled(bool))); 872 connect(this, SIGNAL(canScroll(bool)), action, SLOT(setEnabled(bool)));
853 m_zoomInAction->setStatusTip(tr("Increase the zoom level")); 883 m_zoomInAction->setStatusTip(tr("Increase the zoom level"));
854 connect(m_zoomInAction, SIGNAL(triggered()), this, SLOT(zoomIn())); 884 connect(m_zoomInAction, SIGNAL(triggered()), this, SLOT(zoomIn()));
855 connect(this, SIGNAL(canZoom(bool)), m_zoomInAction, SLOT(setEnabled(bool))); 885 connect(this, SIGNAL(canZoom(bool)), m_zoomInAction, SLOT(setEnabled(bool)));
856 m_keyReference->registerShortcut(m_zoomInAction); 886 m_keyReference->registerShortcut(m_zoomInAction);
857 menu->addAction(m_zoomInAction); 887 menu->addAction(m_zoomInAction);
858 888
859 m_zoomOutAction = new QAction(il.load("zoom-out"), 889 m_zoomOutAction = new QAction(il.load("zoom-out"),
860 tr("Zoom &Out"), this); 890 tr("Zoom &Out"), this);
861 m_zoomOutAction->setShortcut(tr("Down")); 891 m_zoomOutAction->setShortcut(tr("Down"));
862 m_zoomOutAction->setStatusTip(tr("Decrease the zoom level")); 892 m_zoomOutAction->setStatusTip(tr("Decrease the zoom level"));
863 connect(m_zoomOutAction, SIGNAL(triggered()), this, SLOT(zoomOut())); 893 connect(m_zoomOutAction, SIGNAL(triggered()), this, SLOT(zoomOut()));
864 connect(this, SIGNAL(canZoom(bool)), m_zoomOutAction, SLOT(setEnabled(bool))); 894 connect(this, SIGNAL(canZoom(bool)), m_zoomOutAction, SLOT(setEnabled(bool)));
865 m_keyReference->registerShortcut(m_zoomOutAction); 895 m_keyReference->registerShortcut(m_zoomOutAction);
866 menu->addAction(m_zoomOutAction); 896 menu->addAction(m_zoomOutAction);
867 897
868 action = new QAction(tr("Restore &Default Zoom"), this); 898 action = new QAction(tr("Restore &Default Zoom"), this);
869 action->setStatusTip(tr("Restore the zoom level to the default")); 899 action->setStatusTip(tr("Restore the zoom level to the default"));
870 connect(action, SIGNAL(triggered()), this, SLOT(zoomDefault())); 900 connect(action, SIGNAL(triggered()), this, SLOT(zoomDefault()));
871 connect(this, SIGNAL(canZoom(bool)), action, SLOT(setEnabled(bool))); 901 connect(this, SIGNAL(canZoom(bool)), action, SLOT(setEnabled(bool)));
872 menu->addAction(action); 902 menu->addAction(action);
901 menu->addAction(action); 931 menu->addAction(action);
902 932
903 menu->addSeparator(); 933 menu->addSeparator();
904 934
905 QActionGroup *overlayGroup = new QActionGroup(this); 935 QActionGroup *overlayGroup = new QActionGroup(this);
906 936
907 action = new QAction(tr("Show &No Overlays"), this); 937 action = new QAction(tr("Show &No Overlays"), this);
908 action->setShortcut(tr("0")); 938 action->setShortcut(tr("0"));
909 action->setStatusTip(tr("Hide times, layer names, and scale")); 939 action->setStatusTip(tr("Hide times, layer names, and scale"));
910 connect(action, SIGNAL(triggered()), this, SLOT(showNoOverlays())); 940 connect(action, SIGNAL(triggered()), this, SLOT(showNoOverlays()));
911 action->setCheckable(true); 941 action->setCheckable(true);
912 action->setChecked(false); 942 action->setChecked(false);
913 overlayGroup->addAction(action); 943 overlayGroup->addAction(action);
914 m_keyReference->registerShortcut(action); 944 m_keyReference->registerShortcut(action);
915 menu->addAction(action); 945 menu->addAction(action);
916 946
917 action = new QAction(tr("Show &Minimal Overlays"), this); 947 action = new QAction(tr("Show &Minimal Overlays"), this);
918 action->setShortcut(tr("9")); 948 action->setShortcut(tr("9"));
919 action->setStatusTip(tr("Show times and basic scale")); 949 action->setStatusTip(tr("Show times and basic scale"));
920 connect(action, SIGNAL(triggered()), this, SLOT(showMinimalOverlays())); 950 connect(action, SIGNAL(triggered()), this, SLOT(showMinimalOverlays()));
921 action->setCheckable(true); 951 action->setCheckable(true);
922 action->setChecked(true); 952 action->setChecked(true);
923 overlayGroup->addAction(action); 953 overlayGroup->addAction(action);
924 m_keyReference->registerShortcut(action); 954 m_keyReference->registerShortcut(action);
925 menu->addAction(action); 955 menu->addAction(action);
926 956
927 action = new QAction(tr("Show &All Overlays"), this); 957 action = new QAction(tr("Show &All Overlays"), this);
928 action->setShortcut(tr("8")); 958 action->setShortcut(tr("8"));
929 action->setStatusTip(tr("Show times, layer names, and scale")); 959 action->setStatusTip(tr("Show times, layer names, and scale"));
930 connect(action, SIGNAL(triggered()), this, SLOT(showAllOverlays())); 960 connect(action, SIGNAL(triggered()), this, SLOT(showAllOverlays()));
931 action->setCheckable(true); 961 action->setCheckable(true);
933 overlayGroup->addAction(action); 963 overlayGroup->addAction(action);
934 m_keyReference->registerShortcut(action); 964 m_keyReference->registerShortcut(action);
935 menu->addAction(action); 965 menu->addAction(action);
936 966
937 menu->addSeparator(); 967 menu->addSeparator();
938 968
939 action = new QAction(tr("Show &Zoom Wheels"), this); 969 action = new QAction(tr("Show &Zoom Wheels"), this);
940 action->setShortcut(tr("Z")); 970 action->setShortcut(tr("Z"));
941 action->setStatusTip(tr("Show thumbwheels for zooming horizontally and vertically")); 971 action->setStatusTip(tr("Show thumbwheels for zooming horizontally and vertically"));
942 connect(action, SIGNAL(triggered()), this, SLOT(toggleZoomWheels())); 972 connect(action, SIGNAL(triggered()), this, SLOT(toggleZoomWheels()));
943 action->setCheckable(true); 973 action->setCheckable(true);
996 1026
997 void 1027 void
998 MainWindow::setupPaneAndLayerMenus() 1028 MainWindow::setupPaneAndLayerMenus()
999 { 1029 {
1000 if (m_paneMenu) { 1030 if (m_paneMenu) {
1001 m_paneActions.clear(); 1031 m_paneActions.clear();
1002 m_paneMenu->clear(); 1032 m_paneMenu->clear();
1003 } else { 1033 } else {
1004 m_paneMenu = menuBar()->addMenu(tr("&Pane")); 1034 m_paneMenu = menuBar()->addMenu(tr("&Pane"));
1005 m_paneMenu->setTearOffEnabled(true); 1035 m_paneMenu->setTearOffEnabled(true);
1006 } 1036 }
1007 1037
1008 if (m_layerMenu) { 1038 if (m_layerMenu) {
1009 m_layerActions.clear(); 1039 m_layerActions.clear();
1010 m_layerMenu->clear(); 1040 m_layerMenu->clear();
1011 } else { 1041 } else {
1012 m_layerMenu = menuBar()->addMenu(tr("&Layer")); 1042 m_layerMenu = menuBar()->addMenu(tr("&Layer"));
1013 m_layerMenu->setTearOffEnabled(true); 1043 m_layerMenu->setTearOffEnabled(true);
1014 } 1044 }
1015 1045
1016 if (m_rightButtonLayerMenu) { 1046 if (m_rightButtonLayerMenu) {
1017 m_rightButtonLayerMenu->clear(); 1047 m_rightButtonLayerMenu->clear();
1041 menu = m_layerMenu; 1071 menu = m_layerMenu;
1042 1072
1043 // menu->addSeparator(); 1073 // menu->addSeparator();
1044 1074
1045 LayerFactory::LayerTypeSet emptyLayerTypes = 1075 LayerFactory::LayerTypeSet emptyLayerTypes =
1046 LayerFactory::getInstance()->getValidEmptyLayerTypes(); 1076 LayerFactory::getInstance()->getValidEmptyLayerTypes();
1047 1077
1048 for (LayerFactory::LayerTypeSet::iterator i = emptyLayerTypes.begin(); 1078 for (LayerFactory::LayerTypeSet::iterator i = emptyLayerTypes.begin();
1049 i != emptyLayerTypes.end(); ++i) { 1079 i != emptyLayerTypes.end(); ++i) {
1050 1080
1051 QIcon icon; 1081 QIcon icon;
1052 QString mainText, tipText, channelText; 1082 QString mainText, tipText, channelText;
1053 LayerFactory::LayerType type = *i; 1083 LayerFactory::LayerType type = *i;
1054 QString name = LayerFactory::getInstance()->getLayerPresentationName(type); 1084 QString name = LayerFactory::getInstance()->getLayerPresentationName(type);
1055 1085
1056 icon = il.load(LayerFactory::getInstance()->getLayerIconName(type)); 1086 icon = il.load(LayerFactory::getInstance()->getLayerIconName(type));
1057 1087
1058 mainText = tr("Add New %1 Layer").arg(name); 1088 mainText = tr("Add New %1 Layer").arg(name);
1059 tipText = tr("Add a new empty layer of type %1").arg(name); 1089 tipText = tr("Add a new empty layer of type %1").arg(name);
1060 1090
1061 action = new QAction(icon, mainText, this); 1091 action = new QAction(icon, mainText, this);
1062 action->setStatusTip(tipText); 1092 action->setStatusTip(tipText);
1063 1093
1064 if (type == LayerFactory::Text) { 1094 if (type == LayerFactory::Text) {
1065 action->setShortcut(tr("T")); 1095 action->setShortcut(tr("T"));
1066 m_keyReference->registerShortcut(action); 1096 m_keyReference->registerShortcut(action);
1067 } 1097 }
1068 1098 connect(action, SIGNAL(triggered()), this, SLOT(addLayer()));
1069 connect(action, SIGNAL(triggered()), this, SLOT(addLayer())); 1099 connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool)));
1070 connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); 1100 m_layerActions[action] = LayerConfiguration(type);
1071 m_layerActions[action] = LayerConfiguration(type); 1101 menu->addAction(action);
1072 menu->addAction(action); 1102 m_rightButtonLayerMenu->addAction(action);
1073 m_rightButtonLayerMenu->addAction(action); 1103 }
1074 } 1104
1075
1076 m_rightButtonLayerMenu->addSeparator(); 1105 m_rightButtonLayerMenu->addSeparator();
1077 menu->addSeparator(); 1106 menu->addSeparator();
1078 1107
1079 LayerFactory::LayerType backgroundTypes[] = { 1108 LayerFactory::LayerType backgroundTypes[] = {
1080 LayerFactory::Waveform, 1109 LayerFactory::Waveform,
1081 LayerFactory::Spectrogram, 1110 LayerFactory::Spectrogram,
1082 LayerFactory::MelodicRangeSpectrogram, 1111 LayerFactory::MelodicRangeSpectrogram,
1083 LayerFactory::PeakFrequencySpectrogram, 1112 LayerFactory::PeakFrequencySpectrogram,
1084 LayerFactory::Spectrum 1113 LayerFactory::Spectrum
1085 }; 1114 };
1086 1115
1087 std::vector<Model *> models; 1116 std::vector<Model *> models;
1088 if (m_document) models = m_document->getTransformInputModels(); 1117 if (m_document) models = m_document->getTransformInputModels();
1090 if (models.empty()) { 1119 if (models.empty()) {
1091 models.push_back(getMainModel()); // probably 0 1120 models.push_back(getMainModel()); // probably 0
1092 } 1121 }
1093 1122
1094 for (unsigned int i = 0; 1123 for (unsigned int i = 0;
1095 i < sizeof(backgroundTypes)/sizeof(backgroundTypes[0]); ++i) { 1124 i < sizeof(backgroundTypes)/sizeof(backgroundTypes[0]); ++i) {
1096 1125
1097 const int paneMenuType = 0, layerMenuType = 1; 1126 const int paneMenuType = 0, layerMenuType = 1;
1098 1127
1099 for (int menuType = paneMenuType; menuType <= layerMenuType; ++menuType) { 1128 for (int menuType = paneMenuType; menuType <= layerMenuType; ++menuType) {
1100 1129
1101 if (menuType == paneMenuType) menu = m_paneMenu; 1130 if (menuType == paneMenuType) menu = m_paneMenu;
1102 else menu = m_layerMenu; 1131 else menu = m_layerMenu;
1103 1132
1104 QMenu *submenu = 0; 1133 QMenu *submenu = 0;
1105 1134
1106 QIcon icon; 1135 QIcon icon;
1107 QString mainText, shortcutText, tipText, channelText; 1136 QString mainText, shortcutText, tipText, channelText;
1108 LayerFactory::LayerType type = backgroundTypes[i]; 1137 LayerFactory::LayerType type = backgroundTypes[i];
1109 bool mono = true; 1138 bool mono = true;
1110 1139
1111 switch (type) { 1140 switch (type) {
1112 1141
1113 case LayerFactory::Waveform: 1142 case LayerFactory::Waveform:
1114 icon = il.load("waveform"); 1143 icon = il.load("waveform");
1115 mainText = tr("Add &Waveform"); 1144 mainText = tr("Add &Waveform");
1116 if (menuType == paneMenuType) { 1145 if (menuType == paneMenuType) {
1117 shortcutText = tr("W"); 1146 shortcutText = tr("W");
1120 shortcutText = tr("Shift+W"); 1149 shortcutText = tr("Shift+W");
1121 tipText = tr("Add a new layer showing a waveform view"); 1150 tipText = tr("Add a new layer showing a waveform view");
1122 } 1151 }
1123 mono = false; 1152 mono = false;
1124 break; 1153 break;
1125 1154
1126 case LayerFactory::Spectrogram: 1155 case LayerFactory::Spectrogram:
1127 icon = il.load("spectrogram"); 1156 icon = il.load("spectrogram");
1128 mainText = tr("Add Spectro&gram"); 1157 mainText = tr("Add Spectro&gram");
1129 if (menuType == paneMenuType) { 1158 if (menuType == paneMenuType) {
1130 shortcutText = tr("G"); 1159 shortcutText = tr("G");
1132 } else { 1161 } else {
1133 shortcutText = tr("Shift+G"); 1162 shortcutText = tr("Shift+G");
1134 tipText = tr("Add a new layer showing a spectrogram"); 1163 tipText = tr("Add a new layer showing a spectrogram");
1135 } 1164 }
1136 break; 1165 break;
1137 1166
1138 case LayerFactory::MelodicRangeSpectrogram: 1167 case LayerFactory::MelodicRangeSpectrogram:
1139 icon = il.load("spectrogram"); 1168 icon = il.load("spectrogram");
1140 mainText = tr("Add &Melodic Range Spectrogram"); 1169 mainText = tr("Add &Melodic Range Spectrogram");
1141 if (menuType == paneMenuType) { 1170 if (menuType == paneMenuType) {
1142 shortcutText = tr("M"); 1171 shortcutText = tr("M");
1144 } else { 1173 } else {
1145 shortcutText = tr("Shift+M"); 1174 shortcutText = tr("Shift+M");
1146 tipText = tr("Add a new layer showing a spectrogram set up for an overview of note pitches"); 1175 tipText = tr("Add a new layer showing a spectrogram set up for an overview of note pitches");
1147 } 1176 }
1148 break; 1177 break;
1149 1178
1150 case LayerFactory::PeakFrequencySpectrogram: 1179 case LayerFactory::PeakFrequencySpectrogram:
1151 icon = il.load("spectrogram"); 1180 icon = il.load("spectrogram");
1152 mainText = tr("Add Pea&k Frequency Spectrogram"); 1181 mainText = tr("Add Pea&k Frequency Spectrogram");
1153 if (menuType == paneMenuType) { 1182 if (menuType == paneMenuType) {
1154 shortcutText = tr("K"); 1183 shortcutText = tr("K");
1156 } else { 1185 } else {
1157 shortcutText = tr("Shift+K"); 1186 shortcutText = tr("Shift+K");
1158 tipText = tr("Add a new layer showing a spectrogram set up for tracking frequencies"); 1187 tipText = tr("Add a new layer showing a spectrogram set up for tracking frequencies");
1159 } 1188 }
1160 break; 1189 break;
1161 1190
1162 case LayerFactory::Spectrum: 1191 case LayerFactory::Spectrum:
1163 icon = il.load("spectrum"); 1192 icon = il.load("spectrum");
1164 mainText = tr("Add Spectr&um"); 1193 mainText = tr("Add Spectr&um");
1165 if (menuType == paneMenuType) { 1194 if (menuType == paneMenuType) {
1166 shortcutText = tr("U"); 1195 shortcutText = tr("U");
1168 } else { 1197 } else {
1169 shortcutText = tr("Shift+U"); 1198 shortcutText = tr("Shift+U");
1170 tipText = tr("Add a new layer showing a frequency spectrum"); 1199 tipText = tr("Add a new layer showing a frequency spectrum");
1171 } 1200 }
1172 break; 1201 break;
1173 1202
1174 default: break; 1203 default: break;
1175 } 1204 }
1176 1205
1177 std::vector<Model *> candidateModels = models; 1206 std::vector<Model *> candidateModels = models;
1178 1207
1179 for (std::vector<Model *>::iterator mi = 1208 for (std::vector<Model *>::iterator mi =
1180 candidateModels.begin(); 1209 candidateModels.begin();
1181 mi != candidateModels.end(); ++mi) { 1210 mi != candidateModels.end(); ++mi) {
1182 1211
1183 Model *model = *mi; 1212 Model *model = *mi;
1184 1213
1185 int channels = 0; 1214 int channels = 0;
1186 if (model) { 1215 if (model) {
1187 DenseTimeValueModel *dtvm = 1216 DenseTimeValueModel *dtvm =
1222 } 1251 }
1223 if (shortcutText != "") { 1252 if (shortcutText != "") {
1224 m_keyReference->registerShortcut(action); 1253 m_keyReference->registerShortcut(action);
1225 } 1254 }
1226 menu->addAction(action); 1255 menu->addAction(action);
1227 1256
1228 } else { 1257 } else {
1229 1258
1230 if (!submenu) { 1259 if (!submenu) {
1231 submenu = menu->addMenu(mainText); 1260 submenu = menu->addMenu(mainText);
1232 submenu->setTearOffEnabled(true); 1261 submenu->setTearOffEnabled(true);
1233 } else if (isDefault) { 1262 } else if (isDefault) {
1234 submenu->addSeparator(); 1263 submenu->addSeparator();
1252 } 1281 }
1253 1282
1254 if (isDefault) { 1283 if (isDefault) {
1255 action = new QAction(icon, actionText, this); 1284 action = new QAction(icon, actionText, this);
1256 if (!model || model == getMainModel()) { 1285 if (!model || model == getMainModel()) {
1257 action->setShortcut(shortcutText); 1286 action->setShortcut(shortcutText);
1258 } 1287 }
1259 } else { 1288 } else {
1260 action = new QAction(actionText, this); 1289 action = new QAction(actionText, this);
1261 } 1290 }
1262 1291
1293 connect(this, SIGNAL(canAddLayer(bool)), 1322 connect(this, SIGNAL(canAddLayer(bool)),
1294 action, SLOT(setEnabled(bool))); 1323 action, SLOT(setEnabled(bool)));
1295 m_layerActions[action] = LayerConfiguration(type, 0, 0); 1324 m_layerActions[action] = LayerConfiguration(type, 0, 0);
1296 m_rightButtonLayerMenu->addAction(action); 1325 m_rightButtonLayerMenu->addAction(action);
1297 } 1326 }
1298 } 1327 }
1299 } 1328 }
1300 } 1329 }
1301 } 1330 }
1302 1331
1303 m_rightButtonLayerMenu->addSeparator(); 1332 m_rightButtonLayerMenu->addSeparator();
1304 1333
1305 menu = m_paneMenu; 1334 menu = m_paneMenu;
1409 if (m_transformsMenu) { 1438 if (m_transformsMenu) {
1410 m_transformActions.clear(); 1439 m_transformActions.clear();
1411 m_transformActionsReverse.clear(); 1440 m_transformActionsReverse.clear();
1412 m_transformsMenu->clear(); 1441 m_transformsMenu->clear();
1413 } else { 1442 } else {
1414 m_transformsMenu = menuBar()->addMenu(tr("&Transform")); 1443 m_transformsMenu = menuBar()->addMenu(tr("&Transform"));
1415 m_transformsMenu->setTearOffEnabled(true); 1444 m_transformsMenu->setTearOffEnabled(true);
1416 m_transformsMenu->setSeparatorsCollapsible(true); 1445 m_transformsMenu->setSeparatorsCollapsible(true);
1417 } 1446 }
1418 1447
1419 TransformFactory *factory = TransformFactory::getInstance(); 1448 TransformFactory *factory = TransformFactory::getInstance();
1435 connect(&m_recentTransforms, SIGNAL(recentChanged()), 1464 connect(&m_recentTransforms, SIGNAL(recentChanged()),
1436 this, SLOT(setupRecentTransformsMenu())); 1465 this, SLOT(setupRecentTransformsMenu()));
1437 1466
1438 m_transformsMenu->addSeparator(); 1467 m_transformsMenu->addSeparator();
1439 m_rightButtonTransformsMenu->addSeparator(); 1468 m_rightButtonTransformsMenu->addSeparator();
1440 1469
1441 for (vector<TransformDescription::Type>::iterator i = types.begin(); 1470 for (vector<TransformDescription::Type>::iterator i = types.begin();
1442 i != types.end(); ++i) { 1471 i != types.end(); ++i) {
1443 1472
1444 if (i != types.begin()) { 1473 if (i != types.begin()) {
1445 m_transformsMenu->addSeparator(); 1474 m_transformsMenu->addSeparator();
1537 seenNames.insert(name); 1566 seenNames.insert(name);
1538 } 1567 }
1539 } 1568 }
1540 1569
1541 for (unsigned int i = 0; i < transforms.size(); ++i) { 1570 for (unsigned int i = 0; i < transforms.size(); ++i) {
1542 1571
1543 QString name = transforms[i].name; 1572 QString name = transforms[i].name;
1544 if (name == "") name = transforms[i].identifier; 1573 if (name == "") name = transforms[i].identifier;
1545 1574
1546 // std::cerr << "Plugin Name: " << name << std::endl; 1575 // std::cerr << "Plugin Name: " << name << std::endl;
1547 1576
1548 TransformDescription::Type type = transforms[i].type; 1577 TransformDescription::Type type = transforms[i].type;
1549 QString typeStr = factory->getTransformTypeName(type); 1578 QString typeStr = factory->getTransformTypeName(type);
1566 else name = QString("%1: %2") 1595 else name = QString("%1: %2")
1567 .arg(pluginName) 1596 .arg(pluginName)
1568 .arg(output); 1597 .arg(output);
1569 } 1598 }
1570 1599
1571 QAction *action = new QAction(tr("%1...").arg(name), this); 1600 QAction *action = new QAction(tr("%1...").arg(name), this);
1572 connect(action, SIGNAL(triggered()), this, SLOT(addLayer())); 1601 connect(action, SIGNAL(triggered()), this, SLOT(addLayer()));
1573 m_transformActions[action] = transforms[i].identifier; 1602 m_transformActions[action] = transforms[i].identifier;
1574 m_transformActionsReverse[transforms[i].identifier] = action; 1603 m_transformActionsReverse[transforms[i].identifier] = action;
1575 connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); 1604 connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool)));
1576 1605
1577 action->setStatusTip(transforms[i].longDescription); 1606 action->setStatusTip(transforms[i].longDescription);
1578 1607
1579 if (categoryMenus[type].find(category) == categoryMenus[type].end()) { 1608 if (categoryMenus[type].find(category) == categoryMenus[type].end()) {
1580 std::cerr << "WARNING: MainWindow::setupMenus: Internal error: " 1609 std::cerr << "WARNING: MainWindow::setupMenus: Internal error: "
1609 parentMenu->setTearOffEnabled(true); 1638 parentMenu->setTearOffEnabled(true);
1610 1639
1611 if (output == "") { 1640 if (output == "") {
1612 parentMenu->addAction(pluginName, action); 1641 parentMenu->addAction(pluginName, action);
1613 } else { 1642 } else {
1614 pluginNameMenus[type][pluginName] = 1643 pluginNameMenus[type][pluginName] =
1615 parentMenu->addMenu(pluginName); 1644 parentMenu->addMenu(pluginName);
1616 connect(this, SIGNAL(canAddLayer(bool)), 1645 connect(this, SIGNAL(canAddLayer(bool)),
1617 pluginNameMenus[type][pluginName], 1646 pluginNameMenus[type][pluginName],
1618 SLOT(setEnabled(bool))); 1647 SLOT(setEnabled(bool)));
1619 } 1648 }
1648 void 1677 void
1649 MainWindow::setupHelpMenu() 1678 MainWindow::setupHelpMenu()
1650 { 1679 {
1651 QMenu *menu = menuBar()->addMenu(tr("&Help")); 1680 QMenu *menu = menuBar()->addMenu(tr("&Help"));
1652 menu->setTearOffEnabled(true); 1681 menu->setTearOffEnabled(true);
1653 1682
1654 m_keyReference->setCategory(tr("Help")); 1683 m_keyReference->setCategory(tr("Help"));
1655 1684
1656 IconLoader il; 1685 IconLoader il;
1657 1686
1658 QString name = QApplication::applicationName(); 1687 QString name = QApplication::applicationName();
1659 1688
1660 QAction *action = new QAction(il.load("help"), 1689 QAction *action = new QAction(il.load("help"),
1661 tr("&Help Reference"), this); 1690 tr("&Help Reference"), this);
1662 action->setShortcut(tr("F1")); 1691 action->setShortcut(tr("F1"));
1663 action->setStatusTip(tr("Open the %1 reference manual").arg(name)); 1692 action->setStatusTip(tr("Open the %1 reference manual").arg(name));
1664 connect(action, SIGNAL(triggered()), this, SLOT(help())); 1693 connect(action, SIGNAL(triggered()), this, SLOT(help()));
1665 m_keyReference->registerShortcut(action); 1694 m_keyReference->registerShortcut(action);
1666 menu->addAction(action); 1695 menu->addAction(action);
1667 1696
1668 action = new QAction(tr("&Key and Mouse Reference"), this); 1697 action = new QAction(tr("&Key and Mouse Reference"), this);
1669 action->setShortcut(tr("F2")); 1698 action->setShortcut(tr("F2"));
1670 action->setStatusTip(tr("Open a window showing the keystrokes you can use in %1").arg(name)); 1699 action->setStatusTip(tr("Open a window showing the keystrokes you can use in %1").arg(name));
1671 connect(action, SIGNAL(triggered()), this, SLOT(keyReference())); 1700 connect(action, SIGNAL(triggered()), this, SLOT(keyReference()));
1672 m_keyReference->registerShortcut(action); 1701 m_keyReference->registerShortcut(action);
1673 menu->addAction(action); 1702 menu->addAction(action);
1674 1703
1675 action = new QAction(tr("%1 on the &Web").arg(name), this); 1704 action = new QAction(tr("%1 on the &Web").arg(name), this);
1676 action->setStatusTip(tr("Open the %1 website").arg(name)); 1705 action->setStatusTip(tr("Open the %1 website").arg(name));
1677 connect(action, SIGNAL(triggered()), this, SLOT(website())); 1706 connect(action, SIGNAL(triggered()), this, SLOT(website()));
1678 menu->addAction(action); 1707 menu->addAction(action);
1679 1708
1680 action = new QAction(tr("&About %1").arg(name), this); 1709 action = new QAction(tr("&About %1").arg(name), this);
1681 action->setStatusTip(tr("Show information about %1").arg(name)); 1710 action->setStatusTip(tr("Show information about %1").arg(name));
1682 connect(action, SIGNAL(triggered()), this, SLOT(about())); 1711 connect(action, SIGNAL(triggered()), this, SLOT(about()));
1683 menu->addAction(action); 1712 menu->addAction(action);
1684 } 1713 }
1685 1714
1686 void 1715 void
1687 MainWindow::setupRecentFilesMenu() 1716 MainWindow::setupRecentFilesMenu()
1688 { 1717 {
1689 m_recentFilesMenu->clear(); 1718 m_recentFilesMenu->clear();
1690 vector<QString> files = m_recentFiles.getRecent(); 1719 vector<QString> files = m_recentFiles.getRecent();
1691 for (size_t i = 0; i < files.size(); ++i) { 1720 for (size_t i = 0; i < files.size(); ++i) {
1692 QAction *action = new QAction(files[i], this); 1721 QAction *action = new QAction(files[i], this);
1693 connect(action, SIGNAL(triggered()), this, SLOT(openRecentFile())); 1722 connect(action, SIGNAL(triggered()), this, SLOT(openRecentFile()));
1694 if (i == 0) { 1723 if (i == 0) {
1695 action->setShortcut(tr("Ctrl+R")); 1724 action->setShortcut(tr("Ctrl+R"));
1696 m_keyReference->registerShortcut 1725 m_keyReference->registerShortcut
1697 (tr("Re-open"), 1726 (tr("Re-open"),
1698 action->shortcut().toString(), 1727 action->shortcut().toString(),
1699 tr("Re-open the current or most recently opened file")); 1728 tr("Re-open the current or most recently opened file"));
1700 } 1729 }
1701 m_recentFilesMenu->addAction(action); 1730 m_recentFilesMenu->addAction(action);
1702 } 1731 }
1703 } 1732 }
1704 1733
1705 void 1734 void
1706 MainWindow::setupTemplatesMenu() 1735 MainWindow::setupTemplatesMenu()
1774 ti->second->shortcut().toString(), 1803 ti->second->shortcut().toString(),
1775 tr("Re-select the most recently run transform")); 1804 tr("Re-select the most recently run transform"));
1776 } else { 1805 } else {
1777 ti->second->setShortcut(QString("")); 1806 ti->second->setShortcut(QString(""));
1778 } 1807 }
1779 m_recentTransformsMenu->addAction(ti->second); 1808 m_recentTransformsMenu->addAction(ti->second);
1780 } 1809 }
1781 } 1810 }
1782 1811
1783 void 1812 void
1784 MainWindow::setupExistingLayersMenus() 1813 MainWindow::setupExistingLayersMenus()
1801 1830
1802 LayerFactory *factory = LayerFactory::getInstance(); 1831 LayerFactory *factory = LayerFactory::getInstance();
1803 1832
1804 for (int i = 0; i < m_paneStack->getPaneCount(); ++i) { 1833 for (int i = 0; i < m_paneStack->getPaneCount(); ++i) {
1805 1834
1806 Pane *pane = m_paneStack->getPane(i); 1835 Pane *pane = m_paneStack->getPane(i);
1807 if (!pane) continue; 1836 if (!pane) continue;
1808 1837
1809 for (int j = 0; j < pane->getLayerCount(); ++j) { 1838 for (int j = 0; j < pane->getLayerCount(); ++j) {
1810 1839
1811 Layer *layer = pane->getLayer(j); 1840 Layer *layer = pane->getLayer(j);
1812 if (!layer) continue; 1841 if (!layer) continue;
1813 if (observedLayers.find(layer) != observedLayers.end()) { 1842 if (observedLayers.find(layer) != observedLayers.end()) {
1814 // std::cerr << "found duplicate layer " << layer << std::endl; 1843 // std::cerr << "found duplicate layer " << layer << std::endl;
1815 continue; 1844 continue;
1816 } 1845 }
1817 1846
1818 // std::cerr << "found new layer " << layer << " (name = " 1847 // std::cerr << "found new layer " << layer << " (name = "
1819 // << layer->getLayerPresentationName() << ")" << std::endl; 1848 // << layer->getLayerPresentationName() << ")" << std::endl;
1820 1849
1821 orderedLayers.push_back(layer); 1850 orderedLayers.push_back(layer);
1822 observedLayers.insert(layer); 1851 observedLayers.insert(layer);
1823 1852
1824 if (factory->isLayerSliceable(layer)) { 1853 if (factory->isLayerSliceable(layer)) {
1825 sliceableLayers.insert(layer); 1854 sliceableLayers.insert(layer);
1826 } 1855 }
1827 } 1856 }
1828 } 1857 }
1829 1858
1830 map<QString, int> observedNames; 1859 map<QString, int> observedNames;
1831 1860
1832 for (size_t i = 0; i < orderedLayers.size(); ++i) { 1861 for (size_t i = 0; i < orderedLayers.size(); ++i) {
1833 1862
1834 Layer *layer = orderedLayers[i]; 1863 Layer *layer = orderedLayers[i];
1835 1864
1836 QString name = layer->getLayerPresentationName(); 1865 QString name = layer->getLayerPresentationName();
1837 int n = ++observedNames[name]; 1866 int n = ++observedNames[name];
1838 if (n > 1) name = QString("%1 <%2>").arg(name).arg(n); 1867 if (n > 1) name = QString("%1 <%2>").arg(name).arg(n);
1839 1868
1840 QIcon icon = il.load(factory->getLayerIconName 1869 QIcon icon = il.load(factory->getLayerIconName
1841 (factory->getLayerType(layer))); 1870 (factory->getLayerType(layer)));
1842 1871
1843 QAction *action = new QAction(icon, name, this); 1872 QAction *action = new QAction(icon, name, this);
1844 connect(action, SIGNAL(triggered()), this, SLOT(addLayer())); 1873 connect(action, SIGNAL(triggered()), this, SLOT(addLayer()));
1845 connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); 1874 connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool)));
1846 m_existingLayerActions[action] = layer; 1875 m_existingLayerActions[action] = layer;
1847 1876
1848 m_existingLayersMenu->addAction(action); 1877 m_existingLayersMenu->addAction(action);
1849 1878
1850 if (sliceableLayers.find(layer) != sliceableLayers.end()) { 1879 if (sliceableLayers.find(layer) != sliceableLayers.end()) {
1851 action = new QAction(icon, name, this); 1880 action = new QAction(icon, name, this);
1852 connect(action, SIGNAL(triggered()), this, SLOT(addLayer())); 1881 connect(action, SIGNAL(triggered()), this, SLOT(addLayer()));
1853 connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); 1882 connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool)));
1897 m_playAction->setCheckable(true); 1926 m_playAction->setCheckable(true);
1898 m_playAction->setShortcut(tr("Space")); 1927 m_playAction->setShortcut(tr("Space"));
1899 m_playAction->setStatusTip(tr("Start or stop playback from the current position")); 1928 m_playAction->setStatusTip(tr("Start or stop playback from the current position"));
1900 connect(m_playAction, SIGNAL(triggered()), this, SLOT(play())); 1929 connect(m_playAction, SIGNAL(triggered()), this, SLOT(play()));
1901 connect(m_playSource, SIGNAL(playStatusChanged(bool)), 1930 connect(m_playSource, SIGNAL(playStatusChanged(bool)),
1902 m_playAction, SLOT(setChecked(bool))); 1931 m_playAction, SLOT(setChecked(bool)));
1903 connect(m_playSource, SIGNAL(playStatusChanged(bool)), 1932 connect(m_playSource, SIGNAL(playStatusChanged(bool)),
1904 this, SLOT(playStatusChanged(bool))); 1933 this, SLOT(playStatusChanged(bool)));
1905 connect(this, SIGNAL(canPlay(bool)), m_playAction, SLOT(setEnabled(bool))); 1934 connect(this, SIGNAL(canPlay(bool)), m_playAction, SLOT(setEnabled(bool)));
1906 1935
1907 m_ffwdAction = toolbar->addAction(il.load("ffwd"), 1936 m_ffwdAction = toolbar->addAction(il.load("ffwd"),
2017 QAction *fastAction = menu->addAction(tr("Speed Up")); 2046 QAction *fastAction = menu->addAction(tr("Speed Up"));
2018 fastAction->setShortcut(tr("Ctrl+PgUp")); 2047 fastAction->setShortcut(tr("Ctrl+PgUp"));
2019 fastAction->setStatusTip(tr("Time-stretch playback to speed it up without changing pitch")); 2048 fastAction->setStatusTip(tr("Time-stretch playback to speed it up without changing pitch"));
2020 connect(fastAction, SIGNAL(triggered()), this, SLOT(speedUpPlayback())); 2049 connect(fastAction, SIGNAL(triggered()), this, SLOT(speedUpPlayback()));
2021 connect(this, SIGNAL(canSpeedUpPlayback(bool)), fastAction, SLOT(setEnabled(bool))); 2050 connect(this, SIGNAL(canSpeedUpPlayback(bool)), fastAction, SLOT(setEnabled(bool)));
2022 2051
2023 QAction *slowAction = menu->addAction(tr("Slow Down")); 2052 QAction *slowAction = menu->addAction(tr("Slow Down"));
2024 slowAction->setShortcut(tr("Ctrl+PgDown")); 2053 slowAction->setShortcut(tr("Ctrl+PgDown"));
2025 slowAction->setStatusTip(tr("Time-stretch playback to slow it down without changing pitch")); 2054 slowAction->setStatusTip(tr("Time-stretch playback to slow it down without changing pitch"));
2026 connect(slowAction, SIGNAL(triggered()), this, SLOT(slowDownPlayback())); 2055 connect(slowAction, SIGNAL(triggered()), this, SLOT(slowDownPlayback()));
2027 connect(this, SIGNAL(canSlowDownPlayback(bool)), slowAction, SLOT(setEnabled(bool))); 2056 connect(this, SIGNAL(canSlowDownPlayback(bool)), slowAction, SLOT(setEnabled(bool)));
2058 group->addAction(action); 2087 group->addAction(action);
2059 m_keyReference->registerShortcut(action); 2088 m_keyReference->registerShortcut(action);
2060 m_toolActions[ViewManager::NavigateMode] = action; 2089 m_toolActions[ViewManager::NavigateMode] = action;
2061 2090
2062 action = toolbar->addAction(il.load("select"), 2091 action = toolbar->addAction(il.load("select"),
2063 tr("Select")); 2092 tr("Select"));
2064 action->setCheckable(true); 2093 action->setCheckable(true);
2065 action->setShortcut(tr("2")); 2094 action->setShortcut(tr("2"));
2066 action->setStatusTip(tr("Select ranges")); 2095 action->setStatusTip(tr("Select ranges"));
2067 connect(action, SIGNAL(triggered()), this, SLOT(toolSelectSelected())); 2096 connect(action, SIGNAL(triggered()), this, SLOT(toolSelectSelected()));
2068 group->addAction(action); 2097 group->addAction(action);
2069 m_keyReference->registerShortcut(action); 2098 m_keyReference->registerShortcut(action);
2070 m_toolActions[ViewManager::SelectMode] = action; 2099 m_toolActions[ViewManager::SelectMode] = action;
2071 2100
2072 action = toolbar->addAction(il.load("move"), 2101 action = toolbar->addAction(il.load("move"),
2073 tr("Edit")); 2102 tr("Edit"));
2074 action->setCheckable(true); 2103 action->setCheckable(true);
2075 action->setShortcut(tr("3")); 2104 action->setShortcut(tr("3"));
2076 action->setStatusTip(tr("Edit items in layer")); 2105 action->setStatusTip(tr("Edit items in layer"));
2077 connect(action, SIGNAL(triggered()), this, SLOT(toolEditSelected())); 2106 connect(action, SIGNAL(triggered()), this, SLOT(toolEditSelected()));
2078 connect(this, SIGNAL(canEditLayer(bool)), action, SLOT(setEnabled(bool))); 2107 connect(this, SIGNAL(canEditLayer(bool)), action, SLOT(setEnabled(bool)));
2079 group->addAction(action); 2108 group->addAction(action);
2080 m_keyReference->registerShortcut(action); 2109 m_keyReference->registerShortcut(action);
2081 m_toolActions[ViewManager::EditMode] = action; 2110 m_toolActions[ViewManager::EditMode] = action;
2082 2111
2083 action = toolbar->addAction(il.load("draw"), 2112 action = toolbar->addAction(il.load("draw"),
2084 tr("Draw")); 2113 tr("Draw"));
2085 action->setCheckable(true); 2114 action->setCheckable(true);
2086 action->setShortcut(tr("4")); 2115 action->setShortcut(tr("4"));
2087 action->setStatusTip(tr("Draw new items in layer")); 2116 action->setStatusTip(tr("Draw new items in layer"));
2088 connect(action, SIGNAL(triggered()), this, SLOT(toolDrawSelected())); 2117 connect(action, SIGNAL(triggered()), this, SLOT(toolDrawSelected()));
2089 connect(this, SIGNAL(canEditLayer(bool)), action, SLOT(setEnabled(bool))); 2118 connect(this, SIGNAL(canEditLayer(bool)), action, SLOT(setEnabled(bool)));
2090 group->addAction(action); 2119 group->addAction(action);
2091 m_keyReference->registerShortcut(action); 2120 m_keyReference->registerShortcut(action);
2092 m_toolActions[ViewManager::DrawMode] = action; 2121 m_toolActions[ViewManager::DrawMode] = action;
2093 2122
2094 action = toolbar->addAction(il.load("erase"), 2123 action = toolbar->addAction(il.load("erase"),
2095 tr("Erase")); 2124 tr("Erase"));
2096 action->setCheckable(true); 2125 action->setCheckable(true);
2097 action->setShortcut(tr("5")); 2126 action->setShortcut(tr("5"));
2098 action->setStatusTip(tr("Erase items from layer")); 2127 action->setStatusTip(tr("Erase items from layer"));
2099 connect(action, SIGNAL(triggered()), this, SLOT(toolEraseSelected())); 2128 connect(action, SIGNAL(triggered()), this, SLOT(toolEraseSelected()));
2100 connect(this, SIGNAL(canEditLayer(bool)), action, SLOT(setEnabled(bool))); 2129 connect(this, SIGNAL(canEditLayer(bool)), action, SLOT(setEnabled(bool)));
2146 (currentPane != 0); 2175 (currentPane != 0);
2147 bool haveCurrentLayer = 2176 bool haveCurrentLayer =
2148 (haveCurrentPane && 2177 (haveCurrentPane &&
2149 (currentLayer != 0)); 2178 (currentLayer != 0));
2150 bool havePlayTarget = 2179 bool havePlayTarget =
2151 (m_playTarget != 0); 2180 (m_playTarget != 0);
2152 bool haveSelection = 2181 bool haveSelection =
2153 (m_viewManager && 2182 (m_viewManager &&
2154 !m_viewManager->getSelections().empty()); 2183 !m_viewManager->getSelections().empty());
2155 bool haveCurrentEditableLayer = 2184 bool haveCurrentEditableLayer =
2156 (haveCurrentLayer && 2185 (haveCurrentLayer &&
2157 currentLayer->isLayerEditable()); 2186 currentLayer->isLayerEditable());
2158 bool haveCurrentTimeInstantsLayer = 2187 bool haveCurrentTimeInstantsLayer =
2159 (haveCurrentLayer && 2188 (haveCurrentLayer &&
2160 dynamic_cast<TimeInstantLayer *>(currentLayer)); 2189 dynamic_cast<TimeInstantLayer *>(currentLayer));
2161 bool haveCurrentTimeValueLayer = 2190 bool haveCurrentTimeValueLayer =
2162 (haveCurrentLayer && 2191 (haveCurrentLayer &&
2163 dynamic_cast<TimeValueLayer *>(currentLayer)); 2192 dynamic_cast<TimeValueLayer *>(currentLayer));
2164 2193
2165 bool alignMode = m_viewManager && m_viewManager->getAlignMode(); 2194 bool alignMode = m_viewManager && m_viewManager->getAlignMode();
2166 emit canChangeSolo(havePlayTarget && !alignMode); 2195 emit canChangeSolo(havePlayTarget && !alignMode);
2167 emit canAlign(havePlayTarget && m_document && m_document->canAlign()); 2196 emit canAlign(havePlayTarget && m_document && m_document->canAlign());
2168 2197
2169 emit canChangePlaybackSpeed(true); 2198 emit canChangePlaybackSpeed(true);
2170 int v = m_playSpeed->value(); 2199 int v = m_playSpeed->value();
2171 emit canSpeedUpPlayback(v < m_playSpeed->maximum()); 2200 emit canSpeedUpPlayback(v < m_playSpeed->maximum());
2172 emit canSlowDownPlayback(v > m_playSpeed->minimum()); 2201 emit canSlowDownPlayback(v > m_playSpeed->minimum());
2173 2202
2174 if (m_viewManager && 2203 if (m_viewManager &&
2175 (m_viewManager->getToolMode() == ViewManager::MeasureMode)) { 2204 (m_viewManager->getToolMode() == ViewManager::MeasureMode)) {
2176 emit canDeleteSelection(haveCurrentLayer); 2205 emit canDeleteSelection(haveCurrentLayer);
2177 m_deleteSelectedAction->setText(tr("&Delete Current Measurement")); 2206 m_deleteSelectedAction->setText(tr("&Delete Current Measurement"));
2178 m_deleteSelectedAction->setStatusTip(tr("Delete the measurement currently under the mouse pointer")); 2207 m_deleteSelectedAction->setStatusTip(tr("Delete the measurement currently under the mouse pointer"));
2179 } else { 2208 } else {
2204 2233
2205 void 2234 void
2206 MainWindow::updateDescriptionLabel() 2235 MainWindow::updateDescriptionLabel()
2207 { 2236 {
2208 if (!getMainModel()) { 2237 if (!getMainModel()) {
2209 m_descriptionLabel->setText(tr("No audio file loaded.")); 2238 m_descriptionLabel->setText(tr("No audio file loaded."));
2210 return; 2239 return;
2211 } 2240 }
2212 2241
2213 QString description; 2242 QString description;
2214 2243
2215 size_t ssr = getMainModel()->getSampleRate(); 2244 size_t ssr = getMainModel()->getSampleRate();
2216 size_t tsr = ssr; 2245 size_t tsr = ssr;
2217 if (m_playSource) tsr = m_playSource->getTargetSampleRate(); 2246 if (m_playSource) tsr = m_playSource->getTargetSampleRate();
2218 2247
2219 if (ssr != tsr) { 2248 if (ssr != tsr) {
2220 description = tr("%1Hz (resampling to %2Hz)").arg(ssr).arg(tsr); 2249 description = tr("%1Hz (resampling to %2Hz)").arg(ssr).arg(tsr);
2221 } else { 2250 } else {
2222 description = QString("%1Hz").arg(ssr); 2251 description = QString("%1Hz").arg(ssr);
2223 } 2252 }
2224 2253
2225 description = QString("%1 - %2") 2254 description = QString("%1 - %2")
2226 .arg(RealTime::frame2RealTime(getMainModel()->getEndFrame(), ssr) 2255 .arg(RealTime::frame2RealTime(getMainModel()->getEndFrame(), ssr)
2227 .toText(false).c_str()) 2256 .toText(false).c_str())
2228 .arg(description); 2257 .arg(description);
2229 2258
2230 m_descriptionLabel->setText(description); 2259 m_descriptionLabel->setText(description);
2231 } 2260 }
2232 2261
2233 void 2262 void
2284 MainWindow::importAudio() 2313 MainWindow::importAudio()
2285 { 2314 {
2286 QString path = getOpenFileName(FileFinder::AudioFile); 2315 QString path = getOpenFileName(FileFinder::AudioFile);
2287 2316
2288 if (path != "") { 2317 if (path != "") {
2289 if (openAudio(path, ReplaceSession) == FileOpenFailed) { 2318 if (openAudio(path, ReplaceSession) == FileOpenFailed) {
2290 emit hideSplash(); 2319 emit hideSplash();
2291 QMessageBox::critical(this, tr("Failed to open file"), 2320 QMessageBox::critical(this, tr("Failed to open file"),
2292 tr("<b>File open failed</b><p>Audio file \"%1\" could not be opened").arg(path)); 2321 tr("<b>File open failed</b><p>Audio file \"%1\" could not be opened").arg(path));
2293 } 2322 }
2294 } 2323 }
2295 } 2324 }
2296 2325
2297 void 2326 void
2298 MainWindow::importMoreAudio() 2327 MainWindow::importMoreAudio()
2299 { 2328 {
2300 QString path = getOpenFileName(FileFinder::AudioFile); 2329 QString path = getOpenFileName(FileFinder::AudioFile);
2301 2330
2302 if (path != "") { 2331 if (path != "") {
2303 if (openAudio(path, CreateAdditionalModel) == FileOpenFailed) { 2332 if (openAudio(path, CreateAdditionalModel) == FileOpenFailed) {
2304 emit hideSplash(); 2333 emit hideSplash();
2305 QMessageBox::critical(this, tr("Failed to open file"), 2334 QMessageBox::critical(this, tr("Failed to open file"),
2306 tr("<b>File open failed</b><p>Audio file \"%1\" could not be opened").arg(path)); 2335 tr("<b>File open failed</b><p>Audio file \"%1\" could not be opened").arg(path));
2307 } 2336 }
2308 } 2337 }
2338
2339 files_paths[int(m_paneStack->getPaneCount())-1] = path;
2309 } 2340 }
2310 2341
2311 void 2342 void
2312 MainWindow::replaceMainAudio() 2343 MainWindow::replaceMainAudio()
2313 { 2344 {
2314 QString path = getOpenFileName(FileFinder::AudioFile); 2345 QString path = getOpenFileName(FileFinder::AudioFile);
2315 2346
2316 if (path != "") { 2347 if (path != "") {
2317 if (openAudio(path, ReplaceMainModel) == FileOpenFailed) { 2348 if (openAudio(path, ReplaceMainModel) == FileOpenFailed) {
2318 emit hideSplash(); 2349 emit hideSplash();
2319 QMessageBox::critical(this, tr("Failed to open file"), 2350 QMessageBox::critical(this, tr("Failed to open file"),
2320 tr("<b>File open failed</b><p>Audio file \"%1\" could not be opened").arg(path)); 2351 tr("<b>File open failed</b><p>Audio file \"%1\" could not be opened").arg(path));
2321 } 2352 }
2322 } 2353 }
2323 } 2354 }
2324 2355
2325 void 2356 void
2326 MainWindow::exportAudio() 2357 MainWindow::exportAudio()
2337 for (int j = 0; j < pane->getLayerCount(); ++j) { 2368 for (int j = 0; j < pane->getLayerCount(); ++j) {
2338 Layer *layer = pane->getLayer(j); 2369 Layer *layer = pane->getLayer(j);
2339 if (!layer) continue; 2370 if (!layer) continue;
2340 cerr << "layer = " << layer->objectName() << endl; 2371 cerr << "layer = " << layer->objectName() << endl;
2341 Model *m = layer->getModel(); 2372 Model *m = layer->getModel();
2342 RangeSummarisableTimeValueModel *wm = 2373 RangeSummarisableTimeValueModel *wm =
2343 dynamic_cast<RangeSummarisableTimeValueModel *>(m); 2374 dynamic_cast<RangeSummarisableTimeValueModel *>(m);
2344 if (wm) { 2375 if (wm) {
2345 cerr << "found: " << wm->objectName() << endl; 2376 cerr << "found: " << wm->objectName() << endl;
2346 otherModels.insert(wm); 2377 otherModels.insert(wm);
2347 if (pane == m_paneStack->getCurrentPane()) { 2378 if (pane == m_paneStack->getCurrentPane()) {
2399 2430
2400 MultiSelection *selectionToWrite = 0; 2431 MultiSelection *selectionToWrite = 0;
2401 2432
2402 if (selections.size() == 1) { 2433 if (selections.size() == 1) {
2403 2434
2404 QStringList items; 2435 QStringList items;
2405 items << tr("Export the selected region only") 2436 items << tr("Export the selected region only")
2406 << tr("Export the whole audio file"); 2437 << tr("Export the whole audio file");
2407 2438
2408 bool ok = false; 2439 bool ok = false;
2409 QString item = ListInputDialog::getItem 2440 QString item = ListInputDialog::getItem
2410 (this, tr("Select region to export"), 2441 (this, tr("Select region to export"),
2411 tr("Which region from the original audio file do you want to export?"), 2442 tr("Which region from the original audio file do you want to export?"),
2412 items, 0, &ok); 2443 items, 0, &ok);
2413 2444
2414 if (!ok || item.isEmpty()) return; 2445 if (!ok || item.isEmpty()) return;
2415 2446
2416 if (item == items[0]) selectionToWrite = &ms; 2447 if (item == items[0]) selectionToWrite = &ms;
2417 2448
2418 } else if (selections.size() > 1) { 2449 } else if (selections.size() > 1) {
2419 2450
2420 QStringList items; 2451 QStringList items;
2421 items << tr("Export the selected regions into a single audio file") 2452 items << tr("Export the selected regions into a single audio file")
2422 << tr("Export the selected regions into separate files") 2453 << tr("Export the selected regions into separate files")
2423 << tr("Export the whole audio file"); 2454 << tr("Export the whole audio file");
2424 2455
2425 QString item = ListInputDialog::getItem 2456 QString item = ListInputDialog::getItem
2426 (this, tr("Select region to export"), 2457 (this, tr("Select region to export"),
2427 tr("Multiple regions of the original audio file are selected.\nWhat do you want to export?"), 2458 tr("Multiple regions of the original audio file are selected.\nWhat do you want to export?"),
2428 items, 0, &ok); 2459 items, 0, &ok);
2429 2460
2430 if (!ok || item.isEmpty()) return; 2461 if (!ok || item.isEmpty()) return;
2431 2462
2432 if (item == items[0]) { 2463 if (item == items[0]) {
2433 2464
2434 selectionToWrite = &ms; 2465 selectionToWrite = &ms;
2435 2466
2436 } else if (item == items[1]) { 2467 } else if (item == items[1]) {
2437 2468
2438 multiple = true; 2469 multiple = true;
2439 2470
2440 int n = 1; 2471 int n = 1;
2441 QString base = path; 2472 QString base = path;
2442 base.replace(".wav", ""); 2473 base.replace(".wav", "");
2443 2474
2444 for (MultiSelection::SelectionList::iterator i = selections.begin(); 2475 for (MultiSelection::SelectionList::iterator i = selections.begin();
2445 i != selections.end(); ++i) { 2476 i != selections.end(); ++i) {
2446 2477
2447 MultiSelection subms; 2478 MultiSelection subms;
2448 subms.setSelection(*i); 2479 subms.setSelection(*i);
2449 2480
2450 QString subpath = QString("%1.%2.wav").arg(base).arg(n); 2481 QString subpath = QString("%1.%2.wav").arg(base).arg(n);
2451 ++n; 2482 ++n;
2452 2483
2453 if (QFileInfo(subpath).exists()) { 2484 if (QFileInfo(subpath).exists()) {
2454 error = tr("Fragment file %1 already exists, aborting").arg(subpath); 2485 error = tr("Fragment file %1 already exists, aborting").arg(subpath);
2455 break; 2486 break;
2456 } 2487 }
2457 2488
2458 WavFileWriter subwriter(subpath, 2489 WavFileWriter subwriter(subpath,
2459 model->getSampleRate(), 2490 model->getSampleRate(),
2460 model->getChannelCount(), 2491 model->getChannelCount(),
2461 WavFileWriter::WriteToTemporary); 2492 WavFileWriter::WriteToTemporary);
2462 subwriter.writeModel(model, &subms); 2493 subwriter.writeModel(model, &subms);
2463 ok = subwriter.isOK(); 2494 ok = subwriter.isOK();
2464 2495
2465 if (!ok) { 2496 if (!ok) {
2466 error = subwriter.getError(); 2497 error = subwriter.getError();
2467 break; 2498 break;
2468 } 2499 }
2469 } 2500 }
2470 } 2501 }
2471 } 2502 }
2472 2503
2473 if (!multiple) { 2504 if (!multiple) {
2474 WavFileWriter writer(path, 2505 WavFileWriter writer(path,
2475 model->getSampleRate(), 2506 model->getSampleRate(),
2476 model->getChannelCount(), 2507 model->getChannelCount(),
2477 WavFileWriter::WriteToTemporary); 2508 WavFileWriter::WriteToTemporary);
2478 writer.writeModel(model, selectionToWrite); 2509 writer.writeModel(model, selectionToWrite);
2479 ok = writer.isOK(); 2510 ok = writer.isOK();
2480 error = writer.getError(); 2511 error = writer.getError();
2481 } 2512 }
2482 2513
2483 if (ok) { 2514 if (ok) {
2484 if (multiple) { 2515 if (multiple) {
2485 emit activity(tr("Export multiple audio files")); 2516 emit activity(tr("Export multiple audio files"));
2486 } else { 2517 } else {
2487 emit activity(tr("Export audio to \"%1\"").arg(path)); 2518 emit activity(tr("Export audio to \"%1\"").arg(path));
2488 m_recentFiles.addFile(path); 2519 m_recentFiles.addFile(path);
2489 } 2520 }
2490 } else { 2521 } else {
2491 QMessageBox::critical(this, tr("Failed to write file"), error); 2522 QMessageBox::critical(this, tr("Failed to write file"), error);
2492 } 2523 }
2493 } 2524 }
2525
2526
2527
2494 2528
2495 void 2529 void
2496 MainWindow::importLayer() 2530 MainWindow::importLayer()
2497 { 2531 {
2498 Pane *pane = m_paneStack->getCurrentPane(); 2532 Pane *pane = m_paneStack->getCurrentPane();
2499 2533
2500 if (!pane) { 2534 if (!pane) {
2501 // shouldn't happen, as the menu action should have been disabled 2535 // shouldn't happen, as the menu action should have been disabled
2502 std::cerr << "WARNING: MainWindow::importLayer: no current pane" << std::endl; 2536 std::cerr << "WARNING: MainWindow::importLayer: no current pane" << std::endl;
2503 return; 2537 return;
2504 } 2538 }
2505 2539
2506 if (!getMainModel()) { 2540 if (!getMainModel()) {
2507 // shouldn't happen, as the menu action should have been disabled 2541 // shouldn't happen, as the menu action should have been disabled
2508 std::cerr << "WARNING: MainWindow::importLayer: No main model -- hence no default sample rate available" << std::endl; 2542 std::cerr << "WARNING: MainWindow::importLayer: No main model -- hence no default sample rate available" << std::endl;
2509 return; 2543 return;
2510 } 2544 }
2511 2545
2512 QString path = getOpenFileName(FileFinder::LayerFile); 2546 QString path = getOpenFileName(FileFinder::LayerFile);
2513 2547
2514 if (path != "") { 2548 if (path != "") {
2515 2549
2516 FileOpenStatus status = openLayer(path); 2550 FileOpenStatus status = openLayer(path);
2517 2551
2518 if (status == FileOpenFailed) { 2552 if (status == FileOpenFailed) {
2519 emit hideSplash(); 2553 emit hideSplash();
2520 QMessageBox::critical(this, tr("Failed to open file"), 2554 QMessageBox::critical(this, tr("Failed to open file"),
2521 tr("<b>File open failed</b><p>Layer file %1 could not be opened.").arg(path)); 2555 tr("<b>File open failed</b><p>Layer file %1 could not be opened.").arg(path));
2522 return; 2556 return;
2625 void 2659 void
2626 MainWindow::exportImage() 2660 MainWindow::exportImage()
2627 { 2661 {
2628 Pane *pane = m_paneStack->getCurrentPane(); 2662 Pane *pane = m_paneStack->getCurrentPane();
2629 if (!pane) return; 2663 if (!pane) return;
2630 2664
2631 QString path = getSaveFileName(FileFinder::ImageFile); 2665 QString path = getSaveFileName(FileFinder::ImageFile);
2632 2666
2633 if (path == "") return; 2667 if (path == "") return;
2634 2668
2635 if (QFileInfo(path).suffix() == "") path += ".png"; 2669 if (QFileInfo(path).suffix() == "") path += ".png";
2640 total = pane->getImageSize(); 2674 total = pane->getImageSize();
2641 visible = pane->getImageSize(pane->getFirstVisibleFrame(), 2675 visible = pane->getImageSize(pane->getFirstVisibleFrame(),
2642 pane->getLastVisibleFrame()); 2676 pane->getLastVisibleFrame());
2643 2677
2644 size_t sf0 = 0, sf1 = 0; 2678 size_t sf0 = 0, sf1 = 0;
2645 2679
2646 if (haveSelection) { 2680 if (haveSelection) {
2647 MultiSelection::SelectionList selections = m_viewManager->getSelections(); 2681 MultiSelection::SelectionList selections = m_viewManager->getSelections();
2648 sf0 = selections.begin()->getStartFrame(); 2682 sf0 = selections.begin()->getStartFrame();
2649 MultiSelection::SelectionList::iterator e = selections.end(); 2683 MultiSelection::SelectionList::iterator e = selections.end();
2650 --e; 2684 --e;
2684 } 2718 }
2685 2719
2686 bool ok = lid->exec(); 2720 bool ok = lid->exec();
2687 QString item = lid->getCurrentString(); 2721 QString item = lid->getCurrentString();
2688 delete lid; 2722 delete lid;
2689 2723
2690 if (!ok || item.isEmpty()) return; 2724 if (!ok || item.isEmpty()) return;
2691 2725
2692 settings.setValue("lastimageexportregion", deflt); 2726 settings.setValue("lastimageexportregion", deflt);
2693 2727
2694 QImage *image = 0; 2728 QImage *image = 0;
2706 2740
2707 if (!image->save(path, "PNG")) { 2741 if (!image->save(path, "PNG")) {
2708 QMessageBox::critical(this, tr("Failed to save image file"), 2742 QMessageBox::critical(this, tr("Failed to save image file"),
2709 tr("Failed to save image file %1").arg(path)); 2743 tr("Failed to save image file %1").arg(path));
2710 } 2744 }
2711 2745
2712 delete image; 2746 delete image;
2713 } 2747 }
2714 2748
2715 void 2749 void
2716 MainWindow::newSession() 2750 MainWindow::newSession()
2724 2758
2725 connect(pane, SIGNAL(contextHelpChanged(const QString &)), 2759 connect(pane, SIGNAL(contextHelpChanged(const QString &)),
2726 this, SLOT(contextHelpChanged(const QString &))); 2760 this, SLOT(contextHelpChanged(const QString &)));
2727 2761
2728 if (!m_timeRulerLayer) { 2762 if (!m_timeRulerLayer) {
2729 m_timeRulerLayer = m_document->createMainModelLayer 2763 m_timeRulerLayer = m_document->createMainModelLayer
2730 (LayerFactory::TimeRuler); 2764 (LayerFactory::TimeRuler);
2731 } 2765 }
2732 2766
2733 m_document->addLayerToView(pane, m_timeRulerLayer); 2767 m_document->addLayerToView(pane, m_timeRulerLayer);
2734 2768
2735 Layer *waveform = m_document->createMainModelLayer(LayerFactory::Waveform); 2769 Layer *waveform = m_document->createMainModelLayer(LayerFactory::Waveform);
2757 { 2791 {
2758 if (!checkSaveModified()) return; 2792 if (!checkSaveModified()) return;
2759 2793
2760 while (m_paneStack->getPaneCount() > 0) { 2794 while (m_paneStack->getPaneCount() > 0) {
2761 2795
2762 Pane *pane = m_paneStack->getPane(m_paneStack->getPaneCount() - 1); 2796 Pane *pane = m_paneStack->getPane(m_paneStack->getPaneCount() - 1);
2763 2797
2764 while (pane->getLayerCount() > 0) { 2798 while (pane->getLayerCount() > 0) {
2765 m_document->removeLayerFromView 2799 m_document->removeLayerFromView
2766 (pane, pane->getLayer(pane->getLayerCount() - 1)); 2800 (pane, pane->getLayer(pane->getLayerCount() - 1));
2767 } 2801 }
2768 2802
2769 m_overview->unregisterView(pane); 2803 m_overview->unregisterView(pane);
2770 m_paneStack->deletePane(pane); 2804 m_paneStack->deletePane(pane);
2771 } 2805 }
2772 2806
2773 while (m_paneStack->getHiddenPaneCount() > 0) { 2807 while (m_paneStack->getHiddenPaneCount() > 0) {
2774 2808
2775 Pane *pane = m_paneStack->getHiddenPane 2809 Pane *pane = m_paneStack->getHiddenPane
2776 (m_paneStack->getHiddenPaneCount() - 1); 2810 (m_paneStack->getHiddenPaneCount() - 1);
2777 2811
2778 while (pane->getLayerCount() > 0) { 2812 while (pane->getLayerCount() > 0) {
2779 m_document->removeLayerFromView 2813 m_document->removeLayerFromView
2780 (pane, pane->getLayer(pane->getLayerCount() - 1)); 2814 (pane, pane->getLayer(pane->getLayerCount() - 1));
2781 } 2815 }
2782 2816
2783 m_overview->unregisterView(pane); 2817 m_overview->unregisterView(pane);
2784 m_paneStack->deletePane(pane); 2818 m_paneStack->deletePane(pane);
2785 } 2819 }
2786 2820
2787 delete m_layerTreeDialog.data(); 2821 delete m_layerTreeDialog.data();
2788 delete m_preferencesDialog.data(); 2822 delete m_preferencesDialog.data();
2789 2823
2816 2850
2817 if (path.isEmpty()) return; 2851 if (path.isEmpty()) return;
2818 2852
2819 if (openSessionFile(path) == FileOpenFailed) { 2853 if (openSessionFile(path) == FileOpenFailed) {
2820 emit hideSplash(); 2854 emit hideSplash();
2821 QMessageBox::critical(this, tr("Failed to open file"), 2855 QMessageBox::critical(this, tr("Failed to open file"),
2822 tr("<b>File open failed</b><p>Session file \"%1\" could not be opened").arg(path)); 2856 tr("<b>File open failed</b><p>Session file \"%1\" could not be opened").arg(path));
2823 } 2857 }
2824 } 2858 }
2825 2859
2826 void 2860 void
2827 MainWindow::openSomething() 2861 MainWindow::openSomething()
2843 } else if (status == FileOpenWrongMode) { 2877 } else if (status == FileOpenWrongMode) {
2844 emit hideSplash(); 2878 emit hideSplash();
2845 QMessageBox::critical(this, tr("Failed to open file"), 2879 QMessageBox::critical(this, tr("Failed to open file"),
2846 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)); 2880 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));
2847 } 2881 }
2882
2883 files_paths[0] = path;
2884 QTextStream out(stdout);
2885 out << path;
2886
2848 } 2887 }
2849 2888
2850 void 2889 void
2851 MainWindow::openLocation() 2890 MainWindow::openLocation()
2852 { 2891 {
2882 void 2921 void
2883 MainWindow::openRecentFile() 2922 MainWindow::openRecentFile()
2884 { 2923 {
2885 QObject *obj = sender(); 2924 QObject *obj = sender();
2886 QAction *action = dynamic_cast<QAction *>(obj); 2925 QAction *action = dynamic_cast<QAction *>(obj);
2887 2926
2888 if (!action) { 2927 if (!action) {
2889 std::cerr << "WARNING: MainWindow::openRecentFile: sender is not an action" 2928 std::cerr << "WARNING: MainWindow::openRecentFile: sender is not an action"
2890 << std::endl; 2929 << std::endl;
2891 return; 2930 return;
2892 } 2931 }
2893 2932
2894 QString path = action->text(); 2933 QString path = action->text();
2895 if (path == "") return; 2934 if (path == "") return;
2896 2935
2912 { 2951 {
2913 QObject *s = sender(); 2952 QObject *s = sender();
2914 QAction *action = qobject_cast<QAction *>(s); 2953 QAction *action = qobject_cast<QAction *>(s);
2915 2954
2916 if (!action) { 2955 if (!action) {
2917 std::cerr << "WARNING: MainWindow::applyTemplate: sender is not an action" 2956 std::cerr << "WARNING: MainWindow::applyTemplate: sender is not an action"
2918 << std::endl; 2957 << std::endl;
2919 return; 2958 return;
2920 } 2959 }
2921 2960
2922 QString n = action->objectName(); 2961 QString n = action->objectName();
2923 if (n == "") n = action->text(); 2962 if (n == "") n = action->text();
2924 2963
2951 0, 0); 2990 0, 0);
2952 QLineEdit *lineEdit = new QLineEdit; 2991 QLineEdit *lineEdit = new QLineEdit;
2953 layout->addWidget(lineEdit, 1, 0); 2992 layout->addWidget(lineEdit, 1, 0);
2954 QCheckBox *makeDefault = new QCheckBox(tr("Set as default template for future audio files")); 2993 QCheckBox *makeDefault = new QCheckBox(tr("Set as default template for future audio files"));
2955 layout->addWidget(makeDefault, 2, 0); 2994 layout->addWidget(makeDefault, 2, 0);
2956 2995
2957 QDialogButtonBox *bb = new QDialogButtonBox(QDialogButtonBox::Ok | 2996 QDialogButtonBox *bb = new QDialogButtonBox(QDialogButtonBox::Ok |
2958 QDialogButtonBox::Cancel); 2997 QDialogButtonBox::Cancel);
2959 layout->addWidget(bb, 3, 0); 2998 layout->addWidget(bb, 3, 0);
2960 connect(bb, SIGNAL(accepted()), d, SLOT(accept())); 2999 connect(bb, SIGNAL(accepted()), d, SLOT(accept()));
2961 connect(bb, SIGNAL(accepted()), d, SLOT(accept())); 3000 connect(bb, SIGNAL(accepted()), d, SLOT(accept()));
2962 connect(bb, SIGNAL(rejected()), d, SLOT(reject())); 3001 connect(bb, SIGNAL(rejected()), d, SLOT(reject()));
2963 3002
2964 if (d->exec() == QDialog::Accepted) { 3003 if (d->exec() == QDialog::Accepted) {
2965 3004
2966 QString name = lineEdit->text(); 3005 QString name = lineEdit->text();
2967 name.replace(QRegExp("[^\\w\\s\\.\"'-]"), "_"); 3006 name.replace(QRegExp("[^\\w\\s\\.\"'-]"), "_");
2968 3007
2996 3035
2997 void 3036 void
2998 MainWindow::paneAdded(Pane *pane) 3037 MainWindow::paneAdded(Pane *pane)
2999 { 3038 {
3000 if (m_overview) m_overview->registerView(pane); 3039 if (m_overview) m_overview->registerView(pane);
3001 } 3040 }
3002 3041
3003 void 3042 void
3004 MainWindow::paneHidden(Pane *pane) 3043 MainWindow::paneHidden(Pane *pane)
3005 { 3044 {
3006 if (m_overview) m_overview->unregisterView(pane); 3045 if (m_overview) m_overview->unregisterView(pane);
3007 } 3046 }
3008 3047
3009 void 3048 void
3010 MainWindow::paneAboutToBeDeleted(Pane *pane) 3049 MainWindow::paneAboutToBeDeleted(Pane *pane)
3011 { 3050 {
3012 if (m_overview) m_overview->unregisterView(pane); 3051 if (m_overview) m_overview->unregisterView(pane);
3013 } 3052 }
3014 3053
3015 void 3054 void
3016 MainWindow::paneDropAccepted(Pane *pane, QStringList uriList) 3055 MainWindow::paneDropAccepted(Pane *pane, QStringList uriList)
3017 { 3056 {
3018 if (pane) m_paneStack->setCurrentPane(pane); 3057 if (pane) m_paneStack->setCurrentPane(pane);
3047 MainWindow::paneDropAccepted(Pane *pane, QString text) 3086 MainWindow::paneDropAccepted(Pane *pane, QString text)
3048 { 3087 {
3049 if (pane) m_paneStack->setCurrentPane(pane); 3088 if (pane) m_paneStack->setCurrentPane(pane);
3050 3089
3051 QUrl testUrl(text); 3090 QUrl testUrl(text);
3052 if (testUrl.scheme() == "file" || 3091 if (testUrl.scheme() == "file" ||
3053 testUrl.scheme() == "http" || 3092 testUrl.scheme() == "http" ||
3054 testUrl.scheme() == "ftp") { 3093 testUrl.scheme() == "ftp") {
3055 QStringList list; 3094 QStringList list;
3056 list.push_back(text); 3095 list.push_back(text);
3057 paneDropAccepted(pane, list); 3096 paneDropAccepted(pane, list);
3058 return; 3097 return;
3067 { 3106 {
3068 // std::cerr << "MainWindow::closeEvent" << std::endl; 3107 // std::cerr << "MainWindow::closeEvent" << std::endl;
3069 3108
3070 if (m_openingAudioFile) { 3109 if (m_openingAudioFile) {
3071 // std::cerr << "Busy - ignoring close event" << std::endl; 3110 // std::cerr << "Busy - ignoring close event" << std::endl;
3072 e->ignore(); 3111 e->ignore();
3073 return; 3112 return;
3074 } 3113 }
3075 3114
3076 if (!m_abandoning && !checkSaveModified()) { 3115 if (!m_abandoning && !checkSaveModified()) {
3077 // std::cerr << "Close refused by user - ignoring close event" << endl; 3116 // std::cerr << "Close refused by user - ignoring close event" << endl;
3078 e->ignore(); 3117 e->ignore();
3079 return; 3118 return;
3080 } 3119 }
3081 3120
3082 QSettings settings; 3121 QSettings settings;
3083 settings.beginGroup("MainWindow"); 3122 settings.beginGroup("MainWindow");
3084 settings.setValue("size", size()); 3123 settings.setValue("size", size());
3127 if (!QFileInfo(svDir).exists()) { 3166 if (!QFileInfo(svDir).exists()) {
3128 if (!QDir::home().mkdir(svDirBase)) return false; 3167 if (!QDir::home().mkdir(svDirBase)) return false;
3129 } else { 3168 } else {
3130 if (!QFileInfo(svDir).isDir()) return false; 3169 if (!QFileInfo(svDir).isDir()) return false;
3131 } 3170 }
3132 3171
3133 // This name doesn't have to be unguessable 3172 // This name doesn't have to be unguessable
3134 #ifndef _WIN32 3173 #ifndef _WIN32
3135 QString fname = QString("tmp-%1-%2.sv") 3174 QString fname = QString("tmp-%1-%2.sv")
3136 .arg(QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz")) 3175 .arg(QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz"))
3137 .arg(QProcess().pid()); 3176 .arg(QProcess().pid());
3159 3198
3160 if (!m_documentModified) return true; 3199 if (!m_documentModified) return true;
3161 3200
3162 emit hideSplash(); 3201 emit hideSplash();
3163 3202
3164 int button = 3203 int button =
3165 QMessageBox::warning(this, 3204 QMessageBox::warning(this,
3166 tr("Session modified"), 3205 tr("Session modified"),
3167 tr("<b>Session modified</b><p>The current session has been modified.<br>Do you want to save it?"), 3206 tr("<b>Session modified</b><p>The current session has been modified.<br>Do you want to save it?"),
3168 QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel, 3207 QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel,
3169 QMessageBox::Yes); 3208 QMessageBox::Yes);
3170 3209
3171 if (button == QMessageBox::Yes) { 3210 if (button == QMessageBox::Yes) {
3172 saveSession(); 3211 saveSession();
3173 if (m_documentModified) { // save failed -- don't proceed! 3212 if (m_documentModified) { // save failed -- don't proceed!
3174 return false; 3213 return false;
3175 } else { 3214 } else {
3176 return true; // saved, so it's safe to continue now 3215 return true; // saved, so it's safe to continue now
3177 } 3216 }
3178 } else if (button == QMessageBox::No) { 3217 } else if (button == QMessageBox::No) {
3179 m_documentModified = false; // so we know to abandon it 3218 m_documentModified = false; // so we know to abandon it
3180 return true; 3219 return true;
3181 } 3220 }
3182 3221
3183 // else cancel 3222 // else cancel
3184 return false; 3223 return false;
3185 } 3224 }
3193 QSettings settings; 3232 QSettings settings;
3194 settings.beginGroup("MainWindow"); 3233 settings.beginGroup("MainWindow");
3195 bool prevNewSession = settings.value("newsessionforrdfaudio", true).toBool(); 3234 bool prevNewSession = settings.value("newsessionforrdfaudio", true).toBool();
3196 settings.endGroup(); 3235 settings.endGroup();
3197 bool newSession = true; 3236 bool newSession = true;
3198 3237
3199 QStringList items; 3238 QStringList items;
3200 items << tr("Close the current session and create a new one") 3239 items << tr("Close the current session and create a new one")
3201 << tr("Add this data to the current session"); 3240 << tr("Add this data to the current session");
3202 3241
3203 bool ok = false; 3242 bool ok = false;
3204 QString item = ListInputDialog::getItem 3243 QString item = ListInputDialog::getItem
3205 (this, tr("Select target for import"), 3244 (this, tr("Select target for import"),
3206 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?"), 3245 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?"),
3207 items, prevNewSession ? 0 : 1, &ok); 3246 items, prevNewSession ? 0 : 1, &ok);
3208 3247
3209 if (!ok || item.isEmpty()) { 3248 if (!ok || item.isEmpty()) {
3210 *cancel = true; 3249 *cancel = true;
3211 return false; 3250 return false;
3212 } 3251 }
3213 3252
3214 newSession = (item == items[0]); 3253 newSession = (item == items[0]);
3215 settings.beginGroup("MainWindow"); 3254 settings.beginGroup("MainWindow");
3216 settings.setValue("newsessionforrdfaudio", newSession); 3255 settings.setValue("newsessionforrdfaudio", newSession);
3217 settings.endGroup(); 3256 settings.endGroup();
3218 3257
3222 3261
3223 void 3262 void
3224 MainWindow::saveSession() 3263 MainWindow::saveSession()
3225 { 3264 {
3226 if (m_sessionFile != "") { 3265 if (m_sessionFile != "") {
3227 if (!saveSessionFile(m_sessionFile)) { 3266 if (!saveSessionFile(m_sessionFile)) {
3228 QMessageBox::critical(this, tr("Failed to save file"), 3267 QMessageBox::critical(this, tr("Failed to save file"),
3229 tr("<b>Save failed</b><p>Session file \"%1\" could not be saved.").arg(m_sessionFile)); 3268 tr("<b>Save failed</b><p>Session file \"%1\" could not be saved.").arg(m_sessionFile));
3230 } else {
3231 CommandHistory::getInstance()->documentSaved();
3232 documentRestored();
3233 }
3234 } else { 3269 } else {
3235 saveSessionAs(); 3270 CommandHistory::getInstance()->documentSaved();
3271 documentRestored();
3272 }
3273 } else {
3274 saveSessionAs();
3236 } 3275 }
3237 } 3276 }
3238 3277
3239 void 3278 void
3240 MainWindow::saveSessionAs() 3279 MainWindow::saveSessionAs()
3246 QString path = getSaveFileName(FileFinder::SessionFile); 3285 QString path = getSaveFileName(FileFinder::SessionFile);
3247 3286
3248 if (path == "") return; 3287 if (path == "") return;
3249 3288
3250 if (!saveSessionFile(path)) { 3289 if (!saveSessionFile(path)) {
3251 QMessageBox::critical(this, tr("Failed to save file"), 3290 QMessageBox::critical(this, tr("Failed to save file"),
3252 tr("<b>Save failed</b><p>Session file \"%1\" could not be saved.").arg(path)); 3291 tr("<b>Save failed</b><p>Session file \"%1\" could not be saved.").arg(path));
3253 } else { 3292 } else {
3254 setWindowTitle(tr("%1: %1") 3293 setWindowTitle(tr("%1: %1")
3255 .arg(QApplication::applicationName()) 3294 .arg(QApplication::applicationName())
3256 .arg(QFileInfo(path).fileName())); 3295 .arg(QFileInfo(path).fileName()));
3257 m_sessionFile = path; 3296 m_sessionFile = path;
3258 CommandHistory::getInstance()->documentSaved(); 3297 CommandHistory::getInstance()->documentSaved();
3259 documentRestored(); 3298 documentRestored();
3260 m_recentFiles.addFile(path); 3299 m_recentFiles.addFile(path);
3261 emit activity(tr("Save session as \"%1\"").arg(path)); 3300 emit activity(tr("Save session as \"%1\"").arg(path));
3262 } 3301 }
3263 } 3302 }
3264 3303
3272 m_panLayer->setBaseColour 3311 m_panLayer->setBaseColour
3273 (ColourDatabase::getInstance()->getColourIndex(tr("Bright Green"))); 3312 (ColourDatabase::getInstance()->getColourIndex(tr("Bright Green")));
3274 } else { 3313 } else {
3275 m_panLayer->setBaseColour 3314 m_panLayer->setBaseColour
3276 (ColourDatabase::getInstance()->getColourIndex(tr("Green"))); 3315 (ColourDatabase::getInstance()->getColourIndex(tr("Green")));
3277 } 3316 }
3278 } 3317 }
3279 } 3318 }
3280 3319
3281 void 3320 void
3282 MainWindow::propertyStacksResized(int width) 3321 MainWindow::propertyStacksResized(int width)
3283 { 3322 {
3284 // SVDEBUG << "MainWindow::propertyStacksResized(" << width << ")" << endl; 3323 // SVDEBUG << "MainWindow::propertyStacksResized(" << width << ")" << endl;
3285 3324
3286 if (!m_playControlsSpacer) return; 3325 if (!m_playControlsSpacer) return;
3287 3326
3288 int spacerWidth = width - m_playControlsWidth - 4; 3327 int spacerWidth = width - m_playControlsWidth - 4;
3289 3328
3290 // SVDEBUG << "resizing spacer from " << m_playControlsSpacer->width() << " to " << spacerWidth << endl; 3329 // SVDEBUG << "resizing spacer from " << m_playControlsSpacer->width() << " to " << spacerWidth << endl;
3291 3330
3292 m_playControlsSpacer->setFixedSize(QSize(spacerWidth, 2)); 3331 m_playControlsSpacer->setFixedSize(QSize(spacerWidth, 2));
3293 } 3332 }
3294 3333
3295 void 3334 void
3296 MainWindow::addPane() 3335 MainWindow::addPane()
3297 { 3336 {
3298 QObject *s = sender(); 3337 QObject *s = sender();
3299 QAction *action = dynamic_cast<QAction *>(s); 3338 QAction *action = dynamic_cast<QAction *>(s);
3300 3339
3301 if (!action) { 3340 if (!action) {
3302 std::cerr << "WARNING: MainWindow::addPane: sender is not an action" 3341 std::cerr << "WARNING: MainWindow::addPane: sender is not an action"
3303 << std::endl; 3342 << std::endl;
3304 return; 3343 return;
3305 } 3344 }
3306 3345
3307 PaneActionMap::iterator i = m_paneActions.find(action); 3346 PaneActionMap::iterator i = m_paneActions.find(action);
3308 3347
3309 if (i == m_paneActions.end()) { 3348 if (i == m_paneActions.end()) {
3310 std::cerr << "WARNING: MainWindow::addPane: unknown action " 3349 std::cerr << "WARNING: MainWindow::addPane: unknown action "
3311 << action->objectName() << std::endl; 3350 << action->objectName() << std::endl;
3312 return; 3351 return;
3313 } 3352 }
3314 3353
3315 addPane(i->second, action->text()); 3354 addPane(i->second, action->text());
3316 } 3355 }
3317 3356
3332 } 3371 }
3333 3372
3334 if (configuration.layer != LayerFactory::TimeRuler && 3373 if (configuration.layer != LayerFactory::TimeRuler &&
3335 configuration.layer != LayerFactory::Spectrum) { 3374 configuration.layer != LayerFactory::Spectrum) {
3336 3375
3337 if (!m_timeRulerLayer) { 3376 if (!m_timeRulerLayer) {
3338 // std::cerr << "no time ruler layer, creating one" << std::endl; 3377 // std::cerr << "no time ruler layer, creating one" << std::endl;
3339 m_timeRulerLayer = m_document->createMainModelLayer 3378 m_timeRulerLayer = m_document->createMainModelLayer
3340 (LayerFactory::TimeRuler); 3379 (LayerFactory::TimeRuler);
3341 } 3380 }
3342 3381
3343 // SVDEBUG << "adding time ruler layer " << m_timeRulerLayer << endl; 3382 // SVDEBUG << "adding time ruler layer " << m_timeRulerLayer << endl;
3344 3383
3345 m_document->addLayerToView(pane, m_timeRulerLayer); 3384 m_document->addLayerToView(pane, m_timeRulerLayer);
3346 } 3385 }
3347 3386
3348 Layer *newLayer = m_document->createLayer(configuration.layer); 3387 Layer *newLayer = m_document->createLayer(configuration.layer);
3349 3388
3350 Model *suggestedModel = configuration.sourceModel; 3389 Model *suggestedModel = configuration.sourceModel;
3392 void 3431 void
3393 MainWindow::addLayer() 3432 MainWindow::addLayer()
3394 { 3433 {
3395 QObject *s = sender(); 3434 QObject *s = sender();
3396 QAction *action = dynamic_cast<QAction *>(s); 3435 QAction *action = dynamic_cast<QAction *>(s);
3397 3436
3398 if (!action) { 3437 if (!action) {
3399 std::cerr << "WARNING: MainWindow::addLayer: sender is not an action" 3438 std::cerr << "WARNING: MainWindow::addLayer: sender is not an action"
3400 << std::endl; 3439 << std::endl;
3401 return; 3440 return;
3402 } 3441 }
3403 3442
3404 Pane *pane = m_paneStack->getCurrentPane(); 3443 Pane *pane = m_paneStack->getCurrentPane();
3405 3444
3406 if (!pane) { 3445 if (!pane) {
3407 std::cerr << "WARNING: MainWindow::addLayer: no current pane" << std::endl; 3446 std::cerr << "WARNING: MainWindow::addLayer: no current pane" << std::endl;
3408 return; 3447 return;
3409 } 3448 }
3410 3449
3411 ExistingLayerActionMap::iterator ei = m_existingLayerActions.find(action); 3450 ExistingLayerActionMap::iterator ei = m_existingLayerActions.find(action);
3412 3451
3413 if (ei != m_existingLayerActions.end()) { 3452 if (ei != m_existingLayerActions.end()) {
3414 Layer *newLayer = ei->second; 3453 Layer *newLayer = ei->second;
3415 m_document->addLayerToView(pane, newLayer); 3454 m_document->addLayerToView(pane, newLayer);
3416 m_paneStack->setCurrentLayer(pane, newLayer); 3455 m_paneStack->setCurrentLayer(pane, newLayer);
3417 return; 3456 return;
3418 } 3457 }
3419 3458
3420 ei = m_sliceActions.find(action); 3459 ei = m_sliceActions.find(action);
3421 3460
3422 if (ei != m_sliceActions.end()) { 3461 if (ei != m_sliceActions.end()) {
3429 dest->setSliceableModel(source->getSliceableModel()); 3468 dest->setSliceableModel(source->getSliceableModel());
3430 connect(source, SIGNAL(sliceableModelReplaced(const Model *, const Model *)), 3469 connect(source, SIGNAL(sliceableModelReplaced(const Model *, const Model *)),
3431 dest, SLOT(sliceableModelReplaced(const Model *, const Model *))); 3470 dest, SLOT(sliceableModelReplaced(const Model *, const Model *)));
3432 connect(m_document, SIGNAL(modelAboutToBeDeleted(Model *)), 3471 connect(m_document, SIGNAL(modelAboutToBeDeleted(Model *)),
3433 dest, SLOT(modelAboutToBeDeleted(Model *))); 3472 dest, SLOT(modelAboutToBeDeleted(Model *)));
3434 } 3473
3435 m_document->addLayerToView(pane, newLayer); 3474 }
3436 m_paneStack->setCurrentLayer(pane, newLayer); 3475 m_document->addLayerToView(pane, newLayer);
3437 return; 3476 m_paneStack->setCurrentLayer(pane, newLayer);
3477 return;
3438 } 3478 }
3439 3479
3440 TransformActionMap::iterator i = m_transformActions.find(action); 3480 TransformActionMap::iterator i = m_transformActions.find(action);
3441 3481
3442 if (i == m_transformActions.end()) { 3482 if (i == m_transformActions.end()) {
3443 3483
3444 LayerActionMap::iterator i = m_layerActions.find(action); 3484 LayerActionMap::iterator i = m_layerActions.find(action);
3445 3485
3446 if (i == m_layerActions.end()) { 3486 if (i == m_layerActions.end()) {
3447 std::cerr << "WARNING: MainWindow::addLayer: unknown action " 3487 std::cerr << "WARNING: MainWindow::addLayer: unknown action "
3448 << action->objectName() << std::endl; 3488 << action->objectName() << std::endl;
3449 return; 3489 return;
3450 } 3490 }
3451 3491
3452 LayerFactory::LayerType type = i->second.layer; 3492 LayerFactory::LayerType type = i->second.layer;
3453 3493
3454 LayerFactory::LayerTypeSet emptyTypes = 3494 LayerFactory::LayerTypeSet emptyTypes =
3455 LayerFactory::getInstance()->getValidEmptyLayerTypes(); 3495 LayerFactory::getInstance()->getValidEmptyLayerTypes();
3456 3496
3457 Layer *newLayer = 0; 3497 Layer *newLayer = 0;
3458 3498
3459 if (emptyTypes.find(type) != emptyTypes.end()) { 3499 if (emptyTypes.find(type) != emptyTypes.end()) {
3460 3500
3461 newLayer = m_document->createEmptyLayer(type); 3501 newLayer = m_document->createEmptyLayer(type);
3462 if (newLayer) { 3502 if (newLayer) {
3463 m_toolActions[ViewManager::DrawMode]->trigger(); 3503 m_toolActions[ViewManager::DrawMode]->trigger();
3464 } 3504 }
3465 3505
3466 } else { 3506 } else {
3467 3507
3468 Model *model = i->second.sourceModel; 3508 Model *model = i->second.sourceModel;
3469 3509
3470 cerr << "model = "<< model << endl; 3510 cerr << "model = "<< model << endl;
3471 3511
3506 if (newLayer) { 3546 if (newLayer) {
3507 m_document->addLayerToView(pane, newLayer); 3547 m_document->addLayerToView(pane, newLayer);
3508 m_paneStack->setCurrentLayer(pane, newLayer); 3548 m_paneStack->setCurrentLayer(pane, newLayer);
3509 } 3549 }
3510 3550
3511 return; 3551 return;
3512 } 3552 }
3513 3553
3514 //!!! want to do something like this, but it's not supported in 3554 //!!! want to do something like this, but it's not supported in
3515 //ModelTransformerFactory yet 3555 //ModelTransformerFactory yet
3516 /* 3556 /*
3517 int channel = -1; 3557 int channel = -1;
3518 // pick up the default channel from any existing layers on the same pane 3558 // pick up the default channel from any existing layers on the same pane
3519 for (int j = 0; j < pane->getLayerCount(); ++j) { 3559 for (int j = 0; j < pane->getLayerCount(); ++j) {
3520 int c = LayerFactory::getInstance()->getChannel(pane->getLayer(j)); 3560 int c = LayerFactory::getInstance()->getChannel(pane->getLayer(j));
3521 if (c != -1) { 3561 if (c != -1) {
3522 channel = c; 3562 channel = c;
3523 break; 3563 break;
3524 } 3564 }
3525 } 3565 }
3526 */ 3566 */
3527 3567
3528 // We always ask for configuration, even if the plugin isn't 3568 // We always ask for configuration, even if the plugin isn't
3529 // supposed to be configurable, because we need to let the user 3569 // supposed to be configurable, because we need to let the user
3533 3573
3534 addLayer(transformId); 3574 addLayer(transformId);
3535 } 3575 }
3536 3576
3537 void 3577 void
3538 MainWindow::addLayer(QString transformId) 3578 MainWindow:: addLayer(QString transformId)
3539 { 3579 {
3540 Pane *pane = m_paneStack->getCurrentPane(); 3580 Pane *pane = m_paneStack->getCurrentPane();
3541 if (!pane) { 3581 if (!pane) {
3542 std::cerr << "WARNING: MainWindow::addLayer: no current pane" << std::endl; 3582 std::cerr << "WARNING: MainWindow::addLayer: no current pane" << std::endl;
3543 return; 3583 return;
3544 } 3584 }
3545 3585
3546 Transform transform = TransformFactory::getInstance()-> 3586 Transform transform = TransformFactory::getInstance()->
3547 getDefaultTransformFor(transformId); 3587 getDefaultTransformFor(transformId);
3548 3588
3564 break; 3604 break;
3565 } 3605 }
3566 } 3606 }
3567 if (defaultInputModel) break; 3607 if (defaultInputModel) break;
3568 } 3608 }
3569 3609
3570 size_t startFrame = 0, duration = 0; 3610 size_t startFrame = 0, duration = 0;
3571 size_t endFrame = 0; 3611 size_t endFrame = 0;
3572 m_viewManager->getSelection().getExtents(startFrame, endFrame); 3612 m_viewManager->getSelection().getExtents(startFrame, endFrame);
3573 if (endFrame > startFrame) duration = endFrame - startFrame; 3613 if (endFrame > startFrame) duration = endFrame - startFrame;
3574 else startFrame = 0; 3614 else startFrame = 0;
3604 void 3644 void
3605 MainWindow::renameCurrentLayer() 3645 MainWindow::renameCurrentLayer()
3606 { 3646 {
3607 Pane *pane = m_paneStack->getCurrentPane(); 3647 Pane *pane = m_paneStack->getCurrentPane();
3608 if (pane) { 3648 if (pane) {
3609 Layer *layer = pane->getSelectedLayer(); 3649 Layer *layer = pane->getSelectedLayer();
3610 if (layer) { 3650 if (layer) {
3611 bool ok = false; 3651 bool ok = false;
3612 QString newName = QInputDialog::getText 3652 QString newName = QInputDialog::getText
3613 (this, tr("Rename Layer"), 3653 (this, tr("Rename Layer"),
3614 tr("New name for this layer:"), 3654 tr("New name for this layer:"),
3615 QLineEdit::Normal, layer->objectName(), &ok); 3655 QLineEdit::Normal, layer->objectName(), &ok);
3616 if (ok) { 3656 if (ok) {
3617 layer->setPresentationName(newName); 3657 layer->setPresentationName(newName);
3618 setupExistingLayersMenus(); 3658 setupExistingLayersMenus();
3619 } 3659 }
3620 } 3660 }
3621 } 3661 }
3622 } 3662 }
3623 3663
3624 void 3664 void
3625 MainWindow::findTransform() 3665 MainWindow::findTransform()
3629 delete finder; 3669 delete finder;
3630 return; 3670 return;
3631 } 3671 }
3632 TransformId transform = finder->getTransform(); 3672 TransformId transform = finder->getTransform();
3633 delete finder; 3673 delete finder;
3634 3674
3635 if (getMainModel() != 0 && m_paneStack->getCurrentPane() != 0) { 3675 if (getMainModel() != 0 && m_paneStack->getCurrentPane() != 0) {
3636 addLayer(transform); 3676 addLayer(transform);
3637 } 3677 }
3638 } 3678 }
3639 3679
3646 3686
3647 void 3687 void
3648 MainWindow::alignToggled() 3688 MainWindow::alignToggled()
3649 { 3689 {
3650 QAction *action = dynamic_cast<QAction *>(sender()); 3690 QAction *action = dynamic_cast<QAction *>(sender());
3651 3691
3652 if (!m_viewManager) return; 3692 if (!m_viewManager) return;
3653 3693
3654 if (action) { 3694 if (action) {
3655 m_viewManager->setAlignMode(action->isChecked()); 3695 m_viewManager->setAlignMode(action->isChecked());
3656 } else { 3696 } else {
3657 m_viewManager->setAlignMode(!m_viewManager->getAlignMode()); 3697 m_viewManager->setAlignMode(!m_viewManager->getAlignMode());
3658 } 3698 }
3659 3699
3660 if (m_viewManager->getAlignMode()) { 3700 if (m_viewManager->getAlignMode()) {
3661 m_prevSolo = m_soloAction->isChecked(); 3701 m_prevSolo = m_soloAction->isChecked();
3662 if (!m_soloAction->isChecked()) { 3702 if (!m_soloAction->isChecked()) {
3678 m_document->setAutoAlignment(false); 3718 m_document->setAutoAlignment(false);
3679 } 3719 }
3680 3720
3681 for (int i = 0; i < m_paneStack->getPaneCount(); ++i) { 3721 for (int i = 0; i < m_paneStack->getPaneCount(); ++i) {
3682 3722
3683 Pane *pane = m_paneStack->getPane(i); 3723 Pane *pane = m_paneStack->getPane(i);
3684 if (!pane) continue; 3724 if (!pane) continue;
3685 3725
3686 pane->update(); 3726 pane->update();
3687 } 3727 }
3688 } 3728 }
3689 3729
3747 for (int i = pane->getLayerCount(); i > 0; ) { 3787 for (int i = pane->getLayerCount(); i > 0; ) {
3748 --i; 3788 --i;
3749 Layer *layer = pane->getLayer(i); 3789 Layer *layer = pane->getLayer(i);
3750 if (LayerFactory::getInstance()->getLayerType(layer) == 3790 if (LayerFactory::getInstance()->getLayerType(layer) ==
3751 LayerFactory::Waveform) { 3791 LayerFactory::Waveform) {
3752 RangeSummarisableTimeValueModel *tvm = 3792 RangeSummarisableTimeValueModel *tvm =
3753 dynamic_cast<RangeSummarisableTimeValueModel *>(layer->getModel()); 3793 dynamic_cast<RangeSummarisableTimeValueModel *>(layer->getModel());
3754 if (tvm) { 3794 if (tvm) {
3755 m_panLayer->setModel(tvm); 3795 m_panLayer->setModel(tvm);
3756 return; 3796 return;
3757 } 3797 }
3852 emit hideSplash(); 3892 emit hideSplash();
3853 QMessageBox::information 3893 QMessageBox::information
3854 (this, tr("Sample rate mismatch"), 3894 (this, tr("Sample rate mismatch"),
3855 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.") 3895 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.")
3856 .arg(requested).arg(actual)); 3896 .arg(requested).arg(actual));
3857 } 3897 }
3858 3898
3859 updateDescriptionLabel(); 3899 updateDescriptionLabel();
3860 } 3900 }
3861 3901
3862 void 3902 void
3952 } 3992 }
3953 3993
3954 if (!noteOn) continue; 3994 if (!noteOn) continue;
3955 insertInstantAt(ev.getTime()); 3995 insertInstantAt(ev.getTime());
3956 } 3996 }
3957 } 3997 }
3958 3998
3959 void 3999 void
3960 MainWindow::playStatusChanged(bool playing) 4000 MainWindow::playStatusChanged(bool playing)
3961 { 4001 {
3962 Pane *currentPane = 0; 4002 Pane *currentPane = 0;
4013 { 4053 {
4014 QAction *a = dynamic_cast<QAction *>(sender()); 4054 QAction *a = dynamic_cast<QAction *>(sender());
4015 if (!a) return; 4055 if (!a) return;
4016 4056
4017 int type = m_numberingActions[a]; 4057 int type = m_numberingActions[a];
4018 4058
4019 if (m_labeller) m_labeller->setType(Labeller::ValueType(type)); 4059 if (m_labeller) m_labeller->setType(Labeller::ValueType(type));
4020 4060
4021 QSettings settings; 4061 QSettings settings;
4022 settings.beginGroup("MainWindow"); 4062 settings.beginGroup("MainWindow");
4023 settings.setValue("labellertype", type); 4063 settings.setValue("labellertype", type);
4027 void 4067 void
4028 MainWindow::setInstantsCounterCycle() 4068 MainWindow::setInstantsCounterCycle()
4029 { 4069 {
4030 QAction *a = dynamic_cast<QAction *>(sender()); 4070 QAction *a = dynamic_cast<QAction *>(sender());
4031 if (!a) return; 4071 if (!a) return;
4032 4072
4033 int cycle = a->text().toInt(); 4073 int cycle = a->text().toInt();
4034 if (cycle == 0) return; 4074 if (cycle == 0) return;
4035 4075
4036 if (m_labeller) m_labeller->setCounterCycleSize(cycle); 4076 if (m_labeller) m_labeller->setCounterCycleSize(cycle);
4037 4077
4038 QSettings settings; 4078 QSettings settings;
4039 settings.beginGroup("MainWindow"); 4079 settings.beginGroup("MainWindow");
4040 settings.setValue("labellercycle", cycle); 4080 settings.setValue("labellercycle", cycle);
4041 settings.endGroup(); 4081 settings.endGroup();
4042 } 4082 }
4343 4383
4344 #ifndef BUILD_STATIC 4384 #ifndef BUILD_STATIC
4345 aboutText.replace(tr("With "), tr("Using ")); 4385 aboutText.replace(tr("With "), tr("Using "));
4346 #endif 4386 #endif
4347 4387
4348 aboutText += 4388 aboutText +=
4349 "<p><small>Sonic Visualiser Copyright &copy; 2005&ndash;2013 Chris Cannam and " 4389 "<p><small>Sonic Visualiser Copyright &copy; 2005&ndash;2013 Chris Cannam and "
4350 "Queen Mary, University of London.</small></p>" 4390 "Queen Mary, University of London.</small></p>"
4351 "<p><small>This program is free software; you can redistribute it and/or " 4391 "<p><small>This program is free software; you can redistribute it and/or "
4352 "modify it under the terms of the GNU General Public License as " 4392 "modify it under the terms of the GNU General Public License as "
4353 "published by the Free Software Foundation; either version 2 of the " 4393 "published by the Free Software Foundation; either version 2 of the "
4354 "License, or (at your option) any later version.<br>See the file " 4394 "License, or (at your option) any later version.<br>See the file "
4355 "COPYING included with this distribution for more information.</small></p>"; 4395 "COPYING included with this distribution for more information.</small></p>";
4356 4396
4357 QMessageBox::about(this, tr("About Sonic Visualiser"), aboutText); 4397 QMessageBox::about(this, tr("About Sonic Visualiser"), aboutText);
4358 } 4398 }
4359 4399
4360 void 4400 void
4361 MainWindow::keyReference() 4401 MainWindow::keyReference()
4377 } 4417 }
4378 settings.endGroup(); 4418 settings.endGroup();
4379 } 4419 }
4380 4420
4381 4421
4422
4423 CheckBox::CheckBox(QWidget *parent)
4424 : QWidget(parent)
4425 {
4426 // SELECTION RULES
4427 QGroupBox *selrule_box = new QGroupBox(QString::fromUtf8("SELECTION RULES"),this);
4428 selrule_box->setFont(QFont("Times", 9, QFont::Bold));
4429 selrule_box->move(5,5);
4430 selrule_box->resize(235,130);
4431 QButtonGroup *selrule_group = new QButtonGroup(this);
4432 selrule_group->setObjectName("Selection Rule");
4433
4434 QRadioButton *minmax_rule = new QRadioButton(QString::fromUtf8("Min/Max Rule"),this);
4435 minmax_rule->move(20,25);
4436 minmax_rule->setObjectName("0");
4437 QRadioButton *exclusion_rule = new QRadioButton(QString::fromUtf8("Exclusion Rule"),this);
4438 exclusion_rule->move(20,45);
4439 exclusion_rule->setObjectName("1");
4440 QRadioButton *notmute_rule = new QRadioButton(QString::fromUtf8("Not Mute Rule"),this);
4441 notmute_rule->move(130,25);
4442 notmute_rule->setObjectName("2");
4443 QRadioButton *implication_rule = new QRadioButton(QString::fromUtf8("Implication Rule"),this);
4444 implication_rule->move(130,45);
4445 implication_rule->setObjectName("3");
4446
4447 selrule_group->addButton(minmax_rule);
4448 selrule_group->addButton(exclusion_rule);
4449 selrule_group->addButton(notmute_rule);
4450 selrule_group->addButton(implication_rule);
4451
4452 QSpinBox *sel_par1 = new QSpinBox(this);
4453 sel_par1->setEnabled(true);
4454 sel_par1->setGeometry(QRect(20, 75, 40, 20));
4455 sel_par1->setMinimum(1);
4456 sel_par1->setMaximum(numtracks);
4457 selrule_par1 = sel_par1->value();
4458
4459 sel_rule1 = new QLabel(this);
4460 sel_rule1->setText("Parameter 1");
4461 sel_rule1->setGeometry(70, 75, 100, 20);
4462
4463 QSpinBox *sel_par2 = new QSpinBox(this);
4464 sel_par2->setEnabled(true);
4465 sel_par2->setGeometry(QRect(20, 100, 40, 20));
4466 sel_par2->setMinimum(1);
4467 sel_par2->setMaximum(numtracks);
4468 selrule_par2 = sel_par2->value();
4469
4470 sel_rule2 = new QLabel(this);
4471 sel_rule2->setText("Parameter 2");
4472 sel_rule2->setGeometry(70, 100, 100, 20);
4473
4474 connect(selrule_group, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(set_selruleType(QAbstractButton*)));
4475 connect(sel_par1, SIGNAL(valueChanged(int)), this, SLOT(set_selrulePAR1(int)));
4476 connect(sel_par2, SIGNAL(valueChanged(int)), this, SLOT(set_selrulePAR2(int)));
4477
4478 // MIXING RULES (yet to implement)
4479 QGroupBox *mixrule_box = new QGroupBox(QString::fromUtf8("MIXING RULES"),this);
4480 mixrule_box->setFont(QFont("Times", 9, QFont::Bold));
4481 mixrule_box->move(255,5);
4482 mixrule_box->resize(330,130);
4483 QButtonGroup *mixrule_group = new QButtonGroup(this);
4484 mixrule_group->setObjectName("Mixing Rule");
4485
4486 QRadioButton *equivalence_rule = new QRadioButton(QString::fromUtf8("Equivalence Rule"),this);
4487 equivalence_rule->move(270,25);
4488 equivalence_rule->setObjectName("0");
4489 QRadioButton *upper_rule = new QRadioButton(QString::fromUtf8("Upper Rule"),this);
4490 upper_rule->move(270,45);
4491 upper_rule->setObjectName("1");
4492 QRadioButton *lower_rule = new QRadioButton(QString::fromUtf8("Lower Rule"),this);
4493 lower_rule->move(380,25);
4494 lower_rule->setObjectName("2");
4495 QRadioButton *limit_rule = new QRadioButton(QString::fromUtf8("Limit Rule"),this);
4496 limit_rule->move(380,45);
4497 limit_rule->setObjectName("3");
4498
4499 mixrule_group->addButton(equivalence_rule);
4500 mixrule_group->addButton(upper_rule);
4501 mixrule_group->addButton(lower_rule);
4502 mixrule_group->addButton(limit_rule);
4503
4504 QSpinBox *mix_par1 = new QSpinBox(this);
4505 mix_par1->setEnabled(true);
4506 mix_par1->setGeometry(QRect(270, 75, 40, 20));
4507 mix_par1->setMinimum(1);
4508 mix_par1->setMaximum(numtracks);
4509 mixrule_par1 = mix_par1->value();
4510
4511 mix_rule1 = new QLabel(this);
4512 mix_rule1->setText("Parameter 1");
4513 mix_rule1->setGeometry(320, 75, 100, 20);
4514
4515 QSpinBox *mix_par2 = new QSpinBox(this);
4516 mix_par2->setEnabled(true);
4517 mix_par2->setGeometry(QRect(270, 100, 40, 20));
4518 mix_par2->setMinimum(1);
4519 mix_par2->setMaximum(numtracks);
4520 mixrule_par2 = mix_par2->value();
4521
4522 mix_rule2 = new QLabel(this);
4523 mix_rule2->setText("Parameter 2");
4524 mix_rule2->setGeometry(320, 100, 100, 20);
4525
4526 QSpinBox *mix_par3 = new QSpinBox(this);
4527 mix_par3->setEnabled(true);
4528 mix_par3->setGeometry(QRect(410, 75, 40, 20));
4529 mix_par3->setMinimum(0);
4530 mix_par3->setMaximum(100);
4531 mixrule_par3 = mix_par3->value();
4532
4533 mix_rule3 = new QLabel(this);
4534 mix_rule3->setText("Parameter 3");
4535 mix_rule3->setGeometry(460, 75, 100, 20);
4536
4537 QSpinBox *mix_par4 = new QSpinBox(this);
4538 mix_par4->setEnabled(true);
4539 mix_par4->setGeometry(QRect(410, 100, 40, 20));
4540 mix_par4->setMinimum(0);
4541 mix_par4->setMaximum(100);
4542 mixrule_par4 = mix_par4->value();
4543
4544 mix_rule4 = new QLabel(this);
4545 mix_rule4->setText("Parameter 4");
4546 mix_rule4->setGeometry(460, 100, 100, 20);
4547
4548 connect(mixrule_group, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(set_mixruleType(QAbstractButton*)));
4549 connect(mix_par1, SIGNAL(valueChanged(int)), this, SLOT(set_mixrulePAR1(int)));
4550 connect(mix_par2, SIGNAL(valueChanged(int)), this, SLOT(set_mixrulePAR2(int)));
4551 connect(mix_par3, SIGNAL(valueChanged(int)), this, SLOT(set_mixrulePAR3(int)));
4552 connect(mix_par4, SIGNAL(valueChanged(int)), this, SLOT(set_mixrulePAR4(int)));
4553 // connect(equivalence_rule, SIGNAL(toggled(bool)), mix_rule1, SLOT()
4554
4555 // GROUPS
4556 QGroupBox *group_box = new QGroupBox(QString::fromUtf8("GROUPS"),this);
4557 group_box->setFont(QFont("Times", 9, QFont::Bold));
4558 group_box->move(5,150);
4559 group_box->resize(580,100);
4560
4561 group_label = new QLabel(this);
4562 group_label->setText("Select tracks for the group:");
4563 group_label->setGeometry(20, 165, 200, 20);
4564
4565 QButtonGroup *group_cb = new QButtonGroup(this);
4566 group_cb->setObjectName("Group");
4567
4568 for (int i=1; i<=numtracks; i++) {
4569 QCheckBox *track_cb = new QCheckBox(QString::number(i), this);
4570 track_cb->setGeometry(80*i,185,95,30);
4571 track_cb->setObjectName(QString::number(i));
4572 group_cb->setExclusive(false);
4573 group_cb->addButton(track_cb);
4574 }
4575
4576 QSpinBox *group_vol = new QSpinBox(this);
4577 group_vol->setEnabled(true);
4578 group_vol->setGeometry(QRect(280, 220, 40, 20));
4579 group_vol->setMinimum(0);
4580 group_vol->setMaximum(100);
4581 group_vol->setValue(100);
4582 group_volume = group_vol->value();
4583
4584 grp_vol = new QLabel(this);
4585 grp_vol->setText("Group Volume");
4586 grp_vol->setGeometry(330, 220, 100, 20);
4587
4588 group_name_line = new QLineEdit(this);
4589 group_name_line->setGeometry(25,220,150,20);
4590 group_name_line->setText("Insert a name");
4591 group_name_line->setMaxLength(20);
4592
4593 grp_name = new QLabel(this);
4594 grp_name->setText("Group Name");
4595 grp_name->setGeometry(180,220,100,20);
4596
4597 connect(group_cb, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(set_TrackInGroup(QAbstractButton*)));
4598 connect(group_name_line, SIGNAL(textChanged(QString)), this, SLOT(set_GroupName(QString)));
4599 connect(group_vol, SIGNAL(valueChanged(int)), this, SLOT(set_GroupVolume(int)));
4600
4601 // PRESETS
4602 QGroupBox *preset_box = new QGroupBox(QString::fromUtf8("PRESETS"),this);
4603 preset_box->setFont(QFont("Times", 9, QFont::Bold));
4604 preset_box->move(5,270);
4605 preset_box->resize(580,90);
4606
4607 QButtonGroup *preset_group = new QButtonGroup(this);
4608 preset_group->setObjectName("Presets");
4609
4610 QRadioButton *static_preset = new QRadioButton(QString::fromUtf8("Static Volume"),this);
4611 static_preset->move(20,290);
4612 static_preset->setObjectName("0");
4613
4614 QRadioButton *dynamic_preset = new QRadioButton(QString::fromUtf8("Dynamic Volume"),this);
4615 dynamic_preset->move(150,290);
4616 dynamic_preset->setObjectName("4");
4617
4618 preset_group->addButton(static_preset);
4619 preset_group->addButton(dynamic_preset);
4620
4621 QButtonGroup *fade_group = new QButtonGroup(this);
4622 fade_group->setObjectName("Fade IN/OUT");
4623
4624 QRadioButton *fade_in = new QRadioButton(QString::fromUtf8("Fade IN"),this);
4625 fade_in->move(170,310);
4626 fade_in->setObjectName("1");
4627 fade_in->setDisabled(true);
4628
4629 QRadioButton *fade_out = new QRadioButton(QString::fromUtf8("Fade OUT"),this);
4630 fade_out->move(170,330);
4631 fade_out->setObjectName("0");
4632 fade_out->setDisabled(true);
4633
4634 fade_group->addButton(fade_in);
4635 fade_group->addButton(fade_out);
4636
4637 connect(preset_group, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(set_presetType(QAbstractButton*)));
4638 connect(dynamic_preset, SIGNAL(toggled(bool)), fade_in, SLOT(setEnabled(bool)));
4639 connect(dynamic_preset, SIGNAL(toggled(bool)), fade_out, SLOT(setEnabled(bool)));
4640 connect(fade_group, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(set_fade(QAbstractButton*)));
4641
4642
4643 // IMAGE AND LYRICS
4644 QCheckBox *text_cb = new QCheckBox("Include lyrics", this);
4645 text_cb->setGeometry(20, 380, 95, 30);
4646 QCheckBox *jpeg_cb = new QCheckBox("Include picture", this);
4647 jpeg_cb->setGeometry(20, 430, 95, 30);
4648
4649 line->setGeometry(120, 380, 320, 30);
4650 line2->setGeometry(120, 430, 320, 30);
4651
4652 QPushButton *create = new QPushButton("Export", this);
4653 create->setGeometry(20, 500, 95, 30);
4654
4655 QPushButton *TextFilePath = new QPushButton("Select text file", this);
4656 TextFilePath->setGeometry(460, 380, 95, 30);
4657 TextFilePath->setDisabled(true);
4658
4659 QPushButton *JpegFilePath = new QPushButton("Select JPEG file", this);
4660 JpegFilePath->setGeometry(460, 430, 95, 30);
4661 JpegFilePath->setDisabled(true);
4662
4663 // Enable/disable push buttons
4664 connect(text_cb, SIGNAL(toggled(bool)), TextFilePath, SLOT(setEnabled(bool)));
4665 connect(jpeg_cb, SIGNAL(toggled(bool)), JpegFilePath, SLOT(setEnabled(bool)));
4666 // Check the inclusion of image and text
4667 connect(text_cb, SIGNAL(stateChanged(int)), this, SLOT(insertLyrics(int))); // yet to implement
4668 connect(jpeg_cb, SIGNAL(stateChanged(int)), this, SLOT(insertImage(int)));
4669 // Set image and text paths
4670 connect(TextFilePath, SIGNAL(clicked()), this , SLOT(defineImafTextFile()));
4671 connect(JpegFilePath, SIGNAL(clicked()), this , SLOT(defineImafImageFile()));
4672 // Create the file
4673 connect(create, SIGNAL(clicked()), this , SLOT(saveImafFile()));
4674 connect(create, SIGNAL(clicked()), this, SLOT(close()));
4675 }
4676
4677 void CheckBox::insertImage(int state)
4678 {
4679 if (state) {
4680 has_image = true;
4681 } else{
4682 has_image = false;
4683 }
4684 }
4685
4686 void CheckBox::insertLyrics(int state)
4687 {
4688 if (state) {
4689 has_lyrics = true;
4690 } else{
4691 has_lyrics = false;
4692 }
4693 }
4694
4695 void CheckBox::saveImafFile()
4696 {
4697 ImafFileName = QFileDialog::getSaveFileName(this, tr("Save IMAF"), "/", tr("IMAF (*.ima)"));
4698
4699 group_descr = "Thisgroup";
4700
4701 if( ImafFileName != "" ){ //if the user press cancel the function mainIMAFencoder won´t be called
4702 mainIMAFencoder(numtracks, files_paths, ImafFileName, ImageFileName, TextFileName,
4703 ImafVolumeValues, has_image, selrule_type, selrule_par1, selrule_par2,
4704 mixrule_type, mixrule_par1, mixrule_par2, mixrule_par3, mixrule_par4,
4705 group_tracks, group_volume, group_name, group_descr, preset_type, fade_in);
4706 }
4707 }
4708
4709 void CheckBox::defineImafImageFile()
4710 {
4711 ImageFileName = QFileDialog::getOpenFileName(this, tr("Select JPEG"), "/", tr("JPEG (*.jpg)"));
4712 line2->setText(ImageFileName);
4713 }
4714
4715 void CheckBox::defineImafTextFile()
4716 {
4717 TextFileName = QFileDialog::getOpenFileName(this, tr("Select text file"), "/", tr("Text File (*.3gp)"));
4718 line->setText(TextFileName);
4719 }
4720
4721 void
4722 MainWindow::exportIMAF()
4723 {
4724 numtracks = m_paneStack->getPaneCount();
4725
4726 for (int i = 0; i < numtracks; ++i) {
4727 //ImafVolumeValues[i] = int(m_paneStack->getPane(i)->getLayer(0)->getPlayParameters()->getVolImaf())/2;
4728 }
4729
4730 CheckBox *imaf_window = new CheckBox();
4731
4732 imaf_window->resize(600,540);
4733 imaf_window->move(100,100);
4734 imaf_window->setWindowTitle("Export IMAF");
4735 imaf_window->show();
4736 }
4737
4738
4739
4740 void MainWindow::insertLyrics(size_t frame, QString text){
4741 Pane *pane = m_paneStack->getCurrentPane();
4742
4743
4744 pane = m_paneStack->getCurrentPane();
4745 if (!pane) {
4746 return;
4747 }
4748
4749 frame = pane->alignFromReference(frame);
4750
4751 Layer *layer = dynamic_cast<TimeInstantLayer *>
4752 (pane->getSelectedLayer());
4753
4754 if (!layer) {
4755 for (int i = pane->getLayerCount(); i > 0; --i) {
4756 layer = dynamic_cast<TimeInstantLayer *>(pane->getLayer(i - 1));
4757 if (layer) break;
4758 }
4759
4760 if (!layer) {
4761 CommandHistory::getInstance()->startCompoundOperation
4762 (tr("Add Point"), true);
4763 layer = m_document->createEmptyLayer(LayerFactory::TimeInstants);
4764 if (layer) {
4765 m_document->addLayerToView(pane, layer);
4766 m_paneStack->setCurrentLayer(pane, layer);
4767 }
4768 CommandHistory::getInstance()->endCompoundOperation();
4769 }
4770 }
4771
4772 if (layer) {
4773
4774 Model *model = layer->getModel();
4775 SparseOneDimensionalModel *sodm = dynamic_cast<SparseOneDimensionalModel *>
4776 (model);
4777
4778 if (sodm) {
4779 SparseOneDimensionalModel::Point point(frame, "");
4780
4781 SparseOneDimensionalModel::Point prevPoint(0);
4782 bool havePrevPoint = false;
4783
4784 SparseOneDimensionalModel::EditCommand *command =
4785 new SparseOneDimensionalModel::EditCommand(sodm, tr("Add Point"));
4786
4787 if (m_labeller->requiresPrevPoint()) {
4788
4789 SparseOneDimensionalModel::PointList prevPoints =
4790 sodm->getPreviousPoints(frame);
4791
4792 if (!prevPoints.empty()) {
4793 prevPoint = *prevPoints.begin();
4794 havePrevPoint = true;
4795 }
4796 }
4797
4798 if (m_labeller) {
4799
4800 m_labeller->setSampleRate(sodm->getSampleRate());
4801
4802 if (m_labeller->actingOnPrevPoint()) {
4803 command->deletePoint(prevPoint);
4804 }
4805
4806 m_labeller->label<SparseOneDimensionalModel::Point>
4807 (point, havePrevPoint ? &prevPoint : 0);
4808
4809 if (m_labeller->actingOnPrevPoint()) {
4810 command->addPoint(prevPoint);
4811 }
4812 }
4813 point.label=text;
4814 command->addPoint(point);
4815
4816 command->setName(tr("Add Point at %1 s")
4817 .arg(RealTime::frame2RealTime
4818 (frame,
4819 sodm->getSampleRate())
4820 .toText(false).c_str()));
4821
4822 Command *c = command->finish();
4823 if (c) CommandHistory::getInstance()->addCommand(c, false);
4824 }
4825 }
4826
4827 }
4828
4829 void MainWindow::importIMAF()
4830 {
4831
4832 QString filename;
4833 int haslyrics; // if this variable != 2 -> there are lyrics
4834 filename = QFileDialog::getOpenFileName(this,
4835 tr("Import IMAF"), "/", tr("IMAF (*.ima)"));
4836
4837 haslyrics = mainIMAFdecoder(filename);
4838
4839 openMP3IMAF();
4840
4841 if (haslyrics!=2){
4842 addPaneToStack();//it creates a new pane to show the lyrics
4843
4844 Pane *pane = m_paneStack->getCurrentPane();
4845 LayerFactory::LayerType type ; //set the type of layer
4846 type = LayerFactory::TimeInstants;
4847 //create a new layer
4848 Layer *newLayer = 0;
4849 newLayer = m_document->createEmptyLayer(type);
4850 m_toolActions[ViewManager::DrawMode]->trigger();
4851 m_document->addLayerToView(pane, newLayer);
4852
4853 //create a new layer
4854 Layer *newLayer1 = 0;
4855 newLayer1 = m_document->createEmptyLayer(type);
4856 m_toolActions[ViewManager::DrawMode]->trigger();
4857 m_document->addLayerToView(pane, newLayer1);
4858 m_paneStack->setCurrentLayer(pane, newLayer);
4859
4860 //editCurrentLayer();
4861
4862 //text decoder
4863 unsigned char dat,dat1,dat2,dat3;
4864 QTextStream out(stdout);
4865 FILE *imf;
4866 imf = fopen (filename.toStdString().c_str(),"rb");
4867
4868 fseek (imf,0,SEEK_SET);
4869 fseek (imf,24,SEEK_CUR); //jump to 'mdat'
4870 fread(&dat, sizeof(unsigned char), 1, imf);
4871 fread(&dat1, sizeof(unsigned char), 1, imf);
4872 fread(&dat2, sizeof(unsigned char), 1, imf);
4873 fread(&dat3, sizeof(unsigned char), 1, imf);
4874 int sizemdat = (dat<<24) | (dat1<<16) | (dat2<<8) | (dat3);
4875 fseek(imf, sizemdat-4, SEEK_CUR); // -4 because we have to sub the 4 bytes of size
4876
4877 fseek (imf,16,SEEK_CUR);
4878 fseek (imf,96,SEEK_CUR); // next track id is placed 96 bytes after the last byte of type 'mvhd'
4879
4880 fread(&dat, sizeof(unsigned char), 1, imf);
4881 fread(&dat1, sizeof(unsigned char), 1, imf);
4882 fread(&dat2, sizeof(unsigned char), 1, imf);
4883 fread(&dat3, sizeof(unsigned char), 1, imf);
4884
4885
4886 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
4887
4888 fread(&dat, sizeof(unsigned char), 1, imf);//read the size of trak.Every track must be the same size
4889 fread(&dat1, sizeof(unsigned char), 1, imf);
4890 fread(&dat2, sizeof(unsigned char), 1, imf);
4891 fread(&dat3, sizeof(unsigned char), 1, imf);
4892
4893 int sizetrak = ((dat<<24) | (dat1<<16) | (dat2<<8) | (dat3));
4894
4895 fseek(imf, (sizetrak-4)*audiotracks, SEEK_CUR);
4896
4897 int d=0;
4898 while (d==0){
4899
4900 fread(&dat, sizeof(unsigned char), 1, imf);
4901 fread(&dat1, sizeof(unsigned char), 1, imf);
4902 fread(&dat2, sizeof(unsigned char), 1, imf);
4903 fread(&dat3, sizeof(unsigned char), 1, imf);
4904
4905
4906 if (dat == 0x73 && dat1 == 0x74 && dat2 == 0x74 && dat3 == 0x73) { // 73 74 74 73 = s t t s
4907 d=1;
4908 }
4909
4910 else{
4911 fseek(imf, -3, SEEK_CUR); //if we have not readen ´stts´
4912 }
4913
4914 } //close while
4915
4916 fread(&dat, sizeof(unsigned char), 1, imf);//avanzamos 4 bytes (son los 4 bytes de version)
4917 fread(&dat, sizeof(unsigned char), 1, imf);
4918 fread(&dat, sizeof(unsigned char), 1, imf);
4919 fread(&dat, sizeof(unsigned char), 1, imf);
4920
4921 fread(&dat, sizeof(unsigned char), 1, imf);//estos 4 bytes son los de número de entradas de la tabla (entry_count)
4922 fread(&dat1, sizeof(unsigned char), 1, imf);
4923 fread(&dat2, sizeof(unsigned char), 1, imf);
4924 fread(&dat3, sizeof(unsigned char), 1, imf);
4925
4926 int entry_count = ((dat<<24) | (dat1<<16) | (dat2<<8) | (dat3));
4927
4928 int sample_count [entry_count];
4929 int sample_delta [entry_count];
4930
4931 for (int i=0;i<entry_count;i++){
4932
4933
4934 fread(&dat, sizeof(unsigned char), 1, imf);
4935 fread(&dat1, sizeof(unsigned char), 1, imf);
4936 fread(&dat2, sizeof(unsigned char), 1, imf);
4937 fread(&dat3, sizeof(unsigned char), 1, imf);
4938
4939 sample_count[i] = ((dat<<24) | (dat1<<16) | (dat2<<8) | (dat3));
4940
4941 fread(&dat, sizeof(unsigned char), 1, imf);
4942 fread(&dat1, sizeof(unsigned char), 1, imf);
4943 fread(&dat2, sizeof(unsigned char), 1, imf);
4944 fread(&dat3, sizeof(unsigned char), 1, imf);
4945
4946
4947 sample_delta[i] = ((dat<<24) | (dat1<<16) | (dat2<<8) | (dat3));
4948
4949 }
4950
4951 d=0;
4952 while (d==0){
4953
4954 fread(&dat, sizeof(unsigned char), 1, imf);
4955 fread(&dat1, sizeof(unsigned char), 1, imf);
4956 fread(&dat2, sizeof(unsigned char), 1, imf);
4957 fread(&dat3, sizeof(unsigned char), 1, imf);
4958
4959 if (dat == 0x73 && dat1 == 0x74 && dat2 == 0x73 && dat3 == 0x7A) { // 73 74 73 7A = s t s z
4960 d=1;
4961 }
4962
4963 else{
4964 fseek(imf, -3, SEEK_CUR); //if we have not readen ´stts´
4965 }
4966
4967 } //close while
4968
4969 for (int i=1;i<=8;i++){ //avanzamos 8 posiciones
4970
4971 fread(&dat, sizeof(unsigned char), 1, imf);
4972
4973 }
4974
4975 fread(&dat, sizeof(unsigned char), 1, imf); //read sample_count
4976 fread(&dat1, sizeof(unsigned char), 1, imf);
4977 fread(&dat2, sizeof(unsigned char), 1, imf);
4978 fread(&dat3, sizeof(unsigned char), 1, imf);
4979
4980 int samplecount = ((dat<<24) | (dat1<<16) | (dat2<<8) | (dat3));
4981 int sample_size[samplecount];
4982 for (int i=0;i<samplecount;i++){
4983
4984 fread(&dat, sizeof(unsigned char), 1, imf);
4985 fread(&dat1, sizeof(unsigned char), 1, imf);
4986 fread(&dat2, sizeof(unsigned char), 1, imf);
4987 fread(&dat3, sizeof(unsigned char), 1, imf);
4988
4989 sample_size[i] = ((dat<<24) | (dat1<<16) | (dat2<<8) | (dat3));// the size of every string including modifiers
4990
4991 }
4992
4993 d=0;
4994 while (d==0){
4995
4996 fread(&dat, sizeof(unsigned char), 1, imf);
4997 fread(&dat1, sizeof(unsigned char), 1, imf);
4998 fread(&dat2, sizeof(unsigned char), 1, imf);
4999 fread(&dat3, sizeof(unsigned char), 1, imf);
5000
5001 if (dat == 0x63 && dat1 == 0x6F && dat2 == 0x36 && dat3 == 0x34) { // 63 6F 36 34 = c o 6 4
5002 d=1;
5003 }
5004
5005 else{
5006 fseek(imf, -3, SEEK_CUR); //if we have not readen ´stts´
5007 }
5008
5009 } //close while
5010
5011 for (int i=1;i<=12;i++){ //advance 12 memory bytes
5012
5013 fread(&dat, sizeof(unsigned char), 1, imf);
5014
5015 }
5016
5017 fread(&dat, sizeof(unsigned char), 1, imf); //read co64 box
5018 fread(&dat1, sizeof(unsigned char), 1, imf);
5019 fread(&dat2, sizeof(unsigned char), 1, imf);
5020 fread(&dat3, sizeof(unsigned char), 1, imf);
5021
5022 int chunk_offset = ((dat<<24) | (dat1<<16) | (dat2<<8) | (dat3));
5023
5024 fseek (imf,0,SEEK_SET);
5025 fseek (imf,chunk_offset,SEEK_CUR); //jump to the position where starts text strings
5026
5027 int num_modifiers;
5028 float duration1;
5029 for (int j=0;j<samplecount;j++){
5030
5031 fread(&dat, sizeof(unsigned char), 1, imf); // read sizestring
5032 fread(&dat1, sizeof(unsigned char), 1, imf);
5033
5034 int sizestring = ((dat<<8) | (dat1));
5035
5036 char text [sizestring+1];
5037
5038 for (int i=0;i<sizestring;i++){
5039 fread(&dat, sizeof(unsigned char), 1, imf);
5040 text [i] = dat;
5041 }
5042 text[sizestring]= '\0';// indicates the end of the char string.If we don´t add this character, the conversion to QString does not work
5043 num_modifiers = sample_size[j]-sizestring-2;
5044
5045 for (int i=0;i<num_modifiers;i++){
5046 fread(&dat, sizeof(unsigned char), 1, imf);
5047 }
5048 QString result (text);//convert string char to QString
5049 duration1=0;
5050 for (int h=0;h<j;h++){
5051 duration1 = sample_delta[h]+duration1;
5052 }
5053 float duration2 = duration1 / 1000;
5054 int duration3 = duration2 * 44100;
5055 if (sizestring >1){ //sizestring = 1 when there is only a blank space.We do not want to add a blank space alone.
5056
5057 if (samplecount%2==0){//to avoid overlapping
5058 m_paneStack->setCurrentLayer(pane, newLayer);
5059 insertLyrics (duration3, result);
5060 }
5061 else{
5062 m_paneStack->setCurrentLayer(pane, newLayer1);
5063 insertLyrics (duration3, result);
5064 }
5065
5066
5067 } // close if
5068 } //close for
5069 } // close if haslyrics
5070
5071 }
5072 void
5073 MainWindow::openMP3IMAF()
5074 {
5075 FileOpenStatus status;
5076
5077 for (int i=0;i<audiotracks;i++){
5078
5079 char buf[2];
5080 sprintf(buf, "%d", i); //convert int to char
5081 status = open(buf, CreateAdditionalModel);
5082 remove (buf);
5083
5084 }
5085
5086 }
5087 void CheckBox::set_selruleType(QAbstractButton *button)
5088 {
5089 selrule_type = button->objectName().toInt();
5090
5091 if( (selrule_type == 0) || (selrule_type == 1) || (selrule_type == 3) ){
5092 sel_rule1->setText("Track A");
5093 sel_rule1->setDisabled(false);
5094 sel_rule2->setText("Track B");
5095 sel_rule2->setDisabled(false);
5096 }else{
5097 sel_rule1->setText("Track A");
5098 sel_rule1->setDisabled(false);
5099 sel_rule2->setDisabled(true);
5100 }
5101 }
5102
5103 void CheckBox::set_selrulePAR1(int value)
5104 {
5105 selrule_par1 = value; // TRACK A
5106 }
5107
5108 void CheckBox::set_selrulePAR2(int value)
5109 {
5110 selrule_par2 = value; // TRACK B
5111 }
5112
5113 void CheckBox::set_mixruleType(QAbstractButton *button)
5114 {
5115 mixrule_type = button->objectName().toInt();
5116
5117 if( (mixrule_type == 0) || (mixrule_type == 1) || (mixrule_type == 2) ){
5118 mix_rule1->setText("Track A");
5119 mix_rule1->setDisabled(false);
5120 mix_rule2->setText("Track B");
5121 mix_rule2->setDisabled(false);
5122 mix_rule3->setDisabled(true);
5123 mix_rule4->setDisabled(true);
5124 }else{
5125 mix_rule1->setText("Track A");
5126 mix_rule1->setDisabled(false);
5127 mix_rule2->setDisabled(true);
5128 mix_rule3->setText("Min Volume");
5129 mix_rule3->setDisabled(false);
5130 mix_rule4->setText("Max Volume");
5131 mix_rule4->setDisabled(false);
5132 }
5133 }
5134
5135 void CheckBox::set_mixrulePAR1(int value)
5136 {
5137 mixrule_par1 = value; // TRACK A
5138 }
5139
5140 void CheckBox::set_mixrulePAR2(int value)
5141 {
5142 mixrule_par2 = value; // TRACK B
5143 }
5144
5145 void CheckBox::set_mixrulePAR3(int value)
5146 {
5147 mixrule_par3 = value; // MIN VOL for Limit Rule
5148 }
5149
5150 void CheckBox::set_mixrulePAR4(int value)
5151 {
5152 mixrule_par4 = value; // MAX VOL for Limit Rule
5153 }
5154
5155 void CheckBox::set_TrackInGroup(QAbstractButton *button)
5156 {
5157 int temp = button->objectName().toInt();
5158
5159 if (button->isChecked()){
5160 group_tracks[temp-1] = 1;
5161 }else{
5162 group_tracks[temp-1] = 0;
5163 }
5164 }
5165
5166 void CheckBox::set_GroupName(QString name)
5167 {
5168 group_name = name;
5169 }
5170
5171 void CheckBox::set_GroupVolume(int value)
5172 {
5173 group_volume = value;
5174 }
5175
5176 void CheckBox::set_presetType(QAbstractButton *button)
5177 {
5178 preset_type = button->objectName().toInt();
5179 }
5180
5181 void CheckBox::set_fade(QAbstractButton *button)
5182 {
5183 fade_in = button->objectName().toInt();
5184 }