https://bugs.webkit.org/show_bug.cgi?id=81589
Patch by Dinu Jacob <dinu.jacob@nokia.com> on 2012-03-26
Reviewed by Simon Hausmann.
Source/WebKit2:
Added 'allowMutipleFiles' property to filePicker context property to indicate whether to allow
multiple file selections.
* UIProcess/API/qt/qquickwebview.cpp:
(QQuickWebViewPrivate::chooseFiles):
* UIProcess/API/qt/tests/qmltests/DesktopBehavior.pro:
* UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_multiFileUpload.qml: Added.
* UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_singleFileUpload.qml:
* UIProcess/API/qt/tests/qmltests/common/multifileupload.html: Added.
* UIProcess/API/qt/tests/qmltests/common/singlefileupload.html:
* UIProcess/API/qt/tests/qmltests/common/titleupdate.js: Added.
(updateTitle):
* UIProcess/qt/QtDialogRunner.cpp:
(FilePickerContextObject):
(FilePickerContextObject::FilePickerContextObject):
(FilePickerContextObject::allowMultipleFiles):
(FilePickerContextObject::accept):
(QtDialogRunner::initForFilePicker):
* UIProcess/qt/QtDialogRunner.h:
(QtDialogRunner):
Tools:
Modified filePicker to support multi-file upload.
* MiniBrowser/qt/MiniBrowser.qrc:
* MiniBrowser/qt/icons/checkbox_checked.png: Added.
* MiniBrowser/qt/icons/checkbox_unchecked.png: Added.
* MiniBrowser/qt/js/MultiSelect.js: Added.
(values):
(isSelected):
(removeValue):
* MiniBrowser/qt/qml/CheckBox.qml: Added.
* MiniBrowser/qt/qml/FilePicker.qml:
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@112195
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2012-03-26 Dinu Jacob <dinu.jacob@nokia.com>
+
+ [Qt][WK2] Support multi-file upload
+ https://bugs.webkit.org/show_bug.cgi?id=81589
+
+ Reviewed by Simon Hausmann.
+
+ Added 'allowMutipleFiles' property to filePicker context property to indicate whether to allow
+ multiple file selections.
+
+ * UIProcess/API/qt/qquickwebview.cpp:
+ (QQuickWebViewPrivate::chooseFiles):
+ * UIProcess/API/qt/tests/qmltests/DesktopBehavior.pro:
+ * UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_multiFileUpload.qml: Added.
+ * UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_singleFileUpload.qml:
+ * UIProcess/API/qt/tests/qmltests/common/multifileupload.html: Added.
+ * UIProcess/API/qt/tests/qmltests/common/singlefileupload.html:
+ * UIProcess/API/qt/tests/qmltests/common/titleupdate.js: Added.
+ (updateTitle):
+ * UIProcess/qt/QtDialogRunner.cpp:
+ (FilePickerContextObject):
+ (FilePickerContextObject::FilePickerContextObject):
+ (FilePickerContextObject::allowMultipleFiles):
+ (FilePickerContextObject::accept):
+ (QtDialogRunner::initForFilePicker):
+ * UIProcess/qt/QtDialogRunner.h:
+ (QtDialogRunner):
+
2012-03-26 Adam Barth <abarth@webkit.org>
FrameLoader::shouldAllowNavigation uses Frame for context rather than Document
{
Q_Q(QQuickWebView);
- if (!filePicker || type == QtWebPageUIClient::MultipleFilesSelection)
+ if (!filePicker)
return;
QtDialogRunner dialogRunner;
- if (!dialogRunner.initForFilePicker(filePicker, q, selectedFileNames))
+ if (!dialogRunner.initForFilePicker(filePicker, q, selectedFileNames, (type == QtWebPageUIClient::MultipleFilesSelection)))
return;
execDialogRunner(dialogRunner);
DesktopBehavior/tst_loadHtml.qml \
DesktopBehavior/tst_messaging.qml \
DesktopBehavior/tst_navigationRequested.qml \
- DesktopBehavior/tst_singlefileupload.qml
+ DesktopBehavior/tst_singleFileupload.qml \
+ DesktopBehavior/tst_multiFileupload.qml
--- /dev/null
+import QtQuick 2.0
+import QtTest 1.0
+import QtWebKit 3.0
+import QtWebKit.experimental 1.0
+import "../common"
+
+// FIXME: Added to Desktop tests because we want to have mouseClick() to open the <input> tag. We can move it back
+// when TestCase starts supporting touch events, see https://bugreports.qt.nokia.com/browse/QTBUG-23083.
+TestWebView {
+ id: webView
+
+ width: 400
+ height: 400
+
+ property bool selectFile
+
+ experimental.filePicker: Item {
+ Timer {
+ running: true
+ interval: 1
+ onTriggered: {
+ var selectedFiles = ["filename1", "filename2"]
+ if (selectFile)
+ model.accept(selectedFiles)
+ else
+ model.reject();
+ }
+ }
+ }
+
+ SignalSpy {
+ id: titleSpy
+ target: webView
+ signalName: "titleChanged"
+ }
+
+ TestCase {
+ id: test
+ name: "WebViewMultiFilePicker"
+ when: windowShown
+
+ function init() {
+ webView.url = Qt.resolvedUrl("../common/multifileupload.html")
+ verify(webView.waitForLoadSucceeded())
+ titleSpy.clear()
+ }
+
+ function openItemSelector() {
+ mouseClick(webView, 15, 15, Qt.LeftButton)
+ }
+
+ function test_accept() {
+ webView.selectFile = true;
+ openItemSelector()
+ titleSpy.wait()
+ compare(webView.title, "filename1,filename2")
+ }
+
+ function test_reject() {
+ var oldTitle = webView.title
+ webView.selectFile = false;
+ openItemSelector()
+ compare(webView.title, oldTitle)
+ }
+ }
+}
height: 400
property bool selectFile
+ property bool acceptMultiple: false
experimental.filePicker: Item {
Timer {
running: true
interval: 1
onTriggered: {
- if (selectFile)
- model.accept("acceptedfilename");
+ var selectedFiles = ["filename1", "filename2"]
+ if (selectFile) {
+ if (acceptMultiple)
+ model.accept(selectedFiles)
+ else
+ model.accept("acceptedfilename");
+ }
else
model.reject();
}
compare(webView.title, "acceptedfilename")
}
+ function test_multiple() {
+ webView.selectFile = true;
+ webView.acceptMultiple = true;
+ openItemSelector()
+ titleSpy.wait()
+ compare(webView.title, "filename1")
+ }
+
function test_reject() {
var oldTitle = webView.title
webView.selectFile = false;
--- /dev/null
+<html>
+<head>
+<meta name="viewport" initial-scale=1">
+<title> Mutli-file Upload </title>
+<script src = "./titleupdate.js">
+</script>
+
+<body>
+<input type="file" name="file" id="upfile" onchange="updateTitle()" multiple/>
+</body>
+</html>
<html>
<head>
<meta name="viewport" initial-scale=1">
-<title>No file selected</title>
-<script>
-function updateTitle()
-{
- var inp = document.getElementById("upfile");
- var allfiles = new String("");
- var name = new String("");
- for (var i = 0; i < inp.files.length; ++i)
- {
- name = inp.files.item(i).name;
- if (allfiles.length == 0)
- allfiles = name;
- else
- allfiles = allfiles + "," + name;
- }
- document.title = allfiles;
-}
+<title> Single File Upload </title>
+<script src = "./titleupdate.js">
</script>
<body>
--- /dev/null
+function updateTitle()
+{
+ var inp = document.getElementById("upfile");
+ var allfiles = new String("");
+ var name = new String("");
+ for (var i = 0; i < inp.files.length; ++i)
+ {
+ name = inp.files.item(i).name;
+ if (allfiles.length == 0)
+ allfiles = name;
+ else
+ allfiles = allfiles + "," + name;
+ }
+ document.title = allfiles;
+}
class FilePickerContextObject : public QObject {
Q_OBJECT
Q_PROPERTY(QStringList fileList READ fileList CONSTANT)
+ Q_PROPERTY(bool allowMultipleFiles READ allowMultipleFiles CONSTANT)
public:
- FilePickerContextObject(const QStringList& selectedFiles)
+ FilePickerContextObject(const QStringList& selectedFiles, bool allowMultiple)
: QObject()
+ , m_allowMultiple(allowMultiple)
, m_fileList(selectedFiles)
{
}
QStringList fileList() const { return m_fileList; }
+ bool allowMultipleFiles() const { return m_allowMultiple;}
public slots:
void reject() { emit rejected();}
- void accept(const QVariant& path) { emit fileSelected(path.toStringList()); }
+ void accept(const QVariant& path)
+ {
+ QStringList filesPath = path.toStringList();
+ // For single file upload, send only the first element if there are more than one file paths
+ if (!m_allowMultiple && filesPath.count() > 1)
+ filesPath = QStringList(filesPath.at(0));
+ emit fileSelected(filesPath);
+ }
signals:
void rejected();
void fileSelected(const QStringList&);
private:
+ bool m_allowMultiple;
QStringList m_fileList;
};
return true;
}
-bool QtDialogRunner::initForFilePicker(QDeclarativeComponent* component, QQuickItem* dialogParent, const QStringList& selectedFiles)
+bool QtDialogRunner::initForFilePicker(QDeclarativeComponent* component, QQuickItem* dialogParent, const QStringList& selectedFiles, bool allowMultiple)
{
- FilePickerContextObject* contextObject = new FilePickerContextObject(selectedFiles);
+ FilePickerContextObject* contextObject = new FilePickerContextObject(selectedFiles, allowMultiple);
if (!createDialog(component, dialogParent, contextObject))
return false;
bool initForAuthentication(QDeclarativeComponent*, QQuickItem* dialogParent, const QString& hostname, const QString& realm, const QString& prefilledUsername);
bool initForCertificateVerification(QDeclarativeComponent*, QQuickItem*, const QString& hostname);
bool initForProxyAuthentication(QDeclarativeComponent*, QQuickItem*, const QString& hostname, uint16_t port, const QString& prefilledUsername);
- bool initForFilePicker(QDeclarativeComponent*, QQuickItem*, const QStringList& selectedFiles);
+ bool initForFilePicker(QDeclarativeComponent*, QQuickItem*, const QStringList& selectedFiles, bool allowMultiple);
bool initForDatabaseQuotaDialog(QDeclarativeComponent*, QQuickItem*, const QString& databaseName, const QString& displayName, WKSecurityOriginRef, quint64 currentQuota, quint64 currentOriginUsage, quint64 currentDatabaseUsage, quint64 expectedUsage);
QQuickItem* dialog() const { return m_dialog.get(); }
+2012-03-26 Dinu Jacob <dinu.jacob@nokia.com>
+
+ [Qt][WK2] Support multi-file upload
+ https://bugs.webkit.org/show_bug.cgi?id=81589
+
+ Reviewed by Simon Hausmann.
+
+ Modified filePicker to support multi-file upload.
+
+ * MiniBrowser/qt/MiniBrowser.qrc:
+ * MiniBrowser/qt/icons/checkbox_checked.png: Added.
+ * MiniBrowser/qt/icons/checkbox_unchecked.png: Added.
+ * MiniBrowser/qt/js/MultiSelect.js: Added.
+ (values):
+ (isSelected):
+ (removeValue):
+ * MiniBrowser/qt/qml/CheckBox.qml: Added.
+ * MiniBrowser/qt/qml/FilePicker.qml:
+
2012-03-26 Mark Hahnenberg <mhahnenberg@apple.com>
Retry crashing tests serially at the end of NRWT on Apple Mac
<RCC>
<qresource prefix="/">
+ <file>icons/checkbox_checked.png</file>
+ <file>icons/checkbox_unchecked.png</file>
<file>icons/favicon.png</file>
<file>icons/folder.png</file>
<file>icons/info.png</file>
<file>icons/touch.png</file>
<file>icons/touchpoint.png</file>
<file>icons/up.png</file>
+ <file>js/MultiSelect.js</file>
<file>qml/AlertDialog.qml</file>
<file>qml/AuthenticationDialog.qml</file>
<file>qml/BrowserWindow.qml</file>
+ <file>qml/CheckBox.qml</file>
<file>qml/ConfirmDialog.qml</file>
<file>qml/Dialog.qml</file>
<file>qml/DialogButton.qml</file>
--- /dev/null
+/*
+ * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this program; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+var values = []
+
+function selectedValues() {
+ return values
+}
+
+function isSelected(value) {
+ return (values.indexOf(value) != -1)
+}
+
+function addValue(value) {
+ if (values.indexOf(value) != -1)
+ return
+ values.push(value)
+}
+
+function removeValue(value) {
+ var index = values.indexOf(value)
+
+ if (index == -1)
+ return
+ values.splice(index, 1)
+}
--- /dev/null
+/*
+ * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this program; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+import QtQuick 2.0
+
+Item {
+ id: checkbox
+ width: 50
+ height: parent.height
+ property bool checked
+
+ Image {
+ width: 24
+ height: 24
+ source: parent.checked ? '../icons/checkbox_checked.png' : '../icons/checkbox_unchecked.png'
+ anchors.verticalCenter: parent.verticalCenter
+ }
+}
import QtQuick 2.0
import Qt.labs.folderlistmodel 1.0
+import "../js/MultiSelect.js" as MultiSelect
Rectangle {
id: filePicker
function selected() {
if (folders.isFolder(index))
openFolder(filePath);
- else
- fileModel.accept(filePath);
+ else {
+
+ if (fileModel.allowMultipleFiles) {
+ checkbox.checked = !checkbox.checked
+
+ if (checkbox.checked)
+ MultiSelect.addValue(filePath)
+ else
+ MultiSelect.removeValue(filePath)
+ }
+ else
+ fileModel.accept(filePath)
+ }
}
height: 50
color: folders.isFolder(index) ? "lightgray": "darkgray"
Item {
- width: 48;
+ width: 50
height: 48
Image {
source: "../icons/folder.png"
}
Text {
+ id: fileNameText
anchors.centerIn: parent
- anchors.leftMargin: 50
+ anchors.leftMargin: 20
+ width: 300
text: fileName
+ elide: Text.ElideLeft;
+ }
+
+ CheckBox {
+ id: checkbox
+
+ anchors.right: parent.right
+ anchors.verticalCenter: parent.verticalCenter
+
+ checked: MultiSelect.isSelected(filePath)
+ visible: fileModel.allowMultipleFiles && !folders.isFolder(index)
}
MouseArea {
right: parent.right
}
- DialogButton {
- id: cancel
- text: "Cancel"
- anchors {
- horizontalCenter: parent.horizontalCenter;
- verticalCenter: parent.verticalCenter
+ Row {
+ id: buttonRow
+ spacing: 10
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.verticalCenter: parent.verticalCenter
+
+ DialogButton {
+ id: cancel
+ text: "Cancel"
+ onClicked: fileModel.reject()
}
- onClicked: fileModel.reject()
+ DialogButton {
+ id: accept
+ text: "Ok"
+ visible: fileModel.allowMultipleFiles
+ onClicked:
+ fileModel.accept(MultiSelect.selectedValues());
+ }
}
}