[Libreoffice-commits] core.git: Branch 'distro/suse/suse-3.6' - 2 commits - i18npool/qa i18npool/source sw/CppunitTest_sw_swdoc_test.mk sw/inc sw/qa sw/source

Michael Stahl mstahl at redhat.com
Thu Apr 18 01:53:51 PDT 2013


 i18npool/qa/cppunit/test_breakiterator.cxx                   |   33 +
 i18npool/source/breakiterator/data/dict_word.txt             |    2 
 i18npool/source/breakiterator/data/dict_word_ca.txt          |    2 
 i18npool/source/breakiterator/data/dict_word_fi.txt          |    2 
 i18npool/source/breakiterator/data/dict_word_he.txt          |    2 
 i18npool/source/breakiterator/data/dict_word_hu.txt          |    2 
 i18npool/source/breakiterator/data/dict_word_nodash.txt      |    2 
 i18npool/source/breakiterator/data/dict_word_prepostdash.txt |    2 
 i18npool/source/breakiterator/data/edit_word.txt             |    2 
 i18npool/source/breakiterator/data/edit_word_he.txt          |    2 
 i18npool/source/breakiterator/data/edit_word_hu.txt          |    2 
 sw/CppunitTest_sw_swdoc_test.mk                              |    1 
 sw/inc/modeltoviewhelper.hxx                                 |   66 ++-
 sw/inc/ndtxt.hxx                                             |    8 
 sw/inc/swscanner.hxx                                         |    4 
 sw/inc/unoflatpara.hxx                                       |    2 
 sw/inc/unotextmarkup.hxx                                     |    7 
 sw/qa/complex/writer/TextPortionEnumerationTest.java         |   32 +
 sw/qa/core/swdoc-test.cxx                                    |    2 
 sw/source/core/doc/docedt.cxx                                |   22 -
 sw/source/core/docnode/node.cxx                              |   40 +-
 sw/source/core/edit/edlingu.cxx                              |   19 -
 sw/source/core/inc/scriptinfo.hxx                            |    5 
 sw/source/core/text/porlay.cxx                               |  198 +++--------
 sw/source/core/txtnode/modeltoviewhelper.cxx                 |   25 -
 sw/source/core/txtnode/ndtxt.cxx                             |  163 +++++++--
 sw/source/core/txtnode/txtedt.cxx                            |   53 +-
 sw/source/core/unocore/unoflatpara.cxx                       |   25 -
 sw/source/core/unocore/unotextmarkup.cxx                     |   29 -
 29 files changed, 439 insertions(+), 315 deletions(-)

New commits:
commit 0c153a22254bf7d83041192037ee7268c40f06f1
Author: Michael Stahl <mstahl at redhat.com>
Date:   Thu Feb 14 19:27:28 2013 +0100

    bnc#796202, fdo#60732: SwTxtNode: limit to less than STRING_LEN chars
    
    It's not a good idea to have STRING_LEN characters in a SwTxtNode
    because then there is no valid SwPosition at the end of the paragraph.
    Also it turns out that LO 3.6 and 4.0 do rather stupid things with a
    full SwTxtNode.  So enforce a limit, at first in the usual places that
    are used during file import, SwTxtNode::InsertText() and
    SwCntntNode::CanJoinPrev()/CanJoinNext().
    
    (cherry picked from commit 549c0f785d4b6d4bc1b39b22827d77d66f48430a)
    
    Conflicts:
    	sw/source/core/docnode/node.cxx
    
    Change-Id: Icb0f44acd20aa81635d42b84d4ae0f9b693a661c
    Reviewed-on: https://gerrit.libreoffice.org/2178
    Reviewed-by: Miklos Vajna <vmiklos at suse.cz>
    Tested-by: Miklos Vajna <vmiklos at suse.cz>

diff --git a/sw/inc/ndtxt.hxx b/sw/inc/ndtxt.hxx
index 39565cf..8f5d31d 100644
--- a/sw/inc/ndtxt.hxx
+++ b/sw/inc/ndtxt.hxx
@@ -79,6 +79,11 @@ namespace com { namespace sun { namespace star {
 
 typedef std::set< xub_StrLen > SwSoftPageBreakList;
 
+// do not fill the String up to the max - need to be able to have a
+// SwPosition "behind" the last character, i.e., at index TXTNODE_MAX + 1
+// (also STRING_LEN is often used for "not found")
+const xub_StrLen TXTNODE_MAX = STRING_LEN - 2;
+
 /// SwTxtNode is a paragraph in the document model.
 class SW_DLLPUBLIC SwTxtNode: public SwCntntNode, public ::sfx2::Metadatable
 {
diff --git a/sw/source/core/docnode/node.cxx b/sw/source/core/docnode/node.cxx
index f795732..a3ce49e 100644
--- a/sw/source/core/docnode/node.cxx
+++ b/sw/source/core/docnode/node.cxx
@@ -1684,12 +1684,26 @@ const SfxPoolItem* SwCntntNode::GetNoCondAttr( sal_uInt16 nWhich,
     return pFnd;
 }
 
-    // koennen 2 Nodes zusammengefasst werden ?
-    // in pIdx kann die 2. Position returnt werden.
+static bool lcl_CheckMaxLength(SwNode const& rPrev, SwNode const& rNext)
+{
+    if (rPrev.GetNodeType() != rNext.GetNodeType())
+    {
+        return false;
+    }
+    if (!rPrev.IsTxtNode())
+    {
+        return true;
+    }
+    size_t const nSum(  static_cast<const SwTxtNode&>(rPrev).GetTxt().Len()
+                      + static_cast<const SwTxtNode&>(rNext).GetTxt().Len());
+    return (nSum <= TXTNODE_MAX);
+}
+
+// Can we join two Nodes?
+// We can return the 2nd position in pIdx.
 int SwCntntNode::CanJoinNext( SwNodeIndex* pIdx ) const
 {
     const SwNodes& rNds = GetNodes();
-    sal_uInt8 nNdType = GetNodeType();
     SwNodeIndex aIdx( *this, 1 );
 
     const SwNode* pNd = this;
@@ -1698,16 +1712,11 @@ int SwCntntNode::CanJoinNext( SwNodeIndex* pIdx ) const
             ( pNd->IsEndNode() && pNd->StartOfSectionNode()->IsSectionNode() )))
         aIdx++;
 
-    if( pNd->GetNodeType() != nNdType || rNds.Count()-1 == aIdx.GetIndex() )
+    if (rNds.Count()-1 == aIdx.GetIndex())
         return sal_False;
-    if( IsTxtNode() )
-    {   // Do not merge strings if the result exceeds the allowed string length
-        const SwTxtNode* pTxtNd = static_cast<const SwTxtNode*>(this);
-        sal_uInt64 nSum = pTxtNd->GetTxt().Len();
-        pTxtNd = static_cast<const SwTxtNode*>(pNd);
-        nSum += pTxtNd->GetTxt().Len();
-        if( nSum > STRING_LEN )
-            return sal_False;
+    if (!lcl_CheckMaxLength(*this, *pNd))
+    {
+        return false;
     }
     if( pIdx )
         *pIdx = aIdx;
@@ -1719,7 +1728,6 @@ int SwCntntNode::CanJoinNext( SwNodeIndex* pIdx ) const
     // in pIdx kann die 2. Position returnt werden.
 int SwCntntNode::CanJoinPrev( SwNodeIndex* pIdx ) const
 {
-    sal_uInt8 nNdType = GetNodeType();
     SwNodeIndex aIdx( *this, -1 );
 
     const SwNode* pNd = this;
@@ -1728,8 +1736,12 @@ int SwCntntNode::CanJoinPrev( SwNodeIndex* pIdx ) const
             ( pNd->IsEndNode() && pNd->StartOfSectionNode()->IsSectionNode() )))
         aIdx--;
 
-    if( pNd->GetNodeType() != nNdType || 0 == aIdx.GetIndex() )
+    if (0 == aIdx.GetIndex())
         return sal_False;
+    if (!lcl_CheckMaxLength(*pNd, *this))
+    {
+        return false;
+    }
     if( pIdx )
         *pIdx = aIdx;
     return sal_True;
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index fc0a192..9e88202 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -1723,7 +1723,11 @@ void SwTxtNode::InsertText( const XubString & rStr, const SwIndex & rIdx,
 
     xub_StrLen aPos = rIdx.GetIndex();
     xub_StrLen nLen = m_Text.Len() - aPos;
-    m_Text.Insert( rStr, aPos );
+    ssize_t const nOverflow(static_cast<ssize_t>(m_Text.Len())
+            + static_cast<ssize_t>(rStr.Len()) - TXTNODE_MAX);
+    m_Text.Insert((nOverflow > 0) ? rStr.Copy(0, rStr.Len() - nOverflow) : rStr,
+            aPos);
+    assert(m_Text.Len() <= TXTNODE_MAX);
     nLen = m_Text.Len() - aPos - nLen;
 
     if ( !nLen ) return;
commit e59c8a2f885ae1166aa29d40b2442d4b447ab01d
Author: Miklos Vajna <vmiklos at suse.cz>
Date:   Thu Apr 18 10:31:03 2013 +0200

    bnc#796202 backport various word-count-related fixes from 4.0
    
    With these, the word-count of the bugdoc no longer hangs.
    
    3442913accc4e44c3a1ac69a990edee15117948e Related: fdo#46757 fix weird word/char count with hidden deleted text
    e88f6ca683a333d927b1e5a63fcae7a88a01ab6b behind (hinter) -> after
    f8f05d43de8728db58c8224c8aebf31ff570b6fc Resolves: fdo49629 GotoEndOfWord fails with footnote at word end
    331e4d03a70900bc390b376f4073d0efd868b919 refactor ModelToViewHelper, should have unchanged results
    b8aa2fa9506967e20fd0db0af30de599f91cf10a warning C4701: potentially uninitialized local variable used
    27c2fe405ca55a2630176a657fb4895c5e31fcea Related: fdo#46757 extend ModelToViewHelper for more cases
    92236c0fc4c8704a72f20a3c2e6f22df3c5ae333 Related: fdo#46757 unsafe to pass expanded text to masking
    561aeedfb7513342bcbb4e76d5f8348a195dc374 Clean up whitespace and remove silly comments
    4ba497818357b000016a16ec041517de57820e9e split CalcHiddenRanges into hidden text and redline deletion handlers
    
    Change-Id: I6a473398f413a55190a5a9f1bc73a50673f5da84

diff --git a/i18npool/qa/cppunit/test_breakiterator.cxx b/i18npool/qa/cppunit/test_breakiterator.cxx
index 3a64c31..22f45ab 100644
--- a/i18npool/qa/cppunit/test_breakiterator.cxx
+++ b/i18npool/qa/cppunit/test_breakiterator.cxx
@@ -126,6 +126,39 @@ void TestBreakIterator::testLineBreaking()
             CPPUNIT_ASSERT_MESSAGE("Expected a break at the the start of the word", aResult.breakIndex == aWord.getLength()+1);
         }
     }
+
+    //See https://bugs.freedesktop.org/show_bug.cgi?id=49629
+    for (int mode = i18n::WordType::ANY_WORD; mode <= i18n::WordType::WORD_COUNT; ++mode)
+    {
+        //make sure that in all cases isBeginWord and isEndWord matches getWordBoundary
+        //
+        //test "Word", then "Word\x01" then "Word\x02"
+        for (sal_Unicode i = 0; i < 3; ++i)
+        {
+            ::rtl::OUString aTest("Word");
+            if (i > 0)
+                aTest += rtl::OUString(i) + rtl::OUString("Word");
+            i18n::Boundary aBounds = m_xBreak->getWordBoundary(aTest, 0, aLocale, mode, true);
+            switch (mode)
+            {
+                case i18n::WordType::ANY_WORD:
+                    CPPUNIT_ASSERT(aBounds.startPos == 0 && aBounds.endPos == 4);
+                    break;
+                case i18n::WordType::ANYWORD_IGNOREWHITESPACES:
+                    CPPUNIT_ASSERT(aBounds.startPos == 0 && aBounds.endPos == 4);
+                    break;
+                case i18n::WordType::DICTIONARY_WORD:
+                    CPPUNIT_ASSERT(aBounds.startPos == 0 && aBounds.endPos == 4);
+                    break;
+                case i18n::WordType::WORD_COUNT:
+                    CPPUNIT_ASSERT(aBounds.startPos == 0 && aBounds.endPos == 4);
+                    break;
+            }
+
+            CPPUNIT_ASSERT(m_xBreak->isBeginWord(aTest, aBounds.startPos, aLocale, mode));
+            CPPUNIT_ASSERT(m_xBreak->isEndWord(aTest, aBounds.endPos, aLocale, mode));
+        }
+    }
 }
 
 //See http://qa.openoffice.org/issues/show_bug.cgi?id=111152
diff --git a/i18npool/source/breakiterator/data/dict_word.txt b/i18npool/source/breakiterator/data/dict_word.txt
index f69f038..b1666f4 100644
--- a/i18npool/source/breakiterator/data/dict_word.txt
+++ b/i18npool/source/breakiterator/data/dict_word.txt
@@ -24,7 +24,7 @@ $Katakana  = [[:Script = KATAKANA:] [:name = KATAKANA-HIRAGANA PROLONGED SOUND M
 $Ideographic = [:Ideographic:];
 $Hangul = [:Script = HANGUL:];
 
-$ALetter   = [\u0002 [:Alphabetic:] [:name= COMMERCIAL AT:] [:name= HEBREW PUNCTUATION GERESH:]
+$ALetter   = [[:Alphabetic:] [:name= COMMERCIAL AT:] [:name= HEBREW PUNCTUATION GERESH:]
                            - $Ideographic
                            - $Katakana
                            - $Hangul
diff --git a/i18npool/source/breakiterator/data/dict_word_ca.txt b/i18npool/source/breakiterator/data/dict_word_ca.txt
index ca4a14a..6ad6a0b 100644
--- a/i18npool/source/breakiterator/data/dict_word_ca.txt
+++ b/i18npool/source/breakiterator/data/dict_word_ca.txt
@@ -22,7 +22,7 @@ $Katakana  = [[:Script = KATAKANA:] [:name = KATAKANA-HIRAGANA PROLONGED SOUND M
                                    [:name = HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK:]];
 
 
-$ALetter   = [\u0002 [:Alphabetic:] [:name= COMMERCIAL AT:] [:name= HEBREW PUNCTUATION GERESH:]
+$ALetter   = [[:Alphabetic:] [:name= COMMERCIAL AT:] [:name= HEBREW PUNCTUATION GERESH:]
                            - $Katakana
                            - [:Script = Thai:]
                            - [:Script = Lao:]
diff --git a/i18npool/source/breakiterator/data/dict_word_fi.txt b/i18npool/source/breakiterator/data/dict_word_fi.txt
index 2d76179..7026c99 100644
--- a/i18npool/source/breakiterator/data/dict_word_fi.txt
+++ b/i18npool/source/breakiterator/data/dict_word_fi.txt
@@ -24,7 +24,7 @@ $Katakana  = [[:Script = KATAKANA:] [:name = KATAKANA-HIRAGANA PROLONGED SOUND M
 $Ideographic = [:Ideographic:];
 $Hangul = [:Script = HANGUL:];
 
-$ALetter   = [\u0002 [:Alphabetic:] [:name= COMMERCIAL AT:] [:name= HEBREW PUNCTUATION GERESH:] [:name = HYPHEN-MINUS:]
+$ALetter   = [[:Alphabetic:] [:name= COMMERCIAL AT:] [:name= HEBREW PUNCTUATION GERESH:] [:name = HYPHEN-MINUS:]
                            - $Ideographic
                            - $Katakana
                            - $Hangul
diff --git a/i18npool/source/breakiterator/data/dict_word_he.txt b/i18npool/source/breakiterator/data/dict_word_he.txt
index b98350e..40197d9 100644
--- a/i18npool/source/breakiterator/data/dict_word_he.txt
+++ b/i18npool/source/breakiterator/data/dict_word_he.txt
@@ -22,7 +22,7 @@ $Katakana  = [[:Script = KATAKANA:] [:name = KATAKANA-HIRAGANA PROLONGED SOUND M
                                    [:name = HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK:]];
 
 
-$ALetter   = [\u0002 [:Alphabetic:] [:name= COMMERCIAL AT:] [:name= HEBREW PUNCTUATION GERESH:]
+$ALetter   = [[:Alphabetic:] [:name= COMMERCIAL AT:] [:name= HEBREW PUNCTUATION GERESH:]
                            - $Katakana
                            - [:Script = Thai:]
                            - [:Script = Lao:]
diff --git a/i18npool/source/breakiterator/data/dict_word_hu.txt b/i18npool/source/breakiterator/data/dict_word_hu.txt
index 49ae8b5..33d014e 100644
--- a/i18npool/source/breakiterator/data/dict_word_hu.txt
+++ b/i18npool/source/breakiterator/data/dict_word_hu.txt
@@ -24,7 +24,7 @@ $Katakana  = [[:Script = KATAKANA:] [:name = KATAKANA-HIRAGANA PROLONGED SOUND M
 $Ideographic = [:Ideographic:];
 $Hangul = [:Script = HANGUL:];
 
-$ALetter   = [\u0002 [:Alphabetic:] [:name= COMMERCIAL AT:] [:name= HEBREW PUNCTUATION GERESH:]
+$ALetter   = [[:Alphabetic:] [:name= COMMERCIAL AT:] [:name= HEBREW PUNCTUATION GERESH:]
                 [:name = PERCENT SIGN:] [:name = PER MILLE SIGN:] [:name = PER TEN THOUSAND SIGN:]
                 [:name = SECTION SIGN:] [:name = DEGREE SIGN:] [:name = EURO SIGN:]
                 [:name = HYPHEN-MINUS:] [:name = EN DASH:] [:name = EM DASH:]
diff --git a/i18npool/source/breakiterator/data/dict_word_nodash.txt b/i18npool/source/breakiterator/data/dict_word_nodash.txt
index 4c5c808..279cc50 100644
--- a/i18npool/source/breakiterator/data/dict_word_nodash.txt
+++ b/i18npool/source/breakiterator/data/dict_word_nodash.txt
@@ -24,7 +24,7 @@ $Katakana  = [[:Script = KATAKANA:] [:name = KATAKANA-HIRAGANA PROLONGED SOUND M
 $Ideographic = [:Ideographic:];
 $Hangul = [:Script = HANGUL:];
 
-$ALetter   = [\u0002 [:Alphabetic:] [:name= COMMERCIAL AT:] [:name= HEBREW PUNCTUATION GERESH:]
+$ALetter   = [[:Alphabetic:] [:name= COMMERCIAL AT:] [:name= HEBREW PUNCTUATION GERESH:]
                            - $Ideographic
                            - $Katakana
                            - $Hangul
diff --git a/i18npool/source/breakiterator/data/dict_word_prepostdash.txt b/i18npool/source/breakiterator/data/dict_word_prepostdash.txt
index 0a60cc5..fb29b47 100644
--- a/i18npool/source/breakiterator/data/dict_word_prepostdash.txt
+++ b/i18npool/source/breakiterator/data/dict_word_prepostdash.txt
@@ -30,7 +30,7 @@ $Hangul = [:Script = HANGUL:];
 $PrePostDashHyphen = [ [:name = HYPHEN-MINUS:] ];
 
 
-$ALetter   = [\u0002 [:Alphabetic:] [:name= COMMERCIAL AT:] [:name= HEBREW PUNCTUATION GERESH:]
+$ALetter   = [[:Alphabetic:] [:name= COMMERCIAL AT:] [:name= HEBREW PUNCTUATION GERESH:]
                            - $Ideographic
                            - $Katakana
                            - $Hangul
diff --git a/i18npool/source/breakiterator/data/edit_word.txt b/i18npool/source/breakiterator/data/edit_word.txt
index ff83212..92b344c 100644
--- a/i18npool/source/breakiterator/data/edit_word.txt
+++ b/i18npool/source/breakiterator/data/edit_word.txt
@@ -24,7 +24,7 @@ $Katakana  = [[:Script = KATAKANA:] [:name = KATAKANA-HIRAGANA PROLONGED SOUND M
 $Ideographic = [:Ideographic:];
 $Hangul = [:Script = HANGUL:];
 
-$ALetter   = [\u0002 [:Alphabetic:] [:name= NO-BREAK SPACE:] [:name= HEBREW PUNCTUATION GERESH:] 
+$ALetter   = [[:Alphabetic:] [:name= NO-BREAK SPACE:] [:name= HEBREW PUNCTUATION GERESH:] 
                            - $Ideographic
                            - $Katakana
                            - $Hangul
diff --git a/i18npool/source/breakiterator/data/edit_word_he.txt b/i18npool/source/breakiterator/data/edit_word_he.txt
index 0061f55..0b59088 100644
--- a/i18npool/source/breakiterator/data/edit_word_he.txt
+++ b/i18npool/source/breakiterator/data/edit_word_he.txt
@@ -24,7 +24,7 @@ $Katakana  = [[:Script = KATAKANA:] [:name = KATAKANA-HIRAGANA PROLONGED SOUND M
 $Ideographic = [:Ideographic:];
 $Hangul = [:Script = HANGUL:];
 
-$ALetter   = [\u0002 [:Alphabetic:] [:name= NO-BREAK SPACE:] [:name= HEBREW PUNCTUATION GERESH:] 
+$ALetter   = [[:Alphabetic:] [:name= NO-BREAK SPACE:] [:name= HEBREW PUNCTUATION GERESH:] 
                            - $Ideographic
                            - $Katakana
                            - $Hangul
diff --git a/i18npool/source/breakiterator/data/edit_word_hu.txt b/i18npool/source/breakiterator/data/edit_word_hu.txt
index 5262726..4a08aca 100644
--- a/i18npool/source/breakiterator/data/edit_word_hu.txt
+++ b/i18npool/source/breakiterator/data/edit_word_hu.txt
@@ -24,7 +24,7 @@ $Katakana  = [[:Script = KATAKANA:] [:name = KATAKANA-HIRAGANA PROLONGED SOUND M
 $Ideographic = [:Ideographic:];
 $Hangul = [:Script = HANGUL:];
 
-$ALetter   = [\u0002 [:Alphabetic:] [:name= NO-BREAK SPACE:] [:name= HEBREW PUNCTUATION GERESH:] 
+$ALetter   = [[:Alphabetic:] [:name= NO-BREAK SPACE:] [:name= HEBREW PUNCTUATION GERESH:] 
                 [:name = PERCENT SIGN:] [:name = PER MILLE SIGN:] [:name = PER TEN THOUSAND SIGN:]
                 [:name = SECTION SIGN:] [:name = DEGREE SIGN:] [:name = EURO SIGN:]
                 [:name = HYPHEN-MINUS:] [:name = EN DASH:] [:name = EM DASH:]
diff --git a/sw/CppunitTest_sw_swdoc_test.mk b/sw/CppunitTest_sw_swdoc_test.mk
index 94ebab3..b3ab7d72 100644
--- a/sw/CppunitTest_sw_swdoc_test.mk
+++ b/sw/CppunitTest_sw_swdoc_test.mk
@@ -77,6 +77,7 @@ $(eval $(call gb_CppunitTest_use_externals,sw_swdoc_test,\
 
 $(eval $(call gb_CppunitTest_set_include,sw_swdoc_test,\
     -I$(SRCDIR)/sw/source/ui/inc \
+    -I$(SRCDIR)/sw/source/core/inc \
     -I$(SRCDIR)/sw/inc \
     $$(INCLUDE) \
 ))
diff --git a/sw/inc/modeltoviewhelper.hxx b/sw/inc/modeltoviewhelper.hxx
index cf09567..c37e14b 100644
--- a/sw/inc/modeltoviewhelper.hxx
+++ b/sw/inc/modeltoviewhelper.hxx
@@ -29,10 +29,12 @@
 #ifndef _MODELTOVIEWHELPER_HXX
 #define _MODELTOVIEWHELPER_HXX
 
+#include <rtl/ustring.hxx>
 #include <sal/types.h>
-
 #include <vector>
 
+class SwTxtNode;
+
 /** Some helpers for converting model strings to view strings.
 
     A paragraph string does not have its fields expanded, i.e., they are
@@ -41,8 +43,39 @@
     to expand the fields to get the string as it appears in the view. Two
     helper functions are provided to convert model positions to view positions
     and vice versa.
+
+           CH_TXTATR_BREAKWORD -> SwTxtNode will have field attributes associated with these
+                .       .
+                .       .
+                .       .
+    AAAAA BBBBB # CCCCC # DDDDD
+        | |  |    |
+        | |  |    |
+        | ---------
+        |    |  .
+        |    |  .
+        |    |  .......... bounds of a hidden text character attribute
+        ------
+           .
+           .
+           .............. a range of text defined in redline region as deleted
+
+    0000: pass through gives:                                        AAAAA BBBBB # CCCCC # DDDDD
+    0001: only expanding fields gives:                               AAAAA BBBBB foo CCCCC foo DDDDD
+    0010: only hiding hiddens gives:                                 AAAAA CCCCC # DDDDD
+    0100: only hiding redlines gives:                                AAAABB # CCCCC # DDDDD
+    0011: expanding fields + hiding hiddens gives:                   AAAAA CCCC foo DDDDD
+    0101: expanding fields + hiding redlines gives:                  AAAA B foo CCCCC foo DDDDD
+    0110: hiding hiddens + hiding redlines gives:                    AAAACCCC # DDDDD
+    0111: expanding fields + hiding hiddens + hiding redlines gives: AAAABB foo CCCCC foo DDDDD
 */
-namespace ModelToViewHelper
+
+#define PASSTHROUGH   0x0000
+#define EXPANDFIELDS  0x0001
+#define HIDEINVISIBLE 0x0002
+#define HIDEREDLINED  0x0004
+
+class ModelToViewHelper
 {
     /** For each field in the model string, there is an entry in the conversion
         map. The first value of the ConversionMapEntry points to the field
@@ -53,6 +86,12 @@ namespace ModelToViewHelper
     typedef std::pair< sal_uInt32 , sal_uInt32 > ConversionMapEntry;
     typedef std::vector< ConversionMapEntry > ConversionMap;
 
+    ConversionMap m_aMap;
+
+    rtl::OUString m_aRetText;
+
+public:
+
     /** This struct defines a position in the model string.
 
         The 'main' position is given by mnPos. If there's a field located at
@@ -68,12 +107,12 @@ namespace ModelToViewHelper
         ModelPosition() : mnPos(0), mnSubPos(0), mbIsField(false) {}
     };
 
-    /** Converts a model position into a view position
+    ModelToViewHelper(const SwTxtNode &rNode, int eMode = EXPANDFIELDS);
+    ModelToViewHelper() //pass through filter, view == model
+    {
+    }
 
-        @param pMap
-            pMap is the conversion map required for the calculation. If pMap is
-            0, no conversion takes place, i.e., it is assumed that the model
-            string is identical to the view string.
+    /** Converts a model position into a view position
 
         @param nPos
             nPos denotes a position in the model string which should be
@@ -86,15 +125,10 @@ namespace ModelToViewHelper
             nPos is behind the last entry in the conversion map) nPos will
             be returned.
     */
-    sal_uInt32 ConvertToViewPosition( const ConversionMap* pMap, sal_uInt32 nModelPos );
+    sal_uInt32 ConvertToViewPosition( sal_uInt32 nModelPos ) const;
 
     /** Converts a view position into a model position
 
-        @param pMap
-            pMap is the conversion map required for the calculation. If pMap is
-            0, no conversion takes place, i.e., it is assumed that the model
-            string is identical to the view string.
-
         @param nPos
             nPos denotes a position in the view string which should be
             converted.
@@ -106,8 +140,10 @@ namespace ModelToViewHelper
             model position with mnPos = nPos and mnIsField = false will be
             returned.
     */
-    ModelPosition ConvertToModelPosition( const ConversionMap* pMap, sal_uInt32 nViewPos );
-}
+    ModelPosition ConvertToModelPosition( sal_uInt32 nViewPos ) const;
+
+    rtl::OUString getViewText() const { return m_aRetText; }
+};
 
 #endif
 
diff --git a/sw/inc/ndtxt.hxx b/sw/inc/ndtxt.hxx
index 83b3e2f..39565cf 100644
--- a/sw/inc/ndtxt.hxx
+++ b/sw/inc/ndtxt.hxx
@@ -699,9 +699,6 @@ public:
                        sal_Bool bWithNum = sal_False, sal_Bool bWithFtn = sal_True,
                        sal_Bool bReplaceTabsWithSpaces = sal_False ) const;
 
-    const ModelToViewHelper::ConversionMap*
-            BuildConversionMap( rtl::OUString& rExpandText ) const;
-
     XubString GetRedlineTxt( xub_StrLen nIdx = 0,
                           xub_StrLen nLen = STRING_LEN,
                           sal_Bool bExpandFlds = sal_False,
diff --git a/sw/inc/swscanner.hxx b/sw/inc/swscanner.hxx
index 3c05995..f657f23 100644
--- a/sw/inc/swscanner.hxx
+++ b/sw/inc/swscanner.hxx
@@ -45,7 +45,7 @@ class SwScanner
     const SwTxtNode& rNode;
     const rtl::OUString aText;
     const LanguageType* pLanguage;
-    const ModelToViewHelper::ConversionMap* pConversionMap;
+    const ModelToViewHelper& rConversionMap;
     sal_Int32 nStartPos;
     sal_Int32 nEndPos;
     sal_Int32 nBegin;
@@ -57,7 +57,7 @@ class SwScanner
 public:
     SwScanner( const SwTxtNode& rNd, const rtl::OUString& rTxt,
                const LanguageType* pLang,
-               const ModelToViewHelper::ConversionMap* pConvMap,
+               const ModelToViewHelper& rConvMap,
                sal_uInt16 nWordType,
                sal_Int32 nStart, sal_Int32 nEnde, sal_Bool bClip = sal_False );
 
diff --git a/sw/inc/unoflatpara.hxx b/sw/inc/unoflatpara.hxx
index 2ab3e59..0945b3f 100644
--- a/sw/inc/unoflatpara.hxx
+++ b/sw/inc/unoflatpara.hxx
@@ -61,7 +61,7 @@ class SwXFlatParagraph:
     public SwXTextMarkup
 {
 public:
-    SwXFlatParagraph( SwTxtNode& rTxtNode, rtl::OUString aExpandText, const ModelToViewHelper::ConversionMap* pConversionMap );
+    SwXFlatParagraph( SwTxtNode& rTxtNode, rtl::OUString aExpandText, const ModelToViewHelper& rConversionMap );
     virtual ~SwXFlatParagraph();
 
     virtual     ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& aType ) throw(::com::sun::star::uno::RuntimeException);
diff --git a/sw/inc/unotextmarkup.hxx b/sw/inc/unotextmarkup.hxx
index b682a97..2ae333f 100644
--- a/sw/inc/unotextmarkup.hxx
+++ b/sw/inc/unotextmarkup.hxx
@@ -56,7 +56,7 @@ class SwXTextMarkup:
     public SwClient
 {
 public:
-    SwXTextMarkup( SwTxtNode& rTxtNode, const ModelToViewHelper::ConversionMap* pConversionMap );
+    SwXTextMarkup( SwTxtNode& rTxtNode, const ModelToViewHelper& rConversionMap );
     virtual ~SwXTextMarkup();
 
     // ::com::sun::star::text::XTextMarkup:
@@ -72,11 +72,10 @@ private:
 
 protected:
     //SwClient
-   virtual void Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew);
+    virtual void Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew);
 
     SwTxtNode* mpTxtNode;
-    const ModelToViewHelper::ConversionMap* mpConversionMap;
-
+    const ModelToViewHelper maConversionMap;
 };
 
 
diff --git a/sw/qa/complex/writer/TextPortionEnumerationTest.java b/sw/qa/complex/writer/TextPortionEnumerationTest.java
index 114359b..bd996fd 100644
--- a/sw/qa/complex/writer/TextPortionEnumerationTest.java
+++ b/sw/qa/complex/writer/TextPortionEnumerationTest.java
@@ -3259,26 +3259,31 @@ public class TextPortionEnumerationTest
         XWordCursor xWordCursor = (XWordCursor)
             UnoRuntime.queryInterface(XWordCursor.class, xTextCursor);
 
-        bSuccess = xWordCursor.gotoNextWord(true);
+        bSuccess = xWordCursor.gotoNextWord(true);              //at start of "words"
         assertTrue("gotoNextWord(): failed", bSuccess);
         {
             String string = xTextCursor.getString();
             assertEquals("gotoNextWord(): wrong string",
                          "Two ", string);
         }
-        bSuccess = xWordCursor.gotoNextWord(false);
+        bSuccess = xWordCursor.gotoNextWord(false);             //at end of "words", cannot leave metafield
         assertFalse("gotoNextWord(): succeeded", bSuccess);
         xTextCursor.collapseToEnd();
-        bSuccess = xWordCursor.gotoPreviousWord(true);
+        bSuccess = xWordCursor.gotoPreviousWord(true);          //at start of "words"
         assertTrue("gotoPreviousWord(): failed", bSuccess);
         {
             String string = xTextCursor.getString();
             assertEquals("gotoPreviousWord(): wrong string",
                          "words", string);
         }
-        bSuccess = xWordCursor.gotoPreviousWord(false);
+        bSuccess = xWordCursor.gotoPreviousWord(false);         //at start of "Two"
+        assertTrue("gotoPreviousWord(): failed", bSuccess);
+
+
+        bSuccess = xWordCursor.gotoPreviousWord(false);         //cannot leave metafield
         assertFalse("gotoPreviousWord(): succeeded", bSuccess);
-        bSuccess = xWordCursor.gotoEndOfWord(true);
+
+        bSuccess = xWordCursor.gotoEndOfWord(true);             //at end of "Two"
         assertTrue("gotoEndOfWord(): failed", bSuccess);
         {
             String string = xTextCursor.getString();
@@ -3362,6 +3367,23 @@ public class TextPortionEnumerationTest
         assertFalse("gotoEndOfParagraph(): succeeded", bSuccess);
     }
 
+    /** See https://bugs.freedesktop.org/show_bug.cgi?id=49629
+        ensure that gotoEndOfWord does not fail when footnote is at word end*/
+    @Test public void testXTextCursor() throws Exception
+    {
+        RangeInserter inserter = new RangeInserter(m_xDoc);
+        XText xDocText = m_xDoc.getText();
+        XTextCursor xDocTextCursor = xDocText.createTextCursor();
+        inserter.insertText(xDocTextCursor, "Text");
+        XWordCursor xWordCursor = UnoRuntime.queryInterface(XWordCursor.class, xDocTextCursor);
+        xWordCursor.gotoEndOfWord(false);
+        inserter.insertFootnote(xDocTextCursor, "footnote");
+        xDocTextCursor.gotoStart(false);
+        boolean bSuccess = xWordCursor.gotoEndOfWord(true);
+        assertTrue("gotoEndOfWord(): failed", bSuccess);
+        String string = xWordCursor.getString();
+        assertEquals("gotoEndOfWord(): wrong string", "Text", string);
+    }
 
     abstract class AttachHelper
     {
diff --git a/sw/qa/core/swdoc-test.cxx b/sw/qa/core/swdoc-test.cxx
index f19e9e5..1ad4d25 100644
--- a/sw/qa/core/swdoc-test.cxx
+++ b/sw/qa/core/swdoc-test.cxx
@@ -233,7 +233,7 @@ void SwDocTest::testSwScanner()
     {
         SwScanner aScanner(*pTxtNode,
             rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Hello World")),
-            0, 0, i18n::WordType::DICTIONARY_WORD, 0,
+            0, ModelToViewHelper(), i18n::WordType::DICTIONARY_WORD, 0,
             RTL_CONSTASCII_LENGTH("Hello World"));
 
         bool bFirstOk = aScanner.NextWord();
diff --git a/sw/source/core/doc/docedt.cxx b/sw/source/core/doc/docedt.cxx
index c805779..d32a4ba 100644
--- a/sw/source/core/doc/docedt.cxx
+++ b/sw/source/core/doc/docedt.cxx
@@ -1804,7 +1804,7 @@ bool SwDoc::DeleteRange( SwPaM & rPam )
 
 
 void lcl_syncGrammarError( SwTxtNode &rTxtNode, linguistic2::ProofreadingResult& rResult,
-    xub_StrLen /*nBeginGrammarCheck*/, const ModelToViewHelper::ConversionMap* pConversionMap )
+    xub_StrLen /*nBeginGrammarCheck*/, const ModelToViewHelper &rConversionMap )
 {
     if( rTxtNode.IsGrammarCheckDirty() )
         return;
@@ -1816,8 +1816,8 @@ void lcl_syncGrammarError( SwTxtNode &rTxtNode, linguistic2::ProofreadingResult&
         for( i = 0; i < rResult.aErrors.getLength(); ++i )
         {
             const linguistic2::SingleProofreadingError &rError = rResult.aErrors[i];
-            xub_StrLen nStart = (xub_StrLen)ModelToViewHelper::ConvertToModelPosition( pConversionMap, rError.nErrorStart ).mnPos;
-            xub_StrLen nEnd = (xub_StrLen)ModelToViewHelper::ConvertToModelPosition( pConversionMap, rError.nErrorStart + rError.nErrorLength ).mnPos;
+            xub_StrLen nStart = (xub_StrLen)rConversionMap.ConvertToModelPosition( rError.nErrorStart ).mnPos;
+            xub_StrLen nEnd = (xub_StrLen)rConversionMap.ConvertToModelPosition( rError.nErrorStart + rError.nErrorLength ).mnPos;
             if( i != j )
                 pArray[j] = pArray[i];
             if( pWrong->LookForEntry( nStart, nEnd ) )
@@ -1935,22 +1935,22 @@ uno::Any SwDoc::Spell( SwPaM& rPaM,
                                 String aText( ((SwTxtNode*)pNd)->GetTxt().Copy( nBeginGrammarCheck, nEndGrammarCheck - nBeginGrammarCheck ) );
                                 uno::Reference< lang::XComponent > xDoc( ((SwDocShell*)GetDocShell())->GetBaseModel(), uno::UNO_QUERY );
                                 // Expand the string:
-                                rtl::OUString aExpandText;
-                                const ModelToViewHelper::ConversionMap* pConversionMap =
-                                        ((SwTxtNode*)pNd)->BuildConversionMap( aExpandText );
+                                const ModelToViewHelper aConversionMap(*(SwTxtNode*)pNd);
+                                rtl::OUString aExpandText = aConversionMap.getViewText();
+
                                 // get XFlatParagraph to use...
-                                uno::Reference< text::XFlatParagraph > xFlatPara = new SwXFlatParagraph( *((SwTxtNode*)pNd), aExpandText, pConversionMap );
+                                uno::Reference< text::XFlatParagraph > xFlatPara = new SwXFlatParagraph( *((SwTxtNode*)pNd), aExpandText, aConversionMap );
 
                                 // get error position of cursor in XFlatParagraph
                                 linguistic2::ProofreadingResult aResult;
                                 sal_Int32 nGrammarErrors;
                                 do
                                 {
-                                    ModelToViewHelper::ConvertToViewPosition( pConversionMap, nBeginGrammarCheck );
+                                    aConversionMap.ConvertToViewPosition( nBeginGrammarCheck );
                                     aResult = xGCIterator->checkSentenceAtPosition(
                                             xDoc, xFlatPara, aExpandText, lang::Locale(), nBeginGrammarCheck, -1, -1 );
 
-                                    lcl_syncGrammarError( *((SwTxtNode*)pNd), aResult, nBeginGrammarCheck, pConversionMap );
+                                    lcl_syncGrammarError( *((SwTxtNode*)pNd), aResult, nBeginGrammarCheck, aConversionMap );
 
                                     // get suggestions to use for the specific error position
                                     nGrammarErrors = aResult.aErrors.getLength();
@@ -1972,8 +1972,8 @@ uno::Any SwDoc::Spell( SwPaM& rPaM,
                                     pEndPos->nNode = nCurrNd;
                                     pSpellArgs->pStartNode = ((SwTxtNode*)pNd);
                                     pSpellArgs->pEndNode = ((SwTxtNode*)pNd);
-                                    pSpellArgs->pStartIdx->Assign(((SwTxtNode*)pNd), (xub_StrLen)ModelToViewHelper::ConvertToModelPosition( pConversionMap, rError.nErrorStart ).mnPos );
-                                    pSpellArgs->pEndIdx->Assign(((SwTxtNode*)pNd), (xub_StrLen)ModelToViewHelper::ConvertToModelPosition( pConversionMap, rError.nErrorStart + rError.nErrorLength ).mnPos );
+                                    pSpellArgs->pStartIdx->Assign(((SwTxtNode*)pNd), (xub_StrLen)aConversionMap.ConvertToModelPosition( rError.nErrorStart ).mnPos );
+                                    pSpellArgs->pEndIdx->Assign(((SwTxtNode*)pNd), (xub_StrLen)aConversionMap.ConvertToModelPosition( rError.nErrorStart + rError.nErrorLength ).mnPos );
                                     nCurrNd = nEndNd;
                                 }
                             }
diff --git a/sw/source/core/edit/edlingu.cxx b/sw/source/core/edit/edlingu.cxx
index e95f967..d72fbf1 100644
--- a/sw/source/core/edit/edlingu.cxx
+++ b/sw/source/core/edit/edlingu.cxx
@@ -1132,17 +1132,16 @@ bool SwEditShell::GetGrammarCorrection(
                 uno::Reference< lang::XComponent > xDoc( pDoc->GetDocShell()->GetBaseModel(), uno::UNO_QUERY );
 
                 // Expand the string:
-                rtl::OUString aExpandText;
-                const ModelToViewHelper::ConversionMap* pConversionMap =
-                        pNode->BuildConversionMap( aExpandText );
+                const ModelToViewHelper aConversionMap(*pNode);
+                rtl::OUString aExpandText = aConversionMap.getViewText();
                 // get XFlatParagraph to use...
-                uno::Reference< text::XFlatParagraph > xFlatPara = new SwXFlatParagraph( *pNode, aExpandText, pConversionMap );
+                uno::Reference< text::XFlatParagraph > xFlatPara = new SwXFlatParagraph( *pNode, aExpandText, aConversionMap );
 
                 // get error position of cursor in XFlatParagraph
-                rErrorPosInText = ModelToViewHelper::ConvertToViewPosition( pConversionMap, nBegin );
+                rErrorPosInText = aConversionMap.ConvertToViewPosition( nBegin );
 
-                sal_Int32 nStartOfSentence = ModelToViewHelper::ConvertToViewPosition( pConversionMap, pWrong->getSentenceStart( nBegin ) );
-                sal_Int32 nEndOfSentence = ModelToViewHelper::ConvertToViewPosition( pConversionMap, pWrong->getSentenceEnd( nBegin ) );
+                sal_Int32 nStartOfSentence = aConversionMap.ConvertToViewPosition( pWrong->getSentenceStart( nBegin ) );
+                sal_Int32 nEndOfSentence = aConversionMap.ConvertToViewPosition( pWrong->getSentenceEnd( nBegin ) );
                 if( nEndOfSentence == STRING_LEN )
                 {
                         nEndOfSentence = aExpandText.getLength();
@@ -1603,9 +1602,9 @@ bool SwSpellIter::SpellSentence(::svx::SpellPortions& rPortions, bool bIsGrammar
         pMySh->GoEndSentence();
         if( bGrammarErrorFound )
         {
-            rtl::OUString aExpandText;
-            const ModelToViewHelper::ConversionMap* pConversionMap = ((SwTxtNode*)pCrsr->GetNode())->BuildConversionMap( aExpandText );
-            xub_StrLen nSentenceEnd = (xub_StrLen)ModelToViewHelper::ConvertToViewPosition( pConversionMap, aGrammarResult.nBehindEndOfSentencePosition );
+            const ModelToViewHelper aConversionMap(*(SwTxtNode*)pCrsr->GetNode());
+            rtl::OUString aExpandText = aConversionMap.getViewText();
+            xub_StrLen nSentenceEnd = (xub_StrLen)aConversionMap.ConvertToViewPosition( aGrammarResult.nBehindEndOfSentencePosition );
             // remove trailing space
             if( aExpandText[nSentenceEnd - 1] == ' ' )
                 --nSentenceEnd;
diff --git a/sw/source/core/inc/scriptinfo.hxx b/sw/source/core/inc/scriptinfo.hxx
index b58dbb2..01e5345 100644
--- a/sw/source/core/inc/scriptinfo.hxx
+++ b/sw/source/core/inc/scriptinfo.hxx
@@ -128,8 +128,9 @@ public:
 
     inline size_t CountHiddenChg() const;
     inline xub_StrLen GetHiddenChg( const size_t nCnt ) const;
-    static void CalcHiddenRanges( const SwTxtNode& rNode,
-                                                MultiSelection& rHiddenMulti );
+    static void CalcHiddenRanges(const SwTxtNode& rNode, MultiSelection& rHiddenMulti);
+    static void selectHiddenTextProperty(const SwTxtNode& rNode, MultiSelection &rHiddenMulti);
+    static void selectRedLineDeleted(const SwTxtNode& rNode, MultiSelection &rHiddenMulti, bool bSelect=true);
 
     // "high" level operations, nPos refers to string position
     xub_StrLen NextScriptChg( const xub_StrLen nPos ) const;
diff --git a/sw/source/core/text/porlay.cxx b/sw/source/core/text/porlay.cxx
index 8589becf..97da02e 100644
--- a/sw/source/core/text/porlay.cxx
+++ b/sw/source/core/text/porlay.cxx
@@ -34,8 +34,8 @@
 #include "blink.hxx"    // pBlink
 #include "redlnitr.hxx" // SwRedlineItr
 #include "porfly.hxx"   // SwFlyCntPortion
-#include <porrst.hxx>       // SwHangingPortion
-#include <pormulti.hxx>     // SwMultiPortion
+#include <porrst.hxx>   // SwHangingPortion
+#include <pormulti.hxx> // SwMultiPortion
 #include <breakit.hxx>
 #include <unicode/uchar.h>
 #include <com/sun/star/i18n/ScriptType.hdl>
@@ -52,8 +52,8 @@
 #include <i18npool/mslangid.hxx>
 #include <charfmt.hxx>
 #include <fchrfmt.hxx>
-#include <docary.hxx>       // SwRedlineTbl
-#include <redline.hxx>      // SwRedline
+#include <docary.hxx>   // SwRedlineTbl
+#include <redline.hxx>  // SwRedline
 #include <section.hxx>
 #include <switerator.hxx>
 #include <IDocumentRedlineAccess.hxx>
@@ -94,7 +94,7 @@ sal_Bool isTransparentChar ( xub_Unicode cCh )
 }
 
 /*************************************************************************
- *                 lcl_IsLigature
+ * lcl_IsLigature
  *
  * Checks if cCh + cNectCh builds a ligature (used for Kashidas)
  *************************************************************************/
@@ -106,7 +106,7 @@ sal_Bool lcl_IsLigature( xub_Unicode cCh, xub_Unicode cNextCh )
 }
 
 /*************************************************************************
- *                 lcl_ConnectToPrev
+ * lcl_ConnectToPrev
  *
  * Checks if cCh is connectable to cPrevCh (used for Kashidas)
  *************************************************************************/
@@ -124,7 +124,7 @@ sal_Bool lcl_ConnectToPrev( xub_Unicode cCh, xub_Unicode cPrevCh )
 }
 
 /*************************************************************************
- *                 lcl_HasStrongLTR
+ * lcl_HasStrongLTR
  *************************************************************************/
  bool lcl_HasStrongLTR ( const String& rTxt, xub_StrLen nStart, xub_StrLen nEnd )
  {
@@ -140,7 +140,7 @@ sal_Bool lcl_ConnectToPrev( xub_Unicode cCh, xub_Unicode cPrevCh )
  }
 
 /*************************************************************************
- *                 SwLineLayout::~SwLineLayout()
+ * SwLineLayout::~SwLineLayout()
  *
  * class SwLineLayout: Das Layout einer einzelnen Zeile. Dazu
  * gehoeren vor allen Dingen die Dimension, die Anzahl der
@@ -161,10 +161,6 @@ SwLineLayout::~SwLineLayout()
     delete pKanaComp;
 }
 
-/*************************************************************************
- *                virtual SwLineLayout::Insert()
- *************************************************************************/
-
 SwLinePortion *SwLineLayout::Insert( SwLinePortion *pIns )
 {
     // Erster Attributwechsel, Masse und Laengen
@@ -190,10 +186,6 @@ SwLinePortion *SwLineLayout::Insert( SwLinePortion *pIns )
     return pPortion->SwLinePortion::Insert( pIns );
 }
 
-/*************************************************************************
- *                virtual SwLineLayout::Append()
- *************************************************************************/
-
 SwLinePortion *SwLineLayout::Append( SwLinePortion *pIns )
 {
     // Erster Attributwechsel, Masse und Laengen
@@ -204,10 +196,6 @@ SwLinePortion *SwLineLayout::Append( SwLinePortion *pIns )
     return pPortion->SwLinePortion::Append( pIns );
 }
 
-/*************************************************************************
- *                virtual SwLineLayout::Format()
- *************************************************************************/
-
 // fuer die Sonderbehandlung bei leeren Zeilen
 
 sal_Bool SwLineLayout::Format( SwTxtFormatInfo &rInf )
@@ -222,7 +210,7 @@ sal_Bool SwLineLayout::Format( SwTxtFormatInfo &rInf )
 }
 
 /*************************************************************************
- *                    SwLineLayout::CalcLeftMargin()
+ * SwLineLayout::CalcLeftMargin()
  *
  * Wir sammeln alle FlyPortions am Anfang der Zeile zu einer MarginPortion.
  *************************************************************************/
@@ -266,10 +254,6 @@ SwMarginPortion *SwLineLayout::CalcLeftMargin()
     return pLeft;
 }
 
-/*************************************************************************
- *                    SwLineLayout::InitSpaceAdd()
- *************************************************************************/
-
 void SwLineLayout::InitSpaceAdd()
 {
     if ( !pLLSpaceAdd )
@@ -278,10 +262,6 @@ void SwLineLayout::InitSpaceAdd()
         SetLLSpaceAdd( 0, 0 );
 }
 
-/*************************************************************************
- *                    SwLineLayout::CreateSpaceAdd()
- *************************************************************************/
-
 void SwLineLayout::CreateSpaceAdd( const long nInit )
 {
     pLLSpaceAdd = new std::vector<long>;
@@ -309,7 +289,7 @@ bool lcl_HasOnlyBlanks( const XubString& rTxt, xub_StrLen nStt, xub_StrLen nEnd
 }
 
 /*************************************************************************
- *                    SwLineLayout::CalcLine()
+ * SwLineLayout::CalcLine()
  *
  * Aus FormatLine() ausgelagert.
  *************************************************************************/
@@ -626,10 +606,6 @@ void SwLineLayout::MaxAscentDescent( SwTwips& _orAscent,
     }
 }
 
-/*************************************************************************
- *                      class SwCharRange
- *************************************************************************/
-
 SwCharRange &SwCharRange::operator+=(const SwCharRange &rRange)
 {
     if(0 != rRange.nLen ) {
@@ -650,28 +626,23 @@ SwCharRange &SwCharRange::operator+=(const SwCharRange &rRange)
     return *this;
 }
 
-/*************************************************************************
- *                      SwScriptInfo::SwScriptInfo()
- *************************************************************************/
 SwScriptInfo::SwScriptInfo() :
     nInvalidityPos( 0 ),
     nDefaultDir( 0 )
 {
 };
 
-/*************************************************************************
- *                      SwScriptInfo::~SwScriptInfo()
- *************************************************************************/
 SwScriptInfo::~SwScriptInfo()
 {
 }
 
 /*************************************************************************
- *                     SwScriptInfo::WhichFont()
+ * SwScriptInfo::WhichFont()
  *
  * Converts i18n Script Type (LATIN, ASIAN, COMPLEX, WEAK) to
  * Sw Script Types (SW_LATIN, SW_CJK, SW_CTL), used to identify the font
- *************************************************************************/
+*************************************************************************/
+
 sal_uInt8 SwScriptInfo::WhichFont( xub_StrLen nIdx, const String* pTxt, const SwScriptInfo* pSI )
 {
     OSL_ENSURE( pTxt || pSI,"How should I determine the script type?" );
@@ -695,7 +666,7 @@ sal_uInt8 SwScriptInfo::WhichFont( xub_StrLen nIdx, const String* pTxt, const Sw
 }
 
 /*************************************************************************
- *                      SwScriptInfo::InitScriptInfo()
+ * SwScriptInfo::InitScriptInfo()
  *
  * searches for script changes in rTxt and stores them
  *************************************************************************/
@@ -1020,7 +991,7 @@ void SwScriptInfo::InitScriptInfo( const SwTxtNode& rNode, sal_Bool bRTL )
         // we search for connecting opportunities (kashida)
         else if ( bAdjustBlock && i18n::ScriptType::COMPLEX == nScript )
         {
-            SwScanner aScanner( rNode, rNode.GetTxt(), 0, 0,
+            SwScanner aScanner( rNode, rNode.GetTxt(), 0, ModelToViewHelper(),
                                 i18n::WordType::DICTIONARY_WORD,
                                 nLastKashida, nChg );
 
@@ -1326,7 +1297,7 @@ void SwScriptInfo::UpdateBidiInfo( const String& rTxt )
 
 
 /*************************************************************************
- *                        SwScriptInfo::NextScriptChg(..)
+ * SwScriptInfo::NextScriptChg(..)
  * returns the position of the next character which belongs to another script
  * than the character of the actual (input) position.
  * If there's no script change until the end of the paragraph, it will return
@@ -1349,7 +1320,7 @@ xub_StrLen SwScriptInfo::NextScriptChg( const xub_StrLen nPos )  const
 }
 
 /*************************************************************************
- *                        SwScriptInfo::ScriptType(..)
+ * SwScriptInfo::ScriptType(..)
  * returns the script of the character at the input position
  *************************************************************************/
 
@@ -1394,7 +1365,7 @@ sal_uInt8 SwScriptInfo::DirType( const xub_StrLen nPos ) const
 }
 
 /*************************************************************************
- *                        SwScriptInfo::MaskHiddenRanges(..)
+ * SwScriptInfo::MaskHiddenRanges(..)
  * Takes a string and replaced the hidden ranges with cChar.
  **************************************************************************/
 
@@ -1434,7 +1405,7 @@ sal_uInt16 SwScriptInfo::MaskHiddenRanges( const SwTxtNode& rNode, XubString& rT
 }
 
 /*************************************************************************
- *                        SwScriptInfo::DeleteHiddenRanges(..)
+ * SwScriptInfo::DeleteHiddenRanges(..)
  * Takes a SwTxtNode and deletes the hidden ranges from the node.
  **************************************************************************/
 
@@ -1457,7 +1428,7 @@ void SwScriptInfo::DeleteHiddenRanges( SwTxtNode& rNode )
 }
 
 /*************************************************************************
- *                        SwScriptInfo::GetBoundsOfHiddenRange(..)
+ * SwScriptInfo::GetBoundsOfHiddenRange(..)
  * static version
  **************************************************************************/
 
@@ -1545,7 +1516,7 @@ bool SwScriptInfo::GetBoundsOfHiddenRange( const SwTxtNode& rNode, xub_StrLen nP
 }
 
 /*************************************************************************
- *                        SwScriptInfo::GetBoundsOfHiddenRange(..)
+ * SwScriptInfo::GetBoundsOfHiddenRange(..)
  * non-static version
  **************************************************************************/
 
@@ -1583,10 +1554,6 @@ bool SwScriptInfo::GetBoundsOfHiddenRange( xub_StrLen nPos, xub_StrLen& rnStartP
     return CountHiddenChg() > 0;
 }
 
-/*************************************************************************
- *                        SwScriptInfo::IsInHiddenRange()
- **************************************************************************/
-
 bool SwScriptInfo::IsInHiddenRange( const SwTxtNode& rNode, xub_StrLen nPos )
 {
     xub_StrLen nStartPos;
@@ -1598,7 +1565,7 @@ bool SwScriptInfo::IsInHiddenRange( const SwTxtNode& rNode, xub_StrLen nPos )
 
 #ifdef DBG_UTIL
 /*************************************************************************
- *                        SwScriptInfo::CompType(..)
+ * SwScriptInfo::CompType(..)
  * returns the type of the compressed character
  *************************************************************************/
 
@@ -1620,7 +1587,7 @@ sal_uInt8 SwScriptInfo::CompType( const xub_StrLen nPos ) const
 #endif
 
 /*************************************************************************
- *                      SwScriptInfo::HasKana()
+ * SwScriptInfo::HasKana()
  * returns, if there are compressable kanas or specials
  * betwenn nStart and nEnd
  *************************************************************************/
@@ -1645,10 +1612,6 @@ sal_uInt16 SwScriptInfo::HasKana( xub_StrLen nStart, const xub_StrLen nLen ) con
     return USHRT_MAX;
 }
 
-/*************************************************************************
- *                      SwScriptInfo::Compress()
- *************************************************************************/
-
 long SwScriptInfo::Compress( sal_Int32* pKernArray, xub_StrLen nIdx, xub_StrLen nLen,
                              const sal_uInt16 nCompress, const sal_uInt16 nFontHeight,
                              Point* pPoint ) const
@@ -1762,7 +1725,7 @@ long SwScriptInfo::Compress( sal_Int32* pKernArray, xub_StrLen nIdx, xub_StrLen
 }
 
 /*************************************************************************
- *                      SwScriptInfo::KashidaJustify()
+ * SwScriptInfo::KashidaJustify()
  *************************************************************************/
 
 // Note on calling KashidaJustify():
@@ -1854,7 +1817,7 @@ sal_uInt16 SwScriptInfo::KashidaJustify( sal_Int32* pKernArray,
 }
 
 /*************************************************************************
- *                      SwScriptInfo::IsArabicText()
+ * SwScriptInfo::IsArabicText()
  *
  * Checks if the current text is 'Arabic' text. Note that only the first
  * character has to be checked because a ctl portion only contains one
@@ -1896,10 +1859,6 @@ bool SwScriptInfo::IsArabicText( const rtl::OUString& rTxt, sal_Int32 nStt, sal_
     return false;
 }
 
-/*************************************************************************
- *                      SwScriptInfo::IsKashidaValid()
- *************************************************************************/
-
 sal_Bool SwScriptInfo::IsKashidaValid ( xub_StrLen nKashPos ) const
 {
     for ( size_t i = 0; i < aKashidaInvalid.size(); ++i )
@@ -1910,10 +1869,6 @@ sal_Bool SwScriptInfo::IsKashidaValid ( xub_StrLen nKashPos ) const
     return true;
 }
 
-/*************************************************************************
- *                      SwScriptInfo::ClearKashidaInvalid()
- *************************************************************************/
-
 void SwScriptInfo::ClearKashidaInvalid ( xub_StrLen nKashPos )
 {
     for ( size_t i = 0; i < aKashidaInvalid.size(); ++i )
@@ -1927,13 +1882,14 @@ void SwScriptInfo::ClearKashidaInvalid ( xub_StrLen nKashPos )
 }
 
 /*************************************************************************
- *                      SwScriptInfo::MarkOrClearKashidaInvalid()
- *************************************************************************/
-// bMark == true:
-// marks the first valid kashida in the given text range as invalid
-
-// bMark == false:
-// clears all kashida invalid flags in the given text range
+ * SwScriptInfo::MarkOrClearKashidaInvalid()
+ *
+ * bMark == true:
+ * marks the first valid kashida in the given text range as invalid
+ *
+ * bMark == false:
+ * clears all kashida invalid flags in the given text range
+*************************************************************************/
 
 bool SwScriptInfo::MarkOrClearKashidaInvalid ( xub_StrLen nStt, xub_StrLen nLen, bool bMark, xub_StrLen nMarkCount )
 {
@@ -1980,9 +1936,10 @@ void SwScriptInfo::MarkKashidaInvalid ( xub_StrLen nKashPos )
 }
 
 /*************************************************************************
- *                      SwScriptInfo::GetKashidaPositions()
- *************************************************************************/
-// retrieve the kashida positions in the given text range
+ * SwScriptInfo::GetKashidaPositions()
+ * retrieve the kashida positions in the given text range
+*************************************************************************/
+
 sal_uInt16 SwScriptInfo::GetKashidaPositions ( xub_StrLen nStt, xub_StrLen nLen,
                                            xub_StrLen* pKashidaPosition )
 {
@@ -2018,9 +1975,9 @@ void SwScriptInfo::SetNoKashidaLine ( xub_StrLen nStt, xub_StrLen nLen )
 }
 
 /*************************************************************************
- *                      SwScriptInfo::IsKashidaLine()
- *************************************************************************/
-// determines if the line uses kashida justification
+ * SwScriptInfo::IsKashidaLine()
+ * determines if the line uses kashida justification
+*************************************************************************/
 
 bool SwScriptInfo::IsKashidaLine ( xub_StrLen nCharIdx ) const
 {
@@ -2031,9 +1988,6 @@ bool SwScriptInfo::IsKashidaLine ( xub_StrLen nCharIdx ) const
     }
    return true;
 }
-/*************************************************************************
- *                      SwScriptInfo::ClearKashidaLine()
- *************************************************************************/
 
 void SwScriptInfo::ClearNoKashidaLine ( xub_StrLen nStt, xub_StrLen nLen )
 {
@@ -2052,8 +2006,10 @@ void SwScriptInfo::ClearNoKashidaLine ( xub_StrLen nStt, xub_StrLen nLen )
 
 /*************************************************************************
  *                      SwScriptInfo::MarkKashidasInvalid()
- *************************************************************************/
-// mark the given character indices as invalid kashida positions
+ *
+ * mark the given character indices as invalid kashida positions
+************************************************************************/
+
 bool SwScriptInfo::MarkKashidasInvalid ( xub_StrLen nCnt, xub_StrLen* pKashidaPositions )
 {
    OSL_ENSURE( pKashidaPositions && nCnt > 0, "Where are kashidas?" );
@@ -2080,10 +2036,6 @@ bool SwScriptInfo::MarkKashidasInvalid ( xub_StrLen nCnt, xub_StrLen* pKashidaPo
    return true;
 }
 
-/*************************************************************************
- *                      SwScriptInfo::ThaiJustify()
- *************************************************************************/
-
 sal_Int32 SwScriptInfo::ThaiJustify( const rtl::OUString& rTxt, sal_Int32* pKernArray,
                                   sal_Int32* pScrArray, sal_Int32 nStt,
                                   sal_Int32 nLen, sal_Int32 nNumberOfBlanks,
@@ -2122,10 +2074,6 @@ sal_Int32 SwScriptInfo::ThaiJustify( const rtl::OUString& rTxt, sal_Int32* pKern
     return nCnt;
 }
 
-/*************************************************************************
- *                      SwScriptInfo::GetScriptInfo()
- *************************************************************************/
-
 SwScriptInfo* SwScriptInfo::GetScriptInfo( const SwTxtNode& rTNd,
                                            sal_Bool bAllowInvalid )
 {
@@ -2146,9 +2094,6 @@ SwScriptInfo* SwScriptInfo::GetScriptInfo( const SwTxtNode& rTNd,
     return pScriptInfo;
 }
 
-/*************************************************************************
- *                      SwParaPortion::SwParaPortion()
- *************************************************************************/
 SwParaPortion::SwParaPortion()
 {
     FormatReset();
@@ -2156,16 +2101,10 @@ SwParaPortion::SwParaPortion()
     SetWhichPor( POR_PARA );
 }
 
-/*************************************************************************
- *                      SwParaPortion::~SwParaPortion()
- *************************************************************************/
 SwParaPortion::~SwParaPortion()
 {
 }
 
-/*************************************************************************
- *                      SwParaPortion::GetParLen()
- *************************************************************************/
 xub_StrLen SwParaPortion::GetParLen() const
 {
     xub_StrLen nLen = 0;
@@ -2178,10 +2117,6 @@ xub_StrLen SwParaPortion::GetParLen() const
     return nLen;
 }
 
-/*************************************************************************
- *                      SwParaPortion::FindDropPortion()
- *************************************************************************/
-
 const SwDropPortion *SwParaPortion::FindDropPortion() const
 {
     const SwLineLayout *pLay = this;
@@ -2199,10 +2134,6 @@ const SwDropPortion *SwParaPortion::FindDropPortion() const
     return NULL;
 }
 
-/*************************************************************************
- *                      SwLineLayout::Init()
- *************************************************************************/
-
 void SwLineLayout::Init( SwLinePortion* pNextPortion )
 {
     Height( 0 );
@@ -2263,14 +2194,7 @@ SwTwips SwTxtFrm::HangingMargin() const
     return nRet;
 }
 
-
-/*************************************************************************
- *                      SwScriptInfo::CalcHiddenRanges()
- *
- * Returns a MultiSection indicating the hidden ranges.
- *************************************************************************/
-
-void SwScriptInfo::CalcHiddenRanges( const SwTxtNode& rNode, MultiSelection& rHiddenMulti )
+void SwScriptInfo::selectHiddenTextProperty(const SwTxtNode& rNode, MultiSelection &rHiddenMulti)
 {
     const SfxPoolItem* pItem = 0;
     if( SFX_ITEM_SET == rNode.GetSwAttrSet().GetItemState( RES_CHRATR_HIDDEN, sal_True, &pItem ) &&
@@ -2280,7 +2204,6 @@ void SwScriptInfo::CalcHiddenRanges( const SwTxtNode& rNode, MultiSelection& rHi
     }
 
     const SwpHints* pHints = rNode.GetpSwpHints();
-    const SwTxtAttr* pTxtAttr = 0;
 
     if( pHints )
     {
@@ -2288,8 +2211,9 @@ void SwScriptInfo::CalcHiddenRanges( const SwTxtNode& rNode, MultiSelection& rHi
 
         while( nTmp < pHints->GetStartCount() )
         {
-            pTxtAttr = pHints->GetStart( nTmp++ );
-            const SvxCharHiddenItem* pHiddenItem = static_cast<const SvxCharHiddenItem*>( CharFmt::GetItem( *pTxtAttr, RES_CHRATR_HIDDEN ) );
+            const SwTxtAttr* pTxtAttr = pHints->GetStart( nTmp++ );
+            const SvxCharHiddenItem* pHiddenItem =
+                static_cast<const SvxCharHiddenItem*>( CharFmt::GetItem( *pTxtAttr, RES_CHRATR_HIDDEN ) );
             if( pHiddenItem )
             {
                 xub_StrLen nSt = *pTxtAttr->GetStart();
@@ -2302,11 +2226,12 @@ void SwScriptInfo::CalcHiddenRanges( const SwTxtNode& rNode, MultiSelection& rHi
             }
         }
     }
+}
 
-    // If there are any hidden ranges in the current text node, we have
-    // to unhide the redlining ranges:
+void SwScriptInfo::selectRedLineDeleted(const SwTxtNode& rNode, MultiSelection &rHiddenMulti, bool bSelect)
+{
     const IDocumentRedlineAccess& rIDRA = *rNode.getIDocumentRedlineAccess();
-    if ( rHiddenMulti.GetRangeCount() && IDocumentRedlineAccess::IsShowChanges( rIDRA.GetRedlineMode() ) )
+    if ( IDocumentRedlineAccess::IsShowChanges( rIDRA.GetRedlineMode() ) )
     {
         sal_uInt16 nAct = rIDRA.GetRedlinePos( rNode, USHRT_MAX );
 
@@ -2320,13 +2245,30 @@ void SwScriptInfo::CalcHiddenRanges( const SwTxtNode& rNode, MultiSelection& rHi
             xub_StrLen nRedlStart;
             xub_StrLen nRedlnEnd;
             pRed->CalcStartEnd( rNode.GetIndex(), nRedlStart, nRedlnEnd );
+            //clip it if the redline extends past the end of the nodes text
+            nRedlnEnd = std::min(nRedlnEnd, rNode.GetTxt().Len());
             if ( nRedlnEnd > nRedlStart )
             {
                 Range aTmp( nRedlStart, nRedlnEnd - 1 );
-                rHiddenMulti.Select( aTmp, false );
+                rHiddenMulti.Select( aTmp, bSelect );
             }
         }
     }
+}
+
+/*************************************************************************
+ * SwScriptInfo::CalcHiddenRanges()
+ *
+ * Returns a MultiSection indicating the hidden ranges.
+ *************************************************************************/
+
+void SwScriptInfo::CalcHiddenRanges( const SwTxtNode& rNode, MultiSelection& rHiddenMulti )
+{
+    selectHiddenTextProperty(rNode, rHiddenMulti);
+
+    // If there are any hidden ranges in the current text node, we have
+    // to unhide the redlining ranges:
+    selectRedLineDeleted(rNode, rHiddenMulti, false);
 
     //
     // We calculated a lot of stuff. Finally we can update the flags at the text node.
diff --git a/sw/source/core/txtnode/modeltoviewhelper.cxx b/sw/source/core/txtnode/modeltoviewhelper.cxx
index 4f8b89a..2891765 100644
--- a/sw/source/core/txtnode/modeltoviewhelper.cxx
+++ b/sw/source/core/txtnode/modeltoviewhelper.cxx
@@ -28,21 +28,15 @@
 
 #include <modeltoviewhelper.hxx>
 
-namespace ModelToViewHelper
-{
-
 /** Converts a model position into a view position
 */
-sal_uInt32 ConvertToViewPosition( const ConversionMap* pMap, sal_uInt32 nModelPos )
+sal_uInt32 ModelToViewHelper::ConvertToViewPosition( sal_uInt32 nModelPos ) const
 {
     sal_uInt32 nRet = nModelPos;
 
-    if ( !pMap )
-        return nRet;
-
-    // Search for entry behind nPos:
+    // Search for entry after nPos:
     ConversionMap::const_iterator aIter;
-    for ( aIter = pMap->begin(); aIter != pMap->end(); ++aIter )
+    for ( aIter = m_aMap.begin(); aIter != m_aMap.end(); ++aIter )
     {
         if ( (*aIter).first >= nModelPos )
         {
@@ -61,17 +55,14 @@ sal_uInt32 ConvertToViewPosition( const ConversionMap* pMap, sal_uInt32 nModelPo
 
 /** Converts a view position into a model position
 */
-ModelPosition ConvertToModelPosition( const ConversionMap* pMap, sal_uInt32 nViewPos )
+ModelToViewHelper::ModelPosition ModelToViewHelper::ConvertToModelPosition( sal_uInt32 nViewPos ) const
 {
     ModelPosition aRet;
     aRet.mnPos = nViewPos;
 
-    if ( !pMap )
-        return aRet;
-
-    // Search for entry behind nPos:
+    // Search for entry after nPos:
     ConversionMap::const_iterator aIter;
-    for ( aIter = pMap->begin(); aIter != pMap->end(); ++aIter )
+    for ( aIter = m_aMap.begin(); aIter != m_aMap.end(); ++aIter )
     {
         if ( (*aIter).second > nViewPos )
         {
@@ -79,7 +70,7 @@ ModelPosition ConvertToModelPosition( const ConversionMap* pMap, sal_uInt32 nVie
             const sal_uInt32 nPosExpand = (*aIter).second;
 
             // If nViewPos is in front of first field, we are finished.
-            if ( aIter == pMap->begin() )
+            if ( aIter == m_aMap.begin() )
                 break;
 
             --aIter;
@@ -116,6 +107,4 @@ ModelPosition ConvertToModelPosition( const ConversionMap* pMap, sal_uInt32 nVie
     return aRet;
 }
 
-} // namespace ModelToViewStringConverter end
-
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index 46ef849..fc0a192 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -38,6 +38,7 @@
 #include <svl/urihelper.hxx>
 #include <svl/svstdarr.hxx>
 #include <svl/ctloptions.hxx>
+#include <tools/multisel.hxx>
 #include <swmodule.hxx>
 #include <txtfld.hxx>
 #include <txtinet.hxx>
@@ -3108,44 +3109,136 @@ sal_Bool SwTxtNode::GetExpandTxt( SwTxtNode& rDestNd, const SwIndex* pDestIdx,
     return sal_True;
 }
 
-const ModelToViewHelper::ConversionMap*
-        SwTxtNode::BuildConversionMap( rtl::OUString& rRetText ) const
+struct block
 {
-    const rtl::OUString& rNodeText = GetTxt();
-    rRetText = rNodeText;
-    ModelToViewHelper::ConversionMap* pConversionMap = 0;
-
-    const SwpHints* pSwpHints2 = GetpSwpHints();
-    xub_StrLen nPos = 0;
-
-    for ( sal_uInt16 i = 0; pSwpHints2 && i < pSwpHints2->Count(); ++i )
-    {
-        const SwTxtAttr* pAttr = (*pSwpHints2)[i];
-        if ( RES_TXTATR_FIELD == pAttr->Which() )
-        {
-            const XubString aExpand(
-                static_cast<SwTxtFld const*>(pAttr)->GetFld().GetFld()
-                    ->ExpandField(true));
-            if ( aExpand.Len() > 0 )
-            {
-                const xub_StrLen nFieldPos = *pAttr->GetStart();
-                rRetText = rRetText.replaceAt( nPos + nFieldPos, 1, aExpand );
-                if ( !pConversionMap )
-                    pConversionMap = new ModelToViewHelper::ConversionMap;
-                pConversionMap->push_back(
-                        ModelToViewHelper::ConversionMapEntry(
-                            nFieldPos, nPos + nFieldPos ) );
-                nPos += ( aExpand.Len() - 1 );
+    sal_Int32 m_nStart;
+    sal_Int32 m_nLen;
+    bool m_bVisible;
+    std::vector<const SwTxtAttr*> m_aAttrs;
+    block(sal_Int32 nStart, sal_Int32 nLen, bool bVisible)
+        : m_nStart(nStart), m_nLen(nLen), m_bVisible(bVisible)
+    {
+    }
+};
+
+struct containsPos
+{
+    const sal_Int32 m_nPos;
+    containsPos(const sal_Int32 nPos)
+        : m_nPos(nPos)
+    {
+    }
+    bool operator() (const block& rIn) const
+    {
+        return m_nPos >= rIn.m_nStart && m_nPos < rIn.m_nStart + rIn.m_nLen;
+    }
+};
+
+ModelToViewHelper::ModelToViewHelper(const SwTxtNode &rNode, int eMode)
+{
+    const rtl::OUString& rNodeText = rNode.GetTxt();
+    m_aRetText = rNodeText;
+
+    if (eMode == PASSTHROUGH)
+        return;
+
+    Range aRange( 0, rNodeText.isEmpty() ? 0 : rNodeText.getLength() - 1);
+    MultiSelection aHiddenMulti(aRange);
+
+    if (eMode & HIDEINVISIBLE)
+        SwScriptInfo::selectHiddenTextProperty(rNode, aHiddenMulti);
+
+    if (eMode & HIDEREDLINED)
+        SwScriptInfo::selectRedLineDeleted(rNode, aHiddenMulti);
+
+    std::vector<block> aBlocks;
+
+    sal_Int32 nShownStart = 0;
+    for (size_t i = 0; i < aHiddenMulti.GetRangeCount(); ++i)
+    {
+        const Range& rRange = aHiddenMulti.GetRange(i);
+        sal_Int32 nHiddenStart = rRange.Min();
+        sal_Int32 nHiddenEnd = rRange.Max() + 1;
+        sal_Int32 nHiddenLen = nHiddenEnd - nHiddenStart;
+
+        sal_Int32 nShownEnd = nHiddenStart;
+        sal_Int32 nShownLen = nShownEnd - nShownStart;
+
+        if (nShownLen)
+            aBlocks.push_back(block(nShownStart, nShownLen, true));
+
+        if (nHiddenLen)
+            aBlocks.push_back(block(nHiddenStart, nHiddenLen, false));
+
+        nShownStart = nHiddenEnd;
+    }
+
+    sal_Int32 nTrailingShownLen = rNodeText.getLength() - nShownStart;
+    if (nTrailingShownLen)
+        aBlocks.push_back(block(nShownStart, nTrailingShownLen, true));
+
+    if (eMode & EXPANDFIELDS)
+    {
+        const SwpHints* pSwpHints2 = rNode.GetpSwpHints();
+        for ( sal_uInt16 i = 0; pSwpHints2 && i < pSwpHints2->Count(); ++i )
+        {
+            const SwTxtAttr* pAttr = (*pSwpHints2)[i];
+            if (pAttr->HasDummyChar())
+            {
+                xub_StrLen nDummyCharPos = *pAttr->GetStart();
+                if (aHiddenMulti.IsSelected(nDummyCharPos))
+                    continue;
+                std::vector<block>::iterator aFind = std::find_if(aBlocks.begin(), aBlocks.end(), containsPos(nDummyCharPos));
+                aFind->m_aAttrs.push_back(pAttr);
             }
         }
     }
 
-    if ( pConversionMap && pConversionMap->size() )
-        pConversionMap->push_back(
-            ModelToViewHelper::ConversionMapEntry(
-                rNodeText.getLength()+1, rRetText.getLength()+1 ) );
+    sal_Int32 nOffset = 0;
+    for (std::vector<block>::iterator i = aBlocks.begin(); i != aBlocks.end(); ++i)
+    {
+        if (!i->m_bVisible)
+        {
+            const sal_Int32 nHiddenStart = i->m_nStart;
+            const sal_Int32 nHiddenLen = i->m_nLen;
+
+            m_aRetText = m_aRetText.replaceAt( nOffset + nHiddenStart, nHiddenLen, rtl::OUString() );
+            m_aMap.push_back( ConversionMapEntry( nHiddenStart, nOffset + nHiddenStart ) );
+            nOffset -= nHiddenLen;
+        }
+        else
+        {
+            for (std::vector<const SwTxtAttr*>::iterator j = i->m_aAttrs.begin(); j != i->m_aAttrs.end(); ++j)
+            {
+                const SwTxtAttr* pAttr = *j;
+                xub_StrLen nFieldPos = *pAttr->GetStart();
+                rtl::OUString aExpand;
+                switch (pAttr->Which())
+                {
+                    case RES_TXTATR_FIELD:
+                        aExpand =
+                            static_cast<SwTxtFld const*>(pAttr)->GetFld().GetFld()
+                                ->ExpandField(true);
+                        break;
+                    case RES_TXTATR_FTN:
+                        {
+                            const SwFmtFtn& rFtn = static_cast<SwTxtFtn const*>(pAttr)->GetFtn();
+                            const SwDoc *pDoc = rNode.GetDoc();
+                            aExpand = rFtn.GetViewNumStr(*pDoc);
+                        }
+                        break;
+                    default:
+                        break;
+                }
+                m_aRetText = m_aRetText.replaceAt( nOffset + nFieldPos, 1, aExpand );
+                m_aMap.push_back( ConversionMapEntry( nFieldPos, nOffset + nFieldPos ) );
+                nOffset += ( aExpand.getLength() - 1 );
+            }
+        }
+    }
 
-    return pConversionMap;
+    if ( !m_aMap.empty() )
+        m_aMap.push_back( ConversionMapEntry( rNodeText.getLength()+1, m_aRetText.getLength()+1 ) );
 }
 
 XubString SwTxtNode::GetRedlineTxt( xub_StrLen nIdx, xub_StrLen nLen,
diff --git a/sw/source/core/txtnode/txtedt.cxx b/sw/source/core/txtnode/txtedt.cxx
index f303138..e1e6d75 100644
--- a/sw/source/core/txtnode/txtedt.cxx
+++ b/sw/source/core/txtnode/txtedt.cxx
@@ -653,9 +653,9 @@ XubString SwTxtNode::GetCurWord( xub_StrLen nPos ) const
 }
 
 SwScanner::SwScanner( const SwTxtNode& rNd, const rtl::OUString& rTxt,
-    const LanguageType* pLang, const ModelToViewHelper::ConversionMap* pConvMap,
+    const LanguageType* pLang, const ModelToViewHelper& rConvMap,
     sal_uInt16 nType, sal_Int32 nStart, sal_Int32 nEnde, sal_Bool bClp )
-    : rNode( rNd ), aText( rTxt), pLanguage( pLang ), pConversionMap( pConvMap ), nLen( 0 ), nWordType( nType ), bClip( bClp )
+    : rNode( rNd ), aText( rTxt), pLanguage( pLang ), rConversionMap( rConvMap ), nLen( 0 ), nWordType( nType ), bClip( bClp )
 {
     OSL_ENSURE( !aText.isEmpty(), "SwScanner: EmptyString" );
     nStartPos = nBegin = nStart;
@@ -667,7 +667,7 @@ SwScanner::SwScanner( const SwTxtNode& rNd, const rtl::OUString& rTxt,
     }
     else
     {
-        ModelToViewHelper::ModelPosition aModelBeginPos = ModelToViewHelper::ConvertToModelPosition( pConversionMap, nBegin );
+        ModelToViewHelper::ModelPosition aModelBeginPos = rConversionMap.ConvertToModelPosition( nBegin );
         const sal_Int32 nModelBeginPos = aModelBeginPos.mnPos;
         aCurrLang = rNd.GetLang( nModelBeginPos );
     }
@@ -729,7 +729,7 @@ sal_Bool SwScanner::NextWord()
                 if ( !pLanguage )
                 {
                     const sal_uInt16 nNextScriptType = pBreakIt->GetBreakIter()->getScriptType( aText, nBegin );
-                    ModelToViewHelper::ModelPosition aModelBeginPos = ModelToViewHelper::ConvertToModelPosition( pConversionMap, nBegin );
+                    ModelToViewHelper::ModelPosition aModelBeginPos = rConversionMap.ConvertToModelPosition( nBegin );
                     const sal_Int32 nBeginModelPos = aModelBeginPos.mnPos;
                     aCurrLang = rNode.GetLang( nBeginModelPos, 1, nNextScriptType );
                 }
@@ -911,7 +911,7 @@ sal_uInt16 SwTxtNode::Spell(SwSpellArgs* pArgs)
 
         // In case 2. we pass the wrong list to the scanned, because only
         // the words in the wrong list have to be checked
-        SwScanner aScanner( *this, m_Text, 0, 0,
+        SwScanner aScanner( *this, m_Text, 0, ModelToViewHelper(),
                             WordType::DICTIONARY_WORD,
                             nBegin, nEnd );
         while( !pArgs->xSpellAlt.is() && aScanner.NextWord() )
@@ -1219,7 +1219,7 @@ SwRect SwTxtFrm::_AutoSpell( const SwCntntNode* pActNode, const SwViewOption& rV
         uno::Reference< XSpellChecker1 > xSpell( ::GetSpellChecker() );
         SwDoc* pDoc = pNode->GetDoc();
 
-        SwScanner aScanner( *pNode, pNode->GetTxt(), 0, 0,
+        SwScanner aScanner( *pNode, pNode->GetTxt(), 0, ModelToViewHelper(),
                             WordType::DICTIONARY_WORD, nBegin, nEnd);
 
         while( aScanner.NextWord() )
@@ -1369,13 +1369,12 @@ SwRect SwTxtFrm::SmartTagScan( SwCntntNode* /*pActNode*/, xub_StrLen /*nActPos*/
     if ( nBegin < nEnd )
     {
         // Expand the string:
-        rtl::OUString aExpandText;
-        const ModelToViewHelper::ConversionMap* pConversionMap =
-                pNode->BuildConversionMap( aExpandText );
+        const ModelToViewHelper aConversionMap(*pNode);
+        rtl::OUString aExpandText = aConversionMap.getViewText();
 
         // Ownership ov ConversionMap is passed to SwXTextMarkup object!
         Reference< com::sun::star::text::XTextMarkup > xTextMarkup =
-             new SwXTextMarkup( *pNode, pConversionMap );
+             new SwXTextMarkup( *pNode, aConversionMap );
 
         Reference< ::com::sun::star::frame::XController > xController = pNode->GetDoc()->GetDocShell()->GetController();
 
@@ -1391,8 +1390,8 @@ SwRect SwTxtFrm::SmartTagScan( SwCntntNode* /*pActNode*/, xub_StrLen /*nActPos*/
             const com::sun::star::lang::Locale aLocale = pBreakIt->GetLocale( nLang );
             nLangEnd = Min( nEnd, aIter.GetChgPos() );
 
-            const sal_uInt32 nExpandBegin = ModelToViewHelper::ConvertToViewPosition( pConversionMap, nLangBegin );
-            const sal_uInt32 nExpandEnd   = ModelToViewHelper::ConvertToViewPosition( pConversionMap, nLangEnd );
+            const sal_uInt32 nExpandBegin = aConversionMap.ConvertToViewPosition( nLangBegin );
+            const sal_uInt32 nExpandEnd   = aConversionMap.ConvertToViewPosition( nLangEnd );
 
             rSmartTagMgr.Recognize( aExpandText, xTextMarkup, xController, aLocale, nExpandBegin, nExpandEnd - nExpandBegin );
 
@@ -1454,7 +1453,7 @@ void SwTxtFrm::CollectAutoCmplWrds( SwCntntNode* pActNode, xub_StrLen nActPos )
     if( nBegin < nEnd )
     {
         sal_uInt16 nCnt = 200;
-        SwScanner aScanner( *pNode, pNode->GetTxt(), 0, 0,
+        SwScanner aScanner( *pNode, pNode->GetTxt(), 0, ModelToViewHelper(),
                             WordType::DICTIONARY_WORD, nBegin, nEnd );
         while( aScanner.NextWord() )
         {
@@ -1826,6 +1825,11 @@ void SwTxtNode::ReplaceTextOnly( xub_StrLen nPos, xub_StrLen nLen,
 void SwTxtNode::CountWords( SwDocStat& rStat,
                             xub_StrLen nStt, xub_StrLen nEnd ) const
 {
+    if (IsInRedlines())
+    {   //not counting txtnodes used to hold deleted redline content
+        return;
+    }
+
     sal_Bool isCountAll = ( (0 == nStt) && (GetTxt().Len() == nEnd) );
 
     ++rStat.nAllPara; // #i93174#: count _all_ paragraphs
@@ -1852,13 +1856,13 @@ void SwTxtNode::CountWords( SwDocStat& rStat,
         return;
     }
 
-    // expand text into pConversionMap for scanner
-    rtl::OUString aExpandText;
-    const ModelToViewHelper::ConversionMap* pConversionMap = BuildConversionMap( aExpandText );
+    // ConversionMap to expand fields, remove invisible and redline deleted text for scanner
+    const ModelToViewHelper aConversionMap(*this, EXPANDFIELDS | HIDEINVISIBLE | HIDEREDLINED);
+    rtl::OUString aExpandText = aConversionMap.getViewText();
 
     // map start and end points onto the ConversionMap
-    const sal_uInt32 nExpandBegin = ModelToViewHelper::ConvertToViewPosition( pConversionMap, nStt );
-    const sal_uInt32 nExpandEnd   = ModelToViewHelper::ConvertToViewPosition( pConversionMap, nEnd );
+    const sal_uInt32 nExpandBegin = aConversionMap.ConvertToViewPosition( nStt );
+    const sal_uInt32 nExpandEnd   = aConversionMap.ConvertToViewPosition( nEnd );
 
     if ( aExpandText.isEmpty() )
     {
@@ -1866,12 +1870,6 @@ void SwTxtNode::CountWords( SwDocStat& rStat,
         return;
     }
 
-    // make a copy of the expanded text for masking redlined/hidden text with ' '
-    String textCopy = aExpandText;
-    const xub_Unicode cChar(' ');
-    const sal_uInt16 nNumOfMaskedChars = lcl_MaskRedlinesAndHiddenText( *this, textCopy, nExpandBegin, nExpandEnd, cChar, false );
-    aExpandText = textCopy;
-
     //do the count
     // all counts exclude hidden paras and hidden+redlined within para
     // definition of space/white chars in SwScanner (and BreakIter!)
@@ -1885,7 +1883,7 @@ void SwTxtNode::CountWords( SwDocStat& rStat,
     if( pBreakIt->GetBreakIter().is() )
     {
         // zero is NULL for pLanguage -----------v               last param = true for clipping
-        SwScanner aScanner( *this, aExpandText, 0, pConversionMap, i18n::WordType::WORD_COUNT,
+        SwScanner aScanner( *this, aExpandText, 0, aConversionMap, i18n::WordType::WORD_COUNT,
                             nExpandBegin, nExpandEnd, true );
 
         // used to filter out scanner returning almost empty strings (len=1; unichar=0x0001)
@@ -1906,7 +1904,6 @@ void SwTxtNode::CountWords( SwDocStat& rStat,
     }
 
     nTmpChars = pBreakIt->getGraphemeCount(aExpandText, nExpandBegin, nExpandEnd);
-    nTmpChars -= nNumOfMaskedChars;
 
     // no nTmpCharsExcludingSpaces adjust needed neither for blanked out MaskedChars
     // nor for mid-word selection - set scanner bClip = true at creation
@@ -1922,7 +1919,7 @@ void SwTxtNode::CountWords( SwDocStat& rStat,
         {
             LanguageType aLanguage = GetLang( 0 );
 
-            SwScanner aScanner( *this, aNumString, &aLanguage, 0,
+            SwScanner aScanner( *this, aNumString, &aLanguage, ModelToViewHelper(),
                                 i18n::WordType::WORD_COUNT, 0, nNumStringLen, true );
 
             while ( aScanner.NextWord() )
@@ -1944,8 +1941,6 @@ void SwTxtNode::CountWords( SwDocStat& rStat,
         }
     }
 
-    delete pConversionMap;
-
     // If counting the whole para then update cached values and mark clean
     if ( isCountAll )
     {
diff --git a/sw/source/core/unocore/unoflatpara.cxx b/sw/source/core/unocore/unoflatpara.cxx
index c590560..1652f9c 100644
--- a/sw/source/core/unocore/unoflatpara.cxx
+++ b/sw/source/core/unocore/unoflatpara.cxx
@@ -59,8 +59,8 @@ using namespace ::com::sun::star;
  * SwXFlatParagraph
  ******************************************************************************/
 
-SwXFlatParagraph::SwXFlatParagraph( SwTxtNode& rTxtNode, rtl::OUString aExpandText, const ModelToViewHelper::ConversionMap* pMap ) :
-    SwXTextMarkup( rTxtNode, pMap ),
+SwXFlatParagraph::SwXFlatParagraph( SwTxtNode& rTxtNode, rtl::OUString aExpandText, const ModelToViewHelper& rMap ) :
+    SwXTextMarkup( rTxtNode, rMap ),
     maExpandText( aExpandText )
 {
 }
@@ -416,11 +416,10 @@ uno::Reference< text::XFlatParagraph > SwXFlatParagraphIterator::getNextPara()
     if ( pRet )
     {
         // Expand the string:
-        rtl::OUString aExpandText;
-        const ModelToViewHelper::ConversionMap* pConversionMap =
-                pRet->BuildConversionMap( aExpandText );
+        const ModelToViewHelper aConversionMap(*pRet);
+        rtl::OUString aExpandText = aConversionMap.getViewText();
 
-        xRet = new SwXFlatParagraph( *pRet, aExpandText, pConversionMap );
+        xRet = new SwXFlatParagraph( *pRet, aExpandText, aConversionMap );
         // keep hard references...
         m_aFlatParaList.insert( xRet );
     }
@@ -469,11 +468,10 @@ uno::Reference< text::XFlatParagraph > SwXFlatParagraphIterator::getParaAfter(co
     if ( pNextTxtNode )
     {
         // Expand the string:
-        rtl::OUString aExpandText;
-        const ModelToViewHelper::ConversionMap* pConversionMap =
-                pNextTxtNode->BuildConversionMap( aExpandText );
+        const ModelToViewHelper aConversionMap(*pNextTxtNode);
+        rtl::OUString aExpandText = aConversionMap.getViewText();
 
-        xRet = new SwXFlatParagraph( *pNextTxtNode, aExpandText, pConversionMap );
+        xRet = new SwXFlatParagraph( *pNextTxtNode, aExpandText, aConversionMap );
         // keep hard references...
         m_aFlatParaList.insert( xRet );
     }
@@ -516,11 +514,10 @@ uno::Reference< text::XFlatParagraph > SwXFlatParagraphIterator::getParaBefore(c
     if ( pPrevTxtNode )
     {
         // Expand the string:
-        rtl::OUString aExpandText;
-        const ModelToViewHelper::ConversionMap* pConversionMap =
-                pPrevTxtNode->BuildConversionMap( aExpandText );
+        const ModelToViewHelper aConversionMap(*pPrevTxtNode);
+        rtl::OUString aExpandText = aConversionMap.getViewText();
 
-        xRet = new SwXFlatParagraph( *pPrevTxtNode, aExpandText, pConversionMap );
+        xRet = new SwXFlatParagraph( *pPrevTxtNode, aExpandText, aConversionMap );
         // keep hard references...
         m_aFlatParaList.insert( xRet );
     }
diff --git a/sw/source/core/unocore/unotextmarkup.cxx b/sw/source/core/unocore/unotextmarkup.cxx
index 80d410e..a7cddad 100644
--- a/sw/source/core/unocore/unotextmarkup.cxx
+++ b/sw/source/core/unocore/unotextmarkup.cxx
@@ -44,8 +44,8 @@ using namespace ::com::sun::star;
 /*
  * SwXTextMarkup
  */
-SwXTextMarkup::SwXTextMarkup( SwTxtNode& rTxtNode, const ModelToViewHelper::ConversionMap* pMap )
-    : mpTxtNode( &rTxtNode ), mpConversionMap( pMap )
+SwXTextMarkup::SwXTextMarkup( SwTxtNode& rTxtNode, const ModelToViewHelper& rMap )
+    : mpTxtNode( &rTxtNode ), maConversionMap( rMap )
 {
     // FME 2007-07-16 #i79641# SwXTextMarkup is allowed to be removed ...
     SetIsAllowedToBeRemovedInModifyCall(true);
@@ -54,7 +54,6 @@ SwXTextMarkup::SwXTextMarkup( SwTxtNode& rTxtNode, const ModelToViewHelper::Conv
 
 SwXTextMarkup::~SwXTextMarkup()
 {
-     delete mpConversionMap;
 }
 
 uno::Reference< container::XStringKeyMap > SAL_CALL SwXTextMarkup::getMarkupInfoContainer() throw (uno::RuntimeException)
@@ -133,9 +132,9 @@ void SAL_CALL SwXTextMarkup::commitTextMarkup(
 
 
     const ModelToViewHelper::ModelPosition aStartPos =
-            ModelToViewHelper::ConvertToModelPosition( mpConversionMap, nStart );
+            maConversionMap.ConvertToModelPosition( nStart );
     const ModelToViewHelper::ModelPosition aEndPos   =
-            ModelToViewHelper::ConvertToModelPosition( mpConversionMap, nStart + nLength - 1);
+            maConversionMap.ConvertToModelPosition( nStart + nLength - 1);
 
     const bool bStartInField = aStartPos.mbIsField;
     const bool bEndInField   = aEndPos.mbIsField;
@@ -181,8 +180,8 @@ void SAL_CALL SwXTextMarkup::commitTextMarkup(
                 pSubList = new SwGrammarMarkUp();
                 pWList->InsertSubList( nFieldPosModel, 1, nInsertPos, pSubList );
             }
-            const sal_uInt32 nTmpStart = ModelToViewHelper::ConvertToViewPosition( mpConversionMap, aStartPos.mnPos );
-            const sal_uInt32 nTmpLen = ModelToViewHelper::ConvertToViewPosition( mpConversionMap, aStartPos.mnPos + 1 )
+            const sal_uInt32 nTmpStart = maConversionMap.ConvertToViewPosition( aStartPos.mnPos );
+            const sal_uInt32 nTmpLen = maConversionMap.ConvertToViewPosition( aStartPos.mnPos + 1 )
                                        - nTmpStart - aStartPos.mnSubPos;
             if( nTmpLen > 0 )
             {
@@ -233,7 +232,7 @@ void SAL_CALL SwXTextMarkup::commitTextMarkup(
 
 
 void lcl_commitGrammarMarkUp(
-    const ModelToViewHelper::ConversionMap* pConversionMap,
+    const ModelToViewHelper& rConversionMap,
     SwGrammarMarkUp* pWList,
     ::sal_Int32 nType,
     const ::rtl::OUString & rIdentifier,
@@ -243,9 +242,9 @@ void lcl_commitGrammarMarkUp(
 {
     OSL_ENSURE( nType == text::TextMarkupType::PROOFREADING || nType == text::TextMarkupType::SENTENCE, "Wrong mark-up type" );
     const ModelToViewHelper::ModelPosition aStartPos =
-            ModelToViewHelper::ConvertToModelPosition( pConversionMap, nStart );
+            rConversionMap.ConvertToModelPosition( nStart );
     const ModelToViewHelper::ModelPosition aEndPos   =
-            ModelToViewHelper::ConvertToModelPosition( pConversionMap, nStart + nLength - 1);
+            rConversionMap.ConvertToModelPosition( nStart + nLength - 1);
 
     const bool bStartInField = aStartPos.mbIsField;
     const bool bEndInField   = aEndPos.mbIsField;
@@ -288,8 +287,8 @@ void lcl_commitGrammarMarkUp(
                 pSubList = new SwGrammarMarkUp();
                 pWList->InsertSubList( nFieldPosModel, 1, nInsertPos, pSubList );
             }
-            const sal_uInt32 nTmpStart = ModelToViewHelper::ConvertToViewPosition( pConversionMap, aStartPos.mnPos );
-            const sal_uInt32 nTmpLen = ModelToViewHelper::ConvertToViewPosition( pConversionMap, aStartPos.mnPos + 1 )
+            const sal_uInt32 nTmpStart = rConversionMap.ConvertToViewPosition( aStartPos.mnPos );
+            const sal_uInt32 nTmpLen = rConversionMap.ConvertToViewPosition( aStartPos.mnPos + 1 )
                                        - nTmpStart - aStartPos.mnSubPos;
             if( nTmpLen > 0 )
                 pSubList->Insert( rIdentifier, xMarkupInfoContainer,
@@ -391,7 +390,7 @@ throw (lang::IllegalArgumentException, uno::RuntimeException)
     if( pWList->GetBeginInv() < STRING_LEN )
     {
         const ModelToViewHelper::ModelPosition aSentenceEnd =
-            ModelToViewHelper::ConvertToModelPosition( mpConversionMap,
+            maConversionMap.ConvertToModelPosition(
                 pMarkups[nSentenceMarkUpIndex].nOffset + pMarkups[nSentenceMarkUpIndex].nLength );
         bAcceptGrammarError = (xub_StrLen)aSentenceEnd.mnPos > pWList->GetBeginInv();
         pWList->ClearGrammarList( (xub_StrLen)aSentenceEnd.mnPos );
@@ -402,7 +401,7 @@ throw (lang::IllegalArgumentException, uno::RuntimeException)
         for( i = 0;  i < nLen;  ++i )
         {
             const text::TextMarkupDescriptor &rDesc = pMarkups[i];
-            lcl_commitGrammarMarkUp( mpConversionMap, pWList, rDesc.nType,
+            lcl_commitGrammarMarkUp( maConversionMap, pWList, rDesc.nType,
                 rDesc.aIdentifier, rDesc.nOffset, rDesc.nLength, rDesc.xMarkupInfoContainer );
         }
     }
@@ -411,7 +410,7 @@ throw (lang::IllegalArgumentException, uno::RuntimeException)
         bRepaint = false;
         i = nSentenceMarkUpIndex;
         const text::TextMarkupDescriptor &rDesc = pMarkups[i];
-        lcl_commitGrammarMarkUp( mpConversionMap, pWList, rDesc.nType,
+        lcl_commitGrammarMarkUp( maConversionMap, pWList, rDesc.nType,
             rDesc.aIdentifier, rDesc.nOffset, rDesc.nLength, rDesc.xMarkupInfoContainer );
     }
 


More information about the Libreoffice-commits mailing list