OSDN Git Service

e170679bb0468c56a4f80c1f415831b542d3d93f
[qt-creator-jp/qt-creator-jp.git] / src / plugins / coreplugin / fileiconprovider.cpp
1 /**************************************************************************
2 **
3 ** This file is part of Qt Creator
4 **
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
6 **
7 ** Contact: Nokia Corporation (qt-info@nokia.com)
8 **
9 ** No Commercial Usage
10 **
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
14 ** this package.
15 **
16 ** GNU Lesser General Public License Usage
17 **
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.
24 **
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.
28 **
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
31 **
32 **************************************************************************/
33
34 #include "fileiconprovider.h"
35 #include "mimedatabase.h"
36
37 #include <utils/qtcassert.h>
38
39 #include <QtGui/QApplication>
40 #include <QtGui/QStyle>
41 #include <QtGui/QPainter>
42 #include <QtCore/QFileInfo>
43 #include <QtCore/QPair>
44 #include <QtCore/QDebug>
45
46 #include <QtGui/QFileIconProvider>
47 #include <QtGui/QIcon>
48 #include <QtGui/QStyle>
49
50 /*!
51   \class Core::FileIconProvider
52
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.
56
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).
60
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()
63   method.
64   The instance is explicitly deleted by the core plugin for destruction order reasons.
65   */
66
67 // Cache icons in a list of pairs suffix/icon which should be faster than
68 // hashes for small lists.
69
70 enum { debug = 0 };
71
72 typedef QPair<QString, QIcon> StringIconPair;
73 typedef QList<StringIconPair> StringIconPairList;
74
75 // Helper to find an icon by suffix in a list of pairs for const/non-const-iterators.
76
77 template <class StringIconPairListIterator>
78 inline StringIconPairListIterator
79 findBySuffix(const QString &suffix,
80              StringIconPairListIterator iter,
81              const StringIconPairListIterator &end)
82 {
83     for (; iter != end; ++iter)
84         if ((*iter).first == suffix)
85             return iter;
86     return end;
87 }
88
89 namespace Core {
90
91 struct FileIconProviderPrivate {
92     FileIconProviderPrivate();
93
94     // Mapping of file suffix to icon.
95     StringIconPairList m_cache;
96
97     QIcon m_unknownFileIcon;
98
99     // singleton pattern
100     static FileIconProvider *m_instance;
101 };
102
103 FileIconProviderPrivate::FileIconProviderPrivate() :
104     m_unknownFileIcon(qApp->style()->standardIcon(QStyle::SP_FileIcon))
105 {
106 }
107
108 FileIconProvider *FileIconProviderPrivate::m_instance = 0;
109
110 // FileIconProvider
111
112 FileIconProvider::FileIconProvider() :
113     d(new FileIconProviderPrivate)
114 {
115     FileIconProviderPrivate::m_instance = this;
116 }
117
118 FileIconProvider::~FileIconProvider()
119 {
120     FileIconProviderPrivate::m_instance = 0;
121     delete d;
122 }
123
124 /*!
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.
127   */
128
129 QIcon FileIconProvider::icon(const QFileInfo &fileInfo) const
130 {
131     typedef StringIconPairList::const_iterator CacheConstIterator;
132
133     if (debug)
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())
141                 return (*it).second;
142         }
143     }
144     // Get icon from OS.
145 #if defined(Q_WS_WIN) || defined(Q_WS_MAC)
146     return QFileIconProvider::icon(fileInfo);
147 #else
148     // File icons are unknown on linux systems.
149     return (fileInfo.isDir()) ?
150            QFileIconProvider::icon(fileInfo) :
151            d->m_unknownFileIcon;
152 #endif
153 }
154
155 /*!
156   Creates a pixmap with baseicon at size and overlays overlayIcon over it.
157   See platform note in class documentation about recommended usage.
158   */
159 QPixmap FileIconProvider::overlayIcon(QStyle::StandardPixmap baseIcon, const QIcon &overlayIcon, const QSize &size)
160 {
161     QPixmap iconPixmap = qApp->style()->standardIcon(baseIcon).pixmap(size);
162     QPainter painter(&iconPixmap);
163     painter.drawPixmap(0, 0, overlayIcon.pixmap(size));
164     painter.end();
165     return iconPixmap;
166 }
167
168 /*!
169   Registers an icon for a given suffix, overlaying the system file icon.
170   See platform note in class documentation about recommended usage.
171   */
172 void FileIconProvider::registerIconOverlayForSuffix(const QIcon &icon,
173                                                     const QString &suffix)
174 {
175     typedef StringIconPairList::iterator CacheIterator;
176
177     if (debug)
178         qDebug() << "FileIconProvider::registerIconOverlayForSuffix" << suffix;
179
180     QTC_ASSERT(!icon.isNull() && !suffix.isEmpty(), return)
181
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));
187     } else {
188        (*it).second = fileIconPixmap;
189     }
190 }
191
192 /*!
193   Registers an icon for all the suffixes of a given mime type, overlaying the system file icon.
194   */
195 void FileIconProvider::registerIconOverlayForMimeType(const QIcon &icon, const MimeType &mimeType)
196 {
197     foreach (const QString &suffix, mimeType.suffixes())
198         registerIconOverlayForSuffix(icon, suffix);
199 }
200
201 /*!
202   Returns the sole instance of FileIconProvider.
203   */
204
205 FileIconProvider *FileIconProvider::instance()
206 {
207     if (!FileIconProviderPrivate::m_instance)
208         FileIconProviderPrivate::m_instance = new FileIconProvider;
209     return FileIconProviderPrivate::m_instance;
210 }
211
212 } // namespace core