summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRafael Roquetto <rafael.roquetto.qnx@kdab.com>2013-03-04 18:44:52 -0300
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-03-27 03:54:59 +0100
commit5d12417c94579fcbed3beb40b03f4309e7a44e79 (patch)
tree54b2d9963bc0d9c0cc492077bb6cffe8b31f61c9 /src
parentb611da0d97408e1d3c9fabed3ef9e7e1b8c5f7da (diff)
BlackBerry: Native BB10 QFileDialog support
Change-Id: I4e83fbc6ba425d237b08056b45f9bcf47751bfce Reviewed-by: Kevin Krammer <kevin.krammer@kdab.com> Reviewed-by: Tobias Koenig Reviewed-by: Nicolas Arnaud-Cormos <nicolas@kdab.com> Reviewed-by: Sean Harmer <sean.harmer@kdab.com> Reviewed-by: Thomas McGuire <thomas.mcguire@kdab.com>
Diffstat (limited to 'src')
-rw-r--r--src/plugins/platforms/qnx/qnx.pro15
-rw-r--r--src/plugins/platforms/qnx/qqnxbpseventfilter.cpp6
-rw-r--r--src/plugins/platforms/qnx/qqnxbpseventfilter.h2
-rw-r--r--src/plugins/platforms/qnx/qqnxfiledialoghelper.h18
-rw-r--r--src/plugins/platforms/qnx/qqnxfiledialoghelper_bb10.cpp209
-rw-r--r--src/plugins/platforms/qnx/qqnxfiledialoghelper_playbook.cpp (renamed from src/plugins/platforms/qnx/qqnxfiledialoghelper.cpp)18
-rw-r--r--src/plugins/platforms/qnx/qqnxfilepicker.cpp287
-rw-r--r--src/plugins/platforms/qnx/qqnxfilepicker.h110
-rw-r--r--src/plugins/platforms/qnx/qqnxtheme.cpp4
9 files changed, 653 insertions, 16 deletions
diff --git a/src/plugins/platforms/qnx/qnx.pro b/src/plugins/platforms/qnx/qnx.pro
index 203cdebda9..af30bf8666 100644
--- a/src/plugins/platforms/qnx/qnx.pro
+++ b/src/plugins/platforms/qnx/qnx.pro
@@ -40,6 +40,7 @@ CONFIG(blackberry) {
#DEFINES += QQNXVIRTUALKEYBOARD_DEBUG
#DEFINES += QQNXWINDOW_DEBUG
#DEFINES += QQNXCURSOR_DEBUG
+#DEFINES += QQNXFILEPICKER_DEBUG
SOURCES = main.cpp \
@@ -91,8 +92,7 @@ CONFIG(blackberry) {
qqnxbpseventfilter.cpp \
qqnxvirtualkeyboardbps.cpp \
qqnxtheme.cpp \
- qqnxsystemsettings.cpp \
- qqnxfiledialoghelper.cpp
+ qqnxsystemsettings.cpp
HEADERS += qqnxnavigatorbps.h \
qqnxeventdispatcher_blackberry.h \
@@ -105,6 +105,17 @@ CONFIG(blackberry) {
LIBS += -lbps
}
+CONFIG(blackberry-playbook) {
+ SOURCES += qqnxfiledialoghelper_playbook.cpp
+} else {
+ CONFIG(blackberry) {
+ SOURCES += qqnxfiledialoghelper_bb10.cpp \
+ qqnxfilepicker.cpp
+
+ HEADERS += qqnxfilepicker.h
+ }
+}
+
CONFIG(qqnx_pps) {
DEFINES += QQNX_PPS
diff --git a/src/plugins/platforms/qnx/qqnxbpseventfilter.cpp b/src/plugins/platforms/qnx/qqnxbpseventfilter.cpp
index 765853e392..2ef548f59f 100644
--- a/src/plugins/platforms/qnx/qqnxbpseventfilter.cpp
+++ b/src/plugins/platforms/qnx/qqnxbpseventfilter.cpp
@@ -41,10 +41,10 @@
#include "qqnxbpseventfilter.h"
#include "qqnxnavigatoreventhandler.h"
-#include "qqnxfiledialoghelper.h"
#include "qqnxscreen.h"
#include "qqnxscreeneventhandler.h"
#include "qqnxvirtualkeyboardbps.h"
+#include "qqnxfiledialoghelper.h"
#include <QAbstractEventDispatcher>
#include <QDebug>
@@ -126,6 +126,7 @@ void QQnxBpsEventFilter::unregisterForScreenEvents(QQnxScreen *screen)
qWarning("QQNX: failed to unregister for screen events on screen %p", screen->nativeContext());
}
+#if defined(Q_OS_BLACKBERRY_TABLET)
void QQnxBpsEventFilter::registerForDialogEvents(QQnxFileDialogHelper *dialog)
{
if (dialog_request_events(0) != BPS_SUCCESS)
@@ -141,6 +142,7 @@ void QQnxBpsEventFilter::unregisterForDialogEvents(QQnxFileDialogHelper *dialog)
if (count == 0)
qWarning("QQNX: attempting to unregister dialog that was not registered");
}
+#endif // Q_OS_BLACKBERRY_TABLET
bool QQnxBpsEventFilter::nativeEventFilter(const QByteArray &eventType, void *message, long *result)
{
@@ -160,12 +162,14 @@ bool QQnxBpsEventFilter::nativeEventFilter(const QByteArray &eventType, void *me
return m_screenEventHandler->handleEvent(screenEvent);
}
+#if defined(Q_OS_BLACKBERRY_TABLET)
if (eventDomain == dialog_get_domain()) {
dialog_instance_t nativeDialog = dialog_event_get_dialog_instance(event);
QQnxFileDialogHelper *dialog = m_dialogMapper.value(nativeDialog, 0);
if (dialog)
return dialog->handleEvent(event);
}
+#endif
if (eventDomain == navigator_get_domain())
return handleNavigatorEvent(event);
diff --git a/src/plugins/platforms/qnx/qqnxbpseventfilter.h b/src/plugins/platforms/qnx/qqnxbpseventfilter.h
index e897863efb..f8e36823d5 100644
--- a/src/plugins/platforms/qnx/qqnxbpseventfilter.h
+++ b/src/plugins/platforms/qnx/qqnxbpseventfilter.h
@@ -73,8 +73,10 @@ public:
void registerForScreenEvents(QQnxScreen *screen);
void unregisterForScreenEvents(QQnxScreen *screen);
+#ifdef Q_OS_BLACKBERRY_TABLET
void registerForDialogEvents(QQnxFileDialogHelper *dialog);
void unregisterForDialogEvents(QQnxFileDialogHelper *dialog);
+#endif
private:
bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) Q_DECL_OVERRIDE;
diff --git a/src/plugins/platforms/qnx/qqnxfiledialoghelper.h b/src/plugins/platforms/qnx/qqnxfiledialoghelper.h
index e17ea80501..ad2483365b 100644
--- a/src/plugins/platforms/qnx/qqnxfiledialoghelper.h
+++ b/src/plugins/platforms/qnx/qqnxfiledialoghelper.h
@@ -44,12 +44,19 @@
#include <qpa/qplatformdialoghelper.h>
-#include <bps/dialog.h>
QT_BEGIN_NAMESPACE
class QQnxIntegration;
+#if defined(Q_OS_BLACKBERRY_TABLET)
+#include <bps/dialog.h>
+#define NativeDialogPtr dialog_instance_t
+#else
+class QQnxFilePicker;
+#define NativeDialogPtr QQnxFilePicker *
+#endif
+
class QQnxFileDialogHelper : public QPlatformFileDialogHelper
{
Q_OBJECT
@@ -57,7 +64,9 @@ public:
explicit QQnxFileDialogHelper(const QQnxIntegration *);
~QQnxFileDialogHelper();
+#if defined(Q_OS_BLACKBERRY_TABLET)
bool handleEvent(bps_event_t *event);
+#endif
void exec();
@@ -73,21 +82,24 @@ public:
void selectNameFilter(const QString &filter);
QString selectedNameFilter() const;
- dialog_instance_t nativeDialog() const { return m_dialog; }
+ NativeDialogPtr nativeDialog() const { return m_dialog; }
Q_SIGNALS:
void dialogClosed();
private:
void setNameFilter(const QString &filter);
+ void setNameFilters(const QStringList &filters);
const QQnxIntegration *m_integration;
- dialog_instance_t m_dialog;
+ NativeDialogPtr m_dialog;
QFileDialogOptions::AcceptMode m_acceptMode;
QString m_selectedFilter;
QPlatformDialogHelper::DialogCode m_result;
+#if defined(Q_OS_BLACKBERRY_TABLET)
QStringList m_paths;
+#endif
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxfiledialoghelper_bb10.cpp b/src/plugins/platforms/qnx/qqnxfiledialoghelper_bb10.cpp
new file mode 100644
index 0000000000..f4c48610a6
--- /dev/null
+++ b/src/plugins/platforms/qnx/qqnxfiledialoghelper_bb10.cpp
@@ -0,0 +1,209 @@
+/***************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** 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 "qqnxfiledialoghelper.h"
+
+#include "qqnxfilepicker.h"
+#include "qqnxbpseventfilter.h"
+#include "qqnxscreen.h"
+#include "qqnxintegration.h"
+
+#include <QDebug>
+#include <QEventLoop>
+#include <QScreen>
+#include <QTimer>
+#include <QWindow>
+
+#ifdef QQNXFILEDIALOGHELPER_DEBUG
+#define qFileDialogHelperDebug qDebug
+#else
+#define qFileDialogHelperDebug QT_NO_QDEBUG_MACRO
+#endif
+
+QT_BEGIN_NAMESPACE
+
+QQnxFileDialogHelper::QQnxFileDialogHelper(const QQnxIntegration *integration)
+ : QPlatformFileDialogHelper(),
+ m_integration(integration),
+ m_dialog(new QQnxFilePicker),
+ m_acceptMode(QFileDialogOptions::AcceptOpen),
+ m_selectedFilter(),
+ m_result(QPlatformDialogHelper::Rejected)
+{
+}
+
+QQnxFileDialogHelper::~QQnxFileDialogHelper()
+{
+ delete m_dialog;
+}
+
+void QQnxFileDialogHelper::exec()
+{
+ qFileDialogHelperDebug() << Q_FUNC_INFO;
+
+ // Clear any previous results
+ m_dialog->setDirectories(QStringList());
+
+ QEventLoop loop;
+ connect(m_dialog, SIGNAL(closed()), &loop, SLOT(quit()));
+ loop.exec();
+
+ if (m_dialog->selectedFiles().isEmpty())
+ Q_EMIT reject();
+ else
+ Q_EMIT accept();
+}
+
+bool QQnxFileDialogHelper::show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent)
+{
+ Q_UNUSED(flags);
+ Q_UNUSED(parent);
+ Q_UNUSED(modality);
+
+ qFileDialogHelperDebug() << Q_FUNC_INFO;
+
+ // Create dialog
+ const QSharedPointer<QFileDialogOptions> &opts = options();
+ if (opts->acceptMode() == QFileDialogOptions::AcceptOpen) {
+ // Select one or many files?
+ const QQnxFilePicker::Mode mode = (opts->fileMode() == QFileDialogOptions::ExistingFiles)
+ ? QQnxFilePicker::PickerMultiple : QQnxFilePicker::Picker;
+
+ m_dialog->setMode(mode);
+
+ // Set the actual list of extensions
+ if (!opts->nameFilters().isEmpty())
+ setNameFilters(opts->nameFilters());
+ else
+ setNameFilter(tr("All files (*.*)"));
+ } else {
+ const QQnxFilePicker::Mode mode = (opts->initiallySelectedFiles().count() >= 2)
+ ? QQnxFilePicker::SaverMultiple : QQnxFilePicker::Saver;
+
+ m_dialog->setMode(mode);
+
+ if (!opts->initiallySelectedFiles().isEmpty())
+ m_dialog->setDefaultSaveFileNames(opts->initiallySelectedFiles());
+ }
+
+ // Cache the accept mode so we know which functions to use to get the results back
+ m_acceptMode = opts->acceptMode();
+ m_dialog->setTitle(opts->windowTitle());
+ m_dialog->open();
+
+ return true;
+}
+
+void QQnxFileDialogHelper::hide()
+{
+ qFileDialogHelperDebug() << Q_FUNC_INFO;
+ m_dialog->close();
+}
+
+bool QQnxFileDialogHelper::defaultNameFilterDisables() const
+{
+ qFileDialogHelperDebug() << Q_FUNC_INFO;
+ return false;
+}
+
+void QQnxFileDialogHelper::setDirectory(const QString &directory)
+{
+ m_dialog->addDirectory(directory);
+}
+
+QString QQnxFileDialogHelper::directory() const
+{
+ qFileDialogHelperDebug() << Q_FUNC_INFO;
+ if (!m_dialog->directories().isEmpty())
+ return m_dialog->directories().first();
+
+ return QString();
+}
+
+void QQnxFileDialogHelper::selectFile(const QString &fileName)
+{
+ m_dialog->addDefaultSaveFileName(fileName);
+}
+
+QStringList QQnxFileDialogHelper::selectedFiles() const
+{
+ qFileDialogHelperDebug() << Q_FUNC_INFO;
+ return m_dialog->selectedFiles();
+}
+
+void QQnxFileDialogHelper::setFilter()
+{
+ // No native api to support setting a filter from QDir::Filters
+ qFileDialogHelperDebug() << Q_FUNC_INFO;
+}
+
+void QQnxFileDialogHelper::selectNameFilter(const QString &filter)
+{
+ qFileDialogHelperDebug() << Q_FUNC_INFO << "filter =" << filter;
+ setNameFilter(filter);
+}
+
+QString QQnxFileDialogHelper::selectedNameFilter() const
+{
+ // For now there is no way for the user to change the selected filter
+ // so this just reflects what the developer has set programmatically.
+ qFileDialogHelperDebug() << Q_FUNC_INFO;
+ return m_selectedFilter;
+}
+
+void QQnxFileDialogHelper::setNameFilter(const QString &filter)
+{
+ qFileDialogHelperDebug() << Q_FUNC_INFO << "filter =" << filter;
+
+ setNameFilters(QPlatformFileDialogHelper::cleanFilterList(filter));
+}
+
+void QQnxFileDialogHelper::setNameFilters(const QStringList &filters)
+{
+ qFileDialogHelperDebug() << Q_FUNC_INFO << "filters =" << filters;
+
+ Q_ASSERT(!filters.isEmpty());
+
+ m_dialog->setFilters(filters);
+ m_selectedFilter = filters.first();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxfiledialoghelper.cpp b/src/plugins/platforms/qnx/qqnxfiledialoghelper_playbook.cpp
index 79d7c7d9ca..4f61e0c587 100644
--- a/src/plugins/platforms/qnx/qqnxfiledialoghelper.cpp
+++ b/src/plugins/platforms/qnx/qqnxfiledialoghelper_playbook.cpp
@@ -118,7 +118,7 @@ bool QQnxFileDialogHelper::handleEvent(bps_event_t *event)
m_result = QPlatformDialogHelper::Rejected;
}
- emit dialogClosed();
+ Q_EMIT dialogClosed();
return true;
}
@@ -135,9 +135,9 @@ void QQnxFileDialogHelper::exec()
loop.exec();
if (m_result == QPlatformDialogHelper::Accepted)
- emit accept();
+ Q_EMIT accept();
else
- emit reject();
+ Q_EMIT reject();
}
bool QQnxFileDialogHelper::show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent)
@@ -291,9 +291,15 @@ QString QQnxFileDialogHelper::selectedNameFilter() const
void QQnxFileDialogHelper::setNameFilter(const QString &filter)
{
qFileDialogHelperDebug() << Q_FUNC_INFO << "filter =" << filter;
+ setNameFilters(QPlatformFileDialogHelper::cleanFilterList(filter));
+}
+
+void QQnxFileDialogHelper::setNameFilters(const QStringList &filters)
+{
+ qFileDialogHelperDebug() << Q_FUNC_INFO << "filters =" << filters;
+
+ Q_ASSERT(!filters.isEmpty());
- // Extract the globbing expressions
- QStringList filters = QPlatformFileDialogHelper::cleanFilterList(filter);
char **globs = new char*[filters.size()];
for (int i = 0; i < filters.size(); ++i) {
QByteArray glob = filters.at(i).toLocal8Bit();
@@ -303,7 +309,7 @@ void QQnxFileDialogHelper::setNameFilter(const QString &filter)
// Set the filters
dialog_set_filebrowse_filter(m_dialog, const_cast<const char**>(globs), filters.size());
- m_selectedFilter = filter;
+ m_selectedFilter = filters.first();
// Cleanup
for (int i = 0; i < filters.size(); ++i)
diff --git a/src/plugins/platforms/qnx/qqnxfilepicker.cpp b/src/plugins/platforms/qnx/qqnxfilepicker.cpp
new file mode 100644
index 0000000000..9326a23b98
--- /dev/null
+++ b/src/plugins/platforms/qnx/qqnxfilepicker.cpp
@@ -0,0 +1,287 @@
+/***************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** 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 "qqnxfilepicker.h"
+
+#include <QAbstractEventDispatcher>
+#include <QCoreApplication>
+#include <QDebug>
+#include <QJsonDocument>
+#include <QJsonObject>
+#include <QJsonArray>
+#include <QJsonParseError>
+
+#include <bps/navigator.h>
+#include <bps/navigator_invoke.h>
+
+#include <errno.h>
+
+#ifdef QQNXFILEPICKER_DEBUG
+#define qFilePickerDebug qDebug
+#else
+#define qFilePickerDebug QT_NO_QDEBUG_MACRO
+#endif
+
+static const char s_filePickerTarget[] = "sys.filepicker.target";
+
+QQnxFilePicker::QQnxFilePicker(QObject *parent)
+ : QObject(parent)
+ , m_invocationHandle(0)
+ , m_mode(QQnxFilePicker::Picker)
+ , m_title(tr("Pick a file"))
+{
+ QCoreApplication::eventDispatcher()->installNativeEventFilter(this);
+}
+
+QQnxFilePicker::~QQnxFilePicker()
+{
+ cleanup();
+
+ QCoreApplication::eventDispatcher()->removeNativeEventFilter(this);
+}
+
+void QQnxFilePicker::open()
+{
+ if (m_invocationHandle)
+ return;
+
+ int errorCode = BPS_SUCCESS;
+
+ errorCode = navigator_invoke_invocation_create(&m_invocationHandle);
+ if (errorCode != BPS_SUCCESS) {
+ qWarning() << "QQnxFilePicker: unable to create invocation:" << strerror(errno);
+ return;
+ }
+
+ errorCode = navigator_invoke_invocation_set_target(m_invocationHandle, s_filePickerTarget);
+
+ if (errorCode != BPS_SUCCESS) {
+ cleanup();
+ qWarning() << "QQnxFilePicker: unable to set target:" << strerror(errno);
+ return;
+ }
+
+ errorCode = navigator_invoke_invocation_set_action(m_invocationHandle, "bb.action.OPEN");
+ if (errorCode != BPS_SUCCESS) {
+ cleanup();
+ qWarning() << "QQnxFilePicker: unable to set action:" << strerror(errno);
+ return;
+ }
+
+ errorCode = navigator_invoke_invocation_set_type(m_invocationHandle, "application/vnd.blackberry.file_picker");
+ if (errorCode != BPS_SUCCESS) {
+ cleanup();
+ qWarning() << "QQnxFilePicker: unable to set mime type:" << strerror(errno);
+ return;
+ }
+
+ QVariantMap map;
+ map[QStringLiteral("Type")] = QStringLiteral("Other");
+ map[QStringLiteral("Mode")] = modeToString(m_mode);
+ map[QStringLiteral("Title")] = m_title;
+ map[QStringLiteral("ViewMode")] = QStringLiteral("Default");
+ map[QStringLiteral("SortBy")] = QStringLiteral("Default");
+ map[QStringLiteral("SortOrder")] = QStringLiteral("Default");
+ map[QStringLiteral("ImageCrop")] = false;
+ map[QStringLiteral("AllowOverwrite")] = false;
+
+ if (!m_defaultSaveFileNames.isEmpty())
+ map[QStringLiteral("DefaultFileNames")] = m_defaultSaveFileNames.join(",");
+ if (!m_filters.isEmpty())
+ map[QStringLiteral("Filter")] = m_filters.join(";");
+
+ QJsonDocument document;
+ document.setObject(QJsonObject::fromVariantMap(map));
+ const QByteArray jsonData = document.toJson(QJsonDocument::Compact);
+
+ errorCode = navigator_invoke_invocation_set_data(m_invocationHandle, jsonData.constData(), jsonData.size());
+ if (errorCode != BPS_SUCCESS) {
+ cleanup();
+ qWarning() << "QQnxFilePicker: unable to set data:" << strerror(errno);
+ return;
+ }
+
+ navigator_invoke_invocation_send(m_invocationHandle);
+}
+
+void QQnxFilePicker::close()
+{
+ navigator_card_close_child();
+ cleanup();
+}
+
+bool QQnxFilePicker::nativeEventFilter(const QByteArray&, void *message, long*)
+{
+ bps_event_t * const event = static_cast<bps_event_t*>(message);
+ if (!event)
+ return false;
+
+ if (bps_event_get_code(event) == NAVIGATOR_INVOKE_TARGET_RESULT) {
+ const char *id = navigator_event_get_id(event);
+ const char *err = navigator_event_get_err(event);
+ qFilePickerDebug("received invocation response: id=%s err=%s", id, err);
+ } else if (bps_event_get_code(event) == NAVIGATOR_CHILD_CARD_CLOSED) {
+ const char *data = navigator_event_get_card_closed_data(event);
+ qFilePickerDebug("received data: data='%s'", data);
+ handleFilePickerResponse(data);
+ }
+
+ return false; // do not drop the event
+}
+
+void QQnxFilePicker::setMode(QQnxFilePicker::Mode mode)
+{
+ m_mode = mode;
+}
+
+void QQnxFilePicker::setDefaultSaveFileNames(const QStringList &fileNames)
+{
+ m_defaultSaveFileNames = fileNames;
+}
+
+void QQnxFilePicker::addDefaultSaveFileName(const QString &fileName)
+{
+ m_defaultSaveFileNames.append(fileName);
+}
+
+void QQnxFilePicker::setDirectories(const QStringList &directories)
+{
+ m_directories = directories;
+}
+
+void QQnxFilePicker::addDirectory(const QString &directory)
+{
+ m_directories.append(directory);
+}
+
+void QQnxFilePicker::setFilters(const QStringList &filters)
+{
+ m_filters = filters;
+}
+
+void QQnxFilePicker::setTitle(const QString &title)
+{
+ m_title = title;
+}
+
+QQnxFilePicker::Mode QQnxFilePicker::mode() const
+{
+ return m_mode;
+}
+
+QStringList QQnxFilePicker::defaultSaveFileNames() const
+{
+ return m_defaultSaveFileNames;
+}
+
+QStringList QQnxFilePicker::directories() const
+{
+ return m_directories;
+}
+
+QStringList QQnxFilePicker::filters() const
+{
+ return m_filters;
+}
+
+QStringList QQnxFilePicker::selectedFiles() const
+{
+ return m_selectedFiles;
+}
+
+QString QQnxFilePicker::title() const
+{
+ return m_title;
+}
+
+void QQnxFilePicker::cleanup()
+{
+ if (m_invocationHandle) {
+ navigator_invoke_invocation_destroy(m_invocationHandle);
+ m_invocationHandle = 0;
+ }
+}
+
+void QQnxFilePicker::handleFilePickerResponse(const char *data)
+{
+ QJsonParseError jsonError;
+ QJsonDocument document = QJsonDocument::fromJson(data, &jsonError);
+
+ if (jsonError.error != QJsonParseError::NoError) {
+ qFilePickerDebug() << "Error parsing FilePicker response: "
+ << jsonError.errorString();
+ Q_EMIT closed();
+ cleanup();
+ return;
+ }
+
+ // The response is a list of Json objects.
+ const QVariantList array = document.array().toVariantList();
+
+ foreach (const QVariant &variant, array) {
+ const QJsonObject object = QJsonObject::fromVariantMap(variant.toMap());
+ const QString uri = object.value(QStringLiteral("uri")).toString();
+
+ if (!uri.isEmpty())
+ m_selectedFiles << uri;
+
+ qFilePickerDebug() << "FilePicker uri response:" << uri;
+ }
+
+ Q_EMIT closed();
+ cleanup();
+}
+
+QString QQnxFilePicker::modeToString(QQnxFilePicker::Mode mode) const
+{
+ switch (mode) {
+ case Picker:
+ return QStringLiteral("Picker");
+ case Saver:
+ return QStringLiteral("Saver");
+ case PickerMultiple:
+ return QStringLiteral("PickerMultiple");
+ case SaverMultiple:
+ return QStringLiteral("SaverMultiple");
+ }
+
+ return QStringLiteral("Picker");
+}
diff --git a/src/plugins/platforms/qnx/qqnxfilepicker.h b/src/plugins/platforms/qnx/qqnxfilepicker.h
new file mode 100644
index 0000000000..5bb8f0969f
--- /dev/null
+++ b/src/plugins/platforms/qnx/qqnxfilepicker.h
@@ -0,0 +1,110 @@
+/***************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** 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$
+**
+****************************************************************************/
+
+#ifndef QQNXFILEPICKER_H
+#define QQNXFILEPICKER_H
+
+#include <QAbstractNativeEventFilter>
+#include <QObject>
+#include <QStringList>
+
+struct navigator_invoke_invocation_t;
+
+class QQnxFilePicker : public QObject, public QAbstractNativeEventFilter
+{
+ Q_OBJECT
+
+public:
+ explicit QQnxFilePicker(QObject *parent = 0);
+ ~QQnxFilePicker();
+
+ enum Mode {
+ Picker,
+ Saver,
+ PickerMultiple,
+ SaverMultiple
+ };
+
+ bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) Q_DECL_OVERRIDE;
+
+ void setMode(Mode mode);
+ void setDefaultSaveFileNames(const QStringList &fileNames);
+ void addDefaultSaveFileName(const QString &fileName);
+ void setDirectories(const QStringList &directories);
+ void addDirectory(const QString &directory);
+ void setFilters(const QStringList &filters);
+ void setTitle(const QString &title);
+
+ Mode mode() const;
+
+ QStringList defaultSaveFileNames() const;
+ QStringList directories() const;
+ QStringList filters() const;
+ QStringList selectedFiles() const;
+
+ QString title() const;
+
+Q_SIGNALS:
+ void closed();
+
+public Q_SLOTS:
+ void open();
+ void close();
+
+private:
+ void cleanup();
+ void handleFilePickerResponse(const char *data);
+
+ QString modeToString(Mode mode) const;
+
+ navigator_invoke_invocation_t *m_invocationHandle;
+
+ Mode m_mode;
+
+ QStringList m_defaultSaveFileNames;
+ QStringList m_directories;
+ QStringList m_filters;
+ QStringList m_selectedFiles;
+
+ QString m_title;
+};
+
+#endif // QQNXFILEPICKER_H
diff --git a/src/plugins/platforms/qnx/qqnxtheme.cpp b/src/plugins/platforms/qnx/qqnxtheme.cpp
index e8e9e39388..ae9acd845e 100644
--- a/src/plugins/platforms/qnx/qqnxtheme.cpp
+++ b/src/plugins/platforms/qnx/qqnxtheme.cpp
@@ -58,10 +58,8 @@ QQnxTheme::~QQnxTheme()
bool QQnxTheme::usePlatformNativeDialog(DialogType type) const
{
-#if defined(Q_OS_BLACKBERRY_TABLET)
if (type == QPlatformTheme::FileDialog)
return true;
-#endif
#if !defined(QT_NO_COLORDIALOG)
if (type == QPlatformTheme::ColorDialog)
return false;
@@ -76,10 +74,8 @@ bool QQnxTheme::usePlatformNativeDialog(DialogType type) const
QPlatformDialogHelper *QQnxTheme::createPlatformDialogHelper(DialogType type) const
{
switch (type) {
-#if defined(Q_OS_BLACKBERRY_TABLET)
case QPlatformTheme::FileDialog:
return new QQnxFileDialogHelper(m_integration);
-#endif
#ifndef QT_NO_COLORDIALOG
case QPlatformTheme::ColorDialog:
#endif