Mercurial > hg > sonic-visualiser
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 { |