Mercurial > hg > sonic-visualiser
comparison main/MainWindow.cpp @ 193:4e030ebb6b36
* Make it possible to drop audio files, layer files, session files and images
onto SV panes.
Need to do a bit more work on where we expect the dropped file to go,
particularly in the case of audio files -- at the moment they're always
opened in new panes, but it may be better to by default replace whatever is
in the target pane.
author | Chris Cannam |
---|---|
date | Wed, 10 Oct 2007 15:18:02 +0000 |
parents | d3477f673fb4 |
children | c851c49c79fe |
comparison
equal
deleted
inserted
replaced
192:d3477f673fb4 | 193:4e030ebb6b36 |
---|---|
32 #include "layer/TimeInstantLayer.h" | 32 #include "layer/TimeInstantLayer.h" |
33 #include "layer/TimeValueLayer.h" | 33 #include "layer/TimeValueLayer.h" |
34 #include "layer/Colour3DPlotLayer.h" | 34 #include "layer/Colour3DPlotLayer.h" |
35 #include "layer/SliceLayer.h" | 35 #include "layer/SliceLayer.h" |
36 #include "layer/SliceableLayer.h" | 36 #include "layer/SliceableLayer.h" |
37 #include "layer/ImageLayer.h" | |
37 #include "widgets/Fader.h" | 38 #include "widgets/Fader.h" |
38 #include "view/Overview.h" | 39 #include "view/Overview.h" |
39 #include "widgets/PropertyBox.h" | 40 #include "widgets/PropertyBox.h" |
40 #include "widgets/PropertyStack.h" | 41 #include "widgets/PropertyStack.h" |
41 #include "widgets/AudioDial.h" | 42 #include "widgets/AudioDial.h" |
209 this, SLOT(rightButtonMenuRequested(Pane *, QPoint))); | 210 this, SLOT(rightButtonMenuRequested(Pane *, QPoint))); |
210 connect(m_paneStack, SIGNAL(propertyStacksResized()), | 211 connect(m_paneStack, SIGNAL(propertyStacksResized()), |
211 this, SLOT(propertyStacksResized())); | 212 this, SLOT(propertyStacksResized())); |
212 connect(m_paneStack, SIGNAL(contextHelpChanged(const QString &)), | 213 connect(m_paneStack, SIGNAL(contextHelpChanged(const QString &)), |
213 this, SLOT(contextHelpChanged(const QString &))); | 214 this, SLOT(contextHelpChanged(const QString &))); |
215 connect(m_paneStack, SIGNAL(dropAccepted(Pane *, QStringList)), | |
216 this, SLOT(paneDropAccepted(Pane *, QStringList))); | |
217 connect(m_paneStack, SIGNAL(dropAccepted(Pane *, QString)), | |
218 this, SLOT(paneDropAccepted(Pane *, QString))); | |
214 | 219 |
215 scroll->setWidget(m_paneStack); | 220 scroll->setWidget(m_paneStack); |
216 | 221 |
217 m_overview = new Overview(frame); | 222 m_overview = new Overview(frame); |
218 m_overview->setViewManager(m_viewManager); | 223 m_overview->setViewManager(m_viewManager); |
2527 QString path = getOpenFileName(FileFinder::AudioFile); | 2532 QString path = getOpenFileName(FileFinder::AudioFile); |
2528 | 2533 |
2529 if (path != "") { | 2534 if (path != "") { |
2530 if (openAudioFile(path, ReplaceMainModel) == FileOpenFailed) { | 2535 if (openAudioFile(path, ReplaceMainModel) == FileOpenFailed) { |
2531 QMessageBox::critical(this, tr("Failed to open file"), | 2536 QMessageBox::critical(this, tr("Failed to open file"), |
2532 tr("Audio file \"%1\" could not be opened").arg(path)); | 2537 tr("<b>File open failed</b><p>Audio file \"%1\" could not be opened").arg(path)); |
2533 } | 2538 } |
2534 } | 2539 } |
2535 } | 2540 } |
2536 | 2541 |
2537 void | 2542 void |
2540 QString path = getOpenFileName(FileFinder::AudioFile); | 2545 QString path = getOpenFileName(FileFinder::AudioFile); |
2541 | 2546 |
2542 if (path != "") { | 2547 if (path != "") { |
2543 if (openAudioFile(path, CreateAdditionalModel) == FileOpenFailed) { | 2548 if (openAudioFile(path, CreateAdditionalModel) == FileOpenFailed) { |
2544 QMessageBox::critical(this, tr("Failed to open file"), | 2549 QMessageBox::critical(this, tr("Failed to open file"), |
2545 tr("Audio file \"%1\" could not be opened").arg(path)); | 2550 tr("<b>File open failed</b><p>Audio file \"%1\" could not be opened").arg(path)); |
2546 } | 2551 } |
2547 } | 2552 } |
2548 } | 2553 } |
2549 | 2554 |
2550 void | 2555 void |
2673 | 2678 |
2674 QString path = getOpenFileName(FileFinder::LayerFile); | 2679 QString path = getOpenFileName(FileFinder::LayerFile); |
2675 | 2680 |
2676 if (path != "") { | 2681 if (path != "") { |
2677 | 2682 |
2678 if (openLayerFile(path) == FileOpenFailed) { | 2683 FileOpenStatus status = openLayerFile(path); |
2684 | |
2685 if (status == FileOpenFailed) { | |
2679 QMessageBox::critical(this, tr("Failed to open file"), | 2686 QMessageBox::critical(this, tr("Failed to open file"), |
2680 tr("File %1 could not be opened.").arg(path)); | 2687 tr("<b>File open failed</b><p>Layer file %1 could not be opened.").arg(path)); |
2681 return; | 2688 return; |
2689 } else if (status == FileOpenWrongMode) { | |
2690 QMessageBox::critical(this, tr("Failed to open file"), | |
2691 tr("<b>Audio required</b><p>Please load at least one audio file before importing annotation data")); | |
2682 } | 2692 } |
2683 } | 2693 } |
2684 } | 2694 } |
2685 | 2695 |
2686 MainWindow::FileOpenStatus | 2696 MainWindow::FileOpenStatus |
2695 Pane *pane = m_paneStack->getCurrentPane(); | 2705 Pane *pane = m_paneStack->getCurrentPane(); |
2696 | 2706 |
2697 if (!pane) { | 2707 if (!pane) { |
2698 // shouldn't happen, as the menu action should have been disabled | 2708 // shouldn't happen, as the menu action should have been disabled |
2699 std::cerr << "WARNING: MainWindow::openLayerFile: no current pane" << std::endl; | 2709 std::cerr << "WARNING: MainWindow::openLayerFile: no current pane" << std::endl; |
2700 return FileOpenFailed; | 2710 return FileOpenWrongMode; |
2701 } | 2711 } |
2702 | 2712 |
2703 if (!getMainModel()) { | 2713 if (!getMainModel()) { |
2704 // shouldn't happen, as the menu action should have been disabled | 2714 // shouldn't happen, as the menu action should have been disabled |
2705 std::cerr << "WARNING: MainWindow::openLayerFile: No main model -- hence no default sample rate available" << std::endl; | 2715 std::cerr << "WARNING: MainWindow::openLayerFile: No main model -- hence no default sample rate available" << std::endl; |
2706 return FileOpenFailed; | 2716 return FileOpenWrongMode; |
2707 } | 2717 } |
2708 | 2718 |
2709 bool realFile = (location == path); | 2719 bool realFile = (location == path); |
2710 | 2720 |
2711 if (path.endsWith(".svl") || path.endsWith(".xml")) { | 2721 if (path.endsWith(".svl") || path.endsWith(".xml")) { |
2742 | 2752 |
2743 return FileOpenSucceeded; | 2753 return FileOpenSucceeded; |
2744 | 2754 |
2745 } else { | 2755 } else { |
2746 | 2756 |
2747 Model *model = DataFileReaderFactory::load(path, getMainModel()->getSampleRate()); | 2757 try { |
2758 | |
2759 Model *model = DataFileReaderFactory::load | |
2760 (path, getMainModel()->getSampleRate()); | |
2748 | 2761 |
2749 if (model) { | 2762 if (model) { |
2750 | 2763 |
2751 Layer *newLayer = m_document->createImportedLayer(model); | 2764 Layer *newLayer = m_document->createImportedLayer(model); |
2752 | 2765 |
2753 if (newLayer) { | 2766 if (newLayer) { |
2754 | 2767 |
2755 m_document->addLayerToView(pane, newLayer); | 2768 m_document->addLayerToView(pane, newLayer); |
2756 m_recentFiles.addFile(location); | 2769 m_recentFiles.addFile(location); |
2757 | 2770 |
2758 if (realFile) { | 2771 if (realFile) { |
2759 registerLastOpenedFilePath(FileFinder::LayerFile, path); // for file dialog | 2772 registerLastOpenedFilePath(FileFinder::LayerFile, path); // for file dialog |
2773 } | |
2774 | |
2775 return FileOpenSucceeded; | |
2760 } | 2776 } |
2761 | |
2762 return FileOpenSucceeded; | |
2763 } | 2777 } |
2778 } catch (DataFileReaderFactory::Exception e) { | |
2779 if (e == DataFileReaderFactory::ImportCancelled) { | |
2780 return FileOpenCancelled; | |
2781 } | |
2764 } | 2782 } |
2765 } | 2783 } |
2766 | 2784 |
2767 return FileOpenFailed; | 2785 return FileOpenFailed; |
2786 } | |
2787 | |
2788 MainWindow::FileOpenStatus | |
2789 MainWindow::openImageFile(QString path) | |
2790 { | |
2791 return openImageFile(path, path); | |
2792 } | |
2793 | |
2794 MainWindow::FileOpenStatus | |
2795 MainWindow::openImageFile(QString path, QString location) | |
2796 { | |
2797 Pane *pane = m_paneStack->getCurrentPane(); | |
2798 | |
2799 if (!pane) { | |
2800 // shouldn't happen, as the menu action should have been disabled | |
2801 std::cerr << "WARNING: MainWindow::openImageFile: no current pane" << std::endl; | |
2802 return FileOpenWrongMode; | |
2803 } | |
2804 | |
2805 if (!m_document->getMainModel()) { | |
2806 return FileOpenWrongMode; | |
2807 } | |
2808 | |
2809 bool newLayer = false; | |
2810 | |
2811 ImageLayer *il = dynamic_cast<ImageLayer *>(pane->getSelectedLayer()); | |
2812 if (!il) { | |
2813 for (int i = pane->getLayerCount()-1; i >= 0; --i) { | |
2814 il = dynamic_cast<ImageLayer *>(pane->getLayer(i)); | |
2815 if (il) break; | |
2816 } | |
2817 } | |
2818 if (!il) { | |
2819 il = dynamic_cast<ImageLayer *> | |
2820 (m_document->createEmptyLayer(LayerFactory::Image)); | |
2821 if (!il) return FileOpenFailed; | |
2822 newLayer = true; | |
2823 } | |
2824 | |
2825 // We don't put the image file in Recent Files | |
2826 | |
2827 std::cerr << "openImageFile: trying location \"" << location.toStdString() << "\" in image layer" << std::endl; | |
2828 | |
2829 if (!il->addImage(m_viewManager->getGlobalCentreFrame(), location)) { | |
2830 if (newLayer) { | |
2831 m_document->setModel(il, 0); // releasing its model | |
2832 delete il; | |
2833 } | |
2834 return FileOpenFailed; | |
2835 } else { | |
2836 if (newLayer) { | |
2837 m_document->addLayerToView(pane, il); | |
2838 } | |
2839 m_paneStack->setCurrentLayer(pane, il); | |
2840 return FileOpenSucceeded; | |
2841 } | |
2768 } | 2842 } |
2769 | 2843 |
2770 void | 2844 void |
2771 MainWindow::exportLayer() | 2845 MainWindow::exportLayer() |
2772 { | 2846 { |
3123 | 3197 |
3124 m_playTarget = AudioTargetFactory::createCallbackTarget(m_playSource); | 3198 m_playTarget = AudioTargetFactory::createCallbackTarget(m_playSource); |
3125 if (!m_playTarget) { | 3199 if (!m_playTarget) { |
3126 QMessageBox::warning | 3200 QMessageBox::warning |
3127 (this, tr("Couldn't open audio device"), | 3201 (this, tr("Couldn't open audio device"), |
3128 tr("Could not open an audio device for playback.\nAudio playback will not be available during this session.\n"), | 3202 tr("<b>No audio available</b><p>Could not open an audio device for playback.<p>Audio playback will not be available during this session."), |
3129 QMessageBox::Ok); | 3203 QMessageBox::Ok); |
3130 } | 3204 } |
3131 connect(m_fader, SIGNAL(valueChanged(float)), | 3205 connect(m_fader, SIGNAL(valueChanged(float)), |
3132 m_playTarget, SLOT(setOutputGain(float))); | 3206 m_playTarget, SLOT(setOutputGain(float))); |
3133 } | 3207 } |
3262 | 3336 |
3263 if (path.isEmpty()) return; | 3337 if (path.isEmpty()) return; |
3264 | 3338 |
3265 if (openSessionFile(path) == FileOpenFailed) { | 3339 if (openSessionFile(path) == FileOpenFailed) { |
3266 QMessageBox::critical(this, tr("Failed to open file"), | 3340 QMessageBox::critical(this, tr("Failed to open file"), |
3267 tr("Session file \"%1\" could not be opened").arg(path)); | 3341 tr("<b>File open failed</b><p>Session file \"%1\" could not be opened").arg(path)); |
3268 } | 3342 } |
3269 } | 3343 } |
3270 | 3344 |
3271 void | 3345 void |
3272 MainWindow::openSomething() | 3346 MainWindow::openSomething() |
3273 { | 3347 { |
3274 QString orig = m_audioFile; | 3348 QString orig = m_audioFile; |
3275 if (orig == "") orig = "."; | 3349 if (orig == "") orig = "."; |
3276 else orig = QFileInfo(orig).absoluteDir().canonicalPath(); | 3350 else orig = QFileInfo(orig).absoluteDir().canonicalPath(); |
3277 | 3351 |
3278 bool canImportLayer = (getMainModel() != 0 && | |
3279 m_paneStack != 0 && | |
3280 m_paneStack->getCurrentPane() != 0); | |
3281 | |
3282 QString path = getOpenFileName(FileFinder::AnyFile); | 3352 QString path = getOpenFileName(FileFinder::AnyFile); |
3283 | 3353 |
3284 if (path.isEmpty()) return; | 3354 if (path.isEmpty()) return; |
3285 | 3355 |
3286 if (path.endsWith(".sv")) { | 3356 FileOpenStatus status = openSomeFile(path, AskUser); |
3287 | 3357 |
3288 if (!checkSaveModified()) return; | 3358 if (status == FileOpenFailed) { |
3289 | 3359 QMessageBox::critical(this, tr("Failed to open file"), |
3290 if (openSessionFile(path) == FileOpenFailed) { | 3360 tr("<b>File open failed</b><p>File \"%1\" could not be opened").arg(path)); |
3291 QMessageBox::critical(this, tr("Failed to open file"), | 3361 } else if (status == FileOpenWrongMode) { |
3292 tr("Session file \"%1\" could not be opened").arg(path)); | 3362 QMessageBox::critical(this, tr("Failed to open file"), |
3293 } | 3363 tr("<b>Audio required</b><p>Please load at least one audio file before importing annotation data")); |
3294 | |
3295 } else { | |
3296 | |
3297 if (openPlaylistFile(path, AskUser) == FileOpenFailed) { | |
3298 | |
3299 if (openAudioFile(path, AskUser) == FileOpenFailed) { | |
3300 | |
3301 if (!canImportLayer || (openLayerFile(path) == FileOpenFailed)) { | |
3302 | |
3303 QMessageBox::critical(this, tr("Failed to open file"), | |
3304 tr("File \"%1\" could not be opened").arg(path)); | |
3305 } | |
3306 } | |
3307 } | |
3308 } | 3364 } |
3309 } | 3365 } |
3310 | 3366 |
3311 void | 3367 void |
3312 MainWindow::openLocation() | 3368 MainWindow::openLocation() |
3325 | 3381 |
3326 settings.setValue("lastremote", text); | 3382 settings.setValue("lastremote", text); |
3327 | 3383 |
3328 if (text.isEmpty()) return; | 3384 if (text.isEmpty()) return; |
3329 | 3385 |
3330 if (openURL(QUrl(text)) == FileOpenFailed) { | 3386 FileOpenStatus status = openURL(QUrl(text)); |
3387 | |
3388 if (status == FileOpenFailed) { | |
3331 QMessageBox::critical(this, tr("Failed to open location"), | 3389 QMessageBox::critical(this, tr("Failed to open location"), |
3332 tr("URL \"%1\" could not be opened").arg(text)); | 3390 tr("<b>Open failed</b><p>URL \"%1\" could not be opened").arg(text)); |
3391 } else if (status == FileOpenWrongMode) { | |
3392 QMessageBox::critical(this, tr("Failed to open location"), | |
3393 tr("<b>Audio required</b><p>Please load at least one audio file before importing annotation data")); | |
3333 } | 3394 } |
3334 } | 3395 } |
3335 | 3396 |
3336 void | 3397 void |
3337 MainWindow::openRecentFile() | 3398 MainWindow::openRecentFile() |
3346 } | 3407 } |
3347 | 3408 |
3348 QString path = action->text(); | 3409 QString path = action->text(); |
3349 if (path == "") return; | 3410 if (path == "") return; |
3350 | 3411 |
3351 QUrl url(path); | 3412 FileOpenStatus status = openURL(path); |
3352 if (RemoteFile::canHandleScheme(url)) { | 3413 |
3353 openURL(url); | 3414 if (status == FileOpenFailed) { |
3354 return; | 3415 QMessageBox::critical(this, tr("Failed to open location"), |
3355 } | 3416 tr("<b>Open failed</b><p>File or URL \"%1\" could not be opened").arg(path)); |
3356 | 3417 } else if (status == FileOpenWrongMode) { |
3357 if (path.endsWith("sv")) { | 3418 QMessageBox::critical(this, tr("Failed to open location"), |
3358 | 3419 tr("<b>Audio required</b><p>Please load at least one audio file before importing annotation data")); |
3359 if (!checkSaveModified()) return; | |
3360 | |
3361 if (openSessionFile(path) == FileOpenFailed) { | |
3362 QMessageBox::critical(this, tr("Failed to open file"), | |
3363 tr("Session file \"%1\" could not be opened").arg(path)); | |
3364 } | |
3365 | |
3366 } else { | |
3367 | |
3368 if (openPlaylistFile(path, AskUser) == FileOpenFailed) { | |
3369 | |
3370 if (openAudioFile(path, AskUser) == FileOpenFailed) { | |
3371 | |
3372 bool canImportLayer = (getMainModel() != 0 && | |
3373 m_paneStack != 0 && | |
3374 m_paneStack->getCurrentPane() != 0); | |
3375 | |
3376 if (!canImportLayer || (openLayerFile(path) == FileOpenFailed)) { | |
3377 | |
3378 QMessageBox::critical(this, tr("Failed to open file"), | |
3379 tr("File \"%1\" could not be opened").arg(path)); | |
3380 } | |
3381 } | |
3382 } | |
3383 } | 3420 } |
3384 } | 3421 } |
3385 | 3422 |
3386 MainWindow::FileOpenStatus | 3423 MainWindow::FileOpenStatus |
3387 MainWindow::openURL(QUrl url, AudioFileOpenMode mode) | 3424 MainWindow::openURL(QUrl url, AudioFileOpenMode mode) |
3388 { | 3425 { |
3389 if (url.scheme().toLower() == "file") { | 3426 if (url.scheme().toLower() == "file" || url.scheme() == "") { |
3390 | 3427 |
3391 return openSomeFile(url.toLocalFile(), mode); | 3428 return openSomeFile(url.toLocalFile(), mode); |
3392 | 3429 |
3393 } else if (!RemoteFile::canHandleScheme(url)) { | 3430 } else if (!RemoteFile::canHandleScheme(url)) { |
3394 | 3431 |
3395 QMessageBox::critical(this, tr("Unsupported scheme in URL"), | 3432 QMessageBox::critical(this, tr("Unsupported scheme in URL"), |
3396 tr("The URL scheme \"%1\" is not supported") | 3433 tr("<b>Download failed</b><p>The URL scheme \"%1\" is not supported") |
3397 .arg(url.scheme())); | 3434 .arg(url.scheme())); |
3398 return FileOpenFailed; | 3435 return FileOpenFailed; |
3399 | 3436 |
3400 } else { | 3437 } else { |
3401 RemoteFile rf(url); | 3438 RemoteFile rf(url); |
3402 rf.wait(); | 3439 rf.wait(); |
3403 if (!rf.isOK()) { | 3440 if (!rf.isOK()) { |
3404 QMessageBox::critical(this, tr("File download failed"), | 3441 QMessageBox::critical(this, tr("File download failed"), |
3405 tr("Failed to download URL \"%1\": %2") | 3442 tr("<b>Download failed</b><p>Failed to download URL \"%1\": %2") |
3406 .arg(url.toString()).arg(rf.getErrorString())); | 3443 .arg(url.toString()).arg(rf.getErrorString())); |
3407 return FileOpenFailed; | 3444 return FileOpenFailed; |
3408 } | 3445 } |
3409 FileOpenStatus status; | 3446 FileOpenStatus status; |
3410 if ((status = openSomeFile(rf.getLocalFilename(), url.toString(), | 3447 if ((status = openSomeFile(rf.getLocalFilename(), url.toString(), |
3422 // This function is used when we don't know whether the string is | 3459 // This function is used when we don't know whether the string is |
3423 // an encoded or human-readable url | 3460 // an encoded or human-readable url |
3424 | 3461 |
3425 QUrl url(ustr); | 3462 QUrl url(ustr); |
3426 | 3463 |
3427 if (url.scheme().toLower() == "file") { | 3464 if (url.scheme().toLower() == "file" || url.scheme() == "") { |
3428 | 3465 |
3429 return openSomeFile(url.toLocalFile(), mode); | 3466 FileOpenStatus status = openSomeFile(url.toLocalFile(), mode); |
3467 if (status == FileOpenFailed) { | |
3468 url.setEncodedUrl(ustr.toAscii()); | |
3469 status = openSomeFile(url.toLocalFile(), mode); | |
3470 } | |
3471 return status; | |
3430 | 3472 |
3431 } else if (!RemoteFile::canHandleScheme(url)) { | 3473 } else if (!RemoteFile::canHandleScheme(url)) { |
3432 | 3474 |
3433 QMessageBox::critical(this, tr("Unsupported scheme in URL"), | 3475 QMessageBox::critical(this, tr("Unsupported scheme in URL"), |
3434 tr("The URL scheme \"%1\" is not supported") | 3476 tr("<b>Download failed</b><p>The URL scheme \"%1\" is not supported") |
3435 .arg(url.scheme())); | 3477 .arg(url.scheme())); |
3436 return FileOpenFailed; | 3478 return FileOpenFailed; |
3437 | 3479 |
3438 } else { | 3480 } else { |
3439 RemoteFile rf(url); | 3481 RemoteFile rf(url); |
3477 | 3519 |
3478 if ((status = openPlaylistFile(path, location, mode)) != FileOpenFailed) { | 3520 if ((status = openPlaylistFile(path, location, mode)) != FileOpenFailed) { |
3479 return status; | 3521 return status; |
3480 } else if ((status = openAudioFile(path, location, mode)) != FileOpenFailed) { | 3522 } else if ((status = openAudioFile(path, location, mode)) != FileOpenFailed) { |
3481 return status; | 3523 return status; |
3482 } else if ((status = openSessionFile(path, location)) != FileOpenFailed) { | 3524 } else if (QFileInfo(path).suffix().toLower() == "sv" && |
3525 (status = openSessionFile(path, location)) != FileOpenFailed) { | |
3483 return status; | 3526 return status; |
3484 } else if (!canImportLayer) { | 3527 } else if (!canImportLayer) { |
3485 return FileOpenFailed; | 3528 return FileOpenWrongMode; |
3529 } else if ((status = openImageFile(path, location)) != FileOpenFailed) { | |
3530 return status; | |
3486 } else if ((status = openLayerFile(path, location)) != FileOpenFailed) { | 3531 } else if ((status = openLayerFile(path, location)) != FileOpenFailed) { |
3487 return status; | 3532 return status; |
3488 } else { | 3533 } else { |
3489 return FileOpenFailed; | 3534 return FileOpenFailed; |
3490 } | 3535 } |
3551 } else { | 3596 } else { |
3552 setWindowTitle(tr("Sonic Visualiser")); | 3597 setWindowTitle(tr("Sonic Visualiser")); |
3553 } | 3598 } |
3554 | 3599 |
3555 return ok ? FileOpenSucceeded : FileOpenFailed; | 3600 return ok ? FileOpenSucceeded : FileOpenFailed; |
3601 } | |
3602 | |
3603 void | |
3604 MainWindow::paneDropAccepted(Pane *pane, QStringList uriList) | |
3605 { | |
3606 if (pane) m_paneStack->setCurrentPane(pane); | |
3607 | |
3608 for (QStringList::iterator i = uriList.begin(); i != uriList.end(); ++i) { | |
3609 | |
3610 FileOpenStatus status = | |
3611 openURL(*i, (m_document->getMainModel() ? | |
3612 CreateAdditionalModel : ReplaceMainModel)); | |
3613 | |
3614 if (status == FileOpenFailed) { | |
3615 QMessageBox::critical(this, tr("Failed to open dropped URL"), | |
3616 tr("<b>Open failed</b><p>Dropped URL \"%1\" could not be opened").arg(*i)); | |
3617 } else if (status == FileOpenWrongMode) { | |
3618 QMessageBox::critical(this, tr("Failed to open dropped URL"), | |
3619 tr("<b>Audio required</b><p>Please load at least one audio file before importing annotation data")); | |
3620 } | |
3621 } | |
3622 } | |
3623 | |
3624 void | |
3625 MainWindow::paneDropAccepted(Pane *pane, QString text) | |
3626 { | |
3627 if (pane) m_paneStack->setCurrentPane(pane); | |
3628 | |
3629 QUrl testUrl(text); | |
3630 if (testUrl.scheme() == "file" || | |
3631 testUrl.scheme() == "http" || | |
3632 testUrl.scheme() == "ftp") { | |
3633 QStringList list; | |
3634 list.push_back(text); | |
3635 paneDropAccepted(pane, list); | |
3636 return; | |
3637 } | |
3638 | |
3639 //!!! open as text -- but by importing as if a CSV, or just adding | |
3640 //to a text layer? | |
3556 } | 3641 } |
3557 | 3642 |
3558 void | 3643 void |
3559 MainWindow::closeEvent(QCloseEvent *e) | 3644 MainWindow::closeEvent(QCloseEvent *e) |
3560 { | 3645 { |
3657 if (!m_documentModified) return true; | 3742 if (!m_documentModified) return true; |
3658 | 3743 |
3659 int button = | 3744 int button = |
3660 QMessageBox::warning(this, | 3745 QMessageBox::warning(this, |
3661 tr("Session modified"), | 3746 tr("Session modified"), |
3662 tr("The current session has been modified.\nDo you want to save it?"), | 3747 tr("<b>Session modified</b><p>The current session has been modified.<br>Do you want to save it?<br>"), |
3663 QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel, | 3748 QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel, |
3664 QMessageBox::Yes); | 3749 QMessageBox::Yes); |
3665 | 3750 |
3666 if (button == QMessageBox::Yes) { | 3751 if (button == QMessageBox::Yes) { |
3667 saveSession(); | 3752 saveSession(); |
3683 MainWindow::saveSession() | 3768 MainWindow::saveSession() |
3684 { | 3769 { |
3685 if (m_sessionFile != "") { | 3770 if (m_sessionFile != "") { |
3686 if (!saveSessionFile(m_sessionFile)) { | 3771 if (!saveSessionFile(m_sessionFile)) { |
3687 QMessageBox::critical(this, tr("Failed to save file"), | 3772 QMessageBox::critical(this, tr("Failed to save file"), |
3688 tr("Session file \"%1\" could not be saved.").arg(m_sessionFile)); | 3773 tr("<b>Save failed</b><p>Session file \"%1\" could not be saved.").arg(m_sessionFile)); |
3689 } else { | 3774 } else { |
3690 CommandHistory::getInstance()->documentSaved(); | 3775 CommandHistory::getInstance()->documentSaved(); |
3691 documentRestored(); | 3776 documentRestored(); |
3692 } | 3777 } |
3693 } else { | 3778 } else { |
3706 | 3791 |
3707 if (path == "") return; | 3792 if (path == "") return; |
3708 | 3793 |
3709 if (!saveSessionFile(path)) { | 3794 if (!saveSessionFile(path)) { |
3710 QMessageBox::critical(this, tr("Failed to save file"), | 3795 QMessageBox::critical(this, tr("Failed to save file"), |
3711 tr("Session file \"%1\" could not be saved.").arg(path)); | 3796 tr("<b>Save failed</b><p>Session file \"%1\" could not be saved.").arg(path)); |
3712 } else { | 3797 } else { |
3713 setWindowTitle(tr("Sonic Visualiser: %1") | 3798 setWindowTitle(tr("Sonic Visualiser: %1") |
3714 .arg(QFileInfo(path).fileName())); | 3799 .arg(QFileInfo(path).fileName())); |
3715 m_sessionFile = path; | 3800 m_sessionFile = path; |
3716 CommandHistory::getInstance()->documentSaved(); | 3801 CommandHistory::getInstance()->documentSaved(); |
3738 | 3823 |
3739 QApplication::restoreOverrideCursor(); | 3824 QApplication::restoreOverrideCursor(); |
3740 | 3825 |
3741 if (!bzFile.isOK()) { | 3826 if (!bzFile.isOK()) { |
3742 QMessageBox::critical(this, tr("Failed to write file"), | 3827 QMessageBox::critical(this, tr("Failed to write file"), |
3743 tr("Failed to write to file \"%1\": %2") | 3828 tr("<b>Save failed</b><p>Failed to write to file \"%1\": %2") |
3744 .arg(path).arg(bzFile.errorString())); | 3829 .arg(path).arg(bzFile.errorString())); |
3745 bzFile.close(); | 3830 bzFile.close(); |
3746 return false; | 3831 return false; |
3747 } | 3832 } |
3748 | 3833 |
4704 void | 4789 void |
4705 MainWindow::sampleRateMismatch(size_t requested, size_t actual, | 4790 MainWindow::sampleRateMismatch(size_t requested, size_t actual, |
4706 bool willResample) | 4791 bool willResample) |
4707 { | 4792 { |
4708 if (!willResample) { | 4793 if (!willResample) { |
4709 //!!! more helpful message needed | |
4710 QMessageBox::information | 4794 QMessageBox::information |
4711 (this, tr("Sample rate mismatch"), | 4795 (this, tr("Sample rate mismatch"), |
4712 tr("The sample rate of this audio file (%1 Hz) does not match\nthe current playback rate (%2 Hz).\n\nThe file will play at the wrong speed and pitch.") | 4796 tr("<b>Wrong sample rate</b><p>The sample rate of this audio file (%1 Hz) does not match\nthe current playback rate (%2 Hz).<p>The file will play at the wrong speed and pitch.<p>Change the <i>Resample mismatching files on import</i> option under <i>File</i> -> <i>Preferences</i> if you want to alter this behaviour.") |
4713 .arg(requested).arg(actual)); | 4797 .arg(requested).arg(actual)); |
4714 } | 4798 } |
4715 | 4799 |
4716 updateDescriptionLabel(); | 4800 updateDescriptionLabel(); |
4717 } | 4801 } |
4719 void | 4803 void |
4720 MainWindow::audioOverloadPluginDisabled() | 4804 MainWindow::audioOverloadPluginDisabled() |
4721 { | 4805 { |
4722 QMessageBox::information | 4806 QMessageBox::information |
4723 (this, tr("Audio processing overload"), | 4807 (this, tr("Audio processing overload"), |
4724 tr("Audio effects plugin auditioning has been disabled\ndue to a processing overload.")); | 4808 tr("<b>Overloaded</b><p>Audio effects plugin auditioning has been disabled due to a processing overload.")); |
4725 } | 4809 } |
4726 | 4810 |
4727 void | 4811 void |
4728 MainWindow::layerAdded(Layer *) | 4812 MainWindow::layerAdded(Layer *) |
4729 { | 4813 { |
4817 MainWindow::modelGenerationFailed(QString transformName) | 4901 MainWindow::modelGenerationFailed(QString transformName) |
4818 { | 4902 { |
4819 QMessageBox::warning | 4903 QMessageBox::warning |
4820 (this, | 4904 (this, |
4821 tr("Failed to generate layer"), | 4905 tr("Failed to generate layer"), |
4822 tr("Failed to generate a derived layer.\n\nThe layer transform \"%1\" failed.\n\nThis probably means that a plugin failed to initialise, perhaps because it\nrejected the processing block size that was requested.") | 4906 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.") |
4823 .arg(transformName), | 4907 .arg(transformName), |
4824 QMessageBox::Ok); | 4908 QMessageBox::Ok); |
4825 } | 4909 } |
4826 | 4910 |
4827 void | 4911 void |
4828 MainWindow::modelRegenerationFailed(QString layerName, QString transformName) | 4912 MainWindow::modelRegenerationFailed(QString layerName, QString transformName) |
4829 { | 4913 { |
4830 QMessageBox::warning | 4914 QMessageBox::warning |
4831 (this, | 4915 (this, |
4832 tr("Failed to regenerate layer"), | 4916 tr("Failed to regenerate layer"), |
4833 tr("Failed to regenerate derived layer \"%1\".\n\nThe layer transform \"%2\" failed to run.\n\nThis probably means the layer used a plugin that is not currently available.") | 4917 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.") |
4834 .arg(layerName).arg(transformName), | 4918 .arg(layerName).arg(transformName), |
4835 QMessageBox::Ok); | 4919 QMessageBox::Ok); |
4836 } | 4920 } |
4837 | 4921 |
4838 void | 4922 void |