diff options
author | David Faure <david.faure@kdab.com> | 2020-09-11 10:05:51 +0200 |
---|---|---|
committer | David Faure <david.faure@kdab.com> | 2020-09-22 20:40:45 +0200 |
commit | fc8f5afc874073f91d3770273e0a9164182d7897 (patch) | |
tree | 8cfd33f885ac7ee09d3e38bc18cdc343f435646b /src/corelib | |
parent | ad9108e2e96ebf67147a72a7dab00398ff637695 (diff) |
QMimeDatabase: fix handling of glob-deleteall
Binary provider:
It was not possible to remove the first glob in a local override,
because the mainPattern handling would re-add the first glob back.
XML provider:
It didn't support glob-deleteall.
Also, the order of the providers was wrong. We want to pick local
overrides first, the internal DB has to go last in the list.
Fixes: QTBUG-85436
Pick-to: 5.15
Change-Id: I9a4523f37cd962c730df9a6ed992bd01c075bf03
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib')
-rw-r--r-- | src/corelib/mimetypes/qmimedatabase.cpp | 34 | ||||
-rw-r--r-- | src/corelib/mimetypes/qmimeprovider.cpp | 1 | ||||
-rw-r--r-- | src/corelib/mimetypes/qmimetypeparser.cpp | 7 | ||||
-rw-r--r-- | src/corelib/mimetypes/qmimetypeparser_p.h | 1 |
4 files changed, 26 insertions, 17 deletions
diff --git a/src/corelib/mimetypes/qmimedatabase.cpp b/src/corelib/mimetypes/qmimedatabase.cpp index 7a9bf2880d..56f5d471ea 100644 --- a/src/corelib/mimetypes/qmimedatabase.cpp +++ b/src/corelib/mimetypes/qmimedatabase.cpp @@ -101,27 +101,13 @@ void QMimeDatabasePrivate::loadProviders() const auto fdoIterator = std::find_if(mimeDirs.constBegin(), mimeDirs.constEnd(), [](const QString &mimeDir) -> bool { return QFileInfo::exists(mimeDir + QStringLiteral("/packages/freedesktop.org.xml")); } ); + const bool needInternalDB = QMimeXMLProvider::InternalDatabaseAvailable && fdoIterator == mimeDirs.constEnd(); //qDebug() << "mime dirs:" << mimeDirs; Providers currentProviders; std::swap(m_providers, currentProviders); - if (QMimeXMLProvider::InternalDatabaseAvailable && fdoIterator == mimeDirs.constEnd()) { - m_providers.reserve(mimeDirs.size() + 1); - // Check if we already have a provider for the InternalDatabase - const auto isInternal = [](const std::unique_ptr<QMimeProviderBase> &prov) - { - return prov && prov->isInternalDatabase(); - }; - const auto it = std::find_if(currentProviders.begin(), currentProviders.end(), isInternal); - if (it == currentProviders.end()) { - m_providers.push_back(Providers::value_type(new QMimeXMLProvider(this, QMimeXMLProvider::InternalDatabase))); - } else { - m_providers.push_back(std::move(*it)); - } - } else { - m_providers.reserve(mimeDirs.size()); - } + m_providers.reserve(mimeDirs.size() + (needInternalDB ? 1 : 0)); for (const QString &mimeDir : mimeDirs) { const QString cacheFile = mimeDir + QStringLiteral("/mime.cache"); @@ -158,6 +144,21 @@ void QMimeDatabasePrivate::loadProviders() m_providers.push_back(std::move(provider)); } } + // mimeDirs is sorted "most local first, most global last" + // so the internal XML DB goes at the end + if (needInternalDB) { + // Check if we already have a provider for the InternalDatabase + const auto isInternal = [](const std::unique_ptr<QMimeProviderBase> &prov) + { + return prov && prov->isInternalDatabase(); + }; + const auto it = std::find_if(currentProviders.begin(), currentProviders.end(), isInternal); + if (it == currentProviders.end()) { + m_providers.push_back(Providers::value_type(new QMimeXMLProvider(this, QMimeXMLProvider::InternalDatabase))); + } else { + m_providers.push_back(std::move(*it)); + } + } } const QMimeDatabasePrivate::Providers &QMimeDatabasePrivate::providers() @@ -215,7 +216,6 @@ QStringList QMimeDatabasePrivate::mimeTypeForFileName(const QString &fileName) QMimeGlobMatchResult QMimeDatabasePrivate::findByFileName(const QString &fileName) { QMimeGlobMatchResult result; - // TODO this parses in the order (local, global). Check that it handles "NOGLOBS" correctly. for (const auto &provider : providers()) provider->addFileNameMatches(fileName, result); return result; diff --git a/src/corelib/mimetypes/qmimeprovider.cpp b/src/corelib/mimetypes/qmimeprovider.cpp index 7a6c522a9d..fcc6cdf088 100644 --- a/src/corelib/mimetypes/qmimeprovider.cpp +++ b/src/corelib/mimetypes/qmimeprovider.cpp @@ -542,6 +542,7 @@ void QMimeBinaryProvider::loadMimeTypePrivate(QMimeTypePrivate &data) data.iconName = xml.attributes().value(QLatin1String("name")).toString(); } else if (tag == QLatin1String("glob-deleteall")) { // as written out by shared-mime-info >= 0.70 data.globPatterns.clear(); + mainPattern.clear(); } else if (tag == QLatin1String("glob")) { // as written out by shared-mime-info >= 0.70 const QString pattern = xml.attributes().value(QLatin1String("pattern")).toString(); if (mainPattern.isEmpty() && pattern.startsWith(QLatin1Char('*'))) { diff --git a/src/corelib/mimetypes/qmimetypeparser.cpp b/src/corelib/mimetypes/qmimetypeparser.cpp index aa5427b16a..c874e5a6b4 100644 --- a/src/corelib/mimetypes/qmimetypeparser.cpp +++ b/src/corelib/mimetypes/qmimetypeparser.cpp @@ -63,6 +63,7 @@ static const char genericIconTagC[] = "generic-icon"; static const char iconTagC[] = "icon"; static const char nameAttributeC[] = "name"; static const char globTagC[] = "glob"; +static const char globDeleteAllTagC[] = "glob-deleteall"; static const char aliasTagC[] = "alias"; static const char patternAttributeC[] = "pattern"; static const char weightAttributeC[] = "weight"; @@ -123,6 +124,7 @@ QMimeTypeParserBase::ParseState QMimeTypeParserBase::nextState(ParseState curren case ParseGenericIcon: case ParseIcon: case ParseGlobPattern: + case ParseGlobDeleteAll: case ParseSubClass: case ParseAlias: case ParseOtherMimeTypeSubTag: @@ -137,6 +139,8 @@ QMimeTypeParserBase::ParseState QMimeTypeParserBase::nextState(ParseState curren return ParseIcon; if (startElement == QLatin1String(globTagC)) return ParseGlobPattern; + if (startElement == QLatin1String(globDeleteAllTagC)) + return ParseGlobDeleteAll; if (startElement == QLatin1String(subClassTagC)) return ParseSubClass; if (startElement == QLatin1String(aliasTagC)) @@ -242,6 +246,9 @@ bool QMimeTypeParserBase::parse(QIODevice *dev, const QString &fileName, QString data.addGlobPattern(pattern); // just for QMimeType::globPatterns() } break; + case ParseGlobDeleteAll: + data.globPatterns.clear(); + break; case ParseSubClass: { const QString inheritsFrom = atts.value(QLatin1String(mimeTypeAttributeC)).toString(); if (!inheritsFrom.isEmpty()) diff --git a/src/corelib/mimetypes/qmimetypeparser_p.h b/src/corelib/mimetypes/qmimetypeparser_p.h index 6f1869e399..9634718ef1 100644 --- a/src/corelib/mimetypes/qmimetypeparser_p.h +++ b/src/corelib/mimetypes/qmimetypeparser_p.h @@ -90,6 +90,7 @@ private: ParseGenericIcon, ParseIcon, ParseGlobPattern, + ParseGlobDeleteAll, ParseSubClass, ParseAlias, ParseMagic, |