DevCybran DevCybran - 11 months ago 120
C++ Question

QFileDialog combine MIME type filters to "All formats"

I am using Qt 5.9 to open a file dialog asking the user to select an image file:

QStringList mimeTypeFilters;
const QByteArrayList supportedMimeTypes = QImageReader::supportedMimeTypes();
foreach(const QByteArray& mimeTypeName, supportedMimeTypes) {
mimeTypeFilters.append(mimeTypeName);
}
mimeTypeFilters.sort();

QFileDialog* fileDialog = new QFileDialog(this, "Select image");
fileDialog->setMimeTypeFilters(mimeTypeFilters);
fileDialog->setFileMode(QFileDialog::ExistingFile);
fileDialog->exec();


All supported image formats are added as MIME type filters to the dialog, which is working quite well. However, I want to add an additional filter (such as "All formats" or "All supported") that allows the user to select an image of ANY of the supported formats, as selecting the correct format prior to selecting the image is quite tedious. What is the most elegant solution to achieve this, without subclassing any of the involved Qt classes?

Answer Source

Thanks to SteakOverflow's comment, here is the solution I came up with:

// get supported image file types
QStringList mimeTypeFilters;
const QByteArrayList supportedMimeTypes = QImageReader::supportedMimeTypes();
foreach(const QByteArray& mimeTypeName, supportedMimeTypes) {
    mimeTypeFilters.append(mimeTypeName);
}
mimeTypeFilters.sort(Qt::CaseInsensitive);

// compose filter for all supported types
QMimeDatabase mimeDB;
QStringList allSupportedFormats;
for(const QString& mimeTypeFilter: mimeTypeFilters) {
    QMimeType mimeType = mimeDB.mimeTypeForName(mimeTypeFilter);
    if(mimeType.isValid()) {
        allSupportedFormats.append(mimeType.globPatterns());
    }
}
QString allSupportedFormatsFilter = QString("All supported formats (%1)").arg(allSupportedFormats.join(' '));

QFileDialog* fileDialog = new QFileDialog(this, "Select image");
fileDialog->setFileMode(QFileDialog::ExistingFile);
fileDialog->setMimeTypeFilters(mimeTypeFilters);
QStringList nameFilters = fileDialog->nameFilters();
nameFilters.append(allSupportedFormatsFilter);
fileDialog->setNameFilters(nameFilters);
fileDialog->selectNameFilter(allSupportedFormatsFilter);

It is basically the same implementation QFileDialog uses internally to convert mime type filters to name filters. The new name filter for all supported formats will be added at the bottom of the filter list and pre-selected. The filter string is quite long and not fully visible in the dialog at once, but will become fully visible once the user opens the drop-down menu.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download