17 #include "data/fileio/FileSource.h" 18 #include "data/fileio/AudioFileReaderFactory.h" 19 #include "data/fileio/DataFileReaderFactory.h" 20 #include "rdf/RDFImporter.h" 21 #include "rdf/RDFExporter.h" 24 #include <QMessageBox> 25 #include <QFileDialog> 26 #include <QInputDialog> 27 #include <QImageReader> 36 m_sessionExtension(
"sv"),
37 m_lastLocatedLocation(
""),
40 SVDEBUG <<
"Registering interactive file finder" << endl;
41 FileFinder::registerFileFinder(
this);
63 QString settingsKeyStub;
64 QString lastPath = fallbackLocation;
66 QString title = tr(
"Select file");
67 QString filter = tr(
"All files (*.*)");
72 settingsKeyStub =
"session";
73 title = tr(
"Select a session file");
74 filter = tr(
"%1 session files (*.%1)\nRDF files (%3)\nAll files (*.*)")
75 .arg(QApplication::applicationName())
77 .arg(RDFImporter::getKnownExtensions());
81 settingsKeyStub =
"audio";
82 title =
"Select an audio file";
83 filter = tr(
"Audio files (%1)\nAll files (*.*)")
84 .arg(AudioFileReaderFactory::getKnownExtensions());
88 settingsKeyStub =
"layer";
89 filter = tr(
"All supported files (%1 %2)\nSonic Visualiser Layer XML files (*.svl)\nComma-separated data files (*.csv)\nSpace-separated .lab files (*.lab)\nRDF files (%2)\nMIDI files (*.mid)\nText files (*.txt)\nAll files (*.*)")
90 .arg(DataFileReaderFactory::getKnownExtensions())
91 .arg(RDFImporter::getKnownExtensions());
95 settingsKeyStub =
"layer";
96 filter = tr(
"All supported files (%1 %2)\nSonic Visualiser Layer XML files (*.svl)\nComma-separated data files (*.csv)\nSpace-separated .lab files (*.lab)\nRDF files (%2)\nText files (*.txt)\nAll files (*.*)")
97 .arg(DataFileReaderFactory::getKnownExtensions())
98 .arg(RDFImporter::getKnownExtensions());
102 settingsKeyStub =
"layer";
103 filter = tr(
"All supported files (%1 %2)\nComma-separated data files (*.csv)\nSonic Visualiser Layer XML files (*.svl)\nSpace-separated .lab files (*.lab)\nRDF files (%2)\nMIDI files (*.mid)\nText files (*.txt)\nAll files (*.*)")
104 .arg(DataFileReaderFactory::getKnownExtensions())
105 .arg(RDFImporter::getKnownExtensions());
108 case LayerFileNoMidiNonSV:
109 settingsKeyStub =
"layer";
110 filter = tr(
"All supported files (%1 %2)\nComma-separated data files (*.csv)\nSonic Visualiser Layer XML files (*.svl)\nSpace-separated .lab files (*.lab)\nRDF files (%2)\nText files (*.txt)\nAll files (*.*)")
111 .arg(DataFileReaderFactory::getKnownExtensions())
112 .arg(RDFImporter::getKnownExtensions());
115 case SessionOrAudioFile:
116 settingsKeyStub =
"last";
117 filter = tr(
"All supported files (*.sv %1 %2)\n%3 session files (*.%4)\nAudio files (%2)\nRDF files (%1)\nAll files (*.*)")
118 .arg(RDFImporter::getKnownExtensions())
119 .arg(AudioFileReaderFactory::getKnownExtensions())
120 .arg(QApplication::applicationName())
125 settingsKeyStub =
"image";
128 QList<QByteArray> formats = QImageReader::supportedImageFormats();
129 for (QList<QByteArray>::iterator i = formats.begin();
130 i != formats.end(); ++i) {
131 fmts.push_back(QString(
"*.%1")
132 .arg(QString::fromLocal8Bit(*i).toLower()));
134 filter = tr(
"Image files (%1)\nAll files (*.*)").arg(fmts.join(
" "));
139 settingsKeyStub =
"layer";
140 filter = tr(
"Comma-separated data files (*.csv)\nSpace-separated .lab files (*.lab)\nText files (*.txt)\nAll files (*.*)");
144 settingsKeyStub =
"last";
145 filter = tr(
"All supported files (*.sv %1 %2 %3)\n%4 session files (*.%5)\nAudio files (%1)\nLayer files (%2)\nRDF files (%3)\nAll files (*.*)")
146 .arg(AudioFileReaderFactory::getKnownExtensions())
147 .arg(DataFileReaderFactory::getKnownExtensions())
148 .arg(RDFImporter::getKnownExtensions())
149 .arg(QApplication::applicationName())
154 if (lastPath ==
"") {
155 char *home = getenv(
"HOME");
156 if (home) lastPath = home;
158 }
else if (QFileInfo(lastPath).isDir()) {
159 lastPath = QFileInfo(lastPath).canonicalPath();
161 lastPath = QFileInfo(lastPath).absoluteDir().canonicalPath();
165 settings.beginGroup(
"FileFinder");
166 lastPath = settings.value(settingsKeyStub +
"path", lastPath).toString();
173 dialog.setNameFilters(filter.split(
'\n'));
174 dialog.setWindowTitle(title);
175 dialog.setDirectory(lastPath);
177 dialog.setAcceptMode(QFileDialog::AcceptOpen);
178 dialog.setFileMode(QFileDialog::ExistingFile);
181 QStringList files = dialog.selectedFiles();
182 if (!files.empty()) path = *files.begin();
188 QMessageBox::critical(0, tr(
"File does not exist"),
189 tr(
"<b>File not found</b><p>File \"%1\" does not exist").arg(path));
192 }
else if (!fi.isReadable()) {
194 QMessageBox::critical(0, tr(
"File is not readable"),
195 tr(
"<b>File is not readable</b><p>File \"%1\" can not be read").arg(path));
198 }
else if (fi.isDir()) {
200 QMessageBox::critical(0, tr(
"Directory selected"),
201 tr(
"<b>Directory selected</b><p>File \"%1\" is a directory").arg(path));
204 }
else if (!fi.isFile()) {
206 QMessageBox::critical(0, tr(
"Non-file selected"),
207 tr(
"<b>Not a file</b><p>Path \"%1\" is not a file").arg(path));
210 }
else if (fi.size() == 0) {
212 QMessageBox::critical(0, tr(
"File is empty"),
213 tr(
"<b>File is empty</b><p>File \"%1\" is empty").arg(path));
219 settings.setValue(settingsKeyStub +
"path",
220 QFileInfo(path).absoluteDir().canonicalPath());
228 QString fallbackLocation)
230 QString settingsKeyStub;
231 QString lastPath = fallbackLocation;
233 QString title = tr(
"Select file");
234 QString filter = tr(
"All files (*.*)");
239 settingsKeyStub =
"savesession";
240 title = tr(
"Select a session file");
241 filter = tr(
"%1 session files (*.%2)\nAll files (*.*)")
246 settingsKeyStub =
"saveaudio";
247 title =
"Select an audio file";
248 title = tr(
"Select a file to export to");
249 filter = tr(
"WAV audio files (*.wav)\nAll files (*.*)");
253 settingsKeyStub =
"savelayer";
254 title = tr(
"Select a file to export to");
255 filter = tr(
"Sonic Visualiser Layer XML files (*.svl)\nComma-separated data files (*.csv)\nRDF/Turtle files (%1)\nMIDI files (*.mid)\nText files (*.txt)\nAll files (*.*)").arg(RDFExporter::getSupportedExtensions());
258 case LayerFileNoMidi:
259 settingsKeyStub =
"savelayer";
260 title = tr(
"Select a file to export to");
261 filter = tr(
"Sonic Visualiser Layer XML files (*.svl)\nComma-separated data files (*.csv)\nRDF/Turtle files (%1)\nText files (*.txt)\nAll files (*.*)").arg(RDFExporter::getSupportedExtensions());
265 settingsKeyStub =
"savelayer";
266 title = tr(
"Select a file to export to");
267 filter = tr(
"Comma-separated data files (*.csv)\nSonic Visualiser Layer XML files (*.svl)\nRDF/Turtle files (%1)\nMIDI files (*.mid)\nText files (*.txt)\nAll files (*.*)").arg(RDFExporter::getSupportedExtensions());
270 case LayerFileNoMidiNonSV:
271 settingsKeyStub =
"savelayer";
272 title = tr(
"Select a file to export to");
273 filter = tr(
"Comma-separated data files (*.csv)\nSonic Visualiser Layer XML files (*.svl)\nRDF/Turtle files (%1)\nText files (*.txt)\nAll files (*.*)").arg(RDFExporter::getSupportedExtensions());
276 case SessionOrAudioFile:
277 cerr <<
"ERROR: Internal error: InteractiveFileFinder::getSaveFileName: SessionOrAudioFile cannot be used here" << endl;
281 settingsKeyStub =
"saveimage";
282 title = tr(
"Select a file to export to");
283 filter = tr(
"Portable Network Graphics files (*.png)\nAll files (*.*)");
287 settingsKeyStub =
"savelayer";
288 title = tr(
"Select a file to export to");
289 filter = tr(
"Comma-separated data files (*.csv)\nText files (*.txt)\nAll files (*.*)");
293 cerr <<
"ERROR: Internal error: InteractiveFileFinder::getSaveFileName: AnyFile cannot be used here" << endl;
297 if (lastPath ==
"") {
298 char *home = getenv(
"HOME");
299 if (home) lastPath = home;
301 }
else if (QFileInfo(lastPath).isDir()) {
302 lastPath = QFileInfo(lastPath).canonicalPath();
304 lastPath = QFileInfo(lastPath).absoluteDir().canonicalPath();
308 settings.beginGroup(
"FileFinder");
309 lastPath = settings.value(settingsKeyStub +
"path", lastPath).toString();
318 QStringList filters = filter.split(
'\n');
320 dialog.setNameFilters(filters);
321 dialog.setWindowTitle(title);
322 dialog.setDirectory(lastPath);
323 dialog.setAcceptMode(QFileDialog::AcceptSave);
324 dialog.setFileMode(QFileDialog::AnyFile);
325 dialog.setConfirmOverwrite(
false);
327 QString defaultSuffix;
328 if (type == SessionFile) {
330 }
else if (type == AudioFile) {
331 defaultSuffix =
"wav";
332 }
else if (type == ImageFile) {
333 defaultSuffix =
"png";
334 }
else if (type == CSVFile) {
335 defaultSuffix =
"csv";
339 settings.value(settingsKeyStub +
"suffix", defaultSuffix).toString();
341 dialog.setDefaultSuffix(defaultSuffix);
343 foreach (QString f, filters) {
344 if (f.contains(
"." + defaultSuffix)) {
345 dialog.selectNameFilter(f);
355 if (!dialog.exec())
break;
357 QStringList files = dialog.selectedFiles();
358 if (files.empty())
break;
359 path = *files.begin();
363 cerr <<
"type = " << type <<
", suffix = " << fi.suffix() << endl;
365 if ((type == LayerFile || type == LayerFileNoMidi ||
366 type == LayerFileNonSV || type == LayerFileNoMidiNonSV)
367 && fi.suffix() ==
"") {
368 QString expectedExtension;
369 QString selectedFilter = dialog.selectedNameFilter();
370 if (selectedFilter.contains(
".svl")) {
371 expectedExtension =
"svl";
372 }
else if (selectedFilter.contains(
".txt")) {
373 expectedExtension =
"txt";
374 }
else if (selectedFilter.contains(
".csv")) {
375 expectedExtension =
"csv";
376 }
else if (selectedFilter.contains(
".mid")) {
377 expectedExtension =
"mid";
378 }
else if (selectedFilter.contains(
".ttl")) {
379 expectedExtension =
"ttl";
381 cerr <<
"expected extension = " << expectedExtension << endl;
382 if (expectedExtension !=
"") {
383 path = QString(
"%1.%2").arg(path).arg(expectedExtension);
384 fi = QFileInfo(path);
389 QMessageBox::critical(0, tr(
"Directory selected"),
390 tr(
"<b>Directory selected</b><p>File \"%1\" is a directory").arg(path));
395 if (QMessageBox::question(0, tr(
"File exists"),
396 tr(
"<b>File exists</b><p>The file \"%1\" already exists.\nDo you want to overwrite it?").arg(path),
398 QMessageBox::Cancel) != QMessageBox::Ok) {
407 settings.setValue(settingsKeyStub +
"path",
408 QFileInfo(path).absoluteDir().canonicalPath());
409 settings.setValue(settingsKeyStub +
"suffix",
410 QFileInfo(path).suffix());
419 QString settingsKeyStub;
423 settingsKeyStub =
"session";
427 settingsKeyStub =
"audio";
431 settingsKeyStub =
"layer";
434 case LayerFileNoMidi:
435 settingsKeyStub =
"layer";
439 settingsKeyStub =
"layer";
442 case LayerFileNoMidiNonSV:
443 settingsKeyStub =
"layer";
446 case SessionOrAudioFile:
447 settingsKeyStub =
"last";
451 settingsKeyStub =
"image";
455 settingsKeyStub =
"layer";
459 settingsKeyStub =
"last";
465 settings.beginGroup(
"FileFinder");
466 path = QFileInfo(path).absoluteDir().canonicalPath();
467 QString suffix = QFileInfo(path).suffix();
468 settings.setValue(settingsKeyStub +
"path", path);
469 settings.setValue(settingsKeyStub +
"suffix", suffix);
470 settings.setValue(
"lastpath", path);
477 if (FileSource::canHandleScheme(location)) {
478 if (FileSource(location).isAvailable()) {
479 SVDEBUG <<
"InteractiveFileFinder::find: ok, it's available... returning" << endl;
484 if (QFileInfo(location).exists())
return location;
486 QString foundAt =
"";
488 if ((foundAt =
findRelative(location, lastKnownLocation)) !=
"") {
502 if (relativeTo ==
"")
return "";
504 SVDEBUG <<
"Looking for \"" << location <<
"\" next to \"" 505 << relativeTo <<
"\"..." << endl;
510 if (FileSource::isRemote(location)) {
511 fileName = QUrl(location).path().section(
'/', -1, -1,
512 QString::SectionSkipEmpty);
514 if (QUrl(location).scheme() ==
"file") {
515 location = QUrl(location).toLocalFile();
517 fileName = QFileInfo(location).fileName();
520 if (FileSource::isRemote(relativeTo)) {
521 resolved = QUrl(relativeTo).resolved(fileName).toString();
522 if (!FileSource(resolved).isAvailable()) resolved =
"";
523 cerr <<
"resolved: " << resolved << endl;
525 if (QUrl(relativeTo).scheme() ==
"file") {
526 relativeTo = QUrl(relativeTo).toLocalFile();
528 resolved = QFileInfo(relativeTo).dir().filePath(fileName);
529 if (!QFileInfo(resolved).exists() ||
530 !QFileInfo(resolved).isFile() ||
531 !QFileInfo(resolved).isReadable()) {
543 if (type == AudioFile) {
544 question = tr(
"<b>File not found</b><p>Audio file \"%1\" could not be opened.\nDo you want to locate it?");
546 question = tr(
"<b>File not found</b><p>File \"%1\" could not be opened.\nDo you want to locate it?");
554 int rv = QMessageBox::question
556 tr(
"Failed to open file"),
558 tr(
"Locate file..."),
567 if (QFileInfo(thing).dir().exists()) {
568 path = QFileInfo(thing).dir().canonicalPath();
578 path = QInputDialog::getText
580 tr(
"Please enter the URL to use for this file:"),
581 QLineEdit::Normal,
"", &ok);
583 if (ok && path !=
"") {
584 if (FileSource(path).isAvailable()) {
587 QMessageBox::critical
588 (0, tr(
"Failed to open location"),
589 tr(
"<b>Failed to open location</b><p>URL \"%1\" could not be opened").arg(path));
static void setParentWidget(QWidget *)
QString find(FileType type, QString location, QString lastKnownLocation="")
QString getOpenFileName(FileType type, QString fallbackLocation="")
QString m_lastLocatedLocation
QString locateInteractive(FileType type, QString thing)
void setApplicationSessionExtension(QString extension)
Specify the extension for this application's session files (without the dot)
virtual ~InteractiveFileFinder()
void registerLastOpenedFilePath(FileType type, QString path)
QString getSaveFileName(FileType type, QString fallbackLocation="")
QString findRelative(QString location, QString relativeTo)
static InteractiveFileFinder m_instance
QString m_sessionExtension
static InteractiveFileFinder * getInstance()