annotate widgets/InteractiveFileFinder.cpp @ 1160:a429b2acb45d 3.0-integration

Make SVDEBUG always write to a log file -- formerly this was disabled in NDEBUG builds. I think there's little use to that, it just means that we keep adding more cerr debug output because we aren't getting the log we need. And SVDEBUG logging is not usually used in tight loops, I don't think the performance overhead is too serious. Also update the About box.
author Chris Cannam
date Thu, 03 Nov 2016 14:57:00 +0000
parents 831188672987
children 6828735468c9
rev   line source
Chris@529 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@529 2
Chris@529 3 /*
Chris@529 4 Sonic Visualiser
Chris@529 5 An audio file viewer and annotation editor.
Chris@529 6 Centre for Digital Music, Queen Mary, University of London.
Chris@529 7 This file copyright 2007 QMUL.
Chris@529 8
Chris@529 9 This program is free software; you can redistribute it and/or
Chris@529 10 modify it under the terms of the GNU General Public License as
Chris@529 11 published by the Free Software Foundation; either version 2 of the
Chris@529 12 License, or (at your option) any later version. See the file
Chris@529 13 COPYING included with this distribution for more information.
Chris@529 14 */
Chris@529 15
Chris@529 16 #include "InteractiveFileFinder.h"
Chris@529 17 #include "data/fileio/FileSource.h"
Chris@529 18 #include "data/fileio/AudioFileReaderFactory.h"
Chris@529 19 #include "data/fileio/DataFileReaderFactory.h"
Chris@529 20 #include "rdf/RDFImporter.h"
Chris@529 21 #include "rdf/RDFExporter.h"
Chris@529 22
Chris@529 23 #include <QFileInfo>
Chris@529 24 #include <QMessageBox>
Chris@529 25 #include <QFileDialog>
Chris@529 26 #include <QInputDialog>
Chris@529 27 #include <QImageReader>
Chris@529 28 #include <QSettings>
Chris@529 29
Chris@529 30 #include <iostream>
Chris@529 31
Chris@529 32 InteractiveFileFinder
Chris@529 33 InteractiveFileFinder::m_instance;
Chris@529 34
Chris@529 35 InteractiveFileFinder::InteractiveFileFinder() :
Chris@760 36 m_sessionExtension("sv"),
Chris@831 37 m_lastLocatedLocation(""),
Chris@831 38 m_parent(0)
Chris@529 39 {
Chris@529 40 FileFinder::registerFileFinder(this);
Chris@529 41 }
Chris@529 42
Chris@529 43 InteractiveFileFinder::~InteractiveFileFinder()
Chris@529 44 {
Chris@529 45 }
Chris@529 46
Chris@760 47 void
Chris@831 48 InteractiveFileFinder::setParentWidget(QWidget *parent)
Chris@831 49 {
Chris@831 50 getInstance()->m_parent = parent;
Chris@831 51 }
Chris@831 52
Chris@831 53 void
Chris@760 54 InteractiveFileFinder::setApplicationSessionExtension(QString extension)
Chris@760 55 {
Chris@760 56 m_sessionExtension = extension;
Chris@760 57 }
Chris@760 58
Chris@529 59 QString
Chris@529 60 InteractiveFileFinder::getOpenFileName(FileType type, QString fallbackLocation)
Chris@529 61 {
Chris@778 62 QString settingsKeyStub;
Chris@529 63 QString lastPath = fallbackLocation;
Chris@529 64
Chris@529 65 QString title = tr("Select file");
Chris@529 66 QString filter = tr("All files (*.*)");
Chris@529 67
Chris@529 68 switch (type) {
Chris@529 69
Chris@529 70 case SessionFile:
Chris@778 71 settingsKeyStub = "session";
Chris@529 72 title = tr("Select a session file");
Chris@760 73 filter = tr("%1 session files (*.%1)\nRDF files (%3)\nAll files (*.*)")
Chris@760 74 .arg(QApplication::applicationName())
Chris@760 75 .arg(m_sessionExtension)
Chris@760 76 .arg(RDFImporter::getKnownExtensions());
Chris@529 77 break;
Chris@529 78
Chris@529 79 case AudioFile:
Chris@778 80 settingsKeyStub = "audio";
Chris@529 81 title = "Select an audio file";
Chris@529 82 filter = tr("Audio files (%1)\nAll files (*.*)")
Chris@529 83 .arg(AudioFileReaderFactory::getKnownExtensions());
Chris@529 84 break;
Chris@529 85
Chris@529 86 case LayerFile:
Chris@778 87 settingsKeyStub = "layer";
Chris@529 88 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 (*.*)")
Chris@529 89 .arg(DataFileReaderFactory::getKnownExtensions())
Chris@529 90 .arg(RDFImporter::getKnownExtensions());
Chris@529 91 break;
Chris@529 92
Chris@529 93 case LayerFileNoMidi:
Chris@778 94 settingsKeyStub = "layer";
Chris@529 95 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 (*.*)")
Chris@529 96 .arg(DataFileReaderFactory::getKnownExtensions())
Chris@529 97 .arg(RDFImporter::getKnownExtensions());
Chris@529 98 break;
Chris@529 99
Chris@705 100 case LayerFileNonSV:
Chris@778 101 settingsKeyStub = "layer";
Chris@705 102 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 (*.*)")
Chris@705 103 .arg(DataFileReaderFactory::getKnownExtensions())
Chris@705 104 .arg(RDFImporter::getKnownExtensions());
Chris@705 105 break;
Chris@705 106
Chris@705 107 case LayerFileNoMidiNonSV:
Chris@778 108 settingsKeyStub = "layer";
Chris@705 109 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 (*.*)")
Chris@705 110 .arg(DataFileReaderFactory::getKnownExtensions())
Chris@705 111 .arg(RDFImporter::getKnownExtensions());
Chris@705 112 break;
Chris@705 113
Chris@529 114 case SessionOrAudioFile:
Chris@778 115 settingsKeyStub = "last";
Chris@760 116 filter = tr("All supported files (*.sv %1 %2)\n%3 session files (*.%4)\nAudio files (%2)\nRDF files (%1)\nAll files (*.*)")
Chris@529 117 .arg(RDFImporter::getKnownExtensions())
Chris@760 118 .arg(AudioFileReaderFactory::getKnownExtensions())
Chris@760 119 .arg(QApplication::applicationName())
Chris@760 120 .arg(m_sessionExtension);
Chris@529 121 break;
Chris@529 122
Chris@529 123 case ImageFile:
Chris@778 124 settingsKeyStub = "image";
Chris@529 125 {
Chris@529 126 QStringList fmts;
Chris@529 127 QList<QByteArray> formats = QImageReader::supportedImageFormats();
Chris@529 128 for (QList<QByteArray>::iterator i = formats.begin();
Chris@529 129 i != formats.end(); ++i) {
Chris@529 130 fmts.push_back(QString("*.%1")
Chris@529 131 .arg(QString::fromLocal8Bit(*i).toLower()));
Chris@529 132 }
Chris@529 133 filter = tr("Image files (%1)\nAll files (*.*)").arg(fmts.join(" "));
Chris@529 134 }
Chris@529 135 break;
Chris@529 136
Chris@672 137 case CSVFile:
Chris@778 138 settingsKeyStub = "layer";
Chris@672 139 filter = tr("Comma-separated data files (*.csv)\nSpace-separated .lab files (*.lab)\nText files (*.txt)\nAll files (*.*)");
Chris@672 140 break;
Chris@672 141
Chris@529 142 case AnyFile:
Chris@778 143 settingsKeyStub = "last";
Chris@760 144 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 (*.*)")
Chris@529 145 .arg(AudioFileReaderFactory::getKnownExtensions())
Chris@529 146 .arg(DataFileReaderFactory::getKnownExtensions())
Chris@760 147 .arg(RDFImporter::getKnownExtensions())
Chris@760 148 .arg(QApplication::applicationName())
Chris@760 149 .arg(m_sessionExtension);
Chris@529 150 break;
Chris@529 151 };
Chris@529 152
Chris@529 153 if (lastPath == "") {
Chris@529 154 char *home = getenv("HOME");
Chris@529 155 if (home) lastPath = home;
Chris@529 156 else lastPath = ".";
Chris@529 157 } else if (QFileInfo(lastPath).isDir()) {
Chris@529 158 lastPath = QFileInfo(lastPath).canonicalPath();
Chris@529 159 } else {
Chris@529 160 lastPath = QFileInfo(lastPath).absoluteDir().canonicalPath();
Chris@529 161 }
Chris@529 162
Chris@529 163 QSettings settings;
Chris@529 164 settings.beginGroup("FileFinder");
Chris@778 165 lastPath = settings.value(settingsKeyStub + "path", lastPath).toString();
Chris@529 166
Chris@529 167 QString path = "";
Chris@529 168
Chris@529 169 // Use our own QFileDialog just for symmetry with getSaveFileName below
Chris@529 170
Chris@831 171 QFileDialog dialog(m_parent);
Chris@616 172 dialog.setNameFilters(filter.split('\n'));
Chris@529 173 dialog.setWindowTitle(title);
Chris@529 174 dialog.setDirectory(lastPath);
Chris@529 175
Chris@529 176 dialog.setAcceptMode(QFileDialog::AcceptOpen);
Chris@529 177 dialog.setFileMode(QFileDialog::ExistingFile);
Chris@529 178
Chris@529 179 if (dialog.exec()) {
Chris@529 180 QStringList files = dialog.selectedFiles();
Chris@529 181 if (!files.empty()) path = *files.begin();
Chris@529 182
Chris@529 183 QFileInfo fi(path);
Chris@529 184
Chris@529 185 if (!fi.exists()) {
Chris@529 186
Chris@529 187 QMessageBox::critical(0, tr("File does not exist"),
Chris@529 188 tr("<b>File not found</b><p>File \"%1\" does not exist").arg(path));
Chris@529 189 path = "";
Chris@529 190
Chris@529 191 } else if (!fi.isReadable()) {
Chris@529 192
Chris@529 193 QMessageBox::critical(0, tr("File is not readable"),
Chris@529 194 tr("<b>File is not readable</b><p>File \"%1\" can not be read").arg(path));
Chris@529 195 path = "";
Chris@529 196
Chris@529 197 } else if (fi.isDir()) {
Chris@529 198
Chris@529 199 QMessageBox::critical(0, tr("Directory selected"),
Chris@529 200 tr("<b>Directory selected</b><p>File \"%1\" is a directory").arg(path));
Chris@529 201 path = "";
Chris@529 202
Chris@529 203 } else if (!fi.isFile()) {
Chris@529 204
Chris@529 205 QMessageBox::critical(0, tr("Non-file selected"),
Chris@529 206 tr("<b>Not a file</b><p>Path \"%1\" is not a file").arg(path));
Chris@529 207 path = "";
Chris@529 208
Chris@529 209 } else if (fi.size() == 0) {
Chris@529 210
Chris@529 211 QMessageBox::critical(0, tr("File is empty"),
Chris@529 212 tr("<b>File is empty</b><p>File \"%1\" is empty").arg(path));
Chris@529 213 path = "";
Chris@529 214 }
Chris@529 215 }
Chris@529 216
Chris@529 217 if (path != "") {
Chris@778 218 settings.setValue(settingsKeyStub + "path",
Chris@529 219 QFileInfo(path).absoluteDir().canonicalPath());
Chris@529 220 }
Chris@529 221
Chris@529 222 return path;
Chris@529 223 }
Chris@529 224
Chris@529 225 QString
Chris@794 226 InteractiveFileFinder::getSaveFileName(FileType type,
Chris@794 227 QString fallbackLocation)
Chris@529 228 {
Chris@778 229 QString settingsKeyStub;
Chris@529 230 QString lastPath = fallbackLocation;
Chris@529 231
Chris@529 232 QString title = tr("Select file");
Chris@529 233 QString filter = tr("All files (*.*)");
Chris@529 234
Chris@529 235 switch (type) {
Chris@529 236
Chris@529 237 case SessionFile:
Chris@778 238 settingsKeyStub = "savesession";
Chris@529 239 title = tr("Select a session file");
Chris@760 240 filter = tr("%1 session files (*.%2)\nAll files (*.*)")
Chris@760 241 .arg(QApplication::applicationName()).arg(m_sessionExtension);
Chris@529 242 break;
Chris@529 243
Chris@529 244 case AudioFile:
Chris@778 245 settingsKeyStub = "saveaudio";
Chris@529 246 title = "Select an audio file";
Chris@529 247 title = tr("Select a file to export to");
Chris@529 248 filter = tr("WAV audio files (*.wav)\nAll files (*.*)");
Chris@529 249 break;
Chris@529 250
Chris@529 251 case LayerFile:
Chris@778 252 settingsKeyStub = "savelayer";
Chris@529 253 title = tr("Select a file to export to");
Chris@529 254 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());
Chris@529 255 break;
Chris@529 256
Chris@529 257 case LayerFileNoMidi:
Chris@778 258 settingsKeyStub = "savelayer";
Chris@529 259 title = tr("Select a file to export to");
Chris@529 260 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());
Chris@529 261 break;
Chris@529 262
Chris@705 263 case LayerFileNonSV:
Chris@778 264 settingsKeyStub = "savelayer";
Chris@705 265 title = tr("Select a file to export to");
Chris@705 266 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());
Chris@705 267 break;
Chris@705 268
Chris@705 269 case LayerFileNoMidiNonSV:
Chris@778 270 settingsKeyStub = "savelayer";
Chris@705 271 title = tr("Select a file to export to");
Chris@705 272 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());
Chris@705 273 break;
Chris@705 274
Chris@529 275 case SessionOrAudioFile:
Chris@682 276 cerr << "ERROR: Internal error: InteractiveFileFinder::getSaveFileName: SessionOrAudioFile cannot be used here" << endl;
Chris@529 277 abort();
Chris@529 278
Chris@529 279 case ImageFile:
Chris@778 280 settingsKeyStub = "saveimage";
Chris@529 281 title = tr("Select a file to export to");
Chris@529 282 filter = tr("Portable Network Graphics files (*.png)\nAll files (*.*)");
Chris@529 283 break;
Chris@529 284
Chris@672 285 case CSVFile:
Chris@778 286 settingsKeyStub = "savelayer";
Chris@672 287 title = tr("Select a file to export to");
Chris@672 288 filter = tr("Comma-separated data files (*.csv)\nText files (*.txt)\nAll files (*.*)");
Chris@672 289 break;
Chris@672 290
Chris@529 291 case AnyFile:
Chris@682 292 cerr << "ERROR: Internal error: InteractiveFileFinder::getSaveFileName: AnyFile cannot be used here" << endl;
Chris@529 293 abort();
Chris@529 294 };
Chris@529 295
Chris@529 296 if (lastPath == "") {
Chris@529 297 char *home = getenv("HOME");
Chris@529 298 if (home) lastPath = home;
Chris@529 299 else lastPath = ".";
Chris@529 300 } else if (QFileInfo(lastPath).isDir()) {
Chris@529 301 lastPath = QFileInfo(lastPath).canonicalPath();
Chris@529 302 } else {
Chris@529 303 lastPath = QFileInfo(lastPath).absoluteDir().canonicalPath();
Chris@529 304 }
Chris@529 305
Chris@529 306 QSettings settings;
Chris@529 307 settings.beginGroup("FileFinder");
Chris@778 308 lastPath = settings.value(settingsKeyStub + "path", lastPath).toString();
Chris@529 309
Chris@529 310 QString path = "";
Chris@529 311
Chris@529 312 // Use our own QFileDialog instead of static functions, as we may
Chris@529 313 // need to adjust the file extension based on the selected filter
Chris@529 314
Chris@831 315 QFileDialog dialog(m_parent);
Chris@778 316
Chris@778 317 QStringList filters = filter.split('\n');
Chris@778 318
Chris@778 319 dialog.setNameFilters(filters);
Chris@529 320 dialog.setWindowTitle(title);
Chris@529 321 dialog.setDirectory(lastPath);
Chris@529 322 dialog.setAcceptMode(QFileDialog::AcceptSave);
Chris@529 323 dialog.setFileMode(QFileDialog::AnyFile);
Chris@529 324 dialog.setConfirmOverwrite(false); // we'll do that
Chris@778 325
Chris@778 326 QString defaultSuffix;
Chris@529 327 if (type == SessionFile) {
Chris@778 328 defaultSuffix = m_sessionExtension;
Chris@529 329 } else if (type == AudioFile) {
Chris@778 330 defaultSuffix = "wav";
Chris@529 331 } else if (type == ImageFile) {
Chris@778 332 defaultSuffix = "png";
Chris@672 333 } else if (type == CSVFile) {
Chris@778 334 defaultSuffix = "csv";
Chris@778 335 }
Chris@778 336
Chris@778 337 defaultSuffix =
Chris@778 338 settings.value(settingsKeyStub + "suffix", defaultSuffix).toString();
Chris@778 339
Chris@778 340 dialog.setDefaultSuffix(defaultSuffix);
Chris@778 341
Chris@778 342 foreach (QString f, filters) {
Chris@778 343 if (f.contains("." + defaultSuffix)) {
Chris@778 344 dialog.selectNameFilter(f);
Chris@778 345 }
Chris@529 346 }
Chris@529 347
Chris@529 348 bool good = false;
Chris@529 349
Chris@529 350 while (!good) {
Chris@529 351
Chris@529 352 path = "";
Chris@529 353
Chris@529 354 if (!dialog.exec()) break;
Chris@529 355
Chris@529 356 QStringList files = dialog.selectedFiles();
Chris@529 357 if (files.empty()) break;
Chris@529 358 path = *files.begin();
Chris@529 359
Chris@529 360 QFileInfo fi(path);
Chris@529 361
Chris@682 362 cerr << "type = " << type << ", suffix = " << fi.suffix() << endl;
Chris@529 363
Chris@705 364 if ((type == LayerFile || type == LayerFileNoMidi ||
Chris@705 365 type == LayerFileNonSV || type == LayerFileNoMidiNonSV)
Chris@529 366 && fi.suffix() == "") {
Chris@529 367 QString expectedExtension;
Chris@616 368 QString selectedFilter = dialog.selectedNameFilter();
Chris@529 369 if (selectedFilter.contains(".svl")) {
Chris@529 370 expectedExtension = "svl";
Chris@529 371 } else if (selectedFilter.contains(".txt")) {
Chris@529 372 expectedExtension = "txt";
Chris@529 373 } else if (selectedFilter.contains(".csv")) {
Chris@529 374 expectedExtension = "csv";
Chris@529 375 } else if (selectedFilter.contains(".mid")) {
Chris@529 376 expectedExtension = "mid";
Chris@529 377 } else if (selectedFilter.contains(".ttl")) {
Chris@529 378 expectedExtension = "ttl";
Chris@529 379 }
Chris@682 380 cerr << "expected extension = " << expectedExtension << endl;
Chris@529 381 if (expectedExtension != "") {
Chris@529 382 path = QString("%1.%2").arg(path).arg(expectedExtension);
Chris@529 383 fi = QFileInfo(path);
Chris@529 384 }
Chris@529 385 }
Chris@529 386
Chris@529 387 if (fi.isDir()) {
Chris@529 388 QMessageBox::critical(0, tr("Directory selected"),
Chris@529 389 tr("<b>Directory selected</b><p>File \"%1\" is a directory").arg(path));
Chris@529 390 continue;
Chris@529 391 }
Chris@529 392
Chris@529 393 if (fi.exists()) {
Chris@529 394 if (QMessageBox::question(0, tr("File exists"),
Chris@529 395 tr("<b>File exists</b><p>The file \"%1\" already exists.\nDo you want to overwrite it?").arg(path),
Chris@529 396 QMessageBox::Ok,
Chris@529 397 QMessageBox::Cancel) != QMessageBox::Ok) {
Chris@529 398 continue;
Chris@529 399 }
Chris@529 400 }
Chris@529 401
Chris@529 402 good = true;
Chris@529 403 }
Chris@529 404
Chris@529 405 if (path != "") {
Chris@778 406 settings.setValue(settingsKeyStub + "path",
Chris@529 407 QFileInfo(path).absoluteDir().canonicalPath());
Chris@778 408 settings.setValue(settingsKeyStub + "suffix",
Chris@778 409 QFileInfo(path).suffix());
Chris@529 410 }
Chris@529 411
Chris@529 412 return path;
Chris@529 413 }
Chris@529 414
Chris@529 415 void
Chris@529 416 InteractiveFileFinder::registerLastOpenedFilePath(FileType type, QString path)
Chris@529 417 {
Chris@778 418 QString settingsKeyStub;
Chris@529 419
Chris@529 420 switch (type) {
Chris@529 421 case SessionFile:
Chris@778 422 settingsKeyStub = "session";
Chris@529 423 break;
Chris@529 424
Chris@529 425 case AudioFile:
Chris@778 426 settingsKeyStub = "audio";
Chris@529 427 break;
Chris@529 428
Chris@529 429 case LayerFile:
Chris@778 430 settingsKeyStub = "layer";
Chris@529 431 break;
Chris@529 432
Chris@529 433 case LayerFileNoMidi:
Chris@778 434 settingsKeyStub = "layer";
Chris@529 435 break;
Chris@529 436
Chris@705 437 case LayerFileNonSV:
Chris@778 438 settingsKeyStub = "layer";
Chris@705 439 break;
Chris@705 440
Chris@705 441 case LayerFileNoMidiNonSV:
Chris@778 442 settingsKeyStub = "layer";
Chris@705 443 break;
Chris@705 444
Chris@529 445 case SessionOrAudioFile:
Chris@778 446 settingsKeyStub = "last";
Chris@529 447 break;
Chris@529 448
Chris@529 449 case ImageFile:
Chris@778 450 settingsKeyStub = "image";
Chris@529 451 break;
Chris@529 452
Chris@672 453 case CSVFile:
Chris@778 454 settingsKeyStub = "layer";
Chris@672 455 break;
Chris@672 456
Chris@529 457 case AnyFile:
Chris@778 458 settingsKeyStub = "last";
Chris@529 459 break;
Chris@529 460 }
Chris@529 461
Chris@529 462 if (path != "") {
Chris@529 463 QSettings settings;
Chris@529 464 settings.beginGroup("FileFinder");
Chris@529 465 path = QFileInfo(path).absoluteDir().canonicalPath();
Chris@778 466 QString suffix = QFileInfo(path).suffix();
Chris@778 467 settings.setValue(settingsKeyStub + "path", path);
Chris@778 468 settings.setValue(settingsKeyStub + "suffix", suffix);
Chris@529 469 settings.setValue("lastpath", path);
Chris@529 470 }
Chris@529 471 }
Chris@529 472
Chris@529 473 QString
Chris@529 474 InteractiveFileFinder::find(FileType type, QString location, QString lastKnownLocation)
Chris@529 475 {
Chris@529 476 if (FileSource::canHandleScheme(location)) {
Chris@529 477 if (FileSource(location).isAvailable()) {
Chris@587 478 SVDEBUG << "InteractiveFileFinder::find: ok, it's available... returning" << endl;
Chris@529 479 return location;
Chris@529 480 }
Chris@529 481 }
Chris@529 482
Chris@529 483 if (QFileInfo(location).exists()) return location;
Chris@529 484
Chris@529 485 QString foundAt = "";
Chris@529 486
Chris@529 487 if ((foundAt = findRelative(location, lastKnownLocation)) != "") {
Chris@529 488 return foundAt;
Chris@529 489 }
Chris@529 490
Chris@529 491 if ((foundAt = findRelative(location, m_lastLocatedLocation)) != "") {
Chris@529 492 return foundAt;
Chris@529 493 }
Chris@529 494
Chris@529 495 return locateInteractive(type, location);
Chris@529 496 }
Chris@529 497
Chris@529 498 QString
Chris@529 499 InteractiveFileFinder::findRelative(QString location, QString relativeTo)
Chris@529 500 {
Chris@529 501 if (relativeTo == "") return "";
Chris@529 502
Chris@587 503 SVDEBUG << "Looking for \"" << location << "\" next to \""
Chris@585 504 << relativeTo << "\"..." << endl;
Chris@529 505
Chris@529 506 QString fileName;
Chris@529 507 QString resolved;
Chris@529 508
Chris@529 509 if (FileSource::isRemote(location)) {
Chris@529 510 fileName = QUrl(location).path().section('/', -1, -1,
Chris@529 511 QString::SectionSkipEmpty);
Chris@529 512 } else {
Chris@529 513 if (QUrl(location).scheme() == "file") {
Chris@529 514 location = QUrl(location).toLocalFile();
Chris@529 515 }
Chris@529 516 fileName = QFileInfo(location).fileName();
Chris@529 517 }
Chris@529 518
Chris@529 519 if (FileSource::isRemote(relativeTo)) {
Chris@529 520 resolved = QUrl(relativeTo).resolved(fileName).toString();
Chris@529 521 if (!FileSource(resolved).isAvailable()) resolved = "";
Chris@682 522 cerr << "resolved: " << resolved << endl;
Chris@529 523 } else {
Chris@529 524 if (QUrl(relativeTo).scheme() == "file") {
Chris@529 525 relativeTo = QUrl(relativeTo).toLocalFile();
Chris@529 526 }
Chris@529 527 resolved = QFileInfo(relativeTo).dir().filePath(fileName);
Chris@529 528 if (!QFileInfo(resolved).exists() ||
Chris@529 529 !QFileInfo(resolved).isFile() ||
Chris@529 530 !QFileInfo(resolved).isReadable()) {
Chris@529 531 resolved = "";
Chris@529 532 }
Chris@529 533 }
Chris@529 534
Chris@529 535 return resolved;
Chris@529 536 }
Chris@529 537
Chris@529 538 QString
Chris@529 539 InteractiveFileFinder::locateInteractive(FileType type, QString thing)
Chris@529 540 {
Chris@529 541 QString question;
Chris@529 542 if (type == AudioFile) {
Chris@529 543 question = tr("<b>File not found</b><p>Audio file \"%1\" could not be opened.\nDo you want to locate it?");
Chris@529 544 } else {
Chris@529 545 question = tr("<b>File not found</b><p>File \"%1\" could not be opened.\nDo you want to locate it?");
Chris@529 546 }
Chris@529 547
Chris@529 548 QString path = "";
Chris@529 549 bool done = false;
Chris@529 550
Chris@529 551 while (!done) {
Chris@529 552
Chris@529 553 int rv = QMessageBox::question
Chris@529 554 (0,
Chris@529 555 tr("Failed to open file"),
Chris@529 556 question.arg(thing),
Chris@529 557 tr("Locate file..."),
Chris@529 558 tr("Use URL..."),
Chris@529 559 tr("Cancel"),
Chris@529 560 0, 2);
Chris@529 561
Chris@529 562 switch (rv) {
Chris@529 563
Chris@529 564 case 0: // Locate file
Chris@529 565
Chris@529 566 if (QFileInfo(thing).dir().exists()) {
Chris@529 567 path = QFileInfo(thing).dir().canonicalPath();
Chris@529 568 }
Chris@529 569
Chris@529 570 path = getOpenFileName(type, path);
Chris@529 571 done = (path != "");
Chris@529 572 break;
Chris@529 573
Chris@529 574 case 1: // Use URL
Chris@529 575 {
Chris@529 576 bool ok = false;
Chris@529 577 path = QInputDialog::getText
Chris@529 578 (0, tr("Use URL"),
Chris@529 579 tr("Please enter the URL to use for this file:"),
Chris@529 580 QLineEdit::Normal, "", &ok);
Chris@529 581
Chris@529 582 if (ok && path != "") {
Chris@529 583 if (FileSource(path).isAvailable()) {
Chris@529 584 done = true;
Chris@529 585 } else {
Chris@529 586 QMessageBox::critical
Chris@529 587 (0, tr("Failed to open location"),
Chris@529 588 tr("<b>Failed to open location</b><p>URL \"%1\" could not be opened").arg(path));
Chris@529 589 path = "";
Chris@529 590 }
Chris@529 591 }
Chris@529 592 break;
Chris@529 593 }
Chris@529 594
Chris@529 595 case 2: // Cancel
Chris@529 596 path = "";
Chris@529 597 done = true;
Chris@529 598 break;
Chris@529 599 }
Chris@529 600 }
Chris@529 601
Chris@529 602 if (path != "") m_lastLocatedLocation = path;
Chris@529 603 return path;
Chris@529 604 }
Chris@529 605
Chris@529 606