annotate widgets/InteractiveFileFinder.cpp @ 738:d26545a2a02d tonioni

Rather than undrawing the bottom bit of the dial, don't draw it in the first place (necessary on shaded background)
author Chris Cannam
date Thu, 06 Mar 2014 13:52:33 +0000
parents 52e5f6fe31ad
children d0fd7630d32f
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@529 36 m_lastLocatedLocation("")
Chris@529 37 {
Chris@587 38 SVDEBUG << "Registering interactive file finder" << endl;
Chris@529 39 FileFinder::registerFileFinder(this);
Chris@529 40 }
Chris@529 41
Chris@529 42 InteractiveFileFinder::~InteractiveFileFinder()
Chris@529 43 {
Chris@529 44 }
Chris@529 45
Chris@529 46 QString
Chris@529 47 InteractiveFileFinder::getOpenFileName(FileType type, QString fallbackLocation)
Chris@529 48 {
Chris@529 49 QString settingsKey;
Chris@529 50 QString lastPath = fallbackLocation;
Chris@529 51
Chris@529 52 QString title = tr("Select file");
Chris@529 53 QString filter = tr("All files (*.*)");
Chris@529 54
Chris@529 55 switch (type) {
Chris@529 56
Chris@529 57 case SessionFile:
Chris@529 58 settingsKey = "sessionpath";
Chris@529 59 title = tr("Select a session file");
Chris@529 60 filter = tr("Sonic Visualiser session files (*.sv)\nRDF files (%1)\nAll files (*.*)").arg(RDFImporter::getKnownExtensions());
Chris@529 61 break;
Chris@529 62
Chris@529 63 case AudioFile:
Chris@529 64 settingsKey = "audiopath";
Chris@529 65 title = "Select an audio file";
Chris@529 66 filter = tr("Audio files (%1)\nAll files (*.*)")
Chris@529 67 .arg(AudioFileReaderFactory::getKnownExtensions());
Chris@529 68 break;
Chris@529 69
Chris@529 70 case LayerFile:
Chris@529 71 settingsKey = "layerpath";
Chris@529 72 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 73 .arg(DataFileReaderFactory::getKnownExtensions())
Chris@529 74 .arg(RDFImporter::getKnownExtensions());
Chris@529 75 break;
Chris@529 76
Chris@529 77 case LayerFileNoMidi:
Chris@529 78 settingsKey = "layerpath";
Chris@529 79 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 80 .arg(DataFileReaderFactory::getKnownExtensions())
Chris@529 81 .arg(RDFImporter::getKnownExtensions());
Chris@529 82 break;
Chris@529 83
Chris@705 84 case LayerFileNonSV:
Chris@705 85 settingsKey = "layerpath";
Chris@705 86 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 87 .arg(DataFileReaderFactory::getKnownExtensions())
Chris@705 88 .arg(RDFImporter::getKnownExtensions());
Chris@705 89 break;
Chris@705 90
Chris@705 91 case LayerFileNoMidiNonSV:
Chris@705 92 settingsKey = "layerpath";
Chris@705 93 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 94 .arg(DataFileReaderFactory::getKnownExtensions())
Chris@705 95 .arg(RDFImporter::getKnownExtensions());
Chris@705 96 break;
Chris@705 97
Chris@529 98 case SessionOrAudioFile:
Chris@529 99 settingsKey = "lastpath";
Chris@529 100 filter = tr("All supported files (*.sv %1 %2)\nSonic Visualiser session files (*.sv)\nAudio files (%2)\nRDF files (%1)\nAll files (*.*)")
Chris@529 101 .arg(RDFImporter::getKnownExtensions())
Chris@529 102 .arg(AudioFileReaderFactory::getKnownExtensions());
Chris@529 103 break;
Chris@529 104
Chris@529 105 case ImageFile:
Chris@529 106 settingsKey = "imagepath";
Chris@529 107 {
Chris@529 108 QStringList fmts;
Chris@529 109 QList<QByteArray> formats = QImageReader::supportedImageFormats();
Chris@529 110 for (QList<QByteArray>::iterator i = formats.begin();
Chris@529 111 i != formats.end(); ++i) {
Chris@529 112 fmts.push_back(QString("*.%1")
Chris@529 113 .arg(QString::fromLocal8Bit(*i).toLower()));
Chris@529 114 }
Chris@529 115 filter = tr("Image files (%1)\nAll files (*.*)").arg(fmts.join(" "));
Chris@529 116 }
Chris@529 117 break;
Chris@529 118
Chris@672 119 case CSVFile:
Chris@672 120 settingsKey = "layerpath";
Chris@672 121 filter = tr("Comma-separated data files (*.csv)\nSpace-separated .lab files (*.lab)\nText files (*.txt)\nAll files (*.*)");
Chris@672 122 break;
Chris@672 123
Chris@529 124 case AnyFile:
Chris@529 125 settingsKey = "lastpath";
Chris@529 126 filter = tr("All supported files (*.sv %1 %2 %3)\nSonic Visualiser session files (*.sv)\nAudio files (%1)\nLayer files (%2)\nRDF files (%3)\nAll files (*.*)")
Chris@529 127 .arg(AudioFileReaderFactory::getKnownExtensions())
Chris@529 128 .arg(DataFileReaderFactory::getKnownExtensions())
Chris@529 129 .arg(RDFImporter::getKnownExtensions());
Chris@529 130 break;
Chris@529 131 };
Chris@529 132
Chris@529 133 if (lastPath == "") {
Chris@529 134 char *home = getenv("HOME");
Chris@529 135 if (home) lastPath = home;
Chris@529 136 else lastPath = ".";
Chris@529 137 } else if (QFileInfo(lastPath).isDir()) {
Chris@529 138 lastPath = QFileInfo(lastPath).canonicalPath();
Chris@529 139 } else {
Chris@529 140 lastPath = QFileInfo(lastPath).absoluteDir().canonicalPath();
Chris@529 141 }
Chris@529 142
Chris@529 143 QSettings settings;
Chris@529 144 settings.beginGroup("FileFinder");
Chris@529 145 lastPath = settings.value(settingsKey, lastPath).toString();
Chris@529 146
Chris@529 147 QString path = "";
Chris@529 148
Chris@529 149 // Use our own QFileDialog just for symmetry with getSaveFileName below
Chris@529 150
Chris@529 151 QFileDialog dialog;
Chris@616 152 dialog.setNameFilters(filter.split('\n'));
Chris@529 153 dialog.setWindowTitle(title);
Chris@529 154 dialog.setDirectory(lastPath);
Chris@529 155
Chris@529 156 dialog.setAcceptMode(QFileDialog::AcceptOpen);
Chris@529 157 dialog.setFileMode(QFileDialog::ExistingFile);
Chris@529 158
Chris@529 159 if (dialog.exec()) {
Chris@529 160 QStringList files = dialog.selectedFiles();
Chris@529 161 if (!files.empty()) path = *files.begin();
Chris@529 162
Chris@529 163 QFileInfo fi(path);
Chris@529 164
Chris@529 165 if (!fi.exists()) {
Chris@529 166
Chris@529 167 QMessageBox::critical(0, tr("File does not exist"),
Chris@529 168 tr("<b>File not found</b><p>File \"%1\" does not exist").arg(path));
Chris@529 169 path = "";
Chris@529 170
Chris@529 171 } else if (!fi.isReadable()) {
Chris@529 172
Chris@529 173 QMessageBox::critical(0, tr("File is not readable"),
Chris@529 174 tr("<b>File is not readable</b><p>File \"%1\" can not be read").arg(path));
Chris@529 175 path = "";
Chris@529 176
Chris@529 177 } else if (fi.isDir()) {
Chris@529 178
Chris@529 179 QMessageBox::critical(0, tr("Directory selected"),
Chris@529 180 tr("<b>Directory selected</b><p>File \"%1\" is a directory").arg(path));
Chris@529 181 path = "";
Chris@529 182
Chris@529 183 } else if (!fi.isFile()) {
Chris@529 184
Chris@529 185 QMessageBox::critical(0, tr("Non-file selected"),
Chris@529 186 tr("<b>Not a file</b><p>Path \"%1\" is not a file").arg(path));
Chris@529 187 path = "";
Chris@529 188
Chris@529 189 } else if (fi.size() == 0) {
Chris@529 190
Chris@529 191 QMessageBox::critical(0, tr("File is empty"),
Chris@529 192 tr("<b>File is empty</b><p>File \"%1\" is empty").arg(path));
Chris@529 193 path = "";
Chris@529 194 }
Chris@529 195 }
Chris@529 196
Chris@529 197 if (path != "") {
Chris@529 198 settings.setValue(settingsKey,
Chris@529 199 QFileInfo(path).absoluteDir().canonicalPath());
Chris@529 200 }
Chris@529 201
Chris@529 202 return path;
Chris@529 203 }
Chris@529 204
Chris@529 205 QString
Chris@529 206 InteractiveFileFinder::getSaveFileName(FileType type, QString fallbackLocation)
Chris@529 207 {
Chris@529 208 QString settingsKey;
Chris@529 209 QString lastPath = fallbackLocation;
Chris@529 210
Chris@529 211 QString title = tr("Select file");
Chris@529 212 QString filter = tr("All files (*.*)");
Chris@529 213
Chris@529 214 switch (type) {
Chris@529 215
Chris@529 216 case SessionFile:
Chris@529 217 settingsKey = "savesessionpath";
Chris@529 218 title = tr("Select a session file");
Chris@529 219 filter = tr("Sonic Visualiser session files (*.sv)\nAll files (*.*)");
Chris@529 220 break;
Chris@529 221
Chris@529 222 case AudioFile:
Chris@529 223 settingsKey = "saveaudiopath";
Chris@529 224 title = "Select an audio file";
Chris@529 225 title = tr("Select a file to export to");
Chris@529 226 filter = tr("WAV audio files (*.wav)\nAll files (*.*)");
Chris@529 227 break;
Chris@529 228
Chris@529 229 case LayerFile:
Chris@529 230 settingsKey = "savelayerpath";
Chris@529 231 title = tr("Select a file to export to");
Chris@529 232 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 233 break;
Chris@529 234
Chris@529 235 case LayerFileNoMidi:
Chris@529 236 settingsKey = "savelayerpath";
Chris@529 237 title = tr("Select a file to export to");
Chris@529 238 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 239 break;
Chris@529 240
Chris@705 241 case LayerFileNonSV:
Chris@705 242 settingsKey = "savelayerpath";
Chris@705 243 title = tr("Select a file to export to");
Chris@705 244 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 245 break;
Chris@705 246
Chris@705 247 case LayerFileNoMidiNonSV:
Chris@705 248 settingsKey = "savelayerpath";
Chris@705 249 title = tr("Select a file to export to");
Chris@705 250 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 251 break;
Chris@705 252
Chris@529 253 case SessionOrAudioFile:
Chris@682 254 cerr << "ERROR: Internal error: InteractiveFileFinder::getSaveFileName: SessionOrAudioFile cannot be used here" << endl;
Chris@529 255 abort();
Chris@529 256
Chris@529 257 case ImageFile:
Chris@529 258 settingsKey = "saveimagepath";
Chris@529 259 title = tr("Select a file to export to");
Chris@529 260 filter = tr("Portable Network Graphics files (*.png)\nAll files (*.*)");
Chris@529 261 break;
Chris@529 262
Chris@672 263 case CSVFile:
Chris@672 264 settingsKey = "savelayerpath";
Chris@672 265 title = tr("Select a file to export to");
Chris@672 266 filter = tr("Comma-separated data files (*.csv)\nText files (*.txt)\nAll files (*.*)");
Chris@672 267 break;
Chris@672 268
Chris@529 269 case AnyFile:
Chris@682 270 cerr << "ERROR: Internal error: InteractiveFileFinder::getSaveFileName: AnyFile cannot be used here" << endl;
Chris@529 271 abort();
Chris@529 272 };
Chris@529 273
Chris@529 274 if (lastPath == "") {
Chris@529 275 char *home = getenv("HOME");
Chris@529 276 if (home) lastPath = home;
Chris@529 277 else lastPath = ".";
Chris@529 278 } else if (QFileInfo(lastPath).isDir()) {
Chris@529 279 lastPath = QFileInfo(lastPath).canonicalPath();
Chris@529 280 } else {
Chris@529 281 lastPath = QFileInfo(lastPath).absoluteDir().canonicalPath();
Chris@529 282 }
Chris@529 283
Chris@529 284 QSettings settings;
Chris@529 285 settings.beginGroup("FileFinder");
Chris@529 286 lastPath = settings.value(settingsKey, lastPath).toString();
Chris@529 287
Chris@529 288 QString path = "";
Chris@529 289
Chris@529 290 // Use our own QFileDialog instead of static functions, as we may
Chris@529 291 // need to adjust the file extension based on the selected filter
Chris@529 292
Chris@529 293 QFileDialog dialog;
Chris@616 294 dialog.setNameFilters(filter.split('\n'));
Chris@529 295 dialog.setWindowTitle(title);
Chris@529 296 dialog.setDirectory(lastPath);
Chris@529 297
Chris@529 298 dialog.setAcceptMode(QFileDialog::AcceptSave);
Chris@529 299 dialog.setFileMode(QFileDialog::AnyFile);
Chris@529 300 dialog.setConfirmOverwrite(false); // we'll do that
Chris@529 301
Chris@529 302 if (type == SessionFile) {
Chris@529 303 dialog.setDefaultSuffix("sv");
Chris@529 304 } else if (type == AudioFile) {
Chris@529 305 dialog.setDefaultSuffix("wav");
Chris@529 306 } else if (type == ImageFile) {
Chris@529 307 dialog.setDefaultSuffix("png");
Chris@672 308 } else if (type == CSVFile) {
Chris@672 309 dialog.setDefaultSuffix("csv");
Chris@529 310 }
Chris@529 311
Chris@529 312 bool good = false;
Chris@529 313
Chris@529 314 while (!good) {
Chris@529 315
Chris@529 316 path = "";
Chris@529 317
Chris@529 318 if (!dialog.exec()) break;
Chris@529 319
Chris@529 320 QStringList files = dialog.selectedFiles();
Chris@529 321 if (files.empty()) break;
Chris@529 322 path = *files.begin();
Chris@529 323
Chris@529 324 QFileInfo fi(path);
Chris@529 325
Chris@682 326 cerr << "type = " << type << ", suffix = " << fi.suffix() << endl;
Chris@529 327
Chris@705 328 if ((type == LayerFile || type == LayerFileNoMidi ||
Chris@705 329 type == LayerFileNonSV || type == LayerFileNoMidiNonSV)
Chris@529 330 && fi.suffix() == "") {
Chris@529 331 QString expectedExtension;
Chris@616 332 QString selectedFilter = dialog.selectedNameFilter();
Chris@529 333 if (selectedFilter.contains(".svl")) {
Chris@529 334 expectedExtension = "svl";
Chris@529 335 } else if (selectedFilter.contains(".txt")) {
Chris@529 336 expectedExtension = "txt";
Chris@529 337 } else if (selectedFilter.contains(".csv")) {
Chris@529 338 expectedExtension = "csv";
Chris@529 339 } else if (selectedFilter.contains(".mid")) {
Chris@529 340 expectedExtension = "mid";
Chris@529 341 } else if (selectedFilter.contains(".ttl")) {
Chris@529 342 expectedExtension = "ttl";
Chris@529 343 }
Chris@682 344 cerr << "expected extension = " << expectedExtension << endl;
Chris@529 345 if (expectedExtension != "") {
Chris@529 346 path = QString("%1.%2").arg(path).arg(expectedExtension);
Chris@529 347 fi = QFileInfo(path);
Chris@529 348 }
Chris@529 349 }
Chris@529 350
Chris@529 351 if (fi.isDir()) {
Chris@529 352 QMessageBox::critical(0, tr("Directory selected"),
Chris@529 353 tr("<b>Directory selected</b><p>File \"%1\" is a directory").arg(path));
Chris@529 354 continue;
Chris@529 355 }
Chris@529 356
Chris@529 357 if (fi.exists()) {
Chris@529 358 if (QMessageBox::question(0, tr("File exists"),
Chris@529 359 tr("<b>File exists</b><p>The file \"%1\" already exists.\nDo you want to overwrite it?").arg(path),
Chris@529 360 QMessageBox::Ok,
Chris@529 361 QMessageBox::Cancel) != QMessageBox::Ok) {
Chris@529 362 continue;
Chris@529 363 }
Chris@529 364 }
Chris@529 365
Chris@529 366 good = true;
Chris@529 367 }
Chris@529 368
Chris@529 369 if (path != "") {
Chris@529 370 settings.setValue(settingsKey,
Chris@529 371 QFileInfo(path).absoluteDir().canonicalPath());
Chris@529 372 }
Chris@529 373
Chris@529 374 return path;
Chris@529 375 }
Chris@529 376
Chris@529 377 void
Chris@529 378 InteractiveFileFinder::registerLastOpenedFilePath(FileType type, QString path)
Chris@529 379 {
Chris@529 380 QString settingsKey;
Chris@529 381
Chris@529 382 switch (type) {
Chris@529 383 case SessionFile:
Chris@529 384 settingsKey = "sessionpath";
Chris@529 385 break;
Chris@529 386
Chris@529 387 case AudioFile:
Chris@529 388 settingsKey = "audiopath";
Chris@529 389 break;
Chris@529 390
Chris@529 391 case LayerFile:
Chris@529 392 settingsKey = "layerpath";
Chris@529 393 break;
Chris@529 394
Chris@529 395 case LayerFileNoMidi:
Chris@529 396 settingsKey = "layerpath";
Chris@529 397 break;
Chris@529 398
Chris@705 399 case LayerFileNonSV:
Chris@705 400 settingsKey = "layerpath";
Chris@705 401 break;
Chris@705 402
Chris@705 403 case LayerFileNoMidiNonSV:
Chris@705 404 settingsKey = "layerpath";
Chris@705 405 break;
Chris@705 406
Chris@529 407 case SessionOrAudioFile:
Chris@529 408 settingsKey = "lastpath";
Chris@529 409 break;
Chris@529 410
Chris@529 411 case ImageFile:
Chris@529 412 settingsKey = "imagepath";
Chris@529 413 break;
Chris@529 414
Chris@672 415 case CSVFile:
Chris@672 416 settingsKey = "layerpath";
Chris@672 417 break;
Chris@672 418
Chris@529 419 case AnyFile:
Chris@529 420 settingsKey = "lastpath";
Chris@529 421 break;
Chris@529 422 }
Chris@529 423
Chris@529 424 if (path != "") {
Chris@529 425 QSettings settings;
Chris@529 426 settings.beginGroup("FileFinder");
Chris@529 427 path = QFileInfo(path).absoluteDir().canonicalPath();
Chris@529 428 settings.setValue(settingsKey, path);
Chris@529 429 settings.setValue("lastpath", path);
Chris@529 430 }
Chris@529 431 }
Chris@529 432
Chris@529 433 QString
Chris@529 434 InteractiveFileFinder::find(FileType type, QString location, QString lastKnownLocation)
Chris@529 435 {
Chris@529 436 if (FileSource::canHandleScheme(location)) {
Chris@529 437 if (FileSource(location).isAvailable()) {
Chris@587 438 SVDEBUG << "InteractiveFileFinder::find: ok, it's available... returning" << endl;
Chris@529 439 return location;
Chris@529 440 }
Chris@529 441 }
Chris@529 442
Chris@529 443 if (QFileInfo(location).exists()) return location;
Chris@529 444
Chris@529 445 QString foundAt = "";
Chris@529 446
Chris@529 447 if ((foundAt = findRelative(location, lastKnownLocation)) != "") {
Chris@529 448 return foundAt;
Chris@529 449 }
Chris@529 450
Chris@529 451 if ((foundAt = findRelative(location, m_lastLocatedLocation)) != "") {
Chris@529 452 return foundAt;
Chris@529 453 }
Chris@529 454
Chris@529 455 return locateInteractive(type, location);
Chris@529 456 }
Chris@529 457
Chris@529 458 QString
Chris@529 459 InteractiveFileFinder::findRelative(QString location, QString relativeTo)
Chris@529 460 {
Chris@529 461 if (relativeTo == "") return "";
Chris@529 462
Chris@587 463 SVDEBUG << "Looking for \"" << location << "\" next to \""
Chris@585 464 << relativeTo << "\"..." << endl;
Chris@529 465
Chris@529 466 QString fileName;
Chris@529 467 QString resolved;
Chris@529 468
Chris@529 469 if (FileSource::isRemote(location)) {
Chris@529 470 fileName = QUrl(location).path().section('/', -1, -1,
Chris@529 471 QString::SectionSkipEmpty);
Chris@529 472 } else {
Chris@529 473 if (QUrl(location).scheme() == "file") {
Chris@529 474 location = QUrl(location).toLocalFile();
Chris@529 475 }
Chris@529 476 fileName = QFileInfo(location).fileName();
Chris@529 477 }
Chris@529 478
Chris@529 479 if (FileSource::isRemote(relativeTo)) {
Chris@529 480 resolved = QUrl(relativeTo).resolved(fileName).toString();
Chris@529 481 if (!FileSource(resolved).isAvailable()) resolved = "";
Chris@682 482 cerr << "resolved: " << resolved << endl;
Chris@529 483 } else {
Chris@529 484 if (QUrl(relativeTo).scheme() == "file") {
Chris@529 485 relativeTo = QUrl(relativeTo).toLocalFile();
Chris@529 486 }
Chris@529 487 resolved = QFileInfo(relativeTo).dir().filePath(fileName);
Chris@529 488 if (!QFileInfo(resolved).exists() ||
Chris@529 489 !QFileInfo(resolved).isFile() ||
Chris@529 490 !QFileInfo(resolved).isReadable()) {
Chris@529 491 resolved = "";
Chris@529 492 }
Chris@529 493 }
Chris@529 494
Chris@529 495 return resolved;
Chris@529 496 }
Chris@529 497
Chris@529 498 QString
Chris@529 499 InteractiveFileFinder::locateInteractive(FileType type, QString thing)
Chris@529 500 {
Chris@529 501 QString question;
Chris@529 502 if (type == AudioFile) {
Chris@529 503 question = tr("<b>File not found</b><p>Audio file \"%1\" could not be opened.\nDo you want to locate it?");
Chris@529 504 } else {
Chris@529 505 question = tr("<b>File not found</b><p>File \"%1\" could not be opened.\nDo you want to locate it?");
Chris@529 506 }
Chris@529 507
Chris@529 508 QString path = "";
Chris@529 509 bool done = false;
Chris@529 510
Chris@529 511 while (!done) {
Chris@529 512
Chris@529 513 int rv = QMessageBox::question
Chris@529 514 (0,
Chris@529 515 tr("Failed to open file"),
Chris@529 516 question.arg(thing),
Chris@529 517 tr("Locate file..."),
Chris@529 518 tr("Use URL..."),
Chris@529 519 tr("Cancel"),
Chris@529 520 0, 2);
Chris@529 521
Chris@529 522 switch (rv) {
Chris@529 523
Chris@529 524 case 0: // Locate file
Chris@529 525
Chris@529 526 if (QFileInfo(thing).dir().exists()) {
Chris@529 527 path = QFileInfo(thing).dir().canonicalPath();
Chris@529 528 }
Chris@529 529
Chris@529 530 path = getOpenFileName(type, path);
Chris@529 531 done = (path != "");
Chris@529 532 break;
Chris@529 533
Chris@529 534 case 1: // Use URL
Chris@529 535 {
Chris@529 536 bool ok = false;
Chris@529 537 path = QInputDialog::getText
Chris@529 538 (0, tr("Use URL"),
Chris@529 539 tr("Please enter the URL to use for this file:"),
Chris@529 540 QLineEdit::Normal, "", &ok);
Chris@529 541
Chris@529 542 if (ok && path != "") {
Chris@529 543 if (FileSource(path).isAvailable()) {
Chris@529 544 done = true;
Chris@529 545 } else {
Chris@529 546 QMessageBox::critical
Chris@529 547 (0, tr("Failed to open location"),
Chris@529 548 tr("<b>Failed to open location</b><p>URL \"%1\" could not be opened").arg(path));
Chris@529 549 path = "";
Chris@529 550 }
Chris@529 551 }
Chris@529 552 break;
Chris@529 553 }
Chris@529 554
Chris@529 555 case 2: // Cancel
Chris@529 556 path = "";
Chris@529 557 done = true;
Chris@529 558 break;
Chris@529 559 }
Chris@529 560 }
Chris@529 561
Chris@529 562 if (path != "") m_lastLocatedLocation = path;
Chris@529 563 return path;
Chris@529 564 }
Chris@529 565
Chris@529 566