summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/qnx/qqnxfiledialoghelper_playbook.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/qnx/qqnxfiledialoghelper_playbook.cpp')
-rw-r--r--src/plugins/platforms/qnx/qqnxfiledialoghelper_playbook.cpp320
1 files changed, 320 insertions, 0 deletions
diff --git a/src/plugins/platforms/qnx/qqnxfiledialoghelper_playbook.cpp b/src/plugins/platforms/qnx/qqnxfiledialoghelper_playbook.cpp
new file mode 100644
index 0000000000..2a743d03f7
--- /dev/null
+++ b/src/plugins/platforms/qnx/qqnxfiledialoghelper_playbook.cpp
@@ -0,0 +1,320 @@
+/***************************************************************************
+**
+** Copyright (C) 2012 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 "qqnxbpseventfilter.h"
+#include "qqnxscreen.h"
+#include "qqnxintegration.h"
+
+#include <QDebug>
+#include <QEventLoop>
+#include <QScreen>
+#include <QTimer>
+#include <QWindow>
+
+#if defined(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(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(QUrl::fromLocalFile(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(QUrl::fromLocalFile(path));
+ }
+ } else { // Cancel
+ m_result = QPlatformDialogHelper::Rejected;
+ }
+
+ Q_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)
+ Q_EMIT accept();
+ else
+ Q_EMIT reject();
+}
+
+bool QQnxFileDialogHelper::show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent)
+{
+ Q_UNUSED(flags);
+ qFileDialogHelperDebug() << Q_FUNC_INFO;
+
+ QQnxBpsEventFilter *eventFilter = m_integration->bpsEventFilter();
+ // We *really* need the bps event filter ;)
+ if (!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().toLocalFile();
+ 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 = parent ? static_cast<QQnxScreen *>(parent->screen()->handle()) :
+ m_integration->primaryDisplay();
+ Q_ASSERT(nativeScreen);
+ 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
+ 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 QUrl &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.toLocalFile()).constData());
+}
+
+QUrl QQnxFileDialogHelper::directory() const
+{
+ qFileDialogHelperDebug() << Q_FUNC_INFO;
+ return m_paths.first();
+}
+
+void QQnxFileDialogHelper::selectFile(const QUrl &fileName)
+{
+ qFileDialogHelperDebug() << Q_FUNC_INFO << "filename =" << fileName;
+ if (m_dialog && m_acceptMode == QFileDialogOptions::AcceptSave)
+ dialog_set_filesave_filename(m_dialog, QFile::encodeName(fileName.toLocalFile()).constData());
+}
+
+QList<QUrl> 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;
+ setNameFilters(QPlatformFileDialogHelper::cleanFilterList(filter));
+}
+
+void QQnxFileDialogHelper::setNameFilters(const QStringList &filters)
+{
+ qFileDialogHelperDebug() << Q_FUNC_INFO << "filters =" << filters;
+
+ Q_ASSERT(!filters.isEmpty());
+
+ 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 = filters.first();
+
+ // Cleanup
+ for (int i = 0; i < filters.size(); ++i)
+ delete[] globs[i];
+ delete[] globs;
+}
+
+QT_END_NAMESPACE