forked from qt-creator/qt-creator
Core: Clean up FileIconProvider interface
Change-Id: I98c3c8796cb887f5bb3c5184854562ff36727836 Reviewed-by: Christian Kandeler <christian.kandeler@digia.com>
This commit is contained in:
@@ -49,94 +49,91 @@ using namespace Utils;
|
||||
\class Core::FileIconProvider
|
||||
|
||||
Provides icons based on file suffixes with the ability to overwrite system
|
||||
icons for specific subtypes. Implements the QFileIconProvider interface
|
||||
and can therefore be used for QFileSystemModel.
|
||||
icons for specific subtypes. The underlying QFileIconProvider
|
||||
can be used for QFileSystemModel.
|
||||
|
||||
Note: Registering overlay icons currently completely replaces the system
|
||||
icon and is therefore not recommended on platforms that have their
|
||||
own overlay icon handling (Mac/Windows).
|
||||
|
||||
The class is a singleton: It's instance can be accessed via the static instance() method.
|
||||
Plugins can register custom overlay icons via registerIconOverlayForSuffix(), and
|
||||
retrieve icons via the icon() method.
|
||||
The instance is explicitly deleted by the core plugin for destruction order reasons.
|
||||
*/
|
||||
|
||||
// Cache icons in a list of pairs suffix/icon which should be faster than
|
||||
// hashes for small lists.
|
||||
|
||||
namespace Core {
|
||||
namespace FileIconProvider {
|
||||
|
||||
enum { debug = 0 };
|
||||
|
||||
typedef QPair<QString, QIcon> StringIconPair;
|
||||
typedef QList<StringIconPair> StringIconPairList;
|
||||
|
||||
// Helper to find an icon by suffix in a list of pairs for const/non-const-iterators.
|
||||
|
||||
template <class StringIconPairListIterator>
|
||||
inline StringIconPairListIterator
|
||||
findBySuffix(const QString &suffix,
|
||||
StringIconPairListIterator iter,
|
||||
const StringIconPairListIterator &end)
|
||||
class FileIconProviderImplementation : public QFileIconProvider
|
||||
{
|
||||
for (; iter != end; ++iter)
|
||||
if ((*iter).first == suffix)
|
||||
return iter;
|
||||
return end;
|
||||
}
|
||||
public:
|
||||
FileIconProviderImplementation()
|
||||
: m_unknownFileIcon(qApp->style()->standardIcon(QStyle::SP_FileIcon))
|
||||
{}
|
||||
|
||||
namespace Core {
|
||||
QIcon icon(const QFileInfo &info) const;
|
||||
using QFileIconProvider::icon;
|
||||
|
||||
struct FileIconProviderPrivate {
|
||||
FileIconProviderPrivate();
|
||||
void registerIconOverlayForSuffix(const QIcon &icon, const QString &suffix)
|
||||
{
|
||||
if (debug)
|
||||
qDebug() << "FileIconProvider::registerIconOverlayForSuffix" << suffix;
|
||||
|
||||
QTC_ASSERT(!icon.isNull() && !suffix.isEmpty(), return);
|
||||
|
||||
const QPixmap fileIconPixmap = FileIconProvider::overlayIcon(QStyle::SP_FileIcon, icon, QSize(16, 16));
|
||||
|
||||
// replace old icon, if it exists
|
||||
for (int i = 0, n = m_cache.size(); i != n; ++i) {
|
||||
if (m_cache.at(i).first == suffix) {
|
||||
m_cache[i].second = fileIconPixmap;
|
||||
return;
|
||||
}
|
||||
}
|
||||
m_cache.append(StringIconPair(suffix, fileIconPixmap));
|
||||
}
|
||||
|
||||
void registerIconOverlayForMimeType(const QIcon &icon, const MimeType &mimeType)
|
||||
{
|
||||
foreach (const QString &suffix, mimeType.suffixes())
|
||||
registerIconOverlayForSuffix(icon, suffix);
|
||||
}
|
||||
|
||||
// Mapping of file suffix to icon.
|
||||
StringIconPairList m_cache;
|
||||
|
||||
QIcon m_unknownFileIcon;
|
||||
|
||||
// singleton pattern
|
||||
static FileIconProvider *m_instance;
|
||||
};
|
||||
|
||||
FileIconProviderPrivate::FileIconProviderPrivate() :
|
||||
m_unknownFileIcon(qApp->style()->standardIcon(QStyle::SP_FileIcon))
|
||||
FileIconProviderImplementation *instance()
|
||||
{
|
||||
static FileIconProviderImplementation theInstance;
|
||||
return &theInstance;
|
||||
}
|
||||
|
||||
FileIconProvider *FileIconProviderPrivate::m_instance = 0;
|
||||
|
||||
// FileIconProvider
|
||||
|
||||
FileIconProvider::FileIconProvider() :
|
||||
d(new FileIconProviderPrivate)
|
||||
QFileIconProvider *iconProvider()
|
||||
{
|
||||
FileIconProviderPrivate::m_instance = this;
|
||||
return instance();
|
||||
}
|
||||
|
||||
FileIconProvider::~FileIconProvider()
|
||||
QIcon FileIconProviderImplementation::icon(const QFileInfo &fileInfo) const
|
||||
{
|
||||
FileIconProviderPrivate::m_instance = 0;
|
||||
delete d;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the icon associated with the file suffix in fileInfo. If there is none,
|
||||
the default icon of the operating system is returned.
|
||||
*/
|
||||
|
||||
QIcon FileIconProvider::icon(const QFileInfo &fileInfo) const
|
||||
{
|
||||
typedef StringIconPairList::const_iterator CacheConstIterator;
|
||||
|
||||
if (debug)
|
||||
qDebug() << "FileIconProvider::icon" << fileInfo.absoluteFilePath();
|
||||
// Check for cached overlay icons by file suffix.
|
||||
if (!d->m_cache.isEmpty() && !fileInfo.isDir()) {
|
||||
if (!m_cache.isEmpty() && !fileInfo.isDir()) {
|
||||
const QString suffix = fileInfo.suffix();
|
||||
if (!suffix.isEmpty()) {
|
||||
const CacheConstIterator it = findBySuffix(suffix, d->m_cache.constBegin(), d->m_cache.constEnd());
|
||||
if (it != d->m_cache.constEnd())
|
||||
return (*it).second;
|
||||
for (int i = 0, n = m_cache.size(); i != n; ++i)
|
||||
if (m_cache.at(i).first == suffix)
|
||||
return m_cache[i].second;
|
||||
}
|
||||
}
|
||||
// Get icon from OS.
|
||||
@@ -144,16 +141,32 @@ QIcon FileIconProvider::icon(const QFileInfo &fileInfo) const
|
||||
return QFileIconProvider::icon(fileInfo);
|
||||
|
||||
// File icons are unknown on linux systems.
|
||||
return (fileInfo.isDir()) ?
|
||||
QFileIconProvider::icon(fileInfo) :
|
||||
d->m_unknownFileIcon;
|
||||
return fileInfo.isDir() ? QFileIconProvider::icon(fileInfo) : m_unknownFileIcon;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the icon associated with the file suffix in fileInfo. If there is none,
|
||||
the default icon of the operating system is returned.
|
||||
*/
|
||||
|
||||
QIcon icon(const QFileInfo &info)
|
||||
{
|
||||
return instance()->icon(info);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \overload
|
||||
*/
|
||||
QIcon icon(QFileIconProvider::IconType type)
|
||||
{
|
||||
return instance()->icon(type);
|
||||
}
|
||||
|
||||
/*!
|
||||
Creates a pixmap with baseicon at size and overlays overlayIcon over it.
|
||||
See platform note in class documentation about recommended usage.
|
||||
*/
|
||||
QPixmap FileIconProvider::overlayIcon(QStyle::StandardPixmap baseIcon, const QIcon &overlayIcon, const QSize &size)
|
||||
QPixmap overlayIcon(QStyle::StandardPixmap baseIcon, const QIcon &overlayIcon, const QSize &size)
|
||||
{
|
||||
QPixmap iconPixmap = qApp->style()->standardIcon(baseIcon).pixmap(size);
|
||||
QPainter painter(&iconPixmap);
|
||||
@@ -166,43 +179,26 @@ QPixmap FileIconProvider::overlayIcon(QStyle::StandardPixmap baseIcon, const QIc
|
||||
Registers an icon for a given suffix, overlaying the system file icon.
|
||||
See platform note in class documentation about recommended usage.
|
||||
*/
|
||||
void FileIconProvider::registerIconOverlayForSuffix(const QIcon &icon,
|
||||
const QString &suffix)
|
||||
void registerIconOverlayForSuffix(const char *path, const char *suffix)
|
||||
{
|
||||
typedef StringIconPairList::iterator CacheIterator;
|
||||
|
||||
if (debug)
|
||||
qDebug() << "FileIconProvider::registerIconOverlayForSuffix" << suffix;
|
||||
|
||||
QTC_ASSERT(!icon.isNull() && !suffix.isEmpty(), return);
|
||||
|
||||
const QPixmap fileIconPixmap = overlayIcon(QStyle::SP_FileIcon, icon, QSize(16, 16));
|
||||
// replace old icon, if it exists
|
||||
const CacheIterator it = findBySuffix(suffix, d->m_cache.begin(), d->m_cache.end());
|
||||
if (it == d->m_cache.end())
|
||||
d->m_cache.append(StringIconPair(suffix, fileIconPixmap));
|
||||
else
|
||||
(*it).second = fileIconPixmap;
|
||||
instance()->registerIconOverlayForSuffix(QIcon(QLatin1String(path)), QLatin1String(suffix));
|
||||
}
|
||||
|
||||
/*!
|
||||
Registers an icon for all the suffixes of a given mime type, overlaying the system file icon.
|
||||
*/
|
||||
void FileIconProvider::registerIconOverlayForMimeType(const QIcon &icon, const MimeType &mimeType)
|
||||
void registerIconOverlayForMimeType(const QIcon &icon, const char *mimeType)
|
||||
{
|
||||
foreach (const QString &suffix, mimeType.suffixes())
|
||||
registerIconOverlayForSuffix(icon, suffix);
|
||||
instance()->registerIconOverlayForMimeType(icon, MimeDatabase::findByType(QString::fromLatin1(mimeType)));
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the sole instance of FileIconProvider.
|
||||
*/
|
||||
|
||||
FileIconProvider *FileIconProvider::instance()
|
||||
* \overload
|
||||
*/
|
||||
void registerIconOverlayForMimeType(const char *path, const char *mimeType)
|
||||
{
|
||||
if (!FileIconProviderPrivate::m_instance)
|
||||
FileIconProviderPrivate::m_instance = new FileIconProvider;
|
||||
return FileIconProviderPrivate::m_instance;
|
||||
instance()->registerIconOverlayForMimeType(QIcon(QLatin1String(path)), MimeDatabase::findByType(QString::fromLatin1(mimeType)));
|
||||
}
|
||||
|
||||
} // namespace core
|
||||
} // namespace FileIconProvider
|
||||
} // namespace Core
|
||||
|
||||
Reference in New Issue
Block a user