1 | /**************************************************************************** |
---|---|
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the QtWidgets module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:LGPL$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU Lesser General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the |
21 | ** packaging of this file. Please review the following information to |
22 | ** ensure the GNU Lesser General Public License version 3 requirements |
23 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. |
24 | ** |
25 | ** GNU General Public License Usage |
26 | ** Alternatively, this file may be used under the terms of the GNU |
27 | ** General Public License version 2.0 or (at your option) the GNU General |
28 | ** Public license version 3 or any later version approved by the KDE Free |
29 | ** Qt Foundation. The licenses are as published by the Free Software |
30 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 |
31 | ** included in the packaging of this file. Please review the following |
32 | ** information to ensure the GNU General Public License requirements will |
33 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and |
34 | ** https://www.gnu.org/licenses/gpl-3.0.html. |
35 | ** |
36 | ** $QT_END_LICENSE$ |
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 <private/qfilesystementry_p.h> |
50 | #include <qpa/qplatformintegration.h> |
51 | #include <qpa/qplatformservices.h> |
52 | #include <qpa/qplatformtheme.h> |
53 | |
54 | #if defined(Q_OS_WIN) |
55 | # include <qt_windows.h> |
56 | # include <commctrl.h> |
57 | # include <objbase.h> |
58 | #endif |
59 | |
60 | QT_BEGIN_NAMESPACE |
61 | |
62 | /*! |
63 | \class QFileIconProvider |
64 | |
65 | \inmodule QtWidgets |
66 | |
67 | \brief The QFileIconProvider class provides file icons for the QFileSystemModel class. |
68 | */ |
69 | |
70 | QFileIconProviderPrivate::QFileIconProviderPrivate(QFileIconProvider *q) |
71 | : QAbstractFileIconProviderPrivate(q), homePath(QDir::home().absolutePath()) |
72 | { |
73 | } |
74 | |
75 | QIcon QFileIconProviderPrivate::getIcon(QStyle::StandardPixmap name) const |
76 | { |
77 | switch (name) { |
78 | case QStyle::SP_FileIcon: |
79 | if (file.isNull()) |
80 | file = QApplication::style()->standardIcon(name); |
81 | return file; |
82 | case QStyle::SP_FileLinkIcon: |
83 | if (fileLink.isNull()) |
84 | fileLink = QApplication::style()->standardIcon(name); |
85 | return fileLink; |
86 | case QStyle::SP_DirIcon: |
87 | if (directory.isNull()) |
88 | directory = QApplication::style()->standardIcon(name); |
89 | return directory; |
90 | case QStyle::SP_DirLinkIcon: |
91 | if (directoryLink.isNull()) |
92 | directoryLink = QApplication::style()->standardIcon(name); |
93 | return directoryLink; |
94 | case QStyle::SP_DriveHDIcon: |
95 | if (harddisk.isNull()) |
96 | harddisk = QApplication::style()->standardIcon(name); |
97 | return harddisk; |
98 | case QStyle::SP_DriveFDIcon: |
99 | if (floppy.isNull()) |
100 | floppy = QApplication::style()->standardIcon(name); |
101 | return floppy; |
102 | case QStyle::SP_DriveCDIcon: |
103 | if (cdrom.isNull()) |
104 | cdrom = QApplication::style()->standardIcon(name); |
105 | return cdrom; |
106 | case QStyle::SP_DriveNetIcon: |
107 | if (network.isNull()) |
108 | network = QApplication::style()->standardIcon(name); |
109 | return network; |
110 | case QStyle::SP_ComputerIcon: |
111 | if (computer.isNull()) |
112 | computer = QApplication::style()->standardIcon(name); |
113 | return computer; |
114 | case QStyle::SP_DesktopIcon: |
115 | if (desktop.isNull()) |
116 | desktop = QApplication::style()->standardIcon(name); |
117 | return desktop; |
118 | case QStyle::SP_TrashIcon: |
119 | if (trashcan.isNull()) |
120 | trashcan = QApplication::style()->standardIcon(name); |
121 | return trashcan; |
122 | case QStyle::SP_DirHomeIcon: |
123 | if (home.isNull()) |
124 | home = QApplication::style()->standardIcon(name); |
125 | return home; |
126 | default: |
127 | return QIcon(); |
128 | } |
129 | return QIcon(); |
130 | } |
131 | |
132 | /*! |
133 | Constructs a file icon provider. |
134 | */ |
135 | |
136 | QFileIconProvider::QFileIconProvider() |
137 | : QAbstractFileIconProvider(*new QFileIconProviderPrivate(this)) |
138 | { |
139 | } |
140 | |
141 | /*! |
142 | Destroys the file icon provider. |
143 | */ |
144 | |
145 | QFileIconProvider::~QFileIconProvider() = default; |
146 | |
147 | /*! |
148 | \reimp |
149 | */ |
150 | |
151 | QIcon QFileIconProvider::icon(IconType type) const |
152 | { |
153 | Q_D(const QFileIconProvider); |
154 | switch (type) { |
155 | case Computer: |
156 | return d->getIcon(QStyle::SP_ComputerIcon); |
157 | case Desktop: |
158 | return d->getIcon(QStyle::SP_DesktopIcon); |
159 | case Trashcan: |
160 | return d->getIcon(QStyle::SP_TrashIcon); |
161 | case Network: |
162 | return d->getIcon(QStyle::SP_DriveNetIcon); |
163 | case Drive: |
164 | return d->getIcon(QStyle::SP_DriveHDIcon); |
165 | case Folder: |
166 | return d->getIcon(QStyle::SP_DirIcon); |
167 | case File: |
168 | return d->getIcon(QStyle::SP_FileIcon); |
169 | default: |
170 | break; |
171 | }; |
172 | return QIcon(); |
173 | } |
174 | |
175 | static inline QPlatformTheme::IconOptions toThemeIconOptions(QFileIconProvider::Options options) |
176 | { |
177 | QPlatformTheme::IconOptions result; |
178 | if (options & QFileIconProvider::DontUseCustomDirectoryIcons) |
179 | result |= QPlatformTheme::DontUseCustomDirectoryIcons; |
180 | return result; |
181 | } |
182 | |
183 | QIcon QFileIconProviderPrivate::getIcon(const QFileInfo &fi) const |
184 | { |
185 | return QGuiApplicationPrivate::platformTheme()->fileIcon(fi, toThemeIconOptions(options)); |
186 | } |
187 | |
188 | /*! |
189 | \reimp |
190 | */ |
191 | |
192 | QIcon QFileIconProvider::icon(const QFileInfo &info) const |
193 | { |
194 | Q_D(const QFileIconProvider); |
195 | |
196 | QIcon retIcon = d->getIcon(info); |
197 | if (!retIcon.isNull()) |
198 | return retIcon; |
199 | |
200 | const QString &path = info.absoluteFilePath(); |
201 | if (path.isEmpty() || QFileSystemEntry::isRootPath(path)) |
202 | #if defined (Q_OS_WIN) |
203 | { |
204 | UINT type = GetDriveType(reinterpret_cast<const wchar_t *>(path.utf16())); |
205 | |
206 | switch (type) { |
207 | case DRIVE_REMOVABLE: |
208 | return d->getIcon(QStyle::SP_DriveFDIcon); |
209 | case DRIVE_FIXED: |
210 | return d->getIcon(QStyle::SP_DriveHDIcon); |
211 | case DRIVE_REMOTE: |
212 | return d->getIcon(QStyle::SP_DriveNetIcon); |
213 | case DRIVE_CDROM: |
214 | return d->getIcon(QStyle::SP_DriveCDIcon); |
215 | case DRIVE_RAMDISK: |
216 | case DRIVE_UNKNOWN: |
217 | case DRIVE_NO_ROOT_DIR: |
218 | default: |
219 | return d->getIcon(QStyle::SP_DriveHDIcon); |
220 | } |
221 | } |
222 | #else |
223 | return d->getIcon(QStyle::SP_DriveHDIcon); |
224 | #endif |
225 | |
226 | if (info.isFile()) { |
227 | if (info.isSymLink()) |
228 | return d->getIcon(QStyle::SP_FileLinkIcon); |
229 | else |
230 | return d->getIcon(QStyle::SP_FileIcon); |
231 | } |
232 | if (info.isDir()) { |
233 | if (info.isSymLink()) { |
234 | return d->getIcon(QStyle::SP_DirLinkIcon); |
235 | } else { |
236 | if (info.absoluteFilePath() == d->homePath) { |
237 | return d->getIcon(QStyle::SP_DirHomeIcon); |
238 | } else { |
239 | return d->getIcon(QStyle::SP_DirIcon); |
240 | } |
241 | } |
242 | } |
243 | return QIcon(); |
244 | } |
245 | |
246 | QT_END_NAMESPACE |
247 |