From c2f2d131119cdfa7b0ff5da4d7365033128da3b5 Mon Sep 17 00:00:00 2001
From: Leandro Melo <leandro.melo@nokia.com>
Date: Mon, 31 May 2010 13:56:46 +0200
Subject: [PATCH] Generic highlighter: Refactored how format configuration is
 done.

Now the highlighter engine does not directly depend on TextEditor::FontSettings. This also makes things easier for unit testing.
---
 .../generichighlighter/highlighter.cpp        | 67 +++++++------------
 .../generichighlighter/highlighter.h          | 51 +++++++++-----
 .../generichighlighter/itemdata.cpp           | 15 -----
 .../texteditor/generichighlighter/itemdata.h  | 15 -----
 .../generichighlighter/specificrules.cpp      |  3 +-
 src/plugins/texteditor/plaintexteditor.cpp    | 46 +++++++++++--
 6 files changed, 103 insertions(+), 94 deletions(-)

diff --git a/src/plugins/texteditor/generichighlighter/highlighter.cpp b/src/plugins/texteditor/generichighlighter/highlighter.cpp
index 27b0309795c..7c52014f432 100644
--- a/src/plugins/texteditor/generichighlighter/highlighter.cpp
+++ b/src/plugins/texteditor/generichighlighter/highlighter.cpp
@@ -35,8 +35,6 @@
 #include "highlighterexception.h"
 #include "progressdata.h"
 #include "reuse.h"
-#include "texteditorconstants.h"
-#include "fontsettings.h"
 
 #include <QtCore/QLatin1String>
 #include <QtCore/QLatin1Char>
@@ -51,6 +49,8 @@ namespace {
     static const QLatin1Char kHash('#');
 }
 
+const Highlighter::KateFormatMap Highlighter::m_kateFormats;
+
 Highlighter::Highlighter(const QSharedPointer<Context> &defaultContext,QTextDocument *parent) :
     QSyntaxHighlighter(parent),
     m_persistentStatesCounter(PersistentsStart),
@@ -70,6 +70,24 @@ Highlighter::BlockData::BlockData()
 Highlighter::BlockData::~BlockData()
 {}
 
+Highlighter::KateFormatMap::KateFormatMap()
+{
+    m_ids.insert(QLatin1String("dsNormal"), Highlighter::Normal);
+    m_ids.insert(QLatin1String("dsKeyword"), Highlighter::Keyword);
+    m_ids.insert(QLatin1String("dsDataType"), Highlighter::DataType);
+    m_ids.insert(QLatin1String("dsDecVal"), Highlighter::Decimal);
+    m_ids.insert(QLatin1String("dsBaseN"), Highlighter::BaseN);
+    m_ids.insert(QLatin1String("dsFloat"), Highlighter::Float);
+    m_ids.insert(QLatin1String("dsChar"), Highlighter::Char);
+    m_ids.insert(QLatin1String("dsString"), Highlighter::String);
+    m_ids.insert(QLatin1String("dsComment"), Highlighter::Comment);
+    m_ids.insert(QLatin1String("dsOthers"), Highlighter::Others);
+    m_ids.insert(QLatin1String("dsAlert"), Highlighter::Alert);
+    m_ids.insert(QLatin1String("dsFunction"), Highlighter::Function);
+    m_ids.insert(QLatin1String("dsRegionMarker"), Highlighter::RegionMarker);
+    m_ids.insert(QLatin1String("dsError"), Highlighter::Error);
+}
+
 void Highlighter::highlightBlock(const QString &text)
 {
     if (m_isBroken)
@@ -304,8 +322,9 @@ void Highlighter::applyFormat(int offset,
         return;
     }
 
-    if (itemData->style() != ItemData::kDsNormal) {
-        QTextCharFormat format = m_genericFormats.value(itemData->style());
+    TextFormatId formatId = m_kateFormats.m_ids.value(itemData->style());
+    if (formatId != Normal) {
+        QTextCharFormat format = m_creatorFormats.value(formatId);
 
         if (itemData->isCustomized()) {
             // Please notice that the following are applied every time for item datas which have
@@ -340,7 +359,7 @@ void Highlighter::applyVisualWhitespaceFormat(const QString &text)
             int start = offset++;
             while (offset < length && text.at(offset).isSpace())
                 ++offset;
-            setFormat(start, offset - start, m_visualWhitespaceFormat);
+            setFormat(start, offset - start, m_creatorFormats.value(VisualWhitespace));
         } else {
             ++offset;
         }
@@ -438,41 +457,7 @@ void Highlighter::setCurrentContext()
     m_currentContext = m_contexts.back();
 }
 
-void Highlighter::configureFormats(const FontSettings & fs)
+void Highlighter::configureFormat(TextFormatId id, const QTextCharFormat &format)
 {
-    m_visualWhitespaceFormat = fs.toTextCharFormat(
-            QLatin1String(TextEditor::Constants::C_VISUAL_WHITESPACE));
-
-    m_genericFormats[ItemData::kDsKeyword] = fs.toTextCharFormat(
-            QLatin1String(TextEditor::Constants::C_KEYWORD));
-    m_genericFormats[ItemData::kDsDataType] = fs.toTextCharFormat(
-            QLatin1String(TextEditor::Constants::C_TYPE));
-    // Currenlty using C_NUMBER for all kinds of numbers.
-    m_genericFormats[ItemData::kDsDecVal] = fs.toTextCharFormat(
-            QLatin1String(TextEditor::Constants::C_NUMBER));
-    m_genericFormats[ItemData::kDsBaseN] = fs.toTextCharFormat(
-            QLatin1String(TextEditor::Constants::C_NUMBER));
-    m_genericFormats[ItemData::kDsFloat] = fs.toTextCharFormat(
-            QLatin1String(TextEditor::Constants::C_NUMBER));
-    // Currently using C_STRING for strings and chars.
-    m_genericFormats[ItemData::kDsChar] = fs.toTextCharFormat(
-            QLatin1String(TextEditor::Constants::C_STRING));
-    m_genericFormats[ItemData::kDsString] = fs.toTextCharFormat(
-            QLatin1String(TextEditor::Constants::C_STRING));
-    m_genericFormats[ItemData::kDsComment] = fs.toTextCharFormat(
-            QLatin1String(TextEditor::Constants::C_COMMENT));
-
-    // Currently Creator does not have corresponding formats for the following items. We can
-    // implement them... Just for now I will leave hardcoded colors.
-    QTextCharFormat format;
-    format.setForeground(Qt::blue);
-    m_genericFormats[ItemData::kDsOthers] = format;
-    format.setForeground(Qt::red);
-    m_genericFormats[ItemData::kDsAlert] = format;
-    format.setForeground(Qt::darkBlue);
-    m_genericFormats[ItemData::kDsFunction] = format;
-    format.setForeground(Qt::darkGray);
-    m_genericFormats[ItemData::kDsRegionMarker] = format;
-    format.setForeground(Qt::darkRed);
-    m_genericFormats[ItemData::kDsError] = format;
+    m_creatorFormats[id] = format;
 }
diff --git a/src/plugins/texteditor/generichighlighter/highlighter.h b/src/plugins/texteditor/generichighlighter/highlighter.h
index d544092185c..caedb070838 100644
--- a/src/plugins/texteditor/generichighlighter/highlighter.h
+++ b/src/plugins/texteditor/generichighlighter/highlighter.h
@@ -38,10 +38,7 @@
 #include <QtCore/QStringList>
 
 #include <QtGui/QSyntaxHighlighter>
-
-namespace TextEditor {
-class FontSettings;
-}
+#include <QtGui/QTextCharFormat>
 
 namespace TextEditor {
 namespace Internal {
@@ -57,7 +54,24 @@ public:
     Highlighter(const QSharedPointer<Context> &defaultContext, QTextDocument *parent = 0);
     virtual ~Highlighter();
 
-    void configureFormats(const FontSettings &fs);
+    enum TextFormatId {
+        Normal,
+        VisualWhitespace,
+        Keyword,
+        DataType,
+        Decimal,
+        BaseN,
+        Float,
+        Char,
+        String,
+        Comment,
+        Alert,
+        Error,
+        Function,
+        RegionMarker,
+        Others
+    };
+    void configureFormat(TextFormatId id, const QTextCharFormat &format);
 
 protected:
     virtual void highlightBlock(const QString &text);
@@ -76,6 +90,7 @@ private:
                              const bool childRule,
                              const QList<QSharedPointer<Rule> > &rules);
 
+    void setCurrentContext();
     bool contextChangeRequired(const QString &contextName) const;
     void handleContextChange(const QString &contextName,
                              const QSharedPointer<HighlightDefinition> &definition,
@@ -84,22 +99,29 @@ private:
                        const QSharedPointer<HighlightDefinition> &definition,
                        const bool setCurrent = true);
 
-    void applyFormat(int offset,
-                     int count,
-                     const QString &itemDataName,
-                     const QSharedPointer<HighlightDefinition> &definition);
-    void applyVisualWhitespaceFormat(const QString &text);
-
     QString currentContextSequence() const;
     void mapContextSequence(const QString &contextSequence);
     void pushContextSequence(int state);
     void pushDynamicContext(const QSharedPointer<Context> &baseContext);
 
-    void setCurrentContext();
-
     void createWillContinueBlock();
     void analyseConsistencyOfWillContinueBlock(const QString &text);
 
+    void applyFormat(int offset,
+                     int count,
+                     const QString &itemDataName,
+                     const QSharedPointer<HighlightDefinition> &definition);
+    void applyVisualWhitespaceFormat(const QString &text);
+
+    // Mapping from Kate format strings to format ids.
+    struct KateFormatMap
+    {
+        KateFormatMap();
+        QHash<QString, TextFormatId> m_ids;
+    };
+    static const KateFormatMap m_kateFormats;
+    QHash<TextFormatId, QTextCharFormat> m_creatorFormats;
+
     struct BlockData : TextBlockUserData
     {
         BlockData();
@@ -143,9 +165,6 @@ private:
 
     // Captures used in dynamic rules.
     QStringList m_currentCaptures;
-
-    QTextCharFormat m_visualWhitespaceFormat;
-    QHash<QString, QTextCharFormat> m_genericFormats;
 };
 
 } // namespace Internal
diff --git a/src/plugins/texteditor/generichighlighter/itemdata.cpp b/src/plugins/texteditor/generichighlighter/itemdata.cpp
index 498d968e32c..65f6b7f2a32 100644
--- a/src/plugins/texteditor/generichighlighter/itemdata.cpp
+++ b/src/plugins/texteditor/generichighlighter/itemdata.cpp
@@ -33,21 +33,6 @@
 using namespace TextEditor;
 using namespace Internal;
 
-const QLatin1String ItemData::kDsNormal("dsNormal");
-const QLatin1String ItemData::kDsKeyword("dsKeyword");
-const QLatin1String ItemData::kDsDataType("dsDataType");
-const QLatin1String ItemData::kDsDecVal("dsDecVal");
-const QLatin1String ItemData::kDsBaseN("dsBaseN");
-const QLatin1String ItemData::kDsFloat("dsFloat");
-const QLatin1String ItemData::kDsChar("dsChar");
-const QLatin1String ItemData::kDsString("dsString");
-const QLatin1String ItemData::kDsComment("dsComment");
-const QLatin1String ItemData::kDsOthers("dsOthers");
-const QLatin1String ItemData::kDsAlert("dsAlert");
-const QLatin1String ItemData::kDsFunction("dsFunction");
-const QLatin1String ItemData::kDsRegionMarker("dsRegionMarker");
-const QLatin1String ItemData::kDsError("dsError");
-
 ItemData::ItemData() :
     m_italicSpecified(false),
     m_boldSpecified(false),
diff --git a/src/plugins/texteditor/generichighlighter/itemdata.h b/src/plugins/texteditor/generichighlighter/itemdata.h
index c1302397498..57b1f1a9e7a 100644
--- a/src/plugins/texteditor/generichighlighter/itemdata.h
+++ b/src/plugins/texteditor/generichighlighter/itemdata.h
@@ -68,21 +68,6 @@ public:
 
     bool isCustomized() const;
 
-    static const QLatin1String kDsNormal;
-    static const QLatin1String kDsKeyword;
-    static const QLatin1String kDsDataType;
-    static const QLatin1String kDsDecVal;
-    static const QLatin1String kDsBaseN;
-    static const QLatin1String kDsFloat;
-    static const QLatin1String kDsChar;
-    static const QLatin1String kDsString;
-    static const QLatin1String kDsComment;
-    static const QLatin1String kDsOthers;
-    static const QLatin1String kDsAlert;
-    static const QLatin1String kDsFunction;
-    static const QLatin1String kDsRegionMarker;
-    static const QLatin1String kDsError;
-
 private:
     QString m_style;
     QColor m_color;
diff --git a/src/plugins/texteditor/generichighlighter/specificrules.cpp b/src/plugins/texteditor/generichighlighter/specificrules.cpp
index 6fe4269367e..0dd00a3c9db 100644
--- a/src/plugins/texteditor/generichighlighter/specificrules.cpp
+++ b/src/plugins/texteditor/generichighlighter/specificrules.cpp
@@ -185,8 +185,7 @@ bool RegExprRule::doMatchSucceed(const QString &text,
     Q_UNUSED(length)
 
     // This is not documented but a regular expression match is considered valid if it starts
-    // at the current position and if the match length is not zero. Checked in Kate's source code
-    // after some unexpected problems.
+    // at the current position and if the match length is not zero.
     const int offset = progress->offset();
     if (m_expression.indexIn(text, offset, QRegExp::CaretAtZero) == offset) {
         if (m_expression.matchedLength() == 0)
diff --git a/src/plugins/texteditor/plaintexteditor.cpp b/src/plugins/texteditor/plaintexteditor.cpp
index feea084a6ac..04034307070 100644
--- a/src/plugins/texteditor/plaintexteditor.cpp
+++ b/src/plugins/texteditor/plaintexteditor.cpp
@@ -38,6 +38,7 @@
 #include "highlighterexception.h"
 #include "manager.h"
 #include "normalindenter.h"
+#include "fontsettings.h"
 
 #include <coreplugin/coreconstants.h>
 #include <coreplugin/uniqueidmanager.h>
@@ -103,14 +104,49 @@ void PlainTextEditor::unCommentSelection()
     Utils::unCommentSelection(this, m_commentDefinition);
 }
 
-void PlainTextEditor::setFontSettings(const FontSettings & fs)
+void PlainTextEditor::setFontSettings(const FontSettings &fs)
 {
     BaseTextEditor::setFontSettings(fs);
 
     if (baseTextDocument()->syntaxHighlighter()) {
         Highlighter *highlighter =
-                static_cast<Highlighter *>(baseTextDocument()->syntaxHighlighter());
-        highlighter->configureFormats(fs);
+            static_cast<Highlighter *>(baseTextDocument()->syntaxHighlighter());
+
+        highlighter->configureFormat(Highlighter::VisualWhitespace, fs.toTextCharFormat(
+            QLatin1String(Constants::C_VISUAL_WHITESPACE)));
+        highlighter->configureFormat(Highlighter::Keyword, fs.toTextCharFormat(
+            QLatin1String(Constants::C_KEYWORD)));
+        highlighter->configureFormat(Highlighter::DataType, fs.toTextCharFormat(
+            QLatin1String(Constants::C_TYPE)));
+        highlighter->configureFormat(Highlighter::Comment, fs.toTextCharFormat(
+            QLatin1String(Constants::C_COMMENT)));
+        // Using C_NUMBER for all kinds of numbers.
+        highlighter->configureFormat(Highlighter::Decimal, fs.toTextCharFormat(
+            QLatin1String(Constants::C_NUMBER)));
+        highlighter->configureFormat(Highlighter::BaseN, fs.toTextCharFormat(
+            QLatin1String(Constants::C_NUMBER)));
+        highlighter->configureFormat(Highlighter::Float, fs.toTextCharFormat(
+            QLatin1String(Constants::C_NUMBER)));
+        // Using C_STRING for strings and chars.
+        highlighter->configureFormat(Highlighter::Char, fs.toTextCharFormat(
+            QLatin1String(Constants::C_STRING)));
+        highlighter->configureFormat(Highlighter::String, fs.toTextCharFormat(
+            QLatin1String(Constants::C_STRING)));
+
+        // Creator does not have corresponding formats for the following ones. Implement them?
+        // For now I will leave hardcoded values.
+        QTextCharFormat format;
+        format.setForeground(Qt::blue);
+        highlighter->configureFormat(Highlighter::Others, format);
+        format.setForeground(Qt::red);
+        highlighter->configureFormat(Highlighter::Alert, format);
+        format.setForeground(Qt::darkBlue);
+        highlighter->configureFormat(Highlighter::Function, format);
+        format.setForeground(Qt::darkGray);
+        highlighter->configureFormat(Highlighter::RegionMarker, format);
+        format.setForeground(Qt::darkRed);
+        highlighter->configureFormat(Highlighter::Error, format);
+
         highlighter->rehighlight();
     }
 }
@@ -140,8 +176,6 @@ void PlainTextEditor::configure(const Core::MimeType &mimeType)
                     Manager::instance()->definition(definitionId);
 
             Highlighter *highlighter = new Highlighter(definition->initialContext());
-            highlighter->configureFormats(TextEditorSettings::instance()->fontSettings());
-
             baseTextDocument()->setSyntaxHighlighter(highlighter);
 
             m_commentDefinition.setAfterWhiteSpaces(definition->isCommentAfterWhiteSpaces());
@@ -149,6 +183,8 @@ void PlainTextEditor::configure(const Core::MimeType &mimeType)
             m_commentDefinition.setMultiLineStart(definition->multiLineCommentStart());
             m_commentDefinition.setMultiLineEnd(definition->multiLineCommentEnd());
 
+            setFontSettings(TextEditorSettings::instance()->fontSettings());
+
             m_isMissingSyntaxDefinition = false;
         } catch (const HighlighterException &) {
         }
-- 
GitLab