aboutsummaryrefslogtreecommitdiffstats
path: root/src/imports
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@digia.com>2013-01-08 17:30:49 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-03-04 09:15:22 +0100
commitb45f742dd8c533cff0767d2dfbe68ea9fd19a522 (patch)
tree7a5a7a320a432bb0fa1e7fec6d546d09efd7de56 /src/imports
parent84c41e4c7e22774e18d1462fcf4ca907a960900c (diff)
adding QtQuick.Dialogs, with FileDialog implementation
This will obsolete the QFileDialogItem in desktop components and be available to all QtQuick applications. The QML FileDialog type is dynamically defined in the plugin by detecting which implementation will work on the current platform. Change-Id: I073c7a84bff6c02cf592dc46822a5a4b9c9bcaea Reviewed-by: Jens Bache-Wiig <jens.bache-wiig@digia.com>
Diffstat (limited to 'src/imports')
-rw-r--r--src/imports/dialogs/DefaultFileDialog.qml366
-rw-r--r--src/imports/dialogs/WidgetFileDialog.qml45
-rw-r--r--src/imports/dialogs/dialogs.pro30
-rw-r--r--src/imports/dialogs/images/folder.pngbin0 -> 1841 bytes
-rw-r--r--src/imports/dialogs/images/titlebar.pngbin0 -> 1436 bytes
-rw-r--r--src/imports/dialogs/images/titlebar.sci5
-rw-r--r--src/imports/dialogs/images/up.pngbin0 -> 662 bytes
-rw-r--r--src/imports/dialogs/plugin.cpp140
-rw-r--r--src/imports/dialogs/plugins.qmltypes72
-rw-r--r--src/imports/dialogs/qml/Button.qml90
-rw-r--r--src/imports/dialogs/qml/TextField.qml77
-rw-r--r--src/imports/dialogs/qml/qmldir2
-rw-r--r--src/imports/dialogs/qmldir2
-rw-r--r--src/imports/dialogs/qquickabstractfiledialog.cpp233
-rw-r--r--src/imports/dialogs/qquickabstractfiledialog_p.h144
-rw-r--r--src/imports/dialogs/qquickfiledialog.cpp230
-rw-r--r--src/imports/dialogs/qquickfiledialog_p.h99
-rw-r--r--src/imports/dialogs/qquickplatformfiledialog.cpp314
-rw-r--r--src/imports/dialogs/qquickplatformfiledialog_p.h78
-rw-r--r--src/imports/imports.pro3
-rw-r--r--src/imports/widgets/plugins.qmltypes72
-rw-r--r--src/imports/widgets/qmldir3
-rw-r--r--src/imports/widgets/qquickqfiledialog.cpp199
-rw-r--r--src/imports/widgets/qquickqfiledialog_p.h78
-rw-r--r--src/imports/widgets/widgets.pro17
-rw-r--r--src/imports/widgets/widgetsplugin.cpp83
26 files changed, 2382 insertions, 0 deletions
diff --git a/src/imports/dialogs/DefaultFileDialog.qml b/src/imports/dialogs/DefaultFileDialog.qml
new file mode 100644
index 0000000000..80bf6b5cb1
--- /dev/null
+++ b/src/imports/dialogs/DefaultFileDialog.qml
@@ -0,0 +1,366 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtDeclarative module 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 2.1
+import QtQuick.Dialogs 1.0
+import Qt.labs.folderlistmodel 2.0
+import "qml"
+
+AbstractFileDialog {
+ id: root
+ onVisibleChanged: {
+ if (visible) {
+ selectedIndices = []
+ lastClickedIdx = -1
+ currentPathField.visible = false
+ }
+ }
+
+ property bool showFocusHighlight: false
+ property real textX: 28
+ property SystemPalette palette
+ property var selectedIndices: []
+ property int lastClickedIdx: -1
+ folder: urlToPath(view.model.folder)
+
+ function dirDown(path) {
+ view.model.folder = path
+ lastClickedIdx = -1
+ selectedIndices = []
+ }
+ function dirUp() {
+ view.model.folder = view.model.parentFolder
+ lastClickedIdx = -1
+ selectedIndices = []
+ }
+ function up(extend) {
+ if (view.currentIndex > 0)
+ --view.currentIndex
+ else
+ view.currentIndex = 0
+ if (extend) {
+ if (selectedIndices.indexOf(view.currentIndex) < 0) {
+ var selCopy = selectedIndices
+ selCopy.push(view.currentIndex)
+ selectedIndices = selCopy
+ }
+ } else
+ selectedIndices = [view.currentIndex]
+ }
+ function down(extend) {
+ if (view.currentIndex < view.model.count - 1)
+ ++view.currentIndex
+ else
+ view.currentIndex = view.model.count - 1
+ if (extend) {
+ if (selectedIndices.indexOf(view.currentIndex) < 0) {
+ var selCopy = selectedIndices
+ selCopy.push(view.currentIndex)
+ selectedIndices = selCopy
+ }
+ } else
+ selectedIndices = [view.currentIndex]
+ }
+ function acceptSelection() {
+ clearSelection()
+ if (selectFolder && selectedIndices.length == 0)
+ addSelection(folder)
+ else {
+ selectedIndices.map(function(idx) {
+ if (view.model.isFolder(idx)) {
+ if (selectFolder)
+ addSelection(view.model.get(idx, "filePath"))
+ } else {
+ if (!selectFolder)
+ addSelection(view.model.get(idx, "filePath"))
+ }
+ })
+ }
+ accept()
+ }
+
+ Rectangle {
+ width: 480 // TODO: QTBUG-29817 geometry from AbstractFileDialog
+ height: 320
+ id: window
+ color: palette.window
+ anchors.centerIn: Qt.application.supportsMultipleWindows ? null : parent
+
+ SystemPalette { id: palette }
+
+ Component {
+ id: folderDelegate
+ Rectangle {
+ id: wrapper
+ function launch() {
+ if (view.model.isFolder(index)) {
+ dirDown(filePath)
+ } else {
+ root.acceptSelection()
+ }
+ }
+ width: window.width
+ height: nameText.implicitHeight * 1.5
+ color: "transparent"
+ Rectangle {
+ id: itemHighlight
+ visible: root.selectedIndices.indexOf(index) >= 0
+ anchors.fill: parent
+ color: palette.highlight
+ }
+ Image {
+ id: icon
+ source: "images/folder.png"
+ height: wrapper.height - y * 2; width: height
+ x: (root.textX - width) / 2
+ y: 2
+ visible: view.model.isFolder(index)
+ }
+ Text {
+ id: nameText
+ anchors.fill: parent; verticalAlignment: Text.AlignVCenter
+ text: fileName
+ anchors.leftMargin: root.textX
+ color: itemHighlight.visible ? palette.highlightedText : palette.windowText
+ elide: Text.ElideRight
+ }
+ MouseArea {
+ id: mouseRegion
+ anchors.fill: parent
+ onDoubleClicked: {
+ selectedIndices = [index]
+ root.lastClickedIdx = index
+ launch()
+ }
+ onClicked: {
+ view.currentIndex = index
+ if (mouse.modifiers & Qt.ControlModifier && root.selectMultiple) {
+ // modifying the contents of selectedIndices doesn't notify,
+ // so we have to re-assign the variable
+ var selCopy = selectedIndices
+ var existingIdx = selCopy.indexOf(index)
+ if (existingIdx >= 0)
+ selCopy.splice(existingIdx, 1)
+ else
+ selCopy.push(index)
+ selectedIndices = selCopy
+ } else if (mouse.modifiers & Qt.ShiftModifier && root.selectMultiple) {
+ if (root.lastClickedIdx >= 0) {
+ var sel = []
+ if (index > lastClickedIdx) {
+ for (var i = root.lastClickedIdx; i <= index; i++)
+ sel.push(i)
+ } else {
+ for (var i = root.lastClickedIdx; i >= index; i--)
+ sel.push(i)
+ }
+ selectedIndices = sel
+ }
+ } else {
+ selectedIndices = [index]
+ root.lastClickedIdx = index
+ }
+ }
+ }
+ }
+ }
+
+ ListView {
+ id: view
+ anchors.top: titleBar.bottom
+ anchors.bottom: bottomBar.top
+ clip: true
+ x: 0
+ width: parent.width
+ model: FolderListModel { }
+ delegate: folderDelegate
+ highlight: Rectangle {
+ color: "transparent"
+ border.color: palette.midlight
+ }
+ highlightMoveDuration: 0
+ highlightMoveVelocity: -1
+ focus: !currentPathField.visible
+ Keys.onPressed: {
+ event.accepted = true
+ switch (event.key) {
+ case Qt.Key_Up:
+ root.up(event.modifiers & Qt.ShiftModifier && root.selectMultiple)
+ break
+ case Qt.Key_Down:
+ root.down(event.modifiers & Qt.ShiftModifier && root.selectMultiple)
+ break
+ case Qt.Key_Left:
+ root.dirUp()
+ break
+ case Qt.Key_Return:
+ case Qt.Key_Select:
+ case Qt.Key_Right:
+ if (view.currentItem)
+ view.currentItem.launch()
+ else
+ root.acceptSelection()
+ break
+ default:
+ // do nothing
+ event.accepted = false
+ break
+ }
+ }
+ }
+
+ MouseArea {
+ anchors.fill: view
+ enabled: currentPathField.visible
+ onClicked: currentPathField.visible = false
+ }
+
+
+ Item {
+ id: titleBar
+ width: parent.width
+ height: currentPathField.height * 1.5
+ BorderImage {
+ source: "images/titlebar.sci"
+ anchors.fill: parent
+ anchors.topMargin: -7
+ anchors.bottomMargin: -7
+ }
+ Rectangle {
+ id: upButton
+ width: root.textX
+ height: titleBar.height
+ color: "transparent"
+
+ Image {
+ id: upButtonImage
+ anchors.centerIn: parent; source: "images/up.png"
+ }
+ MouseArea { id: upRegion; anchors.centerIn: parent
+ width: 56
+ height: parent.height
+ onClicked: if (view.model.parentFolder != "") dirUp()
+ }
+ states: [
+ State {
+ name: "pressed"
+ when: upRegion.pressed
+ PropertyChanges { target: upButton; color: palette.highlight }
+ }
+ ]
+ }
+ Text {
+ id: currentPathText
+ anchors.left: parent.left; anchors.right: parent.right; anchors.verticalCenter: parent.verticalCenter
+ anchors.leftMargin: textX; anchors.rightMargin: 4
+ text: root.urlToPath(view.model.folder)
+ color: "white"
+ elide: Text.ElideLeft; horizontalAlignment: Text.AlignRight; verticalAlignment: Text.AlignVCenter
+ MouseArea {
+ anchors.fill: parent
+ onClicked: currentPathField.visible = true
+ }
+ }
+ TextField {
+ id: currentPathField
+ anchors.left: parent.left; anchors.right: parent.right; anchors.verticalCenter: parent.verticalCenter
+ anchors.leftMargin: textX; anchors.rightMargin: 4
+ visible: false
+ focus: visible
+ text: root.urlToPath(view.model.folder)
+ onAccepted: {
+ root.clearSelection()
+ if (root.addSelection(text))
+ root.accept()
+ else
+ view.model.folder = root.pathFolder(text)
+ }
+ onDownPressed: currentPathField.visible = false
+ }
+ }
+ Rectangle {
+ id: bottomBar
+ width: parent.width
+ height: buttonRow.height + buttonRow.spacing * 2
+ anchors.bottom: parent.bottom
+ gradient: Gradient {
+ GradientStop { position: 0.0; color: palette.dark }
+ GradientStop { position: 0.3; color: palette.mid }
+ GradientStop { position: 0.85; color: palette.mid }
+ GradientStop { position: 1.0; color: palette.light }
+ }
+
+ Row {
+ id: buttonRow
+ anchors.right: parent.right
+ anchors.rightMargin: spacing
+ anchors.verticalCenter: parent.verticalCenter
+ spacing: 4
+ TextField {
+ id: filterField
+ text: root.selectedNameFilter
+ visible: !selectFolder
+ width: bottomBar.width - cancelButton.width - okButton.width - parent.spacing * 5
+ anchors.verticalCenter: parent.verticalCenter
+ onAccepted: {
+ root.selectNameFilter(text)
+ view.model.nameFilters = text
+ }
+ }
+ Button {
+ id: cancelButton
+ text: "Cancel"
+ onClicked: root.reject()
+ }
+ Button {
+ id: okButton
+ text: "OK"
+ onClicked: {
+ if (view.model.isFolder(view.currentIndex) && !selectFolder)
+ dirDown(view.model.get(view.currentIndex, "filePath"))
+ else
+ root.acceptSelection()
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/imports/dialogs/WidgetFileDialog.qml b/src/imports/dialogs/WidgetFileDialog.qml
new file mode 100644
index 0000000000..837c7f8a57
--- /dev/null
+++ b/src/imports/dialogs/WidgetFileDialog.qml
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtDeclarative module 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 2.1
+import QtQuick.PrivateWidgets 1.0
+
+QtFileDialog { }
diff --git a/src/imports/dialogs/dialogs.pro b/src/imports/dialogs/dialogs.pro
new file mode 100644
index 0000000000..1a8ec05b85
--- /dev/null
+++ b/src/imports/dialogs/dialogs.pro
@@ -0,0 +1,30 @@
+CXX_MODULE = qml
+TARGET = dialogplugin
+TARGETPATH = QtQuick/Dialogs
+IMPORT_VERSION = 1.0
+
+SOURCES += \
+ plugin.cpp \
+ qquickabstractfiledialog.cpp \
+ qquickplatformfiledialog.cpp \
+ qquickfiledialog.cpp
+
+HEADERS += \
+ qquickabstractfiledialog_p.h \
+ qquickplatformfiledialog_p.h \
+ qquickfiledialog_p.h
+
+QML_FILES += \
+ DefaultFileDialog.qml \
+ WidgetFileDialog.qml \
+ qml/Button.qml \
+ qml/TextField.qml \
+ qml/qmldir \
+ images/folder.png \
+ images/titlebar.png \
+ images/titlebar.sci \
+ images/up.png
+
+QT += quick-private gui-private core-private
+
+load(qml_plugin)
diff --git a/src/imports/dialogs/images/folder.png b/src/imports/dialogs/images/folder.png
new file mode 100644
index 0000000000..e53e2ad464
--- /dev/null
+++ b/src/imports/dialogs/images/folder.png
Binary files differ
diff --git a/src/imports/dialogs/images/titlebar.png b/src/imports/dialogs/images/titlebar.png
new file mode 100644
index 0000000000..51c90082d0
--- /dev/null
+++ b/src/imports/dialogs/images/titlebar.png
Binary files differ
diff --git a/src/imports/dialogs/images/titlebar.sci b/src/imports/dialogs/images/titlebar.sci
new file mode 100644
index 0000000000..0418d94cd6
--- /dev/null
+++ b/src/imports/dialogs/images/titlebar.sci
@@ -0,0 +1,5 @@
+border.left: 10
+border.top: 12
+border.bottom: 12
+border.right: 10
+source: titlebar.png
diff --git a/src/imports/dialogs/images/up.png b/src/imports/dialogs/images/up.png
new file mode 100644
index 0000000000..b05f8025d0
--- /dev/null
+++ b/src/imports/dialogs/images/up.png
Binary files differ
diff --git a/src/imports/dialogs/plugin.cpp b/src/imports/dialogs/plugin.cpp
new file mode 100644
index 0000000000..46bd0dcb9d
--- /dev/null
+++ b/src/imports/dialogs/plugin.cpp
@@ -0,0 +1,140 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins 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$
+**
+****************************************************************************/
+
+#include <QtQml/qqml.h>
+#include <QtQml/qqmlextensionplugin.h>
+#include "qquickfiledialog_p.h"
+#include "qquickabstractfiledialog_p.h"
+#include "qquickplatformfiledialog_p.h"
+#include <private/qguiapplication_p.h>
+
+//#define PURE_QML_ONLY
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \qmlmodule QtQuick.Dialogs 1
+ \title Qt Quick Dialog QML Types
+ \ingroup qmlmodules
+ \brief Provides QML types for standard file, color picker and message dialogs
+
+ This QML module contains types for creating and interacting with system dialogs.
+
+ To use the types in this module, import the module with the following line:
+
+ \code
+ import QtQuick.Dialogs 1.0
+ \endcode
+*/
+
+class QtQuick2DialogsPlugin : public QQmlExtensionPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface/1.0")
+
+public:
+ QtQuick2DialogsPlugin() : QQmlExtensionPlugin() { }
+
+ virtual void initializeEngine(QQmlEngine *, const char *uri) {
+ bool needQml = false;
+ QDir qmlDir(baseUrl().toLocalFile());
+ // If there is no support for native dialogs on the platform, we need to
+ // either re-use QFileDialog, or register a QML implementation instead.
+#ifdef PURE_QML_ONLY
+ needQml = true;
+#else
+ if (!QGuiApplicationPrivate::platformTheme()->usePlatformNativeDialog(QPlatformTheme::FileDialog)) {
+ needQml = true;
+ // If there is not a QApplication, there's no point in trying to load
+ // widget-based dialogs, because a runtime error will occur.
+ if (QCoreApplication::instance()->metaObject()->className() == QLatin1String("QApplication")) {
+ // Test whether PrivateWidgets can load. It's not currently possible
+ // to use the given engine for that, so we need to create a temporary one.
+ // That doesn't work in registerTypes either, which is why it's done here.
+ QString dialogQmlPath(qmlDir.filePath("WidgetFileDialog.qml"));
+ QQmlEngine tempEngine;
+ QQmlComponent widgetDialogComponent(&tempEngine);
+ QFile widgetDialogQmlFile(dialogQmlPath);
+ widgetDialogQmlFile.open(QIODevice::ReadOnly);
+ widgetDialogComponent.setData(widgetDialogQmlFile.readAll(), QUrl());
+
+ switch (widgetDialogComponent.status()) {
+ case QQmlComponent::Ready:
+ needQml = (qmlRegisterType(QUrl::fromLocalFile(dialogQmlPath), uri, 1, 0, "FileDialog") < 0);
+ // returns -1 unless we omit the module from qmldir, because otherwise
+ // QtQuick.Dialogs is already a protected namespace
+ // after the qmldir having been parsed. (QQmlImportDatabase::importPlugin)
+ // But omitting the module from qmldir results in this warning:
+ // "Module 'QtQuick.Dialogs' does not contain a module identifier directive -
+ // it cannot be protected from external registrations."
+ // TODO register all types in registerTypes, to avoid the warning
+ // But, in that case we cannot check for existence by trying to instantiate the component.
+ // So it will have to just look for a file (qmldir?) and assume
+ // that whatever modules are installed are also in working order.
+ break;
+ default:
+ break;
+ }
+ }
+ }
+#endif
+ if (needQml) {
+ QString dialogQmlPath = qmlDir.filePath("DefaultFileDialog.qml");
+ qmlRegisterType<QQuickFileDialog>(uri, 1, 0, "AbstractFileDialog"); // implementation wrapper
+ // qDebug() << "registering FileDialog as " << dialogQmlPath << "success?" <<
+ qmlRegisterType(QUrl::fromLocalFile(dialogQmlPath), uri, 1, 0, "FileDialog");
+ }
+ }
+
+ virtual void registerTypes(const char *uri) {
+ Q_ASSERT(QLatin1String(uri) == QLatin1String("QtQuick.Dialogs"));
+
+#ifndef PURE_QML_ONLY
+ // Prefer the QPA file dialog helper if the platform supports it
+ if (QGuiApplicationPrivate::platformTheme()->usePlatformNativeDialog(QPlatformTheme::FileDialog))
+ qmlRegisterType<QQuickPlatformFileDialog>(uri, 1, 0, "FileDialog");
+#endif
+ }
+};
+
+QT_END_NAMESPACE
+
+#include "plugin.moc"
diff --git a/src/imports/dialogs/plugins.qmltypes b/src/imports/dialogs/plugins.qmltypes
new file mode 100644
index 0000000000..faf68de909
--- /dev/null
+++ b/src/imports/dialogs/plugins.qmltypes
@@ -0,0 +1,72 @@
+import QtQuick.tooling 1.1
+
+// This file describes the plugin-supplied types contained in the library.
+// It is used for QML tooling purposes only.
+//
+// This file was auto-generated with the command 'qmlplugindump QtQuick.Dialogs 1.0'.
+
+Module {
+ Component {
+ name: "QQuickAbstractFileDialog"
+ prototype: "QObject"
+ Property { name: "visible"; type: "bool" }
+ Property { name: "modality"; type: "Qt::WindowModality" }
+ Property { name: "title"; type: "string" }
+ Property { name: "selectExisting"; type: "bool" }
+ Property { name: "selectMultiple"; type: "bool" }
+ Property { name: "selectFolder"; type: "bool" }
+ Property { name: "folder"; type: "string" }
+ Property { name: "nameFilters"; type: "QStringList" }
+ Property { name: "selectedNameFilter"; type: "string" }
+ Property { name: "filePath"; type: "string"; isReadonly: true }
+ Property { name: "filePaths"; type: "QStringList"; isReadonly: true }
+ Signal { name: "visibilityChanged" }
+ Signal { name: "filterSelected" }
+ Signal { name: "fileModeChanged" }
+ Signal { name: "accepted" }
+ Signal { name: "rejected" }
+ Method { name: "open" }
+ Method { name: "close" }
+ Method {
+ name: "setVisible"
+ Parameter { name: "v"; type: "bool" }
+ }
+ Method {
+ name: "setModality"
+ Parameter { name: "m"; type: "Qt::WindowModality" }
+ }
+ Method {
+ name: "setTitle"
+ Parameter { name: "t"; type: "string" }
+ }
+ Method {
+ name: "setSelectExisting"
+ Parameter { name: "s"; type: "bool" }
+ }
+ Method {
+ name: "setSelectMultiple"
+ Parameter { name: "s"; type: "bool" }
+ }
+ Method {
+ name: "setSelectFolder"
+ Parameter { name: "s"; type: "bool" }
+ }
+ Method {
+ name: "setFolder"
+ Parameter { name: "f"; type: "string" }
+ }
+ Method {
+ name: "setNameFilters"
+ Parameter { name: "f"; type: "QStringList" }
+ }
+ Method {
+ name: "selectNameFilter"
+ Parameter { name: "f"; type: "string" }
+ }
+ }
+ Component {
+ name: "QQuickQFileDialog"
+ prototype: "QQuickAbstractFileDialog"
+ exports: ["QtQuick.PrivateWidgets/QtFileDialog 1.0"]
+ }
+}
diff --git a/src/imports/dialogs/qml/Button.qml b/src/imports/dialogs/qml/Button.qml
new file mode 100644
index 0000000000..42ee9f79e8
--- /dev/null
+++ b/src/imports/dialogs/qml/Button.qml
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQml module 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 2.1
+
+Item {
+ height: label.implicitHeight * 2
+ width: Math.max(label.implicitWidth * 1.2, height * 2.5);
+ anchors.verticalCenter: parent.verticalCenter
+ property alias text: label.text
+ property string tooltip
+ signal clicked
+ SystemPalette { id: palette }
+ Rectangle {
+ antialiasing: true
+ border.color: mouseArea.pressed ? palette.highlight : palette.light
+ color: "transparent"
+ anchors.fill: parent
+ anchors.rightMargin: 1
+ anchors.bottomMargin: 1
+ radius: 3
+ }
+ Rectangle {
+ border.color: palette.dark
+ anchors.fill: parent
+ anchors.leftMargin: 1
+ anchors.topMargin: 1
+ radius: 3
+ }
+ Rectangle {
+ gradient: Gradient {
+ GradientStop { position: 0.0; color: mouseArea.pressed ? palette.dark : palette.light }
+ GradientStop { position: 0.2; color: palette.button }
+ GradientStop { position: 0.8; color: palette.button }
+ GradientStop { position: 1.0; color: mouseArea.pressed ? palette.light : palette.dark }
+ }
+ anchors.fill: parent
+ anchors.margins: 1
+ radius: 3
+ }
+ Text {
+ id: label
+ anchors.centerIn: parent
+ color: palette.buttonText
+ }
+
+ MouseArea {
+ id: mouseArea
+ anchors.fill: parent
+ onClicked: parent.clicked()
+ }
+}
diff --git a/src/imports/dialogs/qml/TextField.qml b/src/imports/dialogs/qml/TextField.qml
new file mode 100644
index 0000000000..204eef71b9
--- /dev/null
+++ b/src/imports/dialogs/qml/TextField.qml
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQml module 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 2.1
+
+Item {
+ id: root
+
+ property alias textInput: textInput
+ property alias text: textInput.text
+ signal accepted
+ signal downPressed
+
+ SystemPalette { id: palette }
+ height: textInput.implicitHeight + 4
+ Rectangle {
+ id: rect
+ anchors.fill: parent
+ anchors.leftMargin: -radius
+ border.color: palette.light
+ radius: height / 4
+ antialiasing: true
+ gradient: Gradient {
+ GradientStop { position: 0.0; color: palette.dark }
+ GradientStop { position: 0.2; color: palette.button }
+ GradientStop { position: 0.8; color: palette.button }
+ GradientStop { position: 1.0; color: palette.light }
+ }
+ }
+
+ TextInput {
+ id: textInput
+ color: palette.text
+ anchors.fill: parent
+ verticalAlignment: Text.AlignVCenter
+ onAccepted: root.accepted()
+ Keys.onDownPressed: root.downPressed()
+ }
+}
diff --git a/src/imports/dialogs/qml/qmldir b/src/imports/dialogs/qml/qmldir
new file mode 100644
index 0000000000..85575c738a
--- /dev/null
+++ b/src/imports/dialogs/qml/qmldir
@@ -0,0 +1,2 @@
+Button 1.0 Button.qml
+TextField 1.0 TextField.qml
diff --git a/src/imports/dialogs/qmldir b/src/imports/dialogs/qmldir
new file mode 100644
index 0000000000..50867d7361
--- /dev/null
+++ b/src/imports/dialogs/qmldir
@@ -0,0 +1,2 @@
+plugin dialogplugin
+typeinfo plugins.qmltypes
diff --git a/src/imports/dialogs/qquickabstractfiledialog.cpp b/src/imports/dialogs/qquickabstractfiledialog.cpp
new file mode 100644
index 0000000000..905cb5d030
--- /dev/null
+++ b/src/imports/dialogs/qquickabstractfiledialog.cpp
@@ -0,0 +1,233 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQml module 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$
+**
+****************************************************************************/
+
+#include "qquickabstractfiledialog_p.h"
+#include "qquickitem.h"
+
+#include <private/qguiapplication_p.h>
+#include <QWindow>
+#include <QQuickWindow>
+
+QT_BEGIN_NAMESPACE
+
+QQuickAbstractFileDialog::QQuickAbstractFileDialog(QObject *parent)
+ : QObject(parent)
+ , m_dlgHelper(0)
+ , m_parentWindow(0)
+ , m_options(QSharedPointer<QFileDialogOptions>(new QFileDialogOptions()))
+ , m_visible(false)
+ , m_modality(Qt::WindowModal)
+ , m_selectExisting(true)
+ , m_selectMultiple(false)
+ , m_selectFolder(false)
+{
+}
+
+QQuickAbstractFileDialog::~QQuickAbstractFileDialog()
+{
+}
+
+void QQuickAbstractFileDialog::setVisible(bool v)
+{
+ if (m_visible == v) return;
+ m_visible = v;
+ if (helper()) {
+ if (v) {
+ helper()->setOptions(m_options);
+ helper()->setFilter();
+ m_visible = helper()->show(Qt::Dialog, m_modality, parentWindow());
+ emit filterSelected();
+ } else {
+ helper()->hide();
+ }
+ }
+
+ emit visibilityChanged();
+}
+
+void QQuickAbstractFileDialog::setModality(Qt::WindowModality m)
+{
+ if (m_modality == m) return;
+ m_modality = m;
+ emit modalityChanged();
+}
+
+void QQuickAbstractFileDialog::setTitle(QString t)
+{
+ if (m_options->windowTitle() == t) return;
+ m_options->setWindowTitle(t);
+ emit titleChanged();
+}
+
+void QQuickAbstractFileDialog::setSelectExisting(bool selectExisting)
+{
+ if (selectExisting == m_selectExisting) return;
+ m_selectExisting = selectExisting;
+ updateModes();
+}
+
+void QQuickAbstractFileDialog::setSelectMultiple(bool selectMultiple)
+{
+ if (selectMultiple == m_selectMultiple) return;
+ m_selectMultiple = selectMultiple;
+ updateModes();
+}
+
+void QQuickAbstractFileDialog::setSelectFolder(bool selectFolder)
+{
+ if (selectFolder == m_selectFolder) return;
+ m_selectFolder = selectFolder;
+ updateModes();
+}
+
+QString QQuickAbstractFileDialog::folder()
+{
+ if (m_dlgHelper && !m_dlgHelper->directory().isEmpty())
+ return m_dlgHelper->directory();
+ return m_options->initialDirectory();
+}
+
+void QQuickAbstractFileDialog::setFolder(QString f)
+{
+ if (m_dlgHelper)
+ m_dlgHelper->setDirectory(f);
+ m_options->setInitialDirectory(f);
+ emit folderChanged();
+}
+
+void QQuickAbstractFileDialog::setNameFilters(const QStringList &f)
+{
+ m_options->setNameFilters(f);
+ if (f.isEmpty())
+ selectNameFilter(QString());
+ else if (!f.contains(selectedNameFilter()))
+ selectNameFilter(f.first());
+ emit nameFiltersChanged();
+}
+
+QString QQuickAbstractFileDialog::selectedNameFilter()
+{
+ QString ret;
+ if (m_dlgHelper)
+ ret = m_dlgHelper->selectedNameFilter();
+ if (ret.isEmpty())
+ return m_options->initiallySelectedNameFilter();
+ return ret;
+}
+
+void QQuickAbstractFileDialog::selectNameFilter(QString f)
+{
+ // This should work whether the dialog is currently being shown already, or ahead of time.
+ m_options->setInitiallySelectedNameFilter(f);
+ if (m_dlgHelper)
+ m_dlgHelper->selectNameFilter(f);
+ emit filterSelected();
+}
+
+QUrl QQuickAbstractFileDialog::fileUrl()
+{
+ QList<QUrl> urls = fileUrls();
+ return (urls.count() == 1) ? urls[0] : QUrl();
+}
+
+QList<QUrl> QQuickAbstractFileDialog::fileUrls()
+{
+ QList<QUrl> ret;
+ if (m_dlgHelper)
+ foreach (QString path, m_dlgHelper->selectedFiles())
+ ret << QUrl::fromLocalFile(path);
+ return ret;
+}
+
+void QQuickAbstractFileDialog::accept()
+{
+ setVisible(false);
+ emit accepted();
+}
+
+void QQuickAbstractFileDialog::reject()
+{
+ setVisible(false);
+ emit rejected();
+}
+
+void QQuickAbstractFileDialog::visibleChanged(bool v)
+{
+ m_visible = v;
+ emit visibilityChanged();
+}
+
+void QQuickAbstractFileDialog::updateModes()
+{
+ // The 4 possible modes are AnyFile, ExistingFile, Directory, ExistingFiles
+ // Assume AnyFile until we find a reason to the contrary
+ QFileDialogOptions::FileMode mode = QFileDialogOptions::AnyFile;
+
+ if (m_selectFolder) {
+ mode = QFileDialogOptions::Directory;
+ m_options->setOption(QFileDialogOptions::ShowDirsOnly);
+ m_selectMultiple = false;
+ m_selectExisting = true;
+ setNameFilters(QStringList());
+ } else if (m_selectExisting) {
+ mode = m_selectMultiple ?
+ QFileDialogOptions::ExistingFiles : QFileDialogOptions::ExistingFile;
+ m_options->setOption(QFileDialogOptions::ShowDirsOnly, false);
+ } else if (m_selectMultiple) {
+ m_selectExisting = true;
+ }
+ if (!m_selectExisting)
+ m_selectMultiple = false;
+ m_options->setFileMode(mode);
+ m_options->setAcceptMode(m_selectExisting ?
+ QFileDialogOptions::AcceptOpen : QFileDialogOptions::AcceptSave);
+ emit fileModeChanged();
+}
+
+QQuickWindow *QQuickAbstractFileDialog::parentWindow()
+{
+ QQuickItem *parentItem = qobject_cast<QQuickItem *>(parent());
+ if (parentItem)
+ m_parentWindow = parentItem->window();
+ return m_parentWindow;
+}
+
+QT_END_NAMESPACE
diff --git a/src/imports/dialogs/qquickabstractfiledialog_p.h b/src/imports/dialogs/qquickabstractfiledialog_p.h
new file mode 100644
index 0000000000..e9565108d6
--- /dev/null
+++ b/src/imports/dialogs/qquickabstractfiledialog_p.h
@@ -0,0 +1,144 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQml module 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$
+**
+****************************************************************************/
+
+#ifndef QQUICKABSTRACTFILEDIALOG_P_H
+#define QQUICKABSTRACTFILEDIALOG_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtQml>
+#include <QQuickView>
+#include <QtGui/qpa/qplatformdialoghelper.h>
+#include <qpa/qplatformtheme.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickAbstractFileDialog : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibilityChanged)
+ Q_PROPERTY(Qt::WindowModality modality READ modality WRITE setModality NOTIFY modalityChanged)
+ Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged)
+ Q_PROPERTY(bool selectExisting READ selectExisting WRITE setSelectExisting NOTIFY fileModeChanged)
+ Q_PROPERTY(bool selectMultiple READ selectMultiple WRITE setSelectMultiple NOTIFY fileModeChanged)
+ Q_PROPERTY(bool selectFolder READ selectFolder WRITE setSelectFolder NOTIFY fileModeChanged)
+ Q_PROPERTY(QString folder READ folder WRITE setFolder NOTIFY folderChanged)
+ Q_PROPERTY(QStringList nameFilters READ nameFilters WRITE setNameFilters NOTIFY nameFiltersChanged)
+ Q_PROPERTY(QString selectedNameFilter READ selectedNameFilter WRITE selectNameFilter NOTIFY filterSelected)
+ Q_PROPERTY(QUrl fileUrl READ fileUrl NOTIFY accepted)
+ Q_PROPERTY(QList<QUrl> fileUrls READ fileUrls NOTIFY accepted)
+ // TODO: QTBUG-29817: provide x y width and height (after QPlatformDialogHelper provides it)
+
+public:
+ QQuickAbstractFileDialog(QObject *parent = 0);
+ virtual ~QQuickAbstractFileDialog();
+
+ bool isVisible() const { return m_visible; }
+ Qt::WindowModality modality() const { return m_modality; }
+ QString title() const { return m_options->windowTitle(); }
+ bool selectExisting() const { return m_selectExisting; }
+ bool selectMultiple() const { return m_selectMultiple; }
+ bool selectFolder() const { return m_selectFolder; }
+ QString folder();
+ QStringList nameFilters() const { return m_options->nameFilters(); }
+ QString selectedNameFilter();
+ QUrl fileUrl();
+ virtual QList<QUrl> fileUrls();
+
+public Q_SLOTS:
+ void open() { setVisible(true); }
+ void close() { setVisible(false); }
+ virtual void setVisible(bool v);
+ void setModality(Qt::WindowModality m);
+ void setTitle(QString t);
+ void setSelectExisting(bool s);
+ void setSelectMultiple(bool s);
+ void setSelectFolder(bool s);
+ void setFolder(QString f);
+ void setNameFilters(const QStringList &f);
+ void selectNameFilter(QString f);
+
+Q_SIGNALS:
+ void visibilityChanged();
+ void modalityChanged();
+ void titleChanged();
+ void folderChanged();
+ void nameFiltersChanged();
+ void filterSelected();
+ void fileModeChanged();
+ void accepted();
+ void rejected();
+
+protected Q_SLOTS:
+ void accept();
+ void reject();
+ void visibleChanged(bool v);
+
+protected:
+ virtual QPlatformFileDialogHelper *helper() = 0;
+ void updateModes();
+ QQuickWindow *parentWindow();
+
+protected:
+ QPlatformFileDialogHelper *m_dlgHelper;
+ QQuickWindow *m_parentWindow;
+ QSharedPointer<QFileDialogOptions> m_options;
+ bool m_visible;
+ Qt::WindowModality m_modality;
+ bool m_selectExisting;
+ bool m_selectMultiple;
+ bool m_selectFolder;
+
+ Q_DISABLE_COPY(QQuickAbstractFileDialog)
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKABSTRACTFILEDIALOG_P_H
diff --git a/src/imports/dialogs/qquickfiledialog.cpp b/src/imports/dialogs/qquickfiledialog.cpp
new file mode 100644
index 0000000000..89b8b4cc5b
--- /dev/null
+++ b/src/imports/dialogs/qquickfiledialog.cpp
@@ -0,0 +1,230 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQml module 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$
+**
+****************************************************************************/
+
+#include "qquickfiledialog_p.h"
+#include <QQuickItem>
+#include <private/qguiapplication_p.h>
+#include <qpa/qplatformintegration.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \qmltype AbstractFileDialog
+ \instantiates QQuickFileDialog
+ \inqmlmodule QtQuick.Dialogs 1
+ \ingroup qtquick-visual
+ \brief API wrapper for QML file dialog implementations
+ \since 5.1
+ \internal
+
+ AbstractFileDialog provides only the API for implementing a file dialog.
+ The implementation (e.g. a Window or Item) can be provided as \l implementation,
+ which is the default property (the only allowed child element).
+*/
+
+/*!
+ \qmlsignal QtQuick::Dialogs::AbstractFileDialog::accepted
+
+ The \a accepted signal is emitted by \l accept().
+*/
+
+/*!
+ \qmlsignal QtQuick::Dialogs::AbstractFileDialog::rejected
+
+ The \a accepted signal is emitted by \l reject().
+*/
+
+/*!
+ \class QQuickFileDialog
+ \inmodule QtQuick.Dialogs
+ \internal
+
+ The QQuickFileDialog class is a concrete subclass of \l
+ QQuickAbstractFileDialog, but it is abstract from the QML perspective
+ because it needs to enclose a graphical implementation. It exists in order
+ to provide accessors and helper functions which the QML implementation will
+ need.
+
+ \since 5.1
+*/
+
+/*!
+ Constructs a file dialog wrapper with parent window \a parent.
+*/
+QQuickFileDialog::QQuickFileDialog(QObject *parent)
+ : QQuickAbstractFileDialog(parent)
+ , m_implementation(0)
+ , m_dialogWindow(0)
+{
+}
+
+
+/*!
+ Destroys the file dialog wrapper.
+*/
+QQuickFileDialog::~QQuickFileDialog()
+{
+}
+
+QList<QUrl> QQuickFileDialog::fileUrls()
+{
+ QList<QUrl> ret;
+ foreach (QString path, m_selections)
+ ret << QUrl::fromLocalFile(path);
+ return ret;
+}
+
+/*!
+ \qmlproperty bool AbstractFileDialog::visible
+
+ This property holds whether the dialog is visible. By default this is false.
+*/
+void QQuickFileDialog::setVisible(bool v)
+{
+ if (m_visible == v) return;
+ m_visible = v;
+ // For a pure QML implementation, there is no helper.
+ // But m_implementation is probably either an Item or a Window at this point.
+ if (!m_dialogWindow) {
+ m_dialogWindow = qobject_cast<QWindow *>(m_implementation);
+ if (!m_dialogWindow) {
+ QQuickItem *dlgItem = qobject_cast<QQuickItem *>(m_implementation);
+ if (dlgItem) {
+ m_dialogWindow = dlgItem->window();
+ // An Item-based dialog implementation doesn't come with a window, so
+ // we have to instantiate one iff the platform allows it.
+ if (!m_dialogWindow && QGuiApplicationPrivate::platformIntegration()->
+ hasCapability(QPlatformIntegration::MultipleWindows)) {
+ QQuickWindow *win = new QQuickWindow;
+ m_dialogWindow = win;
+ dlgItem->setParentItem(win->contentItem());
+ m_dialogWindow->setMinimumSize(QSize(dlgItem->width(), dlgItem->height()));
+ }
+
+ QQuickItem *parentItem = qobject_cast<QQuickItem *>(parent());
+ // qDebug() << "item implementation" << dlgItem << "has window" << m_dialogWindow << "and parent" << parentItem;
+
+ // If the platform does not support multiple windows, but the dialog is
+ // implemented as an Item, then just reparent it and make it visible.
+ // TODO QTBUG-29818: put it into a fake Item-based window, when we have a reusable self-decorated one.
+ if (parentItem && !m_dialogWindow)
+ dlgItem->setParentItem(parentItem);
+ }
+ }
+ if (m_dialogWindow)
+ connect(m_dialogWindow, SIGNAL(visibleChanged(bool)), this, SLOT(visibleChanged(bool)));
+ }
+ if (m_dialogWindow) {
+ if (v) {
+ m_dialogWindow->setTransientParent(parentWindow());
+ m_dialogWindow->setTitle(title());
+ m_dialogWindow->setModality(m_modality);
+ }
+ m_dialogWindow->setVisible(v);
+ }
+ emit visibilityChanged();
+}
+
+/*!
+ \qmlproperty bool AbstractFileDialog::filePaths
+
+ A list of files to be populated as the user chooses.
+*/
+
+/*!
+ \brief Clears \l filePaths
+*/
+void QQuickFileDialog::clearSelection()
+{
+ m_selections.clear();
+}
+
+/*!
+ \brief Adds one file to \l filePaths
+
+ \l path should be given as an absolute file system path. If it is given as a
+ file:// URL, it will be converted to a path. Returns true on success,
+ false if the given path is not valid given the current setting properties.
+*/
+bool QQuickFileDialog::addSelection(QString path)
+{
+ if (path.startsWith("file:"))
+ path = QUrl(path).toLocalFile();
+ QFileInfo info(path);
+ if (info.exists() && ((info.isDir() && m_selectFolder) || !info.isDir())) {
+ if (m_selectFolder)
+ m_selections.append(pathFolder(path).toLocalFile());
+ else
+ m_selections.append(path);
+ return true;
+ }
+ return false;
+}
+
+/*!
+ \brief get a file's directory as a URL
+
+ If \a path points to a directory, just convert it to a URL.
+ If \a path points to a file, convert the file's directory to a URL.
+*/
+QUrl QQuickFileDialog::pathFolder(const QString &path)
+{
+ QFileInfo info(path);
+ if (info.exists() && info.isDir())
+ return QUrl::fromLocalFile(path);
+ return QUrl::fromLocalFile(QFileInfo(path).absolutePath());
+}
+
+/*!
+ \qmlproperty QObject AbstractFileDialog::implementation
+
+ The QML object which implements the actual file dialog. Should be either a
+ \l Window or an \l Item.
+*/
+void QQuickFileDialog::setImplementation(QObject *obj)
+{
+ m_implementation = obj;
+ if (m_dialogWindow)
+ disconnect(this, SLOT(visibleChanged(bool)));
+ m_dialogWindow = 0;
+}
+
+QT_END_NAMESPACE
diff --git a/src/imports/dialogs/qquickfiledialog_p.h b/src/imports/dialogs/qquickfiledialog_p.h
new file mode 100644
index 0000000000..0a660b316b
--- /dev/null
+++ b/src/imports/dialogs/qquickfiledialog_p.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQml module 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$
+**
+****************************************************************************/
+
+#ifndef QQUICKFILEDIALOG_P_H
+#define QQUICKFILEDIALOG_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qquickabstractfiledialog_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QQuickFileDialog : public QQuickAbstractFileDialog
+{
+ Q_OBJECT
+ Q_PROPERTY(QObject* implementation READ implementation WRITE setImplementation DESIGNABLE false)
+ Q_CLASSINFO("DefaultProperty", "implementation") // AbstractFileDialog in QML can have only one child
+
+public:
+ explicit QQuickFileDialog(QObject *parent = 0);
+ ~QQuickFileDialog();
+ QObject* implementation() { return m_implementation; }
+ virtual QList<QUrl> fileUrls();
+
+signals:
+
+public Q_SLOTS:
+ void setImplementation(QObject* obj);
+ virtual void setVisible(bool v);
+
+ void clearSelection();
+ bool addSelection(QString path);
+
+protected:
+ virtual QPlatformFileDialogHelper *helper() { return 0; }
+ Q_INVOKABLE QString urlToPath(const QUrl &url) { return url.toLocalFile(); }
+ Q_INVOKABLE QUrl pathToUrl(const QString &path) { return QUrl::fromLocalFile(path); }
+ Q_INVOKABLE QUrl pathFolder(const QString &path);
+
+private:
+ QObject *m_implementation;
+ QWindow *m_dialogWindow;
+ QStringList m_selections;
+
+ Q_DISABLE_COPY(QQuickFileDialog)
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickFileDialog *)
+
+#endif // QQUICKFILEDIALOG_P_H
diff --git a/src/imports/dialogs/qquickplatformfiledialog.cpp b/src/imports/dialogs/qquickplatformfiledialog.cpp
new file mode 100644
index 0000000000..f2bd279d7b
--- /dev/null
+++ b/src/imports/dialogs/qquickplatformfiledialog.cpp
@@ -0,0 +1,314 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQml module 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$
+**
+****************************************************************************/
+
+#include "qquickplatformfiledialog_p.h"
+#include "qquickitem.h"
+
+#include <private/qguiapplication_p.h>
+#include <QWindow>
+#include <QQuickView>
+#include <QQuickWindow>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \qmltype FileDialog
+ \instantiates QQuickPlatformFileDialog
+ \inqmlmodule QtQuick.Dialogs 1
+ \ingroup qtquick-visual
+ \brief Dialog component for choosing files from a local filesystem.
+ \since 5.1
+
+ FileDialog provides a basic file chooser: it allows the user to select
+ existing files and/or directories, or create new filenames. The dialog is
+ initially invisible. You need to set the properties as desired first, then
+ set \l visible to true or call \l open().
+
+ Here is a minimal example to open a file dialog and exit after the user
+ chooses a file:
+
+ \qml
+ import QtQuick 2.0
+ import QtQuick.Dialogs 1.0
+
+ FileDialog {
+ id: fileDialog
+ title: "Please choose a file"
+ onAccepted: {
+ console.log("You chose: " + fileDialog.filePaths)
+ Qt.quit()
+ }
+ onRejected: {
+ console.log("Cancelled")
+ Qt.quit()
+ }
+ Component.onCompleted: visible = true
+ }
+ \endqml
+
+ A FileDialog window is automatically transient for its parent window. So
+ whether you declare the dialog inside an \l Item or inside a \l Window, the
+ dialog will appear centered over the window containing the item, or over
+ the Window that you declared.
+
+ The implementation of FileDialog will be a platform file dialog if
+ possible. If that isn't possible, then it will try to instantiate a
+ \l QFileDialog. If that also isn't possible, then it will fall back to a QML
+ implementation, DefaultFileDialog.qml. In that case you can customize the
+ appearance by editing this file. DefaultFileDialog.qml contains a Rectangle
+ to hold the dialog's contents, because certain embedded systems do not
+ support multiple top-level windows. When the dialog becomes visible, it
+ will automatically be wrapped in a Window if possible, or simply reparented
+ on top of the main window if there can only be one window.
+*/
+
+/*!
+ \qmlsignal QtQuick::Dialogs::FileDialog::accepted
+
+ The \a accepted signal is emitted when the user has finished using the
+ dialog. You can then inspect the \a filePath or \a filePaths properties to
+ get the selection.
+
+ Example:
+
+ \qml
+ FileDialog {
+ onAccepted: { console.log("Selected file: " + filePath) }
+ }
+ \endqml
+*/
+
+/*!
+ \qmlsignal QtQuick::Dialogs::FileDialog::rejected
+
+ The \a rejected signal is emitted when the user has dismissed the dialog,
+ either by closing the dialog window or by pressing the Cancel button.
+*/
+
+/*!
+ \class QQuickPlatformFileDialog
+ \inmodule QtQuick.Dialogs
+ \internal
+
+ \brief The QQuickPlatformFileDialog class provides a file dialog
+
+ The dialog is implemented via the QPlatformFileDialogHelper when possible;
+ otherwise it falls back to a QFileDialog or a QML implementation.
+
+ \since 5.1
+*/
+
+/*!
+ Constructs a file dialog with parent window \a parent.
+*/
+QQuickPlatformFileDialog::QQuickPlatformFileDialog(QObject *parent) :
+ QQuickAbstractFileDialog(parent)
+{
+}
+
+/*!
+ Destroys the file dialog.
+*/
+QQuickPlatformFileDialog::~QQuickPlatformFileDialog()
+{
+ if (m_dlgHelper)
+ m_dlgHelper->hide();
+ delete m_dlgHelper;
+}
+
+QPlatformFileDialogHelper *QQuickPlatformFileDialog::helper()
+{
+ QQuickItem *parentItem = qobject_cast<QQuickItem *>(parent());
+ if (parentItem)
+ m_parentWindow = parentItem->window();
+
+ if ( !m_dlgHelper && QGuiApplicationPrivate::platformTheme()->
+ usePlatformNativeDialog(QPlatformTheme::FileDialog) ) {
+ m_dlgHelper = static_cast<QPlatformFileDialogHelper *>(QGuiApplicationPrivate::platformTheme()
+ ->createPlatformDialogHelper(QPlatformTheme::FileDialog));
+ if (!m_dlgHelper)
+ return m_dlgHelper;
+ connect(m_dlgHelper, SIGNAL(directoryEntered(QString)), this, SIGNAL(folderChanged()));
+ connect(m_dlgHelper, SIGNAL(filterSelected(QString)), this, SIGNAL(filterSelected()));
+ connect(m_dlgHelper, SIGNAL(accept()), this, SLOT(accept()));
+ connect(m_dlgHelper, SIGNAL(reject()), this, SLOT(reject()));
+ }
+
+ return m_dlgHelper;
+}
+
+/*!
+ \qmlproperty bool FileDialog::visible
+
+ This property holds whether the dialog is visible. By default this is
+ false.
+
+ \sa modality
+*/
+
+/*!
+ \qmlproperty Qt::WindowModality FileDialog::modality
+
+ Whether the dialog should be shown modal with respect to the window
+ containing the dialog's parent Item, modal with respect to the whole
+ application, or non-modal.
+
+ By default it is \l WindowModal.
+
+ Modality does not mean that there are any blocking calls to wait for the
+ dialog to be accepted or rejected; it's only that the user will be
+ prevented from interacting with the parent window and/or the application
+ windows at the same time. You probably need to write an onAccepted handler
+ to actually load or save the chosen file.
+*/
+
+/*!
+ \qmlmethod void FileDialog::open()
+
+ Shows the dialog to the user. It is equivalent to setting \l visible to
+ true.
+*/
+
+/*!
+ \qmlmethod void FileDialog::close()
+
+ Closes the dialog.
+*/
+
+/*!
+ \qmlproperty string FileDialog::title
+
+ The title of the dialog window.
+*/
+
+/*!
+ \qmlproperty bool FileDialog::selectExisting
+
+ Whether only existing files or directories can be selected.
+
+ By default, this property is true. This property must be set to the desired
+ value before opening the dialog. Setting this property to false implies
+ that the dialog is for naming a file to which to save something, or naming
+ a folder to be created; therefore \l selectMultiple must be false.
+*/
+
+/*!
+ \qmlproperty bool FileDialog::selectMultiple
+
+ Whether more than one filename can be selected.
+
+ By default, this property is false. This property must be set to the
+ desired value before opening the dialog. Setting this property to true
+ implies that \l selectExisting must be true.
+*/
+
+/*!
+ \qmlproperty bool FileDialog::selectFolder
+
+ Whether the selected item should be a folder.
+
+ By default, this property is false. This property must be set to the
+ desired value before opening the dialog. Setting this property to true
+ implies that \l selectMultiple must be false and \l selectExisting must be
+ true.
+*/
+
+/*!
+ \qmlproperty string FileDialog::folder
+
+ The path to the currently selected folder. Setting this property before
+ invoking open() will cause the file browser to be initially positioned on
+ the specified folder.
+
+ The value of this property is also updated after the dialog is closed.
+
+ By default, this property is false.
+*/
+
+/*!
+ \qmlproperty list<string> FileDialog::nameFilters
+
+ A list of strings to be used as file name filters. Each string can be a
+ space-separated list of filters; filters may include the ? and * wildcards.
+ The list of filters can also be enclosed in parentheses and a textual
+ description of the filter can be provided.
+
+ For example:
+
+ \qml
+ FileDialog {
+ nameFilters: [ "Image files (*.jpg *.png)", "All files (*)" ]
+ }
+ \endqml
+
+ \note Directories are not excluded by filters.
+ \sa selectedNameFilter
+*/
+
+/*!
+ \qmlproperty string FileDialog::selectedNameFilter
+
+ Which of the \l nameFilters is currently selected.
+
+ This property can be set before the dialog is visible, to set the default
+ name filter, and can also be set while the dialog is visible to set the
+ current name filter. It is also updated when the user selects a different
+ filter.
+*/
+
+/*!
+ \qmlproperty string FileDialog::filePath
+
+ The path of the file which was selected by the user.
+
+ \note This property is set only if exactly one file was selected. In all
+ other cases, it will return an empty string.
+
+ \sa filePaths
+*/
+
+/*!
+ \qmlproperty list<string> FileDialog::filePaths
+
+ The list of file paths which were selected by the user.
+*/
+
+QT_END_NAMESPACE
diff --git a/src/imports/dialogs/qquickplatformfiledialog_p.h b/src/imports/dialogs/qquickplatformfiledialog_p.h
new file mode 100644
index 0000000000..3559543319
--- /dev/null
+++ b/src/imports/dialogs/qquickplatformfiledialog_p.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQml module 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$
+**
+****************************************************************************/
+
+#ifndef QQUICKPLATFORMFILEDIALOG_P_H
+#define QQUICKPLATFORMFILEDIALOG_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qquickabstractfiledialog_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QQuickPlatformFileDialog : public QQuickAbstractFileDialog
+{
+ Q_OBJECT
+
+public:
+ QQuickPlatformFileDialog(QObject *parent = 0);
+ virtual ~QQuickPlatformFileDialog();
+
+protected:
+ QPlatformFileDialogHelper *helper();
+
+ Q_DISABLE_COPY(QQuickPlatformFileDialog)
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickPlatformFileDialog *)
+
+#endif // QQUICKPLATFORMFILEDIALOG_P_H
diff --git a/src/imports/imports.pro b/src/imports/imports.pro
index 72888b2c71..e411a4f097 100644
--- a/src/imports/imports.pro
+++ b/src/imports/imports.pro
@@ -9,7 +9,10 @@ qtHaveModule(quick) {
qtquick2 \
particles \
window \
+ dialogs \
testlib
}
qtHaveModule(xmlpatterns) : SUBDIRS += xmllistmodel
+
+qtHaveModule(widgets) : SUBDIRS += widgets
diff --git a/src/imports/widgets/plugins.qmltypes b/src/imports/widgets/plugins.qmltypes
new file mode 100644
index 0000000000..f9fe1f722c
--- /dev/null
+++ b/src/imports/widgets/plugins.qmltypes
@@ -0,0 +1,72 @@
+import QtQuick.tooling 1.1
+
+// This file describes the plugin-supplied types contained in the library.
+// It is used for QML tooling purposes only.
+//
+// This file was auto-generated with the command 'qmlplugindump QtQuick.PrivateWidgets 1.0'.
+
+Module {
+ Component {
+ name: "QQuickAbstractFileDialog"
+ prototype: "QObject"
+ Property { name: "visible"; type: "bool" }
+ Property { name: "modality"; type: "Qt::WindowModality" }
+ Property { name: "title"; type: "string" }
+ Property { name: "selectExisting"; type: "bool" }
+ Property { name: "selectMultiple"; type: "bool" }
+ Property { name: "selectFolder"; type: "bool" }
+ Property { name: "folder"; type: "string" }
+ Property { name: "nameFilters"; type: "QStringList" }
+ Property { name: "selectedNameFilter"; type: "string" }
+ Property { name: "filePath"; type: "string"; isReadonly: true }
+ Property { name: "filePaths"; type: "QStringList"; isReadonly: true }
+ Signal { name: "visibilityChanged" }
+ Signal { name: "filterSelected" }
+ Signal { name: "fileModeChanged" }
+ Signal { name: "accepted" }
+ Signal { name: "rejected" }
+ Method { name: "open" }
+ Method { name: "close" }
+ Method {
+ name: "setVisible"
+ Parameter { name: "v"; type: "bool" }
+ }
+ Method {
+ name: "setModality"
+ Parameter { name: "m"; type: "Qt::WindowModality" }
+ }
+ Method {
+ name: "setTitle"
+ Parameter { name: "t"; type: "string" }
+ }
+ Method {
+ name: "setSelectExisting"
+ Parameter { name: "s"; type: "bool" }
+ }
+ Method {
+ name: "setSelectMultiple"
+ Parameter { name: "s"; type: "bool" }
+ }
+ Method {
+ name: "setSelectFolder"
+ Parameter { name: "s"; type: "bool" }
+ }
+ Method {
+ name: "setFolder"
+ Parameter { name: "f"; type: "string" }
+ }
+ Method {
+ name: "setNameFilters"
+ Parameter { name: "f"; type: "QStringList" }
+ }
+ Method {
+ name: "selectNameFilter"
+ Parameter { name: "f"; type: "string" }
+ }
+ }
+ Component {
+ name: "QQuickQFileDialog"
+ prototype: "QQuickAbstractFileDialog"
+ exports: ["QtFileDialog 1.0"]
+ }
+}
diff --git a/src/imports/widgets/qmldir b/src/imports/widgets/qmldir
new file mode 100644
index 0000000000..16c84424f2
--- /dev/null
+++ b/src/imports/widgets/qmldir
@@ -0,0 +1,3 @@
+module QtQuick.PrivateWidgets
+plugin widgetsplugin
+typeinfo plugins.qmltypes
diff --git a/src/imports/widgets/qquickqfiledialog.cpp b/src/imports/widgets/qquickqfiledialog.cpp
new file mode 100644
index 0000000000..672c6d1bf4
--- /dev/null
+++ b/src/imports/widgets/qquickqfiledialog.cpp
@@ -0,0 +1,199 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQml module 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$
+**
+****************************************************************************/
+
+#include "qquickqfiledialog_p.h"
+#include "qquickitem.h"
+
+#include <private/qguiapplication_p.h>
+#include <private/qqmlcontext_p.h>
+#include <QWindow>
+#include <QQuickWindow>
+#include <QFileDialog>
+
+QT_BEGIN_NAMESPACE
+
+class QFileDialogHelper : public QPlatformFileDialogHelper
+{
+public:
+ QFileDialogHelper() :
+ QPlatformFileDialogHelper()
+ {
+ connect(&m_dialog, SIGNAL(currentChanged(const QString&)), this, SIGNAL(currentChanged(const QString&)));
+ connect(&m_dialog, SIGNAL(directoryEntered(const QString&)), this, SIGNAL(directoryEntered(const QString&)));
+ connect(&m_dialog, SIGNAL(fileSelected(const QString&)), this, SIGNAL(fileSelected(const QString&)));
+ connect(&m_dialog, SIGNAL(filesSelected(const QStringList&)), this, SIGNAL(filesSelected(const QStringList&)));
+ connect(&m_dialog, SIGNAL(filterSelected(const QString&)), this, SIGNAL(filterSelected(const QString&)));
+ connect(&m_dialog, SIGNAL(accepted()), this, SIGNAL(accept()));
+ connect(&m_dialog, SIGNAL(rejected()), this, SIGNAL(reject()));
+ }
+
+ virtual bool defaultNameFilterDisables() const { return true; }
+ virtual void setDirectory(const QString &dir) { m_dialog.setDirectory(dir); }
+ virtual QString directory() const { return m_dialog.directory().absolutePath(); }
+ virtual void selectFile(const QString &f) { m_dialog.selectFile(f); }
+ virtual QStringList selectedFiles() const { return m_dialog.selectedFiles(); }
+
+ virtual void setFilter() {
+ m_dialog.setWindowTitle(QPlatformFileDialogHelper::options()->windowTitle());
+ if (QPlatformFileDialogHelper::options()->isLabelExplicitlySet(QFileDialogOptions::LookIn))
+ m_dialog.setLabelText(m_dialog.LookIn, QPlatformFileDialogHelper::options()->labelText(QFileDialogOptions::LookIn));
+ if (QPlatformFileDialogHelper::options()->isLabelExplicitlySet(QFileDialogOptions::FileName))
+ m_dialog.setLabelText(m_dialog.FileName, QPlatformFileDialogHelper::options()->labelText(QFileDialogOptions::FileName));
+ if (QPlatformFileDialogHelper::options()->isLabelExplicitlySet(QFileDialogOptions::FileType))
+ m_dialog.setLabelText(m_dialog.FileType, QPlatformFileDialogHelper::options()->labelText(QFileDialogOptions::FileType));
+ if (QPlatformFileDialogHelper::options()->isLabelExplicitlySet(QFileDialogOptions::Accept))
+ m_dialog.setLabelText(m_dialog.Accept, QPlatformFileDialogHelper::options()->labelText(QFileDialogOptions::Accept));
+ if (QPlatformFileDialogHelper::options()->isLabelExplicitlySet(QFileDialogOptions::Reject))
+ m_dialog.setLabelText(m_dialog.Reject, QPlatformFileDialogHelper::options()->labelText(QFileDialogOptions::Reject));
+ m_dialog.setFilter(QPlatformFileDialogHelper::options()->filter());
+ m_dialog.setNameFilters(QPlatformFileDialogHelper::options()->nameFilters());
+ m_dialog.selectNameFilter(QPlatformFileDialogHelper::options()->initiallySelectedNameFilter());
+ m_dialog.setFileMode(QFileDialog::FileMode(QPlatformFileDialogHelper::options()->fileMode()));
+ m_dialog.setOptions((QFileDialog::Options)((int)(QPlatformFileDialogHelper::options()->options())));
+ m_dialog.setAcceptMode(QFileDialog::AcceptMode(QPlatformFileDialogHelper::options()->acceptMode()));
+ }
+
+ virtual void selectNameFilter(const QString &f) { m_dialog.selectNameFilter(f); }
+ virtual QString selectedNameFilter() const { return m_dialog.selectedNameFilter(); }
+ virtual void exec() { m_dialog.exec(); }
+
+ virtual bool show(Qt::WindowFlags f, Qt::WindowModality m, QWindow *parent) {
+ m_dialog.windowHandle()->setTransientParent(parent);
+ m_dialog.windowHandle()->setFlags(f);
+ m_dialog.setWindowModality(m);
+ m_dialog.show();
+ return m_dialog.isVisible();
+ }
+
+ virtual void hide() { m_dialog.hide(); }
+
+private:
+ QFileDialog m_dialog;
+};
+
+/*!
+ \qmltype QtFileDialog
+ \instantiates QQuickQFileDialog
+ \inqmlmodule QtQuick.PrivateWidgets 1
+ \ingroup qtquick-visual
+ \brief Dialog component for choosing files from a local filesystem.
+ \since 5.1
+ \internal
+
+ QtFileDialog provides a means to instantiate and manage a QFileDialog.
+ It is not recommended to be used directly; it is an implementation
+ detail of \l FileDialog in the \l QtQuick.Dialogs module.
+
+ To use this type, you will need to import the module with the following line:
+ \code
+ import QtQuick.PrivateWidgets 1.0
+ \endcode
+*/
+
+/*!
+ \qmlsignal QtQuick::Dialogs::FileDialog::accepted
+
+ The \a accepted signal is emitted when the user has finished using the
+ dialog. You can then inspect the \a filePath or \a filePaths properties to
+ get the selection.
+
+ Example:
+
+ \qml
+ FileDialog {
+ onAccepted: { console.log("Selected file: " + filePath) }
+ }
+ \endqml
+*/
+
+/*!
+ \qmlsignal QtQuick::Dialogs::FileDialog::rejected
+
+ The \a rejected signal is emitted when the user has dismissed the dialog,
+ either by closing the dialog window or by pressing the Cancel button.
+*/
+
+/*!
+ \class QQuickQFileDialog
+ \inmodule QtQuick.PrivateWidgets
+ \internal
+
+ \brief The QQuickQFileDialog class is a wrapper for a QFileDialog.
+
+ \since 5.1
+*/
+
+/*!
+ Constructs a file dialog with parent window \a parent.
+*/
+QQuickQFileDialog::QQuickQFileDialog(QObject *parent)
+ : QQuickAbstractFileDialog(parent)
+{
+}
+
+/*!
+ Destroys the file dialog.
+*/
+QQuickQFileDialog::~QQuickQFileDialog()
+{
+ if (m_dlgHelper)
+ m_dlgHelper->hide();
+ delete m_dlgHelper;
+}
+
+QPlatformFileDialogHelper *QQuickQFileDialog::helper()
+{
+ QQuickItem *parentItem = qobject_cast<QQuickItem *>(parent());
+ if (parentItem)
+ m_parentWindow = parentItem->window();
+
+ if (!m_dlgHelper) {
+ m_dlgHelper = new QFileDialogHelper();
+ connect(m_dlgHelper, SIGNAL(directoryEntered(QString)), this, SIGNAL(folderChanged()));
+ connect(m_dlgHelper, SIGNAL(filterSelected(QString)), this, SIGNAL(filterSelected()));
+ connect(m_dlgHelper, SIGNAL(accept()), this, SLOT(accept()));
+ connect(m_dlgHelper, SIGNAL(reject()), this, SLOT(reject()));
+ }
+
+ return m_dlgHelper;
+}
+
+QT_END_NAMESPACE
diff --git a/src/imports/widgets/qquickqfiledialog_p.h b/src/imports/widgets/qquickqfiledialog_p.h
new file mode 100644
index 0000000000..73067f796c
--- /dev/null
+++ b/src/imports/widgets/qquickqfiledialog_p.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQml module 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$
+**
+****************************************************************************/
+
+#ifndef QQUICKQFILEDIALOG_P_H
+#define QQUICKQFILEDIALOG_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "../dialogs/qquickabstractfiledialog_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QQuickQFileDialog : public QQuickAbstractFileDialog
+{
+ Q_OBJECT
+
+public:
+ QQuickQFileDialog(QObject *parent = 0);
+ virtual ~QQuickQFileDialog();
+
+protected:
+ QPlatformFileDialogHelper *helper();
+
+ Q_DISABLE_COPY(QQuickQFileDialog)
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickQFileDialog *)
+
+#endif // QQUICKQFILEDIALOG_P_H
diff --git a/src/imports/widgets/widgets.pro b/src/imports/widgets/widgets.pro
new file mode 100644
index 0000000000..57281178a0
--- /dev/null
+++ b/src/imports/widgets/widgets.pro
@@ -0,0 +1,17 @@
+CXX_MODULE = qml
+TARGET = widgetsplugin
+TARGETPATH = QtQuick/PrivateWidgets
+IMPORT_VERSION = 1.0
+
+SOURCES += \
+ widgetsplugin.cpp \
+ qquickqfiledialog.cpp \
+ ../dialogs/qquickabstractfiledialog.cpp
+
+HEADERS += \
+ qquickqfiledialog_p.h \
+ ../dialogs/qquickabstractfiledialog_p.h
+
+QT += quick-private gui-private core-private qml-private v8-private widgets
+
+load(qml_plugin)
diff --git a/src/imports/widgets/widgetsplugin.cpp b/src/imports/widgets/widgetsplugin.cpp
new file mode 100644
index 0000000000..6d3a56ca27
--- /dev/null
+++ b/src/imports/widgets/widgetsplugin.cpp
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins 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$
+**
+****************************************************************************/
+
+#include <QtQml/qqmlextensionplugin.h>
+#include <QtQml/qqml.h>
+#include "qquickqfiledialog_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \qmlmodule QtQuick.PrivateWidgets 1
+ \title QWidget QML Types
+ \ingroup qmlmodules
+ \brief Provides QML types for certain QWidgets
+ \internal
+
+ This QML module contains types which should not be depended upon in QtQuick
+ applications, but are available if the Widgets module is linked. It is
+ recommended to load components from this module conditionally, if at all,
+ and to provide fallback implementations in case they fail to load.
+
+ \code
+ import QtQuick.PrivateWidgets 1.0
+ \endcode
+
+ \since 5.1
+*/
+
+class QtQuick2PrivateWidgetsPlugin : public QQmlExtensionPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface/1.0")
+
+public:
+ virtual void registerTypes(const char *uri)
+ {
+ Q_ASSERT(QLatin1String(uri) == QLatin1String("QtQuick.PrivateWidgets"));
+
+ qmlRegisterType<QQuickQFileDialog>(uri, 1, 0, "QtFileDialog");
+ }
+};
+
+QT_END_NAMESPACE
+
+#include "widgetsplugin.moc"