void QQnxFileDialogHelper::hide()
{
    qFileDialogHelperDebug() << Q_FUNC_INFO;
    if (!m_dialog)
        return;
    dialog_cancel(m_dialog);
}
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;
}
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()) {
            QStringList files;
            Q_FOREACH ( const QUrl &url, opts->initiallySelectedFiles() )
                files.append(url.toLocalFile());
            m_dialog->setDefaultSaveFileNames(files);
        }
    }
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::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());
}
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();
}
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();
}
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;
}
void QQnxFileDialogHelper::setNameFilter(const QString &filter)
{
    qFileDialogHelperDebug() << Q_FUNC_INFO << "filter =" << filter;
    setNameFilters(QPlatformFileDialogHelper::cleanFilterList(filter));
}
void QQnxFileDialogHelper::selectNameFilter(const QString &filter)
{
    qFileDialogHelperDebug() << Q_FUNC_INFO << "filter =" << filter;
    setNameFilter(filter);
}
void QQnxFileDialogHelper::setFilter()
{
    // No native api to support setting a filter from QDir::Filters
    qFileDialogHelperDebug() << Q_FUNC_INFO;
}
QList<QUrl> QQnxFileDialogHelper::selectedFiles() const
{
    qFileDialogHelperDebug() << Q_FUNC_INFO;
    return m_paths;
}
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());
}
QUrl QQnxFileDialogHelper::directory() const
{
    qFileDialogHelperDebug() << Q_FUNC_INFO;
    return m_paths.first();
}
bool QQnxFileDialogHelper::defaultNameFilterDisables() const
{
    qFileDialogHelperDebug() << Q_FUNC_INFO;
    return false;
}
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;
}