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