forked from qt-creator/qt-creator
MimeDatabase: Prevent funny mixing of different mime type definitions
If multiple definitions for the same mime type are found, the mime XML parser/provider would on the one hand replace the first MimeType instance by the later one, but on the other hand keep all previously parsed glob and magic matchers from the first definition. The patch - makes the XML parser ignore definitions of mime types that are already defined - parses custom types first, so custom types can override types from freedesktop.org.xml This fixes opening Cmake projects (CMakeLists.txt) in Qt Creator, because freedesktop.org.xml defines these files to be x-cmake, but we need them to be x-cmake-project. Change-Id: Ia5598c2d0201f608aed6ae8c3268f0512d822f51 Reviewed-by: Daniel Teske <daniel.teske@theqtcompany.com>
This commit is contained in:
@@ -833,7 +833,8 @@ void MimeXMLProvider::ensureLoaded()
|
||||
{
|
||||
if (!m_loaded /*|| shouldCheck()*/) {
|
||||
// bool fdoXmlFound = false;
|
||||
QStringList allFiles;
|
||||
// add custom mime types first, which overrides any default from freedesktop.org.xml
|
||||
QStringList allFiles = m_additionalFiles;
|
||||
|
||||
// const QStringList packageDirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QLatin1String("mime/packages"), QStandardPaths::LocateDirectory);
|
||||
// //qDebug() << "packageDirs=" << packageDirs;
|
||||
@@ -851,11 +852,9 @@ void MimeXMLProvider::ensureLoaded()
|
||||
|
||||
// if (!fdoXmlFound) {
|
||||
// // We could instead install the file as part of installing Qt?
|
||||
allFiles.prepend(QLatin1String(":/qt-project.org/qmime/freedesktop.org.xml"));
|
||||
allFiles.append(QLatin1String(":/qt-project.org/qmime/freedesktop.org.xml"));
|
||||
// }
|
||||
|
||||
allFiles.append(m_additionalFiles);
|
||||
|
||||
if (m_allFiles == allFiles)
|
||||
return;
|
||||
m_allFiles = allFiles;
|
||||
|
@@ -210,9 +210,12 @@ bool MimeTypeParserBase::parse(QIODevice *dev, const QString &fileName, QString
|
||||
QXmlStreamReader reader(dev);
|
||||
ParseState ps = ParseBeginning;
|
||||
QXmlStreamAttributes atts;
|
||||
bool ignoreCurrentMimeType = false;
|
||||
while (!reader.atEnd()) {
|
||||
switch (reader.readNext()) {
|
||||
case QXmlStreamReader::StartElement:
|
||||
if (ignoreCurrentMimeType)
|
||||
continue;
|
||||
ps = nextState(ps, reader.name());
|
||||
atts = reader.attributes();
|
||||
switch (ps) {
|
||||
@@ -221,7 +224,10 @@ bool MimeTypeParserBase::parse(QIODevice *dev, const QString &fileName, QString
|
||||
if (name.isEmpty()) {
|
||||
reader.raiseError(QString::fromLatin1("Missing '%1'-attribute").arg(QString::fromLatin1(mimeTypeAttributeC)));
|
||||
} else {
|
||||
data.name = name;
|
||||
if (mimeTypeExists(name))
|
||||
ignoreCurrentMimeType = true;
|
||||
else
|
||||
data.name = name;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -307,20 +313,25 @@ bool MimeTypeParserBase::parse(QIODevice *dev, const QString &fileName, QString
|
||||
{
|
||||
const QStringRef elementName = reader.name();
|
||||
if (elementName == QLatin1String(mimeTypeTagC)) {
|
||||
if (!process(MimeType(data), errorMessage))
|
||||
return false;
|
||||
if (!ignoreCurrentMimeType) {
|
||||
if (!process(MimeType(data), errorMessage))
|
||||
return false;
|
||||
}
|
||||
ignoreCurrentMimeType = false;
|
||||
data.clear();
|
||||
} else if (elementName == QLatin1String(matchTagC)) {
|
||||
// Closing a <match> tag, pop stack
|
||||
currentRules.pop();
|
||||
//qDebug() << " MATCH closed. Stack size is now" << currentRules.size();
|
||||
} else if (elementName == QLatin1String(magicTagC)) {
|
||||
//qDebug() << "MAGIC ended, we got" << rules.count() << "rules, with prio" << priority;
|
||||
// Finished a <magic> sequence
|
||||
MimeMagicRuleMatcher ruleMatcher(data.name, priority);
|
||||
ruleMatcher.addRules(rules);
|
||||
processMagicMatcher(ruleMatcher);
|
||||
rules.clear();
|
||||
} else if (!ignoreCurrentMimeType) {
|
||||
if (elementName == QLatin1String(matchTagC)) {
|
||||
// Closing a <match> tag, pop stack
|
||||
currentRules.pop();
|
||||
//qDebug() << " MATCH closed. Stack size is now" << currentRules.size();
|
||||
} else if (elementName == QLatin1String(magicTagC)) {
|
||||
//qDebug() << "MAGIC ended, we got" << rules.count() << "rules, with prio" << priority;
|
||||
// Finished a <magic> sequence
|
||||
MimeMagicRuleMatcher ruleMatcher(data.name, priority);
|
||||
ruleMatcher.addRules(rules);
|
||||
processMagicMatcher(ruleMatcher);
|
||||
rules.clear();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@@ -67,6 +67,7 @@ public:
|
||||
bool parse(QIODevice *dev, const QString &fileName, QString *errorMessage);
|
||||
|
||||
protected:
|
||||
virtual bool mimeTypeExists(const QString &mimeTypeName) = 0;
|
||||
virtual bool process(const MimeType &t, QString *errorMessage) = 0;
|
||||
virtual bool process(const MimeGlobPattern &t, QString *errorMessage) = 0;
|
||||
virtual void processParent(const QString &child, const QString &parent) = 0;
|
||||
@@ -100,6 +101,9 @@ public:
|
||||
explicit MimeTypeParser(MimeXMLProvider &provider) : m_provider(provider) {}
|
||||
|
||||
protected:
|
||||
inline bool mimeTypeExists(const QString &mimeTypeName)
|
||||
{ return m_provider.mimeTypeForName(mimeTypeName).isValid(); }
|
||||
|
||||
inline bool process(const MimeType &t, QString *)
|
||||
{ m_provider.addMimeType(t); return true; }
|
||||
|
||||
|
Reference in New Issue
Block a user