Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qfileselector.cpp
Go to the documentation of this file.
1// Copyright (C) 2013 BlackBerry Limited. All rights reserved.
2// Copyright (C) 2016 Intel Corporation.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#include "qfileselector.h"
6#include "qfileselector_p.h"
7
8#include <QtCore/QFile>
9#include <QtCore/QDir>
10#include <QtCore/QMutex>
11#include <QtCore/private/qlocking_p.h>
12#include <QtCore/QUrl>
13#include <QtCore/QFileInfo>
14#include <QtCore/QLocale>
15#include <QtCore/QDebug>
16
18
19using namespace Qt::StringLiterals;
20
21//Environment variable to allow tooling full control of file selectors
22static const char env_override[] = "QT_NO_BUILTIN_SELECTORS";
23
25Q_CONSTINIT static QBasicMutex sharedDataMutex;
26
31
137 : QObject(*(new QFileSelectorPrivate()), parent)
138{
139}
140
147
158{
159 Q_D(const QFileSelector);
160 return d->select(filePath);
161}
162
163static bool isLocalScheme(const QString &file)
164{
165 bool local = file == "qrc"_L1;
166#ifdef Q_OS_ANDROID
167 local |= file == "assets"_L1;
168#endif
169 return local;
170}
171
179QUrl QFileSelector::select(const QUrl &filePath) const
180{
181 Q_D(const QFileSelector);
182 if (!isLocalScheme(filePath.scheme()) && !filePath.isLocalFile())
183 return filePath;
184 QUrl ret(filePath);
185 if (isLocalScheme(filePath.scheme())) {
186 auto scheme = ":"_L1;
187#ifdef Q_OS_ANDROID
188 // use other scheme because ":" means "qrc" here
189 if (filePath.scheme() == "assets"_L1)
190 scheme = "assets:"_L1;
191#endif
192
193 QString equivalentPath = scheme + filePath.path();
194 QString selectedPath = d->select(equivalentPath);
195 ret.setPath(selectedPath.remove(0, scheme.size()));
196 } else {
197 // we need to store the original query and fragment, since toLocalFile() will strip it off
198 QString frag;
199 if (ret.hasFragment())
200 frag = ret.fragment();
202 if (ret.hasQuery())
203 query= ret.query();
204 ret = QUrl::fromLocalFile(d->select(ret.toLocalFile()));
205 if (!frag.isNull())
206 ret.setFragment(frag);
207 if (!query.isNull())
208 ret.setQuery(query);
209 }
210 return ret;
211}
212
214 const QStringList &selectors, QChar indicator)
215{
216 /* selectionHelper does a depth-first search of possible selected files. Because there is strict
217 selector ordering in the API, we can stop checking as soon as we find the file in a directory
218 which does not contain any other valid selector directories.
219 */
220 Q_ASSERT(path.isEmpty() || path.endsWith(u'/'));
221
222 for (const QString &s : selectors) {
223 QString prospectiveBase = path;
224 if (!indicator.isNull())
225 prospectiveBase += indicator;
226 prospectiveBase += s + u'/';
227 QStringList remainingSelectors = selectors;
228 remainingSelectors.removeAll(s);
229 if (!QDir(prospectiveBase).exists())
230 continue;
231 QString prospectiveFile = selectionHelper(prospectiveBase, fileName, remainingSelectors, indicator);
232 if (!prospectiveFile.isEmpty())
233 return prospectiveFile;
234 }
235
236 // If we reach here there were no successful files found at a lower level in this branch, so we
237 // should check this level as a potential result.
239 return QString();
240 return path + fileName;
241}
242
244{
245 Q_Q(const QFileSelector);
246 QFileInfo fi(filePath);
247
249 if (auto path = fi.path(); !path.isEmpty())
250 pathString = path.endsWith(u'/') ? path : path + u'/';
252 fi.fileName(), q->allSelectors());
253
254 if (!ret.isEmpty())
255 return ret;
256 return filePath;
257}
258
263{
264 Q_D(const QFileSelector);
265 return d->extras;
266}
267
274{
275 Q_D(QFileSelector);
276 d->extras = list;
277}
278
283{
284 Q_D(const QFileSelector);
285 const auto locker = qt_scoped_lock(sharedDataMutex);
287 return d->extras + sharedData->staticSelectors;
288}
289
291{
292 if (!sharedData->staticSelectors.isEmpty())
293 return; //Already loaded
294
295 QLatin1Char pathSep(',');
296 QStringList envSelectors = QString::fromLatin1(qgetenv("QT_FILE_SELECTORS"))
297 .split(pathSep, Qt::SkipEmptyParts);
298 if (envSelectors.size())
299 sharedData->staticSelectors << envSelectors;
300
302 return;
303
304 sharedData->staticSelectors << sharedData->preloadedStatics; //Potential for static selectors from other modules
305
306 // TODO: Update on locale changed?
307 sharedData->staticSelectors << QLocale().name();
308
309 sharedData->staticSelectors << platformSelectors();
310}
311
313{
314 // similar, but not identical to QSysInfo::osType
316#if defined(Q_OS_WIN)
317 ret << QStringLiteral("windows");
318 ret << QSysInfo::kernelType(); // "winnt"
319#elif defined(Q_OS_UNIX)
320 ret << QStringLiteral("unix");
321# if !defined(Q_OS_ANDROID) && !defined(Q_OS_QNX)
322 // we don't want "linux" for Android or two instances of "qnx" for QNX
324# endif
325 QString productName = QSysInfo::productType();
326 if (productName != "unknown"_L1)
327 ret << productName; // "opensuse", "fedora", "osx", "ios", "android"
328#endif
329 return ret;
330}
331
333{
334 const auto locker = qt_scoped_lock(sharedDataMutex);
335 sharedData->preloadedStatics << statics;
336 sharedData->staticSelectors.clear();
337}
338
340
341#include "moc_qfileselector.cpp"
\inmodule QtCore
\inmodule QtCore
Definition qdir.h:20
bool exists() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qdir.cpp:1715
static void addStatics(const QStringList &)
static QString selectionHelper(const QString &path, const QString &fileName, const QStringList &selectors, QChar indicator=u'+')
static void updateSelectors()
static QStringList platformSelectors()
QString select(const QString &filePath) const
\inmodule QtCore
QStringList extraSelectors() const
Returns the list of extra selectors which have been added programmatically to this instance.
void setExtraSelectors(const QStringList &list)
Sets the list of extra selectors which have been added programmatically to this instance.
QStringList allSelectors() const
Returns the complete, ordered list of selectors used by this instance.
QString select(const QString &filePath) const
This function returns the selected version of the path, based on the conditions at runtime.
~QFileSelector()
Destroys this selector instance.
QFileSelector(QObject *parent=nullptr)
Create a QFileSelector instance.
bool exists() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qfile.cpp:351
QString name(TagSeparator separator=TagSeparator::Underscore) const
The short name of this locale.
Definition qlocale.cpp:1412
\inmodule QtCore
Definition qmutex.h:281
\inmodule QtCore
Definition qobject.h:103
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5871
bool endsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string ends with s; otherwise returns false.
Definition qstring.cpp:5506
static QString productType()
Definition qsysinfo.cpp:769
static QString kernelType()
Definition qsysinfo.cpp:694
\inmodule QtCore
Definition qurl.h:94
static QUrl fromLocalFile(const QString &localfile)
Returns a QUrl representation of localFile, interpreted as a local file.
Definition qurl.cpp:3368
bool isLocalFile() const
Definition qurl.cpp:3445
QString scheme() const
Returns the scheme of the URL.
Definition qurl.cpp:1991
QString path(ComponentFormattingOptions options=FullyDecoded) const
Returns the path of the URL.
Definition qurl.cpp:2468
Combined button and popup list for selecting options.
@ SkipEmptyParts
Definition qnamespace.h:128
static bool isLocalScheme(const QString &file)
static const char env_override[]
static Q_CONSTINIT QBasicMutex sharedDataMutex
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
return ret
GLenum GLsizei const void * pathString
GLdouble s
[6]
Definition qopenglext.h:235
GLenum query
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLsizei const GLchar *const * path
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define QStringLiteral(str)
Q_CORE_EXPORT QByteArray qgetenv(const char *varName)
Q_CORE_EXPORT bool qEnvironmentVariableIsEmpty(const char *varName) noexcept
QList< int > list
[14]
QFile file
[0]
\inmodule QtCore \reentrant
Definition qchar.h:18