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