1 /**************************************************************************
3 ** This file is part of Qt Creator
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
7 ** Contact: Nokia Corporation (qt-info@nokia.com)
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 ** In addition, as a special exception, Nokia gives you certain additional
26 ** rights. These rights are described in the Nokia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
32 **************************************************************************/
34 #include "fileiconprovider.h"
35 #include "mimedatabase.h"
37 #include <utils/qtcassert.h>
39 #include <QtGui/QApplication>
40 #include <QtGui/QStyle>
41 #include <QtGui/QPainter>
42 #include <QtCore/QFileInfo>
43 #include <QtCore/QPair>
44 #include <QtCore/QDebug>
46 #include <QtGui/QFileIconProvider>
47 #include <QtGui/QIcon>
48 #include <QtGui/QStyle>
51 \class Core::FileIconProvider
53 Provides icons based on file suffixes with the ability to overwrite system
54 icons for specific subtypes. Implements the QFileIconProvider interface
55 and can therefore be used for QFileSystemModel.
57 Note: Registering overlay icons currently completely replaces the system
58 icon and is therefore not recommended on platforms that have their
59 own overlay icon handling (Mac/Windows).
61 The class is a singleton: It's instance can be accessed via the static instance() method.
62 Plugins can register custom icons via registerIconSuffix(), and retrieve icons via the icon()
64 The instance is explicitly deleted by the core plugin for destruction order reasons.
67 // Cache icons in a list of pairs suffix/icon which should be faster than
68 // hashes for small lists.
72 typedef QPair<QString, QIcon> StringIconPair;
73 typedef QList<StringIconPair> StringIconPairList;
75 // Helper to find an icon by suffix in a list of pairs for const/non-const-iterators.
77 template <class StringIconPairListIterator>
78 inline StringIconPairListIterator
79 findBySuffix(const QString &suffix,
80 StringIconPairListIterator iter,
81 const StringIconPairListIterator &end)
83 for (; iter != end; ++iter)
84 if ((*iter).first == suffix)
91 struct FileIconProviderPrivate {
92 FileIconProviderPrivate();
94 // Mapping of file suffix to icon.
95 StringIconPairList m_cache;
97 QIcon m_unknownFileIcon;
100 static FileIconProvider *m_instance;
103 FileIconProviderPrivate::FileIconProviderPrivate() :
104 m_unknownFileIcon(qApp->style()->standardIcon(QStyle::SP_FileIcon))
108 FileIconProvider *FileIconProviderPrivate::m_instance = 0;
112 FileIconProvider::FileIconProvider() :
113 d(new FileIconProviderPrivate)
115 FileIconProviderPrivate::m_instance = this;
118 FileIconProvider::~FileIconProvider()
120 FileIconProviderPrivate::m_instance = 0;
125 Returns the icon associated with the file suffix in fileInfo. If there is none,
126 the default icon of the operating system is returned.
129 QIcon FileIconProvider::icon(const QFileInfo &fileInfo) const
131 typedef StringIconPairList::const_iterator CacheConstIterator;
134 qDebug() << "FileIconProvider::icon" << fileInfo.absoluteFilePath();
135 // Check for cached overlay icons by file suffix.
136 if (!d->m_cache.isEmpty() && !fileInfo.isDir()) {
137 const QString suffix = fileInfo.suffix();
138 if (!suffix.isEmpty()) {
139 const CacheConstIterator it = findBySuffix(suffix, d->m_cache.constBegin(), d->m_cache.constEnd());
140 if (it != d->m_cache.constEnd())
145 #if defined(Q_WS_WIN) || defined(Q_WS_MAC)
146 return QFileIconProvider::icon(fileInfo);
148 // File icons are unknown on linux systems.
149 return (fileInfo.isDir()) ?
150 QFileIconProvider::icon(fileInfo) :
151 d->m_unknownFileIcon;
156 Creates a pixmap with baseicon at size and overlays overlayIcon over it.
157 See platform note in class documentation about recommended usage.
159 QPixmap FileIconProvider::overlayIcon(QStyle::StandardPixmap baseIcon, const QIcon &overlayIcon, const QSize &size)
161 QPixmap iconPixmap = qApp->style()->standardIcon(baseIcon).pixmap(size);
162 QPainter painter(&iconPixmap);
163 painter.drawPixmap(0, 0, overlayIcon.pixmap(size));
169 Registers an icon for a given suffix, overlaying the system file icon.
170 See platform note in class documentation about recommended usage.
172 void FileIconProvider::registerIconOverlayForSuffix(const QIcon &icon,
173 const QString &suffix)
175 typedef StringIconPairList::iterator CacheIterator;
178 qDebug() << "FileIconProvider::registerIconOverlayForSuffix" << suffix;
180 QTC_ASSERT(!icon.isNull() && !suffix.isEmpty(), return)
182 const QPixmap fileIconPixmap = overlayIcon(QStyle::SP_FileIcon, icon, QSize(16, 16));
183 // replace old icon, if it exists
184 const CacheIterator it = findBySuffix(suffix, d->m_cache.begin(), d->m_cache.end());
185 if (it == d->m_cache.end()) {
186 d->m_cache.append(StringIconPair(suffix, fileIconPixmap));
188 (*it).second = fileIconPixmap;
193 Registers an icon for all the suffixes of a given mime type, overlaying the system file icon.
195 void FileIconProvider::registerIconOverlayForMimeType(const QIcon &icon, const MimeType &mimeType)
197 foreach (const QString &suffix, mimeType.suffixes())
198 registerIconOverlayForSuffix(icon, suffix);
202 Returns the sole instance of FileIconProvider.
205 FileIconProvider *FileIconProvider::instance()
207 if (!FileIconProviderPrivate::m_instance)
208 FileIconProviderPrivate::m_instance = new FileIconProvider;
209 return FileIconProviderPrivate::m_instance;