add test for QFileDialog::getExistingDirectory / bug?

Dominik Haumann dhaumann at kde.org
Tue Feb 4 15:00:38 UTC 2014


On Sunday 26 January 2014 18:53:42 Gregor Mi wrote:
> With another addition to qfiledialogtest in
> frameworks/frameworkintegration another potential bug can be exposed:
> 
> Calling
> 
> $ ./qfiledialogtest --nameFilter "c (*.cpp)" --nameFilter "h (*.h)"
> --selectNameFilter "h (*.h)"
> 
> does not select the second filter. Can this be confirmed or maybe I am
> using the API wrong?

Ok, so with respect to this test, here is what happens:

the `qfieldialogtest` calls

    dialog.setNameFilters(nameFilterList);     // list = ("c (*.cpp)", "h (*.h)")   
    dialog.selectNameFilter(selectNameFilter); // filter = "h (*.h)"

dialog.setNameFilters() is a QFileDialog function that calls 

void QFileDialog::setNameFilters(const QStringList &filters)
{
    // [...]
    d->options->setNameFilters(cleanedFilters);

    if (!d->usingWidgets())                    // this evaluates to 'true', since we
        return;                                // use the QPA

So at this point, the QFileDialogOptions class has the named filters set correctly.


Finally, the `qfieldialogtest` calls:

    dialog.exec();

And here comes the initeresting part: At this point, the KDEPlatformFileDialogHelper is
finally shown, through the function

bool KDEPlatformFileDialogHelper::show(...)
{
    initializeDialog();
    // ...
    return true;
}

So initializeDialog() is only called right before the dialog gets visible.
This function looks like this:

void KDEPlatformFileDialogHelper::initializeDialog()
{
    // ...

    QStringList nameFilters = options()->nameFilters();
    m_dialog->m_fileWidget->setFilter(qt2KdeFilter(nameFilters));
}

So only now are the nameFilters from options() put into the fileWidget, which
means at the time
    dialog.selectNameFilter(selectNameFilter); // filter = "h (*.h)"
is called (see `qfieldialogtest`), the combo box is not yet filled with the
items, and therewith setting the current index prior to calling dialog.exec()
or dialog.show() always fails.


I don't think this is how it is intended.

A possible workaround would be to to apply this patch to QFileDialog::selectNameFilter():

void QFileDialog::selectNameFilter(const QString &filter)
{
    Q_D(QFileDialog);
    if (!d->usingWidgets()) {
+       d->options->setInitiallySelectedNameFilter(filter);
        d->selectNameFilter_sys(filter);
        return;
    }

And then putting into

void KDEPlatformFileDialogHelper::initializeDialog()
{
    // ...

    if (!options()->initiallySelectedNameFilter().isEmpty()) {
        m_dialog->selectNameFilter(options()->initiallySelectedNameFilter());
    }

Can someone confirm this (patch in Qt, patch in framrworksintegration) is the
correct fix for this?


I'm a bit surprised about this API right now, since this implies

    dialog.setNameFilters("h (*.h), c (*.c)");
    dialog.selectNameFilter("h (*.h)");
    QString filter = dialog.selectedNameFilter(); // filter.isEmpty() == true

i.e., the code behaves totally different to what one would expect.
Is this the desired QPA API in KF5, or do I mess things up? ;)

Greetings,
Dominik


More information about the Kde-frameworks-devel mailing list