Index: trunk/src/gui/text/qsyntaxhighlighter.cpp
===================================================================
--- trunk/src/gui/text/qsyntaxhighlighter.cpp	(revision 651)
+++ trunk/src/gui/text/qsyntaxhighlighter.cpp	(revision 846)
@@ -1,5 +1,5 @@
 /****************************************************************************
 **
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
 ** All rights reserved.
 ** Contact: Nokia Corporation (qt-info@nokia.com)
@@ -60,21 +60,22 @@
     Q_DECLARE_PUBLIC(QSyntaxHighlighter)
 public:
-    inline QSyntaxHighlighterPrivate() : rehighlightPending(false) {}
+    inline QSyntaxHighlighterPrivate()
+        : rehighlightPending(false), inReformatBlocks(false)
+    {}
 
     QPointer<QTextDocument> doc;
 
     void _q_reformatBlocks(int from, int charsRemoved, int charsAdded);
-    void reformatBlock(QTextBlock block);
-    
+    void reformatBlocks(int from, int charsRemoved, int charsAdded);
+    void reformatBlock(const QTextBlock &block);
+
     inline void rehighlight(QTextCursor &cursor, QTextCursor::MoveOperation operation) {
-        QObject::disconnect(doc, SIGNAL(contentsChange(int,int,int)),
-                            q_func(), SLOT(_q_reformatBlocks(int,int,int)));
+        inReformatBlocks = true;
         cursor.beginEditBlock();
         int from = cursor.position();
         cursor.movePosition(operation);
-        _q_reformatBlocks(from, 0, cursor.position() - from);
+        reformatBlocks(from, 0, cursor.position() - from);
         cursor.endEditBlock();
-        QObject::connect(doc, SIGNAL(contentsChange(int,int,int)),
-                         q_func(), SLOT(_q_reformatBlocks(int,int,int)));
+        inReformatBlocks = false;
     }
 
@@ -84,5 +85,4 @@
         rehighlightPending = false;
         q_func()->rehighlight();
-        return;
     }
 
@@ -91,8 +91,11 @@
     QTextBlock currentBlock;
     bool rehighlightPending;
+    bool inReformatBlocks;
 };
 
 void QSyntaxHighlighterPrivate::applyFormatChanges()
 {
+    bool formatsChanged = false;
+
     QTextLayout *layout = currentBlock.layout();
 
@@ -102,11 +105,18 @@
     const int preeditAreaLength = layout->preeditAreaText().length();
 
-    QList<QTextLayout::FormatRange>::Iterator it = ranges.begin();
-    while (it != ranges.end()) {
-        if (it->start >= preeditAreaStart
-            && it->start + it->length <= preeditAreaStart + preeditAreaLength)
-            ++it;
-        else
-            it = ranges.erase(it);
+    if (preeditAreaLength != 0) {
+        QList<QTextLayout::FormatRange>::Iterator it = ranges.begin();
+        while (it != ranges.end()) {
+            if (it->start >= preeditAreaStart
+                && it->start + it->length <= preeditAreaStart + preeditAreaLength) {
+                ++it;
+            } else {
+                it = ranges.erase(it);
+                formatsChanged = true;
+            }
+        }
+    } else if (!ranges.isEmpty()) {
+        ranges.clear();
+        formatsChanged = true;
     }
 
@@ -114,5 +124,5 @@
 
     QTextLayout::FormatRange r;
-    r.start = r.length = -1;
+    r.start = -1;
 
     int i = 0;
@@ -136,12 +146,14 @@
         r.length = i - r.start;
 
-        if (r.start >= preeditAreaStart) {
-            r.start += preeditAreaLength;
-        } else if (r.start + r.length >= preeditAreaStart) {
-            r.length += preeditAreaLength;
+        if (preeditAreaLength != 0) {
+            if (r.start >= preeditAreaStart)
+                r.start += preeditAreaLength;
+            else if (r.start + r.length >= preeditAreaStart)
+                r.length += preeditAreaLength;
         }
 
         ranges << r;
-        r.start = r.length = -1;
+        formatsChanged = true;
+        r.start = -1;
     }
 
@@ -149,19 +161,29 @@
         r.length = formatChanges.count() - r.start;
 
-        if (r.start >= preeditAreaStart) {
-            r.start += preeditAreaLength;
-        } else if (r.start + r.length >= preeditAreaStart) {
-            r.length += preeditAreaLength;
+        if (preeditAreaLength != 0) {
+            if (r.start >= preeditAreaStart)
+                r.start += preeditAreaLength;
+            else if (r.start + r.length >= preeditAreaStart)
+                r.length += preeditAreaLength;
         }
 
         ranges << r;
-    }
-
-    layout->setAdditionalFormats(ranges);
+        formatsChanged = true;
+    }
+
+    if (formatsChanged) {
+        layout->setAdditionalFormats(ranges);
+        doc->markContentsDirty(currentBlock.position(), currentBlock.length());
+    }
 }
 
 void QSyntaxHighlighterPrivate::_q_reformatBlocks(int from, int charsRemoved, int charsAdded)
 {
-    Q_UNUSED(charsRemoved);
+    if (!inReformatBlocks)
+        reformatBlocks(from, charsRemoved, charsAdded);
+}
+
+void QSyntaxHighlighterPrivate::reformatBlocks(int from, int charsRemoved, int charsAdded)
+{
     rehighlightPending = false;
 
@@ -192,5 +214,5 @@
 }
 
-void QSyntaxHighlighterPrivate::reformatBlock(QTextBlock block)
+void QSyntaxHighlighterPrivate::reformatBlock(const QTextBlock &block)
 {
     Q_Q(QSyntaxHighlighter);
@@ -199,11 +221,8 @@
 
     currentBlock = block;
-    QTextBlock previous = block.previous();
 
     formatChanges.fill(QTextCharFormat(), block.length() - 1);
     q->highlightBlock(block.text());
     applyFormatChanges();
-
-    doc->markContentsDirty(block.position(), block.length());
 
     currentBlock = QTextBlock();
@@ -350,6 +369,6 @@
         connect(d->doc, SIGNAL(contentsChange(int,int,int)),
                 this, SLOT(_q_reformatBlocks(int,int,int)));
+        d->rehighlightPending = true;
         QTimer::singleShot(0, this, SLOT(_q_delayedRehighlight()));
-        d->rehighlightPending = true;
     }
 }
@@ -392,9 +411,14 @@
 {
     Q_D(QSyntaxHighlighter);
-    if (!d->doc)
+    if (!d->doc || !block.isValid() || block.document() != d->doc)
         return;
+
+    const bool rehighlightPending = d->rehighlightPending;
 
     QTextCursor cursor(block);
     d->rehighlight(cursor, QTextCursor::EndOfBlock);
+
+    if (rehighlightPending)
+        d->rehighlightPending = rehighlightPending;
 }
 
@@ -461,5 +485,4 @@
 {
     Q_D(QSyntaxHighlighter);
-
     if (start < 0 || start >= d->formatChanges.count())
         return;
@@ -629,5 +652,5 @@
 
     Returns the current text block.
- */
+*/
 QTextBlock QSyntaxHighlighter::currentBlock() const
 {
