Mercurial > hg > sonic-visualiser
comparison main/MainWindow.cpp @ 246:ddbde90773b0 spectrogram-cache-rejig
* Merge from trunk
author | Chris Cannam |
---|---|
date | Wed, 27 Feb 2008 11:59:42 +0000 |
parents | 11ca12902c6a |
children |
comparison
equal
deleted
inserted
replaced
214:37847fc0b381 | 246:ddbde90773b0 |
---|---|
14 */ | 14 */ |
15 | 15 |
16 #include "../version.h" | 16 #include "../version.h" |
17 | 17 |
18 #include "MainWindow.h" | 18 #include "MainWindow.h" |
19 #include "framework/Document.h" | |
20 #include "PreferencesDialog.h" | 19 #include "PreferencesDialog.h" |
21 | 20 |
22 #include "view/Pane.h" | 21 #include "view/Pane.h" |
23 #include "view/PaneStack.h" | 22 #include "view/PaneStack.h" |
24 #include "data/model/WaveFileModel.h" | 23 #include "data/model/WaveFileModel.h" |
25 #include "data/model/SparseOneDimensionalModel.h" | 24 #include "data/model/SparseOneDimensionalModel.h" |
26 #include "data/model/NoteModel.h" | 25 #include "data/model/NoteModel.h" |
27 #include "data/model/Labeller.h" | 26 #include "data/model/Labeller.h" |
27 #include "data/osc/OSCQueue.h" | |
28 #include "framework/Document.h" | |
28 #include "view/ViewManager.h" | 29 #include "view/ViewManager.h" |
29 #include "base/Preferences.h" | 30 #include "base/Preferences.h" |
30 #include "layer/WaveformLayer.h" | 31 #include "layer/WaveformLayer.h" |
31 #include "layer/TimeRulerLayer.h" | 32 #include "layer/TimeRulerLayer.h" |
32 #include "layer/TimeInstantLayer.h" | 33 #include "layer/TimeInstantLayer.h" |
39 #include "view/Overview.h" | 40 #include "view/Overview.h" |
40 #include "widgets/PropertyBox.h" | 41 #include "widgets/PropertyBox.h" |
41 #include "widgets/PropertyStack.h" | 42 #include "widgets/PropertyStack.h" |
42 #include "widgets/AudioDial.h" | 43 #include "widgets/AudioDial.h" |
43 #include "widgets/IconLoader.h" | 44 #include "widgets/IconLoader.h" |
44 #include "widgets/LayerTree.h" | 45 #include "widgets/LayerTreeDialog.h" |
45 #include "widgets/ListInputDialog.h" | 46 #include "widgets/ListInputDialog.h" |
46 #include "widgets/SubdividingMenu.h" | 47 #include "widgets/SubdividingMenu.h" |
47 #include "widgets/NotifyingPushButton.h" | 48 #include "widgets/NotifyingPushButton.h" |
48 #include "widgets/KeyReference.h" | 49 #include "widgets/KeyReference.h" |
49 #include "widgets/LabelCounterInputDialog.h" | 50 #include "widgets/LabelCounterInputDialog.h" |
67 #include "base/CommandHistory.h" | 68 #include "base/CommandHistory.h" |
68 #include "base/Profiler.h" | 69 #include "base/Profiler.h" |
69 #include "base/Clipboard.h" | 70 #include "base/Clipboard.h" |
70 #include "base/UnitDatabase.h" | 71 #include "base/UnitDatabase.h" |
71 #include "base/ColourDatabase.h" | 72 #include "base/ColourDatabase.h" |
72 #include "data/osc/OSCQueue.h" | |
73 | 73 |
74 // For version information | 74 // For version information |
75 #include "vamp/vamp.h" | 75 #include "vamp/vamp.h" |
76 #include "vamp-sdk/PluginBase.h" | 76 #include "vamp-sdk/PluginBase.h" |
77 #include "plugin/api/ladspa.h" | 77 #include "plugin/api/ladspa.h" |
131 m_soloAction(0), | 131 m_soloAction(0), |
132 m_soloModified(false), | 132 m_soloModified(false), |
133 m_prevSolo(false), | 133 m_prevSolo(false), |
134 m_ffwdAction(0), | 134 m_ffwdAction(0), |
135 m_rwdAction(0), | 135 m_rwdAction(0), |
136 m_playControlsSpacer(0), | |
137 m_playControlsWidth(0), | |
136 m_preferencesDialog(0), | 138 m_preferencesDialog(0), |
137 m_layerTreeView(0), | 139 m_layerTreeDialog(0), |
138 m_keyReference(new KeyReference()) | 140 m_keyReference(new KeyReference()) |
139 { | 141 { |
140 setWindowTitle(tr("Sonic Visualiser")); | 142 setWindowTitle(tr("Sonic Visualiser")); |
141 | 143 |
142 UnitDatabase *udb = UnitDatabase::getInstance(); | 144 UnitDatabase *udb = UnitDatabase::getInstance(); |
218 connect(m_playSpeed, SIGNAL(mouseEntered()), this, SLOT(mouseEnteredWidget())); | 220 connect(m_playSpeed, SIGNAL(mouseEntered()), this, SLOT(mouseEnteredWidget())); |
219 connect(m_playSpeed, SIGNAL(mouseLeft()), this, SLOT(mouseLeftWidget())); | 221 connect(m_playSpeed, SIGNAL(mouseLeft()), this, SLOT(mouseLeftWidget())); |
220 | 222 |
221 IconLoader il; | 223 IconLoader il; |
222 | 224 |
223 m_playSharpen = new NotifyingPushButton(frame); | |
224 m_playSharpen->setToolTip(tr("Sharpen percussive transients")); | |
225 m_playSharpen->setFixedSize(20, 20); | |
226 m_playSharpen->setEnabled(false); | |
227 m_playSharpen->setCheckable(true); | |
228 m_playSharpen->setChecked(false); | |
229 m_playSharpen->setIcon(il.load("sharpen")); | |
230 connect(m_playSharpen, SIGNAL(clicked()), this, SLOT(playSharpenToggled())); | |
231 connect(m_playSharpen, SIGNAL(mouseEntered()), this, SLOT(mouseEnteredWidget())); | |
232 connect(m_playSharpen, SIGNAL(mouseLeft()), this, SLOT(mouseLeftWidget())); | |
233 | |
234 m_playMono = new NotifyingPushButton(frame); | |
235 m_playMono->setToolTip(tr("Run time stretcher in mono only")); | |
236 m_playMono->setFixedSize(20, 20); | |
237 m_playMono->setEnabled(false); | |
238 m_playMono->setCheckable(true); | |
239 m_playMono->setChecked(false); | |
240 m_playMono->setIcon(il.load("mono")); | |
241 connect(m_playMono, SIGNAL(clicked()), this, SLOT(playMonoToggled())); | |
242 connect(m_playMono, SIGNAL(mouseEntered()), this, SLOT(mouseEnteredWidget())); | |
243 connect(m_playMono, SIGNAL(mouseLeft()), this, SLOT(mouseLeftWidget())); | |
244 | |
245 QSettings settings; | 225 QSettings settings; |
246 settings.beginGroup("MainWindow"); | 226 settings.beginGroup("MainWindow"); |
247 m_playSharpen->setChecked(settings.value("playsharpen", true).toBool()); | |
248 m_playMono->setChecked(settings.value("playmono", false).toBool()); | |
249 settings.endGroup(); | 227 settings.endGroup(); |
228 | |
229 m_playControlsSpacer = new QFrame; | |
250 | 230 |
251 layout->setSpacing(4); | 231 layout->setSpacing(4); |
252 layout->addWidget(scroll, 0, 0, 1, 5); | 232 layout->addWidget(scroll, 0, 0, 1, 5); |
253 layout->addWidget(m_overview, 1, 0); | 233 layout->addWidget(m_overview, 1, 1); |
254 layout->addWidget(m_fader, 1, 1); | 234 layout->addWidget(m_playControlsSpacer, 1, 2); |
255 layout->addWidget(m_playSpeed, 1, 2); | 235 layout->addWidget(m_playSpeed, 1, 3); |
256 layout->addWidget(m_playSharpen, 1, 3); | 236 layout->addWidget(m_fader, 1, 4); |
257 layout->addWidget(m_playMono, 1, 4); | 237 |
258 | 238 m_playControlsWidth = |
259 m_paneStack->setPropertyStackMinWidth | 239 m_fader->width() + m_playSpeed->width() + layout->spacing() * 2; |
260 (m_fader->width() + m_playSpeed->width() + m_playSharpen->width() + | 240 |
261 m_playMono->width() + layout->spacing() * 4); | 241 layout->setColumnMinimumWidth(0, 14); |
262 | 242 layout->setColumnStretch(0, 0); |
263 layout->setColumnStretch(0, 10); | 243 |
244 m_paneStack->setPropertyStackMinWidth(m_playControlsWidth | |
245 + 2 + layout->spacing()); | |
246 m_playControlsSpacer->setFixedSize(QSize(2, 2)); | |
247 | |
248 layout->setColumnStretch(1, 10); | |
249 | |
250 connect(m_paneStack, SIGNAL(propertyStacksResized(int)), | |
251 this, SLOT(propertyStacksResized(int))); | |
264 | 252 |
265 frame->setLayout(layout); | 253 frame->setLayout(layout); |
266 | 254 |
267 setupMenus(); | 255 setupMenus(); |
268 setupToolbars(); | 256 setupToolbars(); |
275 | 263 |
276 MainWindow::~MainWindow() | 264 MainWindow::~MainWindow() |
277 { | 265 { |
278 delete m_keyReference; | 266 delete m_keyReference; |
279 delete m_preferencesDialog; | 267 delete m_preferencesDialog; |
280 delete m_layerTreeView; | 268 delete m_layerTreeDialog; |
281 Profiles::getInstance()->dump(); | 269 Profiles::getInstance()->dump(); |
282 } | 270 } |
283 | 271 |
284 void | 272 void |
285 MainWindow::setupMenus() | 273 MainWindow::setupMenus() |
591 connect(this, SIGNAL(canInsertInstantsAtBoundaries(bool)), action, SLOT(setEnabled(bool))); | 579 connect(this, SIGNAL(canInsertInstantsAtBoundaries(bool)), action, SLOT(setEnabled(bool))); |
592 m_keyReference->registerShortcut(action); | 580 m_keyReference->registerShortcut(action); |
593 menu->addAction(action); | 581 menu->addAction(action); |
594 | 582 |
595 QMenu *numberingMenu = menu->addMenu(tr("Number New Instants with")); | 583 QMenu *numberingMenu = menu->addMenu(tr("Number New Instants with")); |
584 numberingMenu->setTearOffEnabled(true); | |
596 QActionGroup *numberingGroup = new QActionGroup(this); | 585 QActionGroup *numberingGroup = new QActionGroup(this); |
597 | 586 |
598 Labeller::TypeNameMap types = m_labeller->getTypeNames(); | 587 Labeller::TypeNameMap types = m_labeller->getTypeNames(); |
599 for (Labeller::TypeNameMap::iterator i = types.begin(); i != types.end(); ++i) { | 588 for (Labeller::TypeNameMap::iterator i = types.begin(); i != types.end(); ++i) { |
600 | 589 |
612 if (i->first == Labeller::ValueFromTwoLevelCounter) { | 601 if (i->first == Labeller::ValueFromTwoLevelCounter) { |
613 | 602 |
614 QMenu *cycleMenu = numberingMenu->addMenu(tr("Cycle size")); | 603 QMenu *cycleMenu = numberingMenu->addMenu(tr("Cycle size")); |
615 QActionGroup *cycleGroup = new QActionGroup(this); | 604 QActionGroup *cycleGroup = new QActionGroup(this); |
616 | 605 |
617 int cycles[] = { 2, 3, 4, 5, 6, 7, 8, 10, 12, 16 }; | 606 int cycles[] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 16 }; |
618 for (int i = 0; i < int(sizeof(cycles)/sizeof(cycles[0])); ++i) { | 607 for (int i = 0; i < int(sizeof(cycles)/sizeof(cycles[0])); ++i) { |
619 action = new QAction(QString("%1").arg(cycles[i]), this); | 608 action = new QAction(QString("%1").arg(cycles[i]), this); |
620 connect(action, SIGNAL(triggered()), this, SLOT(setInstantsCounterCycle())); | 609 connect(action, SIGNAL(triggered()), this, SLOT(setInstantsCounterCycle())); |
621 action->setCheckable(true); | 610 action->setCheckable(true); |
622 action->setChecked(cycles[i] == m_labeller->getCounterCycleSize()); | 611 action->setChecked(cycles[i] == m_labeller->getCounterCycleSize()); |
623 cycleGroup->addAction(action); | 612 cycleGroup->addAction(action); |
624 cycleMenu->addAction(action); | 613 cycleMenu->addAction(action); |
625 } | 614 } |
626 | |
627 action = new QAction(tr("Reset Counters..."), this); | |
628 connect(action, SIGNAL(triggered()), this, SLOT(resetInstantsCounters())); | |
629 numberingMenu->addAction(action); | |
630 } | 615 } |
631 | 616 |
632 if (i->first == Labeller::ValueNone || | 617 if (i->first == Labeller::ValueNone || |
633 i->first == Labeller::ValueFromTwoLevelCounter || | 618 i->first == Labeller::ValueFromTwoLevelCounter || |
634 i->first == Labeller::ValueFromRealTime) { | 619 i->first == Labeller::ValueFromRealTime) { |
635 numberingMenu->addSeparator(); | 620 numberingMenu->addSeparator(); |
636 } | 621 } |
637 } | 622 } |
638 | 623 |
639 action = new QAction(tr("Re-Number Selected Instants"), this); | 624 action = new QAction(tr("Set Numbering Counters..."), this); |
640 action->setStatusTip(tr("Re-number the selected instants using the current labelling scheme")); | 625 action->setStatusTip(tr("Set the counters used for counter-based labelling")); |
626 connect(action, SIGNAL(triggered()), this, SLOT(resetInstantsCounters())); | |
627 menu->addAction(action); | |
628 | |
629 action = new QAction(tr("Renumber Selected Instants"), this); | |
630 action->setStatusTip(tr("Renumber the selected instants using the current labelling scheme")); | |
641 connect(action, SIGNAL(triggered()), this, SLOT(renumberInstants())); | 631 connect(action, SIGNAL(triggered()), this, SLOT(renumberInstants())); |
642 connect(this, SIGNAL(canRenumberInstants(bool)), action, SLOT(setEnabled(bool))); | 632 connect(this, SIGNAL(canRenumberInstants(bool)), action, SLOT(setEnabled(bool))); |
643 // m_keyReference->registerShortcut(action); | 633 // m_keyReference->registerShortcut(action); |
644 menu->addAction(action); | 634 menu->addAction(action); |
645 } | 635 } |
808 } | 798 } |
809 settings.endGroup(); | 799 settings.endGroup(); |
810 | 800 |
811 menu->addSeparator(); | 801 menu->addSeparator(); |
812 | 802 |
813 action = new QAction(tr("Show La&yer Hierarchy"), this); | 803 action = new QAction(tr("Show La&yer Summary"), this); |
814 action->setShortcut(tr("H")); | 804 action->setShortcut(tr("Y")); |
815 action->setStatusTip(tr("Open a window displaying the hierarchy of panes and layers in this session")); | 805 action->setStatusTip(tr("Open a window displaying the hierarchy of panes and layers in this session")); |
816 connect(action, SIGNAL(triggered()), this, SLOT(showLayerTree())); | 806 connect(action, SIGNAL(triggered()), this, SLOT(showLayerTree())); |
817 m_keyReference->registerShortcut(action); | 807 m_keyReference->registerShortcut(action); |
818 menu->addAction(action); | 808 menu->addAction(action); |
819 } | 809 } |
846 QAction *action = new QAction(il.load("pane"), tr("Add &New Pane"), this); | 836 QAction *action = new QAction(il.load("pane"), tr("Add &New Pane"), this); |
847 action->setShortcut(tr("N")); | 837 action->setShortcut(tr("N")); |
848 action->setStatusTip(tr("Add a new pane containing only a time ruler")); | 838 action->setStatusTip(tr("Add a new pane containing only a time ruler")); |
849 connect(action, SIGNAL(triggered()), this, SLOT(addPane())); | 839 connect(action, SIGNAL(triggered()), this, SLOT(addPane())); |
850 connect(this, SIGNAL(canAddPane(bool)), action, SLOT(setEnabled(bool))); | 840 connect(this, SIGNAL(canAddPane(bool)), action, SLOT(setEnabled(bool))); |
851 m_paneActions[action] = PaneConfiguration(LayerFactory::TimeRuler); | 841 m_paneActions[action] = LayerConfiguration(LayerFactory::TimeRuler); |
852 m_keyReference->registerShortcut(action); | 842 m_keyReference->registerShortcut(action); |
853 menu->addAction(action); | 843 menu->addAction(action); |
854 | 844 |
855 menu->addSeparator(); | 845 menu->addSeparator(); |
856 | 846 |
882 m_keyReference->registerShortcut(action); | 872 m_keyReference->registerShortcut(action); |
883 } | 873 } |
884 | 874 |
885 connect(action, SIGNAL(triggered()), this, SLOT(addLayer())); | 875 connect(action, SIGNAL(triggered()), this, SLOT(addLayer())); |
886 connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); | 876 connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); |
887 m_layerActions[action] = type; | 877 m_layerActions[action] = LayerConfiguration(type); |
888 menu->addAction(action); | 878 menu->addAction(action); |
889 m_rightButtonLayerMenu->addAction(action); | 879 m_rightButtonLayerMenu->addAction(action); |
890 } | 880 } |
891 | 881 |
892 m_rightButtonLayerMenu->addSeparator(); | 882 m_rightButtonLayerMenu->addSeparator(); |
899 LayerFactory::PeakFrequencySpectrogram, | 889 LayerFactory::PeakFrequencySpectrogram, |
900 LayerFactory::Spectrum | 890 LayerFactory::Spectrum |
901 }; | 891 }; |
902 | 892 |
903 std::vector<Model *> models; | 893 std::vector<Model *> models; |
904 if (m_document) models = m_document->getTransformerInputModels(); //!!! not well named for this! | 894 if (m_document) models = m_document->getTransformInputModels(); |
905 bool plural = (models.size() > 1); | 895 bool plural = (models.size() > 1); |
906 if (models.empty()) { | 896 if (models.empty()) { |
907 models.push_back(getMainModel()); // probably 0 | 897 models.push_back(getMainModel()); // probably 0 |
908 } | 898 } |
909 | 899 |
910 for (unsigned int i = 0; | 900 for (unsigned int i = 0; |
911 i < sizeof(backgroundTypes)/sizeof(backgroundTypes[0]); ++i) { | 901 i < sizeof(backgroundTypes)/sizeof(backgroundTypes[0]); ++i) { |
912 | 902 |
913 for (int menuType = 0; menuType <= 1; ++menuType) { // pane, layer | 903 const int paneMenuType = 0, layerMenuType = 1; |
914 | 904 |
915 if (menuType == 0) menu = m_paneMenu; | 905 for (int menuType = paneMenuType; menuType <= layerMenuType; ++menuType) { |
906 | |
907 if (menuType == paneMenuType) menu = m_paneMenu; | |
916 else menu = m_layerMenu; | 908 else menu = m_layerMenu; |
917 | 909 |
918 QMenu *submenu = 0; | 910 QMenu *submenu = 0; |
919 | 911 |
920 QIcon icon; | 912 QIcon icon; |
925 switch (type) { | 917 switch (type) { |
926 | 918 |
927 case LayerFactory::Waveform: | 919 case LayerFactory::Waveform: |
928 icon = il.load("waveform"); | 920 icon = il.load("waveform"); |
929 mainText = tr("Add &Waveform"); | 921 mainText = tr("Add &Waveform"); |
930 if (menuType == 0) { | 922 if (menuType == paneMenuType) { |
931 shortcutText = tr("W"); | 923 shortcutText = tr("W"); |
932 tipText = tr("Add a new pane showing a waveform view"); | 924 tipText = tr("Add a new pane showing a waveform view"); |
933 } else { | 925 } else { |
934 tipText = tr("Add a new layer showing a waveform view"); | 926 tipText = tr("Add a new layer showing a waveform view"); |
935 } | 927 } |
937 break; | 929 break; |
938 | 930 |
939 case LayerFactory::Spectrogram: | 931 case LayerFactory::Spectrogram: |
940 icon = il.load("spectrogram"); | 932 icon = il.load("spectrogram"); |
941 mainText = tr("Add Spectro&gram"); | 933 mainText = tr("Add Spectro&gram"); |
942 if (menuType == 0) { | 934 if (menuType == paneMenuType) { |
943 shortcutText = tr("G"); | 935 shortcutText = tr("G"); |
944 tipText = tr("Add a new pane showing a spectrogram"); | 936 tipText = tr("Add a new pane showing a spectrogram"); |
945 } else { | 937 } else { |
946 tipText = tr("Add a new layer showing a spectrogram"); | 938 tipText = tr("Add a new layer showing a spectrogram"); |
947 } | 939 } |
948 break; | 940 break; |
949 | 941 |
950 case LayerFactory::MelodicRangeSpectrogram: | 942 case LayerFactory::MelodicRangeSpectrogram: |
951 icon = il.load("spectrogram"); | 943 icon = il.load("spectrogram"); |
952 mainText = tr("Add &Melodic Range Spectrogram"); | 944 mainText = tr("Add &Melodic Range Spectrogram"); |
953 if (menuType == 0) { | 945 if (menuType == paneMenuType) { |
954 shortcutText = tr("M"); | 946 shortcutText = tr("M"); |
955 tipText = tr("Add a new pane showing a spectrogram set up for an overview of note pitches"); | 947 tipText = tr("Add a new pane showing a spectrogram set up for an overview of note pitches"); |
956 } else { | 948 } else { |
957 tipText = tr("Add a new layer showing a spectrogram set up for an overview of note pitches"); | 949 tipText = tr("Add a new layer showing a spectrogram set up for an overview of note pitches"); |
958 } | 950 } |
959 break; | 951 break; |
960 | 952 |
961 case LayerFactory::PeakFrequencySpectrogram: | 953 case LayerFactory::PeakFrequencySpectrogram: |
962 icon = il.load("spectrogram"); | 954 icon = il.load("spectrogram"); |
963 mainText = tr("Add Pea&k Frequency Spectrogram"); | 955 mainText = tr("Add Pea&k Frequency Spectrogram"); |
964 if (menuType == 0) { | 956 if (menuType == paneMenuType) { |
965 shortcutText = tr("K"); | 957 shortcutText = tr("K"); |
966 tipText = tr("Add a new pane showing a spectrogram set up for tracking frequencies"); | 958 tipText = tr("Add a new pane showing a spectrogram set up for tracking frequencies"); |
967 } else { | 959 } else { |
968 tipText = tr("Add a new layer showing a spectrogram set up for tracking frequencies"); | 960 tipText = tr("Add a new layer showing a spectrogram set up for tracking frequencies"); |
969 } | 961 } |
970 break; | 962 break; |
971 | 963 |
972 case LayerFactory::Spectrum: | 964 case LayerFactory::Spectrum: |
973 icon = il.load("spectrum"); | 965 icon = il.load("spectrum"); |
974 mainText = tr("Add Spectr&um"); | 966 mainText = tr("Add Spectr&um"); |
975 if (menuType == 0) { | 967 if (menuType == paneMenuType) { |
976 shortcutText = tr("U"); | 968 shortcutText = tr("U"); |
977 tipText = tr("Add a new pane showing a frequency spectrum"); | 969 tipText = tr("Add a new pane showing a frequency spectrum"); |
978 } else { | 970 } else { |
979 tipText = tr("Add a new layer showing a frequency spectrum"); | 971 tipText = tr("Add a new layer showing a frequency spectrum"); |
980 } | 972 } |
982 | 974 |
983 default: break; | 975 default: break; |
984 } | 976 } |
985 | 977 |
986 std::vector<Model *> candidateModels; | 978 std::vector<Model *> candidateModels; |
987 if (menuType == 0) { | 979 // if (menuType == paneMenuType) { |
988 candidateModels = models; | 980 candidateModels = models; |
989 } else { | 981 // } else { |
990 candidateModels.push_back(0); | 982 // candidateModels.push_back(0); |
991 } | 983 // } |
992 | 984 |
993 for (std::vector<Model *>::iterator mi = | 985 for (std::vector<Model *>::iterator mi = |
994 candidateModels.begin(); | 986 candidateModels.begin(); |
995 mi != candidateModels.end(); ++mi) { | 987 mi != candidateModels.end(); ++mi) { |
996 | 988 |
1011 | 1003 |
1012 if (c == 1 && channels == 1) continue; | 1004 if (c == 1 && channels == 1) continue; |
1013 bool isDefault = (c == 0); | 1005 bool isDefault = (c == 0); |
1014 bool isOnly = (isDefault && (channels == 1)); | 1006 bool isOnly = (isDefault && (channels == 1)); |
1015 | 1007 |
1016 if (menuType == 1) { | 1008 // if (menuType == layerMenuType) { |
1017 if (isDefault) isOnly = true; | 1009 // if (isDefault) isOnly = true; |
1018 else continue; | 1010 // else continue; |
1019 } | 1011 // } |
1020 | 1012 |
1021 if (isOnly && (!plural || menuType == 1)) { | 1013 if (isOnly && (!plural /*|| menuType == layerMenuType*/)) { |
1022 | 1014 |
1023 if (menuType == 1 && type != LayerFactory::Waveform) { | 1015 // if (menuType == layerMenuType && type != LayerFactory::Waveform) { |
1024 action = new QAction(mainText, this); | 1016 // action = new QAction(mainText, this); |
1025 } else { | 1017 // } else { |
1026 action = new QAction(icon, mainText, this); | 1018 action = new QAction(icon, mainText, this); |
1027 } | 1019 // } |
1028 | 1020 |
1029 action->setShortcut(shortcutText); | 1021 action->setShortcut(shortcutText); |
1030 action->setStatusTip(tipText); | 1022 action->setStatusTip(tipText); |
1031 if (menuType == 0) { | 1023 if (menuType == paneMenuType) { |
1032 connect(action, SIGNAL(triggered()), | 1024 connect(action, SIGNAL(triggered()), |
1033 this, SLOT(addPane())); | 1025 this, SLOT(addPane())); |
1034 connect(this, SIGNAL(canAddPane(bool)), | 1026 connect(this, SIGNAL(canAddPane(bool)), |
1035 action, SLOT(setEnabled(bool))); | 1027 action, SLOT(setEnabled(bool))); |
1036 m_paneActions[action] = PaneConfiguration(type); | 1028 m_paneActions[action] = LayerConfiguration(type); |
1037 } else { | 1029 } else { |
1038 connect(action, SIGNAL(triggered()), | 1030 connect(action, SIGNAL(triggered()), |
1039 this, SLOT(addLayer())); | 1031 this, SLOT(addLayer())); |
1040 connect(this, SIGNAL(canAddLayer(bool)), | 1032 connect(this, SIGNAL(canAddLayer(bool)), |
1041 action, SLOT(setEnabled(bool))); | 1033 action, SLOT(setEnabled(bool))); |
1042 m_layerActions[action] = type; | 1034 m_layerActions[action] = LayerConfiguration(type); |
1043 } | 1035 } |
1044 if (shortcutText != "") { | 1036 if (shortcutText != "") { |
1045 m_keyReference->registerShortcut(action); | 1037 m_keyReference->registerShortcut(action); |
1046 } | 1038 } |
1047 menu->addAction(action); | 1039 menu->addAction(action); |
1081 action = new QAction(actionText, this); | 1073 action = new QAction(actionText, this); |
1082 } | 1074 } |
1083 | 1075 |
1084 action->setStatusTip(tipText); | 1076 action->setStatusTip(tipText); |
1085 | 1077 |
1086 if (menuType == 0) { | 1078 if (menuType == paneMenuType) { |
1087 connect(action, SIGNAL(triggered()), | 1079 connect(action, SIGNAL(triggered()), |
1088 this, SLOT(addPane())); | 1080 this, SLOT(addPane())); |
1089 connect(this, SIGNAL(canAddPane(bool)), | 1081 connect(this, SIGNAL(canAddPane(bool)), |
1090 action, SLOT(setEnabled(bool))); | 1082 action, SLOT(setEnabled(bool))); |
1091 m_paneActions[action] = | 1083 m_paneActions[action] = |
1092 PaneConfiguration(type, model, c - 1); | 1084 LayerConfiguration(type, model, c - 1); |
1093 } else { | 1085 } else { |
1094 connect(action, SIGNAL(triggered()), | 1086 connect(action, SIGNAL(triggered()), |
1095 this, SLOT(addLayer())); | 1087 this, SLOT(addLayer())); |
1096 connect(this, SIGNAL(canAddLayer(bool)), | 1088 connect(this, SIGNAL(canAddLayer(bool)), |
1097 action, SLOT(setEnabled(bool))); | 1089 action, SLOT(setEnabled(bool))); |
1098 m_layerActions[action] = type; | 1090 m_layerActions[action] = |
1091 LayerConfiguration(type, model, c - 1); | |
1099 } | 1092 } |
1100 | 1093 |
1101 submenu->addAction(action); | 1094 submenu->addAction(action); |
1102 } | 1095 } |
1103 } | 1096 } |
1104 } | 1097 } |
1105 } | 1098 } |
1106 } | 1099 } |
1107 | 1100 |
1108 menu = m_paneMenu; | 1101 menu = m_paneMenu; |
1102 menu->addSeparator(); | |
1103 | |
1104 action = new QAction(tr("Switch to Previous Pane"), this); | |
1105 action->setShortcut(tr("[")); | |
1106 action->setStatusTip(tr("Make the next pane up in the pane stack current")); | |
1107 connect(action, SIGNAL(triggered()), this, SLOT(previousPane())); | |
1108 connect(this, SIGNAL(canSelectPreviousPane(bool)), action, SLOT(setEnabled(bool))); | |
1109 m_keyReference->registerShortcut(action); | |
1110 menu->addAction(action); | |
1111 | |
1112 action = new QAction(tr("Switch to Next Pane"), this); | |
1113 action->setShortcut(tr("]")); | |
1114 action->setStatusTip(tr("Make the next pane down in the pane stack current")); | |
1115 connect(action, SIGNAL(triggered()), this, SLOT(nextPane())); | |
1116 connect(this, SIGNAL(canSelectNextPane(bool)), action, SLOT(setEnabled(bool))); | |
1117 m_keyReference->registerShortcut(action); | |
1118 menu->addAction(action); | |
1109 | 1119 |
1110 menu->addSeparator(); | 1120 menu->addSeparator(); |
1111 | 1121 |
1112 action = new QAction(il.load("editdelete"), tr("&Delete Pane"), this); | 1122 action = new QAction(il.load("editdelete"), tr("&Delete Pane"), this); |
1113 action->setShortcut(tr("Ctrl+Shift+D")); | 1123 action->setShortcut(tr("Ctrl+Shift+D")); |
1121 | 1131 |
1122 action = new QAction(il.load("timeruler"), tr("Add &Time Ruler"), this); | 1132 action = new QAction(il.load("timeruler"), tr("Add &Time Ruler"), this); |
1123 action->setStatusTip(tr("Add a new layer showing a time ruler")); | 1133 action->setStatusTip(tr("Add a new layer showing a time ruler")); |
1124 connect(action, SIGNAL(triggered()), this, SLOT(addLayer())); | 1134 connect(action, SIGNAL(triggered()), this, SLOT(addLayer())); |
1125 connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); | 1135 connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); |
1126 m_layerActions[action] = LayerFactory::TimeRuler; | 1136 m_layerActions[action] = LayerConfiguration(LayerFactory::TimeRuler); |
1127 menu->addAction(action); | 1137 menu->addAction(action); |
1128 | 1138 |
1129 menu->addSeparator(); | 1139 menu->addSeparator(); |
1130 | 1140 |
1131 m_existingLayersMenu = menu->addMenu(tr("Add &Existing Layer")); | 1141 m_existingLayersMenu = menu->addMenu(tr("Add &Existing Layer")); |
1136 m_sliceMenu->setTearOffEnabled(true); | 1146 m_sliceMenu->setTearOffEnabled(true); |
1137 m_rightButtonLayerMenu->addMenu(m_sliceMenu); | 1147 m_rightButtonLayerMenu->addMenu(m_sliceMenu); |
1138 | 1148 |
1139 setupExistingLayersMenus(); | 1149 setupExistingLayersMenus(); |
1140 | 1150 |
1151 /*!!! These don't work correctly -- fix or omit | |
1152 menu->addSeparator(); | |
1153 | |
1154 action = new QAction(tr("Switch to Previous Layer"), this); | |
1155 action->setShortcut(tr("{")); | |
1156 action->setStatusTip(tr("Make the previous layer in the pane current")); | |
1157 connect(action, SIGNAL(triggered()), this, SLOT(previousLayer())); | |
1158 connect(this, SIGNAL(canSelectPreviousLayer(bool)), action, SLOT(setEnabled(bool))); | |
1159 m_keyReference->registerShortcut(action); | |
1160 menu->addAction(action); | |
1161 | |
1162 action = new QAction(tr("Switch to Next Layer"), this); | |
1163 action->setShortcut(tr("}")); | |
1164 action->setStatusTip(tr("Make the next layer in the pane current")); | |
1165 connect(action, SIGNAL(triggered()), this, SLOT(nextLayer())); | |
1166 connect(this, SIGNAL(canSelectNextLayer(bool)), action, SLOT(setEnabled(bool))); | |
1167 m_keyReference->registerShortcut(action); | |
1168 menu->addAction(action); | |
1169 */ | |
1141 m_rightButtonLayerMenu->addSeparator(); | 1170 m_rightButtonLayerMenu->addSeparator(); |
1142 menu->addSeparator(); | 1171 menu->addSeparator(); |
1143 | 1172 |
1144 QAction *raction = new QAction(tr("&Rename Layer..."), this); | 1173 QAction *raction = new QAction(tr("&Rename Layer..."), this); |
1145 raction->setShortcut(tr("R")); | 1174 raction->setShortcut(tr("R")); |
1172 m_transformsMenu = menuBar()->addMenu(tr("&Transform")); | 1201 m_transformsMenu = menuBar()->addMenu(tr("&Transform")); |
1173 m_transformsMenu->setTearOffEnabled(true); | 1202 m_transformsMenu->setTearOffEnabled(true); |
1174 } | 1203 } |
1175 | 1204 |
1176 TransformList transforms = | 1205 TransformList transforms = |
1177 TransformFactory::getInstance()->getAllTransforms(); | 1206 TransformFactory::getInstance()->getAllTransformDescriptions(); |
1178 | 1207 |
1179 vector<QString> types = | 1208 vector<QString> types = |
1180 TransformFactory::getInstance()->getAllTransformTypes(); | 1209 TransformFactory::getInstance()->getAllTransformTypes(); |
1181 | 1210 |
1182 map<QString, map<QString, SubdividingMenu *> > categoryMenus; | 1211 map<QString, map<QString, SubdividingMenu *> > categoryMenus; |
1278 byMakerMenu->addMenu(makerMenus[*i][maker]); | 1307 byMakerMenu->addMenu(makerMenus[*i][maker]); |
1279 pendingMenus.insert(makerMenus[*i][maker]); | 1308 pendingMenus.insert(makerMenus[*i][maker]); |
1280 } | 1309 } |
1281 } | 1310 } |
1282 | 1311 |
1312 // Names should only be duplicated here if they have the same | |
1313 // plugin name, output name and maker but are in different library | |
1314 // .so names -- that won't happen often I hope | |
1315 std::map<QString, QString> idNameSonameMap; | |
1316 std::set<QString> seenNames, duplicateNames; | |
1317 for (unsigned int i = 0; i < transforms.size(); ++i) { | |
1318 QString name = transforms[i].name; | |
1319 if (seenNames.find(name) != seenNames.end()) { | |
1320 duplicateNames.insert(name); | |
1321 } else { | |
1322 seenNames.insert(name); | |
1323 } | |
1324 } | |
1325 | |
1283 for (unsigned int i = 0; i < transforms.size(); ++i) { | 1326 for (unsigned int i = 0; i < transforms.size(); ++i) { |
1284 | 1327 |
1285 QString name = transforms[i].name; | 1328 QString name = transforms[i].name; |
1286 if (name == "") name = transforms[i].identifier; | 1329 if (name == "") name = transforms[i].identifier; |
1287 | 1330 |
1296 if (maker == "") maker = tr("Unknown"); | 1339 if (maker == "") maker = tr("Unknown"); |
1297 maker.replace(QRegExp(tr(" [\\(<].*$")), ""); | 1340 maker.replace(QRegExp(tr(" [\\(<].*$")), ""); |
1298 | 1341 |
1299 QString pluginName = name.section(": ", 0, 0); | 1342 QString pluginName = name.section(": ", 0, 0); |
1300 QString output = name.section(": ", 1); | 1343 QString output = name.section(": ", 1); |
1344 | |
1345 if (duplicateNames.find(pluginName) != duplicateNames.end()) { | |
1346 pluginName = QString("%1 <%2>") | |
1347 .arg(pluginName) | |
1348 .arg(transforms[i].identifier.section(':', 1, 1)); | |
1349 if (output == "") name = pluginName; | |
1350 else name = QString("%1: %2") | |
1351 .arg(pluginName) | |
1352 .arg(output); | |
1353 } | |
1301 | 1354 |
1302 QAction *action = new QAction(tr("%1...").arg(name), this); | 1355 QAction *action = new QAction(tr("%1...").arg(name), this); |
1303 connect(action, SIGNAL(triggered()), this, SLOT(addLayer())); | 1356 connect(action, SIGNAL(triggered()), this, SLOT(addLayer())); |
1304 m_transformActions[action] = transforms[i].identifier; | 1357 m_transformActions[action] = transforms[i].identifier; |
1305 m_transformActionsReverse[transforms[i].identifier] = action; | 1358 m_transformActionsReverse[transforms[i].identifier] = action; |
1437 ti->second->setShortcut(tr("Ctrl+T")); | 1490 ti->second->setShortcut(tr("Ctrl+T")); |
1438 m_keyReference->registerShortcut | 1491 m_keyReference->registerShortcut |
1439 (tr("Repeat Transform"), | 1492 (tr("Repeat Transform"), |
1440 ti->second->shortcut(), | 1493 ti->second->shortcut(), |
1441 tr("Re-select the most recently run transform")); | 1494 tr("Re-select the most recently run transform")); |
1495 } else { | |
1496 ti->second->setShortcut(QString("")); | |
1442 } | 1497 } |
1443 m_recentTransformsMenu->addAction(ti->second); | 1498 m_recentTransformsMenu->addAction(ti->second); |
1444 } | 1499 } |
1445 } | 1500 } |
1446 | 1501 |
1735 connect(this, SIGNAL(canEditLayer(bool)), action, SLOT(setEnabled(bool))); | 1790 connect(this, SIGNAL(canEditLayer(bool)), action, SLOT(setEnabled(bool))); |
1736 group->addAction(action); | 1791 group->addAction(action); |
1737 m_keyReference->registerShortcut(action); | 1792 m_keyReference->registerShortcut(action); |
1738 m_toolActions[ViewManager::DrawMode] = action; | 1793 m_toolActions[ViewManager::DrawMode] = action; |
1739 | 1794 |
1795 action = toolbar->addAction(il.load("erase"), | |
1796 tr("Erase")); | |
1797 action->setCheckable(true); | |
1798 action->setShortcut(tr("5")); | |
1799 action->setStatusTip(tr("Erase items from layer")); | |
1800 connect(action, SIGNAL(triggered()), this, SLOT(toolEraseSelected())); | |
1801 connect(this, SIGNAL(canEditLayer(bool)), action, SLOT(setEnabled(bool))); | |
1802 group->addAction(action); | |
1803 m_keyReference->registerShortcut(action); | |
1804 m_toolActions[ViewManager::EraseMode] = action; | |
1805 | |
1740 action = toolbar->addAction(il.load("measure"), | 1806 action = toolbar->addAction(il.load("measure"), |
1741 tr("Measure")); | 1807 tr("Measure")); |
1742 action->setCheckable(true); | 1808 action->setCheckable(true); |
1743 action->setShortcut(tr("5")); | 1809 action->setShortcut(tr("6")); |
1744 action->setStatusTip(tr("Make measurements in layer")); | 1810 action->setStatusTip(tr("Make measurements in layer")); |
1745 connect(action, SIGNAL(triggered()), this, SLOT(toolMeasureSelected())); | 1811 connect(action, SIGNAL(triggered()), this, SLOT(toolMeasureSelected())); |
1746 connect(this, SIGNAL(canMeasureLayer(bool)), action, SLOT(setEnabled(bool))); | 1812 connect(this, SIGNAL(canMeasureLayer(bool)), action, SLOT(setEnabled(bool))); |
1747 group->addAction(action); | 1813 group->addAction(action); |
1748 m_keyReference->registerShortcut(action); | 1814 m_keyReference->registerShortcut(action); |
1749 m_toolActions[ViewManager::MeasureMode] = action; | 1815 m_toolActions[ViewManager::MeasureMode] = action; |
1750 | |
1751 // action = toolbar->addAction(il.load("text"), | |
1752 // tr("Text")); | |
1753 // action->setCheckable(true); | |
1754 // action->setShortcut(tr("5")); | |
1755 // connect(action, SIGNAL(triggered()), this, SLOT(toolTextSelected())); | |
1756 // group->addAction(action); | |
1757 // m_toolActions[ViewManager::TextMode] = action; | |
1758 | 1816 |
1759 toolNavigateSelected(); | 1817 toolNavigateSelected(); |
1760 | 1818 |
1761 Pane::registerShortcuts(*m_keyReference); | 1819 Pane::registerShortcuts(*m_keyReference); |
1762 } | 1820 } |
1896 { | 1954 { |
1897 m_viewManager->setToolMode(ViewManager::DrawMode); | 1955 m_viewManager->setToolMode(ViewManager::DrawMode); |
1898 } | 1956 } |
1899 | 1957 |
1900 void | 1958 void |
1959 MainWindow::toolEraseSelected() | |
1960 { | |
1961 m_viewManager->setToolMode(ViewManager::EraseMode); | |
1962 } | |
1963 | |
1964 void | |
1901 MainWindow::toolMeasureSelected() | 1965 MainWindow::toolMeasureSelected() |
1902 { | 1966 { |
1903 m_viewManager->setToolMode(ViewManager::MeasureMode); | 1967 m_viewManager->setToolMode(ViewManager::MeasureMode); |
1904 } | 1968 } |
1905 | |
1906 //void | |
1907 //MainWindow::toolTextSelected() | |
1908 //{ | |
1909 // m_viewManager->setToolMode(ViewManager::TextMode); | |
1910 //} | |
1911 | 1969 |
1912 void | 1970 void |
1913 MainWindow::importAudio() | 1971 MainWindow::importAudio() |
1914 { | 1972 { |
1915 QString path = getOpenFileName(FileFinder::AudioFile); | 1973 QString path = getOpenFileName(FileFinder::AudioFile); |
2504 | 2562 |
2505 if (m_preferencesDialog && | 2563 if (m_preferencesDialog && |
2506 m_preferencesDialog->isVisible()) { | 2564 m_preferencesDialog->isVisible()) { |
2507 closeSession(); // otherwise we'll have to wait for prefs changes | 2565 closeSession(); // otherwise we'll have to wait for prefs changes |
2508 m_preferencesDialog->applicationClosing(false); | 2566 m_preferencesDialog->applicationClosing(false); |
2509 } | |
2510 | |
2511 if (m_layerTreeView && | |
2512 m_layerTreeView->isVisible()) { | |
2513 delete m_layerTreeView; | |
2514 } | 2567 } |
2515 | 2568 |
2516 closeSession(); | 2569 closeSession(); |
2517 | 2570 |
2518 e->accept(); | 2571 e->accept(); |
2657 } | 2710 } |
2658 } | 2711 } |
2659 } | 2712 } |
2660 | 2713 |
2661 void | 2714 void |
2715 MainWindow::propertyStacksResized(int width) | |
2716 { | |
2717 std::cerr << "MainWindow::propertyStacksResized(" << width << ")" << std::endl; | |
2718 | |
2719 if (!m_playControlsSpacer) return; | |
2720 | |
2721 int spacerWidth = width - m_playControlsWidth - 4; | |
2722 | |
2723 std::cerr << "resizing spacer from " << m_playControlsSpacer->width() << " to " << spacerWidth << std::endl; | |
2724 | |
2725 m_playControlsSpacer->setFixedSize(QSize(spacerWidth, 2)); | |
2726 } | |
2727 | |
2728 void | |
2662 MainWindow::addPane() | 2729 MainWindow::addPane() |
2663 { | 2730 { |
2664 QObject *s = sender(); | 2731 QObject *s = sender(); |
2665 QAction *action = dynamic_cast<QAction *>(s); | 2732 QAction *action = dynamic_cast<QAction *>(s); |
2666 | 2733 |
2680 | 2747 |
2681 addPane(i->second, action->text()); | 2748 addPane(i->second, action->text()); |
2682 } | 2749 } |
2683 | 2750 |
2684 void | 2751 void |
2685 MainWindow::addPane(const PaneConfiguration &configuration, QString text) | 2752 MainWindow::addPane(const LayerConfiguration &configuration, QString text) |
2686 { | 2753 { |
2687 CommandHistory::getInstance()->startCompoundOperation(text, true); | 2754 CommandHistory::getInstance()->startCompoundOperation(text, true); |
2688 | 2755 |
2689 AddPaneCommand *command = new AddPaneCommand(this); | 2756 AddPaneCommand *command = new AddPaneCommand(this); |
2690 CommandHistory::getInstance()->addCommand(command); | 2757 CommandHistory::getInstance()->addCommand(command); |
2717 Model *model = 0; | 2784 Model *model = 0; |
2718 | 2785 |
2719 if (suggestedModel) { | 2786 if (suggestedModel) { |
2720 | 2787 |
2721 // check its validity | 2788 // check its validity |
2722 std::vector<Model *> inputModels = m_document->getTransformerInputModels(); | 2789 std::vector<Model *> inputModels = m_document->getTransformInputModels(); |
2723 for (size_t j = 0; j < inputModels.size(); ++j) { | 2790 for (size_t j = 0; j < inputModels.size(); ++j) { |
2724 if (inputModels[j] == suggestedModel) { | 2791 if (inputModels[j] == suggestedModel) { |
2725 model = suggestedModel; | 2792 model = suggestedModel; |
2726 break; | 2793 break; |
2727 } | 2794 } |
2811 std::cerr << "WARNING: MainWindow::addLayer: unknown action " | 2878 std::cerr << "WARNING: MainWindow::addLayer: unknown action " |
2812 << action->objectName().toStdString() << std::endl; | 2879 << action->objectName().toStdString() << std::endl; |
2813 return; | 2880 return; |
2814 } | 2881 } |
2815 | 2882 |
2816 LayerFactory::LayerType type = i->second; | 2883 LayerFactory::LayerType type = i->second.layer; |
2817 | 2884 |
2818 LayerFactory::LayerTypeSet emptyTypes = | 2885 LayerFactory::LayerTypeSet emptyTypes = |
2819 LayerFactory::getInstance()->getValidEmptyLayerTypes(); | 2886 LayerFactory::getInstance()->getValidEmptyLayerTypes(); |
2820 | 2887 |
2821 Layer *newLayer; | 2888 Layer *newLayer; |
2822 | 2889 |
2823 if (emptyTypes.find(type) != emptyTypes.end()) { | 2890 if (emptyTypes.find(type) != emptyTypes.end()) { |
2824 | 2891 |
2825 newLayer = m_document->createEmptyLayer(type); | 2892 newLayer = m_document->createEmptyLayer(type); |
2826 m_toolActions[ViewManager::DrawMode]->trigger(); | 2893 if (newLayer) { |
2894 m_toolActions[ViewManager::DrawMode]->trigger(); | |
2895 } | |
2827 | 2896 |
2828 } else { | 2897 } else { |
2829 | 2898 |
2830 newLayer = m_document->createMainModelLayer(type); | 2899 if (!i->second.sourceModel) { |
2831 } | 2900 // e.g. time ruler |
2832 | 2901 newLayer = m_document->createMainModelLayer(type); |
2833 m_document->addLayerToView(pane, newLayer); | 2902 } else { |
2834 m_paneStack->setCurrentLayer(pane, newLayer); | 2903 newLayer = m_document->createLayer(type); |
2904 if (m_document->isKnownModel(i->second.sourceModel)) { | |
2905 m_document->setChannel(newLayer, i->second.channel); | |
2906 m_document->setModel(newLayer, i->second.sourceModel); | |
2907 } else { | |
2908 std::cerr << "WARNING: MainWindow::addLayer: unknown model " | |
2909 << i->second.sourceModel | |
2910 << " (\"" | |
2911 << (i->second.sourceModel ? i->second.sourceModel->objectName().toStdString() : "") | |
2912 << "\") in layer action map" | |
2913 << std::endl; | |
2914 } | |
2915 } | |
2916 } | |
2917 | |
2918 if (newLayer) { | |
2919 m_document->addLayerToView(pane, newLayer); | |
2920 m_paneStack->setCurrentLayer(pane, newLayer); | |
2921 } | |
2835 | 2922 |
2836 return; | 2923 return; |
2837 } | 2924 } |
2838 | 2925 |
2839 TransformId transform = i->second; | 2926 //!!! want to do something like this, but it's not supported in |
2840 ModelTransformerFactory *factory = ModelTransformerFactory::getInstance(); | 2927 //ModelTransformerFactory yet |
2841 | 2928 /* |
2842 QString configurationXml; | |
2843 | |
2844 int channel = -1; | 2929 int channel = -1; |
2845 // pick up the default channel from any existing layers on the same pane | 2930 // pick up the default channel from any existing layers on the same pane |
2846 for (int j = 0; j < pane->getLayerCount(); ++j) { | 2931 for (int j = 0; j < pane->getLayerCount(); ++j) { |
2847 int c = LayerFactory::getInstance()->getChannel(pane->getLayer(j)); | 2932 int c = LayerFactory::getInstance()->getChannel(pane->getLayer(j)); |
2848 if (c != -1) { | 2933 if (c != -1) { |
2849 channel = c; | 2934 channel = c; |
2850 break; | 2935 break; |
2851 } | 2936 } |
2852 } | 2937 } |
2938 */ | |
2853 | 2939 |
2854 // We always ask for configuration, even if the plugin isn't | 2940 // We always ask for configuration, even if the plugin isn't |
2855 // supposed to be configurable, because we need to let the user | 2941 // supposed to be configurable, because we need to let the user |
2856 // change the execution context (block size etc). | 2942 // change the execution context (block size etc). |
2857 | 2943 |
2858 PluginTransformer::ExecutionContext context(channel); | 2944 QString transformId = i->second; |
2945 Transform transform = TransformFactory::getInstance()-> | |
2946 getDefaultTransformFor(transformId); | |
2859 | 2947 |
2860 std::vector<Model *> candidateInputModels = | 2948 std::vector<Model *> candidateInputModels = |
2861 m_document->getTransformerInputModels(); | 2949 m_document->getTransformInputModels(); |
2862 | 2950 |
2951 Model *defaultInputModel = 0; | |
2952 for (int j = 0; j < pane->getLayerCount(); ++j) { | |
2953 Layer *layer = pane->getLayer(j); | |
2954 if (!layer) continue; | |
2955 if (LayerFactory::getInstance()->getLayerType(layer) != | |
2956 LayerFactory::Waveform && | |
2957 !layer->isLayerOpaque()) continue; | |
2958 Model *model = layer->getModel(); | |
2959 if (!model) continue; | |
2960 for (size_t k = 0; k < candidateInputModels.size(); ++k) { | |
2961 if (candidateInputModels[k] == model) { | |
2962 defaultInputModel = model; | |
2963 break; | |
2964 } | |
2965 } | |
2966 if (defaultInputModel) break; | |
2967 } | |
2968 | |
2863 size_t startFrame = 0, duration = 0; | 2969 size_t startFrame = 0, duration = 0; |
2864 size_t endFrame = 0; | 2970 size_t endFrame = 0; |
2865 m_viewManager->getSelection().getExtents(startFrame, endFrame); | 2971 m_viewManager->getSelection().getExtents(startFrame, endFrame); |
2866 if (endFrame > startFrame) duration = endFrame - startFrame; | 2972 if (endFrame > startFrame) duration = endFrame - startFrame; |
2867 else startFrame = 0; | 2973 else startFrame = 0; |
2868 | 2974 |
2869 Model *inputModel = factory->getConfigurationForTransformer | 2975 ModelTransformer::Input input = ModelTransformerFactory::getInstance()-> |
2976 getConfigurationForTransform | |
2870 (transform, | 2977 (transform, |
2871 candidateInputModels, | 2978 candidateInputModels, |
2872 context, | 2979 defaultInputModel, |
2873 configurationXml, | |
2874 m_playSource, | 2980 m_playSource, |
2875 startFrame, | 2981 startFrame, |
2876 duration); | 2982 duration); |
2877 | 2983 |
2878 if (!inputModel) return; | 2984 if (!input.getModel()) return; |
2879 | 2985 |
2880 // std::cerr << "MainWindow::addLayer: Input model is " << inputModel << " \"" << inputModel->objectName().toStdString() << "\"" << std::endl; | 2986 // std::cerr << "MainWindow::addLayer: Input model is " << input.getModel() << " \"" << input.getModel()->objectName().toStdString() << "\"" << std::endl; |
2881 | 2987 |
2882 Layer *newLayer = m_document->createDerivedLayer(transform, | 2988 Layer *newLayer = m_document->createDerivedLayer(transform, input); |
2883 inputModel, | |
2884 context, | |
2885 configurationXml); | |
2886 | 2989 |
2887 if (newLayer) { | 2990 if (newLayer) { |
2888 m_document->addLayerToView(pane, newLayer); | 2991 m_document->addLayerToView(pane, newLayer); |
2889 m_document->setChannel(newLayer, context.channel); | 2992 m_document->setChannel(newLayer, input.getChannel()); |
2890 m_recentTransforms.add(transform); | 2993 m_recentTransforms.add(transformId); |
2891 m_paneStack->setCurrentLayer(pane, newLayer); | 2994 m_paneStack->setCurrentLayer(pane, newLayer); |
2892 } | 2995 } |
2893 | 2996 |
2894 updateMenuStates(); | 2997 updateMenuStates(); |
2895 } | 2998 } |
2905 QString newName = QInputDialog::getText | 3008 QString newName = QInputDialog::getText |
2906 (this, tr("Rename Layer"), | 3009 (this, tr("Rename Layer"), |
2907 tr("New name for this layer:"), | 3010 tr("New name for this layer:"), |
2908 QLineEdit::Normal, layer->objectName(), &ok); | 3011 QLineEdit::Normal, layer->objectName(), &ok); |
2909 if (ok) { | 3012 if (ok) { |
2910 layer->setObjectName(newName); | 3013 layer->setPresentationName(newName); |
2911 setupExistingLayersMenus(); | 3014 setupExistingLayersMenus(); |
2912 } | 3015 } |
2913 } | 3016 } |
2914 } | 3017 } |
2915 } | 3018 } |
2984 contextHelpChanged(tr("Playback speed: %1%2%") | 3087 contextHelpChanged(tr("Playback speed: %1%2%") |
2985 .arg(position > 100 ? "+" : "") | 3088 .arg(position > 100 ? "+" : "") |
2986 .arg(pc)); | 3089 .arg(pc)); |
2987 } | 3090 } |
2988 | 3091 |
2989 m_playSharpen->setEnabled(something); | 3092 m_playSource->setTimeStretch(factor); |
2990 m_playMono->setEnabled(something); | |
2991 bool sharpen = (something && m_playSharpen->isChecked()); | |
2992 bool mono = (something && m_playMono->isChecked()); | |
2993 m_playSource->setTimeStretch(factor, sharpen, mono); | |
2994 | 3093 |
2995 updateMenuStates(); | 3094 updateMenuStates(); |
2996 } | 3095 } |
2997 | |
2998 void | |
2999 MainWindow::playSharpenToggled() | |
3000 { | |
3001 QSettings settings; | |
3002 settings.beginGroup("MainWindow"); | |
3003 settings.setValue("playsharpen", m_playSharpen->isChecked()); | |
3004 settings.endGroup(); | |
3005 | |
3006 playSpeedChanged(m_playSpeed->value()); | |
3007 } | |
3008 | |
3009 void | |
3010 MainWindow::playMonoToggled() | |
3011 { | |
3012 QSettings settings; | |
3013 settings.beginGroup("MainWindow"); | |
3014 settings.setValue("playmono", m_playMono->isChecked()); | |
3015 settings.endGroup(); | |
3016 | |
3017 playSpeedChanged(m_playSpeed->value()); | |
3018 } | |
3019 | 3096 |
3020 void | 3097 void |
3021 MainWindow::speedUpPlayback() | 3098 MainWindow::speedUpPlayback() |
3022 { | 3099 { |
3023 int value = m_playSpeed->value(); | 3100 int value = m_playSpeed->value(); |
3037 | 3114 |
3038 void | 3115 void |
3039 MainWindow::restoreNormalPlayback() | 3116 MainWindow::restoreNormalPlayback() |
3040 { | 3117 { |
3041 m_playSpeed->setValue(m_playSpeed->defaultValue()); | 3118 m_playSpeed->setValue(m_playSpeed->defaultValue()); |
3119 } | |
3120 | |
3121 void | |
3122 MainWindow::currentPaneChanged(Pane *pane) | |
3123 { | |
3124 MainWindowBase::currentPaneChanged(pane); | |
3125 | |
3126 if (!pane || !m_panLayer) return; | |
3127 for (int i = pane->getLayerCount(); i > 0; ) { | |
3128 --i; | |
3129 Layer *layer = pane->getLayer(i); | |
3130 if (LayerFactory::getInstance()->getLayerType(layer) == | |
3131 LayerFactory::Waveform) { | |
3132 RangeSummarisableTimeValueModel *tvm = | |
3133 dynamic_cast<RangeSummarisableTimeValueModel *>(layer->getModel()); | |
3134 if (tvm) { | |
3135 m_panLayer->setModel(tvm); | |
3136 return; | |
3137 } | |
3138 } | |
3139 } | |
3042 } | 3140 } |
3043 | 3141 |
3044 void | 3142 void |
3045 MainWindow::updateVisibleRangeDisplay(Pane *p) const | 3143 MainWindow::updateVisibleRangeDisplay(Pane *p) const |
3046 { | 3144 { |
3192 | 3290 |
3193 void | 3291 void |
3194 MainWindow::resetInstantsCounters() | 3292 MainWindow::resetInstantsCounters() |
3195 { | 3293 { |
3196 LabelCounterInputDialog dialog(m_labeller, this); | 3294 LabelCounterInputDialog dialog(m_labeller, this); |
3295 dialog.setWindowTitle(tr("Reset Counters")); | |
3197 dialog.exec(); | 3296 dialog.exec(); |
3198 } | 3297 } |
3199 | 3298 |
3200 void | 3299 void |
3201 MainWindow::modelGenerationFailed(QString transformName) | 3300 MainWindow::modelGenerationFailed(QString transformName, QString message) |
3301 { | |
3302 if (message != "") { | |
3303 | |
3304 QMessageBox::warning | |
3305 (this, | |
3306 tr("Failed to generate layer"), | |
3307 tr("<b>Layer generation failed</b><p>Failed to generate derived layer.<p>The layer transform \"%1\" failed:<p>%2") | |
3308 .arg(transformName).arg(message), | |
3309 QMessageBox::Ok); | |
3310 } else { | |
3311 QMessageBox::warning | |
3312 (this, | |
3313 tr("Failed to generate layer"), | |
3314 tr("<b>Layer generation failed</b><p>Failed to generate a derived layer.<p>The layer transform \"%1\" failed.<p>No error information is available.") | |
3315 .arg(transformName), | |
3316 QMessageBox::Ok); | |
3317 } | |
3318 } | |
3319 | |
3320 void | |
3321 MainWindow::modelGenerationWarning(QString transformName, QString message) | |
3322 { | |
3323 QMessageBox::warning | |
3324 (this, tr("Warning"), message, QMessageBox::Ok); | |
3325 } | |
3326 | |
3327 void | |
3328 MainWindow::modelRegenerationFailed(QString layerName, | |
3329 QString transformName, QString message) | |
3330 { | |
3331 if (message != "") { | |
3332 | |
3333 QMessageBox::warning | |
3334 (this, | |
3335 tr("Failed to regenerate layer"), | |
3336 tr("<b>Layer generation failed</b><p>Failed to regenerate derived layer \"%1\" using new data model as input.<p>The layer transform \"%2\" failed:<p>%3") | |
3337 .arg(layerName).arg(transformName).arg(message), | |
3338 QMessageBox::Ok); | |
3339 } else { | |
3340 QMessageBox::warning | |
3341 (this, | |
3342 tr("Failed to regenerate layer"), | |
3343 tr("<b>Layer generation failed</b><p>Failed to regenerate derived layer \"%1\" using new data model as input.<p>The layer transform \"%2\" failed.<p>No error information is available.") | |
3344 .arg(layerName).arg(transformName), | |
3345 QMessageBox::Ok); | |
3346 } | |
3347 } | |
3348 | |
3349 void | |
3350 MainWindow::modelRegenerationWarning(QString layerName, | |
3351 QString transformName, QString message) | |
3352 { | |
3353 QMessageBox::warning | |
3354 (this, tr("Warning"), tr("<b>Warning when regenerating layer</b><p>When regenerating the derived layer \"%1\" using new data model as input:<p>%2").arg(layerName).arg(message), QMessageBox::Ok); | |
3355 } | |
3356 | |
3357 void | |
3358 MainWindow::alignmentFailed(QString transformName, QString message) | |
3202 { | 3359 { |
3203 QMessageBox::warning | 3360 QMessageBox::warning |
3204 (this, | 3361 (this, |
3205 tr("Failed to generate layer"), | 3362 tr("Failed to calculate alignment"), |
3206 tr("<b>Layer generation failed</b><p>Failed to generate a derived layer.<p>The layer transform \"%1\" failed.<p>This may mean that a plugin failed to initialise, perhaps because it rejected the processing block size that was requested.") | 3363 tr("<b>Alignment calculation failed</b><p>Failed to calculate an audio alignment using transform \"%1\":<p>%2") |
3207 .arg(transformName), | 3364 .arg(transformName).arg(message), |
3208 QMessageBox::Ok); | |
3209 } | |
3210 | |
3211 void | |
3212 MainWindow::modelRegenerationFailed(QString layerName, QString transformName) | |
3213 { | |
3214 QMessageBox::warning | |
3215 (this, | |
3216 tr("Failed to regenerate layer"), | |
3217 tr("<b>Layer generation failed</b><p>Failed to regenerate derived layer \"%1\".<p>The layer transform \"%2\" failed to run.<p>This may mean that the layer used a plugin that is not currently available.") | |
3218 .arg(layerName).arg(transformName), | |
3219 QMessageBox::Ok); | 3365 QMessageBox::Ok); |
3220 } | 3366 } |
3221 | 3367 |
3222 void | 3368 void |
3223 MainWindow::rightButtonMenuRequested(Pane *pane, QPoint position) | 3369 MainWindow::rightButtonMenuRequested(Pane *pane, QPoint position) |
3228 } | 3374 } |
3229 | 3375 |
3230 void | 3376 void |
3231 MainWindow::showLayerTree() | 3377 MainWindow::showLayerTree() |
3232 { | 3378 { |
3233 if (!m_layerTreeView.isNull()) { | 3379 if (!m_layerTreeDialog.isNull()) { |
3234 m_layerTreeView->show(); | 3380 m_layerTreeDialog->show(); |
3235 m_layerTreeView->raise(); | 3381 m_layerTreeDialog->raise(); |
3236 return; | 3382 return; |
3237 } | 3383 } |
3238 | 3384 |
3239 //!!! should use an actual dialog class | 3385 m_layerTreeDialog = new LayerTreeDialog(m_paneStack); |
3240 | 3386 m_layerTreeDialog->setAttribute(Qt::WA_DeleteOnClose); // see below |
3241 m_layerTreeView = new QTreeView(); | 3387 m_layerTreeDialog->show(); |
3242 LayerTreeModel *tree = new LayerTreeModel(m_paneStack); | |
3243 m_layerTreeView->resize(500, 300); //!!! | |
3244 m_layerTreeView->setModel(tree); | |
3245 m_layerTreeView->expandAll(); | |
3246 m_layerTreeView->show(); | |
3247 } | |
3248 | |
3249 void | |
3250 MainWindow::handleOSCMessage(const OSCMessage &message) | |
3251 { | |
3252 std::cerr << "MainWindow::handleOSCMessage: thread id = " | |
3253 << QThread::currentThreadId() << std::endl; | |
3254 | |
3255 // This large function should really be abstracted out. | |
3256 | |
3257 if (message.getMethod() == "open") { | |
3258 | |
3259 if (message.getArgCount() == 1 && | |
3260 message.getArg(0).canConvert(QVariant::String)) { | |
3261 QString path = message.getArg(0).toString(); | |
3262 if (open(path, ReplaceMainModel) != FileOpenSucceeded) { | |
3263 std::cerr << "MainWindow::handleOSCMessage: File open failed for path \"" | |
3264 << path.toStdString() << "\"" << std::endl; | |
3265 } | |
3266 //!!! we really need to spin here and not return until the | |
3267 // file has been completely decoded... | |
3268 } | |
3269 | |
3270 } else if (message.getMethod() == "openadditional") { | |
3271 | |
3272 if (message.getArgCount() == 1 && | |
3273 message.getArg(0).canConvert(QVariant::String)) { | |
3274 QString path = message.getArg(0).toString(); | |
3275 if (open(path, CreateAdditionalModel) != FileOpenSucceeded) { | |
3276 std::cerr << "MainWindow::handleOSCMessage: File open failed for path \"" | |
3277 << path.toStdString() << "\"" << std::endl; | |
3278 } | |
3279 } | |
3280 | |
3281 } else if (message.getMethod() == "recent" || | |
3282 message.getMethod() == "last") { | |
3283 | |
3284 int n = 0; | |
3285 if (message.getMethod() == "recent" && | |
3286 message.getArgCount() == 1 && | |
3287 message.getArg(0).canConvert(QVariant::Int)) { | |
3288 n = message.getArg(0).toInt() - 1; | |
3289 } | |
3290 std::vector<QString> recent = m_recentFiles.getRecent(); | |
3291 if (n >= 0 && n < int(recent.size())) { | |
3292 if (open(recent[n], ReplaceMainModel) != FileOpenSucceeded) { | |
3293 std::cerr << "MainWindow::handleOSCMessage: File open failed for path \"" | |
3294 << recent[n].toStdString() << "\"" << std::endl; | |
3295 } | |
3296 } | |
3297 | |
3298 } else if (message.getMethod() == "save") { | |
3299 | |
3300 QString path; | |
3301 if (message.getArgCount() == 1 && | |
3302 message.getArg(0).canConvert(QVariant::String)) { | |
3303 path = message.getArg(0).toString(); | |
3304 if (QFileInfo(path).exists()) { | |
3305 std::cerr << "MainWindow::handleOSCMessage: Refusing to overwrite existing file in save" << std::endl; | |
3306 } else { | |
3307 saveSessionFile(path); | |
3308 } | |
3309 } | |
3310 | |
3311 } else if (message.getMethod() == "export") { | |
3312 | |
3313 QString path; | |
3314 if (getMainModel()) { | |
3315 if (message.getArgCount() == 1 && | |
3316 message.getArg(0).canConvert(QVariant::String)) { | |
3317 path = message.getArg(0).toString(); | |
3318 if (QFileInfo(path).exists()) { | |
3319 std::cerr << "MainWindow::handleOSCMessage: Refusing to overwrite existing file in export" << std::endl; | |
3320 } else { | |
3321 WavFileWriter writer(path, | |
3322 getMainModel()->getSampleRate(), | |
3323 getMainModel()->getChannelCount()); | |
3324 MultiSelection ms = m_viewManager->getSelection(); | |
3325 if (!ms.getSelections().empty()) { | |
3326 writer.writeModel(getMainModel(), &ms); | |
3327 } else { | |
3328 writer.writeModel(getMainModel()); | |
3329 } | |
3330 } | |
3331 } | |
3332 } | |
3333 | |
3334 } else if (message.getMethod() == "jump" || | |
3335 message.getMethod() == "play") { | |
3336 | |
3337 if (getMainModel()) { | |
3338 | |
3339 unsigned long frame = m_viewManager->getPlaybackFrame(); | |
3340 bool selection = false; | |
3341 bool play = (message.getMethod() == "play"); | |
3342 | |
3343 if (message.getArgCount() == 1) { | |
3344 | |
3345 if (message.getArg(0).canConvert(QVariant::String) && | |
3346 message.getArg(0).toString() == "selection") { | |
3347 | |
3348 selection = true; | |
3349 | |
3350 } else if (message.getArg(0).canConvert(QVariant::String) && | |
3351 message.getArg(0).toString() == "end") { | |
3352 | |
3353 frame = getMainModel()->getEndFrame(); | |
3354 | |
3355 } else if (message.getArg(0).canConvert(QVariant::Double)) { | |
3356 | |
3357 double time = message.getArg(0).toDouble(); | |
3358 if (time < 0.0) time = 0.0; | |
3359 | |
3360 frame = lrint(time * getMainModel()->getSampleRate()); | |
3361 } | |
3362 } | |
3363 | |
3364 if (frame > getMainModel()->getEndFrame()) { | |
3365 frame = getMainModel()->getEndFrame(); | |
3366 } | |
3367 | |
3368 if (play) { | |
3369 m_viewManager->setPlaySelectionMode(selection); | |
3370 } | |
3371 | |
3372 if (selection) { | |
3373 MultiSelection::SelectionList sl = m_viewManager->getSelections(); | |
3374 if (!sl.empty()) { | |
3375 frame = sl.begin()->getStartFrame(); | |
3376 } | |
3377 } | |
3378 | |
3379 m_viewManager->setPlaybackFrame(frame); | |
3380 | |
3381 if (play && !m_playSource->isPlaying()) { | |
3382 m_playSource->play(frame); | |
3383 } | |
3384 } | |
3385 | |
3386 } else if (message.getMethod() == "stop") { | |
3387 | |
3388 if (m_playSource->isPlaying()) m_playSource->stop(); | |
3389 | |
3390 } else if (message.getMethod() == "loop") { | |
3391 | |
3392 if (message.getArgCount() == 1 && | |
3393 message.getArg(0).canConvert(QVariant::String)) { | |
3394 | |
3395 QString str = message.getArg(0).toString(); | |
3396 if (str == "on") { | |
3397 m_viewManager->setPlayLoopMode(true); | |
3398 } else if (str == "off") { | |
3399 m_viewManager->setPlayLoopMode(false); | |
3400 } | |
3401 } | |
3402 | |
3403 } else if (message.getMethod() == "solo") { | |
3404 | |
3405 if (message.getArgCount() == 1 && | |
3406 message.getArg(0).canConvert(QVariant::String)) { | |
3407 | |
3408 QString str = message.getArg(0).toString(); | |
3409 if (str == "on") { | |
3410 m_viewManager->setPlaySoloMode(true); | |
3411 } else if (str == "off") { | |
3412 m_viewManager->setPlaySoloMode(false); | |
3413 } | |
3414 } | |
3415 | |
3416 } else if (message.getMethod() == "select" || | |
3417 message.getMethod() == "addselect") { | |
3418 | |
3419 if (getMainModel()) { | |
3420 | |
3421 int f0 = getMainModel()->getStartFrame(); | |
3422 int f1 = getMainModel()->getEndFrame(); | |
3423 | |
3424 bool done = false; | |
3425 | |
3426 if (message.getArgCount() == 2 && | |
3427 message.getArg(0).canConvert(QVariant::Double) && | |
3428 message.getArg(1).canConvert(QVariant::Double)) { | |
3429 | |
3430 double t0 = message.getArg(0).toDouble(); | |
3431 double t1 = message.getArg(1).toDouble(); | |
3432 if (t1 < t0) { double temp = t0; t0 = t1; t1 = temp; } | |
3433 if (t0 < 0.0) t0 = 0.0; | |
3434 if (t1 < 0.0) t1 = 0.0; | |
3435 | |
3436 f0 = lrint(t0 * getMainModel()->getSampleRate()); | |
3437 f1 = lrint(t1 * getMainModel()->getSampleRate()); | |
3438 | |
3439 Pane *pane = m_paneStack->getCurrentPane(); | |
3440 Layer *layer = 0; | |
3441 if (pane) layer = pane->getSelectedLayer(); | |
3442 if (layer) { | |
3443 size_t resolution; | |
3444 layer->snapToFeatureFrame(pane, f0, resolution, | |
3445 Layer::SnapLeft); | |
3446 layer->snapToFeatureFrame(pane, f1, resolution, | |
3447 Layer::SnapRight); | |
3448 } | |
3449 | |
3450 } else if (message.getArgCount() == 1 && | |
3451 message.getArg(0).canConvert(QVariant::String)) { | |
3452 | |
3453 QString str = message.getArg(0).toString(); | |
3454 if (str == "none") { | |
3455 m_viewManager->clearSelections(); | |
3456 done = true; | |
3457 } | |
3458 } | |
3459 | |
3460 if (!done) { | |
3461 if (message.getMethod() == "select") { | |
3462 m_viewManager->setSelection(Selection(f0, f1)); | |
3463 } else { | |
3464 m_viewManager->addSelection(Selection(f0, f1)); | |
3465 } | |
3466 } | |
3467 } | |
3468 | |
3469 } else if (message.getMethod() == "add") { | |
3470 | |
3471 if (getMainModel()) { | |
3472 | |
3473 if (message.getArgCount() >= 1 && | |
3474 message.getArg(0).canConvert(QVariant::String)) { | |
3475 | |
3476 int channel = -1; | |
3477 if (message.getArgCount() == 2 && | |
3478 message.getArg(0).canConvert(QVariant::Int)) { | |
3479 channel = message.getArg(0).toInt(); | |
3480 if (channel < -1 || | |
3481 channel > int(getMainModel()->getChannelCount())) { | |
3482 std::cerr << "WARNING: MainWindow::handleOSCMessage: channel " | |
3483 << channel << " out of range" << std::endl; | |
3484 channel = -1; | |
3485 } | |
3486 } | |
3487 | |
3488 QString str = message.getArg(0).toString(); | |
3489 | |
3490 LayerFactory::LayerType type = | |
3491 LayerFactory::getInstance()->getLayerTypeForName(str); | |
3492 | |
3493 if (type == LayerFactory::UnknownLayer) { | |
3494 std::cerr << "WARNING: MainWindow::handleOSCMessage: unknown layer " | |
3495 << "type " << str.toStdString() << std::endl; | |
3496 } else { | |
3497 | |
3498 PaneConfiguration configuration(type, | |
3499 getMainModel(), | |
3500 channel); | |
3501 | |
3502 addPane(configuration, | |
3503 tr("Add %1 Pane") | |
3504 .arg(LayerFactory::getInstance()-> | |
3505 getLayerPresentationName(type))); | |
3506 } | |
3507 } | |
3508 } | |
3509 | |
3510 } else if (message.getMethod() == "undo") { | |
3511 | |
3512 CommandHistory::getInstance()->undo(); | |
3513 | |
3514 } else if (message.getMethod() == "redo") { | |
3515 | |
3516 CommandHistory::getInstance()->redo(); | |
3517 | |
3518 } else if (message.getMethod() == "set") { | |
3519 | |
3520 if (message.getArgCount() == 2 && | |
3521 message.getArg(0).canConvert(QVariant::String) && | |
3522 message.getArg(1).canConvert(QVariant::Double)) { | |
3523 | |
3524 QString property = message.getArg(0).toString(); | |
3525 float value = (float)message.getArg(1).toDouble(); | |
3526 | |
3527 if (property == "gain") { | |
3528 if (value < 0.0) value = 0.0; | |
3529 m_fader->setValue(value); | |
3530 if (m_playTarget) m_playTarget->setOutputGain(value); | |
3531 } else if (property == "speedup") { | |
3532 m_playSpeed->setMappedValue(value); | |
3533 } else if (property == "overlays") { | |
3534 if (value < 0.5) { | |
3535 m_viewManager->setOverlayMode(ViewManager::NoOverlays); | |
3536 } else if (value < 1.5) { | |
3537 m_viewManager->setOverlayMode(ViewManager::MinimalOverlays); | |
3538 } else if (value < 2.5) { | |
3539 m_viewManager->setOverlayMode(ViewManager::StandardOverlays); | |
3540 } else { | |
3541 m_viewManager->setOverlayMode(ViewManager::AllOverlays); | |
3542 } | |
3543 } else if (property == "zoomwheels") { | |
3544 m_viewManager->setZoomWheelsEnabled(value > 0.5); | |
3545 } else if (property == "propertyboxes") { | |
3546 bool toggle = ((value < 0.5) != | |
3547 (m_paneStack->getLayoutStyle() == PaneStack::NoPropertyStacks)); | |
3548 if (toggle) togglePropertyBoxes(); | |
3549 } | |
3550 | |
3551 } else { | |
3552 PropertyContainer *container = 0; | |
3553 Pane *pane = m_paneStack->getCurrentPane(); | |
3554 if (pane && | |
3555 message.getArgCount() == 3 && | |
3556 message.getArg(0).canConvert(QVariant::String) && | |
3557 message.getArg(1).canConvert(QVariant::String) && | |
3558 message.getArg(2).canConvert(QVariant::String)) { | |
3559 if (message.getArg(0).toString() == "pane") { | |
3560 container = pane->getPropertyContainer(0); | |
3561 } else if (message.getArg(0).toString() == "layer") { | |
3562 container = pane->getSelectedLayer(); | |
3563 } | |
3564 } | |
3565 if (container) { | |
3566 QString nameString = message.getArg(1).toString(); | |
3567 QString valueString = message.getArg(2).toString(); | |
3568 container->setPropertyWithCommand(nameString, valueString); | |
3569 } | |
3570 } | |
3571 | |
3572 } else if (message.getMethod() == "setcurrent") { | |
3573 | |
3574 int paneIndex = -1, layerIndex = -1; | |
3575 bool wantLayer = false; | |
3576 | |
3577 if (message.getArgCount() >= 1 && | |
3578 message.getArg(0).canConvert(QVariant::Int)) { | |
3579 | |
3580 paneIndex = message.getArg(0).toInt() - 1; | |
3581 | |
3582 if (message.getArgCount() >= 2 && | |
3583 message.getArg(1).canConvert(QVariant::Int)) { | |
3584 wantLayer = true; | |
3585 layerIndex = message.getArg(1).toInt() - 1; | |
3586 } | |
3587 } | |
3588 | |
3589 if (paneIndex >= 0 && paneIndex < m_paneStack->getPaneCount()) { | |
3590 Pane *pane = m_paneStack->getPane(paneIndex); | |
3591 m_paneStack->setCurrentPane(pane); | |
3592 if (layerIndex >= 0 && layerIndex < pane->getLayerCount()) { | |
3593 Layer *layer = pane->getLayer(layerIndex); | |
3594 m_paneStack->setCurrentLayer(pane, layer); | |
3595 } else if (wantLayer && layerIndex == -1) { | |
3596 m_paneStack->setCurrentLayer(pane, 0); | |
3597 } | |
3598 } | |
3599 | |
3600 } else if (message.getMethod() == "delete") { | |
3601 | |
3602 if (message.getArgCount() == 1 && | |
3603 message.getArg(0).canConvert(QVariant::String)) { | |
3604 | |
3605 QString target = message.getArg(0).toString(); | |
3606 | |
3607 if (target == "pane") { | |
3608 | |
3609 deleteCurrentPane(); | |
3610 | |
3611 } else if (target == "layer") { | |
3612 | |
3613 deleteCurrentLayer(); | |
3614 | |
3615 } else { | |
3616 | |
3617 std::cerr << "WARNING: MainWindow::handleOSCMessage: Unknown delete target " << target.toStdString() << std::endl; | |
3618 } | |
3619 } | |
3620 | |
3621 } else if (message.getMethod() == "zoom") { | |
3622 | |
3623 if (message.getArgCount() == 1) { | |
3624 if (message.getArg(0).canConvert(QVariant::String) && | |
3625 message.getArg(0).toString() == "in") { | |
3626 zoomIn(); | |
3627 } else if (message.getArg(0).canConvert(QVariant::String) && | |
3628 message.getArg(0).toString() == "out") { | |
3629 zoomOut(); | |
3630 } else if (message.getArg(0).canConvert(QVariant::String) && | |
3631 message.getArg(0).toString() == "default") { | |
3632 zoomDefault(); | |
3633 } else if (message.getArg(0).canConvert(QVariant::Double)) { | |
3634 double level = message.getArg(0).toDouble(); | |
3635 Pane *currentPane = m_paneStack->getCurrentPane(); | |
3636 if (level < 1.0) level = 1.0; | |
3637 if (currentPane) currentPane->setZoomLevel(lrint(level)); | |
3638 } | |
3639 } | |
3640 | |
3641 } else if (message.getMethod() == "zoomvertical") { | |
3642 | |
3643 Pane *pane = m_paneStack->getCurrentPane(); | |
3644 Layer *layer = 0; | |
3645 if (pane && pane->getLayerCount() > 0) { | |
3646 layer = pane->getLayer(pane->getLayerCount() - 1); | |
3647 } | |
3648 int defaultStep = 0; | |
3649 int steps = 0; | |
3650 if (layer) { | |
3651 steps = layer->getVerticalZoomSteps(defaultStep); | |
3652 if (message.getArgCount() == 1 && steps > 0) { | |
3653 if (message.getArg(0).canConvert(QVariant::String) && | |
3654 message.getArg(0).toString() == "in") { | |
3655 int step = layer->getCurrentVerticalZoomStep() + 1; | |
3656 if (step < steps) layer->setVerticalZoomStep(step); | |
3657 } else if (message.getArg(0).canConvert(QVariant::String) && | |
3658 message.getArg(0).toString() == "out") { | |
3659 int step = layer->getCurrentVerticalZoomStep() - 1; | |
3660 if (step >= 0) layer->setVerticalZoomStep(step); | |
3661 } else if (message.getArg(0).canConvert(QVariant::String) && | |
3662 message.getArg(0).toString() == "default") { | |
3663 layer->setVerticalZoomStep(defaultStep); | |
3664 } | |
3665 } else if (message.getArgCount() == 2) { | |
3666 if (message.getArg(0).canConvert(QVariant::Double) && | |
3667 message.getArg(1).canConvert(QVariant::Double)) { | |
3668 double min = message.getArg(0).toDouble(); | |
3669 double max = message.getArg(1).toDouble(); | |
3670 layer->setDisplayExtents(min, max); | |
3671 } | |
3672 } | |
3673 } | |
3674 | |
3675 } else if (message.getMethod() == "quit") { | |
3676 | |
3677 m_abandoning = true; | |
3678 close(); | |
3679 | |
3680 } else if (message.getMethod() == "resize") { | |
3681 | |
3682 if (message.getArgCount() == 2) { | |
3683 | |
3684 int width = 0, height = 0; | |
3685 | |
3686 if (message.getArg(1).canConvert(QVariant::Int)) { | |
3687 | |
3688 height = message.getArg(1).toInt(); | |
3689 | |
3690 if (message.getArg(0).canConvert(QVariant::String) && | |
3691 message.getArg(0).toString() == "pane") { | |
3692 | |
3693 Pane *pane = m_paneStack->getCurrentPane(); | |
3694 if (pane) pane->resize(pane->width(), height); | |
3695 | |
3696 } else if (message.getArg(0).canConvert(QVariant::Int)) { | |
3697 | |
3698 width = message.getArg(0).toInt(); | |
3699 resize(width, height); | |
3700 } | |
3701 } | |
3702 } | |
3703 | |
3704 } else if (message.getMethod() == "transform") { | |
3705 | |
3706 Pane *pane = m_paneStack->getCurrentPane(); | |
3707 | |
3708 if (getMainModel() && | |
3709 pane && | |
3710 message.getArgCount() == 1 && | |
3711 message.getArg(0).canConvert(QVariant::String)) { | |
3712 | |
3713 TransformId transform = message.getArg(0).toString(); | |
3714 | |
3715 Layer *newLayer = m_document->createDerivedLayer | |
3716 (transform, | |
3717 getMainModel(), | |
3718 ModelTransformerFactory::getInstance()->getDefaultContextForTransformer | |
3719 (transform, getMainModel()), | |
3720 ""); | |
3721 | |
3722 if (newLayer) { | |
3723 m_document->addLayerToView(pane, newLayer); | |
3724 m_recentTransforms.add(transform); | |
3725 m_paneStack->setCurrentLayer(pane, newLayer); | |
3726 } | |
3727 } | |
3728 | |
3729 } else { | |
3730 std::cerr << "WARNING: MainWindow::handleOSCMessage: Unknown or unsupported " | |
3731 << "method \"" << message.getMethod().toStdString() | |
3732 << "\"" << std::endl; | |
3733 } | |
3734 | |
3735 } | 3388 } |
3736 | 3389 |
3737 void | 3390 void |
3738 MainWindow::preferences() | 3391 MainWindow::preferences() |
3739 { | 3392 { |
3764 | 3417 |
3765 if (w == m_fader) { | 3418 if (w == m_fader) { |
3766 contextHelpChanged(tr("Adjust the master playback level")); | 3419 contextHelpChanged(tr("Adjust the master playback level")); |
3767 } else if (w == m_playSpeed) { | 3420 } else if (w == m_playSpeed) { |
3768 contextHelpChanged(tr("Adjust the master playback speed")); | 3421 contextHelpChanged(tr("Adjust the master playback speed")); |
3769 } else if (w == m_playSharpen && w->isEnabled()) { | |
3770 contextHelpChanged(tr("Toggle transient sharpening for playback time scaling")); | |
3771 } else if (w == m_playMono && w->isEnabled()) { | |
3772 contextHelpChanged(tr("Toggle mono mode for playback time scaling")); | |
3773 } | 3422 } |
3774 } | 3423 } |
3775 | 3424 |
3776 void | 3425 void |
3777 MainWindow::mouseLeftWidget() | 3426 MainWindow::mouseLeftWidget() |
3786 } | 3435 } |
3787 | 3436 |
3788 void | 3437 void |
3789 MainWindow::help() | 3438 MainWindow::help() |
3790 { | 3439 { |
3791 openHelpUrl(tr("http://www.sonicvisualiser.org/doc/reference/1.0/en/")); | 3440 openHelpUrl(tr("http://www.sonicvisualiser.org/doc/reference/1.2/en/")); |
3792 } | 3441 } |
3793 | 3442 |
3794 void | 3443 void |
3795 MainWindow::about() | 3444 MainWindow::about() |
3796 { | 3445 { |
3813 #endif | 3462 #endif |
3814 | 3463 |
3815 QString aboutText; | 3464 QString aboutText; |
3816 | 3465 |
3817 aboutText += tr("<h3>About Sonic Visualiser</h3>"); | 3466 aboutText += tr("<h3>About Sonic Visualiser</h3>"); |
3818 aboutText += tr("<p>Sonic Visualiser is a program for viewing and exploring audio data for<br>semantic music analysis and annotation.</p>"); | 3467 aboutText += tr("<p>Sonic Visualiser is a program for viewing and exploring audio data for semantic music analysis and annotation.</p>"); |
3819 aboutText += tr("<p>%1 : %2 configuration</p>") | 3468 aboutText += tr("<p>%1 : %2 configuration</p>") |
3820 .arg(version) | 3469 .arg(version) |
3821 .arg(debug ? tr("Debug") : tr("Release")); | 3470 .arg(debug ? tr("Debug") : tr("Release")); |
3822 | 3471 |
3823 #ifndef BUILD_STATIC | 3472 #ifndef BUILD_STATIC |
3895 #endif | 3544 #endif |
3896 aboutText += "</p>"; | 3545 aboutText += "</p>"; |
3897 #endif | 3546 #endif |
3898 | 3547 |
3899 aboutText += | 3548 aboutText += |
3900 "<p>Sonic Visualiser Copyright © 2005 - 2007 Chris Cannam and<br>" | 3549 "<p>Sonic Visualiser Copyright © 2005 - 2008 Chris Cannam and " |
3901 "Queen Mary, University of London.</p>" | 3550 "Queen Mary, University of London.</p>" |
3902 "<p>This program is free software; you can redistribute it and/or<br>" | 3551 "<p>This program is free software; you can redistribute it and/or " |
3903 "modify it under the terms of the GNU General Public License as<br>" | 3552 "modify it under the terms of the GNU General Public License as " |
3904 "published by the Free Software Foundation; either version 2 of the<br>" | 3553 "published by the Free Software Foundation; either version 2 of the " |
3905 "License, or (at your option) any later version.<br>See the file " | 3554 "License, or (at your option) any later version.<br>See the file " |
3906 "COPYING included with this distribution for more information.</p>"; | 3555 "COPYING included with this distribution for more information.</p>"; |
3907 | 3556 |
3908 QMessageBox::about(this, tr("About Sonic Visualiser"), aboutText); | 3557 QMessageBox::about(this, tr("About Sonic Visualiser"), aboutText); |
3909 } | 3558 } |