Mercurial > hg > sonic-visualiser
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 © 2005–2013 Chris Cannam and " | 4389 "<p><small>Sonic Visualiser Copyright © 2005–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 } |