Implement QAbstractFileIconProvider to use theme and mime databases

This doesn't give useful defaults on all platforms; icon themes are not
provided on platforms other than Linux, and the mime database doesn't
always return user-friendly names based on file names.

However, both icon themes and the mime database can be customized by
application developers by shipping a data file side-by-side with the
application, without the need for reimplementing the provider class.

Change-Id: Ie4b18ac1b861e2da64f01d1f209986b27fbe6bd5
Task-number: QTBUG-66177
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
Volker Hilsheimer 2020-08-24 11:31:13 +02:00
parent 2cb8568ab2
commit 872e37b2ff
3 changed files with 42 additions and 14 deletions

View File

@ -40,6 +40,10 @@
#include "qabstractfileiconprovider.h" #include "qabstractfileiconprovider.h"
#include <qguiapplication.h> #include <qguiapplication.h>
#include <qicon.h>
#include <qmimedatabase.h>
#include <private/qabstractfileiconprovider_p.h> #include <private/qabstractfileiconprovider_p.h>
#include <private/qfilesystementry_p.h> #include <private/qfilesystementry_p.h>
@ -127,23 +131,50 @@ QAbstractFileIconProvider::Options QAbstractFileIconProvider::options() const
} }
/*! /*!
Returns an icon set for the given \a type. Returns an icon set for the given \a type, using the current
icon theme.
\sa QIcon::fromTheme
*/ */
QIcon QAbstractFileIconProvider::icon(IconType type) const QIcon QAbstractFileIconProvider::icon(IconType type) const
{ {
Q_UNUSED(type); Q_UNUSED(type);
return {}; switch (type) {
case Computer:
return QIcon::fromTheme(QLatin1String("computer"));
case Desktop:
return QIcon::fromTheme(QLatin1String("user-desktop"));
case Trashcan:
return QIcon::fromTheme(QLatin1String("user-trash"));
case Network:
return QIcon::fromTheme(QLatin1String("network-workgroup"));
case Drive:
return QIcon::fromTheme(QLatin1String("drive-harddisk"));
case Folder:
return QIcon::fromTheme(QLatin1String("folder"));
case File:
return QIcon::fromTheme(QLatin1String("text-x-generic"));
// no default on purpose; we want warnings when the type enum is extended
}
return QIcon::fromTheme(QLatin1String("text-x-generic"));
} }
/*! /*!
Returns an icon for the file described by \a info. Returns an icon for the file described by \a info, using the
current icon theme.
\sa QIcon::fromTheme
*/ */
QIcon QAbstractFileIconProvider::icon(const QFileInfo &info) const QIcon QAbstractFileIconProvider::icon(const QFileInfo &info) const
{ {
Q_UNUSED(info); Q_D(const QAbstractFileIconProvider);
return {}; if (info.isRoot())
return icon(Drive);
if (info.isDir())
return icon(Folder);
return QIcon::fromTheme(d->mimeDatabase.mimeTypeForFile(info).iconName());
} }
/*! /*!
@ -152,6 +183,7 @@ QIcon QAbstractFileIconProvider::icon(const QFileInfo &info) const
QString QAbstractFileIconProvider::type(const QFileInfo &info) const QString QAbstractFileIconProvider::type(const QFileInfo &info) const
{ {
Q_D(const QAbstractFileIconProvider);
/* ### Qt 6 These string translations being in the QFileDialog context is not ideal, /* ### Qt 6 These string translations being in the QFileDialog context is not ideal,
but translating them in QFileDialog context only in the QFileIconProvider subclass but translating them in QFileDialog context only in the QFileIconProvider subclass
isn't either (it basically requires a duplication of the entire function). isn't either (it basically requires a duplication of the entire function).
@ -162,12 +194,8 @@ QString QAbstractFileIconProvider::type(const QFileInfo &info) const
if (QFileSystemEntry::isRootPath(info.absoluteFilePath())) if (QFileSystemEntry::isRootPath(info.absoluteFilePath()))
return QGuiApplication::translate("QFileDialog", "Drive"); return QGuiApplication::translate("QFileDialog", "Drive");
if (info.isFile()) { if (info.isFile()) {
// ### could use QMimeDatabase::mimeTypeForFile(const QFileInfo&) here const QMimeType mimeType = d->mimeDatabase.mimeTypeForFile(info);
if (!info.suffix().isEmpty()) { return mimeType.comment().isEmpty() ? mimeType.name() : mimeType.comment();
//: %1 is a file name suffix, for example txt
return QGuiApplication::translate("QFileDialog", "%1 File").arg(info.suffix());
}
return QGuiApplication::translate("QFileDialog", "File");
} }
if (info.isDir()) if (info.isDir())

View File

@ -52,6 +52,7 @@
// //
#include <QtGui/private/qtguiglobal_p.h> #include <QtGui/private/qtguiglobal_p.h>
#include <QtCore/QMimeDatabase>
#include "qabstractfileiconprovider.h" #include "qabstractfileiconprovider.h"
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -66,6 +67,8 @@ public:
QAbstractFileIconProvider *q_ptr = nullptr; QAbstractFileIconProvider *q_ptr = nullptr;
QAbstractFileIconProvider::Options options = {}; QAbstractFileIconProvider::Options options = {};
QMimeDatabase mimeDatabase;
}; };
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -196,9 +196,6 @@ void tst_languageChange::retranslatability_data()
<< "QFileDialog::Back" << "QFileDialog::Back"
<< "QFileDialog::Create New Folder" << "QFileDialog::Create New Folder"
<< "QFileDialog::Detail View" << "QFileDialog::Detail View"
#if !defined(Q_OS_MAC)
<< "QFileDialog::File"
#endif
<< "QFileDialog::Files of type:" << "QFileDialog::Files of type:"
<< "QFileDialog::Forward" << "QFileDialog::Forward"
<< "QFileDialog::List View" << "QFileDialog::List View"