diff options
Diffstat (limited to 'src/plugins/platforms')
-rw-r--r-- | src/plugins/platforms/qnx/qnx.pro | 7 | ||||
-rw-r--r-- | src/plugins/platforms/qnx/qqnxbpseventfilter.cpp | 24 | ||||
-rw-r--r-- | src/plugins/platforms/qnx/qqnxbpseventfilter.h | 8 | ||||
-rw-r--r-- | src/plugins/platforms/qnx/qqnxfiledialoghelper.cpp | 309 | ||||
-rw-r--r-- | src/plugins/platforms/qnx/qqnxfiledialoghelper.h | 95 | ||||
-rw-r--r-- | src/plugins/platforms/qnx/qqnxintegration.cpp | 2 | ||||
-rw-r--r-- | src/plugins/platforms/qnx/qqnxintegration.h | 2 | ||||
-rw-r--r-- | src/plugins/platforms/qnx/qqnxtheme.cpp | 38 | ||||
-rw-r--r-- | src/plugins/platforms/qnx/qqnxtheme.h | 8 |
9 files changed, 487 insertions, 6 deletions
diff --git a/src/plugins/platforms/qnx/qnx.pro b/src/plugins/platforms/qnx/qnx.pro index f9af954755..7c25707fa4 100644 --- a/src/plugins/platforms/qnx/qnx.pro +++ b/src/plugins/platforms/qnx/qnx.pro @@ -22,6 +22,7 @@ CONFIG(blackberry) { #DEFINES += QQNXBPSEVENTFILTER_DEBUG #DEFINES += QQNXBUFFER_DEBUG #DEFINES += QQNXCLIPBOARD_DEBUG +#DEFINES += QQNXFILEDIALOGHELPER_DEBUG #DEFINES += QQNXGLBACKINGSTORE_DEBUG #DEFINES += QQNXGLCONTEXT_DEBUG #DEFINES += QQNXINPUTCONTEXT_DEBUG @@ -88,14 +89,16 @@ CONFIG(blackberry) { qqnxbpseventfilter.cpp \ qqnxvirtualkeyboardbps.cpp \ qqnxtheme.cpp \ - qqnxsystemsettings.cpp + qqnxsystemsettings.cpp \ + qqnxfiledialoghelper.cpp HEADERS += qqnxnavigatorbps.h \ qqnxeventdispatcher_blackberry.h \ qqnxbpseventfilter.h \ qqnxvirtualkeyboardbps.h \ qqnxtheme.h \ - qqnxsystemsettings.h + qqnxsystemsettings.h \ + qqnxfiledialoghelper.h LIBS += -lbps } diff --git a/src/plugins/platforms/qnx/qqnxbpseventfilter.cpp b/src/plugins/platforms/qnx/qqnxbpseventfilter.cpp index f5185e3eb7..fd1bfd333e 100644 --- a/src/plugins/platforms/qnx/qqnxbpseventfilter.cpp +++ b/src/plugins/platforms/qnx/qqnxbpseventfilter.cpp @@ -41,6 +41,7 @@ #include "qqnxbpseventfilter.h" #include "qqnxnavigatoreventhandler.h" +#include "qqnxfiledialoghelper.h" #include "qqnxscreen.h" #include "qqnxscreeneventhandler.h" #include "qqnxvirtualkeyboardbps.h" @@ -110,6 +111,22 @@ void QQnxBpsEventFilter::unregisterForScreenEvents(QQnxScreen *screen) qWarning("QQNX: failed to unregister for screen events on screen %p", screen->nativeContext()); } +void QQnxBpsEventFilter::registerForDialogEvents(QQnxFileDialogHelper *dialog) +{ + if (dialog_request_events(0) != BPS_SUCCESS) + qWarning("QQNX: failed to register for dialog events"); + dialog_instance_t nativeDialog = dialog->nativeDialog(); + if (!m_dialogMapper.contains(nativeDialog)) + m_dialogMapper.insert(nativeDialog, dialog); +} + +void QQnxBpsEventFilter::unregisterForDialogEvents(QQnxFileDialogHelper *dialog) +{ + int count = m_dialogMapper.remove(dialog->nativeDialog()); + if (count == 0) + qWarning("QQNX: attempting to unregister dialog that was not registered"); +} + bool QQnxBpsEventFilter::dispatcherEventFilter(void *message) { qBpsEventFilterDebug() << Q_FUNC_INFO; @@ -131,6 +148,13 @@ bool QQnxBpsEventFilter::bpsEventFilter(bps_event_t *event) return m_screenEventHandler->handleEvent(screenEvent); } + 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); + } + 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 215027e8e6..aafca0f989 100644 --- a/src/plugins/platforms/qnx/qqnxbpseventfilter.h +++ b/src/plugins/platforms/qnx/qqnxbpseventfilter.h @@ -43,6 +43,9 @@ #define QQNXBPSEVENTFILTER_H #include <QObject> +#include <QHash> + +#include <bps/dialog.h> struct bps_event_t; @@ -50,6 +53,7 @@ QT_BEGIN_NAMESPACE class QAbstractEventDispatcher; class QQnxNavigatorEventHandler; +class QQnxFileDialogHelper; class QQnxScreen; class QQnxScreenEventHandler; class QQnxVirtualKeyboardBps; @@ -68,6 +72,9 @@ public: void registerForScreenEvents(QQnxScreen *screen); void unregisterForScreenEvents(QQnxScreen *screen); + void registerForDialogEvents(QQnxFileDialogHelper *dialog); + void unregisterForDialogEvents(QQnxFileDialogHelper *dialog); + private: static bool dispatcherEventFilter(void *message); bool bpsEventFilter(bps_event_t *event); @@ -78,6 +85,7 @@ private: QQnxNavigatorEventHandler *m_navigatorEventHandler; QQnxScreenEventHandler *m_screenEventHandler; QQnxVirtualKeyboardBps *m_virtualKeyboard; + QHash<dialog_instance_t, QQnxFileDialogHelper*> m_dialogMapper; }; QT_END_NAMESPACE 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 diff --git a/src/plugins/platforms/qnx/qqnxfiledialoghelper.h b/src/plugins/platforms/qnx/qqnxfiledialoghelper.h new file mode 100644 index 0000000000..9b05da2cd0 --- /dev/null +++ b/src/plugins/platforms/qnx/qqnxfiledialoghelper.h @@ -0,0 +1,95 @@ +/*************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef QQNXFILEDIALOGHELPER_H +#define QQNXFILEDIALOGHELPER_H + +#include <qpa/qplatformdialoghelper.h> + +#include <bps/dialog.h> + +QT_BEGIN_NAMESPACE + +class QQnxBpsEventFilter; + +class QQnxFileDialogHelper : public QPlatformFileDialogHelper +{ + Q_OBJECT +public: + explicit QQnxFileDialogHelper(QQnxBpsEventFilter *eventFilter); + ~QQnxFileDialogHelper(); + + bool handleEvent(bps_event_t *event); + + void exec(); + + bool show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent); + void hide(); + + bool defaultNameFilterDisables() const; + void setDirectory(const QString &directory); + QString directory() const; + void selectFile(const QString &fileName); + QStringList selectedFiles() const; + void setFilter(); + void selectNameFilter(const QString &filter); + QString selectedNameFilter() const; + + dialog_instance_t nativeDialog() const { return m_dialog; } + +Q_SIGNALS: + void dialogClosed(); + +private: + void setNameFilter(const QString &filter); + + QQnxBpsEventFilter *m_eventFilter; + dialog_instance_t m_dialog; + QFileDialogOptions::AcceptMode m_acceptMode; + QString m_selectedFilter; + + QPlatformDialogHelper::DialogCode m_result; + QStringList m_paths; +}; + +QT_END_NAMESPACE + +#endif // QQNXFILEDIALOGHELPER_H diff --git a/src/plugins/platforms/qnx/qqnxintegration.cpp b/src/plugins/platforms/qnx/qqnxintegration.cpp index e6e99d2243..eb95f2d1bd 100644 --- a/src/plugins/platforms/qnx/qqnxintegration.cpp +++ b/src/plugins/platforms/qnx/qqnxintegration.cpp @@ -382,7 +382,7 @@ QPlatformTheme *QQnxIntegration::createPlatformTheme(const QString &name) const { qIntegrationDebug() << Q_FUNC_INFO << "name =" << name; if (name == QQnxTheme::name()) - return new QQnxTheme(m_fontDatabase); + return new QQnxTheme(m_fontDatabase, m_bpsEventFilter); return QPlatformIntegration::createPlatformTheme(name); } #endif diff --git a/src/plugins/platforms/qnx/qqnxintegration.h b/src/plugins/platforms/qnx/qqnxintegration.h index 6820dc1e40..96825679e0 100644 --- a/src/plugins/platforms/qnx/qqnxintegration.h +++ b/src/plugins/platforms/qnx/qqnxintegration.h @@ -52,6 +52,7 @@ QT_BEGIN_NAMESPACE class QQnxBpsEventFilter; class QQnxScreenEventThread; +class QQnxFileDialogHelper; class QQnxNativeInterface; class QQnxWindow; class QQnxScreen; @@ -115,6 +116,7 @@ public: #if defined(Q_OS_BLACKBERRY) QStringList themeNames() const; QPlatformTheme *createPlatformTheme(const QString &name) const; + QQnxBpsEventFilter *bpsEventFilter() const { return m_bpsEventFilter; } #endif static QWindow *window(screen_window_t qnxWindow); diff --git a/src/plugins/platforms/qnx/qqnxtheme.cpp b/src/plugins/platforms/qnx/qqnxtheme.cpp index cd82e0c0c9..472f47141c 100644 --- a/src/plugins/platforms/qnx/qqnxtheme.cpp +++ b/src/plugins/platforms/qnx/qqnxtheme.cpp @@ -41,12 +41,15 @@ #include "qqnxtheme.h" +#include "qqnxfiledialoghelper.h" #include "qqnxsystemsettings.h" QT_BEGIN_NAMESPACE -QQnxTheme::QQnxTheme(QPlatformFontDatabase *fontDatabase) - : m_fontDatabase(fontDatabase) +QQnxTheme::QQnxTheme(QPlatformFontDatabase *fontDatabase, + QQnxBpsEventFilter *eventFilter) + : m_fontDatabase(fontDatabase), + m_eventFilter(eventFilter) { } @@ -55,6 +58,37 @@ QQnxTheme::~QQnxTheme() qDeleteAll(m_fonts); } +bool QQnxTheme::usePlatformNativeDialog(DialogType type) const +{ + if (type == QPlatformTheme::FileDialog) + return true; +#if !defined(QT_NO_COLORDIALOG) + if (type == QPlatformTheme::ColorDialog) + return false; +#endif +#if !defined(QT_NO_FONTDIALOG) + if (type == QPlatformTheme::FontDialog) + return false; +#endif + return false; +} + +QPlatformDialogHelper *QQnxTheme::createPlatformDialogHelper(DialogType type) const +{ + switch (type) { + case QPlatformTheme::FileDialog: + return new QQnxFileDialogHelper(m_eventFilter); +#ifndef QT_NO_COLORDIALOG + case QPlatformTheme::ColorDialog: +#endif +#ifndef QT_NO_FONTDIALOG + case QPlatformTheme::FontDialog: +#endif + default: + return 0; + } +} + const QFont *QQnxTheme::font(Font type) const { if (m_fonts.isEmpty() && m_fontDatabase) diff --git a/src/plugins/platforms/qnx/qqnxtheme.h b/src/plugins/platforms/qnx/qqnxtheme.h index dc9c7bef44..c2c81a5d9a 100644 --- a/src/plugins/platforms/qnx/qqnxtheme.h +++ b/src/plugins/platforms/qnx/qqnxtheme.h @@ -51,20 +51,26 @@ QT_BEGIN_NAMESPACE +class QQnxBpsEventFilter; + class QPlatformFontDatabase; class QQnxTheme : public QPlatformTheme { public: - QQnxTheme(QPlatformFontDatabase *fontDatabase); + QQnxTheme(QPlatformFontDatabase *fontDatabase, QQnxBpsEventFilter *eventFilter); ~QQnxTheme(); static QString name() { return QStringLiteral("blackberry"); } + bool usePlatformNativeDialog(DialogType type) const; + QPlatformDialogHelper *createPlatformDialogHelper(DialogType type) const; + const QFont *font(Font type = SystemFont) const; private: QPlatformFontDatabase *m_fontDatabase; + QQnxBpsEventFilter *m_eventFilter; mutable QHash<QPlatformTheme::Font, QFont*> m_fonts; }; |