Chris@378
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
Chris@378
|
2
|
Chris@378
|
3 /*
|
Chris@378
|
4 Sonic Visualiser
|
Chris@378
|
5 An audio file viewer and annotation editor.
|
Chris@378
|
6 Centre for Digital Music, Queen Mary, University of London.
|
Chris@378
|
7 This file copyright 2007 QMUL.
|
Chris@378
|
8
|
Chris@378
|
9 This program is free software; you can redistribute it and/or
|
Chris@378
|
10 modify it under the terms of the GNU General Public License as
|
Chris@378
|
11 published by the Free Software Foundation; either version 2 of the
|
Chris@378
|
12 License, or (at your option) any later version. See the file
|
Chris@378
|
13 COPYING included with this distribution for more information.
|
Chris@378
|
14 */
|
Chris@378
|
15
|
Chris@378
|
16 #include "FileFinder.h"
|
Chris@378
|
17 #include "data/fileio/FileSource.h"
|
Chris@378
|
18 #include "data/fileio/AudioFileReaderFactory.h"
|
Chris@378
|
19 #include "data/fileio/DataFileReaderFactory.h"
|
Chris@410
|
20 #include "rdf/RDFImporter.h"
|
Chris@378
|
21
|
Chris@378
|
22 #include <QFileInfo>
|
Chris@378
|
23 #include <QMessageBox>
|
Chris@378
|
24 #include <QFileDialog>
|
Chris@378
|
25 #include <QInputDialog>
|
Chris@378
|
26 #include <QImageReader>
|
Chris@378
|
27 #include <QSettings>
|
Chris@378
|
28
|
Chris@378
|
29 #include <iostream>
|
Chris@378
|
30
|
Chris@378
|
31 FileFinder *
|
Chris@378
|
32 FileFinder::m_instance = 0;
|
Chris@378
|
33
|
Chris@378
|
34 FileFinder::FileFinder() :
|
Chris@378
|
35 m_lastLocatedLocation("")
|
Chris@378
|
36 {
|
Chris@378
|
37 }
|
Chris@378
|
38
|
Chris@378
|
39 FileFinder::~FileFinder()
|
Chris@378
|
40 {
|
Chris@378
|
41 }
|
Chris@378
|
42
|
Chris@378
|
43 FileFinder *
|
Chris@378
|
44 FileFinder::getInstance()
|
Chris@378
|
45 {
|
Chris@378
|
46 if (m_instance == 0) {
|
Chris@378
|
47 m_instance = new FileFinder();
|
Chris@378
|
48 }
|
Chris@378
|
49 return m_instance;
|
Chris@378
|
50 }
|
Chris@378
|
51
|
Chris@378
|
52 QString
|
Chris@378
|
53 FileFinder::getOpenFileName(FileType type, QString fallbackLocation)
|
Chris@378
|
54 {
|
Chris@378
|
55 QString settingsKey;
|
Chris@378
|
56 QString lastPath = fallbackLocation;
|
Chris@378
|
57
|
Chris@378
|
58 QString title = tr("Select file");
|
Chris@378
|
59 QString filter = tr("All files (*.*)");
|
Chris@378
|
60
|
Chris@378
|
61 switch (type) {
|
Chris@378
|
62
|
Chris@378
|
63 case SessionFile:
|
Chris@378
|
64 settingsKey = "sessionpath";
|
Chris@378
|
65 title = tr("Select a session file");
|
Chris@378
|
66 filter = tr("Sonic Visualiser session files (*.sv)\nAll files (*.*)");
|
Chris@378
|
67 break;
|
Chris@378
|
68
|
Chris@378
|
69 case AudioFile:
|
Chris@378
|
70 settingsKey = "audiopath";
|
Chris@378
|
71 title = "Select an audio file";
|
Chris@378
|
72 filter = tr("Audio files (%1)\nAll files (*.*)")
|
Chris@378
|
73 .arg(AudioFileReaderFactory::getKnownExtensions());
|
Chris@378
|
74 break;
|
Chris@378
|
75
|
Chris@378
|
76 case LayerFile:
|
Chris@378
|
77 settingsKey = "layerpath";
|
Chris@410
|
78 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 (%3)\nMIDI files (*.mid)\nText files (*.txt)\nAll files (*.*)").arg(DataFileReaderFactory::getKnownExtensions()).arg(RDFImporter::getKnownExtensions()).arg(RDFImporter::getKnownExtensions());
|
Chris@378
|
79 break;
|
Chris@378
|
80
|
Chris@378
|
81 case LayerFileNoMidi:
|
Chris@378
|
82 settingsKey = "layerpath";
|
Chris@410
|
83 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 (%3)\nText files (*.txt)\nAll files (*.*)").arg(DataFileReaderFactory::getKnownExtensions()).arg(RDFImporter::getKnownExtensions()).arg(RDFImporter::getKnownExtensions());
|
Chris@378
|
84 break;
|
Chris@378
|
85
|
Chris@378
|
86 case SessionOrAudioFile:
|
Chris@378
|
87 settingsKey = "lastpath";
|
Chris@378
|
88 filter = tr("All supported files (*.sv %1)\nSonic Visualiser session files (*.sv)\nAudio files (%1)\nAll files (*.*)")
|
Chris@378
|
89 .arg(AudioFileReaderFactory::getKnownExtensions());
|
Chris@378
|
90 break;
|
Chris@378
|
91
|
Chris@378
|
92 case ImageFile:
|
Chris@378
|
93 settingsKey = "imagepath";
|
Chris@378
|
94 {
|
Chris@378
|
95 QStringList fmts;
|
Chris@378
|
96 QList<QByteArray> formats = QImageReader::supportedImageFormats();
|
Chris@378
|
97 for (QList<QByteArray>::iterator i = formats.begin();
|
Chris@378
|
98 i != formats.end(); ++i) {
|
Chris@378
|
99 fmts.push_back(QString("*.%1")
|
Chris@378
|
100 .arg(QString::fromLocal8Bit(*i).toLower()));
|
Chris@378
|
101 }
|
Chris@378
|
102 filter = tr("Image files (%1)\nAll files (*.*)").arg(fmts.join(" "));
|
Chris@378
|
103 }
|
Chris@378
|
104 break;
|
Chris@378
|
105
|
Chris@378
|
106 case AnyFile:
|
Chris@378
|
107 settingsKey = "lastpath";
|
Chris@410
|
108 filter = tr("All supported files (*.sv %1 %2 %3)\nSonic Visualiser session files (*.sv)\nAudio files (%1)\nLayer files (%2)\nAll files (*.*)")
|
Chris@378
|
109 .arg(AudioFileReaderFactory::getKnownExtensions())
|
Chris@410
|
110 .arg(DataFileReaderFactory::getKnownExtensions())
|
Chris@410
|
111 .arg(RDFImporter::getKnownExtensions());
|
Chris@378
|
112 break;
|
Chris@378
|
113 };
|
Chris@378
|
114
|
Chris@378
|
115 if (lastPath == "") {
|
Chris@378
|
116 char *home = getenv("HOME");
|
Chris@378
|
117 if (home) lastPath = home;
|
Chris@378
|
118 else lastPath = ".";
|
Chris@378
|
119 } else if (QFileInfo(lastPath).isDir()) {
|
Chris@378
|
120 lastPath = QFileInfo(lastPath).canonicalPath();
|
Chris@378
|
121 } else {
|
Chris@378
|
122 lastPath = QFileInfo(lastPath).absoluteDir().canonicalPath();
|
Chris@378
|
123 }
|
Chris@378
|
124
|
Chris@378
|
125 QSettings settings;
|
Chris@378
|
126 settings.beginGroup("FileFinder");
|
Chris@378
|
127 lastPath = settings.value(settingsKey, lastPath).toString();
|
Chris@378
|
128
|
Chris@378
|
129 QString path = "";
|
Chris@378
|
130
|
Chris@378
|
131 // Use our own QFileDialog just for symmetry with getSaveFileName below
|
Chris@378
|
132
|
Chris@378
|
133 QFileDialog dialog;
|
Chris@378
|
134 dialog.setFilters(filter.split('\n'));
|
Chris@378
|
135 dialog.setWindowTitle(title);
|
Chris@378
|
136 dialog.setDirectory(lastPath);
|
Chris@378
|
137
|
Chris@378
|
138 dialog.setAcceptMode(QFileDialog::AcceptOpen);
|
Chris@378
|
139 dialog.setFileMode(QFileDialog::ExistingFile);
|
Chris@378
|
140
|
Chris@378
|
141 if (dialog.exec()) {
|
Chris@378
|
142 QStringList files = dialog.selectedFiles();
|
Chris@378
|
143 if (!files.empty()) path = *files.begin();
|
Chris@378
|
144
|
Chris@378
|
145 QFileInfo fi(path);
|
Chris@378
|
146
|
Chris@378
|
147 if (!fi.exists()) {
|
Chris@378
|
148
|
Chris@378
|
149 QMessageBox::critical(0, tr("File does not exist"),
|
Chris@378
|
150 tr("File \"%1\" does not exist").arg(path));
|
Chris@378
|
151 path = "";
|
Chris@378
|
152
|
Chris@378
|
153 } else if (!fi.isReadable()) {
|
Chris@378
|
154
|
Chris@378
|
155 QMessageBox::critical(0, tr("File is not readable"),
|
Chris@378
|
156 tr("File \"%1\" can not be read").arg(path));
|
Chris@378
|
157 path = "";
|
Chris@378
|
158
|
Chris@378
|
159 } else if (fi.isDir()) {
|
Chris@378
|
160
|
Chris@378
|
161 QMessageBox::critical(0, tr("Directory selected"),
|
Chris@378
|
162 tr("File \"%1\" is a directory").arg(path));
|
Chris@378
|
163 path = "";
|
Chris@378
|
164
|
Chris@378
|
165 } else if (!fi.isFile()) {
|
Chris@378
|
166
|
Chris@378
|
167 QMessageBox::critical(0, tr("Non-file selected"),
|
Chris@378
|
168 tr("Path \"%1\" is not a file").arg(path));
|
Chris@378
|
169 path = "";
|
Chris@378
|
170
|
Chris@378
|
171 } else if (fi.size() == 0) {
|
Chris@378
|
172
|
Chris@378
|
173 QMessageBox::critical(0, tr("File is empty"),
|
Chris@378
|
174 tr("File \"%1\" is empty").arg(path));
|
Chris@378
|
175 path = "";
|
Chris@378
|
176 }
|
Chris@378
|
177 }
|
Chris@378
|
178
|
Chris@378
|
179 if (path != "") {
|
Chris@378
|
180 settings.setValue(settingsKey,
|
Chris@378
|
181 QFileInfo(path).absoluteDir().canonicalPath());
|
Chris@378
|
182 }
|
Chris@378
|
183
|
Chris@378
|
184 return path;
|
Chris@378
|
185 }
|
Chris@378
|
186
|
Chris@378
|
187 QString
|
Chris@378
|
188 FileFinder::getSaveFileName(FileType type, QString fallbackLocation)
|
Chris@378
|
189 {
|
Chris@378
|
190 QString settingsKey;
|
Chris@378
|
191 QString lastPath = fallbackLocation;
|
Chris@378
|
192
|
Chris@378
|
193 QString title = tr("Select file");
|
Chris@378
|
194 QString filter = tr("All files (*.*)");
|
Chris@378
|
195
|
Chris@378
|
196 switch (type) {
|
Chris@378
|
197
|
Chris@378
|
198 case SessionFile:
|
Chris@378
|
199 settingsKey = "savesessionpath";
|
Chris@378
|
200 title = tr("Select a session file");
|
Chris@378
|
201 filter = tr("Sonic Visualiser session files (*.sv)\nAll files (*.*)");
|
Chris@378
|
202 break;
|
Chris@378
|
203
|
Chris@378
|
204 case AudioFile:
|
Chris@378
|
205 settingsKey = "saveaudiopath";
|
Chris@378
|
206 title = "Select an audio file";
|
Chris@378
|
207 title = tr("Select a file to export to");
|
Chris@378
|
208 filter = tr("WAV audio files (*.wav)\nAll files (*.*)");
|
Chris@378
|
209 break;
|
Chris@378
|
210
|
Chris@378
|
211 case LayerFile:
|
Chris@378
|
212 settingsKey = "savelayerpath";
|
Chris@378
|
213 title = tr("Select a file to export to");
|
Chris@378
|
214 filter = tr("Sonic Visualiser Layer XML files (*.svl)\nComma-separated data files (*.csv)\nMIDI files (*.mid)\nText files (*.txt)\nAll files (*.*)");
|
Chris@378
|
215 break;
|
Chris@378
|
216
|
Chris@378
|
217 case LayerFileNoMidi:
|
Chris@378
|
218 settingsKey = "savelayerpath";
|
Chris@378
|
219 title = tr("Select a file to export to");
|
Chris@378
|
220 filter = tr("Sonic Visualiser Layer XML files (*.svl)\nComma-separated data files (*.csv)\nText files (*.txt)\nAll files (*.*)");
|
Chris@378
|
221 break;
|
Chris@378
|
222
|
Chris@378
|
223 case SessionOrAudioFile:
|
Chris@378
|
224 std::cerr << "ERROR: Internal error: FileFinder::getSaveFileName: SessionOrAudioFile cannot be used here" << std::endl;
|
Chris@378
|
225 abort();
|
Chris@378
|
226
|
Chris@378
|
227 case ImageFile:
|
Chris@378
|
228 settingsKey = "saveimagepath";
|
Chris@378
|
229 title = tr("Select a file to export to");
|
Chris@378
|
230 filter = tr("Portable Network Graphics files (*.png)\nAll files (*.*)");
|
Chris@378
|
231 break;
|
Chris@378
|
232
|
Chris@378
|
233 case AnyFile:
|
Chris@378
|
234 std::cerr << "ERROR: Internal error: FileFinder::getSaveFileName: AnyFile cannot be used here" << std::endl;
|
Chris@378
|
235 abort();
|
Chris@378
|
236 };
|
Chris@378
|
237
|
Chris@378
|
238 if (lastPath == "") {
|
Chris@378
|
239 char *home = getenv("HOME");
|
Chris@378
|
240 if (home) lastPath = home;
|
Chris@378
|
241 else lastPath = ".";
|
Chris@378
|
242 } else if (QFileInfo(lastPath).isDir()) {
|
Chris@378
|
243 lastPath = QFileInfo(lastPath).canonicalPath();
|
Chris@378
|
244 } else {
|
Chris@378
|
245 lastPath = QFileInfo(lastPath).absoluteDir().canonicalPath();
|
Chris@378
|
246 }
|
Chris@378
|
247
|
Chris@378
|
248 QSettings settings;
|
Chris@378
|
249 settings.beginGroup("FileFinder");
|
Chris@378
|
250 lastPath = settings.value(settingsKey, lastPath).toString();
|
Chris@378
|
251
|
Chris@378
|
252 QString path = "";
|
Chris@378
|
253
|
Chris@378
|
254 // Use our own QFileDialog instead of static functions, as we may
|
Chris@378
|
255 // need to adjust the file extension based on the selected filter
|
Chris@378
|
256
|
Chris@378
|
257 QFileDialog dialog;
|
Chris@378
|
258 dialog.setFilters(filter.split('\n'));
|
Chris@378
|
259 dialog.setWindowTitle(title);
|
Chris@378
|
260 dialog.setDirectory(lastPath);
|
Chris@378
|
261
|
Chris@378
|
262 dialog.setAcceptMode(QFileDialog::AcceptSave);
|
Chris@378
|
263 dialog.setFileMode(QFileDialog::AnyFile);
|
Chris@378
|
264 dialog.setConfirmOverwrite(false); // we'll do that
|
Chris@378
|
265
|
Chris@378
|
266 if (type == SessionFile) {
|
Chris@378
|
267 dialog.setDefaultSuffix("sv");
|
Chris@378
|
268 } else if (type == AudioFile) {
|
Chris@378
|
269 dialog.setDefaultSuffix("wav");
|
Chris@378
|
270 } else if (type == ImageFile) {
|
Chris@378
|
271 dialog.setDefaultSuffix("png");
|
Chris@378
|
272 }
|
Chris@378
|
273
|
Chris@378
|
274 bool good = false;
|
Chris@378
|
275
|
Chris@378
|
276 while (!good) {
|
Chris@378
|
277
|
Chris@378
|
278 path = "";
|
Chris@378
|
279
|
Chris@378
|
280 if (!dialog.exec()) break;
|
Chris@378
|
281
|
Chris@378
|
282 QStringList files = dialog.selectedFiles();
|
Chris@378
|
283 if (files.empty()) break;
|
Chris@378
|
284 path = *files.begin();
|
Chris@378
|
285
|
Chris@378
|
286 QFileInfo fi(path);
|
Chris@378
|
287
|
Chris@378
|
288 std::cerr << "type = " << type << ", suffix = " << fi.suffix().toStdString() << std::endl;
|
Chris@378
|
289
|
Chris@378
|
290 if ((type == LayerFile || type == LayerFileNoMidi)
|
Chris@378
|
291 && fi.suffix() == "") {
|
Chris@378
|
292 QString expectedExtension;
|
Chris@378
|
293 QString selectedFilter = dialog.selectedFilter();
|
Chris@378
|
294 if (selectedFilter.contains(".svl")) {
|
Chris@378
|
295 expectedExtension = "svl";
|
Chris@378
|
296 } else if (selectedFilter.contains(".txt")) {
|
Chris@378
|
297 expectedExtension = "txt";
|
Chris@378
|
298 } else if (selectedFilter.contains(".csv")) {
|
Chris@378
|
299 expectedExtension = "csv";
|
Chris@378
|
300 } else if (selectedFilter.contains(".mid")) {
|
Chris@378
|
301 expectedExtension = "mid";
|
Chris@378
|
302 }
|
Chris@378
|
303 std::cerr << "expected extension = " << expectedExtension.toStdString() << std::endl;
|
Chris@378
|
304 if (expectedExtension != "") {
|
Chris@378
|
305 path = QString("%1.%2").arg(path).arg(expectedExtension);
|
Chris@378
|
306 fi = QFileInfo(path);
|
Chris@378
|
307 }
|
Chris@378
|
308 }
|
Chris@378
|
309
|
Chris@378
|
310 if (fi.isDir()) {
|
Chris@378
|
311 QMessageBox::critical(0, tr("Directory selected"),
|
Chris@378
|
312 tr("File \"%1\" is a directory").arg(path));
|
Chris@378
|
313 continue;
|
Chris@378
|
314 }
|
Chris@378
|
315
|
Chris@378
|
316 if (fi.exists()) {
|
Chris@378
|
317 if (QMessageBox::question(0, tr("File exists"),
|
Chris@378
|
318 tr("The file \"%1\" already exists.\nDo you want to overwrite it?").arg(path),
|
Chris@378
|
319 QMessageBox::Ok,
|
Chris@378
|
320 QMessageBox::Cancel) != QMessageBox::Ok) {
|
Chris@378
|
321 continue;
|
Chris@378
|
322 }
|
Chris@378
|
323 }
|
Chris@378
|
324
|
Chris@378
|
325 good = true;
|
Chris@378
|
326 }
|
Chris@378
|
327
|
Chris@378
|
328 if (path != "") {
|
Chris@378
|
329 settings.setValue(settingsKey,
|
Chris@378
|
330 QFileInfo(path).absoluteDir().canonicalPath());
|
Chris@378
|
331 }
|
Chris@378
|
332
|
Chris@378
|
333 return path;
|
Chris@378
|
334 }
|
Chris@378
|
335
|
Chris@378
|
336 void
|
Chris@378
|
337 FileFinder::registerLastOpenedFilePath(FileType type, QString path)
|
Chris@378
|
338 {
|
Chris@378
|
339 QString settingsKey;
|
Chris@378
|
340
|
Chris@378
|
341 switch (type) {
|
Chris@378
|
342 case SessionFile:
|
Chris@378
|
343 settingsKey = "sessionpath";
|
Chris@378
|
344 break;
|
Chris@378
|
345
|
Chris@378
|
346 case AudioFile:
|
Chris@378
|
347 settingsKey = "audiopath";
|
Chris@378
|
348 break;
|
Chris@378
|
349
|
Chris@378
|
350 case LayerFile:
|
Chris@378
|
351 settingsKey = "layerpath";
|
Chris@378
|
352 break;
|
Chris@378
|
353
|
Chris@378
|
354 case LayerFileNoMidi:
|
Chris@378
|
355 settingsKey = "layerpath";
|
Chris@378
|
356 break;
|
Chris@378
|
357
|
Chris@378
|
358 case SessionOrAudioFile:
|
Chris@378
|
359 settingsKey = "lastpath";
|
Chris@378
|
360 break;
|
Chris@378
|
361
|
Chris@378
|
362 case ImageFile:
|
Chris@378
|
363 settingsKey = "imagepath";
|
Chris@378
|
364 break;
|
Chris@378
|
365
|
Chris@378
|
366 case AnyFile:
|
Chris@378
|
367 settingsKey = "lastpath";
|
Chris@378
|
368 break;
|
Chris@378
|
369 }
|
Chris@378
|
370
|
Chris@378
|
371 if (path != "") {
|
Chris@378
|
372 QSettings settings;
|
Chris@378
|
373 settings.beginGroup("FileFinder");
|
Chris@378
|
374 path = QFileInfo(path).absoluteDir().canonicalPath();
|
Chris@378
|
375 settings.setValue(settingsKey, path);
|
Chris@378
|
376 settings.setValue("lastpath", path);
|
Chris@378
|
377 }
|
Chris@378
|
378 }
|
Chris@378
|
379
|
Chris@378
|
380 QString
|
Chris@378
|
381 FileFinder::find(FileType type, QString location, QString lastKnownLocation)
|
Chris@378
|
382 {
|
Chris@378
|
383 if (FileSource::canHandleScheme(location)) {
|
Chris@378
|
384 if (FileSource(location).isAvailable()) {
|
Chris@378
|
385 std::cerr << "FileFinder::find: ok, it's available... returning" << std::endl;
|
Chris@378
|
386 return location;
|
Chris@378
|
387 }
|
Chris@378
|
388 }
|
Chris@378
|
389
|
Chris@378
|
390 if (QFileInfo(location).exists()) return location;
|
Chris@378
|
391
|
Chris@378
|
392 QString foundAt = "";
|
Chris@378
|
393
|
Chris@378
|
394 if ((foundAt = findRelative(location, lastKnownLocation)) != "") {
|
Chris@378
|
395 return foundAt;
|
Chris@378
|
396 }
|
Chris@378
|
397
|
Chris@378
|
398 if ((foundAt = findRelative(location, m_lastLocatedLocation)) != "") {
|
Chris@378
|
399 return foundAt;
|
Chris@378
|
400 }
|
Chris@378
|
401
|
Chris@378
|
402 return locateInteractive(type, location);
|
Chris@378
|
403 }
|
Chris@378
|
404
|
Chris@378
|
405 QString
|
Chris@378
|
406 FileFinder::findRelative(QString location, QString relativeTo)
|
Chris@378
|
407 {
|
Chris@378
|
408 if (relativeTo == "") return "";
|
Chris@378
|
409
|
Chris@378
|
410 std::cerr << "Looking for \"" << location.toStdString() << "\" next to \""
|
Chris@378
|
411 << relativeTo.toStdString() << "\"..." << std::endl;
|
Chris@378
|
412
|
Chris@378
|
413 QString fileName;
|
Chris@378
|
414 QString resolved;
|
Chris@378
|
415
|
Chris@378
|
416 if (FileSource::isRemote(location)) {
|
Chris@378
|
417 fileName = QUrl(location).path().section('/', -1, -1,
|
Chris@378
|
418 QString::SectionSkipEmpty);
|
Chris@378
|
419 } else {
|
Chris@378
|
420 if (QUrl(location).scheme() == "file") {
|
Chris@378
|
421 location = QUrl(location).toLocalFile();
|
Chris@378
|
422 }
|
Chris@378
|
423 fileName = QFileInfo(location).fileName();
|
Chris@378
|
424 }
|
Chris@378
|
425
|
Chris@378
|
426 if (FileSource::isRemote(relativeTo)) {
|
Chris@378
|
427 resolved = QUrl(relativeTo).resolved(fileName).toString();
|
Chris@378
|
428 if (!FileSource(resolved).isAvailable()) resolved = "";
|
Chris@378
|
429 std::cerr << "resolved: " << resolved.toStdString() << std::endl;
|
Chris@378
|
430 } else {
|
Chris@378
|
431 if (QUrl(relativeTo).scheme() == "file") {
|
Chris@378
|
432 relativeTo = QUrl(relativeTo).toLocalFile();
|
Chris@378
|
433 }
|
Chris@378
|
434 resolved = QFileInfo(relativeTo).dir().filePath(fileName);
|
Chris@378
|
435 if (!QFileInfo(resolved).exists() ||
|
Chris@378
|
436 !QFileInfo(resolved).isFile() ||
|
Chris@378
|
437 !QFileInfo(resolved).isReadable()) {
|
Chris@378
|
438 resolved = "";
|
Chris@378
|
439 }
|
Chris@378
|
440 }
|
Chris@378
|
441
|
Chris@378
|
442 return resolved;
|
Chris@378
|
443 }
|
Chris@378
|
444
|
Chris@378
|
445 QString
|
Chris@378
|
446 FileFinder::locateInteractive(FileType type, QString thing)
|
Chris@378
|
447 {
|
Chris@378
|
448 QString question;
|
Chris@378
|
449 if (type == AudioFile) {
|
Chris@378
|
450 question = tr("Audio file \"%1\" could not be opened.\nDo you want to locate it?");
|
Chris@378
|
451 } else {
|
Chris@378
|
452 question = tr("File \"%1\" could not be opened.\nDo you want to locate it?");
|
Chris@378
|
453 }
|
Chris@378
|
454
|
Chris@378
|
455 QString path = "";
|
Chris@378
|
456 bool done = false;
|
Chris@378
|
457
|
Chris@378
|
458 while (!done) {
|
Chris@378
|
459
|
Chris@378
|
460 int rv = QMessageBox::question
|
Chris@378
|
461 (0,
|
Chris@378
|
462 tr("Failed to open file"),
|
Chris@378
|
463 question.arg(thing),
|
Chris@378
|
464 tr("Locate file..."),
|
Chris@378
|
465 tr("Use URL..."),
|
Chris@378
|
466 tr("Cancel"),
|
Chris@378
|
467 0, 2);
|
Chris@378
|
468
|
Chris@378
|
469 switch (rv) {
|
Chris@378
|
470
|
Chris@378
|
471 case 0: // Locate file
|
Chris@378
|
472
|
Chris@378
|
473 if (QFileInfo(thing).dir().exists()) {
|
Chris@378
|
474 path = QFileInfo(thing).dir().canonicalPath();
|
Chris@378
|
475 }
|
Chris@378
|
476
|
Chris@378
|
477 path = getOpenFileName(type, path);
|
Chris@378
|
478 done = (path != "");
|
Chris@378
|
479 break;
|
Chris@378
|
480
|
Chris@378
|
481 case 1: // Use URL
|
Chris@378
|
482 {
|
Chris@378
|
483 bool ok = false;
|
Chris@378
|
484 path = QInputDialog::getText
|
Chris@378
|
485 (0, tr("Use URL"),
|
Chris@378
|
486 tr("Please enter the URL to use for this file:"),
|
Chris@378
|
487 QLineEdit::Normal, "", &ok);
|
Chris@378
|
488
|
Chris@378
|
489 if (ok && path != "") {
|
Chris@378
|
490 if (FileSource(path).isAvailable()) {
|
Chris@378
|
491 done = true;
|
Chris@378
|
492 } else {
|
Chris@378
|
493 QMessageBox::critical
|
Chris@378
|
494 (0, tr("Failed to open location"),
|
Chris@378
|
495 tr("URL \"%1\" could not be opened").arg(path));
|
Chris@378
|
496 path = "";
|
Chris@378
|
497 }
|
Chris@378
|
498 }
|
Chris@378
|
499 break;
|
Chris@378
|
500 }
|
Chris@378
|
501
|
Chris@378
|
502 case 2: // Cancel
|
Chris@378
|
503 path = "";
|
Chris@378
|
504 done = true;
|
Chris@378
|
505 break;
|
Chris@378
|
506 }
|
Chris@378
|
507 }
|
Chris@378
|
508
|
Chris@378
|
509 if (path != "") m_lastLocatedLocation = path;
|
Chris@378
|
510 return path;
|
Chris@378
|
511 }
|
Chris@378
|
512
|
Chris@378
|
513
|