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