comparison main/MainWindow.cpp @ 81:911c0bd745cd

* Recall last file open/save path appropriately * Harmonise handling of overwrite query etc for different file types * When exporting a layer, export the right file type for the currently selected filter in the file dialog
author Chris Cannam
date Fri, 05 Jan 2007 12:37:14 +0000
parents f4f52566e451
children d82e332cb178
comparison
equal deleted inserted replaced
80:f4f52566e451 81:911c0bd745cd
104 m_timeRulerLayer(0), 104 m_timeRulerLayer(0),
105 m_audioOutput(withAudioOutput), 105 m_audioOutput(withAudioOutput),
106 m_playSource(0), 106 m_playSource(0),
107 m_playTarget(0), 107 m_playTarget(0),
108 m_oscQueue(withOSCSupport ? new OSCQueue() : 0), 108 m_oscQueue(withOSCSupport ? new OSCQueue() : 0),
109 m_recentFiles("RecentFiles"), 109 m_recentFiles("RecentFiles", 20),
110 m_recentTransforms("RecentTransforms", 20), 110 m_recentTransforms("RecentTransforms", 20),
111 m_mainMenusCreated(false), 111 m_mainMenusCreated(false),
112 m_paneMenu(0), 112 m_paneMenu(0),
113 m_layerMenu(0), 113 m_layerMenu(0),
114 m_transformsMenu(0), 114 m_transformsMenu(0),
260 delete m_viewManager; 260 delete m_viewManager;
261 delete m_oscQueue; 261 delete m_oscQueue;
262 Profiles::getInstance()->dump(); 262 Profiles::getInstance()->dump();
263 } 263 }
264 264
265 QString
266 MainWindow::getOpenFileName(FileType type)
267 {
268 QString settingsKey;
269 QString lastPath;
270
271 QString title = tr("Select file");
272 QString filter = tr("All files (*.*)");
273
274 bool canImportLayer = (getMainModel() != 0 &&
275 m_paneStack != 0 &&
276 m_paneStack->getCurrentPane() != 0);
277
278 switch (type) {
279
280 case SessionFile:
281 settingsKey = "sessionpath";
282 lastPath = m_sessionFile;
283 title = tr("Select a session file");
284 filter = tr("Sonic Visualiser session files (*.sv)\nAll files (*.*)");
285 break;
286
287 case AudioFile:
288 settingsKey = "audiopath";
289 lastPath = m_audioFile;
290 title = "Select an audio file";
291 filter = tr("Audio files (%1)\nAll files (*.*)")
292 .arg(AudioFileReaderFactory::getKnownExtensions());
293 break;
294
295 case LayerFile:
296 settingsKey = "layerpath";
297 lastPath = m_sessionFile;
298 filter = tr("All supported files (%1)\nSonic Visualiser Layer XML files (*.svl)\nComma-separated data files (*.csv)\nSpace-separated .lab files (*.lab)\nMIDI files (*.mid)\nText files (*.txt)\nAll files (*.*)").arg(DataFileReaderFactory::getKnownExtensions());
299 break;
300
301 case AnyFile:
302 settingsKey = "lastpath";
303 lastPath = m_sessionFile;
304 if (canImportLayer) {
305 filter = tr("All supported files (*.sv %1 %2)\nSonic Visualiser session files (*.sv)\nAudio files (%1)\nLayer files (%2)\nAll files (*.*)")
306 .arg(AudioFileReaderFactory::getKnownExtensions())
307 .arg(DataFileReaderFactory::getKnownExtensions());
308 } else {
309 filter = tr("All supported files (*.sv %1)\nSonic Visualiser session files (*.sv)\nAudio files (%1)\nAll files (*.*)")
310 .arg(AudioFileReaderFactory::getKnownExtensions());
311 }
312 break;
313 };
314
315 if (lastPath == "") lastPath = m_audioFile;
316 if (lastPath == "") {
317 char *home = getenv("HOME");
318 if (home) lastPath = home;
319 else lastPath = ".";
320 }
321 lastPath = QFileInfo(lastPath).absoluteDir().canonicalPath();
322
323 QSettings settings;
324 settings.beginGroup("MainWindow");
325 lastPath = settings.value(settingsKey, lastPath).toString();
326
327 QString path = "";
328
329 // Use our own QFileDialog just for symmetry with getSaveFileName below
330
331 QFileDialog dialog(this);
332 dialog.setFilters(filter.split('\n'));
333 dialog.setWindowTitle(title);
334 dialog.setDirectory(lastPath);
335
336 dialog.setAcceptMode(QFileDialog::AcceptOpen);
337 dialog.setFileMode(QFileDialog::ExistingFile);
338
339 if (dialog.exec()) {
340 QStringList files = dialog.selectedFiles();
341 if (!files.empty()) path = *files.begin();
342
343 QFileInfo fi(path);
344
345 if (!fi.exists()) {
346
347 QMessageBox::critical(this, tr("File does not exist"),
348 tr("File \"%1\" does not exist").arg(path));
349 path = "";
350
351 } else if (!fi.isReadable()) {
352
353 QMessageBox::critical(this, tr("File is not readable"),
354 tr("File \"%1\" can not be read").arg(path));
355 path = "";
356
357 } else if (fi.isDir()) {
358
359 QMessageBox::critical(this, tr("Directory selected"),
360 tr("File \"%1\" is a directory").arg(path));
361 path = "";
362
363 } else if (!fi.isFile()) {
364
365 QMessageBox::critical(this, tr("Non-file selected"),
366 tr("Path \"%1\" is not a file").arg(path));
367 path = "";
368
369 } else if (fi.size() == 0) {
370
371 QMessageBox::critical(this, tr("File is empty"),
372 tr("File \"%1\" is empty").arg(path));
373 path = "";
374 }
375 }
376
377 if (path != "") {
378 settings.setValue(settingsKey,
379 QFileInfo(path).absoluteDir().canonicalPath());
380 }
381
382 return path;
383 }
384
385 QString
386 MainWindow::getSaveFileName(FileType type)
387 {
388 QString settingsKey;
389 QString lastPath;
390
391 QString title = tr("Select file");
392 QString filter = tr("All files (*.*)");
393
394 switch (type) {
395
396 case SessionFile:
397 settingsKey = "savesessionpath";
398 lastPath = m_sessionFile;
399 title = tr("Select a session file");
400 filter = tr("Sonic Visualiser session files (*.sv)\nAll files (*.*)");
401 break;
402
403 case AudioFile:
404 settingsKey = "saveaudiopath";
405 lastPath = m_audioFile;
406 title = "Select an audio file";
407 title = tr("Select a file to export to");
408 filter = tr("WAV audio files (*.wav)\nAll files (*.*)");
409 break;
410
411 case LayerFile:
412 settingsKey = "savelayerpath";
413 lastPath = m_sessionFile;
414 title = tr("Select a file to export to");
415 filter = tr("Sonic Visualiser Layer XML files (*.svl)\nComma-separated data files (*.csv)\nText files (*.txt)\nAll files (*.*)");
416 break;
417
418 case AnyFile:
419 std::cerr << "ERROR: Internal error: MainWindow::getSaveFileName: AnyFile cannot be used here" << std::endl;
420 abort();
421 };
422
423 if (lastPath == "") lastPath = m_audioFile;
424 if (lastPath == "") {
425 char *home = getenv("HOME");
426 if (home) lastPath = home;
427 else lastPath = ".";
428 }
429 lastPath = QFileInfo(lastPath).absoluteDir().canonicalPath();
430
431 QSettings settings;
432 settings.beginGroup("MainWindow");
433 lastPath = settings.value(settingsKey, lastPath).toString();
434
435 QString path = "";
436
437 // Use our own QFileDialog instead of static functions, as we may
438 // need to adjust the file extension based on the selected filter
439
440 QFileDialog dialog(this);
441 dialog.setFilters(filter.split('\n'));
442 dialog.setWindowTitle(title);
443 dialog.setDirectory(lastPath);
444
445 dialog.setAcceptMode(QFileDialog::AcceptSave);
446 dialog.setFileMode(QFileDialog::AnyFile);
447 dialog.setConfirmOverwrite(false); // we'll do that
448
449 if (type == SessionFile) {
450 dialog.setDefaultSuffix("sv");
451 } else if (type == AudioFile) {
452 dialog.setDefaultSuffix("wav");
453 }
454
455 bool good = false;
456
457 while (!good) {
458
459 path = "";
460
461 if (!dialog.exec()) break;
462
463 QStringList files = dialog.selectedFiles();
464 if (files.empty()) break;
465 path = *files.begin();
466
467 QFileInfo fi(path);
468
469 if (type == LayerFile && fi.suffix() == "") {
470 QString expectedExtension;
471 QString selectedFilter = dialog.selectedFilter();
472 if (selectedFilter.contains(".svl")) {
473 expectedExtension = "svl";
474 } else if (selectedFilter.contains(".txt")) {
475 expectedExtension = "txt";
476 } else if (selectedFilter.contains(".csv")) {
477 expectedExtension = "csv";
478 }
479 if (expectedExtension != "") {
480 path = QString("%1.%2").arg(path).arg(expectedExtension);
481 fi = QFileInfo(path);
482 }
483 }
484
485 if (fi.isDir()) {
486 QMessageBox::critical(this, tr("Directory selected"),
487 tr("File \"%1\" is a directory").arg(path));
488 continue;
489 }
490
491 if (fi.exists()) {
492 if (QMessageBox::question(this, tr("File exists"),
493 tr("The file \"%1\" already exists.\nDo you want to overwrite it?").arg(path),
494 QMessageBox::Ok,
495 QMessageBox::Cancel) != QMessageBox::Ok) {
496 continue;
497 }
498 }
499
500 good = true;
501 }
502
503 if (path != "") {
504 settings.setValue(settingsKey,
505 QFileInfo(path).absoluteDir().canonicalPath());
506 }
507
508 return path;
509 }
510
511 void
512 MainWindow::registerLastOpenedFilePath(FileType type, QString path)
513 {
514 QString settingsKey;
515
516 switch (type) {
517 case SessionFile:
518 settingsKey = "sessionpath";
519 break;
520
521 case AudioFile:
522 settingsKey = "audiopath";
523 break;
524
525 case LayerFile:
526 settingsKey = "layerpath";
527 break;
528
529 case AnyFile:
530 settingsKey = "lastpath";
531 break;
532 }
533
534 if (path != "") {
535 QSettings settings;
536 settings.beginGroup("MainWindow");
537 path = QFileInfo(path).absoluteDir().canonicalPath();
538 settings.setValue(settingsKey, path);
539 settings.setValue("lastpath", path);
540 }
541 }
542
265 void 543 void
266 MainWindow::setupMenus() 544 MainWindow::setupMenus()
267 { 545 {
268 if (!m_mainMenusCreated) { 546 if (!m_mainMenusCreated) {
269 m_rightButtonMenu = new QMenu(); 547 m_rightButtonMenu = new QMenu();
493 771
494 action = new QAction(tr("&Insert Instant at Playback Position"), this); 772 action = new QAction(tr("&Insert Instant at Playback Position"), this);
495 action->setShortcut(tr("Enter")); 773 action->setShortcut(tr("Enter"));
496 connect(action, SIGNAL(triggered()), this, SLOT(insertInstant())); 774 connect(action, SIGNAL(triggered()), this, SLOT(insertInstant()));
497 connect(this, SIGNAL(canInsertInstant(bool)), action, SLOT(setEnabled(bool))); 775 connect(this, SIGNAL(canInsertInstant(bool)), action, SLOT(setEnabled(bool)));
776 menu->addAction(action);
777
778 action = new QAction(tr("Insert Instants at Selection &Boundaries"), this);
779 action->setShortcut(tr("Shift+Enter"));
780 connect(action, SIGNAL(triggered()), this, SLOT(insertInstantsAtBoundaries()));
781 connect(this, SIGNAL(canInsertInstantsAtBoundaries(bool)), action, SLOT(setEnabled(bool)));
498 menu->addAction(action); 782 menu->addAction(action);
499 783
500 // Laptop shortcut (no keypad Enter key) 784 // Laptop shortcut (no keypad Enter key)
501 connect(new QShortcut(tr(";"), this), SIGNAL(activated()), 785 connect(new QShortcut(tr(";"), this), SIGNAL(activated()),
502 this, SLOT(insertInstant())); 786 this, SLOT(insertInstant()));
1417 emit canPlay(/*!!! haveMainModel && */ havePlayTarget); 1701 emit canPlay(/*!!! haveMainModel && */ havePlayTarget);
1418 emit canFfwd(haveCurrentTimeInstantsLayer || haveCurrentTimeValueLayer); 1702 emit canFfwd(haveCurrentTimeInstantsLayer || haveCurrentTimeValueLayer);
1419 emit canRewind(haveCurrentTimeInstantsLayer || haveCurrentTimeValueLayer); 1703 emit canRewind(haveCurrentTimeInstantsLayer || haveCurrentTimeValueLayer);
1420 emit canPaste(haveCurrentEditableLayer && haveClipboardContents); 1704 emit canPaste(haveCurrentEditableLayer && haveClipboardContents);
1421 emit canInsertInstant(haveCurrentPane); 1705 emit canInsertInstant(haveCurrentPane);
1706 emit canInsertInstantsAtBoundaries(haveCurrentPane && haveSelection);
1422 emit canPlaySelection(haveMainModel && havePlayTarget && haveSelection); 1707 emit canPlaySelection(haveMainModel && havePlayTarget && haveSelection);
1423 emit canClearSelection(haveSelection); 1708 emit canClearSelection(haveSelection);
1424 emit canEditSelection(haveSelection && haveCurrentEditableLayer); 1709 emit canEditSelection(haveSelection && haveCurrentEditableLayer);
1425 emit canSave(m_sessionFile != "" && m_documentModified); 1710 emit canSave(m_sessionFile != "" && m_documentModified);
1426 } 1711 }
1693 1978
1694 void 1979 void
1695 MainWindow::insertInstant() 1980 MainWindow::insertInstant()
1696 { 1981 {
1697 int frame = m_viewManager->getPlaybackFrame(); 1982 int frame = m_viewManager->getPlaybackFrame();
1698 1983 insertInstantAt(frame);
1984 }
1985
1986 void
1987 MainWindow::insertInstantsAtBoundaries()
1988 {
1989 MultiSelection::SelectionList selections = m_viewManager->getSelections();
1990 for (MultiSelection::SelectionList::iterator i = selections.begin();
1991 i != selections.end(); ++i) {
1992 size_t start = i->getStartFrame();
1993 size_t end = i->getEndFrame();
1994 if (start != end) {
1995 insertInstantAt(i->getStartFrame());
1996 insertInstantAt(i->getEndFrame());
1997 }
1998 }
1999 }
2000
2001 void
2002 MainWindow::insertInstantAt(size_t frame)
2003 {
1699 Pane *pane = m_paneStack->getCurrentPane(); 2004 Pane *pane = m_paneStack->getCurrentPane();
1700 if (!pane) { 2005 if (!pane) {
1701 return; 2006 return;
1702 } 2007 }
1703 2008
1740 } 2045 }
1741 2046
1742 void 2047 void
1743 MainWindow::importAudio() 2048 MainWindow::importAudio()
1744 { 2049 {
1745 QString orig = m_audioFile; 2050 QString path = getOpenFileName(AudioFile);
1746
1747 // std::cerr << "orig = " << orig.toStdString() << std::endl;
1748
1749 if (orig == "") orig = ".";
1750
1751 QString path = QFileDialog::getOpenFileName
1752 (this, tr("Select an audio file"), orig,
1753 tr("Audio files (%1)\nAll files (*.*)")
1754 .arg(AudioFileReaderFactory::getKnownExtensions()));
1755 2051
1756 if (path != "") { 2052 if (path != "") {
1757 if (!openAudioFile(path, ReplaceMainModel)) { 2053 if (!openAudioFile(path, ReplaceMainModel)) {
1758 QMessageBox::critical(this, tr("Failed to open file"), 2054 QMessageBox::critical(this, tr("Failed to open file"),
1759 tr("Audio file \"%1\" could not be opened").arg(path)); 2055 tr("Audio file \"%1\" could not be opened").arg(path));
1762 } 2058 }
1763 2059
1764 void 2060 void
1765 MainWindow::importMoreAudio() 2061 MainWindow::importMoreAudio()
1766 { 2062 {
1767 QString orig = m_audioFile; 2063 QString path = getOpenFileName(AudioFile);
1768
1769 // std::cerr << "orig = " << orig.toStdString() << std::endl;
1770
1771 if (orig == "") orig = ".";
1772
1773 QString path = QFileDialog::getOpenFileName
1774 (this, tr("Select an audio file"), orig,
1775 tr("Audio files (%1)\nAll files (*.*)")
1776 .arg(AudioFileReaderFactory::getKnownExtensions()));
1777 2064
1778 if (path != "") { 2065 if (path != "") {
1779 if (!openAudioFile(path, CreateAdditionalModel)) { 2066 if (!openAudioFile(path, CreateAdditionalModel)) {
1780 QMessageBox::critical(this, tr("Failed to open file"), 2067 QMessageBox::critical(this, tr("Failed to open file"),
1781 tr("Audio file \"%1\" could not be opened").arg(path)); 2068 tr("Audio file \"%1\" could not be opened").arg(path));
1786 void 2073 void
1787 MainWindow::exportAudio() 2074 MainWindow::exportAudio()
1788 { 2075 {
1789 if (!getMainModel()) return; 2076 if (!getMainModel()) return;
1790 2077
1791 QString path = QFileDialog::getSaveFileName 2078 QString path = getSaveFileName(AudioFile);
1792 (this, tr("Select a file to export to"), ".",
1793 tr("WAV audio files (*.wav)\nAll files (*.*)"));
1794 2079
1795 if (path == "") return; 2080 if (path == "") return;
1796
1797 if (!path.endsWith(".wav")) path = path + ".wav";
1798 2081
1799 bool ok = false; 2082 bool ok = false;
1800 QString error; 2083 QString error;
1801 2084
1802 MultiSelection ms = m_viewManager->getSelection(); 2085 MultiSelection ms = m_viewManager->getSelection();
1909 // shouldn't happen, as the menu action should have been disabled 2192 // shouldn't happen, as the menu action should have been disabled
1910 std::cerr << "WARNING: MainWindow::importLayer: No main model -- hence no default sample rate available" << std::endl; 2193 std::cerr << "WARNING: MainWindow::importLayer: No main model -- hence no default sample rate available" << std::endl;
1911 return; 2194 return;
1912 } 2195 }
1913 2196
1914 QString path = QFileDialog::getOpenFileName 2197 QString path = getOpenFileName(LayerFile);
1915 (this, tr("Select file"), ".",
1916 tr("All supported files (%1)\nSonic Visualiser Layer XML files (*.svl)\nComma-separated data files (*.csv)\nSpace-separated .lab files (*.lab)\nMIDI files (*.mid)\nText files (*.txt)\nAll files (*.*)").arg(DataFileReaderFactory::getKnownExtensions()));
1917 2198
1918 if (path != "") { 2199 if (path != "") {
1919 2200
1920 if (!openLayerFile(path)) { 2201 if (!openLayerFile(path)) {
1921 QMessageBox::critical(this, tr("Failed to open file"), 2202 QMessageBox::critical(this, tr("Failed to open file"),
1967 << reader.getErrorString().toStdString() << std::endl; 2248 << reader.getErrorString().toStdString() << std::endl;
1968 return false; 2249 return false;
1969 } 2250 }
1970 2251
1971 m_recentFiles.addFile(path); 2252 m_recentFiles.addFile(path);
2253 registerLastOpenedFilePath(LayerFile, path); // for file dialog
1972 return true; 2254 return true;
1973 2255
1974 } else { 2256 } else {
1975 2257
1976 Model *model = DataFileReaderFactory::load(path, getMainModel()->getSampleRate()); 2258 Model *model = DataFileReaderFactory::load(path, getMainModel()->getSampleRate());
1998 if (!layer) return; 2280 if (!layer) return;
1999 2281
2000 Model *model = layer->getModel(); 2282 Model *model = layer->getModel();
2001 if (!model) return; 2283 if (!model) return;
2002 2284
2003 QString path = QFileDialog::getSaveFileName 2285 QString path = getSaveFileName(LayerFile);
2004 (this, tr("Select a file to export to"), ".",
2005 tr("Sonic Visualiser Layer XML files (*.svl)\nComma-separated data files (*.csv)\nText files (*.txt)\nAll files (*.*)"));
2006 2286
2007 if (path == "") return; 2287 if (path == "") return;
2008 2288
2009 if (QFileInfo(path).suffix() == "") path += ".svl"; 2289 if (QFileInfo(path).suffix() == "") path += ".svl";
2010 2290
2158 CommandHistory::getInstance()->endCompoundOperation(); 2438 CommandHistory::getInstance()->endCompoundOperation();
2159 } 2439 }
2160 2440
2161 updateMenuStates(); 2441 updateMenuStates();
2162 m_recentFiles.addFile(path); 2442 m_recentFiles.addFile(path);
2443 registerLastOpenedFilePath(AudioFile, path); // for file dialog
2163 m_openingAudioFile = false; 2444 m_openingAudioFile = false;
2164 2445
2165 return true; 2446 return true;
2166 } 2447 }
2167 2448
2295 2576
2296 QString orig = m_audioFile; 2577 QString orig = m_audioFile;
2297 if (orig == "") orig = "."; 2578 if (orig == "") orig = ".";
2298 else orig = QFileInfo(orig).absoluteDir().canonicalPath(); 2579 else orig = QFileInfo(orig).absoluteDir().canonicalPath();
2299 2580
2300 QString path = QFileDialog::getOpenFileName 2581 QString path = getOpenFileName(SessionFile);
2301 (this, tr("Select a session file"), orig,
2302 tr("Sonic Visualiser session files (*.sv)\nAll files (*.*)"));
2303 2582
2304 if (path.isEmpty()) return; 2583 if (path.isEmpty()) return;
2305
2306 if (!(QFileInfo(path).exists() &&
2307 QFileInfo(path).isFile() &&
2308 QFileInfo(path).isReadable())) {
2309 QMessageBox::critical(this, tr("Failed to open file"),
2310 tr("File \"%1\" does not exist or is not a readable file").arg(path));
2311 return;
2312 }
2313 2584
2314 if (!openSessionFile(path)) { 2585 if (!openSessionFile(path)) {
2315 QMessageBox::critical(this, tr("Failed to open file"), 2586 QMessageBox::critical(this, tr("Failed to open file"),
2316 tr("Session file \"%1\" could not be opened").arg(path)); 2587 tr("Session file \"%1\" could not be opened").arg(path));
2317 } 2588 }
2326 2597
2327 bool canImportLayer = (getMainModel() != 0 && 2598 bool canImportLayer = (getMainModel() != 0 &&
2328 m_paneStack != 0 && 2599 m_paneStack != 0 &&
2329 m_paneStack->getCurrentPane() != 0); 2600 m_paneStack->getCurrentPane() != 0);
2330 2601
2331 QString importSpec; 2602 QString path = getOpenFileName(AnyFile);
2332
2333 if (canImportLayer) {
2334 importSpec = tr("All supported files (*.sv %1 %2)\nSonic Visualiser session files (*.sv)\nAudio files (%1)\nLayer files (%2)\nAll files (*.*)")
2335 .arg(AudioFileReaderFactory::getKnownExtensions())
2336 .arg(DataFileReaderFactory::getKnownExtensions());
2337 } else {
2338 importSpec = tr("All supported files (*.sv %1)\nSonic Visualiser session files (*.sv)\nAudio files (%1)\nAll files (*.*)")
2339 .arg(AudioFileReaderFactory::getKnownExtensions());
2340 }
2341
2342 QString path = QFileDialog::getOpenFileName
2343 (this, tr("Select a file to open"), orig, importSpec);
2344 2603
2345 if (path.isEmpty()) return; 2604 if (path.isEmpty()) return;
2346
2347 if (!(QFileInfo(path).exists() &&
2348 QFileInfo(path).isFile() &&
2349 QFileInfo(path).isReadable())) {
2350 QMessageBox::critical(this, tr("Failed to open file"),
2351 tr("File \"%1\" does not exist or is not a readable file").arg(path));
2352 return;
2353 }
2354 2605
2355 if (path.endsWith(".sv")) { 2606 if (path.endsWith(".sv")) {
2356 2607
2357 if (!checkSaveModified()) return; 2608 if (!checkSaveModified()) return;
2358 2609
2464 CommandHistory::getInstance()->clear(); 2715 CommandHistory::getInstance()->clear();
2465 CommandHistory::getInstance()->documentSaved(); 2716 CommandHistory::getInstance()->documentSaved();
2466 m_documentModified = false; 2717 m_documentModified = false;
2467 updateMenuStates(); 2718 updateMenuStates();
2468 m_recentFiles.addFile(path); 2719 m_recentFiles.addFile(path);
2720 registerLastOpenedFilePath(SessionFile, path); // for file dialog
2469 } else { 2721 } else {
2470 setWindowTitle(tr("Sonic Visualiser")); 2722 setWindowTitle(tr("Sonic Visualiser"));
2471 } 2723 }
2472 2724
2473 return ok; 2725 return ok;
2581 { 2833 {
2582 QString orig = m_audioFile; 2834 QString orig = m_audioFile;
2583 if (orig == "") orig = "."; 2835 if (orig == "") orig = ".";
2584 else orig = QFileInfo(orig).absoluteDir().canonicalPath(); 2836 else orig = QFileInfo(orig).absoluteDir().canonicalPath();
2585 2837
2586 QString path; 2838 QString path = getSaveFileName(SessionFile);
2587 bool good = false; 2839
2588 2840 if (path == "") return;
2589 while (!good) {
2590
2591 path = QFileDialog::getSaveFileName
2592 (this, tr("Select a file to save to"), orig,
2593 tr("Sonic Visualiser session files (*.sv)\nAll files (*.*)"), 0,
2594 QFileDialog::DontConfirmOverwrite); // we'll do that
2595
2596 if (path.isEmpty()) return;
2597
2598 if (!path.endsWith(".sv")) path = path + ".sv";
2599
2600 QFileInfo fi(path);
2601
2602 if (fi.isDir()) {
2603 QMessageBox::critical(this, tr("Directory selected"),
2604 tr("File \"%1\" is a directory").arg(path));
2605 continue;
2606 }
2607
2608 if (fi.exists()) {
2609 if (QMessageBox::question(this, tr("File exists"),
2610 tr("The file \"%1\" already exists.\nDo you want to overwrite it?").arg(path),
2611 QMessageBox::Ok,
2612 QMessageBox::Cancel) == QMessageBox::Ok) {
2613 good = true;
2614 } else {
2615 continue;
2616 }
2617 }
2618
2619 good = true;
2620 }
2621 2841
2622 if (!saveSessionFile(path)) { 2842 if (!saveSessionFile(path)) {
2623 QMessageBox::critical(this, tr("Failed to save file"), 2843 QMessageBox::critical(this, tr("Failed to save file"),
2624 tr("Session file \"%1\" could not be saved.").arg(path)); 2844 tr("Session file \"%1\" could not be saved.").arg(path));
2625 } else { 2845 } else {