summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Faure <david.faure@kdab.com>2013-08-27 14:10:45 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-08-29 10:25:01 +0200
commitee9b9d9fd9a714f97ed8f7e26404c2f113588e9c (patch)
tree3cf5ef3432cf746fa395fee1ff104524a20da8b2
parent468b539935331e7cd2eda8e5d2eef07b8e5508e9 (diff)
QFileDialog: add MIME Type filters
Currently just a convenience method for setNameFilters(), it uses QMimeType to create a name filter from the glob patterns and description defined in each MIME type. In the longer term, this API could be used to do proper mimetype-based filtering using QMimeDatabase::mimeTypeForFile() in the builtin QFileDialog (aka "not native"), instead of only looking at globs via the name filters. Change-Id: I0edccf5f30c514481b47cd100d743d1ed7a24024 Reviewed-by: Frederik Gladhorn <frederik.gladhorn@digia.com>
-rw-r--r--src/gui/kernel/qplatformdialoghelper.cpp11
-rw-r--r--src/gui/kernel/qplatformdialoghelper.h3
-rw-r--r--src/widgets/dialogs/qfiledialog.cpp70
-rw-r--r--src/widgets/dialogs/qfiledialog.h4
-rw-r--r--src/widgets/doc/snippets/code/src_gui_dialogs_qfiledialog.cpp11
-rw-r--r--tests/manual/dialogs/filedialogpanel.cpp37
-rw-r--r--tests/manual/dialogs/filedialogpanel.h4
7 files changed, 135 insertions, 5 deletions
diff --git a/src/gui/kernel/qplatformdialoghelper.cpp b/src/gui/kernel/qplatformdialoghelper.cpp
index d9e9c4b17c..404700292c 100644
--- a/src/gui/kernel/qplatformdialoghelper.cpp
+++ b/src/gui/kernel/qplatformdialoghelper.cpp
@@ -359,6 +359,7 @@ public:
QDir::Filters filters;
QList<QUrl> sidebarUrls;
QStringList nameFilters;
+ QStringList mimeTypeFilters;
QString defaultSuffix;
QStringList history;
QUrl initialDirectory;
@@ -477,6 +478,16 @@ QStringList QFileDialogOptions::nameFilters() const
return d->nameFilters;
}
+void QFileDialogOptions::setMimeTypeFilters(const QStringList &filters)
+{
+ d->mimeTypeFilters = filters;
+}
+
+QStringList QFileDialogOptions::mimeTypeFilters() const
+{
+ return d->mimeTypeFilters;
+}
+
void QFileDialogOptions::setDefaultSuffix(const QString &suffix)
{
d->defaultSuffix = suffix;
diff --git a/src/gui/kernel/qplatformdialoghelper.h b/src/gui/kernel/qplatformdialoghelper.h
index 6d7d52ccb1..5269416ffd 100644
--- a/src/gui/kernel/qplatformdialoghelper.h
+++ b/src/gui/kernel/qplatformdialoghelper.h
@@ -265,6 +265,9 @@ public:
void setNameFilters(const QStringList &filters);
QStringList nameFilters() const;
+ void setMimeTypeFilters(const QStringList &filters);
+ QStringList mimeTypeFilters() const;
+
void setDefaultSuffix(const QString &suffix);
QString defaultSuffix() const;
diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp
index 9c4b99253a..62cec34b2b 100644
--- a/src/widgets/dialogs/qfiledialog.cpp
+++ b/src/widgets/dialogs/qfiledialog.cpp
@@ -57,6 +57,7 @@
#include <stdlib.h>
#include <qsettings.h>
#include <qdebug.h>
+#include <qmimedatabase.h>
#include <qapplication.h>
#include <qstylepainter.h>
#if !defined(Q_OS_WINCE)
@@ -1441,6 +1442,75 @@ void QFileDialog::setFilter(QDir::Filters filters)
d->showHiddenAction->setChecked((filters & QDir::Hidden));
}
+static QString nameFilterForMime(const QString &mimeType)
+{
+ QMimeDatabase db;
+ QMimeType mime(db.mimeTypeForName(mimeType));
+ if (mime.isValid()) {
+ if (mime.isDefault()) {
+ return QFileDialog::tr("All files (*)");
+ } else {
+ const QString patterns = mime.globPatterns().join(QLatin1Char(' '));
+ return mime.comment() + QStringLiteral(" (") + patterns + QLatin1Char(')');
+ }
+ }
+ return QString();
+}
+
+/*!
+ \since 5.2
+
+ Sets the \a filters used in the file dialog, from a list of MIME types.
+
+ Convenience method for setNameFilters().
+ Uses QMimeType to create a name filter from the glob patterns and description
+ defined in each MIME type.
+
+ Use application/octet-stream for the "All files (*)" filter, since that
+ is the base MIME type for all files.
+
+ Calling setMimeTypeFilters overrides any previously set name filters,
+ and changes the return value of nameFilters().
+
+ \snippet code/src_gui_dialogs_qfiledialog.cpp 13
+*/
+void QFileDialog::setMimeTypeFilters(const QStringList &filters)
+{
+ Q_D(QFileDialog);
+ QStringList nameFilters;
+ foreach (const QString &mimeType, filters) {
+ const QString text = nameFilterForMime(mimeType);
+ if (!text.isEmpty())
+ nameFilters.append(text);
+ }
+ setNameFilters(nameFilters);
+ d->options->setMimeTypeFilters(filters);
+}
+
+/*!
+ \since 5.2
+
+ Returns the MIME type filters that are in operation on this file
+ dialog.
+*/
+QStringList QFileDialog::mimeTypeFilters() const
+{
+ return d_func()->options->mimeTypeFilters();
+}
+
+/*!
+ \since 5.2
+
+ Sets the current MIME type \a filter.
+
+*/
+void QFileDialog::selectMimeTypeFilter(const QString &filter)
+{
+ const QString text = nameFilterForMime(filter);
+ if (!text.isEmpty())
+ selectNameFilter(text);
+}
+
/*!
\property QFileDialog::viewMode
\brief the way files and directories are displayed in the dialog
diff --git a/src/widgets/dialogs/qfiledialog.h b/src/widgets/dialogs/qfiledialog.h
index 5413a42ea9..404e16cde1 100644
--- a/src/widgets/dialogs/qfiledialog.h
+++ b/src/widgets/dialogs/qfiledialog.h
@@ -124,6 +124,10 @@ public:
void selectNameFilter(const QString &filter);
QString selectedNameFilter() const;
+ void setMimeTypeFilters(const QStringList &filters);
+ QStringList mimeTypeFilters() const;
+ void selectMimeTypeFilter(const QString &filter);
+
QDir::Filters filter() const;
void setFilter(QDir::Filters filters);
diff --git a/src/widgets/doc/snippets/code/src_gui_dialogs_qfiledialog.cpp b/src/widgets/doc/snippets/code/src_gui_dialogs_qfiledialog.cpp
index a253c09d8b..f0010b6f25 100644
--- a/src/widgets/doc/snippets/code/src_gui_dialogs_qfiledialog.cpp
+++ b/src/widgets/doc/snippets/code/src_gui_dialogs_qfiledialog.cpp
@@ -129,3 +129,14 @@ QString dir = QFileDialog::getExistingDirectory(this, tr("Open Directory"),
QFileDialog::ShowDirsOnly
| QFileDialog::DontResolveSymlinks);
//! [12]
+
+//! [13]
+QStringList mimeTypeFilters;
+mimeTypeFilters << "image/jpeg" // will show "JPEG image (*.jpeg *.jpg *.jpe)
+ << "image/png" // will show "PNG image (*.png)"
+ << "application/octet-stream"; // will show "All files (*)"
+
+QFileDialog dialog(this);
+dialog.setMimeTypeFilters(mimeTypeFilters);
+dialog.exec();
+//! [13]
diff --git a/tests/manual/dialogs/filedialogpanel.cpp b/tests/manual/dialogs/filedialogpanel.cpp
index 000d755cef..e234835cdb 100644
--- a/tests/manual/dialogs/filedialogpanel.cpp
+++ b/tests/manual/dialogs/filedialogpanel.cpp
@@ -162,6 +162,7 @@ FileDialogPanel::FileDialogPanel(QWidget *parent)
, m_defaultSuffix(new QLineEdit(this))
, m_directory(new QLineEdit(this))
, m_selectedFileName(new QLineEdit(this))
+ , m_useMimeTypeFilters(new QCheckBox(this))
, m_nameFilters(new QPlainTextEdit)
, m_selectedNameFilter(new QLineEdit(this))
, m_deleteNonModalDialogButton(0)
@@ -183,10 +184,11 @@ FileDialogPanel::FileDialogPanel(QWidget *parent)
// Files
QGroupBox *filesGroupBox = new QGroupBox(tr("Files / Filters"));
- QFormLayout *filesLayout = new QFormLayout(filesGroupBox);
+ filesLayout = new QFormLayout(filesGroupBox);
filesLayout->addRow(tr("Default Suffix:"), m_defaultSuffix);
filesLayout->addRow(tr("Directory:"), m_directory);
filesLayout->addRow(tr("Selected file:"), m_selectedFileName);
+ filesLayout->addRow(tr("Use mime type filters:"), m_useMimeTypeFilters);
m_nameFilters->setMaximumHeight(80);
filesLayout->addRow(tr("Name filters:"), m_nameFilters);
filesLayout->addRow(tr("Selected name filter:"), m_selectedNameFilter);
@@ -236,6 +238,8 @@ FileDialogPanel::FileDialogPanel(QWidget *parent)
gridLayout->addWidget(labelsGroupBox, 1, 0);
gridLayout->addWidget(buttonsGroupBox, 1, 1);
+ connect(m_useMimeTypeFilters, SIGNAL(toggled(bool)), this, SLOT(useMimeTypeFilters(bool)));
+
enableDeleteModalDialogButton();
enableDeleteNonModalDialogButton();
restoreDefaults();
@@ -461,7 +465,8 @@ void FileDialogPanel::restoreDefaults()
m_customDirIcons->setChecked(d.testOption(QFileDialog::DontUseCustomDirectoryIcons));
m_directory->setText(QDir::homePath());
m_defaultSuffix->setText(QLatin1String("txt"));
- m_nameFilters->setPlainText(QLatin1String("Any files (*)\nImage files (*.png *.xpm *.jpg)\nText files (*.txt)"));
+ m_useMimeTypeFilters->setChecked(false);
+ useMimeTypeFilters(false);
m_selectedFileName->setText(QString());
m_selectedNameFilter->setText(QString());
foreach (LabelLineEdit *l, m_labelLineEdits)
@@ -481,14 +486,36 @@ void FileDialogPanel::applySettings(QFileDialog *d) const
const QString file = m_selectedFileName->text().trimmed();
if (!file.isEmpty())
d->selectFile(file);
- d->setNameFilters(m_nameFilters->toPlainText().trimmed().split(QLatin1Char('\n'), QString::SkipEmptyParts));
const QString filter = m_selectedNameFilter->text().trimmed();
- if (!filter.isEmpty())
- d->selectNameFilter(filter);
+ const QStringList filters = m_nameFilters->toPlainText().trimmed().split(QLatin1Char('\n'), QString::SkipEmptyParts);
+ if (!m_useMimeTypeFilters->isChecked()) {
+ d->setNameFilters(filters);
+ if (!filter.isEmpty())
+ d->selectNameFilter(filter);
+ } else {
+ d->setMimeTypeFilters(filters);
+ if (!filter.isEmpty())
+ d->selectMimeTypeFilter(filter);
+ }
foreach (LabelLineEdit *l, m_labelLineEdits)
l->apply(d);
}
+void FileDialogPanel::useMimeTypeFilters(bool b)
+{
+ QWidget *textEdit = filesLayout->labelForField(m_nameFilters);
+ if (QLabel *label = qobject_cast<QLabel *>(textEdit))
+ label->setText(b ? tr("Mime type filters:") : tr("Name filters:"));
+ QWidget *w = filesLayout->labelForField(m_selectedNameFilter);
+ if (QLabel *label = qobject_cast<QLabel *>(w))
+ label->setText(b ? tr("Selected mime type filter:") : tr("Selected name filter:"));
+
+ if (b)
+ m_nameFilters->setPlainText(QLatin1String("image/jpeg\nimage/png\ntext/plain\napplication/octet-stream"));
+ else
+ m_nameFilters->setPlainText(QLatin1String("Any files (*)\nImage files (*.png *.xpm *.jpg)\nText files (*.txt)"));
+}
+
void FileDialogPanel::accepted()
{
const QFileDialog *d = qobject_cast<const QFileDialog *>(sender());
diff --git a/tests/manual/dialogs/filedialogpanel.h b/tests/manual/dialogs/filedialogpanel.h
index 2e1d5d4de9..1e86e0f18e 100644
--- a/tests/manual/dialogs/filedialogpanel.h
+++ b/tests/manual/dialogs/filedialogpanel.h
@@ -52,6 +52,7 @@ class QCheckBox;
class QComboBox;
class QLineEdit;
class QPlainTextEdit;
+class QFormLayout;
QT_END_NAMESPACE
class LabelLineEdit;
@@ -82,6 +83,7 @@ public slots:
private slots:
void enableDeleteNonModalDialogButton();
void enableDeleteModalDialogButton();
+ void useMimeTypeFilters(bool);
private:
QString filterString() const;
@@ -89,6 +91,7 @@ private:
QStringList allowedSchemes() const;
void applySettings(QFileDialog *d) const;
+ QFormLayout *filesLayout;
QCheckBox *m_readOnly;
QCheckBox *m_confirmOverWrite;
QCheckBox *m_nameFilterDetailsVisible;
@@ -103,6 +106,7 @@ private:
QLineEdit *m_directory;
QLineEdit *m_selectedFileName;
QList<LabelLineEdit *> m_labelLineEdits;
+ QCheckBox *m_useMimeTypeFilters;
QPlainTextEdit *m_nameFilters;
QLineEdit *m_selectedNameFilter;
QPushButton *m_deleteNonModalDialogButton;