Mercurial > hg > svapp
comparison framework/MainWindowBase.cpp @ 515:51befd6165a3 alignment-simple
Merge in from SV 3.0-integration branches
author | Chris Cannam |
---|---|
date | Wed, 02 Mar 2016 17:25:27 +0000 |
parents | 74d575708e06 68ab0fe3bce4 |
children | b926f08909b8 |
comparison
equal
deleted
inserted
replaced
459:74d575708e06 | 515:51befd6165a3 |
---|---|
14 */ | 14 */ |
15 | 15 |
16 #include "MainWindowBase.h" | 16 #include "MainWindowBase.h" |
17 #include "Document.h" | 17 #include "Document.h" |
18 | 18 |
19 | |
20 #include "view/Pane.h" | 19 #include "view/Pane.h" |
21 #include "view/PaneStack.h" | 20 #include "view/PaneStack.h" |
22 #include "data/model/WaveFileModel.h" | 21 #include "data/model/ReadOnlyWaveFileModel.h" |
22 #include "data/model/WritableWaveFileModel.h" | |
23 #include "data/model/SparseOneDimensionalModel.h" | 23 #include "data/model/SparseOneDimensionalModel.h" |
24 #include "data/model/NoteModel.h" | 24 #include "data/model/NoteModel.h" |
25 #include "data/model/FlexiNoteModel.h" | 25 #include "data/model/FlexiNoteModel.h" |
26 #include "data/model/Labeller.h" | 26 #include "data/model/Labeller.h" |
27 #include "data/model/TabularModel.h" | 27 #include "data/model/TabularModel.h" |
45 #include "widgets/MIDIFileImportDialog.h" | 45 #include "widgets/MIDIFileImportDialog.h" |
46 #include "widgets/CSVFormatDialog.h" | 46 #include "widgets/CSVFormatDialog.h" |
47 #include "widgets/ModelDataTableDialog.h" | 47 #include "widgets/ModelDataTableDialog.h" |
48 #include "widgets/InteractiveFileFinder.h" | 48 #include "widgets/InteractiveFileFinder.h" |
49 | 49 |
50 #include "audioio/AudioCallbackPlaySource.h" | 50 #include "audio/AudioCallbackPlaySource.h" |
51 #include "audioio/AudioCallbackPlayTarget.h" | 51 #include "audio/AudioRecordTarget.h" |
52 #include "audioio/AudioTargetFactory.h" | 52 #include "audio/PlaySpeedRangeMapper.h" |
53 #include "audioio/PlaySpeedRangeMapper.h" | 53 |
54 #include "data/fileio/DataFileReaderFactory.h" | 54 #include "data/fileio/DataFileReaderFactory.h" |
55 #include "data/fileio/PlaylistFileReader.h" | 55 #include "data/fileio/PlaylistFileReader.h" |
56 #include "data/fileio/WavFileWriter.h" | 56 #include "data/fileio/WavFileWriter.h" |
57 #include "data/fileio/MIDIFileWriter.h" | 57 #include "data/fileio/MIDIFileWriter.h" |
58 #include "data/fileio/BZipFileDevice.h" | 58 #include "data/fileio/BZipFileDevice.h" |
70 #include "base/Exceptions.h" | 70 #include "base/Exceptions.h" |
71 #include "base/ResourceFinder.h" | 71 #include "base/ResourceFinder.h" |
72 | 72 |
73 #include "data/osc/OSCQueue.h" | 73 #include "data/osc/OSCQueue.h" |
74 #include "data/midi/MIDIInput.h" | 74 #include "data/midi/MIDIInput.h" |
75 | |
76 #include <bqaudioio/SystemPlaybackTarget.h> | |
77 #include <bqaudioio/SystemAudioIO.h> | |
78 #include <bqaudioio/AudioFactory.h> | |
75 | 79 |
76 #include <QApplication> | 80 #include <QApplication> |
77 #include <QMessageBox> | 81 #include <QMessageBox> |
78 #include <QGridLayout> | 82 #include <QGridLayout> |
79 #include <QLabel> | 83 #include <QLabel> |
127 return 0; | 131 return 0; |
128 } | 132 } |
129 #undef Window | 133 #undef Window |
130 #endif | 134 #endif |
131 | 135 |
132 MainWindowBase::MainWindowBase(bool withAudioOutput, | 136 MainWindowBase::MainWindowBase(SoundOptions options) : |
133 bool withMIDIInput) : | |
134 m_document(0), | 137 m_document(0), |
135 m_paneStack(0), | 138 m_paneStack(0), |
136 m_viewManager(0), | 139 m_viewManager(0), |
137 m_timeRulerLayer(0), | 140 m_timeRulerLayer(0), |
138 m_audioOutput(withAudioOutput), | 141 m_soundOptions(options), |
139 m_playSource(0), | 142 m_playSource(0), |
143 m_recordTarget(0), | |
140 m_playTarget(0), | 144 m_playTarget(0), |
145 m_audioIO(0), | |
141 m_oscQueue(0), | 146 m_oscQueue(0), |
142 m_oscQueueStarter(0), | 147 m_oscQueueStarter(0), |
143 m_midiInput(0), | 148 m_midiInput(0), |
144 m_recentFiles("RecentFiles", 20), | 149 m_recentFiles("RecentFiles", 20), |
145 m_recentTransforms("RecentTransforms", 20), | 150 m_recentTransforms("RecentTransforms", 20), |
148 m_abandoning(false), | 153 m_abandoning(false), |
149 m_labeller(0), | 154 m_labeller(0), |
150 m_lastPlayStatusSec(0), | 155 m_lastPlayStatusSec(0), |
151 m_initialDarkBackground(false), | 156 m_initialDarkBackground(false), |
152 m_defaultFfwdRwdStep(2, 0), | 157 m_defaultFfwdRwdStep(2, 0), |
158 m_audioRecordMode(RecordCreateAdditionalModel), | |
153 m_statusLabel(0), | 159 m_statusLabel(0), |
154 m_iconsVisibleInMenus(true), | 160 m_iconsVisibleInMenus(true), |
155 m_menuShortcutMapper(0) | 161 m_menuShortcutMapper(0) |
156 { | 162 { |
157 Profiler profiler("MainWindowBase::MainWindowBase"); | 163 Profiler profiler("MainWindowBase::MainWindowBase"); |
158 | 164 |
165 if (options & WithAudioInput) { | |
166 if (!(options & WithAudioOutput)) { | |
167 cerr << "WARNING: MainWindowBase: WithAudioInput requires WithAudioOutput -- recording will not work" << endl; | |
168 } | |
169 } | |
170 | |
159 qRegisterMetaType<sv_frame_t>("sv_frame_t"); | 171 qRegisterMetaType<sv_frame_t>("sv_frame_t"); |
160 qRegisterMetaType<sv_samplerate_t>("sv_samplerate_t"); | 172 qRegisterMetaType<sv_samplerate_t>("sv_samplerate_t"); |
161 | 173 |
162 #ifdef Q_WS_X11 | 174 #ifdef Q_WS_X11 |
163 XSetErrorHandler(handle_x11_error); | 175 XSetErrorHandler(handle_x11_error); |
183 settings.beginGroup("Preferences"); | 195 settings.beginGroup("Preferences"); |
184 viewFontSize = settings.value("view-font-size", viewFontSize).toInt(); | 196 viewFontSize = settings.value("view-font-size", viewFontSize).toInt(); |
185 settings.setValue("view-font-size", viewFontSize); | 197 settings.setValue("view-font-size", viewFontSize); |
186 settings.endGroup(); | 198 settings.endGroup(); |
187 | 199 |
200 #ifdef NOT_DEFINED // This no longer works correctly on any platform AFAICS | |
188 Preferences::BackgroundMode mode = | 201 Preferences::BackgroundMode mode = |
189 Preferences::getInstance()->getBackgroundMode(); | 202 Preferences::getInstance()->getBackgroundMode(); |
190 m_initialDarkBackground = m_viewManager->getGlobalDarkBackground(); | 203 m_initialDarkBackground = m_viewManager->getGlobalDarkBackground(); |
191 if (mode != Preferences::BackgroundFromTheme) { | 204 if (mode != Preferences::BackgroundFromTheme) { |
192 m_viewManager->setGlobalDarkBackground | 205 m_viewManager->setGlobalDarkBackground |
193 (mode == Preferences::DarkBackground); | 206 (mode == Preferences::DarkBackground); |
194 } | 207 } |
208 #endif | |
195 | 209 |
196 m_paneStack = new PaneStack(0, m_viewManager); | 210 m_paneStack = new PaneStack(0, m_viewManager); |
197 connect(m_paneStack, SIGNAL(currentPaneChanged(Pane *)), | 211 connect(m_paneStack, SIGNAL(currentPaneChanged(Pane *)), |
198 this, SLOT(currentPaneChanged(Pane *))); | 212 this, SLOT(currentPaneChanged(Pane *))); |
199 connect(m_paneStack, SIGNAL(currentLayerChanged(Pane *, Layer *)), | 213 connect(m_paneStack, SIGNAL(currentLayerChanged(Pane *, Layer *)), |
215 connect(m_paneStack, SIGNAL(paneDeleteButtonClicked(Pane *)), | 229 connect(m_paneStack, SIGNAL(paneDeleteButtonClicked(Pane *)), |
216 this, SLOT(paneDeleteButtonClicked(Pane *))); | 230 this, SLOT(paneDeleteButtonClicked(Pane *))); |
217 | 231 |
218 m_playSource = new AudioCallbackPlaySource(m_viewManager, | 232 m_playSource = new AudioCallbackPlaySource(m_viewManager, |
219 QApplication::applicationName()); | 233 QApplication::applicationName()); |
234 if (m_soundOptions & WithAudioInput) { | |
235 m_recordTarget = new AudioRecordTarget(m_viewManager, | |
236 QApplication::applicationName()); | |
237 connect(m_recordTarget, SIGNAL(recordDurationChanged(sv_frame_t, sv_samplerate_t)), | |
238 this, SLOT(recordDurationChanged(sv_frame_t, sv_samplerate_t))); | |
239 } | |
220 | 240 |
221 connect(m_playSource, SIGNAL(sampleRateMismatch(sv_samplerate_t, sv_samplerate_t, bool)), | 241 connect(m_playSource, SIGNAL(sampleRateMismatch(sv_samplerate_t, sv_samplerate_t, bool)), |
222 this, SLOT(sampleRateMismatch(sv_samplerate_t, sv_samplerate_t, bool))); | 242 this, SLOT(sampleRateMismatch(sv_samplerate_t, sv_samplerate_t, bool))); |
223 connect(m_playSource, SIGNAL(audioOverloadPluginDisabled()), | 243 connect(m_playSource, SIGNAL(audioOverloadPluginDisabled()), |
224 this, SLOT(audioOverloadPluginDisabled())); | 244 this, SLOT(audioOverloadPluginDisabled())); |
255 settings.endGroup(); | 275 settings.endGroup(); |
256 | 276 |
257 m_labeller = new Labeller(labellerType); | 277 m_labeller = new Labeller(labellerType); |
258 m_labeller->setCounterCycleSize(cycle); | 278 m_labeller->setCounterCycleSize(cycle); |
259 | 279 |
260 if (withMIDIInput) { | 280 if (m_soundOptions & WithMIDIInput) { |
261 m_midiInput = new MIDIInput(QApplication::applicationName(), this); | 281 m_midiInput = new MIDIInput(QApplication::applicationName(), this); |
262 } | 282 } |
263 | 283 |
264 QTimer::singleShot(1500, this, SIGNAL(hideSplash())); | 284 QTimer::singleShot(1500, this, SIGNAL(hideSplash())); |
265 } | 285 } |
266 | 286 |
267 MainWindowBase::~MainWindowBase() | 287 MainWindowBase::~MainWindowBase() |
268 { | 288 { |
269 SVDEBUG << "MainWindowBase::~MainWindowBase" << endl; | 289 SVDEBUG << "MainWindowBase::~MainWindowBase" << endl; |
270 if (m_playTarget) m_playTarget->shutdown(); | 290 delete m_playTarget; |
271 // delete m_playTarget; | |
272 delete m_playSource; | 291 delete m_playSource; |
292 delete m_audioIO; | |
293 delete m_recordTarget; | |
273 delete m_viewManager; | 294 delete m_viewManager; |
274 delete m_oscQueue; | 295 delete m_oscQueue; |
275 delete m_oscQueueStarter; | 296 delete m_oscQueueStarter; |
276 delete m_midiInput; | 297 delete m_midiInput; |
277 Profiles::getInstance()->dump(); | 298 Profiles::getInstance()->dump(); |
549 (haveCurrentPane && | 570 (haveCurrentPane && |
550 (currentLayer != 0)); | 571 (currentLayer != 0)); |
551 bool haveMainModel = | 572 bool haveMainModel = |
552 (getMainModel() != 0); | 573 (getMainModel() != 0); |
553 bool havePlayTarget = | 574 bool havePlayTarget = |
554 (m_playTarget != 0); | 575 (m_playTarget != 0 || m_audioIO != 0); |
555 bool haveSelection = | 576 bool haveSelection = |
556 (m_viewManager && | 577 (m_viewManager && |
557 !m_viewManager->getSelections().empty()); | 578 !m_viewManager->getSelections().empty()); |
558 bool haveCurrentEditableLayer = | 579 bool haveCurrentEditableLayer = |
559 (haveCurrentLayer && | 580 (haveCurrentLayer && |
594 emit canEditLayer(haveCurrentEditableLayer); | 615 emit canEditLayer(haveCurrentEditableLayer); |
595 emit canEditLayerTabular(haveCurrentEditableLayer || haveTabularLayer); | 616 emit canEditLayerTabular(haveCurrentEditableLayer || haveTabularLayer); |
596 emit canMeasureLayer(haveCurrentLayer); | 617 emit canMeasureLayer(haveCurrentLayer); |
597 emit canSelect(haveMainModel && haveCurrentPane); | 618 emit canSelect(haveMainModel && haveCurrentPane); |
598 emit canPlay(haveMainModel && havePlayTarget); | 619 emit canPlay(haveMainModel && havePlayTarget); |
620 emit canRecord(m_recordTarget != 0); | |
599 emit canFfwd(haveMainModel); | 621 emit canFfwd(haveMainModel); |
600 emit canRewind(haveMainModel); | 622 emit canRewind(haveMainModel); |
601 emit canPaste(haveClipboardContents); | 623 emit canPaste(haveClipboardContents); |
602 emit canInsertInstant(haveCurrentPane); | 624 emit canInsertInstant(haveCurrentPane); |
603 emit canInsertInstantsAtBoundaries(haveCurrentPane && haveSelection); | 625 emit canInsertInstantsAtBoundaries(haveCurrentPane && haveSelection); |
1310 rate = Preferences::getInstance()->getFixedSampleRate(); | 1332 rate = Preferences::getInstance()->getFixedSampleRate(); |
1311 } else if (Preferences::getInstance()->getResampleOnLoad()) { | 1333 } else if (Preferences::getInstance()->getResampleOnLoad()) { |
1312 rate = m_playSource->getSourceSampleRate(); | 1334 rate = m_playSource->getSourceSampleRate(); |
1313 } | 1335 } |
1314 | 1336 |
1315 WaveFileModel *newModel = new WaveFileModel(source, rate); | 1337 ReadOnlyWaveFileModel *newModel = new ReadOnlyWaveFileModel(source, rate); |
1316 | 1338 |
1317 if (!newModel->isOK()) { | 1339 if (!newModel->isOK()) { |
1318 delete newModel; | 1340 delete newModel; |
1319 m_openingAudioFile = false; | 1341 m_openingAudioFile = false; |
1320 if (source.wasCancelled()) { | 1342 if (source.wasCancelled()) { |
2202 m_recentFiles.addFile(source.getLocation()); | 2224 m_recentFiles.addFile(source.getLocation()); |
2203 return FileOpenSucceeded; | 2225 return FileOpenSucceeded; |
2204 } | 2226 } |
2205 | 2227 |
2206 void | 2228 void |
2207 MainWindowBase::createPlayTarget() | 2229 MainWindowBase::createAudioIO() |
2208 { | 2230 { |
2209 if (m_playTarget) return; | 2231 if (m_playTarget || m_audioIO) return; |
2210 | 2232 |
2233 if (!(m_soundOptions & WithAudioOutput)) return; | |
2234 | |
2235 //!!! how to handle preferences | |
2236 /* | |
2211 QSettings settings; | 2237 QSettings settings; |
2212 settings.beginGroup("Preferences"); | 2238 settings.beginGroup("Preferences"); |
2213 QString targetName = settings.value("audio-target", "").toString(); | 2239 QString targetName = settings.value("audio-target", "").toString(); |
2214 settings.endGroup(); | 2240 settings.endGroup(); |
2215 | |
2216 AudioTargetFactory *factory = AudioTargetFactory::getInstance(); | 2241 AudioTargetFactory *factory = AudioTargetFactory::getInstance(); |
2217 | 2242 |
2218 factory->setDefaultCallbackTarget(targetName); | 2243 factory->setDefaultCallbackTarget(targetName); |
2219 m_playTarget = factory->createCallbackTarget(m_playSource); | 2244 */ |
2220 | 2245 |
2221 if (!m_playTarget) { | 2246 if (m_soundOptions & WithAudioInput) { |
2247 m_audioIO = breakfastquay::AudioFactory:: | |
2248 createCallbackIO(m_recordTarget, m_playSource); | |
2249 m_audioIO->suspend(); // start in suspended state | |
2250 m_playSource->setSystemPlaybackTarget(m_audioIO); | |
2251 } else { | |
2252 m_playTarget = breakfastquay::AudioFactory:: | |
2253 createCallbackPlayTarget(m_playSource); | |
2254 m_playTarget->suspend(); // start in suspended state | |
2255 m_playSource->setSystemPlaybackTarget(m_playTarget); | |
2256 } | |
2257 | |
2258 if (!m_playTarget && !m_audioIO) { | |
2222 emit hideSplash(); | 2259 emit hideSplash(); |
2223 | 2260 |
2224 if (factory->isAutoCallbackTarget(targetName)) { | 2261 // if (factory->isAutoCallbackTarget(targetName)) { |
2225 QMessageBox::warning | 2262 QMessageBox::warning |
2226 (this, tr("Couldn't open audio device"), | 2263 (this, tr("Couldn't open audio device"), |
2227 tr("<b>No audio available</b><p>Could not open an audio device for playback.<p>Automatic audio device detection failed. Audio playback will not be available during this session.</p>"), | 2264 tr("<b>No audio available</b><p>Could not open an audio device for playback.<p>Automatic audio device detection failed. Audio playback will not be available during this session.</p>"), |
2228 QMessageBox::Ok); | 2265 QMessageBox::Ok); |
2266 /* | |
2229 } else { | 2267 } else { |
2230 QMessageBox::warning | 2268 QMessageBox::warning |
2231 (this, tr("Couldn't open audio device"), | 2269 (this, tr("Couldn't open audio device"), |
2232 tr("<b>No audio available</b><p>Failed to open your preferred audio device (\"%1\").<p>Audio playback will not be available during this session.</p>") | 2270 tr("<b>No audio available</b><p>Failed to open your preferred audio device (\"%1\").<p>Audio playback will not be available during this session.</p>") |
2233 .arg(factory->getCallbackTargetDescription(targetName)), | 2271 .arg(factory->getCallbackTargetDescription(targetName)), |
2234 QMessageBox::Ok); | 2272 QMessageBox::Ok); |
2235 } | 2273 } |
2274 */ | |
2275 return; | |
2236 } | 2276 } |
2237 } | 2277 } |
2238 | 2278 |
2239 WaveFileModel * | 2279 WaveFileModel * |
2240 MainWindowBase::getMainModel() | 2280 MainWindowBase::getMainModel() |
2664 } | 2704 } |
2665 | 2705 |
2666 void | 2706 void |
2667 MainWindowBase::play() | 2707 MainWindowBase::play() |
2668 { | 2708 { |
2669 if (m_playSource->isPlaying()) { | 2709 if (m_recordTarget->isRecording() || m_playSource->isPlaying()) { |
2670 stop(); | 2710 stop(); |
2711 QAction *action = qobject_cast<QAction *>(sender()); | |
2712 if (action) action->setChecked(false); | |
2671 } else { | 2713 } else { |
2714 if (m_audioIO) m_audioIO->resume(); | |
2715 else if (m_playTarget) m_playTarget->resume(); | |
2672 playbackFrameChanged(m_viewManager->getPlaybackFrame()); | 2716 playbackFrameChanged(m_viewManager->getPlaybackFrame()); |
2673 m_playSource->play(m_viewManager->getPlaybackFrame()); | 2717 m_playSource->play(m_viewManager->getPlaybackFrame()); |
2674 } | 2718 } |
2719 } | |
2720 | |
2721 void | |
2722 MainWindowBase::record() | |
2723 { | |
2724 if (!(m_soundOptions & WithAudioInput)) { | |
2725 return; | |
2726 } | |
2727 | |
2728 if (!m_recordTarget) { | |
2729 //!!! report | |
2730 return; | |
2731 } | |
2732 | |
2733 if (!m_audioIO) { | |
2734 createAudioIO(); | |
2735 } | |
2736 | |
2737 if (!m_audioIO) { | |
2738 //!!! report | |
2739 return; | |
2740 } | |
2741 | |
2742 if (m_recordTarget->isRecording()) { | |
2743 stop(); | |
2744 return; | |
2745 } | |
2746 | |
2747 QAction *action = qobject_cast<QAction *>(sender()); | |
2748 | |
2749 if (m_audioRecordMode == RecordReplaceSession) { | |
2750 if (!checkSaveModified()) { | |
2751 if (action) action->setChecked(false); | |
2752 return; | |
2753 } | |
2754 } | |
2755 | |
2756 m_audioIO->resume(); | |
2757 | |
2758 WritableWaveFileModel *model = m_recordTarget->startRecording(); | |
2759 if (!model) { | |
2760 cerr << "ERROR: MainWindowBase::record: Recording failed" << endl; | |
2761 //!!! report | |
2762 if (action) action->setChecked(false); | |
2763 return; | |
2764 } | |
2765 | |
2766 if (!model->isOK()) { | |
2767 m_recordTarget->stopRecording(); | |
2768 m_audioIO->suspend(); | |
2769 delete model; | |
2770 return; | |
2771 } | |
2772 | |
2773 PlayParameterRepository::getInstance()->addPlayable(model); | |
2774 | |
2775 if (m_audioRecordMode == RecordReplaceSession || !getMainModel()) { | |
2776 | |
2777 //!!! duplication with openAudio here | |
2778 | |
2779 QString templateName = getDefaultSessionTemplate(); | |
2780 bool loadedTemplate = false; | |
2781 | |
2782 if (templateName != "") { | |
2783 FileOpenStatus tplStatus = openSessionTemplate(templateName); | |
2784 if (tplStatus == FileOpenCancelled) { | |
2785 m_recordTarget->stopRecording(); | |
2786 m_audioIO->suspend(); | |
2787 PlayParameterRepository::getInstance()->removePlayable(model); | |
2788 return; | |
2789 } | |
2790 if (tplStatus != FileOpenFailed) { | |
2791 loadedTemplate = true; | |
2792 } | |
2793 } | |
2794 | |
2795 if (!loadedTemplate) { | |
2796 closeSession(); | |
2797 createDocument(); | |
2798 } | |
2799 | |
2800 Model *prevMain = getMainModel(); | |
2801 if (prevMain) { | |
2802 m_playSource->removeModel(prevMain); | |
2803 PlayParameterRepository::getInstance()->removePlayable(prevMain); | |
2804 } | |
2805 | |
2806 m_document->setMainModel(model); | |
2807 setupMenus(); | |
2808 | |
2809 if (loadedTemplate || (m_sessionFile == "")) { | |
2810 //!!! shouldn't be dealing directly with title from here -- call a method | |
2811 setWindowTitle(tr("%1: %2") | |
2812 .arg(QApplication::applicationName()) | |
2813 .arg(model->getLocation())); | |
2814 CommandHistory::getInstance()->clear(); | |
2815 CommandHistory::getInstance()->documentSaved(); | |
2816 m_documentModified = false; | |
2817 } else { | |
2818 setWindowTitle(tr("%1: %2 [%3]") | |
2819 .arg(QApplication::applicationName()) | |
2820 .arg(QFileInfo(m_sessionFile).fileName()) | |
2821 .arg(model->getLocation())); | |
2822 if (m_documentModified) { | |
2823 m_documentModified = false; | |
2824 documentModified(); // so as to restore "(modified)" window title | |
2825 } | |
2826 } | |
2827 | |
2828 } else { | |
2829 | |
2830 CommandHistory::getInstance()->startCompoundOperation | |
2831 (tr("Import Recorded Audio"), true); | |
2832 | |
2833 m_document->addImportedModel(model); | |
2834 | |
2835 AddPaneCommand *command = new AddPaneCommand(this); | |
2836 CommandHistory::getInstance()->addCommand(command); | |
2837 | |
2838 Pane *pane = command->getPane(); | |
2839 | |
2840 if (m_timeRulerLayer) { | |
2841 m_document->addLayerToView(pane, m_timeRulerLayer); | |
2842 } | |
2843 | |
2844 Layer *newLayer = m_document->createImportedLayer(model); | |
2845 | |
2846 if (newLayer) { | |
2847 m_document->addLayerToView(pane, newLayer); | |
2848 } | |
2849 | |
2850 CommandHistory::getInstance()->endCompoundOperation(); | |
2851 } | |
2852 | |
2853 updateMenuStates(); | |
2854 m_recentFiles.addFile(model->getLocation()); | |
2855 currentPaneChanged(m_paneStack->getCurrentPane()); | |
2856 | |
2857 emit audioFileLoaded(); | |
2675 } | 2858 } |
2676 | 2859 |
2677 void | 2860 void |
2678 MainWindowBase::ffwd() | 2861 MainWindowBase::ffwd() |
2679 { | 2862 { |
2900 } | 3083 } |
2901 | 3084 |
2902 void | 3085 void |
2903 MainWindowBase::stop() | 3086 MainWindowBase::stop() |
2904 { | 3087 { |
3088 if (m_recordTarget->isRecording()) { | |
3089 m_recordTarget->stopRecording(); | |
3090 } | |
3091 | |
2905 m_playSource->stop(); | 3092 m_playSource->stop(); |
2906 | 3093 |
3094 if (m_audioIO) m_audioIO->suspend(); | |
3095 else if (m_playTarget) m_playTarget->suspend(); | |
3096 | |
2907 if (m_paneStack && m_paneStack->getCurrentPane()) { | 3097 if (m_paneStack && m_paneStack->getCurrentPane()) { |
2908 updateVisibleRangeDisplay(m_paneStack->getCurrentPane()); | 3098 updateVisibleRangeDisplay(m_paneStack->getCurrentPane()); |
2909 } else { | 3099 } else { |
2910 m_myStatusMessage = ""; | 3100 m_myStatusMessage = ""; |
2911 getStatusLabel()->setText(""); | 3101 getStatusLabel()->setText(""); |
3235 remainingStr = (then - now).toText(true).c_str(); | 3425 remainingStr = (then - now).toText(true).c_str(); |
3236 } | 3426 } |
3237 | 3427 |
3238 m_myStatusMessage = tr("Playing: %1 of %2 (%3 remaining)") | 3428 m_myStatusMessage = tr("Playing: %1 of %2 (%3 remaining)") |
3239 .arg(nowStr).arg(thenStr).arg(remainingStr); | 3429 .arg(nowStr).arg(thenStr).arg(remainingStr); |
3430 | |
3431 getStatusLabel()->setText(m_myStatusMessage); | |
3432 } | |
3433 | |
3434 void | |
3435 MainWindowBase::recordDurationChanged(sv_frame_t frame, sv_samplerate_t rate) | |
3436 { | |
3437 RealTime duration = RealTime::frame2RealTime(frame, rate); | |
3438 QString durStr = duration.toSecText().c_str(); | |
3439 | |
3440 m_myStatusMessage = tr("Recording: %1").arg(durStr); | |
3240 | 3441 |
3241 getStatusLabel()->setText(m_myStatusMessage); | 3442 getStatusLabel()->setText(m_myStatusMessage); |
3242 } | 3443 } |
3243 | 3444 |
3244 void | 3445 void |
3370 MainWindowBase::mainModelChanged(WaveFileModel *model) | 3571 MainWindowBase::mainModelChanged(WaveFileModel *model) |
3371 { | 3572 { |
3372 // SVDEBUG << "MainWindowBase::mainModelChanged(" << model << ")" << endl; | 3573 // SVDEBUG << "MainWindowBase::mainModelChanged(" << model << ")" << endl; |
3373 updateDescriptionLabel(); | 3574 updateDescriptionLabel(); |
3374 if (model) m_viewManager->setMainModelSampleRate(model->getSampleRate()); | 3575 if (model) m_viewManager->setMainModelSampleRate(model->getSampleRate()); |
3375 if (model && !m_playTarget && m_audioOutput) { | 3576 if (model && !(m_playTarget || m_audioIO) && |
3376 createPlayTarget(); | 3577 (m_soundOptions & WithAudioOutput)) { |
3578 createAudioIO(); | |
3377 } | 3579 } |
3378 } | 3580 } |
3379 | 3581 |
3380 void | 3582 void |
3381 MainWindowBase::modelAboutToBeDeleted(Model *model) | 3583 MainWindowBase::modelAboutToBeDeleted(Model *model) |
3506 } | 3708 } |
3507 #endif | 3709 #endif |
3508 #endif | 3710 #endif |
3509 } | 3711 } |
3510 | 3712 |
3511 | 3713 void |
3714 MainWindowBase::openLocalFolder(QString path) | |
3715 { | |
3716 QDir d(path); | |
3717 if (d.exists()) { | |
3718 QStringList args; | |
3719 QString path = d.canonicalPath(); | |
3720 #if defined Q_OS_WIN32 | |
3721 // Although the Win32 API is quite happy to have | |
3722 // forward slashes as directory separators, Windows | |
3723 // Explorer is not | |
3724 path = path.replace('/', '\\'); | |
3725 args << path; | |
3726 QProcess::execute("c:/windows/explorer.exe", args); | |
3727 #else | |
3728 args << path; | |
3729 QProcess::execute( | |
3730 #if defined Q_OS_MAC | |
3731 "/usr/bin/open", | |
3732 #else | |
3733 "/usr/bin/xdg-open", | |
3734 #endif | |
3735 args); | |
3736 #endif | |
3737 } | |
3738 } | |
3739 |