summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/qnx/qqnxfiledialoghelper.cpp
diff options
context:
space:
mode:
authorSean Harmer <sean.harmer.qnx@kdab.com>2012-04-25 13:16:24 +0100
committerQt by Nokia <qt-info@nokia.com>2012-05-26 00:34:40 +0200
commit48768ab4337175791681d4452aef3745a51bf8a6 (patch)
treee92b7328e5d31fd19fd1894d1e61749d7a69c042 /src/plugins/platforms/qnx/qqnxfiledialoghelper.cpp
parentc4fbe872be1316f2fd65aa62863d6617cb129a3f (diff)
QNX: Adding native file dialog support for Blackberry
This patch enables use of native file dialogs in the application modal case. The native file open dialog is reasonable but the native file save dialog could do with some improvements to make it more usable. Perhaps providing our own "native" dialog UI would be an option once the widget style is finished. Change-Id: If5fb7cf73d27e52db7bfa6d97d8f8fb7912960bb Reviewed-by: Nicolas Arnaud-Cormos <nicolas@kdab.com>
Diffstat (limited to 'src/plugins/platforms/qnx/qqnxfiledialoghelper.cpp')
-rw-r--r--src/plugins/platforms/qnx/qqnxfiledialoghelper.cpp309
1 files changed, 309 insertions, 0 deletions
diff --git a/src/plugins/platforms/qnx/qqnxfiledialoghelper.cpp b/src/plugins/platforms/qnx/qqnxfiledialoghelper.cpp
new file mode 100644
index 0000000000..e0e84dbb73
--- /dev/null
+++ b/src/plugins/platforms/qnx/qqnxfiledialoghelper.cpp
@@ -0,0 +1,309 @@
+/***************************************************************************
+**
+** Copyright (C) 2012 Research In Motion
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qqnxfiledialoghelper.h"
+
+#include "qqnxbpseventfilter.h"
+#include "qqnxscreen.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(QQnxBpsEventFilter *eventFilter)
+ : QPlatformFileDialogHelper(),
+ m_eventFilter(eventFilter),
+ m_dialog(0),
+ m_acceptMode(QFileDialogOptions::AcceptOpen),
+ m_selectedFilter(),
+ m_result(QPlatformDialogHelper::Rejected),
+ m_paths()
+{
+}
+
+QQnxFileDialogHelper::~QQnxFileDialogHelper()
+{
+ if (m_dialog)
+ dialog_destroy(m_dialog);
+}
+
+bool QQnxFileDialogHelper::handleEvent(bps_event_t *event)
+{
+ qFileDialogHelperDebug() << Q_FUNC_INFO;
+
+ // Check dialog event response type (OK vs CANCEL)
+ // CANCEL => index = 0
+ // OK => index = 1
+ int index = dialog_event_get_selected_index(event);
+ qFileDialogHelperDebug() << "Index =" << index;
+ if (index == 1) {
+ m_result = QPlatformDialogHelper::Accepted;
+
+ if (m_acceptMode == QFileDialogOptions::AcceptOpen) {
+ // File open dialog
+
+ // ###TODO Check that this actually gets multiple paths and cleans up properly
+ char **filePaths = 0;
+ int pathCount = 0;
+ int result = dialog_event_get_filebrowse_filepaths(event, &filePaths, &pathCount);
+ if (result != BPS_SUCCESS) {
+ qWarning() << "Could not get paths from native file dialog";
+ return false;
+ }
+
+ for (int i = 0; i < pathCount; ++i) {
+ QString path = QFile::decodeName(filePaths[i]);
+ m_paths.append(path);
+ qFileDialogHelperDebug() << "path =" << path;
+ }
+
+ bps_free(filePaths);
+ } else {
+ // File save dialog
+ const char *filePath = dialog_event_get_filesave_filepath(event);
+ QString path = QFile::decodeName(filePath);
+ qFileDialogHelperDebug() << "path =" << path;
+ m_paths.append(path);
+ }
+ } else { // Cancel
+ m_result = QPlatformDialogHelper::Rejected;
+ }
+
+ emit dialogClosed();
+
+ return true;
+}
+
+void QQnxFileDialogHelper::exec()
+{
+ qFileDialogHelperDebug() << Q_FUNC_INFO;
+
+ // Clear any previous results
+ m_paths.clear();
+
+ QEventLoop loop;
+ connect(this, SIGNAL(dialogClosed()), &loop, SLOT(quit()));
+ loop.exec();
+
+ if (m_result == QPlatformDialogHelper::Accepted)
+ emit accept();
+ else
+ emit reject();
+}
+
+bool QQnxFileDialogHelper::show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent)
+{
+ Q_UNUSED(flags);
+ qFileDialogHelperDebug() << Q_FUNC_INFO;
+
+ // We *really* need the bps event filter ;)
+ if (!m_eventFilter)
+ return false;
+
+ // Native dialogs can only handle application modal use cases so far
+ if (modality != Qt::ApplicationModal)
+ return false;
+
+ // Tear down any existing dialog and start again as dialog mode may have changed
+ if (m_dialog) {
+ dialog_destroy(m_dialog);
+ m_dialog = 0;
+ }
+
+ // Create dialog
+ const QSharedPointer<QFileDialogOptions> &opts = options();
+ if (opts->acceptMode() == QFileDialogOptions::AcceptOpen) {
+ if (dialog_create_filebrowse(&m_dialog) != BPS_SUCCESS) {
+ qWarning("dialog_create_filebrowse failed");
+ return false;
+ }
+
+ // Select one or many files?
+ bool multiSelect = (opts->fileMode() == QFileDialogOptions::ExistingFiles);
+ dialog_set_filebrowse_multiselect(m_dialog, multiSelect);
+
+ // Set the actual list of extensions
+ if (!opts->nameFilters().isEmpty()) {
+ qFileDialogHelperDebug() << "nameFilters =" << opts->nameFilters();
+ setNameFilter(opts->nameFilters().first());
+ } else {
+ QString defaultNameFilter = QStringLiteral("*.*");
+ setNameFilter(defaultNameFilter);
+ }
+ } else {
+ if (dialog_create_filesave(&m_dialog) != BPS_SUCCESS) {
+ qWarning("dialog_create_filesave failed");
+ return false;
+ }
+
+ // Maybe pre-select a filename
+ if (!opts->initiallySelectedFiles().isEmpty()) {
+ QString fileName = opts->initiallySelectedFiles().first();
+ dialog_set_filesave_filename(m_dialog, QFile::encodeName(fileName).constData());
+ }
+
+ // Add OK and Cancel buttons. We add the buttons in the order "CANCEL" followed by "OK
+ // such that they have indices matching the buttons on the file open dialog which
+ // is automatically populated with buttons.
+ if (dialog_add_button(m_dialog, tr("CANCEL").toLocal8Bit().constData(), true, 0, true) != BPS_SUCCESS) {
+ qWarning("dialog_add_button failed");
+ return false;
+ }
+
+ if (dialog_add_button(m_dialog, tr("OK").toLocal8Bit().constData(), true, 0, true) != BPS_SUCCESS) {
+ qWarning("dialog_add_button failed");
+ return false;
+ }
+ }
+
+ // Cache the accept mode so we know which functions to use to get the results back
+ m_acceptMode = opts->acceptMode();
+
+ // Set the libscreen window group and common properties
+ QQnxScreen *nativeScreen = static_cast<QQnxScreen *>(parent->screen()->handle());
+ dialog_set_group_id(m_dialog, nativeScreen->windowGroupName());
+ dialog_set_title_text(m_dialog, opts->windowTitle().toLocal8Bit().constData());
+
+ // Register ourselves for dialog domain events from bps
+ m_eventFilter->registerForDialogEvents(this);
+
+ // Show the dialog
+ dialog_show(m_dialog);
+
+ return true;
+}
+
+void QQnxFileDialogHelper::hide()
+{
+ qFileDialogHelperDebug() << Q_FUNC_INFO;
+ if (!m_dialog)
+ return;
+ dialog_cancel(m_dialog);
+}
+
+bool QQnxFileDialogHelper::defaultNameFilterDisables() const
+{
+ qFileDialogHelperDebug() << Q_FUNC_INFO;
+ return false;
+}
+
+void QQnxFileDialogHelper::setDirectory(const QString &directory)
+{
+ qFileDialogHelperDebug() << Q_FUNC_INFO << "directory =" << directory;
+ // No native API for setting the directory(!). The best we can do is to
+ // set it as the file name but even then only with a file save dialog.
+ if (m_dialog && m_acceptMode == QFileDialogOptions::AcceptSave)
+ dialog_set_filesave_filename(m_dialog, QFile::encodeName(directory).constData());
+}
+
+QString QQnxFileDialogHelper::directory() const
+{
+ qFileDialogHelperDebug() << Q_FUNC_INFO;
+ return m_paths.first();
+}
+
+void QQnxFileDialogHelper::selectFile(const QString &fileName)
+{
+ qFileDialogHelperDebug() << Q_FUNC_INFO << "filename =" << fileName;
+ if (m_dialog && m_acceptMode == QFileDialogOptions::AcceptSave)
+ dialog_set_filesave_filename(m_dialog, QFile::encodeName(fileName).constData());
+}
+
+QStringList QQnxFileDialogHelper::selectedFiles() const
+{
+ qFileDialogHelperDebug() << Q_FUNC_INFO;
+ return m_paths;
+}
+
+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;
+
+ // 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();
+ globs[i] = new char[glob.length()];
+ strcpy(globs[i], glob.constData());
+ }
+
+ // Set the filters
+ dialog_set_filebrowse_filter(m_dialog, const_cast<const char**>(globs), filters.size());
+ m_selectedFilter = filter;
+
+ // Cleanup
+ for (int i = 0; i < filters.size(); ++i)
+ delete[] globs[i];
+ delete[] globs;
+}
+
+QT_END_NAMESPACE