QLibraryInfo: Introduce paths
QLibraryInfo::path only allows a single value, however, at least for QmlImportsPath we would benefit from having more than one to ease deployment (note that this is unrelated to Qml2ImportsPath which was necessary to support QML 1 and 2 in a single Qt install). Users inside Qt will ported in follow-up patches where it makes sense. [ChangeLog][QLibraryInfo] qt.conf now allows providing mutliple paths, and QLibraryInfo has a new paths method to fetch all of them. Task-number: QTBUG-124009 Change-Id: I78b3bcfa94c8d975dbd789f6826cda4fc5e60403 Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
This commit is contained in:
parent
f65d11ecbf
commit
ef2912334c
@ -516,12 +516,27 @@ QLibraryInfoPrivate::LocationInfo QLibraryInfoPrivate::locationInfo(QLibraryInfo
|
||||
/*!
|
||||
\since 6.0
|
||||
Returns the path specified by \a p.
|
||||
|
||||
If there is more than one path listed in qt.conf, it will
|
||||
only return the first one.
|
||||
\sa paths
|
||||
*/
|
||||
QString QLibraryInfo::path(LibraryPath p)
|
||||
{
|
||||
return QLibraryInfoPrivate::path(p);
|
||||
}
|
||||
|
||||
/*!
|
||||
\since 6.8
|
||||
Returns all paths specificied by \a p.
|
||||
|
||||
\sa path
|
||||
*/
|
||||
QStringList QLibraryInfo::paths(LibraryPath p)
|
||||
{
|
||||
return QLibraryInfoPrivate::paths(p);
|
||||
}
|
||||
|
||||
|
||||
static QString normalizePath(QString ret)
|
||||
{
|
||||
@ -573,6 +588,64 @@ static QVariant libraryPathToValue(QLibraryInfo::LibraryPath loc)
|
||||
}
|
||||
#endif // settings
|
||||
|
||||
QStringList QLibraryInfoPrivate::paths(QLibraryInfo::LibraryPath p,
|
||||
QLibraryInfoPrivate::UsageMode usageMode)
|
||||
{
|
||||
const QLibraryInfo::LibraryPath loc = p;
|
||||
QList<QString> ret;
|
||||
bool fromConf = false;
|
||||
#if QT_CONFIG(settings)
|
||||
if (havePaths()) {
|
||||
fromConf = true;
|
||||
|
||||
QVariant value = libraryPathToValue(loc);
|
||||
if (value.isValid()) {
|
||||
|
||||
if (auto *asList = get_if<QList<QString>>(&value))
|
||||
ret = std::move(*asList);
|
||||
else
|
||||
ret = QList<QString>({ std::move(value).toString()});
|
||||
for (qsizetype i = 0, end = ret.size(); i < end; ++i)
|
||||
ret[i] = normalizePath(ret[i]);
|
||||
}
|
||||
}
|
||||
#endif // settings
|
||||
|
||||
if (!fromConf) {
|
||||
QString noConfResult;
|
||||
if (loc == QLibraryInfo::PrefixPath) {
|
||||
noConfResult = getPrefix(usageMode);
|
||||
} else if (int(loc) <= qt_configure_strs.count()) {
|
||||
noConfResult = QString::fromLocal8Bit(qt_configure_strs.viewAt(loc - 1));
|
||||
#ifndef Q_OS_WIN // On Windows we use the registry
|
||||
} else if (loc == QLibraryInfo::SettingsPath) {
|
||||
// Use of volatile is a hack to discourage compilers from calling
|
||||
// strlen(), in the inlined fromLocal8Bit(const char *)'s body, at
|
||||
// compile-time, as Qt installers binary-patch the path, replacing
|
||||
// the dummy path seen at compile-time, typically changing length.
|
||||
const char *volatile path = QT_CONFIGURE_SETTINGS_PATH;
|
||||
noConfResult = QString::fromLocal8Bit(path);
|
||||
#endif
|
||||
}
|
||||
if (!noConfResult.isEmpty())
|
||||
ret.push_back(std::move(noConfResult));
|
||||
}
|
||||
if (ret.isEmpty())
|
||||
return ret;
|
||||
|
||||
QString baseDir;
|
||||
if (loc == QLibraryInfo::PrefixPath) {
|
||||
baseDir = prefixFromAppDirHelper();
|
||||
} else {
|
||||
// we make any other path absolute to the prefix directory
|
||||
baseDir = QLibraryInfoPrivate::path(QLibraryInfo::PrefixPath, usageMode);
|
||||
}
|
||||
for (qsizetype i = 0, end = ret.size(); i < end; ++i)
|
||||
if (QDir::isRelativePath(ret[i]))
|
||||
ret[i] = QDir::cleanPath(baseDir + u'/' + std::move(ret[i]));
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
Returns the path specified by \a p.
|
||||
|
||||
@ -581,49 +654,7 @@ static QVariant libraryPathToValue(QLibraryInfo::LibraryPath loc)
|
||||
*/
|
||||
QString QLibraryInfoPrivate::path(QLibraryInfo::LibraryPath p, UsageMode usageMode)
|
||||
{
|
||||
const QLibraryInfo::LibraryPath loc = p;
|
||||
QString ret;
|
||||
bool fromConf = false;
|
||||
#if QT_CONFIG(settings)
|
||||
if (havePaths()) {
|
||||
fromConf = true;
|
||||
|
||||
QVariant value = libraryPathToValue(loc);
|
||||
if (value.isValid()) {
|
||||
ret = std::move(value).toString();
|
||||
ret = normalizePath(std::move(ret));
|
||||
}
|
||||
}
|
||||
#endif // settings
|
||||
|
||||
if (!fromConf) {
|
||||
if (loc == QLibraryInfo::PrefixPath) {
|
||||
ret = getPrefix(usageMode);
|
||||
} else if (int(loc) <= qt_configure_strs.count()) {
|
||||
ret = QString::fromLocal8Bit(qt_configure_strs.viewAt(loc - 1));
|
||||
#ifndef Q_OS_WIN // On Windows we use the registry
|
||||
} else if (loc == QLibraryInfo::SettingsPath) {
|
||||
// Use of volatile is a hack to discourage compilers from calling
|
||||
// strlen(), in the inlined fromLocal8Bit(const char *)'s body, at
|
||||
// compile-time, as Qt installers binary-patch the path, replacing
|
||||
// the dummy path seen at compile-time, typically changing length.
|
||||
const char *volatile path = QT_CONFIGURE_SETTINGS_PATH;
|
||||
ret = QString::fromLocal8Bit(path);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (!ret.isEmpty() && QDir::isRelativePath(ret)) {
|
||||
QString baseDir;
|
||||
if (loc == QLibraryInfo::PrefixPath) {
|
||||
baseDir = prefixFromAppDirHelper();
|
||||
} else {
|
||||
// we make any other path absolute to the prefix directory
|
||||
baseDir = path(QLibraryInfo::PrefixPath, usageMode);
|
||||
}
|
||||
ret = QDir::cleanPath(baseDir + u'/' + ret);
|
||||
}
|
||||
return ret;
|
||||
return paths(p, usageMode).value(0, QString());
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -42,6 +42,7 @@ public:
|
||||
SettingsPath = 100
|
||||
};
|
||||
static QString path(LibraryPath p);
|
||||
static QStringList paths(LibraryPath p);
|
||||
#if QT_DEPRECATED_SINCE(6, 0)
|
||||
using LibraryLocation = LibraryPath;
|
||||
QT_DEPRECATED_VERSION_X_6_0("Use path()")
|
||||
|
@ -50,6 +50,7 @@ public:
|
||||
};
|
||||
|
||||
static QString path(QLibraryInfo::LibraryPath p, UsageMode usageMode = RegularUsage);
|
||||
static QList<QString> paths(QLibraryInfo::LibraryPath p, UsageMode usageMode = RegularUsage);
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -14,4 +14,10 @@ qt_internal_add_test(tst_qlibraryinfo SOURCES tst_qlibraryinfo.cpp
|
||||
|
||||
)
|
||||
|
||||
qt_add_resources(tst_qlibraryinfo "qtconffiles" PREFIX "/" FILES empty.qt.conf partial.qt.conf)
|
||||
qt_add_resources(tst_qlibraryinfo "qtconffiles"
|
||||
PREFIX "/"
|
||||
FILES
|
||||
empty.qt.conf
|
||||
partial.qt.conf
|
||||
list.qt.conf
|
||||
)
|
||||
|
2
tests/auto/corelib/global/qlibraryinfo/list.qt.conf
Normal file
2
tests/auto/corelib/global/qlibraryinfo/list.qt.conf
Normal file
@ -0,0 +1,2 @@
|
||||
[Paths]
|
||||
Documentation = "/path/to/mydoc","/path/to/anotherdoc","relativePath"
|
@ -15,6 +15,7 @@ private slots:
|
||||
void cleanup();
|
||||
void path_data();
|
||||
void path();
|
||||
void paths();
|
||||
};
|
||||
|
||||
void tst_QLibraryInfo::initTestCase()
|
||||
@ -59,6 +60,24 @@ void tst_QLibraryInfo::path()
|
||||
QString value = QLibraryInfo::path(path);
|
||||
QCOMPARE(value, expected);
|
||||
|
||||
// check consistency with paths
|
||||
auto values = QLibraryInfo::paths(path);
|
||||
QVERIFY(!values.isEmpty());
|
||||
QCOMPARE(values.first(), expected);
|
||||
}
|
||||
|
||||
void tst_QLibraryInfo::paths()
|
||||
{
|
||||
QString qtConfPath(u":/list.qt.conf");
|
||||
QLibraryInfoPrivate::setQtconfManualPath(&qtConfPath);
|
||||
QLibraryInfoPrivate::reload();
|
||||
|
||||
QList<QString> values = QLibraryInfo::paths(QLibraryInfo::DocumentationPath);
|
||||
QCOMPARE(values.length(), 3);
|
||||
QCOMPARE(values[0], "/path/to/mydoc");
|
||||
QCOMPARE(values[1], "/path/to/anotherdoc");
|
||||
QString baseDir = QCoreApplication::applicationDirPath();
|
||||
QCOMPARE(values[2], baseDir + "/relativePath");
|
||||
}
|
||||
|
||||
QTEST_GUILESS_MAIN(tst_QLibraryInfo)
|
||||
|
Loading…
x
Reference in New Issue
Block a user