Line | Source | Count |
1 | | - |
2 | | - |
3 | | - |
4 | | - |
5 | | - |
6 | | - |
7 | | - |
8 | | - |
9 | | - |
10 | | - |
11 | | - |
12 | | - |
13 | | - |
14 | | - |
15 | | - |
16 | | - |
17 | | - |
18 | | - |
19 | | - |
20 | | - |
21 | | - |
22 | | - |
23 | | - |
24 | | - |
25 | | - |
26 | | - |
27 | | - |
28 | | - |
29 | | - |
30 | | - |
31 | | - |
32 | | - |
33 | | - |
34 | | - |
35 | | - |
36 | | - |
37 | | - |
38 | | - |
39 | | - |
40 | #include "qfileiconprovider.h" | - |
41 | #include "qfileiconprovider_p.h" | - |
42 | | - |
43 | #include <qapplication.h> | - |
44 | #include <qdir.h> | - |
45 | #include <qpixmapcache.h> | - |
46 | #include <private/qfunctions_p.h> | - |
47 | #include <private/qguiapplication_p.h> | - |
48 | #include <private/qicon_p.h> | - |
49 | #include <qpa/qplatformintegration.h> | - |
50 | #include <qpa/qplatformservices.h> | - |
51 | #include <qpa/qplatformtheme.h> | - |
52 | | - |
53 | #if defined(Q_OS_WIN) | - |
54 | # include <qt_windows.h> | - |
55 | # ifndef Q_OS_WINRT | - |
56 | # include <commctrl.h> | - |
57 | # include <objbase.h> | - |
58 | # endif | - |
| #endif | |
| | |
| #if defined(Q_OS_UNIX) && !defined(QT_NO_STYLE_GTK) | |
| # include <private/qgtkstyle_p_p.h>#endif | |
60 | | - |
61 | QT_BEGIN_NAMESPACE | - |
62 | | - |
63 | static bool isCacheable(const QFileInfo &fi); | - |
64 | | - |
65 | class QFileIconEngine : public QPixmapIconEngine | - |
66 | { | - |
67 | public: | - |
68 | QFileIconEngine(const QFileInfo &info, QFileIconProvider::Options opts) | - |
69 | : QPixmapIconEngine(), m_fileInfo(info), m_fipOpts(opts) | - |
70 | { } | - |
71 | | - |
72 | QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) Q_DECL_OVERRIDE | - |
73 | { | - |
74 | Q_UNUSED(mode); | - |
75 | Q_UNUSED(state); | - |
76 | QPixmap pixmap; | - |
77 | | - |
78 | if (!size.isValid()) | - |
79 | return pixmap; | - |
80 | | - |
81 | const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme(); | - |
82 | if (!theme) | - |
83 | return pixmap; | - |
84 | | - |
85 | const QString &keyBase = QLatin1String("qt_.") + m_fileInfo.suffix().toUpper(); | - |
86 | | - |
87 | bool cacheable = isCacheable(m_fileInfo); | - |
88 | if (cacheable) { | - |
89 | QPixmapCache::find(keyBase + QString::number(size.width()), pixmap); | - |
90 | if (!pixmap.isNull()) | - |
91 | return pixmap; | - |
92 | } | - |
93 | | - |
94 | QPlatformTheme::IconOptions iconOptions; | - |
95 | if (m_fipOpts & QFileIconProvider::DontUseCustomDirectoryIcons) | - |
96 | iconOptions |= QPlatformTheme::DontUseCustomDirectoryIcons; | - |
97 | | - |
98 | pixmap = theme->fileIconPixmap(m_fileInfo, size, iconOptions); | - |
99 | if (!pixmap.isNull()) { | - |
100 | if (cacheable) | - |
101 | QPixmapCache::insert(keyBase + QString::number(size.width()), pixmap); | - |
102 | } | - |
103 | | - |
104 | return pixmap; | - |
105 | } | - |
106 | | - |
107 | QList<QSize> availableSizes(QIcon::Mode mode = QIcon::Normal, QIcon::State state = QIcon::Off) const Q_DECL_OVERRIDE | - |
108 | { | - |
109 | Q_UNUSED(mode); | - |
110 | Q_UNUSED(state); | - |
111 | static QList<QSize> sizes; | - |
112 | static QPlatformTheme *theme = 0; | - |
113 | if (!theme) { | - |
114 | theme = QGuiApplicationPrivate::platformTheme(); | - |
115 | if (!theme) | - |
116 | return sizes; | - |
117 | | - |
118 | QList<int> themeSizes = theme->themeHint(QPlatformTheme::IconPixmapSizes).value<QList<int> >(); | - |
119 | if (themeSizes.isEmpty()) | - |
120 | return sizes; | - |
121 | | - |
122 | sizes.reserve(themeSizes.count()); | - |
123 | foreach (int size, themeSizes) | - |
124 | sizes << QSize(size, size); | - |
125 | } | - |
126 | return sizes; | - |
127 | } | - |
128 | | - |
129 | QSize actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state) Q_DECL_OVERRIDE | - |
130 | { | - |
131 | const QList<QSize> &sizes = availableSizes(mode, state); | - |
132 | const int numberSizes = sizes.length(); | - |
133 | if (numberSizes == 0) | - |
134 | return QSize(); | - |
135 | | - |
136 | | - |
137 | | - |
138 | | - |
139 | const int sizeArea = size.width() * size.height(); | - |
140 | QSize actualSize = sizes.first(); | - |
141 | int actualArea = actualSize.width() * actualSize.height(); | - |
142 | for (int i = 1; i < numberSizes; ++i) { | - |
143 | const QSize &s = sizes.at(i); | - |
144 | const int a = s.width() * s.height(); | - |
145 | if ((sizeArea <= a && a < actualArea) || (actualArea < sizeArea && actualArea < a)) { | - |
146 | actualSize = s; | - |
147 | actualArea = a; | - |
148 | } | - |
149 | } | - |
150 | | - |
151 | if (!actualSize.isNull() && (actualSize.width() > size.width() || actualSize.height() > size.height())) | - |
152 | actualSize.scale(size, Qt::KeepAspectRatio); | - |
153 | | - |
154 | return actualSize; | - |
155 | } | - |
156 | | - |
157 | private: | - |
158 | QFileInfo m_fileInfo; | - |
159 | QFileIconProvider::Options m_fipOpts; | - |
160 | }; | - |
161 | | - |
162 | | - |
163 | | - |
164 | | - |
165 | | - |
166 | | - |
167 | | - |
168 | | - |
169 | | - |
170 | | - |
171 | | - |
172 | | - |
173 | | - |
174 | | - |
175 | | - |
176 | | - |
177 | | - |
178 | | - |
179 | | - |
180 | | - |
181 | | - |
182 | | - |
183 | | - |
184 | | - |
185 | | - |
186 | | - |
187 | | - |
188 | | - |
189 | | - |
190 | | - |
191 | | - |
192 | QFileIconProviderPrivate::QFileIconProviderPrivate(QFileIconProvider *q) : | - |
193 | q_ptr(q), homePath(QDir::home().absolutePath()) | - |
194 | { | - |
195 | } | - |
196 | | - |
197 | QIcon QFileIconProviderPrivate::getIcon(QStyle::StandardPixmap name) const | - |
198 | { | - |
199 | switch (name) { | - |
200 | case QStyle::SP_FileIcon: | - |
201 | if (file.isNull()) | - |
202 | file = QApplication::style()->standardIcon(name); | - |
203 | return file; | - |
204 | case QStyle::SP_FileLinkIcon: | - |
205 | if (fileLink.isNull()) | - |
206 | fileLink = QApplication::style()->standardIcon(name); | - |
207 | return fileLink; | - |
208 | case QStyle::SP_DirIcon: | - |
209 | if (directory.isNull()) | - |
210 | directory = QApplication::style()->standardIcon(name); | - |
211 | return directory; | - |
212 | case QStyle::SP_DirLinkIcon: | - |
213 | if (directoryLink.isNull()) | - |
214 | directoryLink = QApplication::style()->standardIcon(name); | - |
215 | return directoryLink; | - |
216 | case QStyle::SP_DriveHDIcon: | - |
217 | if (harddisk.isNull()) | - |
218 | harddisk = QApplication::style()->standardIcon(name); | - |
219 | return harddisk; | - |
220 | case QStyle::SP_DriveFDIcon: | - |
221 | if (floppy.isNull()) | - |
222 | floppy = QApplication::style()->standardIcon(name); | - |
223 | return floppy; | - |
224 | case QStyle::SP_DriveCDIcon: | - |
225 | if (cdrom.isNull()) | - |
226 | cdrom = QApplication::style()->standardIcon(name); | - |
227 | return cdrom; | - |
228 | case QStyle::SP_DriveNetIcon: | - |
229 | if (network.isNull()) | - |
230 | network = QApplication::style()->standardIcon(name); | - |
231 | return network; | - |
232 | case QStyle::SP_ComputerIcon: | - |
233 | if (computer.isNull()) | - |
234 | computer = QApplication::style()->standardIcon(name); | - |
235 | return computer; | - |
236 | case QStyle::SP_DesktopIcon: | - |
237 | if (desktop.isNull()) | - |
238 | desktop = QApplication::style()->standardIcon(name); | - |
239 | return desktop; | - |
240 | case QStyle::SP_TrashIcon: | - |
241 | if (trashcan.isNull()) | - |
242 | trashcan = QApplication::style()->standardIcon(name); | - |
243 | return trashcan; | - |
244 | case QStyle::SP_DirHomeIcon: | - |
245 | if (home.isNull()) | - |
246 | home = QApplication::style()->standardIcon(name); | - |
247 | return home; | - |
248 | default: | - |
249 | return QIcon(); | - |
250 | } | - |
251 | return QIcon(); dead code: return QIcon(); | - |
252 | } | - |
253 | | - |
254 | | - |
255 | | - |
256 | | - |
257 | | - |
258 | QFileIconProvider::QFileIconProvider() | - |
259 | : d_ptr(new QFileIconProviderPrivate(this)) | - |
260 | { | - |
261 | } | - |
262 | | - |
263 | | - |
264 | | - |
265 | | - |
266 | | - |
267 | | - |
268 | QFileIconProvider::~QFileIconProvider() | - |
269 | { | - |
270 | } | - |
271 | | - |
272 | | - |
273 | | - |
274 | | - |
275 | | - |
276 | | - |
277 | | - |
278 | void QFileIconProvider::setOptions(QFileIconProvider::Options options) | - |
279 | { | - |
280 | Q_D(QFileIconProvider); | - |
281 | d->options = options; | - |
282 | } | - |
283 | | - |
284 | | - |
285 | | - |
286 | | - |
287 | | - |
288 | | - |
289 | | - |
290 | | - |
291 | QFileIconProvider::Options QFileIconProvider::options() const | - |
292 | { | - |
293 | Q_D(const QFileIconProvider); | - |
294 | return d->options; | - |
295 | } | - |
296 | | - |
297 | | - |
298 | | - |
299 | | - |
300 | | - |
301 | QIcon QFileIconProvider::icon(IconType type) const | - |
302 | { | - |
303 | Q_D(const QFileIconProvider); | - |
304 | switch (type) { | - |
305 | case Computer: | - |
306 | return d->getIcon(QStyle::SP_ComputerIcon); | - |
307 | case Desktop: | - |
308 | return d->getIcon(QStyle::SP_DesktopIcon); | - |
309 | case Trashcan: | - |
310 | return d->getIcon(QStyle::SP_TrashIcon); | - |
311 | case Network: | - |
312 | return d->getIcon(QStyle::SP_DriveNetIcon); | - |
313 | case Drive: | - |
314 | return d->getIcon(QStyle::SP_DriveHDIcon); | - |
315 | case Folder: | - |
316 | return d->getIcon(QStyle::SP_DirIcon); | - |
317 | case File: | - |
318 | return d->getIcon(QStyle::SP_FileIcon); | - |
319 | default: | - |
320 | break; | - |
321 | }; | - |
322 | return QIcon(); | - |
323 | } | - |
324 | | - |
325 | static bool isCacheable(const QFileInfo &fi) | - |
326 | { | - |
327 | if (!fi.isFile()) | - |
328 | return false; | - |
329 | | - |
330 | #ifdef Q_OS_WIN | - |
331 | | - |
332 | const QString fileExtension = fi.suffix(); | - |
333 | | - |
334 | return fileExtension.compare(QLatin1String("exe"), Qt::CaseInsensitive) && | - |
335 | fileExtension.compare(QLatin1String("lnk"), Qt::CaseInsensitive) && | - |
336 | fileExtension.compare(QLatin1String("ico"), Qt::CaseInsensitive); | - |
337 | #else | - |
338 | return !fi.isExecutable() && !fi.isSymLink(); | - |
339 | #endif | - |
340 | } | - |
341 | | - |
342 | QIcon QFileIconProviderPrivate::getIcon(const QFileInfo &fi) const | - |
343 | { | - |
344 | const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme(); | - |
345 | if (!theme) | - |
346 | return QIcon(); | - |
347 | | - |
348 | QList<int> sizes = theme->themeHint(QPlatformTheme::IconPixmapSizes).value<QList<int> >(); | - |
349 | if (sizes.isEmpty()) | - |
350 | return QIcon(); | - |
351 | | - |
352 | return QIcon(new QFileIconEngine(fi, options)); | - |
353 | } | - |
354 | | - |
355 | | - |
356 | | - |
357 | | - |
358 | | - |
359 | QIcon QFileIconProvider::icon(const QFileInfo &info) const | - |
360 | { | - |
361 | Q_D(const QFileIconProvider); | - |
| | |
| #if defined(Q_OS_UNIX) && !defined(QT_NO_STYLE_GTK) | |
| const QByteArray desktopEnvironment = QGuiApplicationPrivate::platformIntegration()->services()->desktopEnvironment(); | |
| if (desktopEnvironment != QByteArrayLiteral("KDE")) { | |
| QIcon gtkIcon = QGtkStylePrivate::getFilesystemIcon(info);if (!gtkIcon.isNull()) | |
| return gtkIcon; | |
| } | |
| #endif | |
362 | | - |
363 | QIcon retIcon = d->getIcon(info); | - |
364 | if (!retIcon.isNull())TRUE | never evaluated | FALSE | never evaluated |
| 0 |
365 | return retIcon; never executed: return retIcon; | 0 |
366 | | - |
367 | if (info.isRoot())TRUE | never evaluated | FALSE | never evaluated |
| 0 |
368 | #if defined (Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) | - |
369 | { | - |
370 | UINT type = GetDriveType((wchar_t *)info.absoluteFilePath().utf16()); | - |
371 | | - |
372 | switch (type) { | - |
373 | case DRIVE_REMOVABLE: | - |
374 | return d->getIcon(QStyle::SP_DriveFDIcon); | - |
375 | case DRIVE_FIXED: | - |
376 | return d->getIcon(QStyle::SP_DriveHDIcon); | - |
377 | case DRIVE_REMOTE: | - |
378 | return d->getIcon(QStyle::SP_DriveNetIcon); | - |
379 | case DRIVE_CDROM: | - |
380 | return d->getIcon(QStyle::SP_DriveCDIcon); | - |
381 | case DRIVE_RAMDISK: | - |
382 | case DRIVE_UNKNOWN: | - |
383 | case DRIVE_NO_ROOT_DIR: | - |
384 | default: | - |
385 | return d->getIcon(QStyle::SP_DriveHDIcon); | - |
386 | } | - |
387 | } | - |
388 | #else | - |
389 | return d->getIcon(QStyle::SP_DriveHDIcon); never executed: return d->getIcon(QStyle::SP_DriveHDIcon); | 0 |
390 | #endif | - |
391 | | - |
392 | if (info.isFile()) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
393 | if (info.isSymLink())TRUE | never evaluated | FALSE | never evaluated |
| 0 |
394 | return d->getIcon(QStyle::SP_FileLinkIcon); never executed: return d->getIcon(QStyle::SP_FileLinkIcon); | 0 |
395 | else | - |
396 | return d->getIcon(QStyle::SP_FileIcon); never executed: return d->getIcon(QStyle::SP_FileIcon); | 0 |
397 | } | - |
398 | if (info.isDir()) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
399 | if (info.isSymLink()) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
400 | return d->getIcon(QStyle::SP_DirLinkIcon); never executed: return d->getIcon(QStyle::SP_DirLinkIcon); | 0 |
401 | } else { | - |
402 | if (info.absoluteFilePath() == d->homePath) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
403 | return d->getIcon(QStyle::SP_DirHomeIcon); never executed: return d->getIcon(QStyle::SP_DirHomeIcon); | 0 |
404 | } else { | - |
405 | return d->getIcon(QStyle::SP_DirIcon); never executed: return d->getIcon(QStyle::SP_DirIcon); | 0 |
406 | } | - |
407 | } | - |
408 | } | - |
409 | return QIcon(); never executed: return QIcon(); | 0 |
410 | } | - |
411 | | - |
412 | | - |
413 | | - |
414 | | - |
415 | | - |
416 | QString QFileIconProvider::type(const QFileInfo &info) const | - |
417 | { | - |
418 | if (info.isRoot()) | - |
419 | return QApplication::translate("QFileDialog", "Drive"); | - |
420 | if (info.isFile()) { | - |
421 | if (!info.suffix().isEmpty()) { | - |
422 | | - |
423 | return QApplication::translate("QFileDialog", "%1 File").arg(info.suffix()); | - |
424 | } | - |
425 | return QApplication::translate("QFileDialog", "File"); | - |
426 | } | - |
427 | | - |
428 | if (info.isDir()) | - |
429 | #ifdef Q_OS_WIN | - |
430 | return QApplication::translate("QFileDialog", "File Folder", "Match Windows Explorer"); | - |
431 | #else | - |
432 | return QApplication::translate("QFileDialog", "Folder", "All other platforms"); | - |
433 | #endif | - |
434 | | - |
435 | | - |
436 | | - |
437 | | - |
438 | | - |
439 | if (info.isSymLink()) | - |
440 | #ifdef Q_OS_MAC | - |
441 | return QApplication::translate("QFileDialog", "Alias", "OS X Finder"); | - |
442 | #else | - |
443 | return QApplication::translate("QFileDialog", "Shortcut", "All other platforms"); | - |
444 | #endif | - |
445 | | - |
446 | | - |
447 | | - |
448 | | - |
449 | | - |
450 | return QApplication::translate("QFileDialog", "Unknown"); | - |
451 | } | - |
452 | | - |
453 | QT_END_NAMESPACE | - |
| | |