diff options
Diffstat (limited to 'src/core/file_picker_controller.cpp')
-rw-r--r-- | src/core/file_picker_controller.cpp | 106 |
1 files changed, 84 insertions, 22 deletions
diff --git a/src/core/file_picker_controller.cpp b/src/core/file_picker_controller.cpp index 3e64afd20..62e02e126 100644 --- a/src/core/file_picker_controller.cpp +++ b/src/core/file_picker_controller.cpp @@ -39,14 +39,18 @@ #include "file_picker_controller.h" #include "type_conversion.h" +#if defined(OS_WIN) +#include "base/files/file_path.h" +#endif #include "content/browser/renderer_host/render_view_host_impl.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/public/browser/file_select_listener.h" -#include <QFileInfo> #include <QDir> -#include <QVariant> +#include <QFileInfo> +#include <QMimeDatabase> #include <QStringList> +#include <QVariant> namespace QtWebEngineCore { @@ -64,12 +68,31 @@ FilePickerController::~FilePickerController() = default; void FilePickerController::accepted(const QStringList &files) { QStringList stringList; - - for (const QString &file : files) { - if (QDir(file).isAbsolute()) - stringList.append(file); - else - qWarning("Ignore invalid item in FilePickerController::accepted(QStringList): %s", qPrintable(file)); + stringList.reserve(files.count()); + + for (const QString &urlString : files) { + // We accept strings on both absolute-path and file-URL form: + if (QDir::isAbsolutePath(urlString)) { + QString absolutePath = QDir::fromNativeSeparators(urlString); +#if defined(OS_WIN) + if (absolutePath.at(0).isLetter() && absolutePath.at(1) == QLatin1Char(':') && !base::FilePath::IsSeparator(absolutePath.at(2).toLatin1())) + qWarning("Ignoring invalid item in FilePickerController::accepted(QStringList): %s", qPrintable(urlString)); + else +#endif + stringList.append(absolutePath); + } else { + QUrl url(urlString, QUrl::StrictMode); + if (url.isLocalFile() && QDir::isAbsolutePath(url.toLocalFile())) { + QString absolutePath = url.toLocalFile(); +#if defined(OS_WIN) + if (absolutePath.at(0).isLetter() && absolutePath.at(1) == QLatin1Char(':') && !base::FilePath::IsSeparator(absolutePath.at(2).toLatin1())) + qWarning("Ignoring invalid item in FilePickerController::accepted(QStringList): %s", qPrintable(urlString)); + else +#endif + stringList.append(absolutePath); + } else + qWarning("Ignoring invalid item in FilePickerController::accepted(QStringList): %s", qPrintable(urlString)); + } } FilePickerController::filesSelectedInChooser(stringList); @@ -77,21 +100,10 @@ void FilePickerController::accepted(const QStringList &files) void FilePickerController::accepted(const QVariant &files) { - QStringList stringList; - QList<QUrl> urlList = QUrl::fromStringList(files.toStringList()); - - if (urlList.isEmpty()) { - FilePickerController::accepted(stringList); - } else { - for (const QUrl &url : qAsConst(urlList)) { - if (url.isValid() && url.scheme() == "file" && !url.path().isEmpty()) - stringList.append(url.path()); - else - qWarning("Ignore invalid item in FilePickerController::accepted(QVariant): %s", qPrintable(url.toString())); - } + if (!files.canConvert(QVariant::StringList)) + qWarning("An unhandled type '%s' was provided in FilePickerController::accepted(QVariant)", files.typeName()); - FilePickerController::accepted(stringList); - } + accepted(files.toStringList()); } void FilePickerController::rejected() @@ -154,4 +166,54 @@ QString FilePickerController::defaultFileName() const return m_defaultFileName; } +QStringList FilePickerController::nameFilters(const QStringList &acceptedMimeTypes) +{ + QStringList nameFilters; + QStringList acceptedGlobs; + QMimeDatabase mimeDatabase; + + if (acceptedMimeTypes.isEmpty()) + return nameFilters; + + for (QString type : acceptedMimeTypes) { + if (type.startsWith(".")) { + // A single suffix + // Filename.type doesn't have to exist and mimeTypeForFile() supports + // custom suffixes as valid (but unknown) MIME types. + const QMimeType &mimeType = mimeDatabase.mimeTypeForFile("filename" + type); + if (mimeType.isValid()) { + QString glob = "*" + type; + acceptedGlobs.append(glob); + nameFilters.append(mimeType.comment() + " (" + glob + ")"); + } + } else if (type.contains("/") && !type.endsWith("*")) { + // All suffixes for a given MIME type + const QMimeType &mimeType = mimeDatabase.mimeTypeForName(type); + if (mimeType.isValid() && !mimeType.globPatterns().isEmpty()) { + QString globs = mimeType.globPatterns().join(" "); + acceptedGlobs.append(globs); + nameFilters.append(mimeType.comment() + " (" + globs + ")"); + } + } else if (type.endsWith("/*")) { + // All MIME types for audio/*, image/* or video/* + // as separate filters as Chrome does + static const QList<QMimeType> &allMimeTypes = mimeDatabase.allMimeTypes(); + type = type.remove("/*"); + for (const QMimeType &m : allMimeTypes) { + if (m.name().startsWith(type) && !m.globPatterns().isEmpty()) { + QString globs = m.globPatterns().join(" "); + acceptedGlobs.append(globs); + nameFilters.append(m.comment() + " (" + globs + ")"); + } + } + } else { + NOTREACHED(); + } + } + + nameFilters.prepend(QObject::tr("Accepted types") + " (" + acceptedGlobs.join(" ") + ")"); + + return nameFilters; +} + } // namespace |