sw; convert SwTxtNode::m_Text to OUString

Do not convert any of the 16bit index variables at this time: the
enforced limit of TXTNODE_MAX should ensure that they are sufficient,
and there are thousands of these variables all around sw.
(also, STRING_LEN/STRING_NOTFOUND is used as a "not found" value all
over the place)

Change-Id: Id26a145701de731470b0bcb95359ed62d4d6d579
diff --git a/sw/inc/ndtxt.hxx b/sw/inc/ndtxt.hxx
index fb46717..854dbdc 100644
--- a/sw/inc/ndtxt.hxx
+++ b/sw/inc/ndtxt.hxx
@@ -91,7 +91,7 @@ class SW_DLLPUBLIC SwTxtNode: public SwCntntNode, public ::sfx2::Metadatable

    mutable SwNodeNum* mpNodeNum;  ///< Numbering for this paragraph.

    XubString   m_Text;
    OUString m_Text;

    SwParaIdleData_Impl* m_pParaIdleData_Impl;

@@ -218,7 +218,7 @@ protected:
public:
    using SwCntntNode::GetAttr;

    const String& GetTxt() const { return m_Text; }
    const String& GetTxt() const { return (String&)m_Text; } //FIXME

    /// getters for SwpHints
    inline       SwpHints &GetSwpHints();
diff --git a/sw/source/core/inc/scriptinfo.hxx b/sw/source/core/inc/scriptinfo.hxx
index 82de2ea..bb05d1d 100644
--- a/sw/source/core/inc/scriptinfo.hxx
+++ b/sw/source/core/inc/scriptinfo.hxx
@@ -24,6 +24,8 @@
#include <deque>
#include "swscanner.hxx"

namespace rtl { class OUStringBuffer; }

class SwTxtNode;
class Point;
class MultiSelection;
@@ -184,14 +186,15 @@ public:

    @param  rNode
                The text node.
    @param  nPos
    @param  rText
                The string to modify.
    @param  cChar
                The character that should replace the hidden characters.
    @param  bDel
                If set, the hidden ranges will be deleted from the text node.
 */
    static sal_uInt16 MaskHiddenRanges( const SwTxtNode& rNode, XubString& rText,
    static sal_uInt16 MaskHiddenRanges(
            const SwTxtNode& rNode, ::rtl::OUStringBuffer& rText,
                                    const xub_StrLen nStt, const xub_StrLen nEnd,
                                    const sal_Unicode cChar );

diff --git a/sw/source/core/text/itratr.cxx b/sw/source/core/text/itratr.cxx
index 084df86..71885ad 100644
--- a/sw/source/core/text/itratr.cxx
+++ b/sw/source/core/text/itratr.cxx
@@ -623,7 +623,7 @@ void SwTxtNode::GetMinMaxSize( sal_uLong nIndex, sal_uLong& rMin, sal_uLong &rMa
    SwAttrIter aIter( *(SwTxtNode*)this, aScriptInfo );
    xub_StrLen nIdx = 0;
    aIter.SeekAndChgAttrIter( nIdx, pOut );
    xub_StrLen nLen = m_Text.Len();
    xub_StrLen nLen = m_Text.getLength();
    long nAktWidth = 0;
    MSHORT nAdd = 0;
    SwMinMaxArgs aArg( pOut, pSh, rMin, rMax, rAbsMin );
@@ -637,7 +637,7 @@ void SwTxtNode::GetMinMaxSize( sal_uLong nIndex, sal_uLong& rMin, sal_uLong &rMa
        sal_Unicode cChar = CH_BLANK;
        nStop = nIdx;
        while( nStop < nLen && nStop < nNextChg &&
               CH_TAB != ( cChar = m_Text.GetChar( nStop ) ) &&
               CH_TAB != ( cChar = m_Text[nStop] ) &&
               CH_BREAK != cChar && CHAR_HARDBLANK != cChar &&
               CHAR_HARDHYPHEN != cChar && CHAR_SOFTHYPHEN != cChar &&
               !pHint )
@@ -887,7 +887,7 @@ sal_uInt16 SwTxtNode::GetScalingOfSelectedText( xub_StrLen nStt, xub_StrLen nEnd
        // stop at special characters in [ nIdx, nNextChg ]
        while( nStop < nEnd && nStop < nNextChg )
        {
            cChar = m_Text.GetChar( nStop );
            cChar = m_Text[nStop];
            if (
                CH_TAB == cChar ||
                CH_BREAK == cChar ||
diff --git a/sw/source/core/text/porlay.cxx b/sw/source/core/text/porlay.cxx
index d6ce5be..27f1d18 100644
--- a/sw/source/core/text/porlay.cxx
+++ b/sw/source/core/text/porlay.cxx
@@ -1354,11 +1354,11 @@ sal_uInt8 SwScriptInfo::DirType( const xub_StrLen nPos ) const
 * Takes a string and replaced the hidden ranges with cChar.
 **************************************************************************/

sal_uInt16 SwScriptInfo::MaskHiddenRanges( const SwTxtNode& rNode, XubString& rText,
sal_uInt16 SwScriptInfo::MaskHiddenRanges( const SwTxtNode& rNode, OUStringBuffer & rText,
                                       const xub_StrLen nStt, const xub_StrLen nEnd,
                                       const sal_Unicode cChar )
{
    assert(rNode.GetTxt().Len() == rText.Len());
    assert(rNode.GetTxt().Len() == rText.getLength());

    PositionList aList;
    xub_StrLen nHiddenStart;
@@ -1379,7 +1379,7 @@ sal_uInt16 SwScriptInfo::MaskHiddenRanges( const SwTxtNode& rNode, XubString& rT
        {
            if ( nHiddenStart >= nStt && nHiddenStart < nEnd )
            {
                rText.SetChar( nHiddenStart, cChar );
                rText[nHiddenStart] = cChar;
                ++nNumOfHiddenChars;
            }
            ++nHiddenStart;
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index c5ffa22..77ac029 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -269,7 +269,7 @@ SwCntntFrm *SwTxtNode::MakeFrm( SwFrm* pSib )

xub_StrLen SwTxtNode::Len() const
{
    return m_Text.Len();
    return m_Text.getLength();
}

/*---------------------------------------------------------------------------
@@ -359,7 +359,7 @@ SwCntntNode *SwTxtNode::SplitCntntNode( const SwPosition &rPos )

    // lege den Node "vor" mir an
    const xub_StrLen nSplitPos = rPos.nContent.GetIndex();
    const xub_StrLen nTxtLen = m_Text.Len();
    const xub_StrLen nTxtLen = m_Text.getLength();
    SwTxtNode* const pNode =
        _MakeNewTxtNode( rPos.nNode, sal_False, nSplitPos==nTxtLen );

@@ -384,7 +384,7 @@ SwCntntNode *SwTxtNode::SplitCntntNode( const SwPosition &rPos )
        ResetAttr( RES_PARATR_LIST_LEVEL );
    }

    if ( GetDepends() && m_Text.Len() && (nTxtLen / 2) < nSplitPos )
    if ( GetDepends() && !m_Text.isEmpty() && (nTxtLen / 2) < nSplitPos )
    {
// JP 25.04.95: Optimierung fuer SplitNode:
//              Wird am Ende vom Node gesplittet, dann verschiebe die
@@ -603,7 +603,7 @@ void SwTxtNode::MoveTxtAttr_To_AttrSet()
        if( !pHtEndIdx )
            continue;

        if ( *pHtEndIdx < m_Text.Len() || pHt->IsCharFmtAttr() )
        if (*pHtEndIdx < m_Text.getLength() || pHt->IsCharFmtAttr())
            break;

        if( !pHt->IsDontMoveAttr() &&
@@ -627,7 +627,7 @@ SwCntntNode *SwTxtNode::JoinNext()
        std::vector<sal_uLong> aBkmkArr;
        _SaveCntntIdx( pDoc, aIdx.GetIndex(), USHRT_MAX, aBkmkArr, SAVEFLY );
        SwTxtNode *pTxtNode = aIdx.GetNode().GetTxtNode();
        xub_StrLen nOldLen = m_Text.Len();
        xub_StrLen nOldLen = m_Text.getLength();

        // METADATA: merge
        this->JoinMetadatable(*pTxtNode, !this->Len(), !pTxtNode->Len());
@@ -1102,7 +1102,7 @@ bool SwTxtNode::DontExpandFmt( const SwIndex& rIdx, bool bFlag,
                                bool bFmtToTxtAttributes )
{
    const xub_StrLen nIdx = rIdx.GetIndex();
    if ( bFmtToTxtAttributes && nIdx == m_Text.Len() )
    if (bFmtToTxtAttributes && nIdx == m_Text.getLength())
    {
        FmtToTxtAttr( this );
    }
@@ -1451,7 +1451,7 @@ void SwTxtNode::CopyText( SwTxtNode *const pDest,
                      const xub_StrLen nLen,
                      const bool bForceCopyOfAllAttrs )
{
    SwIndex aIdx( pDest, pDest->m_Text.Len() );
    SwIndex const aIdx( pDest, pDest->m_Text.getLength() );
    CopyText( pDest, aIdx, rStart, nLen, bForceCopyOfAllAttrs );
}

@@ -1510,15 +1510,15 @@ void SwTxtNode::CopyText( SwTxtNode *const pDest,
    }

    // 1. Text kopieren
    const xub_StrLen oldLen = pDest->m_Text.Len();
    const xub_StrLen oldLen = pDest->m_Text.getLength();
    //JP 15.02.96: Bug 25537 - Attributbehandlung am Ende fehlt! Darum
    //              ueber die InsertMethode den Text einfuegen und nicht
    //              selbst direkt
    pDest->InsertText( m_Text.Copy( nTxtStartIdx, nLen ), rDestStart,
    pDest->InsertText( m_Text.copy(nTxtStartIdx, nLen), rDestStart,
                   IDocumentContentOperations::INS_EMPTYEXPAND );

    // um reale Groesse Updaten !
    nLen = pDest->m_Text.Len() - oldLen;
    nLen = pDest->m_Text.getLength() - oldLen;
    if ( !nLen ) // string not longer?
        return;

@@ -1706,11 +1706,11 @@ void SwTxtNode::CopyText( SwTxtNode *const pDest,
OUString SwTxtNode::InsertText( const XubString & rStr, const SwIndex & rIdx,
        const IDocumentContentOperations::InsertFlags nMode )
{
    OSL_ENSURE( rIdx <= m_Text.Len(), "SwTxtNode::InsertText: invalid index." );
    OSL_ENSURE( rIdx <= m_Text.getLength(), "SwTxtNode::InsertText: invalid index." );

    xub_StrLen aPos = rIdx.GetIndex();
    xub_StrLen nLen = m_Text.Len() - aPos;
    long const nOverflow(static_cast<long>(m_Text.Len())
    xub_StrLen nLen = m_Text.getLength() - aPos;
    long const nOverflow(static_cast<long>(m_Text.getLength())
            + static_cast<long>(rStr.Len()) - TXTNODE_MAX);
    SAL_WARN_IF(nOverflow > 0, "sw.core",
            "SwTxtNode::InsertText: node text with insertion > TXTNODE_MAX.");
@@ -1720,9 +1720,9 @@ OUString SwTxtNode::InsertText( const XubString & rStr, const SwIndex & rIdx,
    {
        return sInserted;
    }
    m_Text.Insert(sInserted, aPos);
    assert(m_Text.Len() <= TXTNODE_MAX);
    nLen = m_Text.Len() - aPos - nLen;
    m_Text = m_Text.replaceAt(aPos, 0, sInserted);
    assert(m_Text.getLength() <= TXTNODE_MAX);
    nLen = m_Text.getLength() - aPos - nLen;
    assert(nLen != 0);

    bool bOldExpFlg = IsIgnoreDontExpand();
@@ -1864,14 +1864,17 @@ void SwTxtNode::CutImpl( SwTxtNode * const pDest, const SwIndex & rDestStart,

    xub_StrLen nTxtStartIdx = rStart.GetIndex();
    xub_StrLen nDestStart = rDestStart.GetIndex();      // alte Pos merken
    const xub_StrLen nInitSize = pDest->m_Text.Len();
    const xub_StrLen nInitSize = pDest->m_Text.getLength();

    // wird in sich selbst verschoben, muss es gesondert behandelt werden !!
    if( pDest == this )
    {
        OSL_FAIL("mst: entering dead and bitrotted code; fasten your seatbelts!");
        m_Text.Insert( m_Text, nTxtStartIdx, nLen, nDestStart );
        m_Text.Erase( nTxtStartIdx + (nDestStart<nTxtStartIdx ? nLen : 0), nLen );
        OUStringBuffer buf(m_Text);
        buf.insert(nDestStart, m_Text.copy(nTxtStartIdx, nLen));
        buf.remove(
            nTxtStartIdx + ((nDestStart < nTxtStartIdx) ? nLen : 0), nLen);
        m_Text = buf.makeStringAndClear();

        const xub_StrLen nEnd = rStart.GetIndex() + nLen;

@@ -1978,9 +1981,10 @@ void SwTxtNode::CutImpl( SwTxtNode * const pDest, const SwIndex & rDestStart,
    }
    else
    {
        pDest->m_Text.Insert( m_Text, nTxtStartIdx, nLen, nDestStart );
        m_Text.Erase( nTxtStartIdx, nLen );
        nLen = pDest->m_Text.Len() - nInitSize; // update w/ current size!
        pDest->m_Text = pDest->m_Text.replaceAt(nDestStart, 0,
                            m_Text.copy(nTxtStartIdx, nLen));
        m_Text = m_Text.replaceAt(nTxtStartIdx, nLen, "");
        nLen = pDest->m_Text.getLength() - nInitSize; // update w/ current size!
        if( !nLen )                 // String nicht gewachsen ??
            return;

@@ -2165,13 +2169,13 @@ void SwTxtNode::CutImpl( SwTxtNode * const pDest, const SwIndex & rDestStart,
void SwTxtNode::EraseText(const SwIndex &rIdx, const xub_StrLen nCount,
        const IDocumentContentOperations::InsertFlags nMode )
{
    OSL_ENSURE( rIdx <= m_Text.Len(), "SwTxtNode::EraseText: invalid index." );
    OSL_ENSURE( rIdx <= m_Text.getLength(), "SwTxtNode::EraseText: invalid index." );

    const xub_StrLen nStartIdx = rIdx.GetIndex();
    const xub_StrLen nCnt = (STRING_LEN == nCount)
                      ? m_Text.Len() - nStartIdx : nCount;
                      ? m_Text.getLength() - nStartIdx : nCount;
    const xub_StrLen nEndIdx = nStartIdx + nCnt;
    m_Text.Erase( nStartIdx, nCnt );
    m_Text = m_Text.replaceAt(nStartIdx, nCnt, "");

    /* GCAttr(); alle leeren weggwerfen ist zu brutal.
     * Es duerfen nur die wegggeworfen werden,
@@ -2278,7 +2282,7 @@ void SwTxtNode::GCAttr()
        return;

    bool   bChanged = false;
    sal_uInt16 nMin = m_Text.Len(),
    sal_uInt16 nMin = m_Text.getLength(),
           nMax = 0;
    bool bAll = nMin != 0; // Bei leeren Absaetzen werden nur die
                           // INet-Formate entfernt.
@@ -2959,16 +2963,20 @@ sal_Bool SwTxtNode::GetExpandTxt( SwTxtNode& rDestNd, const SwIndex* pDestIdx,
    xub_StrLen nDestStt = aDestIdx.GetIndex();

    // Text einfuegen
    String sTmpText = GetTxt();
    OUStringBuffer buf(GetTxt());
    if( bReplaceTabsWithSpaces )
        sTmpText.SearchAndReplaceAll('\t', ' ');
        buf.replace('\t', ' ');

    // mask hidden characters
    const sal_Unicode cChar = CH_TXTATR_BREAKWORD;
    SwScriptInfo::MaskHiddenRanges(*this, sTmpText, 0, sTmpText.Len(), cChar);
    SwScriptInfo::MaskHiddenRanges(*this, buf, 0, buf.getLength(), cChar);

    sTmpText = sTmpText.Copy( nIdx, nLen );
    rDestNd.InsertText( sTmpText, aDestIdx );
    buf.remove(0, nIdx);
    if (STRING_LEN != nLen)
    {
        buf.truncate(nLen);
    }
    rDestNd.InsertText(buf.makeStringAndClear(), aDestIdx);
    nLen = aDestIdx.GetIndex() - nDestStt;

    // alle FontAttribute mit CHARSET Symbol in dem Bereich setzen
@@ -3324,11 +3332,11 @@ XubString SwTxtNode::GetRedlineTxt( xub_StrLen nIdx, xub_StrLen nLen,
void SwTxtNode::ReplaceText( const SwIndex& rStart, const xub_StrLen nDelLen,
                             const XubString& rStr)
{
    OSL_ENSURE( rStart.GetIndex() < m_Text.Len() &&
            rStart.GetIndex() + nDelLen <= m_Text.Len(),
    OSL_ENSURE( rStart.GetIndex() < m_Text.getLength()
             && rStart.GetIndex() + nDelLen <= m_Text.getLength(),
            "SwTxtNode::ReplaceText: index out of bounds" );

    long const nOverflow(static_cast<long>(m_Text.Len())
    long const nOverflow(static_cast<long>(m_Text.getLength())
            + static_cast<long>(rStr.Len()) - nDelLen - TXTNODE_MAX);
    SAL_WARN_IF(nOverflow > 0, "sw.core",
            "SwTxtNode::ReplaceText: node text with insertion > TXTNODE_MAX.");
@@ -3344,8 +3352,8 @@ void SwTxtNode::ReplaceText( const SwIndex& rStart, const xub_StrLen nDelLen,
    xub_StrLen nLen = nDelLen;
    for ( xub_StrLen nPos = nStartPos; nPos < nEndPos; ++nPos )
    {
        if ( ( CH_TXTATR_BREAKWORD == m_Text.GetChar( nPos ) ) ||
             ( CH_TXTATR_INWORD    == m_Text.GetChar( nPos ) ) )
        if ((CH_TXTATR_BREAKWORD == m_Text[nPos]) ||
            (CH_TXTATR_INWORD    == m_Text[nPos]))
        {
            SwTxtAttr *const pHint = GetTxtAttrForCharAt( nPos );
            if (pHint)
@@ -3369,22 +3377,22 @@ void SwTxtNode::ReplaceText( const SwIndex& rStart, const xub_StrLen nDelLen,
    {
        // dann das 1. Zeichen ersetzen den Rest loschen und einfuegen
        // Dadurch wird die Attributierung des 1. Zeichen expandiert!
        m_Text.SetChar( nStartPos, sInserted[0] );
        m_Text = m_Text.replaceAt(nStartPos, 1, sInserted.copy(0, 1));

        ++((SwIndex&)rStart);
        m_Text.Erase( rStart.GetIndex(), nLen - 1 );
        m_Text = m_Text.replaceAt(rStart.GetIndex(), nLen - 1, "");
        Update( rStart, nLen - 1, true );

        XubString aTmpTxt(sInserted); aTmpTxt.Erase( 0, 1 );
        m_Text.Insert( aTmpTxt, rStart.GetIndex() );
        m_Text = m_Text.replaceAt(rStart.GetIndex(), 0, aTmpTxt);
        Update( rStart, aTmpTxt.Len(), false );
    }
    else
    {
        m_Text.Erase( nStartPos, nLen );
        m_Text = m_Text.replaceAt(nStartPos, nLen, "");
        Update( rStart, nLen, true );

        m_Text.Insert( sInserted, nStartPos );
        m_Text = m_Text.replaceAt(nStartPos, 0, sInserted);
        Update( rStart, sInserted.getLength(), false );
    }

diff --git a/sw/source/core/txtnode/thints.cxx b/sw/source/core/txtnode/thints.cxx
index e133f45f..e80d21b 100644
--- a/sw/source/core/txtnode/thints.cxx
+++ b/sw/source/core/txtnode/thints.cxx
@@ -1301,11 +1301,11 @@ bool SwTxtNode::InsertHint( SwTxtAttr * const pAttr, const SetAttrMode nMode )
                        {
                            // loesche das Zeichen aus dem String !
                            OSL_ENSURE( ( CH_TXTATR_BREAKWORD ==
                                        m_Text.GetChar(*pAttr->GetStart() ) ||
                                        m_Text[*pAttr->GetStart()] ||
                                      CH_TXTATR_INWORD ==
                                        m_Text.GetChar(*pAttr->GetStart())),
                                        m_Text[*pAttr->GetStart()]),
                                    "where is my attribute character?" );
                            m_Text.Erase( *pAttr->GetStart(), 1 );
                            m_Text = m_Text.replaceAt(*pAttr->GetStart(), 1, "");
                            // Indizies Updaten
                            SwIndex aTmpIdx( this, *pAttr->GetStart() );
                            Update( aTmpIdx, 1, sal_True );
@@ -1337,11 +1337,11 @@ bool SwTxtNode::InsertHint( SwTxtAttr * const pAttr, const SetAttrMode nMode )
                    {
                        // loesche das Zeichen aus dem String !
                        OSL_ENSURE( ( CH_TXTATR_BREAKWORD ==
                                      m_Text.GetChar(*pAttr->GetStart() ) ||
                                      m_Text[*pAttr->GetStart()] ||
                                  CH_TXTATR_INWORD ==
                                      m_Text.GetChar(*pAttr->GetStart())),
                                      m_Text[*pAttr->GetStart()]),
                                "where is my attribute character?" );
                        m_Text.Erase( *pAttr->GetStart(), 1 );
                        m_Text = m_Text.replaceAt(*pAttr->GetStart(), 1, "");
                        // Indizies Updaten
                        SwIndex aTmpIdx( this, *pAttr->GetStart() );
                        Update( aTmpIdx, 1, sal_True );
@@ -1473,8 +1473,8 @@ bool SwTxtNode::InsertHint( SwTxtAttr * const pAttr, const SetAttrMode nMode )
        // resulting in infinite recursion
        if ( !(nsSetAttrMode::SETATTR_NOTXTATRCHR & nMode) )
        {
            OSL_ENSURE( ( CH_TXTATR_BREAKWORD == m_Text.GetChar(nStart) ||
                      CH_TXTATR_INWORD    == m_Text.GetChar(nStart) ),
            OSL_ENSURE( ( CH_TXTATR_BREAKWORD == m_Text[nStart] ||
                          CH_TXTATR_INWORD    == m_Text[nStart] ),
                    "where is my attribute character?" );
            SwIndex aIdx( this, nStart );
            EraseText( aIdx, 1 );
@@ -1596,9 +1596,8 @@ void SwTxtNode::DeleteAttributes( const sal_uInt16 nWhich,

void SwTxtNode::DelSoftHyph( const xub_StrLen nStt, const xub_StrLen nEnd )
{
    xub_StrLen nFndPos = nStt, nEndPos = nEnd;
    while( STRING_NOTFOUND !=
            ( nFndPos = m_Text.Search( CHAR_SOFTHYPHEN, nFndPos )) &&
    sal_Int32 nFndPos = nStt, nEndPos = nEnd;
    while ((-1 != (nFndPos = m_Text.indexOf(CHAR_SOFTHYPHEN, nFndPos))) &&
            nFndPos < nEndPos )
    {
        const SwIndex aIdx( this, nFndPos );
@@ -1620,7 +1619,7 @@ sal_Bool SwTxtNode::SetAttr( const SfxItemSet& rSet, xub_StrLen nStt,
    SfxItemSet aTxtSet( *rSet.GetPool(), RES_TXTATR_BEGIN, RES_TXTATR_END-1 );

    // gesamter Bereich
    if ( !nStt && (nEnd == m_Text.Len()) &&
    if ( !nStt && (nEnd == m_Text.getLength()) &&
         !(nMode & nsSetAttrMode::SETATTR_NOFORMATATTR ) )
    {
        // sind am Node schon Zeichenvorlagen gesetzt, muss man diese Attribute
@@ -2192,7 +2191,7 @@ SwTxtNode::impl_FmtToTxtAttr(const SfxItemSet& i_rAttrSet)

    // 1. Identify all spans in hints' array

    lcl_CollectHintSpans(*m_pSwpHints, m_Text.Len(), aAttrSpanMap);
    lcl_CollectHintSpans(*m_pSwpHints, m_Text.getLength(), aAttrSpanMap);

    // 2. Go through all spans and insert new attrs

diff --git a/sw/source/core/txtnode/txtedt.cxx b/sw/source/core/txtnode/txtedt.cxx
index 40327cb7..de26219 100644
--- a/sw/source/core/txtnode/txtedt.cxx
+++ b/sw/source/core/txtnode/txtedt.cxx
@@ -95,7 +95,8 @@ extern       SwTxtFrm  *pLinguFrm;
 * only for deleted redlines
 */

static sal_uInt16 lcl_MaskRedlines( const SwTxtNode& rNode, XubString& rText,
static sal_uInt16
lcl_MaskRedlines( const SwTxtNode& rNode, OUStringBuffer& rText,
                         const xub_StrLen nStt, const xub_StrLen nEnd,
                         const sal_Unicode cChar )
{
@@ -125,7 +126,7 @@ static sal_uInt16 lcl_MaskRedlines( const SwTxtNode& rNode, XubString& rText,
            {
                if ( nRedlineStart >= nStt && nRedlineStart < nEnd )
                {
                    rText.SetChar( nRedlineStart, cChar );
                    rText[nRedlineStart] = cChar;
                    ++nNumOfMaskedRedlines;
                }
                ++nRedlineStart;
@@ -140,7 +141,8 @@ static sal_uInt16 lcl_MaskRedlines( const SwTxtNode& rNode, XubString& rText,
 * Used for spell checking. Deleted redlines and hidden characters are masked
 */

static sal_uInt16 lcl_MaskRedlinesAndHiddenText( const SwTxtNode& rNode, XubString& rText,
static sal_uInt16
lcl_MaskRedlinesAndHiddenText( const SwTxtNode& rNode, OUStringBuffer& rText,
                                      const xub_StrLen nStt, const xub_StrLen nEnd,
                                      const sal_Unicode cChar = CH_TXTATR_INWORD,
                                      bool bCheckShowHiddenChar = true )
@@ -384,7 +386,7 @@ void SwTxtNode::RstAttr(const SwIndex &rIdx, xub_StrLen nLen, sal_uInt16 nWhich,
    bool bChanged = false;

    // nMin and nMax initialized to maximum / minimum (inverse)
    xub_StrLen nMin = m_Text.Len();
    xub_StrLen nMin = m_Text.getLength();
    xub_StrLen nMax = nStt;

    const bool bNoLen = !nMin;
@@ -605,9 +607,9 @@ void SwTxtNode::RstAttr(const SwIndex &rIdx, xub_StrLen nLen, sal_uInt16 nWhich,

XubString SwTxtNode::GetCurWord( xub_StrLen nPos ) const
{
    OSL_ENSURE( nPos <= m_Text.Len(), "SwTxtNode::GetCurWord: invalid index." );
    OSL_ENSURE( nPos <= m_Text.getLength(), "SwTxtNode::GetCurWord: invalid index." );

    if (!m_Text.Len())
    if (m_Text.isEmpty())
        return m_Text;

    Boundary aBndry;
@@ -637,8 +639,8 @@ XubString SwTxtNode::GetCurWord( xub_StrLen nPos ) const
    if (aBndry.endPos != aBndry.startPos && IsSymbol( (xub_StrLen)aBndry.startPos ))
        aBndry.endPos = aBndry.startPos;

    return m_Text.Copy( static_cast<xub_StrLen>(aBndry.startPos),
                       static_cast<xub_StrLen>(aBndry.endPos - aBndry.startPos) );
    return m_Text.copy(aBndry.startPos,
                       aBndry.endPos - aBndry.startPos);
}

SwScanner::SwScanner( const SwTxtNode& rNd, const rtl::OUString& rTxt,
@@ -872,9 +874,14 @@ sal_uInt16 SwTxtNode::Spell(SwSpellArgs* pArgs)
    xub_StrLen nBegin, nEnd;

    // modify string according to redline information and hidden text
    const XubString aOldTxt( m_Text );
    const OUString aOldTxt( m_Text );
    OUStringBuffer buf(m_Text);
    const bool bRestoreString =
        lcl_MaskRedlinesAndHiddenText( *this, m_Text, 0, m_Text.Len() ) > 0;
        lcl_MaskRedlinesAndHiddenText(*this, buf, 0, m_Text.getLength()) > 0;
    if (bRestoreString)
    {   // ??? UGLY: is it really necessary to modify m_Text here?
        m_Text = buf.makeStringAndClear();
    }

    if ( pArgs->pStartNode != this )
        nBegin = 0;
@@ -882,7 +889,7 @@ sal_uInt16 SwTxtNode::Spell(SwSpellArgs* pArgs)
        nBegin = pArgs->pStartIdx->GetIndex();

    nEnd = ( pArgs->pEndNode != this )
            ? m_Text.Len()
            ? m_Text.getLength()
            : pArgs->pEndIdx->GetIndex();

    pArgs->xSpellAlt = NULL;
@@ -899,15 +906,15 @@ sal_uInt16 SwTxtNode::Spell(SwSpellArgs* pArgs)
    //      Text has been checked but there is an invalid range in the wrong list
    //
    // Nothing has to be done for case 1.
    if ( ( IsWrongDirty() || GetWrong() ) && m_Text.Len() )
    if ( ( IsWrongDirty() || GetWrong() ) && m_Text.getLength() )
    {
        if ( nBegin > m_Text.Len() )
        if (nBegin > m_Text.getLength())
        {
            nBegin = m_Text.Len();
            nBegin = m_Text.getLength();
        }
        if ( nEnd > m_Text.Len() )
        if (nEnd > m_Text.getLength())
        {
            nEnd = m_Text.Len();
            nEnd = m_Text.getLength();
        }
        //
        if(!IsWrongDirty())
@@ -1037,27 +1044,32 @@ sal_uInt16 SwTxtNode::Convert( SwConversionArgs &rArgs )
    }
    else
        nTextBegin = rArgs.pStartIdx->GetIndex();
    if (nTextBegin > m_Text.Len())
    if (nTextBegin > m_Text.getLength())
    {
        nTextBegin = m_Text.Len();
        nTextBegin = m_Text.getLength();
    }

    nTextEnd = ( rArgs.pEndNode != this )
        ?  m_Text.Len()
        :  ::std::min( rArgs.pEndIdx->GetIndex(), m_Text.Len() );
        ?  m_Text.getLength()
        :  ::std::min<xub_StrLen>(rArgs.pEndIdx->GetIndex(), m_Text.getLength());

    rArgs.aConvText = rtl::OUString();

    // modify string according to redline information and hidden text
    const OUString aOldTxt( m_Text );
    OUStringBuffer buf(m_Text);
    const bool bRestoreString =
        lcl_MaskRedlinesAndHiddenText( *this, m_Text, 0, m_Text.Len() ) > 0;
        lcl_MaskRedlinesAndHiddenText(*this, buf, 0, m_Text.getLength()) > 0;
    if (bRestoreString)
    {   // ??? UGLY: is it really necessary to modify m_Text here?
        m_Text = buf.makeStringAndClear();
    }

    bool    bFound  = false;
    xub_StrLen  nBegin  = nTextBegin;
    xub_StrLen  nLen = 0;
    LanguageType nLangFound = LANGUAGE_NONE;
    if (!m_Text.Len())
    if (m_Text.isEmpty())
    {
        if (rArgs.bAllowImplicitChangesForNotConvertibleText)
        {
@@ -1093,7 +1105,7 @@ sal_uInt16 SwTxtNode::Convert( SwConversionArgs &rArgs )
            // and thus must be cut to the end of the actual string.
            if (nChPos == (xub_StrLen) -1)
            {
                nChPos = m_Text.Len();
                nChPos = m_Text.getLength();
            }

            nLen = nChPos - nBegin;
@@ -1142,8 +1154,8 @@ sal_uInt16 SwTxtNode::Convert( SwConversionArgs &rArgs )

    if (bFound && bInSelection)     // convertible text found within selection/range?
    {
        OSL_ENSURE( m_Text.Len() > 0, "convertible text portion missing!" );
        rArgs.aConvText     = m_Text.Copy( nBegin, nLen );
        OSL_ENSURE( !m_Text.isEmpty(), "convertible text portion missing!" );
        rArgs.aConvText     = m_Text.copy(nBegin, nLen);
        rArgs.nConvTextLang = nLangFound;

        // position where to start looking in next iteration (after current ends)
@@ -1182,14 +1194,18 @@ SwRect SwTxtFrm::_AutoSpell( const SwCntntNode* pActNode, const SwViewOption& rV
    SwAutoCompleteWord& rACW = SwDoc::GetAutoCompleteWords();

    // modify string according to redline information and hidden text
    const XubString aOldTxt( pNode->GetTxt() );
    const bool bRestoreString =
            lcl_MaskRedlinesAndHiddenText( *pNode, pNode->m_Text,
    const OUString aOldTxt( pNode->GetTxt() );
    OUStringBuffer buf(pNode->m_Text);
    const bool bRestoreString = lcl_MaskRedlinesAndHiddenText( *pNode, buf,
                0, pNode->GetTxt().Len() )     > 0;
    if (bRestoreString)
    {   // ??? UGLY: is it really necessary to modify m_Text here?
        pNode->m_Text = buf.makeStringAndClear();
    }

    // a change of data indicates that at least one word has been modified
    const bool bRedlineChg =
        ( pNode->GetTxt().GetBuffer() != aOldTxt.GetBuffer() );
        ( pNode->GetTxt().GetBuffer() != aOldTxt.getStr() );

    xub_StrLen nBegin = 0;
    xub_StrLen nEnd = pNode->GetTxt().Len();
@@ -1526,7 +1542,7 @@ sal_Bool SwTxtNode::Hyphenate( SwInterHyphInfo &rHyphInf )
{
    // Abkuerzung: am Absatz ist keine Sprache eingestellt:
    if ( LANGUAGE_NONE == sal_uInt16( GetSwAttrSet().GetLanguage().GetLanguage() )
         && USHRT_MAX == GetLang( 0, m_Text.Len() ) )
         && USHRT_MAX == GetLang(0, m_Text.getLength()))
    {
        if( !rHyphInf.IsCheck() )
            rHyphInf.SetNoLang( sal_True );
@@ -1648,9 +1664,13 @@ void SwTxtNode::TransliterateText(
                OSL_ENSURE( nLen > 0, "invalid word length of 0" );

                Sequence <sal_Int32> aOffsets;
                String sChgd( rTrans.transliterate( GetTxt(), GetLang( nStt ), nStt, nLen, &aOffsets ));
                OUString const sChgd( rTrans.transliterate(
                            GetTxt(), GetLang(nStt), nStt, nLen, &aOffsets) );

                if (!m_Text.Equals( sChgd, nStt, nLen ))
                assert(nStt < m_Text.getLength());
                if (0 == rtl_ustr_shortenedCompare_WithLength(
                            m_Text.getStr() + nStt, m_Text.getLength() - nStt,
                            sChgd.getStr(), sChgd.getLength(), nLen))
                {
                    aChgData.nStart     = nStt;
                    aChgData.nLen       = nLen;
@@ -1728,10 +1748,13 @@ void SwTxtNode::TransliterateText(
                OSL_ENSURE( nLen > 0, "invalid word length of 0" );

                Sequence <sal_Int32> aOffsets;
                String sChgd( rTrans.transliterate( GetTxt(),
                        GetLang( nCurrentStart ), nCurrentStart, nLen, &aOffsets ));
                OUString const sChgd( rTrans.transliterate(GetTxt(),
                    GetLang(nCurrentStart), nCurrentStart, nLen, &aOffsets) );

                if (!m_Text.Equals( sChgd, nStt, nLen ))
                assert(nStt < m_Text.getLength());
                if (0 == rtl_ustr_shortenedCompare_WithLength(
                            m_Text.getStr() + nStt, m_Text.getLength() - nStt,
                            sChgd.getStr(), sChgd.getLength(), nLen))
                {
                    aChgData.nStart     = nCurrentStart;
                    aChgData.nLen       = nLen;
@@ -1779,9 +1802,13 @@ void SwTxtNode::TransliterateText(
                xub_StrLen nLen = nEndPos - nStt;

                Sequence <sal_Int32> aOffsets;
                String sChgd( rTrans.transliterate( m_Text, nLang, nStt, nLen, &aOffsets ));
                OUString const sChgd( rTrans.transliterate(
                            m_Text, nLang, nStt, nLen, &aOffsets) );

                if (!m_Text.Equals( sChgd, nStt, nLen ))
                assert(nStt < m_Text.getLength());
                if (0 == rtl_ustr_shortenedCompare_WithLength(
                            m_Text.getStr() + nStt, m_Text.getLength() - nStt,
                            sChgd.getStr(), sChgd.getLength(), nLen))
                {
                    aChgData.nStart     = nStt;
                    aChgData.nLen       = nLen;
@@ -1799,7 +1826,7 @@ void SwTxtNode::TransliterateText(
        {
            // now apply the changes from end to start to leave the offsets of the
            // yet unchanged text parts remain the same.
            size_t nSum(m_Text.Len());
            size_t nSum(m_Text.getLength());
            for (size_t i = 0; i < aChanges.size(); ++i)
            {   // check this here since AddChanges cannot be moved below
                // call to ReplaceTextOnly
@@ -1824,10 +1851,10 @@ void SwTxtNode::ReplaceTextOnly( xub_StrLen nPos, xub_StrLen nLen,
                                const XubString& rText,
                                const Sequence<sal_Int32>& rOffsets )
{
    assert(static_cast<size_t>(m_Text.Len()) +
    assert(static_cast<size_t>(m_Text.getLength()) +
        static_cast<size_t>(rText.Len()) - nLen <= TXTNODE_MAX);

    m_Text.Replace( nPos, nLen, rText );
    m_Text = m_Text.replaceAt(nPos, nLen, rText);

    xub_StrLen nTLen = rText.Len();
    const sal_Int32* pOffsets = rOffsets.getConstArray();