QMimeDatabase: fix glob-deleteall support for the binary providers
This fixes the recently added QEXPECT_FAIL about glob-deleteall in a local directory (with a binary cache). Before adding a glob match we ask the more-local (higher-precedence) directories if they have a glob-deleteall for that mimetype, and skip it then. This "asking" is a virtual method, implemented for both XML and binary providers. Change-Id: I6e4baf0120749f3331fd2d9254bea750a322b72d (cherry picked from commit 1f0bc1ade316547d01100dcca4f3f7187485f917) Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
705118a554
commit
525b05599c
@ -144,18 +144,12 @@ void QMimeDatabasePrivate::loadProviders()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle mimetypes with glob-deleteall tags (from XML providers)
|
|
||||||
auto it = m_providers.begin();
|
auto it = m_providers.begin();
|
||||||
|
(*it)->setOverrideProvider(nullptr);
|
||||||
|
++it;
|
||||||
const auto end = m_providers.end();
|
const auto end = m_providers.end();
|
||||||
for (;it != end; ++it) {
|
for (; it != end; ++it)
|
||||||
const QStringList &list = (*it)->m_mimeTypesWithDeletedGlobs;
|
(*it)->setOverrideProvider((it - 1)->get());
|
||||||
if (list.isEmpty())
|
|
||||||
continue;
|
|
||||||
// Each Provider affects Providers with lower precedence
|
|
||||||
auto nextIt = it + 1;
|
|
||||||
for (; nextIt != end; ++nextIt)
|
|
||||||
(*nextIt)->excludeMimeTypeGlobs(list);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const QMimeDatabasePrivate::Providers &QMimeDatabasePrivate::providers()
|
const QMimeDatabasePrivate::Providers &QMimeDatabasePrivate::providers()
|
||||||
|
@ -220,11 +220,11 @@ void QMimeAllGlobPatterns::removeMimeType(const QString &mimeType)
|
|||||||
m_lowWeightGlobs.removeMimeType(mimeType);
|
m_lowWeightGlobs.removeMimeType(mimeType);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QMimeGlobPatternList::match(QMimeGlobMatchResult &result,
|
void QMimeGlobPatternList::match(QMimeGlobMatchResult &result, const QString &fileName,
|
||||||
const QString &fileName) const
|
const AddMatchFilterFunc &filterFunc) const
|
||||||
{
|
{
|
||||||
for (const QMimeGlobPattern &glob : *this) {
|
for (const QMimeGlobPattern &glob : *this) {
|
||||||
if (glob.matchFileName(fileName)) {
|
if (glob.matchFileName(fileName) && filterFunc(glob.mimeType())) {
|
||||||
const QString pattern = glob.pattern();
|
const QString pattern = glob.pattern();
|
||||||
const qsizetype suffixLen = isSimplePattern(pattern) ? pattern.size() - strlen("*.") : 0;
|
const qsizetype suffixLen = isSimplePattern(pattern) ? pattern.size() - strlen("*.") : 0;
|
||||||
result.addMatch(glob.mimeType(), glob.weight(), pattern, suffixLen);
|
result.addMatch(glob.mimeType(), glob.weight(), pattern, suffixLen);
|
||||||
@ -232,10 +232,11 @@ void QMimeGlobPatternList::match(QMimeGlobMatchResult &result,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QMimeAllGlobPatterns::matchingGlobs(const QString &fileName, QMimeGlobMatchResult &result) const
|
void QMimeAllGlobPatterns::matchingGlobs(const QString &fileName, QMimeGlobMatchResult &result,
|
||||||
|
const AddMatchFilterFunc &filterFunc) const
|
||||||
{
|
{
|
||||||
// First try the high weight matches (>50), if any.
|
// First try the high weight matches (>50), if any.
|
||||||
m_highWeightGlobs.match(result, fileName);
|
m_highWeightGlobs.match(result, fileName, filterFunc);
|
||||||
|
|
||||||
// Now use the "fast patterns" dict, for simple *.foo patterns with weight 50
|
// Now use the "fast patterns" dict, for simple *.foo patterns with weight 50
|
||||||
// (which is most of them, so this optimization is definitely worth it)
|
// (which is most of them, so this optimization is definitely worth it)
|
||||||
@ -247,14 +248,17 @@ void QMimeAllGlobPatterns::matchingGlobs(const QString &fileName, QMimeGlobMatch
|
|||||||
|
|
||||||
const QStringList matchingMimeTypes = m_fastPatterns.value(simpleExtension);
|
const QStringList matchingMimeTypes = m_fastPatterns.value(simpleExtension);
|
||||||
const QString simplePattern = "*."_L1 + simpleExtension;
|
const QString simplePattern = "*."_L1 + simpleExtension;
|
||||||
for (const QString &mime : matchingMimeTypes)
|
for (const QString &mime : matchingMimeTypes) {
|
||||||
result.addMatch(mime, 50, simplePattern, simpleExtension.size());
|
if (filterFunc(mime)) {
|
||||||
|
result.addMatch(mime, 50, simplePattern, simpleExtension.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
// Can't return yet; *.tar.bz2 has to win over *.bz2, so we need the low-weight mimetypes anyway,
|
// Can't return yet; *.tar.bz2 has to win over *.bz2, so we need the low-weight mimetypes anyway,
|
||||||
// at least those with weight 50.
|
// at least those with weight 50.
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally, try the low weight matches (<=50)
|
// Finally, try the low weight matches (<=50)
|
||||||
m_lowWeightGlobs.match(result, fileName);
|
m_lowWeightGlobs.match(result, fileName, filterFunc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QMimeAllGlobPatterns::clear()
|
void QMimeAllGlobPatterns::clear()
|
||||||
|
@ -87,6 +87,8 @@ private:
|
|||||||
};
|
};
|
||||||
Q_DECLARE_SHARED(QMimeGlobPattern)
|
Q_DECLARE_SHARED(QMimeGlobPattern)
|
||||||
|
|
||||||
|
using AddMatchFilterFunc = std::function<bool(const QString &)>;
|
||||||
|
|
||||||
class QMimeGlobPatternList : public QList<QMimeGlobPattern>
|
class QMimeGlobPatternList : public QList<QMimeGlobPattern>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -111,7 +113,8 @@ public:
|
|||||||
removeIf(isMimeTypeEqual);
|
removeIf(isMimeTypeEqual);
|
||||||
}
|
}
|
||||||
|
|
||||||
void match(QMimeGlobMatchResult &result, const QString &fileName) const;
|
void match(QMimeGlobMatchResult &result, const QString &fileName,
|
||||||
|
const AddMatchFilterFunc &filterFunc) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -128,7 +131,8 @@ public:
|
|||||||
|
|
||||||
void addGlob(const QMimeGlobPattern &glob);
|
void addGlob(const QMimeGlobPattern &glob);
|
||||||
void removeMimeType(const QString &mimeType);
|
void removeMimeType(const QString &mimeType);
|
||||||
void matchingGlobs(const QString &fileName, QMimeGlobMatchResult &result) const;
|
void matchingGlobs(const QString &fileName, QMimeGlobMatchResult &result,
|
||||||
|
const AddMatchFilterFunc &filterFunc) const;
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
PatternsMap m_fastPatterns; // example: "doc" -> "application/msword", "text/plain"
|
PatternsMap m_fastPatterns; // example: "doc" -> "application/msword", "text/plain"
|
||||||
|
@ -62,6 +62,25 @@ QMimeProviderBase::QMimeProviderBase(QMimeDatabasePrivate *db, const QString &di
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QMimeProviderBase *QMimeProviderBase::overrideProvider() const
|
||||||
|
{
|
||||||
|
return m_overrideProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMimeProviderBase::setOverrideProvider(QMimeProviderBase *provider)
|
||||||
|
{
|
||||||
|
m_overrideProvider = provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QMimeProviderBase::isMimeTypeGlobsExcluded(const QString &name) const
|
||||||
|
{
|
||||||
|
if (m_overrideProvider) {
|
||||||
|
if (m_overrideProvider->hasGlobDeleteAll(name))
|
||||||
|
return true;
|
||||||
|
return m_overrideProvider->isMimeTypeGlobsExcluded(name);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
QMimeBinaryProvider::QMimeBinaryProvider(QMimeDatabasePrivate *db, const QString &directory)
|
QMimeBinaryProvider::QMimeBinaryProvider(QMimeDatabasePrivate *db, const QString &directory)
|
||||||
: QMimeProviderBase(db, directory), m_mimetypeListLoaded(false)
|
: QMimeProviderBase(db, directory), m_mimetypeListLoaded(false)
|
||||||
@ -222,17 +241,6 @@ void QMimeBinaryProvider::addFileNameMatches(const QString &fileName, QMimeGlobM
|
|||||||
fileName);
|
fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QMimeBinaryProvider::isMimeTypeGlobsExcluded(const char *mimeTypeName)
|
|
||||||
{
|
|
||||||
return m_mimeTypesWithExcludedGlobs.contains(QLatin1StringView(mimeTypeName));
|
|
||||||
}
|
|
||||||
|
|
||||||
void QMimeBinaryProvider::excludeMimeTypeGlobs(const QStringList &toExclude)
|
|
||||||
{
|
|
||||||
for (const auto &mt : toExclude)
|
|
||||||
appendIfNew(m_mimeTypesWithExcludedGlobs, mt);
|
|
||||||
}
|
|
||||||
|
|
||||||
int QMimeBinaryProvider::matchGlobList(QMimeGlobMatchResult &result, CacheFile *cacheFile, int off,
|
int QMimeBinaryProvider::matchGlobList(QMimeGlobMatchResult &result, CacheFile *cacheFile, int off,
|
||||||
const QString &fileName)
|
const QString &fileName)
|
||||||
{
|
{
|
||||||
@ -248,14 +256,14 @@ int QMimeBinaryProvider::matchGlobList(QMimeGlobMatchResult &result, CacheFile *
|
|||||||
const Qt::CaseSensitivity qtCaseSensitive = caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive;
|
const Qt::CaseSensitivity qtCaseSensitive = caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive;
|
||||||
const QString pattern = QLatin1StringView(cacheFile->getCharStar(globOffset));
|
const QString pattern = QLatin1StringView(cacheFile->getCharStar(globOffset));
|
||||||
|
|
||||||
const char *mimeType = cacheFile->getCharStar(mimeTypeOffset);
|
const QLatin1StringView mimeType(cacheFile->getCharStar(mimeTypeOffset));
|
||||||
//qDebug() << pattern << mimeType << weight << caseSensitive;
|
//qDebug() << pattern << mimeType << weight << caseSensitive;
|
||||||
if (isMimeTypeGlobsExcluded(mimeType))
|
if (isMimeTypeGlobsExcluded(mimeType))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
QMimeGlobPattern glob(pattern, QString() /*unused*/, weight, qtCaseSensitive);
|
QMimeGlobPattern glob(pattern, QString() /*unused*/, weight, qtCaseSensitive);
|
||||||
if (glob.matchFileName(fileName)) {
|
if (glob.matchFileName(fileName)) {
|
||||||
result.addMatch(QLatin1StringView(mimeType), weight, pattern);
|
result.addMatch(mimeType, weight, pattern);
|
||||||
++numMatches;
|
++numMatches;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -292,15 +300,15 @@ bool QMimeBinaryProvider::matchSuffixTree(QMimeGlobMatchResult &result,
|
|||||||
if (mch != 0)
|
if (mch != 0)
|
||||||
break;
|
break;
|
||||||
const int mimeTypeOffset = cacheFile->getUint32(childOff + 4);
|
const int mimeTypeOffset = cacheFile->getUint32(childOff + 4);
|
||||||
const char *mimeType = cacheFile->getCharStar(mimeTypeOffset);
|
const QLatin1StringView mimeType(cacheFile->getCharStar(mimeTypeOffset));
|
||||||
if (isMimeTypeGlobsExcluded(mimeType))
|
if (isMimeTypeGlobsExcluded(mimeType))
|
||||||
continue;
|
continue;
|
||||||
const int flagsAndWeight = cacheFile->getUint32(childOff + 8);
|
const int flagsAndWeight = cacheFile->getUint32(childOff + 8);
|
||||||
const int weight = flagsAndWeight & 0xff;
|
const int weight = flagsAndWeight & 0xff;
|
||||||
const bool caseSensitive = flagsAndWeight & 0x100;
|
const bool caseSensitive = flagsAndWeight & 0x100;
|
||||||
if (caseSensitiveCheck || !caseSensitive) {
|
if (caseSensitiveCheck || !caseSensitive) {
|
||||||
result.addMatch(QLatin1StringView(mimeType), weight,
|
result.addMatch(mimeType, weight,
|
||||||
u'*' + QStringView{fileName}.mid(charPos + 1),
|
u'*' + QStringView{ fileName }.mid(charPos + 1),
|
||||||
fileName.size() - charPos - 2);
|
fileName.size() - charPos - 2);
|
||||||
success = true;
|
success = true;
|
||||||
}
|
}
|
||||||
@ -705,7 +713,8 @@ bool QMimeXMLProvider::knowsMimeType(const QString &name)
|
|||||||
|
|
||||||
void QMimeXMLProvider::addFileNameMatches(const QString &fileName, QMimeGlobMatchResult &result)
|
void QMimeXMLProvider::addFileNameMatches(const QString &fileName, QMimeGlobMatchResult &result)
|
||||||
{
|
{
|
||||||
m_mimeTypeGlobs.matchingGlobs(fileName, result);
|
auto filterFunc = [this](const QString &name) { return !isMimeTypeGlobsExcluded(name); };
|
||||||
|
m_mimeTypeGlobs.matchingGlobs(fileName, result, filterFunc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QMimeXMLProvider::findByMagic(const QByteArray &data, int *accuracyPtr, QString *candidate)
|
void QMimeXMLProvider::findByMagic(const QByteArray &data, int *accuracyPtr, QString *candidate)
|
||||||
@ -740,7 +749,6 @@ void QMimeXMLProvider::ensureLoaded()
|
|||||||
m_parents.clear();
|
m_parents.clear();
|
||||||
m_mimeTypeGlobs.clear();
|
m_mimeTypeGlobs.clear();
|
||||||
m_magicMatchers.clear();
|
m_magicMatchers.clear();
|
||||||
m_mimeTypesWithDeletedGlobs.clear();
|
|
||||||
|
|
||||||
//qDebug() << "Loading" << m_allFiles;
|
//qDebug() << "Loading" << m_allFiles;
|
||||||
|
|
||||||
@ -816,29 +824,9 @@ void QMimeXMLProvider::addGlobPattern(const QMimeGlobPattern &glob)
|
|||||||
|
|
||||||
void QMimeXMLProvider::addMimeType(const QMimeTypeXMLData &mt)
|
void QMimeXMLProvider::addMimeType(const QMimeTypeXMLData &mt)
|
||||||
{
|
{
|
||||||
if (mt.hasGlobDeleteAll)
|
|
||||||
appendIfNew(m_mimeTypesWithDeletedGlobs, mt.name);
|
|
||||||
m_nameMimeTypeMap.insert(mt.name, mt);
|
m_nameMimeTypeMap.insert(mt.name, mt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
\a toExclude is a list of mime type names that should have the the glob patterns
|
|
||||||
associated with them cleared (because there are mime types with the same names
|
|
||||||
in a higher precedence Provider that have glob-deleteall tags).
|
|
||||||
|
|
||||||
This method is called from QMimeDatabasePrivate::loadProviders() to exclude mime
|
|
||||||
type glob patterns in lower precedence Providers.
|
|
||||||
*/
|
|
||||||
void QMimeXMLProvider::excludeMimeTypeGlobs(const QStringList &toExclude)
|
|
||||||
{
|
|
||||||
for (const auto &mt : toExclude) {
|
|
||||||
auto it = m_nameMimeTypeMap.find(mt);
|
|
||||||
if (it != m_nameMimeTypeMap.end())
|
|
||||||
it->globPatterns.clear();
|
|
||||||
m_mimeTypeGlobs.removeMimeType(mt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void QMimeXMLProvider::addParents(const QString &mime, QStringList &result)
|
void QMimeXMLProvider::addParents(const QString &mime, QStringList &result)
|
||||||
{
|
{
|
||||||
for (const QString &parent : m_parents.value(mime)) {
|
for (const QString &parent : m_parents.value(mime)) {
|
||||||
|
@ -29,6 +29,7 @@ QT_BEGIN_NAMESPACE
|
|||||||
|
|
||||||
class QMimeMagicRuleMatcher;
|
class QMimeMagicRuleMatcher;
|
||||||
class QMimeTypeXMLData;
|
class QMimeTypeXMLData;
|
||||||
|
class QMimeProviderBase;
|
||||||
|
|
||||||
class QMimeProviderBase
|
class QMimeProviderBase
|
||||||
{
|
{
|
||||||
@ -53,38 +54,16 @@ public:
|
|||||||
virtual QString icon(const QString &name) = 0;
|
virtual QString icon(const QString &name) = 0;
|
||||||
virtual QString genericIcon(const QString &name) = 0;
|
virtual QString genericIcon(const QString &name) = 0;
|
||||||
virtual void ensureLoaded() { }
|
virtual void ensureLoaded() { }
|
||||||
virtual void excludeMimeTypeGlobs(const QStringList &) { }
|
|
||||||
|
|
||||||
QString directory() const { return m_directory; }
|
QString directory() const { return m_directory; }
|
||||||
|
|
||||||
|
QMimeProviderBase *overrideProvider() const;
|
||||||
|
void setOverrideProvider(QMimeProviderBase *provider);
|
||||||
|
bool isMimeTypeGlobsExcluded(const QString &name) const;
|
||||||
|
|
||||||
QMimeDatabasePrivate *m_db;
|
QMimeDatabasePrivate *m_db;
|
||||||
QString m_directory;
|
QString m_directory;
|
||||||
|
QMimeProviderBase *m_overrideProvider = nullptr; // more "local" than this one
|
||||||
/*
|
|
||||||
MimeTypes with "glob-deleteall" tags are handled differently by each provider
|
|
||||||
sub-class:
|
|
||||||
- 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 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
|
|
||||||
about mimetypes with glob-deleteall.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
List of mimetypes in _this_ Provider that have a "glob-deleteall" tag,
|
|
||||||
glob patterns for those mimetypes should be ignored in all _other_ lower
|
|
||||||
precedence Providers.
|
|
||||||
*/
|
|
||||||
QStringList m_mimeTypesWithDeletedGlobs;
|
|
||||||
|
|
||||||
/*
|
|
||||||
List of mimetypes with glob patterns that are "overwritten" in _this_ Provider,
|
|
||||||
by a "glob-deleteall" tag in a mimetype definition in a _higher precedence_
|
|
||||||
Provider. With QMimeBinaryProvider, we can't change the data in the binary mmap'ed
|
|
||||||
file, hence the need for this list.
|
|
||||||
*/
|
|
||||||
QStringList m_mimeTypesWithExcludedGlobs;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -111,7 +90,6 @@ public:
|
|||||||
QString icon(const QString &name) override;
|
QString icon(const QString &name) override;
|
||||||
QString genericIcon(const QString &name) override;
|
QString genericIcon(const QString &name) override;
|
||||||
void ensureLoaded() override;
|
void ensureLoaded() override;
|
||||||
void excludeMimeTypeGlobs(const QStringList &toExclude) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct CacheFile;
|
struct CacheFile;
|
||||||
@ -121,7 +99,6 @@ private:
|
|||||||
bool matchSuffixTree(QMimeGlobMatchResult &result, CacheFile *cacheFile, int numEntries,
|
bool matchSuffixTree(QMimeGlobMatchResult &result, CacheFile *cacheFile, int numEntries,
|
||||||
int firstOffset, const QString &fileName, qsizetype charPos,
|
int firstOffset, const QString &fileName, qsizetype charPos,
|
||||||
bool caseSensitiveCheck);
|
bool caseSensitiveCheck);
|
||||||
bool isMimeTypeGlobsExcluded(const char *name);
|
|
||||||
bool matchMagicRule(CacheFile *cacheFile, int numMatchlets, int firstOffset,
|
bool matchMagicRule(CacheFile *cacheFile, int numMatchlets, int firstOffset,
|
||||||
const QByteArray &data);
|
const QByteArray &data);
|
||||||
QLatin1StringView iconForMime(CacheFile *cacheFile, int posListOffset, const QByteArray &inputMime);
|
QLatin1StringView iconForMime(CacheFile *cacheFile, int posListOffset, const QByteArray &inputMime);
|
||||||
@ -180,7 +157,6 @@ public:
|
|||||||
|
|
||||||
// Called by the mimetype xml parser
|
// Called by the mimetype xml parser
|
||||||
void addMimeType(const QMimeTypeXMLData &mt);
|
void addMimeType(const QMimeTypeXMLData &mt);
|
||||||
void excludeMimeTypeGlobs(const QStringList &toExclude) override;
|
|
||||||
void addGlobPattern(const QMimeGlobPattern &glob);
|
void addGlobPattern(const QMimeGlobPattern &glob);
|
||||||
void addParent(const QString &child, const QString &parent);
|
void addParent(const QString &child, const QString &parent);
|
||||||
void addAlias(const QString &alias, const QString &name);
|
void addAlias(const QString &alias, const QString &name);
|
||||||
|
@ -1221,10 +1221,6 @@ void tst_QMimeDatabase::installNewLocalMimeType()
|
|||||||
{ // QTBUG-101755
|
{ // QTBUG-101755
|
||||||
QList<QMimeType> mimes = db.mimeTypesForFileName(u"foo.webm"_s);
|
QList<QMimeType> mimes = db.mimeTypesForFileName(u"foo.webm"_s);
|
||||||
// "*.webm" glob pattern is deleted with "glob-deleteall"
|
// "*.webm" glob pattern is deleted with "glob-deleteall"
|
||||||
if (m_isUsingCacheProvider && useLocalBinaryCache)
|
|
||||||
QEXPECT_FAIL("with_binary_cache",
|
|
||||||
"BUG, glob-deleteall isn't handled correctly between binary providers",
|
|
||||||
Continue);
|
|
||||||
QVERIFY2(mimes.isEmpty(), qPrintable(mimeTypeNames(mimes).join(u',')));
|
QVERIFY2(mimes.isEmpty(), qPrintable(mimeTypeNames(mimes).join(u',')));
|
||||||
mimes = db.mimeTypesForFileName(u"foo.videowebm"_s);
|
mimes = db.mimeTypesForFileName(u"foo.videowebm"_s);
|
||||||
QCOMPARE(mimes.size(), 1);
|
QCOMPARE(mimes.size(), 1);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user