Commit 5a3a940a authored by Eike Ziller's avatar Eike Ziller
Browse files

Use new mime database

Change-Id: I4305872b6b11ef3e8a364280ffa5209a5a793600
Reviewed-by: default avatarEike Ziller <>
parent 365c1ddb
......@@ -54,7 +54,6 @@
#include <coreplugin/imode.h>
#include <coreplugin/infobar.h>
#include <coreplugin/iversioncontrol.h>
#include <coreplugin/mimedatabase.h>
#include <coreplugin/modemanager.h>
#include <coreplugin/outputpane.h>
#include <coreplugin/outputpanemanager.h>
......@@ -68,6 +67,7 @@
#include <utils/fileutils.h>
#include <utils/hostosinfo.h>
#include <utils/macroexpander.h>
#include <utils/mimetypes/mimedatabase.h>
#include <utils/qtcassert.h>
#include <QClipboard>
......@@ -774,10 +774,11 @@ void EditorManagerPrivate::showPopupOrSelectDocument()
Id EditorManagerPrivate::getOpenWithEditorId(const QString &fileName, bool *isExternalEditor)
// Collect editors that can open the file
MimeType mt = MimeDatabase::findByFile(fileName);
Utils::MimeDatabase mdb;
Utils::MimeType mt = mdb.mimeTypeForFile(fileName);
//Unable to determine mime type of fileName. Falling back to text/plain",
if (!mt)
mt = MimeDatabase::findByType(QLatin1String("text/plain"));
if (!mt.isValid())
mt = mdb.mimeTypeForName(QLatin1String("text/plain"));
QList<Id> allEditorIds;
QStringList allEditorDisplayNames;
QList<Id> externalEditorIds;
......@@ -889,16 +890,17 @@ IEditor *EditorManagerPrivate::createEditor(Id editorId, const QString &fileName
if (!editorId.isValid()) {
const QFileInfo fileInfo(fileName);
// Find by mime type
MimeType mimeType = MimeDatabase::findByFile(fileInfo);
if (!mimeType) {
Utils::MimeDatabase mdb;
Utils::MimeType mimeType = mdb.mimeTypeForFile(fileInfo);
if (!mimeType.isValid()) {
qWarning("%s unable to determine mime type of %s/%s. Falling back to text/plain",
Q_FUNC_INFO, fileName.toUtf8().constData(),;
mimeType = MimeDatabase::findByType(QLatin1String("text/plain"));
mimeType = mdb.mimeTypeForName(QLatin1String("text/plain"));
// open text files > 48 MB in binary editor
if (fileInfo.size() > EditorManager::maxTextFileSize()
&& mimeType.type().startsWith(QLatin1String("text"))) {
mimeType = MimeDatabase::findByType(QLatin1String("application/octet-stream"));
&&"text"))) {
mimeType = mdb.mimeTypeForName(QLatin1String("application/octet-stream"));
factories = EditorManager::editorFactories(mimeType, true);
} else {
......@@ -1692,11 +1694,12 @@ bool EditorManagerPrivate::saveDocumentAs(IDocument *document)
if (!document)
return false;
const QString filter = MimeDatabase::allFiltersString();
Utils::MimeDatabase mdb;
const QString filter = Utils::MimeDatabase::allFiltersString();
QString selectedFilter =
if (selectedFilter.isEmpty())
selectedFilter = MimeDatabase::findByType(document->mimeType()).filterString();
selectedFilter = mdb.mimeTypeForName(document->mimeType()).filterString();
const QString &absoluteFilePath =
DocumentManager::getSaveAsFileName(document, filter, &selectedFilter);
......@@ -2192,54 +2195,58 @@ IEditor *EditorManager::activateEditorForDocument(IDocument *document, OpenEdito
* or IExternalEditor), find the one best matching the mimetype passed in.
* Recurse over the parent classes of the mimetype to find them. */
template <class EditorFactoryLike>
static void mimeTypeFactoryRecursion(const MimeType &mimeType,
static void mimeTypeFactoryRecursion(const Utils::MimeType &mimeType,
const QList<EditorFactoryLike*> &allFactories,
bool firstMatchOnly,
QList<EditorFactoryLike*> *list)
typedef typename QList<EditorFactoryLike*>::const_iterator EditorFactoryLikeListConstIterator;
// Loop factories to find type
const QString type = mimeType.type();
const EditorFactoryLikeListConstIterator fcend = allFactories.constEnd();
for (EditorFactoryLikeListConstIterator fit = allFactories.constBegin(); fit != fcend; ++fit) {
// Exclude duplicates when recursing over xml or C++ -> C -> text.
EditorFactoryLike *factory = *fit;
if (!list->contains(factory) && factory->mimeTypes().contains(type)) {
if (firstMatchOnly)
if (!list->contains(factory)) {
foreach (const QString &mt, factory->mimeTypes()) {
if (mimeType.matchesName(mt)) {
if (firstMatchOnly)
// Any parent mime type classes? -> recurse
QStringList parentTypes = mimeType.subClassesOf();
if (parentTypes.empty())
QStringList parentNames = mimeType.parentMimeTypes();
if (parentNames.empty())
const QStringList::const_iterator pcend = parentTypes .constEnd();
for (QStringList::const_iterator pit = parentTypes .constBegin(); pit != pcend; ++pit) {
if (const MimeType parent = MimeDatabase::findByType(*pit))
Utils::MimeDatabase mdb;
foreach (const QString &parentName, parentNames) {
const Utils::MimeType parent = mdb.mimeTypeForName(parentName);
if (parent.isValid())
mimeTypeFactoryRecursion(parent, allFactories, firstMatchOnly, list);
EditorManager::editorFactories(const MimeType &mimeType, bool bestMatchOnly)
EditorManager::editorFactories(const Utils::MimeType &mimeType, bool bestMatchOnly)
EditorFactoryList rc;
const EditorFactoryList allFactories = ExtensionSystem::PluginManager::getObjects<IEditorFactory>();
mimeTypeFactoryRecursion(mimeType, allFactories, bestMatchOnly, &rc);
if (debugEditorManager)
qDebug() << Q_FUNC_INFO << mimeType.type() << " returns " << rc;
qDebug() << Q_FUNC_INFO << << " returns " << rc;
return rc;
EditorManager::externalEditors(const MimeType &mimeType, bool bestMatchOnly)
EditorManager::externalEditors(const Utils::MimeType &mimeType, bool bestMatchOnly)
ExternalEditorList rc;
const ExternalEditorList allEditors = ExtensionSystem::PluginManager::getObjects<IExternalEditor>();
mimeTypeFactoryRecursion(mimeType, allEditors, bestMatchOnly, &rc);
if (debugEditorManager)
qDebug() << Q_FUNC_INFO << mimeType.type() << " returns " << rc;
qDebug() << Q_FUNC_INFO << << " returns " << rc;
return rc;
......@@ -2308,7 +2315,7 @@ bool EditorManager::openExternalEditor(const QString &fileName, Id editorId)
QStringList EditorManager::getOpenFileNames()
QString selectedFilter;
const QString &fileFilters = MimeDatabase::allFiltersString(&selectedFilter);
const QString &fileFilters = Utils::MimeDatabase::allFiltersString(&selectedFilter);
return DocumentManager::getOpenFileNames(fileFilters, QString(), &selectedFilter);
......@@ -37,6 +37,7 @@
#include <coreplugin/id.h>
#include <coreplugin/idocument.h> // enumerations
#include <utils/mimetypes/mimetype.h>
#include <QList>
#include <QWidget>
......@@ -53,7 +54,6 @@ class IContext;
class IEditor;
class IEditorFactory;
class IExternalEditor;
class MimeType;
class IDocument;
class IMode;
class IVersionControl;
......@@ -157,8 +157,8 @@ public:
QObject *object = 0, const char *member = 0);
static void hideEditorStatusBar(const QString &id);
static EditorFactoryList editorFactories(const MimeType &mimeType, bool bestMatchOnly = true);
static ExternalEditorList externalEditors(const MimeType &mimeType, bool bestMatchOnly = true);
static EditorFactoryList editorFactories(const Utils::MimeType &mimeType, bool bestMatchOnly = true);
static ExternalEditorList externalEditors(const Utils::MimeType &mimeType, bool bestMatchOnly = true);
static bool isAutoSaveFile(const QString &fileName);
......@@ -29,9 +29,9 @@
#include "fileiconprovider.h"
#include "mimedatabase.h"
#include <utils/hostosinfo.h>
#include <utils/mimetypes/mimedatabase.h>
#include <utils/qtcassert.h>
#include <QApplication>
......@@ -91,7 +91,7 @@ public:
m_cache.insert(suffix, fileIconPixmap);
void registerIconOverlayForMimeType(const QIcon &icon, const MimeType &mimeType)
void registerIconOverlayForMimeType(const QIcon &icon, const Utils::MimeType &mimeType)
foreach (const QString &suffix, mimeType.suffixes())
registerIconOverlayForSuffix(icon, suffix);
......@@ -181,7 +181,9 @@ void registerIconOverlayForSuffix(const char *path, const char *suffix)
void registerIconOverlayForMimeType(const QIcon &icon, const char *mimeType)
instance()->registerIconOverlayForMimeType(icon, MimeDatabase::findByType(QString::fromLatin1(mimeType)));
Utils::MimeDatabase mdb;
......@@ -189,7 +191,9 @@ void registerIconOverlayForMimeType(const QIcon &icon, const char *mimeType)
void registerIconOverlayForMimeType(const char *path, const char *mimeType)
instance()->registerIconOverlayForMimeType(QIcon(QLatin1String(path)), MimeDatabase::findByType(QString::fromLatin1(mimeType)));
Utils::MimeDatabase mdb;
} // namespace FileIconProvider
......@@ -38,8 +38,6 @@
namespace Core {
class MimeType;
namespace FileIconProvider {
// Access to the single instance
......@@ -100,12 +100,6 @@
\fn MimeDatabase *ICore::mimeDatabase()
Uses the MIME database to manage MIME types.
\fn QSettings *ICore::settings(QSettings::Scope scope = QSettings::UserScope)
......@@ -40,7 +40,6 @@
namespace Core {
class MimeType;
class InfoBar;
namespace Internal {
......@@ -42,7 +42,6 @@
#include "idocumentfactory.h"
#include "messagemanager.h"
#include "modemanager.h"
#include "mimedatabase.h"
#include "outputpanemanager.h"
#include "plugindialog.h"
#include "vcsmanager.h"
......@@ -77,6 +76,7 @@
#include <utils/algorithm.h>
#include <utils/historycompleter.h>
#include <utils/hostosinfo.h>
#include <utils/mimetypes/mimedatabase.h>
#include <utils/qtcassert.h>
#include <utils/stylehelper.h>
#include <utils/theme/theme.h>
......@@ -124,7 +124,6 @@ MainWindow::MainWindow() :
m_vcsManager(new VcsManager),
m_mimeDatabase(new MimeDatabase),
m_helpManager(new HelpManager),
m_modeStack(new FancyTabWidget(this)),
......@@ -298,8 +297,6 @@ MainWindow::~MainWindow()
delete m_modeManager;
m_modeManager = 0;
delete m_mimeDatabase;
m_mimeDatabase = 0;
delete m_helpManager;
m_helpManager = 0;
......@@ -311,9 +308,6 @@ bool MainWindow::init(QString *errorMessage)
if (!MimeDatabase::addMimeTypes(QLatin1String(":/core/editormanager/BinFiles.mimetypes.xml"), errorMessage))
return false;
......@@ -751,10 +745,12 @@ void MainWindow::openFile()
static IDocumentFactory *findDocumentFactory(const QList<IDocumentFactory*> &fileFactories,
const QFileInfo &fi)
if (const MimeType mt = MimeDatabase::findByFile(fi)) {
const QString type = mt.type();
Utils::MimeDatabase mdb;
const Utils::MimeType mt = mdb.mimeTypeForFile(fi);
if (mt.isValid()) {
const QString typeName =;
foreach (IDocumentFactory *factory, fileFactories) {
if (factory->mimeTypes().contains(type))
if (factory->mimeTypes().contains(typeName))
return factory;
......@@ -58,7 +58,6 @@ class IDocument;
class IWizardFactory;
class JsExpander;
class MessageManager;
class MimeDatabase;
class ModeManager;
class ProgressManager;
class NavigationWidget;
......@@ -172,7 +171,6 @@ private:
VcsManager *m_vcsManager;
StatusBarManager *m_statusBarManager;
ModeManager *m_modeManager;
MimeDatabase *m_mimeDatabase;
HelpManager *m_helpManager;
FancyTabWidget *m_modeStack;
NavigationWidget *m_navigationWidget;
This diff is collapsed.
** Copyright (C) 2015 The Qt Company Ltd.
** Contact:
** This file is part of Qt Creator.
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms and
** conditions see For further information
** use the contact form at
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: and
** In addition, as a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
#include <coreplugin/core_global.h>
#include <QStringList>
#include <QSharedDataPointer>
#include <QSharedPointer>
#include <QByteArray>
#include <QMutex>
#include <QFileInfo>
#include <QPair>
class QIODevice;
class QDebug;
namespace Core {
class MimeTypeData;
class MimeDatabasePrivate;
namespace Internal {
class BaseMimeTypeParser;
class FileMatchContext;
class MainWindow;
class CORE_EXPORT IMagicMatcher
IMagicMatcher() {}
typedef QSharedPointer<IMagicMatcher> IMagicMatcherSharedPointer;
typedef QList<IMagicMatcherSharedPointer> IMagicMatcherList;
// Check for a match on contents of a file
virtual bool matches(const QByteArray &data) const = 0;
// Return a priority value from 1..100
virtual int priority() const = 0;
virtual ~IMagicMatcher() {}
class CORE_EXPORT MagicRule
MagicRule(int startPos, int endPos);
virtual ~MagicRule();
virtual QString matchType() const = 0;
virtual QString matchValue() const = 0;
virtual bool matches(const QByteArray &data) const = 0;
int startPos() const;
int endPos() const;
static QString toOffset(const QPair<int, int> &startEnd);
static QPair<int, int> fromOffset(const QString &offset);
static const QChar kColon;
const int m_startPos;
const int m_endPos;
class CORE_EXPORT MagicStringRule : public MagicRule
MagicStringRule(const QString &s, int startPos, int endPos);
virtual ~MagicStringRule();
virtual QString matchType() const;
virtual QString matchValue() const;
virtual bool matches(const QByteArray &data) const;
static const QString kMatchType;
const QByteArray m_pattern;
class CORE_EXPORT MagicByteRule : public MagicRule
MagicByteRule(const QString &s, int startPos, int endPos);
virtual ~MagicByteRule();
virtual QString matchType() const;
virtual QString matchValue() const;
virtual bool matches(const QByteArray &data) const;
static bool validateByteSequence(const QString &sequence, QList<int> *bytes = 0);
static const QString kMatchType;
int m_bytesSize;
QList<int> m_bytes;
class CORE_EXPORT MagicRuleMatcher : public IMagicMatcher
typedef QSharedPointer<MagicRule> MagicRuleSharedPointer;
typedef QList<MagicRuleSharedPointer> MagicRuleList;
void add(const MagicRuleSharedPointer &rule);
void add(const MagicRuleList &ruleList);
MagicRuleList magicRules() const;
virtual bool matches(const QByteArray &data) const;
virtual int priority() const;
void setPriority(int p);
// Create a list of MagicRuleMatchers from a hash of rules indexed by priorities.
static IMagicMatcher::IMagicMatcherList createMatchers(const QHash<int, MagicRuleList> &);
MagicRuleList m_list;
int m_priority;
class CORE_EXPORT MimeGlobPattern
static const unsigned MaxWeight = 100;
static const unsigned MinWeight = 1;
explicit MimeGlobPattern(const QString &pattern, unsigned weight = MaxWeight);
bool matches(const QString &fileName) const;
unsigned weight() const { return m_weight; }
QString pattern() const { return m_pattern; }
enum { Suffix, Exact, Glob } m_type;
QString m_pattern;
QRegExp m_regexp; // Will be used in \c Glob case only.
unsigned m_weight;
class CORE_EXPORT MimeType
typedef IMagicMatcher::IMagicMatcherList IMagicMatcherList;
typedef IMagicMatcher::IMagicMatcherSharedPointer IMagicMatcherSharedPointer;
MimeType(const MimeType&);
MimeType &operator=(const MimeType&);
void clear();
bool isNull() const;
operator bool() const;
bool isTopLevel() const;
QString type() const;
void setType(const QString &type);
QStringList aliases() const;
void setAliases(const QStringList &);
QString comment() const;
void setComment(const QString &comment);
QString localeComment(const QString &locale = QString() /* en, de...*/) const;
void setLocaleComment(const QString &locale, const QString &comment);
QList<MimeGlobPattern> globPatterns() const;
void setGlobPatterns(const QList<MimeGlobPattern> &);
QStringList subClassesOf() const;
void setSubClassesOf(const QStringList &);
// Extension over standard mime data
QStringList suffixes() const;
QString preferredSuffix() const;
bool setPreferredSuffix(const QString&);
// Check for type or one of the aliases
bool matchesType(const QString &type) const;
// Check glob patterns weights and magic priorities so the highest
// value is returned. A 0 (zero) indicates no match.
unsigned matchesFile(const QFileInfo &file) const;
// Return a filter string usable for a file dialog
QString filterString() const;
void addMagicMatcher(const IMagicMatcherSharedPointer &matcher);
const IMagicMatcherList &magicMatchers() const;
void setMagicMatchers(const IMagicMatcherList &matchers);
// Convenience for rule-base matchers.
IMagicMatcherList magicRuleMatchers() const;
void setMagicRuleMatchers(const IMagicMatcherList &matchers);
friend QDebug operator<<(QDebug d, const MimeType &mt);
static QString formatFilterString(const QString &description,
const QList<MimeGlobPattern> &globs);
explicit MimeType(const MimeTypeData &d);
unsigned matchesFileBySuffix(Internal::FileMatchContext &c) const;
unsigned matchesFileByContent(Internal::FileMatchContext &c) const;
unsigned matchesData(const QByteArray &data) const;
friend class Internal::BaseMimeTypeParser;
friend class MimeDatabasePrivate;
QSharedDataPointer<MimeTypeData> m_d;
class CORE_EXPORT MimeDatabase
typedef IMagicMatcher::IMagicMatcherList IMagicMatcherList;
typedef IMagicMatcher::IMagicMatcherSharedPointer IMagicMatcherSharedPointer;
static bool addMimeTypes(const QString &fileName, QString *errorMessage);
static bool addMimeTypes(QIODevice *device, QString *errorMessage);
static bool addMimeType(const MimeType &mt);
// Returns a mime type or Null one if none found
static MimeType findByType(const QString &type);
// Returns a mime type or Null one if none found
static MimeType findByFile(const QFileInfo &f);
// Returns a mime type or Null one if none found
static MimeType findByData(const QByteArray &data);
// Return all known suffixes
static QStringList suffixes();
static bool setPreferredSuffix(const QString &typeOrAlias, const QString &suffix);
static QString preferredSuffixByType(const QString &type);