[neon/qt6/qt6-base/Neon/release] debian/patches: qmimedatabase_collect_glob_patterns_from_all_locations
Carlos De Maine
null at kde.org
Thu Jan 11 03:40:35 GMT 2024
Git commit 55e7422eeb128b81cf07d202b463c3d3feaf7e34 by Carlos De Maine.
Committed on 11/01/2024 at 04:40.
Pushed by carlosdem into branch 'Neon/release'.
qmimedatabase_collect_glob_patterns_from_all_locations
A +1185 -0 debian/patches/qmimedatabase_collect_glob_patterns_from_all_locations
M +1 -0 debian/patches/series
https://invent.kde.org/neon/qt6/qt6-base/-/commit/55e7422eeb128b81cf07d202b463c3d3feaf7e34
diff --git a/debian/patches/qmimedatabase_collect_glob_patterns_from_all_locations b/debian/patches/qmimedatabase_collect_glob_patterns_from_all_locations
new file mode 100644
index 0000000..4e82a9e
--- /dev/null
+++ b/debian/patches/qmimedatabase_collect_glob_patterns_from_all_locations
@@ -0,0 +1,1185 @@
+From 705118a554083161b6fe54aaf37a04ddca844f48 Mon Sep 17 00:00:00 2001
+From: David Faure <david.faure at kdab.com>
+Date: Thu, 7 Dec 2023 11:38:38 +0100
+Subject: [PATCH] QMimeDatabase: collect glob patterns from all locations
+
+A QMimeTypePrivate used to belong to a single provider, which would
+provide the complete data for it.
+But since the redesign in commit 7a5644d6481a3c1a741677, each provider
+represents is a single mime directory, and the merging happens at the
+QMimeDatabase level. So we need a QMimeType[Private] to be just a name
+(a "request" for information about this mimetype) and the information
+for that mimetype is retrieved on demand by querying the providers
+and either stopping at the first one (e.g. for icons) or merging
+the data from all of them (e.g. for glob patterns).
+
+The XML provider was using QMimeTypePrivate as data storage,
+give it its own struct QMimeTypeXMLData for that purpose instead.
+
+Task-number: QTBUG-116905
+Change-Id: Ia0e0d94aa899720dc0b908f40c25317473005af4
+(cherry picked from commit 4e9944e6c8a456353d243ab268cb0f01ff006faa)
+Reviewed-by: Thiago Macieira <thiago.macieira at intel.com>
+---
+ src/corelib/mimetypes/qmimedatabase.cpp | 83 +++++-----
+ src/corelib/mimetypes/qmimedatabase_p.h | 9 +-
+ src/corelib/mimetypes/qmimeprovider.cpp | 168 ++++++++++++---------
+ src/corelib/mimetypes/qmimeprovider_p.h | 56 ++++---
+ src/corelib/mimetypes/qmimetype.cpp | 64 +++-----
+ src/corelib/mimetypes/qmimetype_p.h | 39 +----
+ src/corelib/mimetypes/qmimetypeparser.cpp | 20 ++-
+ src/corelib/mimetypes/qmimetypeparser_p.h | 21 ++-
+ .../mimetypes/qmimedatabase/add-extension.xml | 7 +
+ .../qmimedatabase-cache/CMakeLists.txt | 1 +
+ .../qmimedatabase/qmimedatabase-xml/CMakeLists.txt | 1 +
+ .../mimetypes/qmimedatabase/tst_qmimedatabase.cpp | 6 +
+ .../corelib/mimetypes/qmimetype/tst_qmimetype.cpp | 111 ++------------
+ 13 files changed, 258 insertions(+), 328 deletions(-)
+ create mode 100644 tests/auto/corelib/mimetypes/qmimedatabase/add-extension.xml
+
+diff --git a/src/corelib/mimetypes/qmimedatabase.cpp b/src/corelib/mimetypes/qmimedatabase.cpp
+index f2786f3723c3..a549cd3acf87 100644
+--- a/src/corelib/mimetypes/qmimedatabase.cpp
++++ b/src/corelib/mimetypes/qmimedatabase.cpp
+@@ -191,9 +191,8 @@ QMimeType QMimeDatabasePrivate::mimeTypeForName(const QString &nameOrAlias)
+ {
+ const QString mimeName = resolveAlias(nameOrAlias);
+ for (const auto &provider : providers()) {
+- QMimeType mime = provider->mimeTypeForName(mimeName);
+- if (mime.isValid())
+- return mime;
++ if (provider->knowsMimeType(mimeName))
++ return QMimeType(QMimeTypePrivate(mimeName));
+ }
+ return {};
+ }
+@@ -218,54 +217,54 @@ QMimeGlobMatchResult QMimeDatabasePrivate::findByFileName(const QString &fileNam
+ return result;
+ }
+
+-void QMimeDatabasePrivate::loadMimeTypePrivate(QMimeTypePrivate &mimePrivate)
++QMimeTypePrivate::LocaleHash QMimeDatabasePrivate::localeComments(const QString &name)
+ {
+ QMutexLocker locker(&mutex);
+- if (mimePrivate.name.isEmpty())
+- return; // invalid mimetype
+- if (!mimePrivate.loaded) { // XML provider sets loaded=true, binary provider does this on demand
+- Q_ASSERT(mimePrivate.fromCache);
+- bool found = false;
+- for (const auto &provider : providers()) {
+- if (provider->loadMimeTypePrivate(mimePrivate)) {
+- found = true;
+- break;
+- }
+- }
+- if (!found) {
+- const QString file = mimePrivate.name + ".xml"_L1;
+- qWarning() << "No file found for" << file << ", even though update-mime-info said it would exist.\n"
+- "Either it was just removed, or the directory doesn't have executable permission..."
+- << locateMimeDirectories();
+- }
+- mimePrivate.loaded = true;
++ for (const auto &provider : providers()) {
++ auto comments = provider->localeComments(name);
++ if (!comments.isEmpty())
++ return comments; // maybe we want to merge in comments from more global providers, in
++ // case of more translations?
+ }
++ return {};
+ }
+
+-void QMimeDatabasePrivate::loadGenericIcon(QMimeTypePrivate &mimePrivate)
++QStringList QMimeDatabasePrivate::globPatterns(const QString &name)
+ {
+ QMutexLocker locker(&mutex);
+- if (mimePrivate.fromCache) {
+- mimePrivate.genericIconName.clear();
+- for (const auto &provider : providers()) {
+- provider->loadGenericIcon(mimePrivate);
+- if (!mimePrivate.genericIconName.isEmpty())
+- break;
+- }
++ QStringList patterns;
++ const auto &providerList = providers();
++ // reverse iteration because we start from most global, add up, clear if delete-all, and add up
++ // again.
++ for (auto rit = providerList.rbegin(); rit != providerList.rend(); ++rit) {
++ auto *provider = rit->get();
++ if (provider->hasGlobDeleteAll(name))
++ patterns.clear();
++ patterns += provider->globPatterns(name);
+ }
++ return patterns;
+ }
+
+-void QMimeDatabasePrivate::loadIcon(QMimeTypePrivate &mimePrivate)
++QString QMimeDatabasePrivate::genericIcon(const QString &name)
+ {
+ QMutexLocker locker(&mutex);
+- if (mimePrivate.fromCache) {
+- mimePrivate.iconName.clear();
+- for (const auto &provider : providers()) {
+- provider->loadIcon(mimePrivate);
+- if (!mimePrivate.iconName.isEmpty())
+- break;
+- }
++ for (const auto &provider : providers()) {
++ QString genericIconName = provider->genericIcon(name);
++ if (!genericIconName.isEmpty())
++ return genericIconName;
+ }
++ return {};
++}
++
++QString QMimeDatabasePrivate::icon(const QString &name)
++{
++ QMutexLocker locker(&mutex);
++ for (const auto &provider : providers()) {
++ QString iconName = provider->icon(name);
++ if (!iconName.isEmpty())
++ return iconName;
++ }
++ return {};
+ }
+
+ QString QMimeDatabasePrivate::fallbackParent(const QString &mimeTypeName) const
+@@ -346,12 +345,12 @@ QMimeType QMimeDatabasePrivate::findByData(const QByteArray &data, int *accuracy
+ }
+
+ *accuracyPtr = 0;
+- QMimeType candidate;
++ QString candidate;
+ for (const auto &provider : providers())
+- provider->findByMagic(data, accuracyPtr, candidate);
++ provider->findByMagic(data, accuracyPtr, &candidate);
+
+- if (candidate.isValid())
+- return candidate;
++ if (!candidate.isEmpty())
++ return QMimeType(QMimeTypePrivate(candidate));
+
+ if (isTextFile(data)) {
+ *accuracyPtr = 5;
+diff --git a/src/corelib/mimetypes/qmimedatabase_p.h b/src/corelib/mimetypes/qmimedatabase_p.h
+index 96981ba3fe13..cb28f0b7910e 100644
+--- a/src/corelib/mimetypes/qmimedatabase_p.h
++++ b/src/corelib/mimetypes/qmimedatabase_p.h
+@@ -66,9 +66,10 @@ public:
+ QMimeGlobMatchResult findByFileName(const QString &fileName);
+
+ // API for QMimeType. Takes care of locking the mutex.
+- void loadMimeTypePrivate(QMimeTypePrivate &mimePrivate);
+- void loadGenericIcon(QMimeTypePrivate &mimePrivate);
+- void loadIcon(QMimeTypePrivate &mimePrivate);
++ QMimeTypePrivate::LocaleHash localeComments(const QString &name);
++ QStringList globPatterns(const QString &name);
++ QString genericIcon(const QString &name);
++ QString icon(const QString &name);
+ QStringList mimeParents(const QString &mimeName);
+ QStringList listAliases(const QString &mimeName);
+ bool mimeInherits(const QString &mime, const QString &parent);
+@@ -81,7 +82,7 @@ private:
+ QString fallbackParent(const QString &mimeTypeName) const;
+
+ const QString m_defaultMimeType;
+- mutable Providers m_providers;
++ mutable Providers m_providers; // most local first, most global last
+ QElapsedTimer m_lastCheck;
+
+ public:
+diff --git a/src/corelib/mimetypes/qmimeprovider.cpp b/src/corelib/mimetypes/qmimeprovider.cpp
+index 586a0c64373d..8c97c4f16bc9 100644
+--- a/src/corelib/mimetypes/qmimeprovider.cpp
++++ b/src/corelib/mimetypes/qmimeprovider.cpp
+@@ -186,25 +186,11 @@ void QMimeBinaryProvider::ensureLoaded()
+ m_cacheFile.reset();
+ }
+
+-static QMimeType mimeTypeForNameUnchecked(const QString &name)
+-{
+- QMimeTypePrivate data;
+- data.name = name;
+- data.fromCache = true;
+- // The rest is retrieved on demand.
+- // comment and globPatterns: in loadMimeTypePrivate
+- // iconName: in loadIcon
+- // genericIconName: in loadGenericIcon
+- return QMimeType(data);
+-}
+-
+-QMimeType QMimeBinaryProvider::mimeTypeForName(const QString &name)
++bool QMimeBinaryProvider::knowsMimeType(const QString &name)
+ {
+ if (!m_mimetypeListLoaded)
+ loadMimeTypeList();
+- if (!m_mimetypeNames.contains(name))
+- return QMimeType(); // unknown mimetype
+- return mimeTypeForNameUnchecked(name);
++ return m_mimetypeNames.contains(name);
+ }
+
+ void QMimeBinaryProvider::addFileNameMatches(const QString &fileName, QMimeGlobMatchResult &result)
+@@ -354,7 +340,7 @@ bool QMimeBinaryProvider::matchMagicRule(QMimeBinaryProvider::CacheFile *cacheFi
+ return false;
+ }
+
+-void QMimeBinaryProvider::findByMagic(const QByteArray &data, int *accuracyPtr, QMimeType &candidate)
++void QMimeBinaryProvider::findByMagic(const QByteArray &data, int *accuracyPtr, QString *candidate)
+ {
+ const int magicListOffset = m_cacheFile->getUint32(PosMagicListOffset);
+ const int numMatches = m_cacheFile->getUint32(magicListOffset);
+@@ -371,7 +357,7 @@ void QMimeBinaryProvider::findByMagic(const QByteArray &data, int *accuracyPtr,
+ *accuracyPtr = m_cacheFile->getUint32(off);
+ // Return the first match. We have no rules for conflicting magic data...
+ // (mime.cache itself is sorted, but what about local overrides with a lower prio?)
+- candidate = mimeTypeForNameUnchecked(QLatin1StringView(mimeType));
++ *candidate = QString::fromLatin1(mimeType);
+ return;
+ }
+ }
+@@ -479,35 +465,63 @@ void QMimeBinaryProvider::addAllMimeTypes(QList<QMimeType> &result)
+ if (result.isEmpty()) {
+ result.reserve(m_mimetypeNames.size());
+ for (const QString &name : std::as_const(m_mimetypeNames))
+- result.append(mimeTypeForNameUnchecked(name));
++ result.append(QMimeType(QMimeTypePrivate(name)));
+ } else {
+ for (const QString &name : std::as_const(m_mimetypeNames))
+ if (std::find_if(result.constBegin(), result.constEnd(), [name](const QMimeType &mime) -> bool { return mime.name() == name; })
+ == result.constEnd())
+- result.append(mimeTypeForNameUnchecked(name));
++ result.append(QMimeType(QMimeTypePrivate(name)));
+ }
+ }
+
+-bool QMimeBinaryProvider::loadMimeTypePrivate(QMimeTypePrivate &data)
++QMimeTypePrivate::LocaleHash QMimeBinaryProvider::localeComments(const QString &name)
+ {
+-#if QT_CONFIG(xmlstreamreader)
+- if (data.loaded)
+- return true;
++ MimeTypeExtraMap::const_iterator it = loadMimeTypeExtra(name);
++ if (it != m_mimetypeExtra.constEnd()) {
++ const MimeTypeExtra &e = it.value();
++ return e.localeComments;
++ }
++ return {};
++}
+
+- auto it = m_mimetypeExtra.constFind(data.name);
++bool QMimeBinaryProvider::hasGlobDeleteAll(const QString &name)
++{
++ MimeTypeExtraMap::const_iterator it = loadMimeTypeExtra(name);
++ if (it != m_mimetypeExtra.constEnd()) {
++ const MimeTypeExtra &e = it.value();
++ return e.hasGlobDeleteAll;
++ }
++ return {};
++}
++
++QStringList QMimeBinaryProvider::globPatterns(const QString &name)
++{
++ MimeTypeExtraMap::const_iterator it = loadMimeTypeExtra(name);
++ if (it != m_mimetypeExtra.constEnd()) {
++ const MimeTypeExtra &e = it.value();
++ return e.globPatterns;
++ }
++ return {};
++}
++
++QMimeBinaryProvider::MimeTypeExtraMap::const_iterator
++QMimeBinaryProvider::loadMimeTypeExtra(const QString &mimeName)
++{
++#if QT_CONFIG(xmlstreamreader)
++ auto it = m_mimetypeExtra.constFind(mimeName);
+ if (it == m_mimetypeExtra.constEnd()) {
+ // load comment and globPatterns
+
+ // shared-mime-info since 1.3 lowercases the xml files
+- QString mimeFile = m_directory + u'/' + data.name.toLower() + ".xml"_L1;
++ QString mimeFile = m_directory + u'/' + mimeName.toLower() + ".xml"_L1;
+ if (!QFile::exists(mimeFile))
+- mimeFile = m_directory + u'/' + data.name + ".xml"_L1; // pre-1.3
++ mimeFile = m_directory + u'/' + mimeName + ".xml"_L1; // pre-1.3
+
+ QFile qfile(mimeFile);
+ if (!qfile.open(QFile::ReadOnly))
+- return false;
++ return m_mimetypeExtra.constEnd();
+
+- auto insertIt = m_mimetypeExtra.insert(data.name, MimeTypeExtra{});
++ auto insertIt = m_mimetypeExtra.insert(mimeName, MimeTypeExtra{});
+ it = insertIt;
+ MimeTypeExtra &extra = insertIt.value();
+ QString mainPattern;
+@@ -515,13 +529,13 @@ bool QMimeBinaryProvider::loadMimeTypePrivate(QMimeTypePrivate &data)
+ QXmlStreamReader xml(&qfile);
+ if (xml.readNextStartElement()) {
+ if (xml.name() != "mime-type"_L1) {
+- return false;
++ return m_mimetypeExtra.constEnd();
+ }
+ const auto name = xml.attributes().value("type"_L1);
+ if (name.isEmpty())
+- return false;
+- if (name.compare(data.name, Qt::CaseInsensitive))
+- qWarning() << "Got name" << name << "in file" << mimeFile << "expected" << data.name;
++ return m_mimetypeExtra.constEnd();
++ if (name.compare(mimeName, Qt::CaseInsensitive))
++ qWarning() << "Got name" << name << "in file" << mimeFile << "expected" << mimeName;
+
+ while (xml.readNextStartElement()) {
+ const auto tag = xml.name();
+@@ -534,8 +548,7 @@ bool QMimeBinaryProvider::loadMimeTypePrivate(QMimeTypePrivate &data)
+ extra.localeComments.insert(lang, text);
+ continue; // we called readElementText, so we're at the EndElement already.
+ } else if (tag == "glob-deleteall"_L1) { // as written out by shared-mime-info >= 0.70
+- extra.globPatterns.clear();
+- mainPattern.clear();
++ extra.hasGlobDeleteAll = true;
+ } else if (tag == "glob"_L1) { // as written out by shared-mime-info >= 0.70
+ const QString pattern = xml.attributes().value("pattern"_L1).toString();
+ if (mainPattern.isEmpty() && pattern.startsWith(u'*')) {
+@@ -557,14 +570,11 @@ bool QMimeBinaryProvider::loadMimeTypePrivate(QMimeTypePrivate &data)
+ extra.globPatterns.prepend(mainPattern);
+ }
+ }
+- const MimeTypeExtra &e = it.value();
+- data.localeComments = e.localeComments;
+- data.globPatterns = e.globPatterns;
+- return true;
++ return it;
+ #else
+- Q_UNUSED(data);
++ Q_UNUSED(mimeName);
+ qWarning("Cannot load mime type since QXmlStreamReader is not available.");
+- return false;
++ return m_mimetypeExtra.constEnd();
+ #endif // feature xmlstreamreader
+ }
+
+@@ -594,22 +604,16 @@ QLatin1StringView QMimeBinaryProvider::iconForMime(CacheFile *cacheFile, int pos
+ return QLatin1StringView();
+ }
+
+-void QMimeBinaryProvider::loadIcon(QMimeTypePrivate &data)
++QString QMimeBinaryProvider::icon(const QString &name)
+ {
+- const QByteArray inputMime = data.name.toLatin1();
+- const QLatin1StringView icon = iconForMime(m_cacheFile.get(), PosIconsListOffset, inputMime);
+- if (!icon.isEmpty()) {
+- data.iconName = icon;
+- }
++ const QByteArray inputMime = name.toLatin1();
++ return iconForMime(m_cacheFile.get(), PosIconsListOffset, inputMime);
+ }
+
+-void QMimeBinaryProvider::loadGenericIcon(QMimeTypePrivate &data)
++QString QMimeBinaryProvider::genericIcon(const QString &name)
+ {
+- const QByteArray inputMime = data.name.toLatin1();
+- const QLatin1StringView icon = iconForMime(m_cacheFile.get(), PosGenericIconsListOffset, inputMime);
+- if (!icon.isEmpty()) {
+- data.genericIconName = icon;
+- }
++ const QByteArray inputMime = name.toLatin1();
++ return iconForMime(m_cacheFile.get(), PosGenericIconsListOffset, inputMime);
+ }
+
+ ////
+@@ -694,9 +698,9 @@ bool QMimeXMLProvider::isInternalDatabase() const
+ #endif
+ }
+
+-QMimeType QMimeXMLProvider::mimeTypeForName(const QString &name)
++bool QMimeXMLProvider::knowsMimeType(const QString &name)
+ {
+- return m_nameMimeTypeMap.value(name);
++ return m_nameMimeTypeMap.contains(name);
+ }
+
+ void QMimeXMLProvider::addFileNameMatches(const QString &fileName, QMimeGlobMatchResult &result)
+@@ -704,22 +708,17 @@ void QMimeXMLProvider::addFileNameMatches(const QString &fileName, QMimeGlobMatc
+ m_mimeTypeGlobs.matchingGlobs(fileName, result);
+ }
+
+-void QMimeXMLProvider::findByMagic(const QByteArray &data, int *accuracyPtr, QMimeType &candidate)
++void QMimeXMLProvider::findByMagic(const QByteArray &data, int *accuracyPtr, QString *candidate)
+ {
+- QString candidateName;
+- bool foundOne = false;
+ for (const QMimeMagicRuleMatcher &matcher : std::as_const(m_magicMatchers)) {
+ if (matcher.matches(data)) {
+ const int priority = matcher.priority();
+ if (priority > *accuracyPtr) {
+ *accuracyPtr = priority;
+- candidateName = matcher.mimetype();
+- foundOne = true;
++ *candidate = matcher.mimetype();
+ }
+ }
+ }
+- if (foundOne)
+- candidate = mimeTypeForName(candidateName);
+ }
+
+ void QMimeXMLProvider::ensureLoaded()
+@@ -749,6 +748,31 @@ void QMimeXMLProvider::ensureLoaded()
+ load(file);
+ }
+
++QMimeTypePrivate::LocaleHash QMimeXMLProvider::localeComments(const QString &name)
++{
++ return m_nameMimeTypeMap.value(name).localeComments;
++}
++
++bool QMimeXMLProvider::hasGlobDeleteAll(const QString &name)
++{
++ return m_nameMimeTypeMap.value(name).hasGlobDeleteAll;
++}
++
++QStringList QMimeXMLProvider::globPatterns(const QString &name)
++{
++ return m_nameMimeTypeMap.value(name).globPatterns;
++}
++
++QString QMimeXMLProvider::icon(const QString &name)
++{
++ return m_nameMimeTypeMap.value(name).iconName;
++}
++
++QString QMimeXMLProvider::genericIcon(const QString &name)
++{
++ return m_nameMimeTypeMap.value(name).genericIconName;
++}
++
+ void QMimeXMLProvider::load(const QString &fileName)
+ {
+ QString errorMessage;
+@@ -790,14 +814,11 @@ void QMimeXMLProvider::addGlobPattern(const QMimeGlobPattern &glob)
+ m_mimeTypeGlobs.addGlob(glob);
+ }
+
+-void QMimeXMLProvider::addMimeType(const QMimeType &mt)
++void QMimeXMLProvider::addMimeType(const QMimeTypeXMLData &mt)
+ {
+- Q_ASSERT(!mt.d.data()->fromCache);
+-
+- QString name = mt.name();
+- if (mt.d->hasGlobDeleteAll)
+- appendIfNew(m_mimeTypesWithDeletedGlobs, name);
+- m_nameMimeTypeMap.insert(mt.name(), mt);
++ if (mt.hasGlobDeleteAll)
++ appendIfNew(m_mimeTypesWithDeletedGlobs, mt.name);
++ m_nameMimeTypeMap.insert(mt.name, mt);
+ }
+
+ /*
+@@ -813,7 +834,7 @@ void QMimeXMLProvider::excludeMimeTypeGlobs(const QStringList &toExclude)
+ for (const auto &mt : toExclude) {
+ auto it = m_nameMimeTypeMap.find(mt);
+ if (it != m_nameMimeTypeMap.end())
+- it->d->globPatterns.clear();
++ it->globPatterns.clear();
+ m_mimeTypeGlobs.removeMimeType(mt);
+ }
+ }
+@@ -853,13 +874,16 @@ void QMimeXMLProvider::addAlias(const QString &alias, const QString &name)
+ void QMimeXMLProvider::addAllMimeTypes(QList<QMimeType> &result)
+ {
+ if (result.isEmpty()) { // fast path
+- result = m_nameMimeTypeMap.values();
++ for (auto it = m_nameMimeTypeMap.constBegin(), end = m_nameMimeTypeMap.constEnd();
++ it != end; ++it) {
++ result.append(QMimeType(QMimeTypePrivate(it.value().name)));
++ }
+ } else {
+ for (auto it = m_nameMimeTypeMap.constBegin(), end = m_nameMimeTypeMap.constEnd() ; it != end ; ++it) {
+ const QString newMime = it.key();
+ if (std::find_if(result.constBegin(), result.constEnd(), [newMime](const QMimeType &mime) -> bool { return mime.name() == newMime; })
+ == result.constEnd())
+- result.append(it.value());
++ result.append(QMimeType(QMimeTypePrivate(it.value().name)));
+ }
+ }
+ }
+diff --git a/src/corelib/mimetypes/qmimeprovider_p.h b/src/corelib/mimetypes/qmimeprovider_p.h
+index e498cf8c3992..755737eaafa1 100644
+--- a/src/corelib/mimetypes/qmimeprovider_p.h
++++ b/src/corelib/mimetypes/qmimeprovider_p.h
+@@ -28,6 +28,7 @@ QT_REQUIRE_CONFIG(mimetype);
+ QT_BEGIN_NAMESPACE
+
+ class QMimeMagicRuleMatcher;
++class QMimeTypeXMLData;
+
+ class QMimeProviderBase
+ {
+@@ -39,18 +40,20 @@ public:
+
+ virtual bool isValid() = 0;
+ virtual bool isInternalDatabase() const = 0;
+- virtual QMimeType mimeTypeForName(const QString &name) = 0;
++ virtual bool knowsMimeType(const QString &name) = 0;
+ virtual void addFileNameMatches(const QString &fileName, QMimeGlobMatchResult &result) = 0;
+ virtual void addParents(const QString &mime, QStringList &result) = 0;
+ virtual QString resolveAlias(const QString &name) = 0;
+ virtual void addAliases(const QString &name, QStringList &result) = 0;
+- virtual void findByMagic(const QByteArray &data, int *accuracyPtr, QMimeType &candidate) = 0;
++ virtual void findByMagic(const QByteArray &data, int *accuracyPtr, QString *candidate) = 0;
+ virtual void addAllMimeTypes(QList<QMimeType> &result) = 0;
+- virtual bool loadMimeTypePrivate(QMimeTypePrivate &) { return false; }
+- virtual void loadIcon(QMimeTypePrivate &) {}
+- virtual void loadGenericIcon(QMimeTypePrivate &) {}
+- virtual void ensureLoaded() {}
+- virtual void excludeMimeTypeGlobs(const QStringList &) {}
++ virtual QMimeTypePrivate::LocaleHash localeComments(const QString &name) = 0;
++ virtual bool hasGlobDeleteAll(const QString &name) = 0;
++ virtual QStringList globPatterns(const QString &name) = 0;
++ virtual QString icon(const QString &name) = 0;
++ virtual QString genericIcon(const QString &name) = 0;
++ virtual void ensureLoaded() { }
++ virtual void excludeMimeTypeGlobs(const QStringList &) { }
+
+ QString directory() const { return m_directory; }
+
+@@ -60,9 +63,9 @@ public:
+ /*
+ MimeTypes with "glob-deleteall" tags are handled differently by each provider
+ sub-class:
+- - QMimeBinaryProvider parses glob-deleteall tags lazily, i.e. only when loadMimeTypePrivate()
++ - QMimeBinaryProvider parses glob-deleteall tags lazily, i.e. only when hasGlobDeleteAll()
+ is called, and clears the glob patterns associated with mimetypes that have this tag
+- - QMimeXMLProvider parses glob-deleteall from the the start, i.e. when a XML file is
++ - QMimeXMLProvider parses glob-deleteall from the start, i.e. when a XML file is
+ parsed with QMimeTypeParser
+
+ The two lists below are used to let both provider types (XML and Binary) communicate
+@@ -95,16 +98,18 @@ public:
+
+ bool isValid() override;
+ bool isInternalDatabase() const override;
+- QMimeType mimeTypeForName(const QString &name) override;
++ bool knowsMimeType(const QString &name) override;
+ void addFileNameMatches(const QString &fileName, QMimeGlobMatchResult &result) override;
+ void addParents(const QString &mime, QStringList &result) override;
+ QString resolveAlias(const QString &name) override;
+ void addAliases(const QString &name, QStringList &result) override;
+- void findByMagic(const QByteArray &data, int *accuracyPtr, QMimeType &candidate) override;
++ void findByMagic(const QByteArray &data, int *accuracyPtr, QString *candidate) override;
+ void addAllMimeTypes(QList<QMimeType> &result) override;
+- bool loadMimeTypePrivate(QMimeTypePrivate &) override;
+- void loadIcon(QMimeTypePrivate &) override;
+- void loadGenericIcon(QMimeTypePrivate &) override;
++ QMimeTypePrivate::LocaleHash localeComments(const QString &name) override;
++ bool hasGlobDeleteAll(const QString &name) override;
++ QStringList globPatterns(const QString &name) override;
++ QString icon(const QString &name) override;
++ QString genericIcon(const QString &name) override;
+ void ensureLoaded() override;
+ void excludeMimeTypeGlobs(const QStringList &toExclude) override;
+
+@@ -116,8 +121,9 @@ private:
+ bool matchSuffixTree(QMimeGlobMatchResult &result, CacheFile *cacheFile, int numEntries,
+ int firstOffset, const QString &fileName, qsizetype charPos,
+ bool caseSensitiveCheck);
+- bool matchMagicRule(CacheFile *cacheFile, int numMatchlets, int firstOffset, const QByteArray &data);
+ bool isMimeTypeGlobsExcluded(const char *name);
++ bool matchMagicRule(CacheFile *cacheFile, int numMatchlets, int firstOffset,
++ const QByteArray &data);
+ QLatin1StringView iconForMime(CacheFile *cacheFile, int posListOffset, const QByteArray &inputMime);
+ void loadMimeTypeList();
+ bool checkCacheChanged();
+@@ -128,11 +134,14 @@ private:
+ bool m_mimetypeListLoaded;
+ struct MimeTypeExtra
+ {
+- // Both retrieved on demand in loadMimeTypePrivate
+ QHash<QString, QString> localeComments;
+ QStringList globPatterns;
++ bool hasGlobDeleteAll = false;
+ };
+- QMap<QString, MimeTypeExtra> m_mimetypeExtra;
++ using MimeTypeExtraMap = QMap<QString, MimeTypeExtra>;
++ MimeTypeExtraMap m_mimetypeExtra;
++
++ MimeTypeExtraMap::const_iterator loadMimeTypeExtra(const QString &mimeName);
+ };
+
+ /*
+@@ -153,19 +162,24 @@ public:
+
+ bool isValid() override;
+ bool isInternalDatabase() const override;
+- QMimeType mimeTypeForName(const QString &name) override;
++ bool knowsMimeType(const QString &name) override;
+ void addFileNameMatches(const QString &fileName, QMimeGlobMatchResult &result) override;
+ void addParents(const QString &mime, QStringList &result) override;
+ QString resolveAlias(const QString &name) override;
+ void addAliases(const QString &name, QStringList &result) override;
+- void findByMagic(const QByteArray &data, int *accuracyPtr, QMimeType &candidate) override;
++ void findByMagic(const QByteArray &data, int *accuracyPtr, QString *candidate) override;
+ void addAllMimeTypes(QList<QMimeType> &result) override;
+ void ensureLoaded() override;
++ QMimeTypePrivate::LocaleHash localeComments(const QString &name) override;
++ bool hasGlobDeleteAll(const QString &name) override;
++ QStringList globPatterns(const QString &name) override;
++ QString icon(const QString &name) override;
++ QString genericIcon(const QString &name) override;
+
+ bool load(const QString &fileName, QString *errorMessage);
+
+ // Called by the mimetype xml parser
+- void addMimeType(const QMimeType &mt);
++ void addMimeType(const QMimeTypeXMLData &mt);
+ void excludeMimeTypeGlobs(const QStringList &toExclude) override;
+ void addGlobPattern(const QMimeGlobPattern &glob);
+ void addParent(const QString &child, const QString &parent);
+@@ -176,7 +190,7 @@ private:
+ void load(const QString &fileName);
+ void load(const char *data, qsizetype len);
+
+- typedef QHash<QString, QMimeType> NameMimeTypeMap;
++ typedef QHash<QString, QMimeTypeXMLData> NameMimeTypeMap;
+ NameMimeTypeMap m_nameMimeTypeMap;
+
+ typedef QHash<QString, QString> AliasHash;
+diff --git a/src/corelib/mimetypes/qmimetype.cpp b/src/corelib/mimetypes/qmimetype.cpp
+index 94df48c6959e..1563fc564159 100644
+--- a/src/corelib/mimetypes/qmimetype.cpp
++++ b/src/corelib/mimetypes/qmimetype.cpp
+@@ -6,9 +6,6 @@
+
+ #include "qmimetype_p.h"
+ #include "qmimedatabase_p.h"
+-#include "qmimeprovider_p.h"
+-
+-#include "qmimeglobpattern_p.h"
+
+ #include <QtCore/QDebug>
+ #include <QtCore/QLocale>
+@@ -20,33 +17,6 @@ QT_BEGIN_NAMESPACE
+
+ using namespace Qt::StringLiterals;
+
+-QMimeTypePrivate::QMimeTypePrivate()
+- : loaded(false), fromCache(false)
+-{}
+-
+-QMimeTypePrivate::QMimeTypePrivate(const QMimeType &other)
+- : loaded(other.d->loaded),
+- name(other.d->name),
+- localeComments(other.d->localeComments),
+- genericIconName(other.d->genericIconName),
+- iconName(other.d->iconName),
+- globPatterns(other.d->globPatterns)
+-{}
+-
+-void QMimeTypePrivate::clear()
+-{
+- name.clear();
+- localeComments.clear();
+- genericIconName.clear();
+- iconName.clear();
+- globPatterns.clear();
+-}
+-
+-void QMimeTypePrivate::addGlobPattern(const QString &pattern)
+-{
+- globPatterns.append(pattern);
+-}
+-
+ /*!
+ \class QMimeType
+ \inmodule QtCore
+@@ -219,7 +189,7 @@ QString QMimeType::name() const
+ */
+ QString QMimeType::comment() const
+ {
+- QMimeDatabasePrivate::instance()->loadMimeTypePrivate(const_cast<QMimeTypePrivate&>(*d));
++ const auto localeComments = QMimeDatabasePrivate::instance()->localeComments(d->name);
+
+ QStringList languageList = QLocale().uiLanguages();
+ qsizetype defaultIndex = languageList.indexOf(u"en-US"_s);
+@@ -244,13 +214,13 @@ QString QMimeType::comment() const
+ // uiLanguages() uses '-' as separator, MIME database uses '_'
+ const QString lang
+ = language == "C"_L1 ? u"en_US"_s : QString(language).replace(u'-', u'_');
+- QString comm = d->localeComments.value(lang);
++ QString comm = localeComments.value(lang);
+ if (!comm.isEmpty())
+ return comm;
+ const qsizetype cut = lang.indexOf(u'_');
+ // If "de_CH" is missing, check for "de" (and similar):
+ if (cut != -1) {
+- comm = d->localeComments.value(lang.left(cut));
++ comm = localeComments.value(lang.left(cut));
+ if (!comm.isEmpty())
+ return comm;
+ }
+@@ -276,8 +246,8 @@ QString QMimeType::comment() const
+ */
+ QString QMimeType::genericIconName() const
+ {
+- QMimeDatabasePrivate::instance()->loadGenericIcon(const_cast<QMimeTypePrivate&>(*d));
+- if (d->genericIconName.isEmpty()) {
++ QString genericIconName = QMimeDatabasePrivate::instance()->genericIcon(d->name);
++ if (genericIconName.isEmpty()) {
+ // From the spec:
+ // If the generic icon name is empty (not specified by the mimetype definition)
+ // then the mimetype is used to generate the generic icon by using the top-level
+@@ -290,7 +260,7 @@ QString QMimeType::genericIconName() const
+ groupRef = groupRef.left(slashindex);
+ return groupRef + "-x-generic"_L1;
+ }
+- return d->genericIconName;
++ return genericIconName;
+ }
+
+ static QString make_default_icon_name_from_mimetype_name(QString iconName)
+@@ -312,11 +282,11 @@ static QString make_default_icon_name_from_mimetype_name(QString iconName)
+ */
+ QString QMimeType::iconName() const
+ {
+- QMimeDatabasePrivate::instance()->loadIcon(const_cast<QMimeTypePrivate&>(*d));
+- if (d->iconName.isEmpty()) {
++ QString iconName = QMimeDatabasePrivate::instance()->icon(d->name);
++ if (iconName.isEmpty()) {
+ return make_default_icon_name_from_mimetype_name(name());
+ }
+- return d->iconName;
++ return iconName;
+ }
+
+ /*!
+@@ -328,8 +298,7 @@ QString QMimeType::iconName() const
+ */
+ QStringList QMimeType::globPatterns() const
+ {
+- QMimeDatabasePrivate::instance()->loadMimeTypePrivate(const_cast<QMimeTypePrivate&>(*d));
+- return d->globPatterns;
++ return QMimeDatabasePrivate::instance()->globPatterns(d->name);
+ }
+
+ /*!
+@@ -426,10 +395,11 @@ QStringList QMimeType::aliases() const
+ */
+ QStringList QMimeType::suffixes() const
+ {
+- QMimeDatabasePrivate::instance()->loadMimeTypePrivate(const_cast<QMimeTypePrivate&>(*d));
++ const QStringList patterns = globPatterns();
+
+ QStringList result;
+- for (const QString &pattern : std::as_const(d->globPatterns)) {
++ result.reserve(patterns.size());
++ for (const QString &pattern : patterns) {
+ // Not a simple suffix if it looks like: README or *. or *.* or *.JP*G or *.JP?
+ if (pattern.startsWith("*."_L1) &&
+ pattern.size() > 2 &&
+@@ -469,15 +439,15 @@ QString QMimeType::preferredSuffix() const
+ */
+ QString QMimeType::filterString() const
+ {
+- QMimeDatabasePrivate::instance()->loadMimeTypePrivate(const_cast<QMimeTypePrivate&>(*d));
++ const QStringList patterns = globPatterns();
+ QString filter;
+
+- if (!d->globPatterns.empty()) {
++ if (!patterns.empty()) {
+ filter += comment() + " ("_L1;
+- for (int i = 0; i < d->globPatterns.size(); ++i) {
++ for (int i = 0; i < patterns.size(); ++i) {
+ if (i != 0)
+ filter += u' ';
+- filter += d->globPatterns.at(i);
++ filter += patterns.at(i);
+ }
+ filter += u')';
+ }
+diff --git a/src/corelib/mimetypes/qmimetype_p.h b/src/corelib/mimetypes/qmimetype_p.h
+index 7b5ed77f40a5..b6040098a998 100644
+--- a/src/corelib/mimetypes/qmimetype_p.h
++++ b/src/corelib/mimetypes/qmimetype_p.h
+@@ -16,13 +16,14 @@
+ //
+
+ #include <QtCore/private/qglobal_p.h>
+-#include "qmimetype.h"
++#include <QtCore/qshareddata.h>
+
+ QT_REQUIRE_CONFIG(mimetype);
+
+ #include <QtCore/qhash.h>
+ #include <QtCore/qstringlist.h>
+
++class QMimeBinaryProvider;
+ QT_BEGIN_NAMESPACE
+
+ class Q_AUTOTEST_EXPORT QMimeTypePrivate : public QSharedData
+@@ -30,42 +31,12 @@ class Q_AUTOTEST_EXPORT QMimeTypePrivate : public QSharedData
+ public:
+ typedef QHash<QString, QString> LocaleHash;
+
+- QMimeTypePrivate();
+- explicit QMimeTypePrivate(const QMimeType &other);
++ QMimeTypePrivate() { }
++ explicit QMimeTypePrivate(const QString &name) : name(name) { }
+
+- void clear();
+-
+- void addGlobPattern(const QString &pattern);
+-
+- bool loaded; // QSharedData leaves a 4 byte gap, so don't put 8 byte members first
+- bool fromCache; // true if this comes from the binary provider
+- bool hasGlobDeleteAll = false; // true if the mimetype has a glob-deleteall tag
+ QString name;
+- LocaleHash localeComments;
+- QString genericIconName;
+- QString iconName;
+- QStringList globPatterns;
+ };
+
+ QT_END_NAMESPACE
+
+-#define QMIMETYPE_BUILDER_FROM_RVALUE_REFS \
+- QT_BEGIN_NAMESPACE \
+- static QMimeType buildQMimeType ( \
+- QString &&name, \
+- QString &&genericIconName, \
+- QString &&iconName, \
+- QStringList &&globPatterns \
+- ) \
+- { \
+- QMimeTypePrivate qMimeTypeData; \
+- qMimeTypeData.loaded = true; \
+- qMimeTypeData.name = std::move(name); \
+- qMimeTypeData.genericIconName = std::move(genericIconName); \
+- qMimeTypeData.iconName = std::move(iconName); \
+- qMimeTypeData.globPatterns = std::move(globPatterns); \
+- return QMimeType(qMimeTypeData); \
+- } \
+- QT_END_NAMESPACE
+-
+-#endif // QMIMETYPE_P_H
++#endif // QMIMETYPE_P_H
+diff --git a/src/corelib/mimetypes/qmimetypeparser.cpp b/src/corelib/mimetypes/qmimetypeparser.cpp
+index 66cbc32b5c8d..3f1e53b25d11 100644
+--- a/src/corelib/mimetypes/qmimetypeparser.cpp
++++ b/src/corelib/mimetypes/qmimetypeparser.cpp
+@@ -165,8 +165,7 @@ static CreateMagicMatchRuleResult createMagicMatchRule(const QXmlStreamAttribute
+ bool QMimeTypeParserBase::parse(QIODevice *dev, const QString &fileName, QString *errorMessage)
+ {
+ #if QT_CONFIG(xmlstreamreader)
+- QMimeTypePrivate data;
+- data.loaded = true;
++ QMimeTypeXMLData data;
+ int priority = 50;
+ QStack<QMimeMagicRule *> currentRules; // stack for the nesting of rules
+ QList<QMimeMagicRule> rules; // toplevel rules
+@@ -273,7 +272,7 @@ bool QMimeTypeParserBase::parse(QIODevice *dev, const QString &fileName, QString
+ {
+ const auto elementName = reader.name();
+ if (elementName == QLatin1StringView(mimeTypeTagC)) {
+- if (!process(QMimeType(data), errorMessage))
++ if (!process(data, errorMessage))
+ return false;
+ data.clear();
+ } else if (elementName == QLatin1StringView(matchTagC)) {
+@@ -314,4 +313,19 @@ bool QMimeTypeParserBase::parse(QIODevice *dev, const QString &fileName, QString
+ #endif // feature xmlstreamreader
+ }
+
++void QMimeTypeXMLData::clear()
++{
++ hasGlobDeleteAll = false;
++ name.clear();
++ localeComments.clear();
++ genericIconName.clear();
++ iconName.clear();
++ globPatterns.clear();
++}
++
++void QMimeTypeXMLData::addGlobPattern(const QString &pattern)
++{
++ globPatterns.append(pattern);
++}
++
+ QT_END_NAMESPACE
+diff --git a/src/corelib/mimetypes/qmimetypeparser_p.h b/src/corelib/mimetypes/qmimetypeparser_p.h
+index c9698e149f89..d4266ffcc039 100644
+--- a/src/corelib/mimetypes/qmimetypeparser_p.h
++++ b/src/corelib/mimetypes/qmimetypeparser_p.h
+@@ -16,7 +16,7 @@
+ // We mean it.
+ //
+
+-#include "qmimedatabase_p.h"
++#include <QtCore/qtconfigmacros.h>
+
+ QT_REQUIRE_CONFIG(mimetype);
+
+@@ -24,6 +24,21 @@ QT_REQUIRE_CONFIG(mimetype);
+
+ QT_BEGIN_NAMESPACE
+
++class QMimeTypeXMLData
++{
++public:
++ void clear();
++
++ void addGlobPattern(const QString &pattern);
++
++ bool hasGlobDeleteAll = false; // true if the mimetype has a glob-deleteall tag
++ QString name;
++ QMimeTypePrivate::LocaleHash localeComments;
++ QString genericIconName; // TODO move to a struct that's specific to the XML provider
++ QString iconName; // TODO move to a struct that's specific to the XML provider
++ QStringList globPatterns;
++};
++
+ class QIODevice;
+
+ class QMimeTypeParserBase
+@@ -39,7 +54,7 @@ public:
+ static bool parseNumber(QStringView n, int *target, QString *errorMessage);
+
+ protected:
+- virtual bool process(const QMimeType &t, QString *errorMessage) = 0;
++ virtual bool process(const QMimeTypeXMLData &t, QString *errorMessage) = 0;
+ virtual bool process(const QMimeGlobPattern &t, QString *errorMessage) = 0;
+ virtual void processParent(const QString &child, const QString &parent) = 0;
+ virtual void processAlias(const QString &alias, const QString &name) = 0;
+@@ -73,7 +88,7 @@ public:
+ explicit QMimeTypeParser(QMimeXMLProvider &provider) : m_provider(provider) {}
+
+ protected:
+- inline bool process(const QMimeType &t, QString *) override
++ inline bool process(const QMimeTypeXMLData &t, QString *) override
+ { m_provider.addMimeType(t); return true; }
+
+ inline bool process(const QMimeGlobPattern &glob, QString *) override
+diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/add-extension.xml b/tests/auto/corelib/mimetypes/qmimedatabase/add-extension.xml
+new file mode 100644
+index 000000000000..c4141e0f7072
+--- /dev/null
++++ b/tests/auto/corelib/mimetypes/qmimedatabase/add-extension.xml
+@@ -0,0 +1,7 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
++ <mime-type type="image/jpeg">
++ <glob pattern="*.jnewext"/>
++ <comment>JPEG Image</comment>
++ </mime-type>
++</mime-info>
+diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/CMakeLists.txt b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/CMakeLists.txt
+index c2642456faf5..e5ad5fd31175 100644
+--- a/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/CMakeLists.txt
++++ b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/CMakeLists.txt
+@@ -25,6 +25,7 @@ qt_internal_add_test(tst_qmimedatabase-cache
+ #)
+ set(testdata_resource_files
+ "../circular-inheritance.xml"
++ "../add-extension.xml"
+ "../invalid-magic1.xml"
+ "../invalid-magic2.xml"
+ "../invalid-magic3.xml"
+diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/CMakeLists.txt b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/CMakeLists.txt
+index b21324aeb4b9..50db02abfeea 100644
+--- a/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/CMakeLists.txt
++++ b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/CMakeLists.txt
+@@ -25,6 +25,7 @@ qt_internal_add_test(tst_qmimedatabase-xml
+ #)
+ set(testdata_resource_files
+ "../circular-inheritance.xml"
++ "../add-extension.xml"
+ "../invalid-magic1.xml"
+ "../invalid-magic2.xml"
+ "../invalid-magic3.xml"
+diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp
+index 31c5e701dac1..b1e9f51a25eb 100644
+--- a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp
++++ b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp
+@@ -38,6 +38,7 @@ static const std::array additionalGlobalMimeFiles = {
+ };
+
+ static const std::array additionalLocalMimeFiles = {
++ "add-extension.xml", // adds *.jnewext to image/jpeg
+ "yast2-metapackage-handler-mimetypes.xml",
+ "qml-again.xml",
+ "text-x-objcsrc.xml",
+@@ -1232,6 +1233,11 @@ void tst_QMimeDatabase::installNewLocalMimeType()
+ QCOMPARE(mimes.at(0).name(), u"video/webm");
+ }
+
++ // QTBUG-116905: globPatterns() should merge all locations
++ // add-extension.xml adds *.jnewext
++ const QStringList expectedJpegPatterns{ "*.jpg", "*.jpeg", "*.jpe", "*.jnewext" };
++ QCOMPARE(db.mimeTypeForName(QStringLiteral("image/jpeg")).globPatterns(), expectedJpegPatterns);
++
+ // Now that we have two directories with mime definitions, check that everything still works
+ inheritance();
+ if (QTest::currentTestFailed())
+diff --git a/tests/auto/corelib/mimetypes/qmimetype/tst_qmimetype.cpp b/tests/auto/corelib/mimetypes/qmimetype/tst_qmimetype.cpp
+index fda12298fe6a..50183ca4e0b0 100644
+--- a/tests/auto/corelib/mimetypes/qmimetype/tst_qmimetype.cpp
++++ b/tests/auto/corelib/mimetypes/qmimetype/tst_qmimetype.cpp
+@@ -21,7 +21,6 @@ private slots:
+ void name();
+ void genericIconName();
+ void iconName();
+- void suffixes();
+ void gadget();
+ };
+
+@@ -36,52 +35,15 @@ void tst_qmimetype::initTestCase()
+
+ static QString qMimeTypeName()
+ {
+- static const QString result ("No name of the MIME type");
++ static const QString result("group/fake-mime");
+ return result;
+ }
+
+-static QString qMimeTypeGenericIconName()
+-{
+- static const QString result ("No file name of an icon image that represents the MIME type");
+- return result;
+-}
+-
+-static QString qMimeTypeIconName()
+-{
+- static const QString result ("No file name of an icon image that represents the MIME type");
+- return result;
+-}
+-
+-static QStringList buildQMimeTypeFilenameExtensions()
+-{
+- QStringList result;
+- result << QString::fromLatin1("*.png");
+- return result;
+-}
+-
+-static QStringList qMimeTypeGlobPatterns()
+-{
+- static const QStringList result (buildQMimeTypeFilenameExtensions());
+- return result;
+-}
+-
+-// ------------------------------------------------------------------------------------------------
+-
+-QMIMETYPE_BUILDER_FROM_RVALUE_REFS
+-
+ // ------------------------------------------------------------------------------------------------
+
+ void tst_qmimetype::isValid()
+ {
+- QMimeType instantiatedQMimeType (
+- buildQMimeType (
+- qMimeTypeName(),
+- qMimeTypeGenericIconName(),
+- qMimeTypeIconName(),
+- qMimeTypeGlobPatterns()
+- )
+- );
+-
++ QMimeType instantiatedQMimeType{ QMimeTypePrivate(qMimeTypeName()) };
+ QVERIFY(instantiatedQMimeType.isValid());
+
+ QMimeType otherQMimeType (instantiatedQMimeType);
+@@ -98,23 +60,8 @@ void tst_qmimetype::isValid()
+
+ void tst_qmimetype::name()
+ {
+- QMimeType instantiatedQMimeType (
+- buildQMimeType (
+- qMimeTypeName(),
+- qMimeTypeGenericIconName(),
+- qMimeTypeIconName(),
+- qMimeTypeGlobPatterns()
+- )
+- );
+-
+- QMimeType otherQMimeType (
+- buildQMimeType (
+- QString(),
+- qMimeTypeGenericIconName(),
+- qMimeTypeIconName(),
+- qMimeTypeGlobPatterns()
+- )
+- );
++ QMimeType instantiatedQMimeType{ QMimeTypePrivate(qMimeTypeName()) };
++ QMimeType otherQMimeType{ QMimeTypePrivate(QString()) };
+
+ // Verify that the Name is part of the equality test:
+ QCOMPARE(instantiatedQMimeType.name(), qMimeTypeName());
+@@ -127,63 +74,23 @@ void tst_qmimetype::name()
+
+ void tst_qmimetype::genericIconName()
+ {
+- QMimeType instantiatedQMimeType (
+- buildQMimeType (
+- qMimeTypeName(),
+- qMimeTypeGenericIconName(),
+- qMimeTypeIconName(),
+- qMimeTypeGlobPatterns()
+- )
+- );
+-
+- QCOMPARE(instantiatedQMimeType.genericIconName(), qMimeTypeGenericIconName());
++ const QMimeType instantiatedQMimeType{ QMimeTypePrivate(qMimeTypeName()) };
++ QCOMPARE(instantiatedQMimeType.genericIconName(), "group-x-generic");
+ }
+
+ // ------------------------------------------------------------------------------------------------
+
+ void tst_qmimetype::iconName()
+ {
+- QMimeType instantiatedQMimeType (
+- buildQMimeType (
+- qMimeTypeName(),
+- qMimeTypeGenericIconName(),
+- qMimeTypeIconName(),
+- qMimeTypeGlobPatterns()
+- )
+- );
+-
+- QCOMPARE(instantiatedQMimeType.iconName(), qMimeTypeIconName());
+-}
+-
+-// ------------------------------------------------------------------------------------------------
+-
+-void tst_qmimetype::suffixes()
+-{
+- QMimeType instantiatedQMimeType (
+- buildQMimeType (
+- qMimeTypeName(),
+- qMimeTypeGenericIconName(),
+- qMimeTypeIconName(),
+- qMimeTypeGlobPatterns()
+- )
+- );
+-
+- QCOMPARE(instantiatedQMimeType.globPatterns(), qMimeTypeGlobPatterns());
+- QCOMPARE(instantiatedQMimeType.suffixes(), QStringList() << QString::fromLatin1("png"));
++ const QMimeType instantiatedQMimeType{ QMimeTypePrivate(qMimeTypeName()) };
++ QCOMPARE(instantiatedQMimeType.iconName(), "group-fake-mime");
+ }
+
+ // ------------------------------------------------------------------------------------------------
+
+ void tst_qmimetype::gadget()
+ {
+- QMimeType instantiatedQMimeType (
+- buildQMimeType (
+- qMimeTypeName(),
+- qMimeTypeGenericIconName(),
+- qMimeTypeIconName(),
+- qMimeTypeGlobPatterns()
+- )
+- );
++ QMimeType instantiatedQMimeType = QMimeDatabase().mimeTypeForName("text/plain");
+
+ const QMetaObject *metaObject = &instantiatedQMimeType.staticMetaObject;
+
+--
+2.16.3
diff --git a/debian/patches/series b/debian/patches/series
index e4b75f8..639e66d 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,4 +1,5 @@
# NEON backported patches as requested - fixed in 6.6.2??
+qmimedatabase_collect_glob_patterns_from_all_locations
# Needs to be fixed upstream.
Add-SH-detection.patch
More information about the Neon-commits
mailing list