From db2c0781218b7dfa03f7bc39b1e2115dbf4a0fb0 Mon Sep 17 00:00:00 2001 From: Pierre Rossi Date: Mon, 16 Dec 2013 20:48:08 +0100 Subject: Qt Quick File Picker Change-Id: I6195c49f1647c78b16d9d47770ab37ba998a61a5 Reviewed-by: Jocelyn Turcotte --- src/webengine/api/qquickwebengineview.cpp | 6 ++ src/webengine/api/qquickwebengineview_p_p.h | 2 +- src/webengine/ui/FilePicker.qml | 51 ++++++++++++++++ src/webengine/ui/qmldir | 1 + src/webengine/ui/ui.pro | 1 + src/webengine/ui_delegates_manager.cpp | 93 +++++++++++++++++++++++++++++ src/webengine/ui_delegates_manager.h | 6 +- 7 files changed, 158 insertions(+), 2 deletions(-) create mode 100644 src/webengine/ui/FilePicker.qml (limited to 'src/webengine') diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp index c06a4af48..db9ab7d25 100644 --- a/src/webengine/api/qquickwebengineview.cpp +++ b/src/webengine/api/qquickwebengineview.cpp @@ -177,6 +177,12 @@ void QQuickWebEngineViewPrivate::javascriptDialog(QSharedPointershowDialog(dialog); } + +void QQuickWebEngineViewPrivate::runFileChooser(FileChooserMode mode, const QString &defaultFileName, const QStringList &acceptedMimeTypes) +{ + ui()->showFilePicker(mode, defaultFileName, acceptedMimeTypes, adapter); +} + void QQuickWebEngineViewPrivate::titleChanged(const QString &title) { Q_Q(QQuickWebEngineView); diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h index 45622d308..f0bc0a9fb 100644 --- a/src/webengine/api/qquickwebengineview_p_p.h +++ b/src/webengine/api/qquickwebengineview_p_p.h @@ -137,7 +137,7 @@ public: virtual void close() Q_DECL_OVERRIDE; virtual bool contextMenuRequested(const WebEngineContextMenuData &) Q_DECL_OVERRIDE; virtual void javascriptDialog(QSharedPointer) Q_DECL_OVERRIDE; - virtual void runFileChooser(FileChooserMode, const QString &defaultFileName, const QStringList &acceptedMimeTypes) { Q_UNUSED(defaultFileName); Q_UNUSED(acceptedMimeTypes);} + virtual void runFileChooser(FileChooserMode, const QString &defaultFileName, const QStringList &acceptedMimeTypes) Q_DECL_OVERRIDE; void setDevicePixelRatio(qreal); diff --git a/src/webengine/ui/FilePicker.qml b/src/webengine/ui/FilePicker.qml new file mode 100644 index 000000000..02b0bebea --- /dev/null +++ b/src/webengine/ui/FilePicker.qml @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick.Dialogs 1.1 + +FileDialog { + + signal filesSelected(var fileList); + + onAccepted: { + filesSelected(fileUrls); + } +} diff --git a/src/webengine/ui/qmldir b/src/webengine/ui/qmldir index bb942a81a..69ebe1bad 100644 --- a/src/webengine/ui/qmldir +++ b/src/webengine/ui/qmldir @@ -1,6 +1,7 @@ module QtWebEngine.UIDelegates AlertDialog 1.0 AlertDialog.qml ConfirmDialog 1.0 ConfirmDialog.qml +FilePicker 1.0 FilePicker.qml PromptDialog 1.0 PromptDialog.qml Menu 1.0 Menu.qml MenuItem 1.0 MenuItem.qml diff --git a/src/webengine/ui/ui.pro b/src/webengine/ui/ui.pro index 049b428f5..a5ae648cb 100644 --- a/src/webengine/ui/ui.pro +++ b/src/webengine/ui/ui.pro @@ -4,6 +4,7 @@ QML_FILES += \ # JS Dialogs AlertDialog.qml \ ConfirmDialog.qml \ + FilePicker.qml \ PromptDialog.qml \ # Menus. Based on Qt Quick Controls Menu.qml \ diff --git a/src/webengine/ui_delegates_manager.cpp b/src/webengine/ui_delegates_manager.cpp index 6ee3ea360..13e4a9fce 100644 --- a/src/webengine/ui_delegates_manager.cpp +++ b/src/webengine/ui_delegates_manager.cpp @@ -304,3 +304,96 @@ void UIDelegatesManager::showDialog(QSharedPointer d QMetaObject::invokeMethod(dialog, "open"); } + +namespace { +class FilePickerController : public QObject { + Q_OBJECT +public: + FilePickerController(WebContentsAdapterClient::FileChooserMode, const QExplicitlySharedDataPointer &, QObject * = 0); + +public Q_SLOTS: + void accepted(const QVariant &files); + void rejected(); + +private: + QExplicitlySharedDataPointer m_adapter; + WebContentsAdapterClient::FileChooserMode m_mode; + +}; + + +FilePickerController::FilePickerController(WebContentsAdapterClient::FileChooserMode mode, const QExplicitlySharedDataPointer &adapter, QObject *parent) + : QObject(parent) + , m_adapter(adapter) + , m_mode(mode) +{ +} + +void FilePickerController::accepted(const QVariant &files) +{ + QStringList stringList; + // Qt Quick's file dialog returns a list of QUrls, this will hence shape our API there. + Q_FOREACH (const QUrl &url, files.value >()) + stringList.append(url.toLocalFile()); + + m_adapter->filesSelectedInChooser(stringList, m_mode); +} + +void FilePickerController::rejected() +{ + m_adapter->filesSelectedInChooser(QStringList(), m_mode); +} + +} // namespace + + +void UIDelegatesManager::showFilePicker(WebContentsAdapterClient::FileChooserMode mode, const QString &defaultFileName, const QStringList &acceptedMimeTypes, const QExplicitlySharedDataPointer &adapter) +{ + Q_UNUSED(defaultFileName); + Q_UNUSED(acceptedMimeTypes); + + if (!ensureComponentLoaded(FilePicker)) + return; + QQmlContext *context(creationContextForComponent(filePickerComponent.data())); + QObject *filePicker = filePickerComponent->beginCreate(context); + if (QQuickItem* item = qobject_cast(filePicker)) + item->setParentItem(m_view); + filePicker->setParent(m_view); + filePickerComponent->completeCreate(); + + // Fine-tune some properties depending on the mode. + switch (mode) { + case WebContentsAdapterClient::Open: + break; + case WebContentsAdapterClient::Save: + filePicker->setProperty("selectExisting", false); + break; + case WebContentsAdapterClient::OpenMultiple: + filePicker->setProperty("selectMultiple", true); + break; + case WebContentsAdapterClient::UploadFolder: + filePicker->setProperty("selectFolder", true); + break; + default: + Q_UNREACHABLE(); + } + + FilePickerController *controller = new FilePickerController(mode, adapter, filePicker); + QQmlProperty filesPickedSignal(filePicker, QStringLiteral("onFilesSelected")); + CHECK_QML_SIGNAL_PROPERTY(filesPickedSignal, filePickerComponent->url()); + QQmlProperty rejectSignal(filePicker, QStringLiteral("onRejected")); + CHECK_QML_SIGNAL_PROPERTY(rejectSignal, filePickerComponent->url()); + static int acceptedIndex = controller->metaObject()->indexOfSlot("accepted(QVariant)"); + QObject::connect(filePicker, filesPickedSignal.method(), controller, controller->metaObject()->method(acceptedIndex)); + static int rejectedIndex = controller->metaObject()->indexOfSlot("rejected()"); + QObject::connect(filePicker, rejectSignal.method(), controller, controller->metaObject()->method(rejectedIndex)); + + // delete when done. + static int deleteLaterIndex = filePicker->metaObject()->indexOfSlot("deleteLater()"); + QObject::connect(filePicker, filesPickedSignal.method(), filePicker, filePicker->metaObject()->method(deleteLaterIndex)); + QObject::connect(filePicker, rejectSignal.method(), filePicker, filePicker->metaObject()->method(deleteLaterIndex)); + + QMetaObject::invokeMethod(filePicker, "open"); +} + +#include "ui_delegates_manager.moc" diff --git a/src/webengine/ui_delegates_manager.h b/src/webengine/ui_delegates_manager.h index eeece895c..a6d15a530 100644 --- a/src/webengine/ui_delegates_manager.h +++ b/src/webengine/ui_delegates_manager.h @@ -44,6 +44,7 @@ #include "qglobal.h" #include "web_contents_adapter.h" +#include "web_contents_adapter_client.h" #include #include @@ -58,7 +59,8 @@ F(MenuSeparator, menuSeparator) SEPARATOR \ F(AlertDialog, alertDialog) SEPARATOR \ F(ConfirmDialog, confirmDialog) SEPARATOR \ - F(PromptDialog, promptDialog) SEPARATOR + F(PromptDialog, promptDialog) SEPARATOR \ + F(FilePicker, filePicker) SEPARATOR #define COMMA_SEPARATOR , #define SEMICOLON_SEPARATOR ; @@ -123,6 +125,8 @@ public: QObject *addMenu(QObject *parentMenu, const QString &title, const QPoint &pos = QPoint()); QQmlContext *creationContextForComponent(QQmlComponent *); void showDialog(QSharedPointer); + void showFilePicker(WebContentsAdapterClient::FileChooserMode, const QString &defaultFileName, const QStringList &acceptedMimeTypes + , const QExplicitlySharedDataPointer &); private: bool ensureComponentLoaded(ComponentType); -- cgit v1.2.3