forked from qt-creator/qt-creator
Parsing of definitions metadata for mime type registering is now in a separate thread (QtConcurrent). Also some clean up.
This commit is contained in:
@@ -47,8 +47,6 @@
|
||||
#include <QtCore/QSharedPointer>
|
||||
#include <QtCore/QFileInfo>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
using namespace GenericEditor;
|
||||
using namespace Internal;
|
||||
|
||||
@@ -97,7 +95,7 @@ void Editor::configure()
|
||||
try {
|
||||
const QString &definitionId =
|
||||
GenericEditorPlugin::instance()->definitionIdByMimeType(mimeType);
|
||||
QSharedPointer<HighlightDefinition> definition =
|
||||
const QSharedPointer<HighlightDefinition> &definition =
|
||||
GenericEditorPlugin::instance()->definition(definitionId);
|
||||
|
||||
Highlighter *highlighter = new Highlighter(definition->initialContext());
|
||||
@@ -112,9 +110,10 @@ void Editor::configure()
|
||||
|
||||
//@todo: It's possible to specify an indenter style in the definition file. However, this
|
||||
// is not really being used because Kate recommends to configure indentation through
|
||||
// another editor feature. Maybe we should provide something similar in Creator?
|
||||
// For now the normal indenter is used.
|
||||
// another feature. Maybe we should provide something similar in Creator? For now the
|
||||
// normal indenter is used.
|
||||
m_indenter.reset(new TextEditor::NormalIndenter);
|
||||
|
||||
} catch (const HighlighterException &) {
|
||||
// No highlighter will be set.
|
||||
}
|
||||
|
||||
@@ -36,11 +36,9 @@
|
||||
#include "editorfactory.h"
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/mimedatabase.h>
|
||||
#include <texteditor/texteditorsettings.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <cppeditor/cppeditorconstants.h>
|
||||
#include <qmljseditor/qmljseditorconstants.h>
|
||||
#include <qtconcurrent/QtConcurrentTools>
|
||||
|
||||
#include <QtCore/QtAlgorithms>
|
||||
#include <QtCore/QtPlugin>
|
||||
@@ -53,6 +51,8 @@
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QRegExp>
|
||||
#include <QtCore/QFuture>
|
||||
#include <QtCore/QtConcurrentRun>
|
||||
#include <QtXml/QXmlSimpleReader>
|
||||
#include <QtXml/QXmlInputSource>
|
||||
#include <QtXml/QXmlStreamReader>
|
||||
@@ -69,8 +69,7 @@ GenericEditorPlugin::GenericEditorPlugin() :
|
||||
QTC_ASSERT(!m_instance, return);
|
||||
m_instance = this;
|
||||
|
||||
connect(Core::ICore::instance(), SIGNAL(coreOpened()),
|
||||
this, SLOT(lookforAvailableDefinitions()));
|
||||
connect(Core::ICore::instance(), SIGNAL(coreOpened()), this, SLOT(registerMimeTypes()));
|
||||
}
|
||||
|
||||
GenericEditorPlugin::~GenericEditorPlugin()
|
||||
@@ -158,7 +157,16 @@ const QSharedPointer<HighlightDefinition> &GenericEditorPlugin::definition(const
|
||||
bool GenericEditorPlugin::isBuildingDefinition(const QString &id) const
|
||||
{ return m_isBuilding.contains(id); }
|
||||
|
||||
void GenericEditorPlugin::lookforAvailableDefinitions()
|
||||
void GenericEditorPlugin::registerMimeTypes()
|
||||
{
|
||||
QFuture<Core::MimeType> future =
|
||||
QtConcurrent::run(&GenericEditorPlugin::gatherDefinitionsMimeTypes, this);
|
||||
m_watcher.setFuture(future);
|
||||
|
||||
connect(&m_watcher, SIGNAL(resultReadyAt(int)), this, SLOT(registerMimeType(int)));
|
||||
}
|
||||
|
||||
void GenericEditorPlugin::gatherDefinitionsMimeTypes(QFutureInterface<Core::MimeType> &future)
|
||||
{
|
||||
QDir definitionsDir(Core::ICore::instance()->resourcePath() +
|
||||
QLatin1String("/generic-highlighter"));
|
||||
@@ -167,11 +175,50 @@ void GenericEditorPlugin::lookforAvailableDefinitions()
|
||||
definitionsDir.setNameFilters(filter);
|
||||
|
||||
const QFileInfoList &filesInfo = definitionsDir.entryInfoList();
|
||||
foreach (const QFileInfo &fileInfo, filesInfo)
|
||||
parseDefinitionMetadata(fileInfo);
|
||||
foreach (const QFileInfo &fileInfo, filesInfo) {
|
||||
QString comment;
|
||||
QStringList mimeTypes;
|
||||
QStringList patterns;
|
||||
parseDefinitionMetadata(fileInfo, &comment, &mimeTypes, &patterns);
|
||||
|
||||
// A definition can specify multiple MIME types and file extensions/patterns. However, each
|
||||
// thing is done with a single string. Then, there is no direct way to tell which patterns
|
||||
// belong to which MIME types nor whether a MIME type is just an alias for the other.
|
||||
// Currently, I associate all expressions/patterns with all MIME types from a definition.
|
||||
|
||||
static const QStringList textPlain(QLatin1String("text/plain"));
|
||||
|
||||
QList<QRegExp> expressions;
|
||||
foreach (const QString &type, mimeTypes) {
|
||||
Core::MimeType mimeType = Core::ICore::instance()->mimeDatabase()->findByType(type);
|
||||
if (mimeType.isNull()) {
|
||||
if (expressions.isEmpty()) {
|
||||
foreach (const QString &pattern, patterns)
|
||||
expressions.append(QRegExp(pattern, Qt::CaseSensitive, QRegExp::Wildcard));
|
||||
}
|
||||
|
||||
mimeType.setType(type);
|
||||
mimeType.setSubClassesOf(textPlain);
|
||||
mimeType.setComment(comment);
|
||||
mimeType.setGlobPatterns(expressions);
|
||||
|
||||
future.reportResult(mimeType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GenericEditorPlugin::parseDefinitionMetadata(const QFileInfo &fileInfo)
|
||||
void GenericEditorPlugin::registerMimeType(int index) const
|
||||
{
|
||||
const Core::MimeType &mimeType = m_watcher.resultAt(index);
|
||||
Core::ICore::instance()->mimeDatabase()->addMimeType(mimeType);
|
||||
m_factory->m_mimeTypes.append(mimeType.type());
|
||||
}
|
||||
|
||||
void GenericEditorPlugin::parseDefinitionMetadata(const QFileInfo &fileInfo,
|
||||
QString *comment,
|
||||
QStringList *mimeTypes,
|
||||
QStringList *patterns)
|
||||
{
|
||||
static const QLatin1Char kSemiColon(';');
|
||||
static const QLatin1Char kSlash('/');
|
||||
@@ -194,24 +241,24 @@ void GenericEditorPlugin::parseDefinitionMetadata(const QFileInfo &fileInfo)
|
||||
reader.name() == kLanguage) {
|
||||
const QXmlStreamAttributes &attr = reader.attributes();
|
||||
|
||||
const QString &name = attr.value(kName).toString();
|
||||
m_idByName.insert(name, id);
|
||||
*comment = attr.value(kName).toString();
|
||||
m_idByName.insert(*comment, id);
|
||||
|
||||
const QStringList &patterns =
|
||||
attr.value(kExtensions).toString().split(kSemiColon, QString::SkipEmptyParts);
|
||||
*patterns = attr.value(kExtensions).toString().split(kSemiColon,
|
||||
QString::SkipEmptyParts);
|
||||
|
||||
QStringList mimeTypes =
|
||||
attr.value(kMimeType).toString().split(kSemiColon, QString::SkipEmptyParts);
|
||||
if (mimeTypes.isEmpty()) {
|
||||
*mimeTypes = attr.value(kMimeType).toString().split(kSemiColon,
|
||||
QString::SkipEmptyParts);
|
||||
if (mimeTypes->isEmpty()) {
|
||||
// There are definitions which do not specify a MIME type, but specify file
|
||||
// patterns. Creating an artificial MIME type is a workaround.
|
||||
QString mimeType(kArtificial);
|
||||
mimeType.append(kSlash).append(name);
|
||||
m_idByMimeType.insert(mimeType, id);
|
||||
mimeTypes.append(mimeType);
|
||||
QString artificialType(kArtificial);
|
||||
artificialType.append(kSlash).append(*comment);
|
||||
m_idByMimeType.insert(artificialType, id);
|
||||
mimeTypes->append(artificialType);
|
||||
} else {
|
||||
foreach (const QString &mimeType, mimeTypes)
|
||||
m_idByMimeType.insert(mimeType, id);
|
||||
foreach (const QString &type, *mimeTypes)
|
||||
m_idByMimeType.insert(type, id);
|
||||
}
|
||||
|
||||
// The priority below should not be confused with the priority used when matching files
|
||||
@@ -220,7 +267,6 @@ void GenericEditorPlugin::parseDefinitionMetadata(const QFileInfo &fileInfo)
|
||||
// multiple ones associated with the same MIME type (should not happen in general).
|
||||
m_priorityComp.m_priorityById.insert(id, attr.value(kPriority).toString().toInt());
|
||||
|
||||
registerMimeTypes(name, mimeTypes, patterns);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -228,35 +274,4 @@ void GenericEditorPlugin::parseDefinitionMetadata(const QFileInfo &fileInfo)
|
||||
definitionFile.close();
|
||||
}
|
||||
|
||||
void GenericEditorPlugin::registerMimeTypes(const QString &comment,
|
||||
const QStringList &types,
|
||||
const QStringList &patterns)
|
||||
{
|
||||
static const QStringList textPlain(QLatin1String("text/plain"));
|
||||
|
||||
// A definition can specify multiple MIME types and file extensions/patterns. However, each
|
||||
// thing is done with a single string. Then, there is no direct way to tell which extensions/
|
||||
// patterns belong to which MIME types nor whether a MIME type is just an alias for the other.
|
||||
// Currentl y, I associate all expressions/patterns with all MIME types from a definition.
|
||||
|
||||
QList<QRegExp> expressions;
|
||||
foreach (const QString &type, types) {
|
||||
Core::MimeType mimeType = Core::ICore::instance()->mimeDatabase()->findByType(type);
|
||||
if (mimeType.isNull()) {
|
||||
if (expressions.isEmpty()) {
|
||||
foreach (const QString &pattern, patterns)
|
||||
expressions.append(QRegExp(pattern, Qt::CaseSensitive, QRegExp::Wildcard));
|
||||
}
|
||||
|
||||
mimeType.setType(type);
|
||||
mimeType.setSubClassesOf(textPlain);
|
||||
mimeType.setComment(comment);
|
||||
mimeType.setGlobPatterns(expressions);
|
||||
|
||||
Core::ICore::instance()->mimeDatabase()->addMimeType(mimeType);
|
||||
m_factory->m_mimeTypes.append(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Q_EXPORT_PLUGIN(GenericEditorPlugin)
|
||||
|
||||
@@ -30,27 +30,28 @@
|
||||
#ifndef GENERICEDITORPLUGIN_H
|
||||
#define GENERICEDITORPLUGIN_H
|
||||
|
||||
#include <coreplugin/mimedatabase.h>
|
||||
#include <extensionsystem/iplugin.h>
|
||||
#include <texteditor/texteditoractionhandler.h>
|
||||
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QLatin1String>
|
||||
#include <QtCore/QHash>
|
||||
#include <QtCore/QMultiHash>
|
||||
#include <QtCore/QSet>
|
||||
#include <QtCore/QSharedPointer>
|
||||
#include <QtCore/QFutureWatcher>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QFileInfo;
|
||||
class QStringList;
|
||||
template <class> class QFutureInterface;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace GenericEditor {
|
||||
namespace Internal {
|
||||
|
||||
class HighlightDefinition;
|
||||
class HighlightDefinitionMetadata;
|
||||
class Editor;
|
||||
class EditorFactory;
|
||||
|
||||
@@ -75,17 +76,19 @@ public:
|
||||
const QSharedPointer<HighlightDefinition> &definition(const QString &id);
|
||||
|
||||
private slots:
|
||||
void lookforAvailableDefinitions();
|
||||
void registerMimeTypes();
|
||||
void registerMimeType(int index) const;
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(GenericEditorPlugin)
|
||||
|
||||
static GenericEditorPlugin *m_instance;
|
||||
|
||||
void parseDefinitionMetadata(const QFileInfo &fileInfo);
|
||||
void registerMimeTypes(const QString &comment,
|
||||
const QStringList &types,
|
||||
const QStringList &patterns);
|
||||
void gatherDefinitionsMimeTypes(QFutureInterface<Core::MimeType> &future);
|
||||
void parseDefinitionMetadata(const QFileInfo &fileInfo,
|
||||
QString *comment,
|
||||
QStringList *mimeTypes,
|
||||
QStringList *patterns);
|
||||
|
||||
struct PriorityCompare
|
||||
{
|
||||
@@ -100,6 +103,8 @@ private:
|
||||
|
||||
EditorFactory *m_factory;
|
||||
|
||||
QFutureWatcher<Core::MimeType> m_watcher;
|
||||
|
||||
QHash<QString, QString> m_idByName;
|
||||
QMultiHash<QString, QString> m_idByMimeType;
|
||||
QHash<QString, QSharedPointer<HighlightDefinition> > m_definitions;
|
||||
|
||||
@@ -109,9 +109,6 @@ private:
|
||||
QString m_multiLineCommentRegion;
|
||||
|
||||
Qt::CaseSensitivity m_keywordCaseSensitivity;
|
||||
|
||||
QString m_languageName;
|
||||
QString m_fileExtensions;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
@@ -430,13 +430,13 @@ void HighlightDefinitionHandler::processIncludeRules(const QSharedPointer<Contex
|
||||
// definition they are from.
|
||||
QString externalName = QString::fromRawData(sourceName.unicode() + 2,
|
||||
sourceName.length() - 2);
|
||||
const QString id = GenericEditorPlugin::instance()->definitionIdByName(externalName);
|
||||
const QString &id = GenericEditorPlugin::instance()->definitionIdByName(externalName);
|
||||
|
||||
// If there is an incorrect circular dependency among definitions this is skipped.
|
||||
if (GenericEditorPlugin::instance()->isBuildingDefinition(id))
|
||||
continue;
|
||||
|
||||
QSharedPointer<HighlightDefinition> externalDefinition =
|
||||
const QSharedPointer<HighlightDefinition> &externalDefinition =
|
||||
GenericEditorPlugin::instance()->definition(id);
|
||||
sourceContext = externalDefinition->initialContext();
|
||||
} else if (!sourceName.startsWith(kHash)) {
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
#include <QtCore/QStringList>
|
||||
|
||||
#include <QtGui/QSyntaxHighlighter>
|
||||
#include <QtGui/QTextBlockUserData>
|
||||
|
||||
#include <texteditor/basetextdocumentlayout.h>
|
||||
|
||||
|
||||
@@ -31,10 +31,7 @@
|
||||
#define ITEMDATA_H
|
||||
|
||||
#include <QtCore/QString>
|
||||
|
||||
#include <QtGui/QColor>
|
||||
#include <QtGui/QFont>
|
||||
#include <QtGui/QTextCharFormat>
|
||||
|
||||
namespace GenericEditor {
|
||||
namespace Internal {
|
||||
|
||||
Reference in New Issue
Block a user