source: trunk/src/gui/itemviews/qfileiconprovider.cpp@ 466

Last change on this file since 466 was 2, checked in by Dmitry A. Kuminov, 17 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 13.6 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtGui module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qfileiconprovider.h"
43
44#ifndef QT_NO_FILEICONPROVIDER
45#include <qstyle.h>
46#include <qapplication.h>
47#include <qdir.h>
48#if defined(Q_WS_WIN)
49#define _WIN32_IE 0x0500
50#include <objbase.h>
51#include <private/qpixmapdata_p.h>
52#include <qpixmapcache.h>
53#elif defined(Q_WS_MAC)
54#include <private/qt_mac_p.h>
55#endif
56#include <private/qfunctions_p.h>
57#ifdef Q_OS_WINCE
58#include <Commctrl.h>
59#endif
60
61#ifndef SHGFI_ADDOVERLAYS
62#define SHGFI_ADDOVERLAYS 0x000000020
63#endif
64
65QT_BEGIN_NAMESPACE
66
67/*!
68 \class QFileIconProvider
69
70 \brief The QFileIconProvider class provides file icons for the QDirModel class.
71*/
72
73/*!
74 \enum QFileIconProvider::IconType
75 \value Computer
76 \value Desktop
77 \value Trashcan
78 \value Network
79 \value Drive
80 \value Folder
81 \value File
82*/
83
84class QFileIconProviderPrivate
85{
86 Q_DECLARE_PUBLIC(QFileIconProvider)
87
88public:
89 QFileIconProviderPrivate();
90 QIcon getIcon(QStyle::StandardPixmap name) const;
91#ifdef Q_WS_WIN
92 QIcon getWinIcon(const QFileInfo &fi) const;
93#elif defined(Q_WS_MAC)
94 QIcon getMacIcon(const QFileInfo &fi) const;
95#endif
96 QFileIconProvider *q_ptr;
97 QString homePath;
98
99private:
100 QIcon file;
101 QIcon fileLink;
102 QIcon directory;
103 QIcon directoryLink;
104 QIcon harddisk;
105 QIcon floppy;
106 QIcon cdrom;
107 QIcon ram;
108 QIcon network;
109 QIcon computer;
110 QIcon desktop;
111 QIcon trashcan;
112 QIcon generic;
113 QIcon home;
114};
115
116QFileIconProviderPrivate::QFileIconProviderPrivate()
117{
118 QStyle *style = QApplication::style();
119 file = style->standardIcon(QStyle::SP_FileIcon);
120 directory = style->standardIcon(QStyle::SP_DirIcon);
121 fileLink = style->standardIcon(QStyle::SP_FileLinkIcon);
122 directoryLink = style->standardIcon(QStyle::SP_DirLinkIcon);
123 harddisk = style->standardIcon(QStyle::SP_DriveHDIcon);
124 floppy = style->standardIcon(QStyle::SP_DriveFDIcon);
125 cdrom = style->standardIcon(QStyle::SP_DriveCDIcon);
126 network = style->standardIcon(QStyle::SP_DriveNetIcon);
127 computer = style->standardIcon(QStyle::SP_ComputerIcon);
128 desktop = style->standardIcon(QStyle::SP_DesktopIcon);
129 trashcan = style->standardIcon(QStyle::SP_TrashIcon);
130 home = style->standardIcon(QStyle::SP_DirHomeIcon);
131 homePath = QDir::home().absolutePath();
132}
133
134QIcon QFileIconProviderPrivate::getIcon(QStyle::StandardPixmap name) const
135{
136 switch (name) {
137 case QStyle::SP_FileIcon:
138 return file;
139 case QStyle::SP_FileLinkIcon:
140 return fileLink;
141 case QStyle::SP_DirIcon:
142 return directory;
143 case QStyle::SP_DirLinkIcon:
144 return directoryLink;
145 case QStyle::SP_DriveHDIcon:
146 return harddisk;
147 case QStyle::SP_DriveFDIcon:
148 return floppy;
149 case QStyle::SP_DriveCDIcon:
150 return cdrom;
151 case QStyle::SP_DriveNetIcon:
152 return network;
153 case QStyle::SP_ComputerIcon:
154 return computer;
155 case QStyle::SP_DesktopIcon:
156 return desktop;
157 case QStyle::SP_TrashIcon:
158 return trashcan;
159 case QStyle::SP_DirHomeIcon:
160 return home;
161 default:
162 return QIcon();
163 }
164 return QIcon();
165}
166
167/*!
168 Constructs a file icon provider.
169*/
170
171QFileIconProvider::QFileIconProvider()
172 : d_ptr(new QFileIconProviderPrivate)
173{
174}
175
176/*!
177 Destroys the file icon provider.
178
179*/
180
181QFileIconProvider::~QFileIconProvider()
182{
183 delete d_ptr;
184}
185
186/*!
187 Returns an icon set for the given \a type.
188*/
189
190QIcon QFileIconProvider::icon(IconType type) const
191{
192 Q_D(const QFileIconProvider);
193 switch (type) {
194 case Computer:
195 return d->getIcon(QStyle::SP_ComputerIcon);
196 case Desktop:
197 return d->getIcon(QStyle::SP_DesktopIcon);
198 case Trashcan:
199 return d->getIcon(QStyle::SP_TrashIcon);
200 case Network:
201 return d->getIcon(QStyle::SP_DriveNetIcon);
202 case Drive:
203 return d->getIcon(QStyle::SP_DriveHDIcon);
204 case Folder:
205 return d->getIcon(QStyle::SP_DirIcon);
206 case File:
207 return d->getIcon(QStyle::SP_FileIcon);
208 default:
209 break;
210 };
211 return QIcon();
212}
213
214#ifdef Q_WS_WIN
215QIcon QFileIconProviderPrivate::getWinIcon(const QFileInfo &fileInfo) const
216{
217 QIcon retIcon;
218 QString fileExtension = fileInfo.suffix().toUpper();
219 fileExtension.prepend( QLatin1String(".") );
220
221 QString key;
222 if (fileInfo.isFile() && !fileInfo.isExecutable() && !fileInfo.isSymLink())
223 key = QLatin1String("qt_") + fileExtension;
224
225 QPixmap pixmap;
226 if (!key.isEmpty()) {
227 QPixmapCache::find(key, pixmap);
228 }
229
230 if (!pixmap.isNull()) {
231 retIcon.addPixmap(pixmap);
232 if (QPixmapCache::find(key + QLatin1Char('l'), pixmap))
233 retIcon.addPixmap(pixmap);
234 return retIcon;
235 }
236
237 /* We don't use the variable, but by storing it statically, we
238 * ensure CoInitialize is only called once. */
239 static HRESULT comInit = CoInitialize(NULL);
240 Q_UNUSED(comInit);
241
242 SHFILEINFO info;
243 unsigned long val = 0;
244
245 //Get the small icon
246#ifndef Q_OS_WINCE
247 val = SHGetFileInfo((const WCHAR *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info,
248 sizeof(SHFILEINFO), SHGFI_ICON|SHGFI_SMALLICON|SHGFI_SYSICONINDEX|SHGFI_ADDOVERLAYS);
249#else
250 val = SHGetFileInfo((const WCHAR *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info,
251 sizeof(SHFILEINFO), SHGFI_SMALLICON|SHGFI_SYSICONINDEX);
252#endif
253 if (val) {
254 if (fileInfo.isDir() && !fileInfo.isRoot()) {
255 //using the unique icon index provided by windows save us from duplicate keys
256 key = QString::fromLatin1("qt_dir_%1").arg(info.iIcon);
257 QPixmapCache::find(key, pixmap);
258 if (!pixmap.isNull()) {
259 retIcon.addPixmap(pixmap);
260 if (QPixmapCache::find(key + QLatin1Char('l'), pixmap))
261 retIcon.addPixmap(pixmap);
262 DestroyIcon(info.hIcon);
263 return retIcon;
264 }
265 }
266 if (pixmap.isNull()) {
267#ifndef Q_OS_WINCE
268 pixmap = convertHIconToPixmap(info.hIcon);
269#else
270 pixmap = convertHIconToPixmap(ImageList_GetIcon((HIMAGELIST) val, info.iIcon, ILD_NORMAL));
271#endif
272 if (!pixmap.isNull()) {
273 retIcon.addPixmap(pixmap);
274 if (!key.isEmpty())
275 QPixmapCache::insert(key, pixmap);
276 }
277 else {
278 qWarning("QFileIconProviderPrivate::getWinIcon() no small icon found");
279 }
280 }
281 DestroyIcon(info.hIcon);
282 }
283
284 //Get the big icon
285#ifndef Q_OS_WINCE
286 val = SHGetFileInfo((const WCHAR *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info,
287 sizeof(SHFILEINFO), SHGFI_ICON|SHGFI_LARGEICON|SHGFI_SYSICONINDEX|SHGFI_ADDOVERLAYS);
288#else
289 val = SHGetFileInfo((const WCHAR *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info,
290 sizeof(SHFILEINFO), SHGFI_LARGEICON|SHGFI_SYSICONINDEX);
291#endif
292 if (val) {
293 if (fileInfo.isDir() && !fileInfo.isRoot()) {
294 //using the unique icon index provided by windows save us from duplicate keys
295 key = QString::fromLatin1("qt_dir_%1").arg(info.iIcon);
296 }
297#ifndef Q_OS_WINCE
298 pixmap = convertHIconToPixmap(info.hIcon);
299#else
300 pixmap = convertHIconToPixmap(ImageList_GetIcon((HIMAGELIST) val, info.iIcon, ILD_NORMAL), true);
301#endif
302 if (!pixmap.isNull()) {
303 retIcon.addPixmap(pixmap);
304 if (!key.isEmpty())
305 QPixmapCache::insert(key + QLatin1Char('l'), pixmap);
306 }
307 else {
308 qWarning("QFileIconProviderPrivate::getWinIcon() no large icon found");
309 }
310 DestroyIcon(info.hIcon);
311 }
312 return retIcon;
313}