summaryrefslogtreecommitdiffstats
path: root/src/corelib/mimetypes
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/mimetypes')
-rw-r--r--src/corelib/mimetypes/mimetypes.qrc2
-rw-r--r--src/corelib/mimetypes/qmimedatabase.cpp240
-rw-r--r--src/corelib/mimetypes/qmimedatabase_p.h27
-rw-r--r--src/corelib/mimetypes/qmimeglobpattern.cpp5
-rw-r--r--src/corelib/mimetypes/qmimeglobpattern_p.h2
-rw-r--r--src/corelib/mimetypes/qmimemagicrule.cpp2
-rw-r--r--src/corelib/mimetypes/qmimemagicrule_p.h2
-rw-r--r--src/corelib/mimetypes/qmimeprovider.cpp525
-rw-r--r--src/corelib/mimetypes/qmimeprovider_p.h82
-rw-r--r--src/corelib/mimetypes/qmimetype.cpp115
-rw-r--r--src/corelib/mimetypes/qmimetype.h18
-rw-r--r--src/corelib/mimetypes/qmimetype_p.h3
-rw-r--r--src/corelib/mimetypes/qmimetypeparser.cpp2
13 files changed, 588 insertions, 437 deletions
diff --git a/src/corelib/mimetypes/mimetypes.qrc b/src/corelib/mimetypes/mimetypes.qrc
index f0cf47cd49..19bc1d3e2a 100644
--- a/src/corelib/mimetypes/mimetypes.qrc
+++ b/src/corelib/mimetypes/mimetypes.qrc
@@ -1,5 +1,5 @@
<RCC>
- <qresource prefix="/qt-project.org/qmime">
+ <qresource prefix="/qt-project.org/qmime/packages">
<file alias="freedesktop.org.xml">mime/packages/freedesktop.org.xml</file>
</qresource>
</RCC>
diff --git a/src/corelib/mimetypes/qmimedatabase.cpp b/src/corelib/mimetypes/qmimedatabase.cpp
index 687f0b3e03..edc414fa0a 100644
--- a/src/corelib/mimetypes/qmimedatabase.cpp
+++ b/src/corelib/mimetypes/qmimedatabase.cpp
@@ -51,6 +51,7 @@
#include <QtCore/QFile>
#include <QtCore/QFileInfo>
#include <QtCore/QSet>
+#include <QtCore/QStandardPaths>
#include <QtCore/QBuffer>
#include <QtCore/QUrl>
#include <QtCore/QDebug>
@@ -69,34 +70,107 @@ QMimeDatabasePrivate *QMimeDatabasePrivate::instance()
}
QMimeDatabasePrivate::QMimeDatabasePrivate()
- : m_provider(0), m_defaultMimeType(QLatin1String("application/octet-stream"))
+ : m_defaultMimeType(QLatin1String("application/octet-stream"))
{
}
QMimeDatabasePrivate::~QMimeDatabasePrivate()
{
- delete m_provider;
- m_provider = 0;
+ qDeleteAll(m_providers);
}
-QMimeProviderBase *QMimeDatabasePrivate::provider()
+#ifdef QT_BUILD_INTERNAL
+Q_CORE_EXPORT
+#else
+static const
+#endif
+int qmime_secondsBetweenChecks = 5;
+
+bool QMimeDatabasePrivate::shouldCheck()
+{
+ if (m_lastCheck.isValid() && m_lastCheck.elapsed() < qmime_secondsBetweenChecks * 1000)
+ return false;
+ m_lastCheck.start();
+ return true;
+}
+
+#if defined(Q_OS_UNIX) && !defined(Q_OS_INTEGRITY)
+#define QT_USE_MMAP
+#endif
+
+void QMimeDatabasePrivate::loadProviders()
{
- if (!m_provider) {
- QMimeProviderBase *binaryProvider = new QMimeBinaryProvider(this);
- if (binaryProvider->isValid()) {
- m_provider = binaryProvider;
+ // We use QStandardPaths every time to check if new files appeared
+ QStringList mimeDirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QLatin1String("mime"), QStandardPaths::LocateDirectory);
+ const auto fdoIterator = std::find_if(mimeDirs.constBegin(), mimeDirs.constEnd(), [](const QString &mimeDir) -> bool {
+ return QFileInfo::exists(mimeDir + QStringLiteral("/packages/freedesktop.org.xml")); }
+ );
+ if (fdoIterator == mimeDirs.constEnd())
+ mimeDirs.prepend(QLatin1String(":/qt-project.org/qmime"));
+ //qDebug() << "mime dirs:" << mimeDirs;
+
+ QVector<QMimeProviderBase *> currentProviders = m_providers;
+ m_providers.clear();
+ m_providers.reserve(mimeDirs.size());
+ for (const QString &mimeDir : qAsConst(mimeDirs)) {
+ const QString cacheFile = mimeDir + QStringLiteral("/mime.cache");
+ QFileInfo fileInfo(cacheFile);
+ // Check if we already have a provider for this dir
+ const auto it = std::find_if(currentProviders.begin(), currentProviders.end(), [mimeDir](QMimeProviderBase *prov) { return prov->directory() == mimeDir; });
+ if (it == currentProviders.end()) {
+ QMimeProviderBase *provider = nullptr;
+#if defined(QT_USE_MMAP)
+ if (qEnvironmentVariableIsEmpty("QT_NO_MIME_CACHE") && fileInfo.exists()) {
+ provider = new QMimeBinaryProvider(this, mimeDir);
+ //qDebug() << "Created binary provider for" << mimeDir;
+ if (!provider->isValid()) {
+ delete provider;
+ provider = nullptr;
+ }
+ }
+#endif
+ if (!provider) {
+ provider = new QMimeXMLProvider(this, mimeDir);
+ //qDebug() << "Created XML provider for" << mimeDir;
+ }
+ m_providers.append(provider);
} else {
- delete binaryProvider;
- m_provider = new QMimeXMLProvider(this);
+ QMimeProviderBase *provider = *it;
+ currentProviders.erase(it);
+ provider->ensureLoaded();
+ if (!provider->isValid()) {
+ delete provider;
+ provider = new QMimeXMLProvider(this, mimeDir);
+ //qDebug() << "Created XML provider to replace binary provider for" << mimeDir;
+ }
+ m_providers.append(provider);
}
}
- return m_provider;
+ qDeleteAll(currentProviders);
}
-void QMimeDatabasePrivate::setProvider(QMimeProviderBase *theProvider)
+QVector<QMimeProviderBase *> QMimeDatabasePrivate::providers()
{
- delete m_provider;
- m_provider = theProvider;
+ Q_ASSERT(!mutex.tryLock()); // caller should have locked mutex
+ if (m_providers.isEmpty()) {
+ loadProviders();
+ m_lastCheck.start();
+ } else {
+ if (shouldCheck())
+ loadProviders();
+ }
+ return m_providers;
+}
+
+QString QMimeDatabasePrivate::resolveAlias(const QString &nameOrAlias)
+{
+ const auto allProviders = providers();
+ for (QMimeProviderBase *provider : allProviders) {
+ const QString ret = provider->resolveAlias(nameOrAlias);
+ if (!ret.isEmpty())
+ return ret;
+ }
+ return nameOrAlias;
}
/*!
@@ -105,7 +179,14 @@ void QMimeDatabasePrivate::setProvider(QMimeProviderBase *theProvider)
*/
QMimeType QMimeDatabasePrivate::mimeTypeForName(const QString &nameOrAlias)
{
- return provider()->mimeTypeForName(provider()->resolveAlias(nameOrAlias));
+ const auto allProviders = providers();
+ const QString mimeName = resolveAlias(nameOrAlias);
+ for (QMimeProviderBase *provider : allProviders) {
+ const QMimeType mime = provider->mimeTypeForName(mimeName);
+ if (mime.isValid())
+ return mime;
+ }
+ return {};
}
QStringList QMimeDatabasePrivate::mimeTypeForFileName(const QString &fileName)
@@ -113,11 +194,113 @@ QStringList QMimeDatabasePrivate::mimeTypeForFileName(const QString &fileName)
if (fileName.endsWith(QLatin1Char('/')))
return QStringList() << QLatin1String("inode/directory");
- QStringList matchingMimeTypes = provider()->findByFileName(QFileInfo(fileName).fileName()).m_matchingMimeTypes;
+ const QString shortName = QFileInfo(fileName).fileName();
+ const QMimeGlobMatchResult result = findByFileName(shortName);
+ QStringList matchingMimeTypes = result.m_matchingMimeTypes;
matchingMimeTypes.sort(); // make it deterministic
return matchingMimeTypes;
}
+QMimeGlobMatchResult QMimeDatabasePrivate::findByFileName(const QString &fileName)
+{
+ QMimeGlobMatchResult result;
+ // TODO this parses in the order (local, global). Check that it handles "NOGLOBS" correctly.
+ const auto allProviders = providers();
+ for (QMimeProviderBase *provider : allProviders)
+ provider->addFileNameMatches(fileName, result);
+ return result;
+}
+
+void QMimeDatabasePrivate::loadMimeTypePrivate(QMimeTypePrivate &mimePrivate)
+{
+ QMutexLocker locker(&mutex);
+ if (!mimePrivate.loaded) { // XML provider sets loaded=true, binary provider does this on demand
+ Q_ASSERT(mimePrivate.fromCache);
+ QMimeBinaryProvider::loadMimeTypePrivate(mimePrivate);
+ }
+}
+
+void QMimeDatabasePrivate::loadGenericIcon(QMimeTypePrivate &mimePrivate)
+{
+ QMutexLocker locker(&mutex);
+ if (mimePrivate.fromCache) {
+ mimePrivate.genericIconName.clear();
+ const auto allProviders = providers();
+ for (QMimeProviderBase *provider : allProviders) {
+ provider->loadGenericIcon(mimePrivate);
+ if (!mimePrivate.genericIconName.isEmpty())
+ break;
+ }
+ }
+}
+
+void QMimeDatabasePrivate::loadIcon(QMimeTypePrivate &mimePrivate)
+{
+ QMutexLocker locker(&mutex);
+ if (mimePrivate.fromCache) {
+ mimePrivate.iconName.clear();
+ const auto allProviders = providers();
+ for (QMimeProviderBase *provider : allProviders) {
+ provider->loadIcon(mimePrivate);
+ if (!mimePrivate.iconName.isEmpty())
+ break;
+ }
+ }
+}
+
+static QString fallbackParent(const QString &mimeTypeName)
+{
+ const QStringRef myGroup = mimeTypeName.leftRef(mimeTypeName.indexOf(QLatin1Char('/')));
+ // All text/* types are subclasses of text/plain.
+ if (myGroup == QLatin1String("text") && mimeTypeName != QLatin1String("text/plain"))
+ return QLatin1String("text/plain");
+ // All real-file mimetypes implicitly derive from application/octet-stream
+ if (myGroup != QLatin1String("inode") &&
+ // ignore non-file extensions
+ myGroup != QLatin1String("all") && myGroup != QLatin1String("fonts") && myGroup != QLatin1String("print") && myGroup != QLatin1String("uri")
+ && mimeTypeName != QLatin1String("application/octet-stream")) {
+ return QLatin1String("application/octet-stream");
+ }
+ return QString();
+}
+
+QStringList QMimeDatabasePrivate::mimeParents(const QString &mimeName)
+{
+ QMutexLocker locker(&mutex);
+ return parents(mimeName);
+}
+
+QStringList QMimeDatabasePrivate::parents(const QString &mimeName)
+{
+ Q_ASSERT(!mutex.tryLock());
+ QStringList result;
+ const auto allProviders = providers();
+ for (QMimeProviderBase *provider : allProviders)
+ provider->addParents(mimeName, result);
+ if (result.isEmpty()) {
+ const QString parent = fallbackParent(mimeName);
+ if (!parent.isEmpty())
+ result.append(parent);
+ }
+ return result;
+}
+
+QStringList QMimeDatabasePrivate::listAliases(const QString &mimeName)
+{
+ QMutexLocker locker(&mutex);
+ QStringList result;
+ const auto allProviders = providers();
+ for (QMimeProviderBase *provider : allProviders)
+ provider->addAliases(mimeName, result);
+ return result;
+}
+
+bool QMimeDatabasePrivate::mimeInherits(const QString &mime, const QString &parent)
+{
+ QMutexLocker locker(&mutex);
+ return inherits(mime, parent);
+}
+
static inline bool isTextFile(const QByteArray &data)
{
// UTF16 byte order marks
@@ -145,7 +328,10 @@ QMimeType QMimeDatabasePrivate::findByData(const QByteArray &data, int *accuracy
}
*accuracyPtr = 0;
- QMimeType candidate = provider()->findByMagic(data, accuracyPtr);
+ QMimeType candidate;
+ const auto allProviders = providers();
+ for (QMimeProviderBase *provider : allProviders)
+ provider->findByMagic(data, accuracyPtr, candidate);
if (candidate.isValid())
return candidate;
@@ -172,7 +358,7 @@ QMimeType QMimeDatabasePrivate::mimeTypeForFileNameAndData(const QString &fileNa
if (fileName.endsWith(QLatin1Char('/')))
candidatesByName.addMatch(QLatin1String("inode/directory"), 100, QString());
else
- candidatesByName = provider()->findByFileName(QFileInfo(fileName).fileName());
+ candidatesByName = findByFileName(QFileInfo(fileName).fileName());
if (candidatesByName.m_allMatchingMimeTypes.count() == 1) {
*accuracyPtr = 100;
const QMimeType mime = mimeTypeForName(candidatesByName.m_matchingMimeTypes.at(0));
@@ -222,21 +408,25 @@ QMimeType QMimeDatabasePrivate::mimeTypeForFileNameAndData(const QString &fileNa
QList<QMimeType> QMimeDatabasePrivate::allMimeTypes()
{
- return provider()->allMimeTypes();
+ QList<QMimeType> result;
+ const auto allProviders = providers();
+ for (QMimeProviderBase *provider : allProviders)
+ provider->addAllMimeTypes(result);
+ return result;
}
bool QMimeDatabasePrivate::inherits(const QString &mime, const QString &parent)
{
- const QString resolvedParent = provider()->resolveAlias(parent);
- //Q_ASSERT(provider()->resolveAlias(mime) == mime);
+ const QString resolvedParent = resolveAlias(parent);
std::stack<QString, QStringList> toCheck;
toCheck.push(mime);
while (!toCheck.empty()) {
if (toCheck.top() == resolvedParent)
return true;
- const auto parents = provider()->parents(toCheck.top());
+ const QString mimeName = toCheck.top();
toCheck.pop();
- for (const QString &par : parents)
+ const auto parentList = parents(mimeName);
+ for (const QString &par : parentList)
toCheck.push(par);
}
return false;
@@ -460,7 +650,7 @@ QList<QMimeType> QMimeDatabase::mimeTypesForFileName(const QString &fileName) co
QString QMimeDatabase::suffixForFileName(const QString &fileName) const
{
QMutexLocker locker(&d->mutex);
- return d->provider()->findByFileName(QFileInfo(fileName).fileName()).m_foundSuffix;
+ return d->findByFileName(QFileInfo(fileName).fileName()).m_foundSuffix;
}
/*!
@@ -550,6 +740,7 @@ QMimeType QMimeDatabase::mimeTypeForUrl(const QUrl &url) const
*/
QMimeType QMimeDatabase::mimeTypeForFileNameAndData(const QString &fileName, QIODevice *device) const
{
+ QMutexLocker locker(&d->mutex);
int accuracy = 0;
const bool openedByUs = !device->isOpen() && device->open(QIODevice::ReadOnly);
const QMimeType result = d->mimeTypeForFileNameAndData(fileName, device, &accuracy);
@@ -576,6 +767,7 @@ QMimeType QMimeDatabase::mimeTypeForFileNameAndData(const QString &fileName, QIO
*/
QMimeType QMimeDatabase::mimeTypeForFileNameAndData(const QString &fileName, const QByteArray &data) const
{
+ QMutexLocker locker(&d->mutex);
QBuffer buffer(const_cast<QByteArray *>(&data));
buffer.open(QIODevice::ReadOnly);
int accuracy = 0;
diff --git a/src/corelib/mimetypes/qmimedatabase_p.h b/src/corelib/mimetypes/qmimedatabase_p.h
index 3f63f5f103..1c38f46115 100644
--- a/src/corelib/mimetypes/qmimedatabase_p.h
+++ b/src/corelib/mimetypes/qmimedatabase_p.h
@@ -59,7 +59,9 @@
#include "qmimetype_p.h"
#include "qmimeglobpattern_p.h"
+#include <QtCore/qelapsedtimer.h>
#include <QtCore/qmutex.h>
+#include <QtCore/qvector.h>
QT_BEGIN_NAMESPACE
@@ -77,22 +79,37 @@ public:
static QMimeDatabasePrivate *instance();
- QMimeProviderBase *provider();
- void setProvider(QMimeProviderBase *theProvider);
-
inline QString defaultMimeType() const { return m_defaultMimeType; }
bool inherits(const QString &mime, const QString &parent);
QList<QMimeType> allMimeTypes();
-
+ QString resolveAlias(const QString &nameOrAlias);
+ QStringList parents(const QString &mimeName);
QMimeType mimeTypeForName(const QString &nameOrAlias);
QMimeType mimeTypeForFileNameAndData(const QString &fileName, QIODevice *device, int *priorityPtr);
QMimeType findByData(const QByteArray &data, int *priorityPtr);
QStringList mimeTypeForFileName(const QString &fileName);
+ 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);
+ QStringList mimeParents(const QString &mimeName);
+ QStringList listAliases(const QString &mimeName);
+ bool mimeInherits(const QString &mime, const QString &parent);
- mutable QMimeProviderBase *m_provider;
+private:
+ QVector<QMimeProviderBase *> providers();
+ bool shouldCheck();
+ void loadProviders();
+
+ mutable QVector<QMimeProviderBase *> m_providers;
+ QElapsedTimer m_lastCheck;
+
+public:
const QString m_defaultMimeType;
QMutex mutex;
};
diff --git a/src/corelib/mimetypes/qmimeglobpattern.cpp b/src/corelib/mimetypes/qmimeglobpattern.cpp
index a4d2b046fa..e7b2b879a1 100644
--- a/src/corelib/mimetypes/qmimeglobpattern.cpp
+++ b/src/corelib/mimetypes/qmimeglobpattern.cpp
@@ -206,10 +206,9 @@ void QMimeGlobPatternList::match(QMimeGlobMatchResult &result,
}
}
-QMimeGlobMatchResult QMimeAllGlobPatterns::matchingGlobs(const QString &fileName) const
+void QMimeAllGlobPatterns::matchingGlobs(const QString &fileName, QMimeGlobMatchResult &result) const
{
// First try the high weight matches (>50), if any.
- QMimeGlobMatchResult result;
m_highWeightGlobs.match(result, fileName);
// Now use the "fast patterns" dict, for simple *.foo patterns with weight 50
@@ -230,8 +229,6 @@ QMimeGlobMatchResult QMimeAllGlobPatterns::matchingGlobs(const QString &fileName
// Finally, try the low weight matches (<=50)
m_lowWeightGlobs.match(result, fileName);
-
- return result;
}
void QMimeAllGlobPatterns::clear()
diff --git a/src/corelib/mimetypes/qmimeglobpattern_p.h b/src/corelib/mimetypes/qmimeglobpattern_p.h
index 21332e71bc..103729c4ff 100644
--- a/src/corelib/mimetypes/qmimeglobpattern_p.h
+++ b/src/corelib/mimetypes/qmimeglobpattern_p.h
@@ -152,7 +152,7 @@ public:
void addGlob(const QMimeGlobPattern &glob);
void removeMimeType(const QString &mimeType);
- QMimeGlobMatchResult matchingGlobs(const QString &fileName) const;
+ void matchingGlobs(const QString &fileName, QMimeGlobMatchResult &result) const;
void clear();
PatternsMap m_fastPatterns; // example: "doc" -> "application/msword", "text/plain"
diff --git a/src/corelib/mimetypes/qmimemagicrule.cpp b/src/corelib/mimetypes/qmimemagicrule.cpp
index 5bbf1bba9d..6356a3581b 100644
--- a/src/corelib/mimetypes/qmimemagicrule.cpp
+++ b/src/corelib/mimetypes/qmimemagicrule.cpp
@@ -65,7 +65,7 @@ static const char magicRuleTypes_string[] =
"\0";
static const int magicRuleTypes_indices[] = {
- 0, 8, 15, 22, 29, 35, 41, 50, 59, 65, 0
+ 0, 8, 15, 22, 29, 35, 41, 50, 59, 64, 0
};
QMimeMagicRule::Type QMimeMagicRule::type(const QByteArray &theTypeName)
diff --git a/src/corelib/mimetypes/qmimemagicrule_p.h b/src/corelib/mimetypes/qmimemagicrule_p.h
index 0c6c1dbcd7..9b27ef2657 100644
--- a/src/corelib/mimetypes/qmimemagicrule_p.h
+++ b/src/corelib/mimetypes/qmimemagicrule_p.h
@@ -90,7 +90,7 @@ public:
int endPos() const { return m_endPos; }
QByteArray mask() const;
- bool isValid() const { return m_matchFunction != Q_NULLPTR; }
+ bool isValid() const { return m_matchFunction != nullptr; }
bool matches(const QByteArray &data) const;
diff --git a/src/corelib/mimetypes/qmimeprovider.cpp b/src/corelib/mimetypes/qmimeprovider.cpp
index 5c0acce4c3..ec0a6bf0ef 100644
--- a/src/corelib/mimetypes/qmimeprovider.cpp
+++ b/src/corelib/mimetypes/qmimeprovider.cpp
@@ -61,46 +61,18 @@ static void initResources()
QT_BEGIN_NAMESPACE
-static QString fallbackParent(const QString &mimeTypeName)
-{
- const QStringRef myGroup = mimeTypeName.leftRef(mimeTypeName.indexOf(QLatin1Char('/')));
- // All text/* types are subclasses of text/plain.
- if (myGroup == QLatin1String("text") && mimeTypeName != QLatin1String("text/plain"))
- return QLatin1String("text/plain");
- // All real-file mimetypes implicitly derive from application/octet-stream
- if (myGroup != QLatin1String("inode") &&
- // ignore non-file extensions
- myGroup != QLatin1String("all") && myGroup != QLatin1String("fonts") && myGroup != QLatin1String("print") && myGroup != QLatin1String("uri")
- && mimeTypeName != QLatin1String("application/octet-stream")) {
- return QLatin1String("application/octet-stream");
- }
- return QString();
-}
-
-QMimeProviderBase::QMimeProviderBase(QMimeDatabasePrivate *db)
- : m_db(db)
+QMimeProviderBase::QMimeProviderBase(QMimeDatabasePrivate *db, const QString &directory)
+ : m_db(db), m_directory(directory)
{
}
-Q_CORE_EXPORT int qmime_secondsBetweenChecks = 5; // exported for the unit test
-bool QMimeProviderBase::shouldCheck()
-{
- if (m_lastCheck.isValid() && m_lastCheck.elapsed() < qmime_secondsBetweenChecks * 1000)
- return false;
- m_lastCheck.start();
- return true;
-}
-
-QMimeBinaryProvider::QMimeBinaryProvider(QMimeDatabasePrivate *db)
- : QMimeProviderBase(db), m_mimetypeListLoaded(false)
+QMimeBinaryProvider::QMimeBinaryProvider(QMimeDatabasePrivate *db, const QString &directory)
+ : QMimeProviderBase(db, directory), m_mimetypeListLoaded(false)
{
+ ensureLoaded();
}
-#if defined(Q_OS_UNIX) && !defined(Q_OS_INTEGRITY)
-#define QT_USE_MMAP
-#endif
-
struct QMimeBinaryProvider::CacheFile
{
CacheFile(const QString &fileName);
@@ -154,7 +126,6 @@ bool QMimeBinaryProvider::CacheFile::load()
bool QMimeBinaryProvider::CacheFile::reload()
{
- //qDebug() << "reload!" << file->fileName();
m_valid = false;
if (file.isOpen()) {
file.close();
@@ -163,18 +134,14 @@ bool QMimeBinaryProvider::CacheFile::reload()
return load();
}
-QMimeBinaryProvider::CacheFile *QMimeBinaryProvider::CacheFileList::findCacheFile(const QString &fileName) const
+QMimeBinaryProvider::~QMimeBinaryProvider()
{
- for (const_iterator it = begin(); it != end(); ++it) {
- if ((*it)->file.fileName() == fileName)
- return *it;
- }
- return 0;
+ delete m_cacheFile;
}
-QMimeBinaryProvider::~QMimeBinaryProvider()
+bool QMimeBinaryProvider::isValid()
{
- qDeleteAll(m_cacheFiles);
+ return m_cacheFile != nullptr;
}
// Position of the "list offsets" values, at the beginning of the mime.cache file
@@ -190,79 +157,33 @@ enum {
PosGenericIconsListOffset = 36
};
-bool QMimeBinaryProvider::isValid()
+bool QMimeBinaryProvider::checkCacheChanged()
{
-#if defined(QT_USE_MMAP)
- if (!qEnvironmentVariableIsEmpty("QT_NO_MIME_CACHE"))
- return false;
-
- Q_ASSERT(m_cacheFiles.isEmpty()); // this method is only ever called once
- checkCache();
-
- if (m_cacheFiles.count() > 1)
+ QFileInfo fileInfo(m_cacheFile->file);
+ if (fileInfo.lastModified() > m_cacheFile->m_mtime) {
+ // Deletion can't happen by just running update-mime-database.
+ // But the user could use rm -rf :-)
+ m_cacheFile->reload(); // will mark itself as invalid on failure
return true;
- if (m_cacheFiles.isEmpty())
- return false;
-
- // We found exactly one file; is it the user-modified mimes, or a system file?
- const QString foundFile = m_cacheFiles.constFirst()->file.fileName();
- const QString localCacheFile = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1String("/mime/mime.cache");
-
- return foundFile != localCacheFile;
-#else
- return false;
-#endif
-}
-
-bool QMimeBinaryProvider::CacheFileList::checkCacheChanged()
-{
- bool somethingChanged = false;
- for (CacheFile *cacheFile : qAsConst(*this)) {
- QFileInfo fileInfo(cacheFile->file);
- if (!fileInfo.exists() || fileInfo.lastModified() > cacheFile->m_mtime) {
- // Deletion can't happen by just running update-mime-database.
- // But the user could use rm -rf :-)
- cacheFile->reload(); // will mark itself as invalid on failure
- somethingChanged = true;
- }
- }
- if (somethingChanged) {
- auto deleteIfNoLongerValid = [](CacheFile *cacheFile) -> bool {
- const bool invalid = !cacheFile->isValid();
- if (invalid)
- delete cacheFile;
- return invalid;
- };
- erase(std::remove_if(begin(), end(), deleteIfNoLongerValid), end());
}
- return somethingChanged;
+ return false;
}
-void QMimeBinaryProvider::checkCache()
+void QMimeBinaryProvider::ensureLoaded()
{
- if (!shouldCheck())
- return;
-
- // First iterate over existing known cache files and check for uptodate
- if (m_cacheFiles.checkCacheChanged())
- m_mimetypeListLoaded = false;
-
- // Then check if new cache files appeared
- const QStringList cacheFileNames = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QLatin1String("mime/mime.cache"));
- if (cacheFileNames != m_cacheFileNames) {
- for (const QString &cacheFileName : cacheFileNames) {
- CacheFile *cacheFile = m_cacheFiles.findCacheFile(cacheFileName);
- if (!cacheFile) {
- //qDebug() << "new file:" << cacheFileName;
- cacheFile = new CacheFile(cacheFileName);
- if (cacheFile->isValid()) // verify version
- m_cacheFiles.append(cacheFile);
- else
- delete cacheFile;
- }
- }
- m_cacheFileNames = cacheFileNames;
+ if (!m_cacheFile) {
+ const QString cacheFileName = m_directory + QLatin1String("/mime.cache");
+ m_cacheFile = new CacheFile(cacheFileName);
m_mimetypeListLoaded = false;
+ } else {
+ if (checkCacheChanged())
+ m_mimetypeListLoaded = false;
+ else
+ return; // nothing to do
+ }
+ if (!m_cacheFile->isValid()) { // verify existence and version
+ delete m_cacheFile;
+ m_cacheFile = nullptr;
}
}
@@ -270,6 +191,7 @@ 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
@@ -279,7 +201,6 @@ static QMimeType mimeTypeForNameUnchecked(const QString &name)
QMimeType QMimeBinaryProvider::mimeTypeForName(const QString &name)
{
- checkCache();
if (!m_mimetypeListLoaded)
loadMimeTypeList();
if (!m_mimetypeNames.contains(name))
@@ -287,28 +208,23 @@ QMimeType QMimeBinaryProvider::mimeTypeForName(const QString &name)
return mimeTypeForNameUnchecked(name);
}
-QMimeGlobMatchResult QMimeBinaryProvider::findByFileName(const QString &fileName)
+void QMimeBinaryProvider::addFileNameMatches(const QString &fileName, QMimeGlobMatchResult &result)
{
- checkCache();
- QMimeGlobMatchResult result;
if (fileName.isEmpty())
- return result;
+ return;
+ Q_ASSERT(m_cacheFile);
const QString lowerFileName = fileName.toLower();
- // TODO this parses in the order (local, global). Check that it handles "NOGLOBS" correctly.
- for (CacheFile *cacheFile : qAsConst(m_cacheFiles)) {
- // Check literals (e.g. "Makefile")
- matchGlobList(result, cacheFile, cacheFile->getUint32(PosLiteralListOffset), fileName);
- // Check complex globs (e.g. "callgrind.out[0-9]*")
- matchGlobList(result, cacheFile, cacheFile->getUint32(PosGlobListOffset), fileName);
- // Check the very common *.txt cases with the suffix tree
- const int reverseSuffixTreeOffset = cacheFile->getUint32(PosReverseSuffixTreeOffset);
- const int numRoots = cacheFile->getUint32(reverseSuffixTreeOffset);
- const int firstRootOffset = cacheFile->getUint32(reverseSuffixTreeOffset + 4);
- matchSuffixTree(result, cacheFile, numRoots, firstRootOffset, lowerFileName, lowerFileName.length() - 1, false);
- if (result.m_matchingMimeTypes.isEmpty())
- matchSuffixTree(result, cacheFile, numRoots, firstRootOffset, fileName, fileName.length() - 1, true);
- }
- return result;
+ // Check literals (e.g. "Makefile")
+ matchGlobList(result, m_cacheFile, m_cacheFile->getUint32(PosLiteralListOffset), fileName);
+ // Check complex globs (e.g. "callgrind.out[0-9]*")
+ matchGlobList(result, m_cacheFile, m_cacheFile->getUint32(PosGlobListOffset), fileName);
+ // Check the very common *.txt cases with the suffix tree
+ const int reverseSuffixTreeOffset = m_cacheFile->getUint32(PosReverseSuffixTreeOffset);
+ const int numRoots = m_cacheFile->getUint32(reverseSuffixTreeOffset);
+ const int firstRootOffset = m_cacheFile->getUint32(reverseSuffixTreeOffset + 4);
+ matchSuffixTree(result, m_cacheFile, numRoots, firstRootOffset, lowerFileName, lowerFileName.length() - 1, false);
+ if (result.m_matchingMimeTypes.isEmpty())
+ matchSuffixTree(result, m_cacheFile, numRoots, firstRootOffset, fileName, fileName.length() - 1, true);
}
void QMimeBinaryProvider::matchGlobList(QMimeGlobMatchResult &result, CacheFile *cacheFile, int off, const QString &fileName)
@@ -406,124 +322,106 @@ bool QMimeBinaryProvider::matchMagicRule(QMimeBinaryProvider::CacheFile *cacheFi
return false;
}
-QMimeType QMimeBinaryProvider::findByMagic(const QByteArray &data, int *accuracyPtr)
-{
- checkCache();
- for (CacheFile *cacheFile : qAsConst(m_cacheFiles)) {
- const int magicListOffset = cacheFile->getUint32(PosMagicListOffset);
- const int numMatches = cacheFile->getUint32(magicListOffset);
- //const int maxExtent = cacheFile->getUint32(magicListOffset + 4);
- const int firstMatchOffset = cacheFile->getUint32(magicListOffset + 8);
-
- for (int i = 0; i < numMatches; ++i) {
- const int off = firstMatchOffset + i * 16;
- const int numMatchlets = cacheFile->getUint32(off + 8);
- const int firstMatchletOffset = cacheFile->getUint32(off + 12);
- if (matchMagicRule(cacheFile, numMatchlets, firstMatchletOffset, data)) {
- const int mimeTypeOffset = cacheFile->getUint32(off + 4);
- const char *mimeType = cacheFile->getCharStar(mimeTypeOffset);
- *accuracyPtr = 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?)
- return mimeTypeForNameUnchecked(QLatin1String(mimeType));
- }
+void QMimeBinaryProvider::findByMagic(const QByteArray &data, int *accuracyPtr, QMimeType &candidate)
+{
+ const int magicListOffset = m_cacheFile->getUint32(PosMagicListOffset);
+ const int numMatches = m_cacheFile->getUint32(magicListOffset);
+ //const int maxExtent = cacheFile->getUint32(magicListOffset + 4);
+ const int firstMatchOffset = m_cacheFile->getUint32(magicListOffset + 8);
+
+ for (int i = 0; i < numMatches; ++i) {
+ const int off = firstMatchOffset + i * 16;
+ const int numMatchlets = m_cacheFile->getUint32(off + 8);
+ const int firstMatchletOffset = m_cacheFile->getUint32(off + 12);
+ if (matchMagicRule(m_cacheFile, numMatchlets, firstMatchletOffset, data)) {
+ const int mimeTypeOffset = m_cacheFile->getUint32(off + 4);
+ const char *mimeType = m_cacheFile->getCharStar(mimeTypeOffset);
+ *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(QLatin1String(mimeType));
+ return;
}
}
- return QMimeType();
}
-QStringList QMimeBinaryProvider::parents(const QString &mime)
+void QMimeBinaryProvider::addParents(const QString &mime, QStringList &result)
{
- checkCache();
const QByteArray mimeStr = mime.toLatin1();
- QStringList result;
- for (CacheFile *cacheFile : qAsConst(m_cacheFiles)) {
- const int parentListOffset = cacheFile->getUint32(PosParentListOffset);
- const int numEntries = cacheFile->getUint32(parentListOffset);
-
- int begin = 0;
- int end = numEntries - 1;
- while (begin <= end) {
- const int medium = (begin + end) / 2;
- const int off = parentListOffset + 4 + 8 * medium;
- const int mimeOffset = cacheFile->getUint32(off);
- const char *aMime = cacheFile->getCharStar(mimeOffset);
- const int cmp = qstrcmp(aMime, mimeStr);
- if (cmp < 0) {
- begin = medium + 1;
- } else if (cmp > 0) {
- end = medium - 1;
- } else {
- const int parentsOffset = cacheFile->getUint32(off + 4);
- const int numParents = cacheFile->getUint32(parentsOffset);
- for (int i = 0; i < numParents; ++i) {
- const int parentOffset = cacheFile->getUint32(parentsOffset + 4 + 4 * i);
- const char *aParent = cacheFile->getCharStar(parentOffset);
- result.append(QString::fromLatin1(aParent));
- }
- break;
+ const int parentListOffset = m_cacheFile->getUint32(PosParentListOffset);
+ const int numEntries = m_cacheFile->getUint32(parentListOffset);
+
+ int begin = 0;
+ int end = numEntries - 1;
+ while (begin <= end) {
+ const int medium = (begin + end) / 2;
+ const int off = parentListOffset + 4 + 8 * medium;
+ const int mimeOffset = m_cacheFile->getUint32(off);
+ const char *aMime = m_cacheFile->getCharStar(mimeOffset);
+ const int cmp = qstrcmp(aMime, mimeStr);
+ if (cmp < 0) {
+ begin = medium + 1;
+ } else if (cmp > 0) {
+ end = medium - 1;
+ } else {
+ const int parentsOffset = m_cacheFile->getUint32(off + 4);
+ const int numParents = m_cacheFile->getUint32(parentsOffset);
+ for (int i = 0; i < numParents; ++i) {
+ const int parentOffset = m_cacheFile->getUint32(parentsOffset + 4 + 4 * i);
+ const char *aParent = m_cacheFile->getCharStar(parentOffset);
+ const QString strParent = QString::fromLatin1(aParent);
+ if (!result.contains(strParent))
+ result.append(strParent);
}
+ break;
}
}
- if (result.isEmpty()) {
- const QString parent = fallbackParent(mime);
- if (!parent.isEmpty())
- result.append(parent);
- }
- return result;
}
QString QMimeBinaryProvider::resolveAlias(const QString &name)
{
- checkCache();
const QByteArray input = name.toLatin1();
- for (CacheFile *cacheFile : qAsConst(m_cacheFiles)) {
- const int aliasListOffset = cacheFile->getUint32(PosAliasListOffset);
- const int numEntries = cacheFile->getUint32(aliasListOffset);
- int begin = 0;
- int end = numEntries - 1;
- while (begin <= end) {
- const int medium = (begin + end) / 2;
- const int off = aliasListOffset + 4 + 8 * medium;
- const int aliasOffset = cacheFile->getUint32(off);
- const char *alias = cacheFile->getCharStar(aliasOffset);
- const int cmp = qstrcmp(alias, input);
- if (cmp < 0) {
- begin = medium + 1;
- } else if (cmp > 0) {
- end = medium - 1;
- } else {
- const int mimeOffset = cacheFile->getUint32(off + 4);
- const char *mimeType = cacheFile->getCharStar(mimeOffset);
- return QLatin1String(mimeType);
- }
+ const int aliasListOffset = m_cacheFile->getUint32(PosAliasListOffset);
+ const int numEntries = m_cacheFile->getUint32(aliasListOffset);
+ int begin = 0;
+ int end = numEntries - 1;
+ while (begin <= end) {
+ const int medium = (begin + end) / 2;
+ const int off = aliasListOffset + 4 + 8 * medium;
+ const int aliasOffset = m_cacheFile->getUint32(off);
+ const char *alias = m_cacheFile->getCharStar(aliasOffset);
+ const int cmp = qstrcmp(alias, input);
+ if (cmp < 0) {
+ begin = medium + 1;
+ } else if (cmp > 0) {
+ end = medium - 1;
+ } else {
+ const int mimeOffset = m_cacheFile->getUint32(off + 4);
+ const char *mimeType = m_cacheFile->getCharStar(mimeOffset);
+ return QLatin1String(mimeType);
}
}
-
return name;
}
-QStringList QMimeBinaryProvider::listAliases(const QString &name)
+void QMimeBinaryProvider::addAliases(const QString &name, QStringList &result)
{
- checkCache();
- QStringList result;
const QByteArray input = name.toLatin1();
- for (CacheFile *cacheFile : qAsConst(m_cacheFiles)) {
- const int aliasListOffset = cacheFile->getUint32(PosAliasListOffset);
- const int numEntries = cacheFile->getUint32(aliasListOffset);
- for (int pos = 0; pos < numEntries; ++pos) {
- const int off = aliasListOffset + 4 + 8 * pos;
- const int mimeOffset = cacheFile->getUint32(off + 4);
- const char *mimeType = cacheFile->getCharStar(mimeOffset);
-
- if (input == mimeType) {
- const int aliasOffset = cacheFile->getUint32(off);
- const char *alias = cacheFile->getCharStar(aliasOffset);
- result.append(QString::fromLatin1(alias));
- }
+ const int aliasListOffset = m_cacheFile->getUint32(PosAliasListOffset);
+ const int numEntries = m_cacheFile->getUint32(aliasListOffset);
+ for (int pos = 0; pos < numEntries; ++pos) {
+ const int off = aliasListOffset + 4 + 8 * pos;
+ const int mimeOffset = m_cacheFile->getUint32(off + 4);
+ const char *mimeType = m_cacheFile->getCharStar(mimeOffset);
+
+ if (input == mimeType) {
+ const int aliasOffset = m_cacheFile->getUint32(off);
+ const char *alias = m_cacheFile->getCharStar(aliasOffset);
+ const QString strAlias = QString::fromLatin1(alias);
+ if (!result.contains(strAlias))
+ result.append(strAlias);
}
}
- return result;
}
void QMimeBinaryProvider::loadMimeTypeList()
@@ -533,31 +431,30 @@ void QMimeBinaryProvider::loadMimeTypeList()
m_mimetypeNames.clear();
// Unfortunately mime.cache doesn't have a full list of all mimetypes.
// So we have to parse the plain-text files called "types".
- const QStringList typesFilenames = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QLatin1String("mime/types"));
- for (const QString &typeFilename : typesFilenames) {
- QFile file(typeFilename);
- if (file.open(QIODevice::ReadOnly)) {
- QTextStream stream(&file);
- stream.setCodec("ISO 8859-1");
- QString line;
- while (stream.readLineInto(&line))
- m_mimetypeNames.insert(line);
- }
+ QFile file(m_directory + QStringLiteral("/types"));
+ if (file.open(QIODevice::ReadOnly)) {
+ QTextStream stream(&file);
+ stream.setCodec("ISO 8859-1");
+ QString line;
+ while (stream.readLineInto(&line))
+ m_mimetypeNames.insert(line);
}
}
}
-QList<QMimeType> QMimeBinaryProvider::allMimeTypes()
+void QMimeBinaryProvider::addAllMimeTypes(QList<QMimeType> &result)
{
- QList<QMimeType> result;
loadMimeTypeList();
- result.reserve(m_mimetypeNames.count());
-
- for (QSet<QString>::const_iterator it = m_mimetypeNames.constBegin();
- it != m_mimetypeNames.constEnd(); ++it)
- result.append(mimeTypeForNameUnchecked(*it));
-
- return result;
+ if (result.isEmpty()) {
+ result.reserve(m_mimetypeNames.count());
+ for (const QString &name : m_mimetypeNames)
+ result.append(mimeTypeForNameUnchecked(name));
+ } else {
+ for (const QString &name : 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));
+ }
}
void QMimeBinaryProvider::loadMimeTypePrivate(QMimeTypePrivate &data)
@@ -655,7 +552,7 @@ void QMimeBinaryProvider::loadMimeTypePrivate(QMimeTypePrivate &data)
}
// Binary search in the icons or generic-icons list
-QString QMimeBinaryProvider::iconForMime(CacheFile *cacheFile, int posListOffset, const QByteArray &inputMime)
+QLatin1String QMimeBinaryProvider::iconForMime(CacheFile *cacheFile, int posListOffset, const QByteArray &inputMime)
{
const int iconsListOffset = cacheFile->getUint32(posListOffset);
const int numIcons = cacheFile->getUint32(iconsListOffset);
@@ -676,41 +573,34 @@ QString QMimeBinaryProvider::iconForMime(CacheFile *cacheFile, int posListOffset
return QLatin1String(cacheFile->getCharStar(iconOffset));
}
}
- return QString();
+ return QLatin1String();
}
void QMimeBinaryProvider::loadIcon(QMimeTypePrivate &data)
{
- checkCache();
const QByteArray inputMime = data.name.toLatin1();
- for (CacheFile *cacheFile : qAsConst(m_cacheFiles)) {
- const QString icon = iconForMime(cacheFile, PosIconsListOffset, inputMime);
- if (!icon.isEmpty()) {
- data.iconName = icon;
- return;
- }
+ const QLatin1String icon = iconForMime(m_cacheFile, PosIconsListOffset, inputMime);
+ if (!icon.isEmpty()) {
+ data.iconName = icon;
}
}
void QMimeBinaryProvider::loadGenericIcon(QMimeTypePrivate &data)
{
- checkCache();
const QByteArray inputMime = data.name.toLatin1();
- for (CacheFile *cacheFile : qAsConst(m_cacheFiles)) {
- const QString icon = iconForMime(cacheFile, PosGenericIconsListOffset, inputMime);
- if (!icon.isEmpty()) {
- data.genericIconName = icon;
- return;
- }
+ const QLatin1String icon = iconForMime(m_cacheFile, PosGenericIconsListOffset, inputMime);
+ if (!icon.isEmpty()) {
+ data.genericIconName = icon;
}
}
////
-QMimeXMLProvider::QMimeXMLProvider(QMimeDatabasePrivate *db)
- : QMimeProviderBase(db), m_loaded(false)
+QMimeXMLProvider::QMimeXMLProvider(QMimeDatabasePrivate *db, const QString &directory)
+ : QMimeProviderBase(db, directory)
{
initResources();
+ ensureLoaded();
}
QMimeXMLProvider::~QMimeXMLProvider()
@@ -719,81 +609,63 @@ QMimeXMLProvider::~QMimeXMLProvider()
bool QMimeXMLProvider::isValid()
{
+ // If you change this method, adjust the logic in QMimeDatabasePrivate::loadProviders,
+ // which assumes isValid==false is only possible in QMimeBinaryProvider.
return true;
}
QMimeType QMimeXMLProvider::mimeTypeForName(const QString &name)
{
- ensureLoaded();
-
return m_nameMimeTypeMap.value(name);
}
-QMimeGlobMatchResult QMimeXMLProvider::findByFileName(const QString &fileName)
+void QMimeXMLProvider::addFileNameMatches(const QString &fileName, QMimeGlobMatchResult &result)
{
- ensureLoaded();
-
- return m_mimeTypeGlobs.matchingGlobs(fileName);
+ m_mimeTypeGlobs.matchingGlobs(fileName, result);
}
-QMimeType QMimeXMLProvider::findByMagic(const QByteArray &data, int *accuracyPtr)
+void QMimeXMLProvider::findByMagic(const QByteArray &data, int *accuracyPtr, QMimeType &candidate)
{
- ensureLoaded();
-
- QString candidate;
-
+ QString candidateName;
+ bool foundOne = false;
for (const QMimeMagicRuleMatcher &matcher : qAsConst(m_magicMatchers)) {
if (matcher.matches(data)) {
const int priority = matcher.priority();
if (priority > *accuracyPtr) {
*accuracyPtr = priority;
- candidate = matcher.mimetype();
+ candidateName = matcher.mimetype();
+ foundOne = true;
}
}
}
- return mimeTypeForName(candidate);
+ if (foundOne)
+ candidate = mimeTypeForName(candidateName);
}
void QMimeXMLProvider::ensureLoaded()
{
- if (!m_loaded || shouldCheck()) {
- bool fdoXmlFound = false;
- QStringList allFiles;
-
- const QStringList packageDirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QLatin1String("mime/packages"), QStandardPaths::LocateDirectory);
- //qDebug() << "packageDirs=" << packageDirs;
- for (const QString &packageDir : packageDirs) {
- QDir dir(packageDir);
- const QStringList files = dir.entryList(QDir::Files | QDir::NoDotAndDotDot);
- //qDebug() << static_cast<const void *>(this) << packageDir << files;
- if (!fdoXmlFound)
- fdoXmlFound = files.contains(QLatin1String("freedesktop.org.xml"));
- QStringList::const_iterator endIt(files.constEnd());
- for (QStringList::const_iterator it(files.constBegin()); it != endIt; ++it) {
- allFiles.append(packageDir + QLatin1Char('/') + *it);
- }
- }
-
- if (!fdoXmlFound) {
- // We could instead install the file as part of installing Qt?
- allFiles.prepend(QLatin1String(":/qt-project.org/qmime/freedesktop.org.xml"));
- }
+ QStringList allFiles;
+ const QString packageDir = m_directory + QStringLiteral("/packages");
+ QDir dir(packageDir);
+ const QStringList files = dir.entryList(QDir::Files | QDir::NoDotAndDotDot);
+ allFiles.reserve(files.count());
+ for (const QString &xmlFile : files)
+ allFiles.append(packageDir + QLatin1Char('/') + xmlFile);
- if (m_allFiles == allFiles)
- return;
- m_allFiles = allFiles;
+ if (m_allFiles == allFiles)
+ return;
+ m_allFiles = allFiles;
- m_nameMimeTypeMap.clear();
- m_aliases.clear();
- m_parents.clear();
- m_mimeTypeGlobs.clear();
- m_magicMatchers.clear();
+ m_nameMimeTypeMap.clear();
+ m_aliases.clear();
+ m_parents.clear();
+ m_mimeTypeGlobs.clear();
+ m_magicMatchers.clear();
- //qDebug() << "Loading" << m_allFiles;
+ //qDebug() << "Loading" << m_allFiles;
- for (const QString &file : qAsConst(allFiles))
- load(file);
- }
+ for (const QString &file : qAsConst(allFiles))
+ load(file);
}
void QMimeXMLProvider::load(const QString &fileName)
@@ -805,8 +677,6 @@ void QMimeXMLProvider::load(const QString &fileName)
bool QMimeXMLProvider::load(const QString &fileName, QString *errorMessage)
{
- m_loaded = true;
-
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
if (errorMessage)
@@ -828,19 +698,16 @@ void QMimeXMLProvider::addGlobPattern(const QMimeGlobPattern &glob)
void QMimeXMLProvider::addMimeType(const QMimeType &mt)
{
+ Q_ASSERT(!mt.d.data()->fromCache);
m_nameMimeTypeMap.insert(mt.name(), mt);
}
-QStringList QMimeXMLProvider::parents(const QString &mime)
+void QMimeXMLProvider::addParents(const QString &mime, QStringList &result)
{
- ensureLoaded();
- QStringList result = m_parents.value(mime);
- if (result.isEmpty()) {
- const QString parent = fallbackParent(mime);
- if (!parent.isEmpty())
+ for (const QString &parent : m_parents.value(mime)) {
+ if (!result.contains(parent))
result.append(parent);
}
- return result;
}
void QMimeXMLProvider::addParent(const QString &child, const QString &parent)
@@ -848,16 +715,20 @@ void QMimeXMLProvider::addParent(const QString &child, const QString &parent)
m_parents[child].append(parent);
}
-QStringList QMimeXMLProvider::listAliases(const QString &name)
+void QMimeXMLProvider::addAliases(const QString &name, QStringList &result)
{
- ensureLoaded();
// Iterate through the whole hash. This method is rarely used.
- return m_aliases.keys(name);
+ for (auto it = m_aliases.constBegin(), end = m_aliases.constEnd() ; it != end ; ++it) {
+ if (it.value() == name) {
+ if (!result.contains(it.key()))
+ result.append(it.key());
+ }
+ }
+
}
QString QMimeXMLProvider::resolveAlias(const QString &name)
{
- ensureLoaded();
return m_aliases.value(name, name);
}
@@ -866,10 +737,18 @@ void QMimeXMLProvider::addAlias(const QString &alias, const QString &name)
m_aliases.insert(alias, name);
}
-QList<QMimeType> QMimeXMLProvider::allMimeTypes()
+void QMimeXMLProvider::addAllMimeTypes(QList<QMimeType> &result)
{
- ensureLoaded();
- return m_nameMimeTypeMap.values();
+ if (result.isEmpty()) { // fast path
+ result = m_nameMimeTypeMap.values();
+ } 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());
+ }
+ }
}
void QMimeXMLProvider::addMagicMatcher(const QMimeMagicRuleMatcher &matcher)
diff --git a/src/corelib/mimetypes/qmimeprovider_p.h b/src/corelib/mimetypes/qmimeprovider_p.h
index f410e62267..b2be545cf8 100644
--- a/src/corelib/mimetypes/qmimeprovider_p.h
+++ b/src/corelib/mimetypes/qmimeprovider_p.h
@@ -59,7 +59,6 @@
#include "qmimeglobpattern_p.h"
#include <QtCore/qdatetime.h>
#include <QtCore/qset.h>
-#include <QtCore/qelapsedtimer.h>
QT_BEGIN_NAMESPACE
@@ -68,25 +67,25 @@ class QMimeMagicRuleMatcher;
class QMimeProviderBase
{
public:
- QMimeProviderBase(QMimeDatabasePrivate *db);
+ QMimeProviderBase(QMimeDatabasePrivate *db, const QString &directory);
virtual ~QMimeProviderBase() {}
virtual bool isValid() = 0;
virtual QMimeType mimeTypeForName(const QString &name) = 0;
- virtual QMimeGlobMatchResult findByFileName(const QString &fileName) = 0;
- virtual QStringList parents(const QString &mime) = 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 QStringList listAliases(const QString &name) = 0;
- virtual QMimeType findByMagic(const QByteArray &data, int *accuracyPtr) = 0;
- virtual QList<QMimeType> allMimeTypes() = 0;
- virtual void loadMimeTypePrivate(QMimeTypePrivate &) {}
+ virtual void addAliases(const QString &name, QStringList &result) = 0;
+ virtual void findByMagic(const QByteArray &data, int *accuracyPtr, QMimeType &candidate) = 0;
+ virtual void addAllMimeTypes(QList<QMimeType> &result) = 0;
virtual void loadIcon(QMimeTypePrivate &) {}
virtual void loadGenericIcon(QMimeTypePrivate &) {}
+ virtual void ensureLoaded() {}
+
+ QString directory() const { return m_directory; }
QMimeDatabasePrivate *m_db;
-protected:
- bool shouldCheck();
- QElapsedTimer m_lastCheck;
+ QString m_directory;
};
/*
@@ -95,20 +94,21 @@ protected:
class QMimeBinaryProvider : public QMimeProviderBase
{
public:
- QMimeBinaryProvider(QMimeDatabasePrivate *db);
+ QMimeBinaryProvider(QMimeDatabasePrivate *db, const QString &directory);
virtual ~QMimeBinaryProvider();
- virtual bool isValid() Q_DECL_OVERRIDE;
- virtual QMimeType mimeTypeForName(const QString &name) Q_DECL_OVERRIDE;
- virtual QMimeGlobMatchResult findByFileName(const QString &fileName) Q_DECL_OVERRIDE;
- virtual QStringList parents(const QString &mime) Q_DECL_OVERRIDE;
- virtual QString resolveAlias(const QString &name) Q_DECL_OVERRIDE;
- virtual QStringList listAliases(const QString &name) Q_DECL_OVERRIDE;
- virtual QMimeType findByMagic(const QByteArray &data, int *accuracyPtr) Q_DECL_OVERRIDE;
- virtual QList<QMimeType> allMimeTypes() Q_DECL_OVERRIDE;
- virtual void loadMimeTypePrivate(QMimeTypePrivate &) Q_DECL_OVERRIDE;
- virtual void loadIcon(QMimeTypePrivate &) Q_DECL_OVERRIDE;
- virtual void loadGenericIcon(QMimeTypePrivate &) Q_DECL_OVERRIDE;
+ virtual bool isValid() override;
+ virtual QMimeType mimeTypeForName(const QString &name) override;
+ void addFileNameMatches(const QString &fileName, QMimeGlobMatchResult &result) override;
+ void addParents(const QString &mime, QStringList &result) override;
+ virtual 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 addAllMimeTypes(QList<QMimeType> &result) override;
+ static void loadMimeTypePrivate(QMimeTypePrivate &);
+ virtual void loadIcon(QMimeTypePrivate &) override;
+ virtual void loadGenericIcon(QMimeTypePrivate &) override;
+ void ensureLoaded() override;
private:
struct CacheFile;
@@ -116,17 +116,11 @@ private:
void matchGlobList(QMimeGlobMatchResult &result, CacheFile *cacheFile, int offset, const QString &fileName);
bool matchSuffixTree(QMimeGlobMatchResult &result, CacheFile *cacheFile, int numEntries, int firstOffset, const QString &fileName, int charPos, bool caseSensitiveCheck);
bool matchMagicRule(CacheFile *cacheFile, int numMatchlets, int firstOffset, const QByteArray &data);
- QString iconForMime(CacheFile *cacheFile, int posListOffset, const QByteArray &inputMime);
+ QLatin1String iconForMime(CacheFile *cacheFile, int posListOffset, const QByteArray &inputMime);
void loadMimeTypeList();
- void checkCache();
-
- class CacheFileList : public QList<CacheFile *>
- {
- public:
- CacheFile *findCacheFile(const QString &fileName) const;
- bool checkCacheChanged();
- };
- CacheFileList m_cacheFiles;
+ bool checkCacheChanged();
+
+ CacheFile *m_cacheFile = nullptr;
QStringList m_cacheFileNames;
QSet<QString> m_mimetypeNames;
bool m_mimetypeListLoaded;
@@ -138,17 +132,18 @@ private:
class QMimeXMLProvider : public QMimeProviderBase
{
public:
- QMimeXMLProvider(QMimeDatabasePrivate *db);
+ QMimeXMLProvider(QMimeDatabasePrivate *db, const QString &directory);
~QMimeXMLProvider();
- virtual bool isValid() Q_DECL_OVERRIDE;
- virtual QMimeType mimeTypeForName(const QString &name) Q_DECL_OVERRIDE;
- virtual QMimeGlobMatchResult findByFileName(const QString &fileName) Q_DECL_OVERRIDE;
- virtual QStringList parents(const QString &mime) Q_DECL_OVERRIDE;
- virtual QString resolveAlias(const QString &name) Q_DECL_OVERRIDE;
- virtual QStringList listAliases(const QString &name) Q_DECL_OVERRIDE;
- virtual QMimeType findByMagic(const QByteArray &data, int *accuracyPtr) Q_DECL_OVERRIDE;
- virtual QList<QMimeType> allMimeTypes() Q_DECL_OVERRIDE;
+ virtual bool isValid() override;
+ virtual QMimeType mimeTypeForName(const QString &name) override;
+ void addFileNameMatches(const QString &fileName, QMimeGlobMatchResult &result) override;
+ void addParents(const QString &mime, QStringList &result) override;
+ virtual 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 addAllMimeTypes(QList<QMimeType> &result) override;
+ void ensureLoaded() override;
bool load(const QString &fileName, QString *errorMessage);
@@ -160,11 +155,8 @@ public:
void addMagicMatcher(const QMimeMagicRuleMatcher &matcher);
private:
- void ensureLoaded();
void load(const QString &fileName);
- bool m_loaded;
-
typedef QHash<QString, QMimeType> NameMimeTypeMap;
NameMimeTypeMap m_nameMimeTypeMap;
diff --git a/src/corelib/mimetypes/qmimetype.cpp b/src/corelib/mimetypes/qmimetype.cpp
index 98a0e8eb1b..d7590ecf1f 100644
--- a/src/corelib/mimetypes/qmimetype.cpp
+++ b/src/corelib/mimetypes/qmimetype.cpp
@@ -57,7 +57,7 @@
QT_BEGIN_NAMESPACE
QMimeTypePrivate::QMimeTypePrivate()
- : loaded(false)
+ : loaded(false), fromCache(false)
{}
QMimeTypePrivate::QMimeTypePrivate(const QMimeType &other)
@@ -76,7 +76,6 @@ void QMimeTypePrivate::clear()
genericIconName.clear();
iconName.clear();
globPatterns.clear();
- loaded = false;
}
void QMimeTypePrivate::addGlobPattern(const QString &pattern)
@@ -206,10 +205,14 @@ uint qHash(const QMimeType &key, uint seed) Q_DECL_NOTHROW
*/
/*!
- \fn bool QMimeType::isValid() const;
- Returns \c true if the QMimeType object contains valid data, otherwise returns \c false.
+ \property QMimeType::valid
+ \brief \c true if the QMimeType object contains valid data, \c false otherwise
+
A valid MIME type has a non-empty name().
The invalid MIME type is the default-constructed QMimeType.
+
+ While this property was introduced in 5.10, the
+ corresponding accessor method has always been there.
*/
bool QMimeType::isValid() const
{
@@ -217,9 +220,12 @@ bool QMimeType::isValid() const
}
/*!
- \fn bool QMimeType::isDefault() const;
- Returns \c true if this MIME type is the default MIME type which
+ \property QMimeType::isDefault
+ \brief \c true if this MIME type is the default MIME type which
applies to all files: application/octet-stream.
+
+ While this property was introduced in 5.10, the
+ corresponding accessor method has always been there.
*/
bool QMimeType::isDefault() const
{
@@ -227,8 +233,11 @@ bool QMimeType::isDefault() const
}
/*!
- \fn QString QMimeType::name() const;
- Returns the name of the MIME type.
+ \property QMimeType::name
+ \brief the name of the MIME type
+
+ While this property was introduced in 5.10, the
+ corresponding accessor method has always been there.
*/
QString QMimeType::name() const
{
@@ -236,13 +245,17 @@ QString QMimeType::name() const
}
/*!
- Returns the description of the MIME type to be displayed on user interfaces.
+ \property QMimeType::comment
+ \brief the description of the MIME type to be displayed on user interfaces
The default language (QLocale().name()) is used to select the appropriate translation.
+
+ While this property was introduced in 5.10, the
+ corresponding accessor method has always been there.
*/
QString QMimeType::comment() const
{
- QMimeDatabasePrivate::instance()->provider()->loadMimeTypePrivate(*d);
+ QMimeDatabasePrivate::instance()->loadMimeTypePrivate(*d);
QStringList languageList;
languageList << QLocale().name();
@@ -267,8 +280,8 @@ QString QMimeType::comment() const
}
/*!
- \fn QString QMimeType::genericIconName() const;
- Returns the file name of a generic icon that represents the MIME type.
+ \property QMimeType::genericIconName
+ \brief the file name of a generic icon that represents the MIME type
This should be used if the icon returned by iconName() cannot be found on
the system. It is used for categories of similar types (like spreadsheets
@@ -276,10 +289,13 @@ QString QMimeType::comment() const
The freedesktop.org Icon Naming Specification lists a set of such icon names.
The icon name can be given to QIcon::fromTheme() in order to load the icon.
+
+ While this property was introduced in 5.10, the
+ corresponding accessor method has always been there.
*/
QString QMimeType::genericIconName() const
{
- QMimeDatabasePrivate::instance()->provider()->loadGenericIcon(*d);
+ QMimeDatabasePrivate::instance()->loadGenericIcon(*d);
if (d->genericIconName.isEmpty()) {
// From the spec:
// If the generic icon name is empty (not specified by the mimetype definition)
@@ -297,14 +313,17 @@ QString QMimeType::genericIconName() const
}
/*!
- \fn QString QMimeType::iconName() const;
- Returns the file name of an icon image that represents the MIME type.
+ \property QMimeType::iconName
+ \brief the file name of an icon image that represents the MIME type
The icon name can be given to QIcon::fromTheme() in order to load the icon.
+
+ While this property was introduced in 5.10, the
+ corresponding accessor method has always been there.
*/
QString QMimeType::iconName() const
{
- QMimeDatabasePrivate::instance()->provider()->loadIcon(*d);
+ QMimeDatabasePrivate::instance()->loadIcon(*d);
if (d->iconName.isEmpty()) {
// Make default icon name from the mimetype name
d->iconName = name();
@@ -316,16 +335,22 @@ QString QMimeType::iconName() const
}
/*!
- \fn QStringList QMimeType::globPatterns() const;
- Returns the list of glob matching patterns.
+ \property QMimeType::globPatterns
+ \brief the list of glob matching patterns
+
+ While this property was introduced in 5.10, the
+ corresponding accessor method has always been there.
*/
QStringList QMimeType::globPatterns() const
{
- QMimeDatabasePrivate::instance()->provider()->loadMimeTypePrivate(*d);
+ QMimeDatabasePrivate::instance()->loadMimeTypePrivate(*d);
return d->globPatterns;
}
/*!
+ \property QMimeType::parentMimeTypes
+ \brief the names of parent MIME types
+
A type is a subclass of another type if any instance of the first type is
also an instance of the second. For example, all image/svg+xml files are also
text/xml, text/plain and application/octet-stream files. Subclassing is about
@@ -336,15 +361,18 @@ QStringList QMimeType::globPatterns() const
A mimetype can have multiple parents. For instance application/x-perl
has two parents: application/x-executable and text/plain. This makes
it possible to both execute perl scripts, and to open them in text editors.
+
+ While this property was introduced in 5.10, the
+ corresponding accessor method has always been there.
*/
QStringList QMimeType::parentMimeTypes() const
{
- return QMimeDatabasePrivate::instance()->provider()->parents(d->name);
+ return QMimeDatabasePrivate::instance()->mimeParents(d->name);
}
static void collectParentMimeTypes(const QString &mime, QStringList &allParents)
{
- const QStringList parents = QMimeDatabasePrivate::instance()->provider()->parents(mime);
+ const QStringList parents = QMimeDatabasePrivate::instance()->mimeParents(mime);
for (const QString &parent : parents) {
// I would use QSet, but since order matters I better not
if (!allParents.contains(parent))
@@ -357,6 +385,9 @@ static void collectParentMimeTypes(const QString &mime, QStringList &allParents)
}
/*!
+ \property QMimeType::allAncestors
+ \brief the names of direct and indirect parent MIME types
+
Return all the parent mimetypes of this mimetype, direct and indirect.
This includes the parent(s) of its parent(s), etc.
@@ -365,6 +396,9 @@ static void collectParentMimeTypes(const QString &mime, QStringList &allParents)
Note that application/octet-stream is the ultimate parent for all types
of files (but not directories).
+
+ While this property was introduced in 5.10, the
+ corresponding accessor method has always been there.
*/
QStringList QMimeType::allAncestors() const
{
@@ -374,7 +408,8 @@ QStringList QMimeType::allAncestors() const
}
/*!
- Return the list of aliases of this mimetype.
+ \property QMimeType::aliases
+ \brief the list of aliases of this mimetype
For instance, for text/csv, the returned list would be:
text/x-csv, text/x-comma-separated-values.
@@ -383,19 +418,27 @@ QStringList QMimeType::allAncestors() const
never to aliases directly.
The order of the aliases in the list is undefined.
+
+ While this property was introduced in 5.10, the
+ corresponding accessor method has always been there.
*/
QStringList QMimeType::aliases() const
{
- return QMimeDatabasePrivate::instance()->provider()->listAliases(d->name);
+ return QMimeDatabasePrivate::instance()->listAliases(d->name);
}
/*!
- Returns the known suffixes for the MIME type.
+ \property QMimeType::suffixes
+ \brief the known suffixes for the MIME type
+
No leading dot is included, so for instance this would return "jpg", "jpeg" for image/jpeg.
+
+ While this property was introduced in 5.10, the
+ corresponding accessor method has always been there.
*/
QStringList QMimeType::suffixes() const
{
- QMimeDatabasePrivate::instance()->provider()->loadMimeTypePrivate(*d);
+ QMimeDatabasePrivate::instance()->loadMimeTypePrivate(*d);
QStringList result;
for (const QString &pattern : qAsConst(d->globPatterns)) {
@@ -412,23 +455,33 @@ QStringList QMimeType::suffixes() const
}
/*!
- Returns the preferred suffix for the MIME type.
+ \property QMimeType::preferredSuffix
+ \brief the preferred suffix for the MIME type
+
No leading dot is included, so for instance this would return "pdf" for application/pdf.
The return value can be empty, for mime types which do not have any suffixes associated.
+
+ While this property was introduced in 5.10, the
+ corresponding accessor method has always been there.
*/
QString QMimeType::preferredSuffix() const
{
+ if (isDefault()) // workaround for unwanted *.bin suffix for octet-stream, https://bugs.freedesktop.org/show_bug.cgi?id=101667, fixed upstream in 1.10
+ return QString();
const QStringList suffixList = suffixes();
return suffixList.isEmpty() ? QString() : suffixList.at(0);
}
/*!
- \fn QString QMimeType::filterString() const;
- Returns a filter string usable for a file dialog.
+ \property QMimeType::filterString
+ \brief a filter string usable for a file dialog
+
+ While this property was introduced in 5.10, the
+ corresponding accessor method has always been there.
*/
QString QMimeType::filterString() const
{
- QMimeDatabasePrivate::instance()->provider()->loadMimeTypePrivate(*d);
+ QMimeDatabasePrivate::instance()->loadMimeTypePrivate(*d);
QString filter;
if (!d->globPatterns.empty()) {
@@ -449,12 +502,14 @@ QString QMimeType::filterString() const
Returns \c true if this mimetype is \a mimeTypeName,
or inherits \a mimeTypeName (see parentMimeTypes()),
or \a mimeTypeName is an alias for this mimetype.
+
+ This method has been made invokable from QML since 5.10.
*/
bool QMimeType::inherits(const QString &mimeTypeName) const
{
if (d->name == mimeTypeName)
return true;
- return QMimeDatabasePrivate::instance()->inherits(d->name, mimeTypeName);
+ return QMimeDatabasePrivate::instance()->mimeInherits(d->name, mimeTypeName);
}
#ifndef QT_NO_DEBUG_STREAM
diff --git a/src/corelib/mimetypes/qmimetype.h b/src/corelib/mimetypes/qmimetype.h
index e9ff9ace84..def4034f8a 100644
--- a/src/corelib/mimetypes/qmimetype.h
+++ b/src/corelib/mimetypes/qmimetype.h
@@ -45,6 +45,7 @@
#ifndef QT_NO_MIMETYPE
+#include <QtCore/qobjectdefs.h>
#include <QtCore/qshareddata.h>
#include <QtCore/qstring.h>
@@ -58,6 +59,21 @@ Q_CORE_EXPORT uint qHash(const QMimeType &key, uint seed = 0) Q_DECL_NOTHROW;
class Q_CORE_EXPORT QMimeType
{
+ Q_GADGET
+ Q_PROPERTY(bool valid READ isValid CONSTANT)
+ Q_PROPERTY(bool isDefault READ isDefault CONSTANT)
+ Q_PROPERTY(QString name READ name CONSTANT)
+ Q_PROPERTY(QString comment READ comment CONSTANT)
+ Q_PROPERTY(QString genericIconName READ genericIconName CONSTANT)
+ Q_PROPERTY(QString iconName READ iconName CONSTANT)
+ Q_PROPERTY(QStringList globPatterns READ globPatterns CONSTANT)
+ Q_PROPERTY(QStringList parentMimeTypes READ parentMimeTypes CONSTANT)
+ Q_PROPERTY(QStringList allAncestors READ allAncestors CONSTANT)
+ Q_PROPERTY(QStringList aliases READ aliases CONSTANT)
+ Q_PROPERTY(QStringList suffixes READ suffixes CONSTANT)
+ Q_PROPERTY(QString preferredSuffix READ preferredSuffix CONSTANT)
+ Q_PROPERTY(QString filterString READ filterString CONSTANT)
+
public:
QMimeType();
QMimeType(const QMimeType &other);
@@ -94,7 +110,7 @@ public:
QStringList suffixes() const;
QString preferredSuffix() const;
- bool inherits(const QString &mimeTypeName) const;
+ Q_INVOKABLE bool inherits(const QString &mimeTypeName) const;
QString filterString() const;
diff --git a/src/corelib/mimetypes/qmimetype_p.h b/src/corelib/mimetypes/qmimetype_p.h
index b0bfad2f65..aa38a1adf5 100644
--- a/src/corelib/mimetypes/qmimetype_p.h
+++ b/src/corelib/mimetypes/qmimetype_p.h
@@ -74,6 +74,7 @@ public:
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
QString name;
LocaleHash localeComments;
QString genericIconName;
@@ -94,6 +95,7 @@ QT_END_NAMESPACE
{ \
QMimeTypePrivate qMimeTypeData; \
qMimeTypeData.name = name; \
+ qMimeTypeData.loaded = true; \
qMimeTypeData.genericIconName = genericIconName; \
qMimeTypeData.iconName = iconName; \
qMimeTypeData.globPatterns = globPatterns; \
@@ -112,6 +114,7 @@ QT_END_NAMESPACE
) \
{ \
QMimeTypePrivate qMimeTypeData; \
+ qMimeTypeData.loaded = true; \
qMimeTypeData.name = std::move(name); \
qMimeTypeData.genericIconName = std::move(genericIconName); \
qMimeTypeData.iconName = std::move(iconName); \
diff --git a/src/corelib/mimetypes/qmimetypeparser.cpp b/src/corelib/mimetypes/qmimetypeparser.cpp
index 20b4461b03..0a55560ab0 100644
--- a/src/corelib/mimetypes/qmimetypeparser.cpp
+++ b/src/corelib/mimetypes/qmimetypeparser.cpp
@@ -49,7 +49,6 @@
#include <QtCore/QCoreApplication>
#include <QtCore/QDebug>
#include <QtCore/QDir>
-#include <QtCore/QPair>
#include <QtCore/QXmlStreamReader>
#include <QtCore/QXmlStreamWriter>
#include <QtCore/QStack>
@@ -202,6 +201,7 @@ bool QMimeTypeParserBase::parse(QIODevice *dev, const QString &fileName, QString
return false;
#else
QMimeTypePrivate data;
+ data.loaded = true;
int priority = 50;
QStack<QMimeMagicRule *> currentRules; // stack for the nesting of rules
QList<QMimeMagicRule> rules; // toplevel rules