summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
authorPierre Rossi <pierre.rossi@digia.com>2013-11-25 15:38:24 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-01-15 18:26:51 +0100
commitc34b72183e85e7c615ca65381d8591cdca23faf2 (patch)
treed5359c75cc8178e1f0e07c56aa52f88daba3fa23 /src/core
parent0b611c393e8208af717bd1c5e6c1aed1379d03ca (diff)
[Widgets] wire the file pickers
Introduce a new version of chooseFiles in QWebEnginePage. The existing API in WebKit1 seemed a bit dusty in any case (multiple only supported via extensions). Changes are: * oldFile becomes oldFiles, so that we could at a later stage expose the already selected files in the "multiple" case. * a type is introduced, for now limited to multiple selection, but over time, we might consider additions such as directory upload. Change-Id: I14cfea64ce95e892a0a1877c8cb914c5a421409f Reviewed-by: Jocelyn Turcotte <jocelyn.turcotte@digia.com>
Diffstat (limited to 'src/core')
-rw-r--r--src/core/type_conversion.h28
-rw-r--r--src/core/web_contents_adapter.cpp27
-rw-r--r--src/core/web_contents_adapter.h1
-rw-r--r--src/core/web_contents_adapter_client.h10
-rw-r--r--src/core/web_contents_delegate_qt.cpp15
-rw-r--r--src/core/web_contents_delegate_qt.h2
6 files changed, 83 insertions, 0 deletions
diff --git a/src/core/type_conversion.h b/src/core/type_conversion.h
index 659096b6e..a1c39581f 100644
--- a/src/core/type_conversion.h
+++ b/src/core/type_conversion.h
@@ -51,6 +51,7 @@
#include "third_party/skia/include/utils/SkMatrix44.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/gfx/rect.h"
+#include "ui/shell_dialogs/selected_file_info.h"
#include "url/gurl.h"
inline QString toQt(const base::string16 &string)
@@ -134,4 +135,31 @@ inline base::FilePath::StringType toFilePathString(const QString &str)
#endif
}
+template <typename T>
+inline T fileListingHelper(const QString &) {qFatal("Specialization missing for %s.", Q_FUNC_INFO);}
+
+template <>
+inline ui::SelectedFileInfo fileListingHelper<ui::SelectedFileInfo>(const QString &file)
+{
+ base::FilePath fp(toFilePathString(file));
+ return ui::SelectedFileInfo(fp, fp);
+}
+
+template <>
+inline base::FilePath fileListingHelper<base::FilePath>(const QString &file)
+{
+ return base::FilePath(toFilePathString(file));
+}
+
+
+template <typename T>
+inline std::vector<T> toVector(const QStringList &fileList)
+{
+ std::vector<T> selectedFiles;
+ selectedFiles.reserve(fileList.size());
+ Q_FOREACH (const QString &file, fileList)
+ selectedFiles.push_back(fileListingHelper<T>(file));
+ return selectedFiles;
+}
+
#endif // TYPE_CONVERSION_H
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index f3caa7478..7542f35bd 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -55,8 +55,10 @@
#include "content/public/browser/web_contents.h"
#include "content/public/common/page_zoom.h"
#include "content/public/common/renderer_preferences.h"
+#include "ui/shell_dialogs/selected_file_info.h"
#include <QGuiApplication>
+#include <QStringList>
#include <QStyleHints>
#include <QVariant>
@@ -146,6 +148,19 @@ static void callbackOnEvaluateJS(JSCallbackBase *callback, const base::Value *re
delete callback;
}
+static QStringList listRecursively(const QDir& dir) {
+ QStringList ret;
+ QFileInfoList infoList(dir.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot |QDir::Hidden));
+ Q_FOREACH (const QFileInfo &fileInfo, infoList) {
+ if (fileInfo.isDir()) {
+ ret.append(fileInfo.absolutePath() + QStringLiteral("/.")); // Match chromium's behavior. See chrome/browser/file_select_helper.cc
+ ret.append(listRecursively(QDir(fileInfo.absoluteFilePath())));
+ } else
+ ret.append(fileInfo.absoluteFilePath());
+ }
+ return ret;
+}
+
class WebContentsAdapterPrivate {
public:
WebContentsAdapterPrivate(WebContentsAdapterClient::RenderingMode renderingMode);
@@ -355,3 +370,15 @@ void WebContentsAdapter::dpiScaleChanged()
if (impl)
impl->NotifyScreenInfoChanged();
}
+
+void WebContentsAdapter::filesSelectedInChooser(const QStringList &fileList, WebContentsAdapterClient::FileChooserMode mode)
+{
+ Q_D(WebContentsAdapter);
+ content::RenderViewHost *rvh = d->webContents->GetRenderViewHost();
+ Q_ASSERT(rvh);
+ QStringList files(fileList);
+ if (mode == WebContentsAdapterClient::UploadFolder && !fileList.isEmpty()
+ && QFileInfo(fileList.first()).isDir()) // Enumerate the directory
+ files = listRecursively(QDir(fileList.first()));
+ rvh->FilesSelectedInChooser(toVector<ui::SelectedFileInfo>(files), static_cast<content::FileChooserParams::Mode>(mode));
+}
diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h
index 4bad8aa9b..5379afb70 100644
--- a/src/core/web_contents_adapter.h
+++ b/src/core/web_contents_adapter.h
@@ -88,6 +88,7 @@ public:
qreal currentZoomFactor() const;
void enableInspector(bool);
void runJavaScript(const QString &javaScript, const QString &xPath = QString(), JSCallbackBase * = 0);
+ void filesSelectedInChooser(const QStringList &fileList, WebContentsAdapterClient::FileChooserMode);
void dpiScaleChanged();
diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h
index 72754e9dc..2231fd46b 100644
--- a/src/core/web_contents_adapter_client.h
+++ b/src/core/web_contents_adapter_client.h
@@ -45,6 +45,7 @@
#include <QRect>
#include <QString>
+#include <QStringList>
#include <QUrl>
class RenderWidgetHostViewQt;
@@ -99,6 +100,14 @@ public:
PromptDialog
};
+ // Must match the ones in file_chooser_params.h
+ enum FileChooserMode {
+ Open,
+ OpenMultiple,
+ UploadFolder,
+ Save
+ };
+
virtual ~WebContentsAdapterClient() { }
virtual RenderWidgetHostViewQtDelegate* CreateRenderWidgetHostViewQtDelegate(RenderWidgetHostViewQtDelegateClient *client, RenderingMode mode) = 0;
@@ -115,6 +124,7 @@ public:
virtual void close() = 0;
virtual bool contextMenuRequested(const WebEngineContextMenuData&) = 0;
virtual bool javascriptDialog(JavascriptDialogType type, const QString &message, const QString &defaultValue = QString(), QString *result = 0) = 0;
+ virtual void runFileChooser(FileChooserMode, const QString &defaultFileName, const QStringList &acceptedMimeTypes) = 0;
};
#endif // WEB_CONTENTS_ADAPTER_CLIENT_H
diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp
index 5c5026f78..6dd8121dd 100644
--- a/src/core/web_contents_delegate_qt.cpp
+++ b/src/core/web_contents_delegate_qt.cpp
@@ -50,6 +50,7 @@
#include "content/public/browser/web_contents.h"
#include "content/public/browser/invalidate_type.h"
#include "content/public/common/favicon_url.h"
+#include "content/public/common/file_chooser_params.h"
WebContentsDelegateQt::WebContentsDelegateQt(content::WebContents *webContents, WebContentsAdapterClient *adapterClient)
: m_viewClient(adapterClient)
@@ -130,3 +131,17 @@ content::JavaScriptDialogManager *WebContentsDelegateQt::GetJavaScriptDialogMana
{
return JavaScriptDialogManagerQt::GetInstance();
}
+
+Q_STATIC_ASSERT_X(static_cast<int>(WebContentsAdapterClient::Open) == static_cast<int>(content::FileChooserParams::Open), "Enums out of sync");
+Q_STATIC_ASSERT_X(static_cast<int>(WebContentsAdapterClient::Save) == static_cast<int>(content::FileChooserParams::Save), "Enums out of sync");
+
+void WebContentsDelegateQt::RunFileChooser(content::WebContents *web_contents, const content::FileChooserParams &params)
+{
+ Q_UNUSED(web_contents)
+ QStringList acceptedMimeTypes;
+ acceptedMimeTypes.reserve(params.accept_types.size());
+ for (std::vector<base::string16>::const_iterator it = params.accept_types.begin(); it < params.accept_types.end(); ++it)
+ acceptedMimeTypes.append(toQt(*it));
+
+ m_viewClient->runFileChooser(static_cast<WebContentsAdapterClient::FileChooserMode>(params.mode), toQt(params.default_file_name.value()), acceptedMimeTypes);
+}
diff --git a/src/core/web_contents_delegate_qt.h b/src/core/web_contents_delegate_qt.h
index b0cfd8952..e6d481469 100644
--- a/src/core/web_contents_delegate_qt.h
+++ b/src/core/web_contents_delegate_qt.h
@@ -46,6 +46,7 @@
#include "content/public/browser/web_contents_observer.h"
#include "javascript_dialog_manager_qt.h"
+#include <QtCore/qcompilerdetection.h>
namespace content {
class BrowserContext;
@@ -73,6 +74,7 @@ public:
virtual void DidUpdateFaviconURL(int32 page_id, const std::vector<content::FaviconURL>& candidates) Q_DECL_OVERRIDE;
virtual void DidFailProvisionalLoad(int64 frame_id, bool is_main_frame, const GURL& validated_url, int error_code, const string16& error_description, content::RenderViewHost* render_view_host) Q_DECL_OVERRIDE;
virtual content::JavaScriptDialogManager *GetJavaScriptDialogManager() Q_DECL_OVERRIDE;
+ virtual void RunFileChooser(content::WebContents *, const content::FileChooserParams &params) Q_DECL_OVERRIDE;
private:
WebContentsAdapterClient *m_viewClient;