summaryrefslogtreecommitdiffstats
path: root/src/core/file_picker_controller.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/file_picker_controller.cpp')
-rw-r--r--src/core/file_picker_controller.cpp106
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