Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qabstractfileiconprovider.cpp
Go to the documentation of this file.
1// Copyright (C) 2020 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
6
7#include <qguiapplication.h>
8#include <private/qguiapplication_p.h>
9#include <qpa/qplatformtheme.h>
10#include <qicon.h>
11#if QT_CONFIG(mimetype)
12#include <qmimedatabase.h>
13#endif
14
15
16#include <private/qabstractfileiconprovider_p.h>
17#include <private/qfilesystementry_p.h>
18
20
21using namespace Qt::StringLiterals;
22
23QAbstractFileIconProviderPrivate::QAbstractFileIconProviderPrivate(QAbstractFileIconProvider *q)
24 : q_ptr(q)
25{}
26
27QAbstractFileIconProviderPrivate::~QAbstractFileIconProviderPrivate() = default;
28
29using IconTypeCache = QHash<QAbstractFileIconProvider::IconType, QIcon>;
31
32void QAbstractFileIconProviderPrivate::clearIconTypeCache()
33{
34 iconTypeCache()->clear();
35}
36
37QIcon QAbstractFileIconProviderPrivate::getPlatformThemeIcon(QAbstractFileIconProvider::IconType type) const
38{
39 auto theme = QGuiApplicationPrivate::platformTheme();
40 if (theme == nullptr)
41 return {};
42
43 if (theme->themeHint(QPlatformTheme::PreferFileIconFromTheme).toBool()) {
44 const QIcon result = getIconThemeIcon(type);
45 if (!result.isNull())
46 return result;
47 }
48
49 auto &cache = *iconTypeCache();
50 auto it = cache.find(type);
51 if (it == cache.end()) {
52 const auto sp = [&]() -> QPlatformTheme::StandardPixmap {
53 switch (type) {
54 case QAbstractFileIconProvider::Computer:
55 return QPlatformTheme::ComputerIcon;
56 case QAbstractFileIconProvider::Desktop:
57 return QPlatformTheme::DesktopIcon;
58 case QAbstractFileIconProvider::Trashcan:
59 return QPlatformTheme::TrashIcon;
60 case QAbstractFileIconProvider::Network:
61 return QPlatformTheme::DriveNetIcon;
62 case QAbstractFileIconProvider::Drive:
63 return QPlatformTheme::DriveHDIcon;
64 case QAbstractFileIconProvider::Folder:
65 return QPlatformTheme::DirIcon;
66 case QAbstractFileIconProvider::File:
67 break;
68 // no default on purpose; we want warnings when the type enum is extended
69 }
70 return QPlatformTheme::FileIcon;
71 }();
72
73 const auto sizesHint = theme->themeHint(QPlatformTheme::IconPixmapSizes);
74 auto sizes = sizesHint.value<QList<QSize>>();
75 if (sizes.isEmpty())
76 sizes.append({64, 64});
77
78 QIcon icon;
79 for (const auto &size : sizes)
80 icon.addPixmap(theme->standardPixmap(sp, size));
81 it = cache.insert(type, icon);
82 }
83 return it.value();
84}
85
86QIcon QAbstractFileIconProviderPrivate::getIconThemeIcon(QAbstractFileIconProvider::IconType type) const
87{
88 switch (type) {
89 case QAbstractFileIconProvider::Computer:
90 return QIcon::fromTheme("computer"_L1);
91 case QAbstractFileIconProvider::Desktop:
92 return QIcon::fromTheme("user-desktop"_L1);
93 case QAbstractFileIconProvider::Trashcan:
94 return QIcon::fromTheme("user-trash"_L1);
95 case QAbstractFileIconProvider::Network:
96 return QIcon::fromTheme("network-workgroup"_L1);
97 case QAbstractFileIconProvider::Drive:
98 return QIcon::fromTheme("drive-harddisk"_L1);
99 case QAbstractFileIconProvider::Folder:
100 return QIcon::fromTheme("folder"_L1);
101 case QAbstractFileIconProvider::File:
102 return QIcon::fromTheme("text-x-generic"_L1);
103 // no default on purpose; we want warnings when the type enum is extended
104 }
105 return QIcon::fromTheme("text-x-generic"_L1);
106}
107
108static inline QPlatformTheme::IconOptions toThemeIconOptions(QAbstractFileIconProvider::Options options)
109{
110 QPlatformTheme::IconOptions result;
111 if (options.testFlag(QAbstractFileIconProvider::DontUseCustomDirectoryIcons))
112 result |= QPlatformTheme::DontUseCustomDirectoryIcons;
113 return result;
114}
115
116QIcon QAbstractFileIconProviderPrivate::getPlatformThemeIcon(const QFileInfo &info) const
117{
118 if (auto theme = QGuiApplicationPrivate::platformTheme()) {
119 if (theme->themeHint(QPlatformTheme::PreferFileIconFromTheme).toBool()) {
120 const QIcon result = getIconThemeIcon(info);
121 if (!result.isNull())
122 return result;
123 }
124 return theme->fileIcon(info, toThemeIconOptions(options));
125 }
126 return {};
127}
128
129QIcon QAbstractFileIconProviderPrivate::getIconThemeIcon(const QFileInfo &info) const
130{
131 if (info.isRoot())
132 return getIconThemeIcon(QAbstractFileIconProvider::Drive);
133 if (info.isDir())
134 return getIconThemeIcon(QAbstractFileIconProvider::Folder);
135#if QT_CONFIG(mimetype)
136 return QIcon::fromTheme(mimeDatabase.mimeTypeForFile(info).iconName());
137#else
138 return QIcon::fromTheme("text-x-generic"_L1);
139#endif
140}
141
142/*!
143 \class QAbstractFileIconProvider
144
145 \inmodule QtGui
146 \since 6.0
147
148 \brief The QAbstractFileIconProvider class provides file icons for the QFileSystemModel class.
149*/
150
151/*!
152 \enum QAbstractFileIconProvider::IconType
153
154 \value Computer The icon used for the computing device as a whole
155 \value Desktop The icon for the special "Desktop" directory of the user
156 \value Trashcan The icon for the user's "Trash" place in the desktop's file manager
157 \value Network The icon for the “Network Servers” place in the desktop's file manager,
158 and workgroups within the network
159 \value Drive The icon used for disk drives
160 \value Folder The standard folder icon used to represent directories on local filesystems
161 \value File The icon used for generic text file types
162*/
163
164/*!
165 \enum QAbstractFileIconProvider::Option
166
167 \value DontUseCustomDirectoryIcons Always use the default directory icon.
168 Some platforms allow the user to set a different icon. Custom icon lookup
169 cause a big performance impact over network or removable drives.
170*/
171
172/*!
173 Constructs a file icon provider.
174*/
175QAbstractFileIconProvider::QAbstractFileIconProvider()
176 : d_ptr(new QAbstractFileIconProviderPrivate(this))
177{
178}
179
180/*!
181 \internal
182*/
183QAbstractFileIconProvider::QAbstractFileIconProvider(QAbstractFileIconProviderPrivate &dd)
184 : d_ptr(&dd)
185{}
186
187/*!
188 Destroys the file icon provider.
189*/
190
191QAbstractFileIconProvider::~QAbstractFileIconProvider() = default;
192
193
194/*!
195 Sets \a options that affect the icon provider.
196 \sa options()
197*/
198
199void QAbstractFileIconProvider::setOptions(QAbstractFileIconProvider::Options options)
200{
201 Q_D(QAbstractFileIconProvider);
202 d->options = options;
203}
204
205/*!
206 Returns all the options that affect the icon provider.
207 By default, all options are disabled.
208 \sa setOptions()
209*/
210
211QAbstractFileIconProvider::Options QAbstractFileIconProvider::options() const
212{
213 Q_D(const QAbstractFileIconProvider);
214 return d->options;
215}
216
217/*!
218 Returns an icon set for the given \a type, using the current
219 icon theme.
220
221 \sa QIcon::fromTheme
222*/
223
224QIcon QAbstractFileIconProvider::icon(IconType type) const
225{
226 Q_D(const QAbstractFileIconProvider);
227 return d->getPlatformThemeIcon(type);
228}
229
230/*!
231 Returns an icon for the file described by \a info, using the
232 current icon theme.
233
234 \sa QIcon::fromTheme
235*/
236
237QIcon QAbstractFileIconProvider::icon(const QFileInfo &info) const
238{
239 Q_D(const QAbstractFileIconProvider);
240 return d->getPlatformThemeIcon(info);
241}
242
243
244QString QAbstractFileIconProviderPrivate::getFileType(const QFileInfo &info)
245{
246 if (QFileSystemEntry::isRootPath(info.absoluteFilePath()))
247 return QGuiApplication::translate("QAbstractFileIconProvider", "Drive");
248 if (info.isFile()) {
249#if QT_CONFIG(mimetype)
250 const QMimeType mimeType = QMimeDatabase().mimeTypeForFile(info);
251 return mimeType.comment().isEmpty() ? mimeType.name() : mimeType.comment();
252#else
253 return QGuiApplication::translate("QAbstractFileIconProvider", "File");
254#endif
255 }
256
257 if (info.isDir())
258#ifdef Q_OS_WIN
259 return QGuiApplication::translate("QAbstractFileIconProvider", "File Folder", "Match Windows Explorer");
260#else
261 return QGuiApplication::translate("QAbstractFileIconProvider", "Folder", "All other platforms");
262#endif
263 // Windows - "File Folder"
264 // macOS - "Folder"
265 // Konqueror - "Folder"
266 // Nautilus - "folder"
267
268 if (info.isSymLink())
269#ifdef Q_OS_MACOS
270 return QGuiApplication::translate("QAbstractFileIconProvider", "Alias", "macOS Finder");
271#else
272 return QGuiApplication::translate("QAbstractFileIconProvider", "Shortcut", "All other platforms");
273#endif
274 // macOS - "Alias"
275 // Windows - "Shortcut"
276 // Konqueror - "Folder" or "TXT File" i.e. what it is pointing to
277 // Nautilus - "link to folder" or "link to object file", same as Konqueror
278
279 return QGuiApplication::translate("QAbstractFileIconProvider", "Unknown");
280}
281
282/*!
283 Returns the type of the file described by \a info.
284*/
285
286QString QAbstractFileIconProvider::type(const QFileInfo &info) const
287{
288 return QAbstractFileIconProviderPrivate::getFileType(info);
289}
290
291QT_END_NAMESPACE
292
293#include "moc_qabstractfileiconprovider.cpp"
Combined button and popup list for selecting options.
static QPlatformTheme::IconOptions toThemeIconOptions(QAbstractFileIconProvider::Options options)
Q_GLOBAL_STATIC(QReadWriteLock, g_updateMutex)