1
/***************************************************************************
3
** Copyright (C) 2012 Research In Motion
4
** Contact: http://www.qt-project.org/legal
6
** This file is part of the plugins of the Qt Toolkit.
8
** $QT_BEGIN_LICENSE:LGPL$
9
** Commercial License Usage
10
** Licensees holding valid commercial Qt licenses may use this file in
11
** accordance with the commercial license agreement provided with the
12
** Software or, alternatively, in accordance with the terms contained in
13
** a written agreement between you and Digia. For licensing terms and
14
** conditions see http://qt.digia.com/licensing. For further information
15
** use the contact form at http://qt.digia.com/contact-us.
17
** GNU Lesser General Public License Usage
18
** Alternatively, this file may be used under the terms of the GNU Lesser
19
** General Public License version 2.1 as published by the Free Software
20
** Foundation and appearing in the file LICENSE.LGPL included in the
21
** packaging of this file. Please review the following information to
22
** ensure the GNU Lesser General Public License version 2.1 requirements
23
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25
** In addition, as a special exception, Digia gives you certain additional
26
** rights. These rights are described in the Digia Qt LGPL Exception
27
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29
** GNU General Public License Usage
30
** Alternatively, this file may be used under the terms of the GNU
31
** General Public License version 3.0 as published by the Free Software
32
** Foundation and appearing in the file LICENSE.GPL included in the
33
** packaging of this file. Please review the following information to
34
** ensure the GNU General Public License version 3.0 requirements will be
35
** met: http://www.gnu.org/copyleft/gpl.html.
40
****************************************************************************/
42
#include "qqnxfiledialoghelper.h"
44
#include "qqnxbpseventfilter.h"
45
#include "qqnxscreen.h"
46
#include "qqnxintegration.h"
54
#ifdef QQNXFILEDIALOGHELPER_DEBUG
55
#define qFileDialogHelperDebug qDebug
57
#define qFileDialogHelperDebug QT_NO_QDEBUG_MACRO
62
QQnxFileDialogHelper::QQnxFileDialogHelper(const QQnxIntegration *integration)
63
: QPlatformFileDialogHelper(),
64
m_integration(integration),
66
m_acceptMode(QFileDialogOptions::AcceptOpen),
68
m_result(QPlatformDialogHelper::Rejected),
73
QQnxFileDialogHelper::~QQnxFileDialogHelper()
76
dialog_destroy(m_dialog);
79
bool QQnxFileDialogHelper::handleEvent(bps_event_t *event)
81
qFileDialogHelperDebug() << Q_FUNC_INFO;
83
// Check dialog event response type (OK vs CANCEL)
84
// CANCEL => index = 0
86
int index = dialog_event_get_selected_index(event);
87
qFileDialogHelperDebug() << "Index =" << index;
89
m_result = QPlatformDialogHelper::Accepted;
91
if (m_acceptMode == QFileDialogOptions::AcceptOpen) {
94
// ###TODO Check that this actually gets multiple paths and cleans up properly
97
int result = dialog_event_get_filebrowse_filepaths(event, &filePaths, &pathCount);
98
if (result != BPS_SUCCESS) {
99
qWarning() << "Could not get paths from native file dialog";
103
for (int i = 0; i < pathCount; ++i) {
104
QString path = QFile::decodeName(filePaths[i]);
105
m_paths.append(path);
106
qFileDialogHelperDebug() << "path =" << path;
112
const char *filePath = dialog_event_get_filesave_filepath(event);
113
QString path = QFile::decodeName(filePath);
114
qFileDialogHelperDebug() << "path =" << path;
115
m_paths.append(path);
118
m_result = QPlatformDialogHelper::Rejected;
126
void QQnxFileDialogHelper::exec()
128
qFileDialogHelperDebug() << Q_FUNC_INFO;
130
// Clear any previous results
134
connect(this, SIGNAL(dialogClosed()), &loop, SLOT(quit()));
137
if (m_result == QPlatformDialogHelper::Accepted)
143
bool QQnxFileDialogHelper::show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent)
146
qFileDialogHelperDebug() << Q_FUNC_INFO;
148
QQnxBpsEventFilter *eventFilter = m_integration->bpsEventFilter();
149
// We *really* need the bps event filter ;)
153
// Native dialogs can only handle application modal use cases so far
154
if (modality != Qt::ApplicationModal)
157
// Tear down any existing dialog and start again as dialog mode may have changed
159
dialog_destroy(m_dialog);
164
const QSharedPointer<QFileDialogOptions> &opts = options();
165
if (opts->acceptMode() == QFileDialogOptions::AcceptOpen) {
166
if (dialog_create_filebrowse(&m_dialog) != BPS_SUCCESS) {
167
qWarning("dialog_create_filebrowse failed");
171
// Select one or many files?
172
bool multiSelect = (opts->fileMode() == QFileDialogOptions::ExistingFiles);
173
dialog_set_filebrowse_multiselect(m_dialog, multiSelect);
175
// Set the actual list of extensions
176
if (!opts->nameFilters().isEmpty()) {
177
qFileDialogHelperDebug() << "nameFilters =" << opts->nameFilters();
178
setNameFilter(opts->nameFilters().first());
180
QString defaultNameFilter = QStringLiteral("*.*");
181
setNameFilter(defaultNameFilter);
184
if (dialog_create_filesave(&m_dialog) != BPS_SUCCESS) {
185
qWarning("dialog_create_filesave failed");
189
// Maybe pre-select a filename
190
if (!opts->initiallySelectedFiles().isEmpty()) {
191
QString fileName = opts->initiallySelectedFiles().first();
192
dialog_set_filesave_filename(m_dialog, QFile::encodeName(fileName).constData());
195
// Add OK and Cancel buttons. We add the buttons in the order "CANCEL" followed by "OK
196
// such that they have indices matching the buttons on the file open dialog which
197
// is automatically populated with buttons.
198
if (dialog_add_button(m_dialog, tr("CANCEL").toLocal8Bit().constData(), true, 0, true) != BPS_SUCCESS) {
199
qWarning("dialog_add_button failed");
203
if (dialog_add_button(m_dialog, tr("OK").toLocal8Bit().constData(), true, 0, true) != BPS_SUCCESS) {
204
qWarning("dialog_add_button failed");
209
// Cache the accept mode so we know which functions to use to get the results back
210
m_acceptMode = opts->acceptMode();
212
// Set the libscreen window group and common properties
214
QQnxScreen *nativeScreen = parent ? static_cast<QQnxScreen *>(parent->screen()->handle()) :
215
m_integration->primaryDisplay();
216
Q_ASSERT(nativeScreen);
217
dialog_set_group_id(m_dialog, nativeScreen->windowGroupName());
218
dialog_set_title_text(m_dialog, opts->windowTitle().toLocal8Bit().constData());
220
// Register ourselves for dialog domain events from bps
221
eventFilter->registerForDialogEvents(this);
224
dialog_show(m_dialog);
229
void QQnxFileDialogHelper::hide()
231
qFileDialogHelperDebug() << Q_FUNC_INFO;
234
dialog_cancel(m_dialog);
237
bool QQnxFileDialogHelper::defaultNameFilterDisables() const
239
qFileDialogHelperDebug() << Q_FUNC_INFO;
243
void QQnxFileDialogHelper::setDirectory(const QString &directory)
245
qFileDialogHelperDebug() << Q_FUNC_INFO << "directory =" << directory;
246
// No native API for setting the directory(!). The best we can do is to
247
// set it as the file name but even then only with a file save dialog.
248
if (m_dialog && m_acceptMode == QFileDialogOptions::AcceptSave)
249
dialog_set_filesave_filename(m_dialog, QFile::encodeName(directory).constData());
252
QString QQnxFileDialogHelper::directory() const
254
qFileDialogHelperDebug() << Q_FUNC_INFO;
255
return m_paths.first();
258
void QQnxFileDialogHelper::selectFile(const QString &fileName)
260
qFileDialogHelperDebug() << Q_FUNC_INFO << "filename =" << fileName;
261
if (m_dialog && m_acceptMode == QFileDialogOptions::AcceptSave)
262
dialog_set_filesave_filename(m_dialog, QFile::encodeName(fileName).constData());
265
QStringList QQnxFileDialogHelper::selectedFiles() const
267
qFileDialogHelperDebug() << Q_FUNC_INFO;
271
void QQnxFileDialogHelper::setFilter()
273
// No native api to support setting a filter from QDir::Filters
274
qFileDialogHelperDebug() << Q_FUNC_INFO;
277
void QQnxFileDialogHelper::selectNameFilter(const QString &filter)
279
qFileDialogHelperDebug() << Q_FUNC_INFO << "filter =" << filter;
280
setNameFilter(filter);
283
QString QQnxFileDialogHelper::selectedNameFilter() const
285
// For now there is no way for the user to change the selected filter
286
// so this just reflects what the developer has set programmatically.
287
qFileDialogHelperDebug() << Q_FUNC_INFO;
288
return m_selectedFilter;
291
void QQnxFileDialogHelper::setNameFilter(const QString &filter)
293
qFileDialogHelperDebug() << Q_FUNC_INFO << "filter =" << filter;
295
// Extract the globbing expressions
296
QStringList filters = QPlatformFileDialogHelper::cleanFilterList(filter);
297
char **globs = new char*[filters.size()];
298
for (int i = 0; i < filters.size(); ++i) {
299
QByteArray glob = filters.at(i).toLocal8Bit();
300
globs[i] = new char[glob.length()];
301
strcpy(globs[i], glob.constData());
305
dialog_set_filebrowse_filter(m_dialog, const_cast<const char**>(globs), filters.size());
306
m_selectedFilter = filter;
309
for (int i = 0; i < filters.size(); ++i)