LCOV - code coverage report
Current view: top level - sw/source/core/txtnode - ndtxt.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 1563 2176 71.8 %
Date: 2014-04-11 Functions: 109 121 90.1 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <hintids.hxx>
      21             : #include <hints.hxx>
      22             : 
      23             : #include <comphelper/string.hxx>
      24             : #include <editeng/fontitem.hxx>
      25             : #include <editeng/formatbreakitem.hxx>
      26             : #include <editeng/escapementitem.hxx>
      27             : #include <editeng/lrspitem.hxx>
      28             : #include <editeng/rsiditem.hxx>
      29             : #include <editeng/tstpitem.hxx>
      30             : #include <svl/urihelper.hxx>
      31             : #include <svl/ctloptions.hxx>
      32             : #include <swmodule.hxx>
      33             : #include <txtfld.hxx>
      34             : #include <txtinet.hxx>
      35             : #include <fmtinfmt.hxx>
      36             : #include <fmtpdsc.hxx>
      37             : #include <txtatr.hxx>
      38             : #include <fmtrfmrk.hxx>
      39             : #include <txttxmrk.hxx>
      40             : #include <fchrfmt.hxx>
      41             : #include <txtftn.hxx>
      42             : #include <fmtflcnt.hxx>
      43             : #include <fmtfld.hxx>
      44             : #include <frmatr.hxx>
      45             : #include <charatr.hxx>
      46             : #include <ftnidx.hxx>
      47             : #include <ftninfo.hxx>
      48             : #include <fmtftn.hxx>
      49             : #include <fmtmeta.hxx>
      50             : #include <charfmt.hxx>
      51             : #include <ndtxt.hxx>
      52             : #include <doc.hxx>
      53             : #include <IDocumentUndoRedo.hxx>
      54             : #include <docary.hxx>
      55             : #include <pam.hxx>
      56             : #include <fldbas.hxx>
      57             : #include <paratr.hxx>
      58             : #include <txtfrm.hxx>
      59             : #include <ftnfrm.hxx>
      60             : #include <ftnboss.hxx>
      61             : #include <rootfrm.hxx>
      62             : #include <pagedesc.hxx>
      63             : #include <expfld.hxx>
      64             : #include <section.hxx>
      65             : #include <mvsave.hxx>
      66             : #include <swcache.hxx>
      67             : #include <SwGrammarMarkUp.hxx>
      68             : #include <dcontact.hxx>
      69             : #include <redline.hxx>
      70             : #include <doctxm.hxx>
      71             : #include <IMark.hxx>
      72             : #include <scriptinfo.hxx>
      73             : #include <istyleaccess.hxx>
      74             : #include <SwStyleNameMapper.hxx>
      75             : #include <numrule.hxx>
      76             : #include <swtable.hxx>
      77             : #include <docsh.hxx>
      78             : #include <SwNodeNum.hxx>
      79             : #include <svl/intitem.hxx>
      80             : #include <list.hxx>
      81             : #include <switerator.hxx>
      82             : #include <attrhint.hxx>
      83             : #include <boost/scoped_ptr.hpp>
      84             : 
      85             : using namespace ::com::sun::star;
      86             : 
      87             : typedef std::vector<SwTxtAttr*> SwpHts;
      88             : 
      89      612809 : TYPEINIT1( SwTxtNode, SwCntntNode )
      90             : 
      91             : // unfortunately everyone can change Hints without ensuring order or the linking between them
      92             : #ifdef DBG_UTIL
      93             : #define CHECK_SWPHINTS(pNd)  { if( pNd->GetpSwpHints() && \
      94             :                                    !pNd->GetDoc()->IsInReading() ) \
      95             :                                   pNd->GetpSwpHints()->Check(true); }
      96             : #else
      97             : #define CHECK_SWPHINTS(pNd)
      98             : #endif
      99             : 
     100        5784 : SwTxtNode *SwNodes::MakeTxtNode( const SwNodeIndex & rWhere,
     101             :                                  SwTxtFmtColl *pColl,
     102             :                                  SwAttrSet* pAutoAttr )
     103             : {
     104             :     OSL_ENSURE( pColl, "Collection pointer is 0." );
     105             : 
     106        5784 :     SwTxtNode *pNode = new SwTxtNode( rWhere, pColl, pAutoAttr );
     107             : 
     108        5784 :     SwNodeIndex aIdx( *pNode );
     109             : 
     110             :     // #125329#
     111             :     // call method <UpdateOutlineNode(..)> only for the document nodes array
     112        5784 :     if ( IsDocNodes() )
     113        5784 :         UpdateOutlineNode(*pNode);
     114             : 
     115             :     // if there is no layout or it is in a hidden section, MakeFrms is not needed
     116             :     const SwSectionNode* pSectNd;
     117       11582 :     if( !GetDoc()->GetCurrentViewShell() ||
     118         373 :         ( 0 != (pSectNd = pNode->FindSectionNode()) &&
     119          37 :             pSectNd->GetSection().IsHiddenFlag() ))
     120        5462 :         return pNode;
     121             : 
     122         644 :     SwNodeIndex aTmp( rWhere );
     123             :     do {
     124             :         // max. 2 loops:
     125             :         // 1. take the successor
     126             :         // 2. take the predecessor
     127             : 
     128         605 :         SwNode * pNd = & aTmp.GetNode();
     129         605 :         switch (pNd->GetNodeType())
     130             :         {
     131             :         case ND_TABLENODE:
     132           5 :             ((SwTableNode*)pNd)->MakeFrms( aIdx );
     133           5 :             return pNode;
     134             : 
     135             :         case ND_SECTIONNODE:
     136           4 :             if( ((SwSectionNode*)pNd)->GetSection().IsHidden() ||
     137           2 :                 ((SwSectionNode*)pNd)->IsCntntHidden() )
     138             :             {
     139           0 :                 SwNodeIndex aTmpIdx( *pNode );
     140           0 :                 pNd = FindPrvNxtFrmNode( aTmpIdx, pNode );
     141           0 :                 if( !pNd )
     142           0 :                     return pNode;
     143           0 :                 aTmp = *pNd;
     144           0 :                 break;
     145             :             }
     146           2 :             ((SwSectionNode*)pNd)->MakeFrms( aIdx );
     147           2 :             return pNode;
     148             : 
     149             :         case ND_TEXTNODE:
     150             :         case ND_GRFNODE:
     151             :         case ND_OLENODE:
     152          68 :             ((SwCntntNode*)pNd)->MakeFrms( *pNode );
     153          68 :             return pNode;
     154             : 
     155             :         case ND_ENDNODE:
     156         312 :             if( pNd->StartOfSectionNode()->IsSectionNode() &&
     157           0 :                 aTmp.GetIndex() < rWhere.GetIndex() )
     158             :             {
     159           0 :                 if( pNd->StartOfSectionNode()->GetSectionNode()->GetSection().IsHiddenFlag())
     160             :                 {
     161           0 :                     if( !GoPrevSection( &aTmp, true, false ) ||
     162           0 :                         aTmp.GetNode().FindTableNode() !=
     163           0 :                             pNode->FindTableNode() )
     164           0 :                         return pNode;       // schade, das wars
     165             :                 }
     166             :                 else
     167           0 :                     aTmp = *pNd->StartOfSectionNode();
     168           0 :                 break;
     169             :             }
     170         314 :             else if( pNd->StartOfSectionNode()->IsTableNode() &&
     171           2 :                     aTmp.GetIndex() < rWhere.GetIndex() )
     172             :             {
     173             :                 // after a table node
     174           0 :                 aTmp = *pNd->StartOfSectionNode();
     175           0 :                 break;
     176             :             }
     177             :             // no break !!!
     178             :         default:
     179         530 :             if( rWhere == aTmp )
     180         283 :                 aTmp -= 2;
     181             :             else
     182         247 :                 return pNode;
     183         283 :             break;
     184             :         }
     185        5784 :     } while( true );
     186             : }
     187             : 
     188             : // SwTxtNode
     189             : 
     190       37106 : SwTxtNode::SwTxtNode( const SwNodeIndex &rWhere,
     191             :                       SwTxtFmtColl *pTxtColl,
     192             :                       const SfxItemSet* pAutoAttr )
     193             :     : SwCntntNode( rWhere, ND_TEXTNODE, pTxtColl ),
     194             :       m_pSwpHints( 0 ),
     195             :       mpNodeNum( 0 ),
     196             :       m_bLastOutlineState( false ),
     197             :       m_bNotifiable( false ),
     198             :       // #i70748#
     199             :       mbEmptyListStyleSetDueToSetOutlineLevelAttr( false ),
     200             :       mbInSetOrResetAttr( false ),
     201       37106 :       mpList( 0 )
     202             : {
     203       37106 :     InitSwParaStatistics( true );
     204             : 
     205       37106 :     if( pAutoAttr )
     206        1750 :         SetAttr( *pAutoAttr );
     207             : 
     208       37106 :     if (!IsInList() && GetNumRule() && !GetListId().isEmpty())
     209             :     {
     210             :         // #i101516#
     211             :         // apply paragraph style's assigned outline style list level as
     212             :         // list level of the paragraph, if it has none set already.
     213         402 :         if ( !HasAttrListLevel() &&
     214         201 :              pTxtColl && pTxtColl->IsAssignedToListLevelOfOutlineStyle() )
     215             :         {
     216           0 :             SetAttrListLevel( pTxtColl->GetAssignedOutlineStyleLevel() );
     217             :         }
     218         201 :         AddToList();
     219             :     }
     220       37106 :     GetNodes().UpdateOutlineNode(*this);
     221             : 
     222       37106 :     m_bNotifiable = true;
     223             : 
     224       37106 :     m_bContainsHiddenChars = m_bHiddenCharsHidePara = false;
     225       37106 :     m_bRecalcHiddenCharFlags = true;
     226       37106 : }
     227             : 
     228      111174 : SwTxtNode::~SwTxtNode()
     229             : {
     230             :     // delete only removes the pointer not the array elements!
     231       37058 :     if ( m_pSwpHints )
     232             :     {
     233             :         // do not delete attributes twice when those delte their content
     234       14619 :         SwpHints* pTmpHints = m_pSwpHints;
     235       14619 :         m_pSwpHints = 0;
     236             : 
     237       60812 :         for( sal_uInt16 j = pTmpHints->Count(); j; )
     238             :         {
     239             :             // first remove the attribute from the array otherwise
     240             :             // if would delete itself
     241       31574 :             DestroyAttr( pTmpHints->GetTextHint( --j ) );
     242             :         }
     243             : 
     244       14619 :         delete pTmpHints;
     245             :     }
     246             : 
     247             :     // must be removed from outline nodes by now
     248             : #if OSL_DEBUG_LEVEL > 0
     249             :     sal_uInt16 foo;
     250             :     assert(!GetNodes().GetOutLineNds().Seek_Entry(this, &foo));
     251             : #endif
     252             : 
     253       37058 :     RemoveFromList();
     254             : 
     255       37058 :     InitSwParaStatistics( false );
     256       74116 : }
     257             : 
     258       25822 : SwCntntFrm *SwTxtNode::MakeFrm( SwFrm* pSib )
     259             : {
     260             :     // fdo#52028: ODF file import does not result in MergePortions being called
     261             :     // for every attribute, since that would be inefficient.  So call it here.
     262       25822 :     if (m_pSwpHints)
     263             :     {
     264       11908 :         m_pSwpHints->MergePortions(*this);
     265             :     }
     266       25822 :     SwCntntFrm *pFrm = new SwTxtFrm( this, pSib );
     267       25822 :     return pFrm;
     268             : }
     269             : 
     270      593821 : sal_Int32 SwTxtNode::Len() const
     271             : {
     272      593821 :     return m_Text.getLength();
     273             : }
     274             : 
     275             : /*---------------------------------------------------------------------------
     276             :  * lcl_ChangeFtnRef
     277             :  *  After a split node, it's necessary to actualize the ref-pointer of the
     278             :  *  ftnfrms.
     279             :  * --------------------------------------------------------------------------*/
     280             : 
     281         582 : static void lcl_ChangeFtnRef( SwTxtNode &rNode )
     282             : {
     283         582 :     SwpHints *pSwpHints = rNode.GetpSwpHints();
     284         582 :     if( pSwpHints && rNode.GetDoc()->GetCurrentViewShell() )
     285             :     {
     286             :         SwTxtAttr* pHt;
     287           0 :         SwCntntFrm* pFrm = NULL;
     288             :         // OD 07.11.2002 #104840# - local variable to remember first footnote
     289             :         // of node <rNode> in order to invalidate position of its first content.
     290             :         // Thus, in its <MakeAll()> it will checked its position relative to its reference.
     291           0 :         SwFtnFrm* pFirstFtnOfNode = 0;
     292           0 :         for( sal_uInt16 j = pSwpHints->Count(); j; )
     293             :         {
     294           0 :             pHt = pSwpHints->GetTextHint(--j);
     295           0 :             if (RES_TXTATR_FTN == pHt->Which())
     296             :             {
     297           0 :                 if( !pFrm )
     298             :                 {
     299           0 :                     pFrm = SwIterator<SwCntntFrm,SwTxtNode>::FirstElement( rNode );
     300           0 :                     if( !pFrm )
     301         582 :                         return;
     302             :                 }
     303           0 :                 SwTxtFtn *pAttr = (SwTxtFtn*)pHt;
     304             :                 OSL_ENSURE( pAttr->GetStartNode(), "FtnAtr ohne StartNode." );
     305           0 :                 SwNodeIndex aIdx( *pAttr->GetStartNode(), 1 );
     306           0 :                 SwCntntNode *pNd = aIdx.GetNode().GetCntntNode();
     307           0 :                 if ( !pNd )
     308             :                     pNd = pFrm->GetAttrSet()->GetDoc()->
     309           0 :                             GetNodes().GoNextSection( &aIdx, true, false );
     310           0 :                 if ( !pNd )
     311           0 :                     continue;
     312             : 
     313           0 :                 SwIterator<SwCntntFrm,SwCntntNode> aIter( *pNd );
     314           0 :                 SwCntntFrm* pCntnt = aIter.First();
     315           0 :                 if( pCntnt )
     316             :                 {
     317             :                     OSL_ENSURE( pCntnt->getRootFrm() == pFrm->getRootFrm(),
     318             :                             "lcl_ChangeFtnRef: Layout double?" );
     319           0 :                     SwFtnFrm *pFtn = pCntnt->FindFtnFrm();
     320           0 :                     if( pFtn && pFtn->GetAttr() == pAttr )
     321             :                     {
     322           0 :                         while( pFtn->GetMaster() )
     323           0 :                             pFtn = pFtn->GetMaster();
     324             :                         // #104840# - remember footnote frame
     325           0 :                         pFirstFtnOfNode = pFtn;
     326           0 :                         while ( pFtn )
     327             :                         {
     328           0 :                             pFtn->SetRef( pFrm );
     329           0 :                             pFtn = pFtn->GetFollow();
     330           0 :                             ((SwTxtFrm*)pFrm)->SetFtn( true );
     331             :                         }
     332             :                     }
     333             : #if OSL_DEBUG_LEVEL > 0
     334             :                     while( 0 != (pCntnt = aIter.Next()) )
     335             :                     {
     336             :                         SwFtnFrm *pDbgFtn = pCntnt->FindFtnFrm();
     337             :                         OSL_ENSURE( !pDbgFtn || pDbgFtn->GetRef() == pFrm,
     338             :                                 "lcl_ChangeFtnRef: Who's that guy?" );
     339             :                     }
     340             : #endif
     341           0 :                 }
     342             :             }
     343             :         } // end of for-loop on <SwpHints>
     344             :         // #104840# - invalidate
     345           0 :         if ( pFirstFtnOfNode )
     346             :         {
     347           0 :             SwCntntFrm* pCntnt = pFirstFtnOfNode->ContainsCntnt();
     348           0 :             if ( pCntnt )
     349             :             {
     350           0 :                 pCntnt->_InvalidatePos();
     351             :             }
     352             :         }
     353             :     }
     354             : }
     355             : 
     356         582 : SwCntntNode *SwTxtNode::SplitCntntNode( const SwPosition &rPos )
     357             : {
     358         582 :     bool parentIsOutline = IsOutline();
     359             : 
     360             :     // create a node "in front" of me
     361         582 :     const sal_Int32 nSplitPos = rPos.nContent.GetIndex();
     362         582 :     const sal_Int32 nTxtLen = m_Text.getLength();
     363             :     SwTxtNode* const pNode =
     364         582 :         _MakeNewTxtNode( rPos.nNode, false, nSplitPos==nTxtLen );
     365             : 
     366             :     // the first paragraph gets the XmlId,
     367             :     // _except_ if it is empty and the second is not empty
     368         582 :     if (nSplitPos != 0) {
     369         403 :         pNode->RegisterAsCopyOf(*this, true);
     370         403 :         if (nSplitPos == nTxtLen)
     371             :         {
     372         362 :             this->RemoveMetadataReference();
     373             :             // NB: SwUndoSplitNode will call pNode->JoinNext,
     374             :             // which is sufficient even in this case!
     375             :         }
     376             :     }
     377             : 
     378         582 :     ResetAttr( RES_PARATR_LIST_ISRESTART );
     379         582 :     ResetAttr( RES_PARATR_LIST_RESTARTVALUE );
     380         582 :     ResetAttr( RES_PARATR_LIST_ISCOUNTED );
     381         582 :     if ( GetNumRule() == 0 || (parentIsOutline && !IsOutline()) )
     382             :     {
     383         582 :         ResetAttr( RES_PARATR_LIST_ID );
     384         582 :         ResetAttr( RES_PARATR_LIST_LEVEL );
     385             :     }
     386             : 
     387         582 :     if ( GetDepends() && !m_Text.isEmpty() && (nTxtLen / 2) < nSplitPos )
     388             :     {
     389             :         // optimization for SplitNode: If a split is at the end of a node then
     390             :         // move the frames from the current to the new one and create new ones
     391             :         // for the current one. As a result, no need for recreating the layout.
     392             : 
     393         102 :         LockModify();   // disable notifications
     394             : 
     395             :         // werden FlyFrames mit verschoben, so muessen diese nicht ihre
     396             :         // Frames zerstoeren. Im SwTxtFly::SetAnchor wird es abgefragt!
     397         102 :         if ( HasHints() )
     398             :         {
     399           1 :             pNode->GetOrCreateSwpHints().SetInSplitNode(true);
     400             :         }
     401             : 
     402             :         //Ersten Teil des Inhalts in den neuen Node uebertragen und
     403             :         //im alten Node loeschen.
     404         102 :         SwIndex aIdx( this );
     405         102 :         CutText( pNode, aIdx, nSplitPos );
     406             : 
     407         102 :         if( GetWrong() )
     408             :         {
     409          84 :             pNode->SetWrong( GetWrong()->SplitList( nSplitPos ) );
     410             :         }
     411         102 :         SetWrongDirty( true );
     412             : 
     413         102 :         if( GetGrammarCheck() )
     414             :         {
     415           0 :             pNode->SetGrammarCheck( GetGrammarCheck()->SplitGrammarList( nSplitPos ) );
     416             :         }
     417         102 :         SetGrammarCheckDirty( true );
     418             : 
     419         102 :         SetWordCountDirty( true );
     420             : 
     421         102 :         if( GetSmartTags() )
     422             :         {
     423           0 :             pNode->SetSmartTags( GetSmartTags()->SplitList( nSplitPos ) );
     424             :         }
     425         102 :         SetSmartTagDirty( true );
     426             : 
     427         102 :         if ( pNode->HasHints() )
     428             :         {
     429           1 :             if ( pNode->m_pSwpHints->CanBeDeleted() )
     430             :             {
     431           0 :                 delete pNode->m_pSwpHints;
     432           0 :                 pNode->m_pSwpHints = 0;
     433             :             }
     434             :             else
     435             :             {
     436           1 :                 pNode->m_pSwpHints->SetInSplitNode(false);
     437             :             }
     438             : 
     439             :             // alle zeichengebundenen Rahmen, die im neuen Absatz laden
     440             :             // muessen aus den alten Frame entfernt werden:
     441             :             // JP 01.10.96: alle leeren und nicht zu expandierenden
     442             :             //              Attribute loeschen
     443           1 :             if ( HasHints() )
     444             :             {
     445           0 :                 for ( sal_uInt16 j = m_pSwpHints->Count(); j; )
     446             :                 {
     447           0 :                     SwTxtAttr* const pHt = m_pSwpHints->GetTextHint( --j );
     448           0 :                     if ( RES_TXTATR_FLYCNT == pHt ->Which() )
     449             :                     {
     450           0 :                         pHt->GetFlyCnt().GetFrmFmt()->DelFrms();
     451             :                     }
     452           0 :                     else if ( pHt->DontExpand() )
     453             :                     {
     454           0 :                         const sal_Int32* const pEnd = pHt->GetEnd();
     455           0 :                         if (pEnd && *pHt->GetStart() == *pEnd )
     456             :                         {
     457             :                             // delete it!
     458           0 :                             m_pSwpHints->DeleteAtPos( j );
     459           0 :                             DestroyAttr( pHt );
     460             :                         }
     461             :                     }
     462             :                 }
     463             :             }
     464             : 
     465             :         }
     466             : 
     467         204 :         SwIterator<SwCntntFrm,SwTxtNode> aIter( *this );
     468         206 :         for( SwCntntFrm* pFrm = aIter.First(); pFrm; pFrm = aIter.Next() )
     469             :         {
     470         104 :             pFrm->RegisterToNode( *pNode );
     471         104 :             if( pFrm->IsTxtFrm() && !pFrm->IsFollow() && ((SwTxtFrm*)pFrm)->GetOfst() )
     472           0 :                 ((SwTxtFrm*)pFrm)->SetOfst( 0 );
     473             :         }
     474             : 
     475         102 :         if ( IsInCache() )
     476             :         {
     477          90 :             SwFrm::GetCache().Delete( this );
     478          90 :             SetInCache( sal_False );
     479             :         }
     480             : 
     481         102 :         UnlockModify(); // Benachrichtigungen wieder freischalten
     482             : 
     483             :         // If there is an accessible layout we must call modify even
     484             :         // with length zero, because we have to notify about the changed
     485             :         // text node.
     486             :         const SwRootFrm *pRootFrm;
     487         204 :         if ( (nTxtLen != nSplitPos) ||
     488         198 :             ( (pRootFrm = pNode->GetDoc()->GetCurrentLayout()) != 0 &&
     489          99 :               pRootFrm->IsAnyShellAccessible() ) )
     490             :         {
     491             :             // dann sage den Frames noch, das am Ende etwas "geloescht" wurde
     492           3 :             if( 1 == nTxtLen - nSplitPos )
     493             :             {
     494           0 :                 SwDelChr aHint( nSplitPos );
     495           0 :                 pNode->NotifyClients( 0, &aHint );
     496             :             }
     497             :             else
     498             :             {
     499           3 :                 SwDelTxt aHint( nSplitPos, nTxtLen - nSplitPos );
     500           3 :                 pNode->NotifyClients( 0, &aHint );
     501             :             }
     502             :         }
     503         102 :         if ( HasHints() )
     504             :         {
     505           0 :             MoveTxtAttr_To_AttrSet();
     506             :         }
     507         102 :         pNode->MakeFrms( *this );       // neue Frames anlegen.
     508         204 :         lcl_ChangeFtnRef( *this );
     509             :     }
     510             :     else
     511             :     {
     512         480 :         SwWrongList *pList = GetWrong();
     513         480 :         SetWrong( 0, false );
     514         480 :         SetWrongDirty( true );
     515             : 
     516         480 :         SwGrammarMarkUp *pList3 = GetGrammarCheck();
     517         480 :         SetGrammarCheck( 0, false );
     518         480 :         SetGrammarCheckDirty( true );
     519             : 
     520         480 :         SetWordCountDirty( true );
     521             : 
     522         480 :         SwWrongList *pList2 = GetSmartTags();
     523         480 :         SetSmartTags( 0, false );
     524         480 :         SetSmartTagDirty( true );
     525             : 
     526         480 :         SwIndex aIdx( this );
     527         480 :         CutText( pNode, aIdx, nSplitPos );
     528             : 
     529             :         // JP 01.10.96: alle leeren und nicht zu expandierenden
     530             :         //              Attribute loeschen
     531         480 :         if ( HasHints() )
     532             :         {
     533           6 :             for ( sal_uInt16 j = m_pSwpHints->Count(); j; )
     534             :             {
     535           2 :                 SwTxtAttr* const pHt = m_pSwpHints->GetTextHint( --j );
     536           2 :                 const sal_Int32* const pEnd = pHt->GetEnd();
     537           2 :                 if ( pHt->DontExpand() && pEnd && (*pHt->GetStart() == *pEnd) )
     538             :                 {
     539             :                     // delete it!
     540           0 :                     m_pSwpHints->DeleteAtPos( j );
     541           0 :                     DestroyAttr( pHt );
     542             :                 }
     543             :             }
     544           2 :             MoveTxtAttr_To_AttrSet();
     545             :         }
     546             : 
     547         480 :         if( pList )
     548             :         {
     549           4 :             pNode->SetWrong( pList->SplitList( nSplitPos ) );
     550           4 :             SetWrong( pList, false );
     551             :         }
     552             : 
     553         480 :         if( pList3 )
     554             :         {
     555           0 :             pNode->SetGrammarCheck( pList3->SplitGrammarList( nSplitPos ) );
     556           0 :             SetGrammarCheck( pList3, false );
     557             :         }
     558             : 
     559         480 :         if( pList2 )
     560             :         {
     561           0 :             pNode->SetSmartTags( pList2->SplitList( nSplitPos ) );
     562           0 :             SetSmartTags( pList2, false );
     563             :         }
     564             : 
     565         480 :         if ( GetDepends() )
     566             :         {
     567         207 :             MakeFrms( *pNode );     // neue Frames anlegen.
     568             :         }
     569         480 :         lcl_ChangeFtnRef( *pNode );
     570             :     }
     571             : 
     572             :     {
     573             :         //Hint fuer Pagedesc versenden. Das mueste eigntlich das Layout im
     574             :         //Paste der Frames selbst erledigen, aber das fuehrt dann wiederum
     575             :         //zu weiteren Folgefehlern, die mit Laufzeitkosten geloest werden
     576             :         //muesten. #56977# #55001# #56135#
     577             :         const SfxPoolItem *pItem;
     578         891 :         if( GetDepends() && SFX_ITEM_SET == pNode->GetSwAttrSet().
     579         309 :             GetItemState( RES_PAGEDESC, true, &pItem ) )
     580             :         {
     581           0 :             pNode->ModifyNotification( (SfxPoolItem*)pItem, (SfxPoolItem*)pItem );
     582             :         }
     583             :     }
     584         582 :     return pNode;
     585             : }
     586             : 
     587           2 : void SwTxtNode::MoveTxtAttr_To_AttrSet()
     588             : {
     589             :     OSL_ENSURE( m_pSwpHints, "MoveTxtAttr_To_AttrSet without SwpHints?" );
     590           4 :     for ( sal_uInt16 i = 0; m_pSwpHints && i < m_pSwpHints->Count(); ++i )
     591             :     {
     592           2 :         SwTxtAttr *pHt = m_pSwpHints->GetTextHint(i);
     593             : 
     594           2 :         if( *pHt->GetStart() )
     595           0 :             break;
     596             : 
     597           2 :         const sal_Int32* pHtEndIdx = pHt->GetEnd();
     598             : 
     599           2 :         if( !pHtEndIdx )
     600           0 :             continue;
     601             : 
     602           2 :         if (*pHtEndIdx < m_Text.getLength() || pHt->IsCharFmtAttr())
     603           0 :             break;
     604             : 
     605           4 :         if( !pHt->IsDontMoveAttr() &&
     606           2 :             SetAttr( pHt->GetAttr() ) )
     607             :         {
     608           0 :             m_pSwpHints->DeleteAtPos(i);
     609           0 :             DestroyAttr( pHt );
     610           0 :             --i;
     611             :         }
     612             :     }
     613             : 
     614           2 : }
     615             : 
     616        1885 : SwCntntNode *SwTxtNode::JoinNext()
     617             : {
     618        1885 :     SwNodes& rNds = GetNodes();
     619        1885 :     SwNodeIndex aIdx( *this );
     620        1885 :     if( SwCntntNode::CanJoinNext( &aIdx ) )
     621             :     {
     622        1885 :         SwDoc* pDoc = rNds.GetDoc();
     623        1885 :         std::vector<sal_uLong> aBkmkArr;
     624        1885 :         _SaveCntntIdx( pDoc, aIdx.GetIndex(), SAL_MAX_INT32, aBkmkArr, SAVEFLY );
     625        1885 :         SwTxtNode *pTxtNode = aIdx.GetNode().GetTxtNode();
     626        1885 :         sal_Int32 nOldLen = m_Text.getLength();
     627             : 
     628             :         // METADATA: merge
     629        1885 :         this->JoinMetadatable(*pTxtNode, !this->Len(), !pTxtNode->Len());
     630             : 
     631        1885 :         SwWrongList *pList = GetWrong();
     632        1885 :         if( pList )
     633             :         {
     634           8 :             pList->JoinList( pTxtNode->GetWrong(), nOldLen );
     635           8 :             SetWrongDirty( true );
     636           8 :             SetWrong( 0, false );
     637             :         }
     638             :         else
     639             :         {
     640        1877 :             pList = pTxtNode->GetWrong();
     641        1877 :             if( pList )
     642             :             {
     643           2 :                 pList->Move( 0, nOldLen );
     644           2 :                 SetWrongDirty( true );
     645           2 :                 pTxtNode->SetWrong( 0, false );
     646             :             }
     647             :         }
     648             : 
     649        1885 :         SwGrammarMarkUp *pList3 = GetGrammarCheck();
     650        1885 :         if( pList3 )
     651             :         {
     652           0 :             pList3->JoinGrammarList( pTxtNode->GetGrammarCheck(), nOldLen );
     653           0 :             SetGrammarCheckDirty( true );
     654           0 :             SetGrammarCheck( 0, false );
     655             :         }
     656             :         else
     657             :         {
     658        1885 :             pList3 = pTxtNode->GetGrammarCheck();
     659        1885 :             if( pList3 )
     660             :             {
     661           0 :                 pList3->MoveGrammar( 0, nOldLen );
     662           0 :                 SetGrammarCheckDirty( true );
     663           0 :                 pTxtNode->SetGrammarCheck( 0, false );
     664             :             }
     665             :         }
     666             : 
     667        1885 :         SwWrongList *pList2 = GetSmartTags();
     668        1885 :         if( pList2 )
     669             :         {
     670           0 :             pList2->JoinList( pTxtNode->GetSmartTags(), nOldLen );
     671           0 :             SetSmartTagDirty( true );
     672           0 :             SetSmartTags( 0, false );
     673             :         }
     674             :         else
     675             :         {
     676        1885 :             pList2 = pTxtNode->GetSmartTags();
     677        1885 :             if( pList2 )
     678             :             {
     679           0 :                 pList2->Move( 0, nOldLen );
     680           0 :                 SetSmartTagDirty( true );
     681           0 :                 pTxtNode->SetSmartTags( 0, false );
     682             :             }
     683             :         }
     684             : 
     685             :         { // wg. SwIndex
     686        1885 :             pTxtNode->CutText( this, SwIndex(pTxtNode), pTxtNode->Len() );
     687             :         }
     688             :         // verschiebe noch alle Bookmarks/TOXMarks
     689        1885 :         if( !aBkmkArr.empty() )
     690           1 :             _RestoreCntntIdx( pDoc, aBkmkArr, GetIndex(), nOldLen );
     691             : 
     692        1885 :         if( pTxtNode->HasAnyIndex() )
     693             :         {
     694             :             // alle Crsr/StkCrsr/UnoCrsr aus dem Loeschbereich verschieben
     695           0 :             pDoc->CorrAbs( aIdx, SwPosition( *this ), nOldLen, sal_True );
     696             :         }
     697        1885 :         rNds.Delete(aIdx);
     698        1885 :         SetWrong( pList, false );
     699        1885 :         SetGrammarCheck( pList3, false );
     700        1885 :         SetSmartTags( pList2, false );
     701        1885 :         InvalidateNumRule();
     702             :     }
     703             :     else {
     704             :         OSL_FAIL( "kein TxtNode." );
     705             :     }
     706             : 
     707        1885 :     return this;
     708             : }
     709             : 
     710          70 : SwCntntNode *SwTxtNode::JoinPrev()
     711             : {
     712          70 :     SwNodes& rNds = GetNodes();
     713          70 :     SwNodeIndex aIdx( *this );
     714          70 :     if( SwCntntNode::CanJoinPrev( &aIdx ) )
     715             :     {
     716          70 :         SwDoc* pDoc = rNds.GetDoc();
     717          70 :         std::vector<sal_uLong> aBkmkArr;
     718          70 :         _SaveCntntIdx( pDoc, aIdx.GetIndex(), SAL_MAX_INT32, aBkmkArr, SAVEFLY );
     719          70 :         SwTxtNode *pTxtNode = aIdx.GetNode().GetTxtNode();
     720          70 :         const sal_Int32 nLen = pTxtNode->Len();
     721             : 
     722          70 :         SwWrongList *pList = pTxtNode->GetWrong();
     723          70 :         if( pList )
     724             :         {
     725           1 :             pList->JoinList( GetWrong(), Len() );
     726           1 :             SetWrongDirty( true );
     727           1 :             pTxtNode->SetWrong( 0, false );
     728           1 :             SetWrong( NULL );
     729             :         }
     730             :         else
     731             :         {
     732          69 :             pList = GetWrong();
     733          69 :             if( pList )
     734             :             {
     735           0 :                 pList->Move( 0, nLen );
     736           0 :                 SetWrongDirty( true );
     737           0 :                 SetWrong( 0, false );
     738             :             }
     739             :         }
     740             : 
     741          70 :         SwGrammarMarkUp *pList3 = pTxtNode->GetGrammarCheck();
     742          70 :         if( pList3 )
     743             :         {
     744           0 :             pList3->JoinGrammarList( GetGrammarCheck(), Len() );
     745           0 :             SetGrammarCheckDirty( true );
     746           0 :             pTxtNode->SetGrammarCheck( 0, false );
     747           0 :             SetGrammarCheck( NULL );
     748             :         }
     749             :         else
     750             :         {
     751          70 :             pList3 = GetGrammarCheck();
     752          70 :             if( pList3 )
     753             :             {
     754           0 :                 pList3->MoveGrammar( 0, nLen );
     755           0 :                 SetGrammarCheckDirty( true );
     756           0 :                 SetGrammarCheck( 0, false );
     757             :             }
     758             :         }
     759             : 
     760          70 :         SwWrongList *pList2 = pTxtNode->GetSmartTags();
     761          70 :         if( pList2 )
     762             :         {
     763           0 :             pList2->JoinList( GetSmartTags(), Len() );
     764           0 :             SetSmartTagDirty( true );
     765           0 :             pTxtNode->SetSmartTags( 0, false );
     766           0 :             SetSmartTags( NULL );
     767             :         }
     768             :         else
     769             :         {
     770          70 :             pList2 = GetSmartTags();
     771          70 :             if( pList2 )
     772             :             {
     773           0 :                 pList2->Move( 0, nLen );
     774           0 :                 SetSmartTagDirty( true );
     775           0 :                 SetSmartTags( 0, false );
     776             :             }
     777             :         }
     778             : 
     779             :         { // wg. SwIndex
     780          70 :             pTxtNode->CutText( this, SwIndex(this), SwIndex(pTxtNode), nLen );
     781             :         }
     782             :         // verschiebe noch alle Bookmarks/TOXMarks
     783          70 :         if( !aBkmkArr.empty() )
     784           0 :             _RestoreCntntIdx( pDoc, aBkmkArr, GetIndex() );
     785             : 
     786          70 :         if( pTxtNode->HasAnyIndex() )
     787             :         {
     788             :             // alle Crsr/StkCrsr/UnoCrsr aus dem Loeschbereich verschieben
     789           0 :             pDoc->CorrAbs( aIdx, SwPosition( *this ), nLen, sal_True );
     790             :         }
     791          70 :         rNds.Delete(aIdx);
     792          70 :         SetWrong( pList, false );
     793          70 :         SetGrammarCheck( pList3, false );
     794          70 :         SetSmartTags( pList2, false );
     795          70 :         InvalidateNumRule();
     796             :     }
     797             :     else {
     798             :         OSL_FAIL( "kein TxtNode." );
     799             :     }
     800             : 
     801          70 :     return this;
     802             : }
     803             : 
     804             : // erzeugt einen AttrSet mit Bereichen fuer Frame-/Para/Char-Attributen
     805       23368 : void SwTxtNode::NewAttrSet( SwAttrPool& rPool )
     806             : {
     807             :     OSL_ENSURE( !mpAttrSet.get(), "AttrSet ist doch gesetzt" );
     808       23368 :     SwAttrSet aNewAttrSet( rPool, aTxtNodeSetRange );
     809             : 
     810             :     // put names of parent style and conditional style:
     811       23368 :     const SwFmtColl* pAnyFmtColl = &GetAnyFmtColl();
     812       23368 :     const SwFmtColl* pFmtColl = GetFmtColl();
     813       46736 :     OUString sVal;
     814       23368 :     SwStyleNameMapper::FillProgName( pAnyFmtColl->GetName(), sVal, nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL, true );
     815       46736 :     SfxStringItem aAnyFmtColl( RES_FRMATR_STYLE_NAME, sVal );
     816       23368 :     if ( pFmtColl != pAnyFmtColl )
     817           0 :         SwStyleNameMapper::FillProgName( pFmtColl->GetName(), sVal, nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL, true );
     818       46736 :     SfxStringItem aFmtColl( RES_FRMATR_CONDITIONAL_STYLE_NAME, sVal );
     819       23368 :     aNewAttrSet.Put( aAnyFmtColl );
     820       23368 :     aNewAttrSet.Put( aFmtColl );
     821             : 
     822       23368 :     aNewAttrSet.SetParent( &pAnyFmtColl->GetAttrSet() );
     823       46736 :     mpAttrSet = GetDoc()->GetIStyleAccess().getAutomaticStyle( aNewAttrSet, IStyleAccess::AUTO_STYLE_PARA );
     824       23368 : }
     825             : 
     826             : // override SwIndexReg::Update => text hints do not need SwIndex for start/end!
     827      105614 : void SwTxtNode::Update(
     828             :     SwIndex const & rPos,
     829             :     const sal_Int32 nChangeLen,
     830             :     const bool bNegative,
     831             :     const bool bDelete )
     832             : {
     833      105614 :     SetAutoCompleteWordDirty( true );
     834             : 
     835      105614 :     boost::scoped_ptr<SwpHts> pCollector;
     836      105614 :     const sal_Int32 nChangePos = rPos.GetIndex();
     837             : 
     838      105614 :     if ( HasHints() )
     839             :     {
     840       17151 :         if ( bNegative )
     841             :         {
     842         326 :             const sal_Int32 nChangeEnd = nChangePos + nChangeLen;
     843         791 :             for ( sal_uInt16 n = 0; n < m_pSwpHints->Count(); ++n )
     844             :             {
     845         465 :                 bool bTxtAttrChanged = false;
     846         465 :                 bool bStartOfTxtAttrChanged = false;
     847         465 :                 SwTxtAttr * const pHint = m_pSwpHints->GetTextHint(n);
     848         465 :                 sal_Int32 * const pStart = pHint->GetStart();
     849         465 :                 if ( *pStart > nChangePos )
     850             :                 {
     851         200 :                     if ( *pStart > nChangeEnd )
     852             :                     {
     853         107 :                          *pStart = *pStart - nChangeLen;
     854             :                     }
     855             :                     else
     856             :                     {
     857          93 :                          *pStart = nChangePos;
     858             :                     }
     859         200 :                     bStartOfTxtAttrChanged = true;
     860             :                 }
     861             : 
     862         465 :                 sal_Int32 * const pEnd = pHint->GetEnd();
     863         465 :                 if (pEnd)
     864             :                 {
     865         356 :                     if ( *pEnd > nChangePos )
     866             :                     {
     867         347 :                         if( *pEnd > nChangeEnd )
     868             :                         {
     869         196 :                             *pEnd = *pEnd - nChangeLen;
     870             :                         }
     871             :                         else
     872             :                         {
     873         151 :                             *pEnd = nChangePos;
     874             :                         }
     875         347 :                         bTxtAttrChanged = !bStartOfTxtAttrChanged;
     876             :                     }
     877             :                 }
     878             : 
     879         465 :                 if ( bTxtAttrChanged
     880         465 :                      && pHint->Which() == RES_TXTATR_INPUTFIELD )
     881             :                 {
     882           1 :                     SwTxtInputFld* pTxtInputFld = dynamic_cast<SwTxtInputFld*>(pHint);
     883           1 :                     if ( pTxtInputFld )
     884             :                     {
     885           1 :                         pTxtInputFld->UpdateFieldContent();
     886             :                     }
     887             :                 }
     888             :             }
     889             : 
     890         326 :             m_pSwpHints->MergePortions( *this );
     891             :         }
     892             :         else
     893             :         {
     894       16825 :             bool bNoExp = false;
     895       16825 :             bool bResort = false;
     896       16825 :             bool bMergePortionsNeeded = false;
     897             :             const sal_uInt16 coArrSz =
     898       16825 :                 static_cast<sal_uInt16>(RES_TXTATR_WITHEND_END) - static_cast<sal_uInt16>(RES_CHRATR_BEGIN);
     899             : 
     900             :             sal_Bool aDontExp[ coArrSz ];
     901       16825 :             memset( &aDontExp, 0, coArrSz * sizeof(sal_Bool) );
     902             : 
     903      165929 :             for ( sal_uInt16 n = 0; n < m_pSwpHints->Count(); ++n )
     904             :             {
     905      149104 :                 bool bTxtAttrChanged = false;
     906      149104 :                 SwTxtAttr * const pHint = m_pSwpHints->GetTextHint(n);
     907      149104 :                 sal_Int32 * const pStart = pHint->GetStart();
     908      149104 :                 sal_Int32 * const pEnd = pHint->GetEnd();
     909      149104 :                 if ( *pStart >= nChangePos )
     910             :                 {
     911         325 :                     *pStart = *pStart + nChangeLen;
     912         325 :                     if ( pEnd )
     913             :                     {
     914         220 :                         *pEnd = *pEnd + nChangeLen;
     915             :                     }
     916             :                 }
     917      148779 :                 else if ( pEnd && (*pEnd >= nChangePos) )
     918             :                 {
     919       15122 :                     if ( (*pEnd > nChangePos) || IsIgnoreDontExpand() )
     920             :                     {
     921         122 :                         *pEnd = *pEnd + nChangeLen;
     922         122 :                         bTxtAttrChanged = true;
     923             :                     }
     924             :                     else // *pEnd == nChangePos
     925             :                     {
     926             :                         sal_uInt16 nWhPos;
     927       15000 :                         const sal_uInt16 nWhich = pHint->Which();
     928             : 
     929             :                         OSL_ENSURE(!isCHRATR(nWhich), "Update: char attr hint?");
     930       15000 :                         if (isCHRATR(nWhich) || isTXTATR_WITHEND(nWhich))
     931             :                         {
     932             :                             nWhPos = static_cast<sal_uInt16>(nWhich -
     933       15000 :                                         RES_CHRATR_BEGIN);
     934             :                         }
     935             :                         else
     936           0 :                             continue;
     937             : 
     938       15000 :                         if( aDontExp[ nWhPos ] )
     939         190 :                             continue;
     940             : 
     941       14810 :                         if ( pHint->DontExpand() )
     942             :                         {
     943       14656 :                             pHint->SetDontExpand( false );
     944       14656 :                             bResort = true;
     945             :                             // could have a continuation with IgnoreStart()...
     946       14656 :                             if (pHint->IsFormatIgnoreEnd())
     947             :                             {
     948           0 :                                 bMergePortionsNeeded = true;
     949             :                             }
     950       14656 :                             if ( pHint->IsCharFmtAttr() )
     951             :                             {
     952         844 :                                 bNoExp = true;
     953             :                                 aDontExp[ static_cast<sal_uInt16>(RES_TXTATR_CHARFMT) - static_cast<sal_uInt16>(RES_CHRATR_BEGIN) ]
     954         844 :                                     = sal_True;
     955             :                                 aDontExp[ static_cast<sal_uInt16>(RES_TXTATR_INETFMT) - static_cast<sal_uInt16>(RES_CHRATR_BEGIN) ]
     956         844 :                                     = sal_True;
     957             :                             }
     958             :                             else
     959       13812 :                                 aDontExp[ nWhPos ] = sal_True;
     960             :                         }
     961         154 :                         else if( bNoExp )
     962             :                         {
     963           1 :                             if ( !pCollector.get() )
     964             :                             {
     965           1 :                                pCollector.reset( new SwpHts );
     966             :                             }
     967           1 :                             for(SwpHts::iterator it =  pCollector->begin(); it != pCollector->end(); ++it)
     968             :                             {
     969           0 :                                SwTxtAttr *pTmp = *it;
     970           0 :                                if( nWhich == pTmp->Which() )
     971             :                                {
     972           0 :                                    pCollector->erase( it );
     973             :                                    SwTxtAttr::Destroy( pTmp,
     974           0 :                                        GetDoc()->GetAttrPool() );
     975           0 :                                    break;
     976             :                                }
     977             :                             }
     978             :                             SwTxtAttr * const pTmp =
     979           1 :                             MakeTxtAttr( *GetDoc(),
     980           2 :                                 pHint->GetAttr(), nChangePos, nChangePos + nChangeLen);
     981           1 :                             pCollector->push_back( pTmp );
     982             :                         }
     983             :                         else
     984             :                         {
     985         153 :                             *pEnd = *pEnd + nChangeLen;
     986         153 :                             bTxtAttrChanged = true;
     987             :                         }
     988             :                     }
     989             :                 }
     990             : 
     991      148914 :                 if ( bTxtAttrChanged
     992      148914 :                      && pHint->Which() == RES_TXTATR_INPUTFIELD )
     993             :                 {
     994           1 :                     SwTxtInputFld* pTxtInputFld = dynamic_cast<SwTxtInputFld*>(pHint);
     995           1 :                     if ( pTxtInputFld )
     996             :                     {
     997           1 :                         pTxtInputFld->UpdateFieldContent();
     998             :                     }
     999             :                 }
    1000             :             }
    1001       16825 :             if (bMergePortionsNeeded)
    1002             :             {
    1003           0 :                 m_pSwpHints->MergePortions(*this); // does Resort too
    1004             :             }
    1005       16825 :             else if (bResort)
    1006             :             {
    1007       14006 :                 m_pSwpHints->Resort();
    1008             :             }
    1009             :         }
    1010             :     }
    1011             : 
    1012      105614 :     bool bSortMarks = false;
    1013      211228 :     SwIndexReg aTmpIdxReg;
    1014      105614 :     if ( !bNegative && !bDelete )
    1015             :     {
    1016      102825 :         const SwRedlineTbl& rTbl = GetDoc()->GetRedlineTbl();
    1017      204506 :         for ( sal_uInt16 i = 0; i < rTbl.size(); ++i )
    1018             :         {
    1019      101681 :             SwRangeRedline *const pRedl = rTbl[ i ];
    1020      101681 :             if ( pRedl->HasMark() )
    1021             :             {
    1022      101670 :                 SwPosition* const pEnd = pRedl->End();
    1023      119834 :                 if ( this == &pEnd->nNode.GetNode() &&
    1024       18164 :                      *pRedl->GetPoint() != *pRedl->GetMark() )
    1025             :                 {
    1026       18164 :                     SwIndex & rIdx = pEnd->nContent;
    1027       18164 :                     if (nChangePos == rIdx.GetIndex())
    1028             :                     {
    1029         930 :                         rIdx.Assign( &aTmpIdxReg, rIdx.GetIndex() );
    1030             :                     }
    1031             :                 }
    1032             :             }
    1033          11 :             else if ( this == &pRedl->GetPoint()->nNode.GetNode() )
    1034             :             {
    1035           0 :                 SwIndex & rIdx = pRedl->GetPoint()->nContent;
    1036           0 :                 if (nChangePos == rIdx.GetIndex())
    1037             :                 {
    1038           0 :                     rIdx.Assign( &aTmpIdxReg, rIdx.GetIndex() );
    1039             :                     // mst: FIXME: why does this adjust the unused position???
    1040             :                     SwIndex * pIdx;
    1041           0 :                     if ( &pRedl->GetBound( true ) == pRedl->GetPoint() )
    1042             :                     {
    1043           0 :                         pRedl->GetBound( false ) = pRedl->GetBound( true );
    1044           0 :                         pIdx = &pRedl->GetBound( false ).nContent;
    1045             :                     }
    1046             :                     else
    1047             :                     {
    1048           0 :                         pRedl->GetBound( true ) = pRedl->GetBound( false );
    1049           0 :                         pIdx = &pRedl->GetBound( true ).nContent;
    1050             :                     }
    1051           0 :                     pIdx->Assign( &aTmpIdxReg, pIdx->GetIndex() );
    1052             :                 }
    1053             :             }
    1054             :         }
    1055             : 
    1056             :         // Bookmarks must never grow to either side, when editing (directly) to the left or right (#i29942#)!
    1057             :         // And a bookmark with same start and end must remain to the left of the inserted text (used in XML import).
    1058             :         {
    1059      102825 :             const IDocumentMarkAccess* const pMarkAccess = getIDocumentMarkAccess();
    1060    15265245 :             for ( IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->getAllMarksBegin();
    1061    10176830 :                 ppMark != pMarkAccess->getAllMarksEnd();
    1062             :                 ++ppMark )
    1063             :             {
    1064     4985590 :                 const ::sw::mark::IMark* const pMark = ppMark->get();
    1065     4985590 :                 const SwPosition* pEnd = &pMark->GetMarkEnd();
    1066     4985590 :                 SwIndex & rIdx = const_cast<SwIndex&>(pEnd->nContent);
    1067     5368525 :                 if( this == &pEnd->nNode.GetNode() &&
    1068      382935 :                     rPos.GetIndex() == rIdx.GetIndex() )
    1069             :                 {
    1070       11875 :                     rIdx.Assign( &aTmpIdxReg, rIdx.GetIndex() );
    1071       11875 :                     bSortMarks = true;
    1072             :                 }
    1073             :             }
    1074             :         }
    1075             :     }
    1076             : 
    1077             :     // base class
    1078      105614 :     SwIndexReg::Update( rPos, nChangeLen, bNegative, bDelete );
    1079             : 
    1080      105614 :     if ( pCollector.get() )
    1081             :     {
    1082           1 :         const sal_uInt16 nCount = pCollector->size();
    1083           2 :         for ( sal_uInt16 i = 0; i < nCount; ++i )
    1084             :         {
    1085           1 :             m_pSwpHints->TryInsertHint( (*pCollector)[ i ], *this );
    1086             :         }
    1087             :     }
    1088             : 
    1089      105614 :     aTmpIdxReg.MoveTo( *this );
    1090      105614 :     if ( bSortMarks )
    1091             :     {
    1092        8381 :         getIDocumentMarkAccess()->assureSortedMarkContainers();
    1093      105614 :     }
    1094      105614 : }
    1095             : 
    1096       56444 : void SwTxtNode::_ChgTxtCollUpdateNum( const SwTxtFmtColl *pOldColl,
    1097             :                                         const SwTxtFmtColl *pNewColl)
    1098             : {
    1099       56444 :     SwDoc* pDoc = GetDoc();
    1100             :     OSL_ENSURE( pDoc, "Kein Doc?" );
    1101             :     // erfrage die OutlineLevel und update gegebenenfalls das Nodes-Array,
    1102             :     // falls sich die Level geaendert haben !
    1103       30358 :     const int nOldLevel = pOldColl && pOldColl->IsAssignedToListLevelOfOutlineStyle() ?
    1104       56872 :                      pOldColl->GetAssignedOutlineStyleLevel() : MAXLEVEL;
    1105       56444 :     const int nNewLevel = pNewColl && pNewColl->IsAssignedToListLevelOfOutlineStyle() ?
    1106       57124 :                      pNewColl->GetAssignedOutlineStyleLevel() : MAXLEVEL;
    1107             : 
    1108       56444 :     if ( MAXLEVEL != nNewLevel && -1 != nNewLevel )
    1109             :     {
    1110         679 :         SetAttrListLevel(nNewLevel);
    1111             :     }
    1112       56444 :     if (pDoc)
    1113             :     {
    1114       56444 :         pDoc->GetNodes().UpdateOutlineNode(*this);
    1115             :     }
    1116             : 
    1117       56444 :     SwNodes& rNds = GetNodes();
    1118             :     // Update beim Level 0 noch die Fussnoten !!
    1119      112692 :     if( ( !nNewLevel || !nOldLevel) && pDoc && !pDoc->GetFtnIdxs().empty() &&
    1120       56456 :         FTNNUM_CHAPTER == pDoc->GetFtnInfo().eNum &&
    1121           0 :         rNds.IsDocNodes() )
    1122             :     {
    1123           0 :         SwNodeIndex aTmpIndex( rNds, GetIndex());
    1124             : 
    1125           0 :         pDoc->GetFtnIdxs().UpdateFtn( aTmpIndex);
    1126             :     }
    1127             : 
    1128       56444 :     if( pNewColl && RES_CONDTXTFMTCOLL == pNewColl->Which() )
    1129             :     {
    1130             :         // Erfrage die akt. Condition des TextNodes:
    1131         196 :         ChkCondColl();
    1132             :     }
    1133       56444 : }
    1134             : 
    1135             : // Wenn man sich genau am Ende einer Text- bzw. INetvorlage befindet,
    1136             : // bekommt diese das DontExpand-Flag verpasst
    1137             : 
    1138       47817 : bool SwTxtNode::DontExpandFmt( const SwIndex& rIdx, bool bFlag,
    1139             :                                 bool bFmtToTxtAttributes )
    1140             : {
    1141       47817 :     const sal_Int32 nIdx = rIdx.GetIndex();
    1142       47817 :     if (bFmtToTxtAttributes && nIdx == m_Text.getLength())
    1143             :     {
    1144       47671 :         FmtToTxtAttr( this );
    1145             :     }
    1146             : 
    1147       47817 :     bool bRet = false;
    1148       47817 :     if ( HasHints() )
    1149             :     {
    1150       14797 :         const sal_uInt16 nEndCnt = m_pSwpHints->GetEndCount();
    1151       14797 :         sal_uInt16 nPos = nEndCnt;
    1152       48574 :         while( nPos )
    1153             :         {
    1154       18980 :             SwTxtAttr *pTmp = m_pSwpHints->GetEnd( --nPos );
    1155       18980 :             sal_Int32 *pEnd = pTmp->GetEnd();
    1156       18980 :             if( !pEnd || *pEnd > nIdx )
    1157         768 :                 continue;
    1158       18212 :             if( nIdx != *pEnd )
    1159        3502 :                 nPos = 0;
    1160       43621 :             else if( bFlag != pTmp->DontExpand() && !pTmp->IsLockExpandFlag()
    1161       28911 :                      && *pEnd > *pTmp->GetStart())
    1162             :             {
    1163       14201 :                 bRet = true;
    1164       14201 :                 m_pSwpHints->NoteInHistory( pTmp );
    1165       14201 :                 pTmp->SetDontExpand( bFlag );
    1166             :             }
    1167             :         }
    1168             :     }
    1169       47817 :     return bRet;
    1170             : }
    1171             : 
    1172        1324 : static bool lcl_GetTxtAttrDefault(sal_Int32 nIndex, sal_Int32 nHintStart, sal_Int32 nHintEnd)
    1173             : {
    1174        1324 :     return ((nHintStart <= nIndex) && (nIndex <  nHintEnd));
    1175             : }
    1176          59 : static bool lcl_GetTxtAttrExpand(sal_Int32 nIndex, sal_Int32 nHintStart, sal_Int32 nHintEnd)
    1177             : {
    1178          59 :     return ((nHintStart <  nIndex) && (nIndex <= nHintEnd));
    1179             : }
    1180          39 : static bool lcl_GetTxtAttrParent(sal_Int32 nIndex, sal_Int32 nHintStart, sal_Int32 nHintEnd)
    1181             : {
    1182          39 :     return ((nHintStart <  nIndex) && (nIndex <  nHintEnd));
    1183             : }
    1184             : 
    1185             : static void
    1186      309856 : lcl_GetTxtAttrs(
    1187             :     ::std::vector<SwTxtAttr *> *const pVector,
    1188             :     SwTxtAttr **const ppTxtAttr,
    1189             :     SwpHints *const pSwpHints,
    1190             :     sal_Int32 const nIndex, RES_TXTATR const nWhich,
    1191             :     enum SwTxtNode::GetTxtAttrMode const eMode)
    1192             : {
    1193      309856 :     sal_uInt16 const nSize = (pSwpHints) ? pSwpHints->Count() : 0;
    1194      309856 :     sal_Int32 nPreviousIndex(0); // index of last hint with nWhich
    1195      309856 :     bool (*pMatchFunc)(sal_Int32, sal_Int32, sal_Int32)=0;
    1196      309856 :     switch (eMode)
    1197             :     {
    1198       37077 :         case SwTxtNode::DEFAULT:   pMatchFunc = &lcl_GetTxtAttrDefault; break;
    1199          32 :         case SwTxtNode::EXPAND:    pMatchFunc = &lcl_GetTxtAttrExpand;  break;
    1200      272747 :         case SwTxtNode::PARENT:    pMatchFunc = &lcl_GetTxtAttrParent;  break;
    1201             :         default: assert(false);
    1202             :     }
    1203             : 
    1204      901376 :     for( sal_uInt16 i = 0; i < nSize; ++i )
    1205             :     {
    1206      607486 :         SwTxtAttr *const pHint = pSwpHints->GetTextHint(i);
    1207      607486 :         sal_Int32 const nHintStart( *(pHint->GetStart()) );
    1208      607486 :         if (nIndex < nHintStart)
    1209             :         {
    1210      325822 :             return; // hints are sorted by start, so we are done...
    1211             :         }
    1212             : 
    1213      591520 :         if (pHint->Which() != nWhich)
    1214             :         {
    1215      590088 :             continue;
    1216             :         }
    1217             : 
    1218        1432 :         sal_Int32 const*const pEndIdx = pHint->GetEnd();
    1219             :         // cannot have hint with no end and no dummy char
    1220             :         assert(pEndIdx || pHint->HasDummyChar());
    1221             :             // Wenn bExpand gesetzt ist, wird das Verhalten bei Eingabe
    1222             :             // simuliert, d.h. der Start wuede verschoben, das Ende expandiert,
    1223             :         bool const bContained( (pEndIdx)
    1224        1422 :             ? (*pMatchFunc)(nIndex, nHintStart, *pEndIdx)
    1225        2854 :             : (nHintStart == nIndex) );
    1226        1432 :         if (bContained)
    1227             :         {
    1228         249 :             if (pVector)
    1229             :             {
    1230          70 :                 if (nPreviousIndex < nHintStart)
    1231             :                 {
    1232           8 :                     pVector->clear(); // clear hints that are outside pHint
    1233           8 :                     nPreviousIndex = nHintStart;
    1234             :                 }
    1235          70 :                 pVector->push_back(pHint);
    1236             :             }
    1237             :             else
    1238             :             {
    1239         179 :                 *ppTxtAttr = pHint; // and possibly overwrite outer hint
    1240             :             }
    1241         249 :             if (!pEndIdx)
    1242             :             {
    1243           0 :                 break;
    1244             :             }
    1245             :         }
    1246             :     }
    1247             : }
    1248             : 
    1249             : ::std::vector<SwTxtAttr *>
    1250          56 : SwTxtNode::GetTxtAttrsAt(sal_Int32 const nIndex, RES_TXTATR const nWhich,
    1251             :                         enum GetTxtAttrMode const eMode) const
    1252             : {
    1253          56 :     ::std::vector<SwTxtAttr *> ret;
    1254          56 :     lcl_GetTxtAttrs(& ret, 0, m_pSwpHints, nIndex, nWhich, eMode);
    1255          56 :     return ret;
    1256             : }
    1257             : 
    1258             : SwTxtAttr *
    1259      309800 : SwTxtNode::GetTxtAttrAt(sal_Int32 const nIndex, RES_TXTATR const nWhich,
    1260             :                         enum GetTxtAttrMode const eMode) const
    1261             : {
    1262             :     assert(    (nWhich == RES_TXTATR_META)
    1263             :             || (nWhich == RES_TXTATR_METAFIELD)
    1264             :             || (nWhich == RES_TXTATR_AUTOFMT)
    1265             :             || (nWhich == RES_TXTATR_INETFMT)
    1266             :             || (nWhich == RES_TXTATR_CJK_RUBY)
    1267             :             || (nWhich == RES_TXTATR_UNKNOWN_CONTAINER)
    1268             :             || (nWhich == RES_TXTATR_INPUTFIELD ) );
    1269             :             // "GetTxtAttrAt() will give wrong result for this hint!")
    1270             : 
    1271      309800 :     SwTxtAttr * pRet(0);
    1272      309800 :     lcl_GetTxtAttrs(0, & pRet, m_pSwpHints, nIndex, nWhich, eMode);
    1273      309800 :     return pRet;
    1274             : }
    1275             : 
    1276       64133 : const SwTxtInputFld* SwTxtNode::GetOverlappingInputFld( const SwTxtAttr& rTxtAttr ) const
    1277             : {
    1278       64133 :     const SwTxtInputFld* pTxtInputFld = NULL;
    1279             : 
    1280       64133 :     pTxtInputFld = dynamic_cast<const SwTxtInputFld*>(GetTxtAttrAt( *(rTxtAttr.GetStart()), RES_TXTATR_INPUTFIELD, PARENT ));
    1281             : 
    1282       64133 :     if ( pTxtInputFld == NULL && rTxtAttr.End() != NULL )
    1283             :     {
    1284       60390 :         pTxtInputFld = dynamic_cast<const SwTxtInputFld*>(GetTxtAttrAt( *(rTxtAttr.End()), RES_TXTATR_INPUTFIELD, PARENT ));
    1285             :     }
    1286             : 
    1287       64133 :     return pTxtInputFld;
    1288             : }
    1289             : 
    1290       71756 : SwTxtFld* SwTxtNode::GetFldTxtAttrAt(
    1291             :     const sal_Int32 nIndex,
    1292             :     const bool bIncludeInputFldAtStart ) const
    1293             : {
    1294       71756 :     SwTxtFld* pTxtFld = NULL;
    1295             : 
    1296       71756 :     pTxtFld = dynamic_cast<SwTxtFld*>(GetTxtAttrForCharAt( nIndex, RES_TXTATR_FIELD ));
    1297       71756 :     if ( pTxtFld == NULL )
    1298             :     {
    1299       71301 :         pTxtFld = dynamic_cast<SwTxtFld*>(GetTxtAttrForCharAt( nIndex, RES_TXTATR_ANNOTATION ));
    1300             :     }
    1301       71756 :     if ( pTxtFld == NULL )
    1302             :     {
    1303             :         pTxtFld =
    1304             :             dynamic_cast<SwTxtFld*>( GetTxtAttrAt(
    1305             :                 nIndex,
    1306             :                 RES_TXTATR_INPUTFIELD,
    1307       71206 :                 bIncludeInputFldAtStart ? DEFAULT : PARENT ));
    1308             :     }
    1309             : 
    1310       71756 :     return pTxtFld;
    1311             : }
    1312             : 
    1313             : /*************************************************************************
    1314             :  *                          CopyHint()
    1315             :  *************************************************************************/
    1316             : 
    1317           0 : static SwCharFmt* lcl_FindCharFmt( const SwCharFmts* pCharFmts, const OUString& rName )
    1318             : {
    1319           0 :     if( !rName.isEmpty() )
    1320             :     {
    1321             :         SwCharFmt* pFmt;
    1322           0 :         sal_uInt16 nArrLen = pCharFmts->size();
    1323           0 :         for( sal_uInt16 i = 1; i < nArrLen; i++ )
    1324             :         {
    1325           0 :             pFmt = (*pCharFmts)[ i ];
    1326           0 :             if( pFmt->GetName()==rName )
    1327           0 :                 return pFmt;
    1328             :         }
    1329             :     }
    1330           0 :     return NULL;
    1331             : }
    1332             : 
    1333        2045 : void lcl_CopyHint(
    1334             :     const sal_uInt16 nWhich,
    1335             :     const SwTxtAttr * const pHt,
    1336             :     SwTxtAttr *const pNewHt,
    1337             :     SwDoc *const pOtherDoc,
    1338             :     SwTxtNode *const pDest )
    1339             : {
    1340             :     assert(nWhich == pHt->Which()); // wrong hint-id
    1341        2045 :     switch( nWhich )
    1342             :     {
    1343             :     // copy nodesarray section with footnote content
    1344             :     case RES_TXTATR_FTN :
    1345             :             assert(pDest); // "lcl_CopyHint: no destination text node?"
    1346           0 :             static_cast<const SwTxtFtn*>(pHt)->CopyFtn( *static_cast<SwTxtFtn*>(pNewHt), *pDest);
    1347           0 :             break;
    1348             : 
    1349             :     // Beim Kopieren von Feldern in andere Dokumente
    1350             :     // muessen die Felder bei ihren neuen Feldtypen angemeldet werden.
    1351             : 
    1352             :     // TabellenFormel muessen relativ kopiert werden.
    1353             :     case RES_TXTATR_FIELD :
    1354             :         {
    1355         344 :             if( pOtherDoc != NULL )
    1356             :             {
    1357           0 :                 static_cast<const SwTxtFld*>(pHt)->CopyTxtFld( static_cast<SwTxtFld*>(pNewHt) );
    1358             :             }
    1359             : 
    1360             :             // Tabellenformel ??
    1361         344 :             const SwFmtFld& rFld = pHt->GetFmtFld();
    1362         688 :             if( RES_TABLEFLD == rFld.GetField()->GetTyp()->Which()
    1363         344 :                 && static_cast<const SwTblField*>(rFld.GetField())->IsIntrnlName())
    1364             :             {
    1365             :                 // wandel die interne in eine externe Formel um
    1366             :                 const SwTableNode* const pDstTblNd =
    1367           0 :                     static_cast<const SwTxtFld*>(pHt)->GetTxtNode().FindTableNode();
    1368           0 :                 if( pDstTblNd )
    1369             :                 {
    1370             :                     SwTblField* const pTblFld =
    1371             :                         const_cast<SwTblField*>(static_cast<const SwTblField*>(
    1372           0 :                             pNewHt->GetFmtFld().GetField()));
    1373           0 :                     pTblFld->PtrToBoxNm( &pDstTblNd->GetTable() );
    1374             :                 }
    1375             :             }
    1376             :         }
    1377         344 :         break;
    1378             : 
    1379             :     case RES_TXTATR_INPUTFIELD :
    1380             :     case RES_TXTATR_ANNOTATION :
    1381           0 :         if( pOtherDoc != NULL )
    1382             :         {
    1383           0 :             static_cast<const SwTxtFld*>(pHt)->CopyTxtFld( static_cast<SwTxtFld*>(pNewHt) );
    1384             :         }
    1385           0 :         break;
    1386             : 
    1387             :     case RES_TXTATR_TOXMARK :
    1388           0 :         if( pOtherDoc && pDest && pDest->GetpSwpHints()
    1389           0 :             && USHRT_MAX != pDest->GetpSwpHints()->GetPos( pNewHt ) )
    1390             :         {
    1391             :             // Beim Kopieren von TOXMarks(Client) in andere Dokumente
    1392             :             // muss der Verzeichnis (Modify) ausgetauscht werden
    1393           0 :             static_cast<SwTxtTOXMark*>(pNewHt)->CopyTOXMark( pOtherDoc );
    1394             :         }
    1395           0 :         break;
    1396             : 
    1397             :     case RES_TXTATR_CHARFMT :
    1398             :         // Wenn wir es mit einer Zeichenvorlage zu tun haben,
    1399             :         // muessen wir natuerlich auch die Formate kopieren.
    1400         182 :         if( pDest && pDest->GetpSwpHints()
    1401         182 :             && USHRT_MAX != pDest->GetpSwpHints()->GetPos( pNewHt ) )
    1402             :         {
    1403             :             SwCharFmt* pFmt =
    1404          91 :                 static_cast<SwCharFmt*>(pHt->GetCharFmt().GetCharFmt());
    1405             : 
    1406          91 :             if (pOtherDoc)
    1407             :             {
    1408           0 :                 pFmt = pOtherDoc->CopyCharFmt( *pFmt );
    1409             :             }
    1410             :             const_cast<SwFmtCharFmt&>( static_cast<const SwFmtCharFmt&>(
    1411          91 :                 pNewHt->GetCharFmt() ) ).SetCharFmt( pFmt );
    1412             :         }
    1413          91 :         break;
    1414             :     case RES_TXTATR_INETFMT :
    1415             :         {
    1416             :             // Wenn wir es mit benutzerdefinierten INet-Zeichenvorlagen
    1417             :             // zu tun haben, muessen wir natuerlich auch die Formate kopieren.
    1418           6 :             if( pOtherDoc && pDest && pDest->GetpSwpHints()
    1419           6 :                 && USHRT_MAX != pDest->GetpSwpHints()->GetPos( pNewHt ) )
    1420             :             {
    1421             :                 const SwDoc* const pDoc = static_cast<const SwTxtINetFmt*>(pHt)
    1422           0 :                     ->GetTxtNode().GetDoc();
    1423           0 :                 if ( pDoc )
    1424             :                 {
    1425           0 :                     const SwCharFmts* pCharFmts = pDoc->GetCharFmts();
    1426           0 :                     const SwFmtINetFmt& rFmt = pHt->GetINetFmt();
    1427             :                     SwCharFmt* pFmt;
    1428           0 :                     pFmt = lcl_FindCharFmt( pCharFmts, rFmt.GetINetFmt() );
    1429           0 :                     if( pFmt )
    1430           0 :                         pOtherDoc->CopyCharFmt( *pFmt );
    1431           0 :                     pFmt = lcl_FindCharFmt( pCharFmts, rFmt.GetVisitedFmt() );
    1432           0 :                     if( pFmt )
    1433           0 :                         pOtherDoc->CopyCharFmt( *pFmt );
    1434             :                 }
    1435             :             }
    1436             :             //JP 24.04.98: Bug 49753 - ein TextNode muss am Attribut
    1437             :             //              gesetzt sein, damit die Vorlagen erzeugt
    1438             :             //              werden koenne
    1439           6 :             SwTxtINetFmt* const pINetHt = static_cast<SwTxtINetFmt*>(pNewHt);
    1440           6 :             if ( !pINetHt->GetpTxtNode() )
    1441             :             {
    1442           0 :                 pINetHt->ChgTxtNode( pDest );
    1443             :             }
    1444             : 
    1445             :             //JP 22.10.97: Bug 44875 - Verbindung zum Format herstellen
    1446           6 :             pINetHt->GetCharFmt();
    1447           6 :             break;
    1448             :         }
    1449             :     case RES_TXTATR_META:
    1450             :     case RES_TXTATR_METAFIELD:
    1451             :         OSL_ENSURE( pNewHt, "copying Meta should not fail!" );
    1452             :         OSL_ENSURE( pDest
    1453             :                     && (CH_TXTATR_INWORD == pDest->GetTxt()[*pNewHt->GetStart()]),
    1454             :             "missing CH_TXTATR?");
    1455           0 :         break;
    1456             :     }
    1457        2045 : }
    1458             : 
    1459             : /*************************************************************************
    1460             : |*  SwTxtNode::CopyAttr()
    1461             : |*  Beschreibung    kopiert Attribute an der Position nStart in pDest.
    1462             : |*  BP 7.6.93:      Es werden mit Absicht nur die Attribute _mit_ EndIdx
    1463             : |*                  kopiert! CopyAttr wird vornehmlich dann gerufen,
    1464             : |*                  wenn Attribute fuer einen Node mit leerem String
    1465             : |*                  gesetzt werden sollen.
    1466             : *************************************************************************/
    1467             : 
    1468        1870 : void SwTxtNode::CopyAttr( SwTxtNode *pDest, const sal_Int32 nTxtStartIdx,
    1469             :                           const sal_Int32 nOldPos )
    1470             : {
    1471        1870 :     if ( HasHints() )    // keine Attribute, keine Kekse
    1472             :     {
    1473          62 :         SwDoc* const pOtherDoc = (pDest->GetDoc() != GetDoc()) ?
    1474          62 :                 pDest->GetDoc() : 0;
    1475             : 
    1476          79 :         for ( sal_uInt16 i = 0; i < m_pSwpHints->Count(); i++ )
    1477             :         {
    1478          17 :             SwTxtAttr *const pHt = m_pSwpHints->GetTextHint(i);
    1479          17 :             sal_Int32 const nAttrStartIdx = *pHt->GetStart();
    1480          17 :             if ( nTxtStartIdx < nAttrStartIdx )
    1481           0 :                 break; // ueber das Textende, da nLen == 0
    1482             : 
    1483          17 :             const sal_Int32 *const pEndIdx = pHt->GetEnd();
    1484          17 :             if ( pEndIdx && !pHt->HasDummyChar() )
    1485             :             {
    1486          17 :                 if ( ( *pEndIdx > nTxtStartIdx
    1487          17 :                        || ( *pEndIdx == nTxtStartIdx
    1488          17 :                             && nAttrStartIdx == nTxtStartIdx ) ) )
    1489             :                 {
    1490          17 :                     sal_uInt16 const nWhich = pHt->Which();
    1491          17 :                     if ( RES_TXTATR_REFMARK != nWhich )
    1492             :                     {
    1493             :                         // attribute in the area => copy
    1494             :                         SwTxtAttr *const pNewHt =
    1495          17 :                             pDest->InsertItem( pHt->GetAttr(), nOldPos, nOldPos, nsSetAttrMode::SETATTR_IS_COPY);
    1496          17 :                         if ( pNewHt )
    1497             :                         {
    1498             :                             lcl_CopyHint( nWhich, pHt, pNewHt,
    1499          17 :                                 pOtherDoc, pDest );
    1500             :                         }
    1501             :                     }
    1502           0 :                     else if( !pOtherDoc
    1503           0 :                              ? GetDoc()->IsCopyIsMove()
    1504           0 :                              : 0 == pOtherDoc->GetRefMark( pHt->GetRefMark().GetRefName() ) )
    1505             :                     {
    1506             :                         pDest->InsertItem(
    1507           0 :                             pHt->GetAttr(), nOldPos, nOldPos, nsSetAttrMode::SETATTR_IS_COPY);
    1508             :                     }
    1509             :                 }
    1510             :             }
    1511             :         }
    1512             :     }
    1513             : 
    1514        1870 :     if( this != pDest )
    1515             :     {
    1516             :         // Frames benachrichtigen, sonst verschwinden die Ftn-Nummern
    1517        1870 :         SwUpdateAttr aHint( nOldPos, nOldPos, 0 );
    1518        1870 :         pDest->ModifyNotification( 0, &aHint );
    1519             :     }
    1520        1870 : }
    1521             : 
    1522             : /*************************************************************************
    1523             : |*  SwTxtNode::Copy()
    1524             : |*  Beschreibung        kopiert Zeichen und Attibute in pDest,
    1525             : |*                      wird angehaengt
    1526             : *************************************************************************/
    1527             : 
    1528             : // introduction of new optional parameter to control, if all attributes have to be copied.
    1529        3572 : void SwTxtNode::CopyText( SwTxtNode *const pDest,
    1530             :                       const SwIndex &rStart,
    1531             :                       const sal_Int32 nLen,
    1532             :                       const bool bForceCopyOfAllAttrs )
    1533             : {
    1534        3572 :     SwIndex const aIdx( pDest, pDest->m_Text.getLength() );
    1535        3572 :     CopyText( pDest, aIdx, rStart, nLen, bForceCopyOfAllAttrs );
    1536        3572 : }
    1537             : 
    1538             : // introduction of new optional parameter to control, if all attributes have to be copied.
    1539        3679 : void SwTxtNode::CopyText( SwTxtNode *const pDest,
    1540             :                       const SwIndex &rDestStart,
    1541             :                       const SwIndex &rStart,
    1542             :                       sal_Int32 nLen,
    1543             :                       const bool bForceCopyOfAllAttrs )
    1544             : {
    1545        3679 :     sal_Int32 nTxtStartIdx = rStart.GetIndex();
    1546        3679 :     sal_Int32 nDestStart = rDestStart.GetIndex();      // alte Pos merken
    1547             : 
    1548        3679 :     if (pDest->GetDoc()->IsClipBoard() && this->GetNum())
    1549             :     {
    1550             :         // #i111677# cache expansion of source (for clipboard)
    1551             :         pDest->m_pNumStringCache.reset( (nTxtStartIdx != 0)
    1552           0 :             ? new OUString // fdo#49076: numbering only if copy from para start
    1553           0 :             : new OUString(this->GetNumString()));
    1554             :     }
    1555             : 
    1556        3679 :     if( !nLen )
    1557             :     {
    1558             :         // wurde keine Laenge angegeben, dann Kopiere die Attribute
    1559             :         // an der Position rStart.
    1560        1778 :         CopyAttr( pDest, nTxtStartIdx, nDestStart );
    1561             : 
    1562             :         // harte Absatz umspannende Attribute kopieren
    1563        1778 :         if( HasSwAttrSet() )
    1564             :         {
    1565             :             // alle, oder nur die CharAttribute ?
    1566             :             // #i96213#
    1567         498 :             if ( !bForceCopyOfAllAttrs &&
    1568          33 :                  ( nDestStart ||
    1569          65 :                    pDest->HasSwAttrSet() ||
    1570          32 :                    nLen != pDest->GetTxt().getLength()))
    1571             :             {
    1572           1 :                 SfxItemSet aCharSet( pDest->GetDoc()->GetAttrPool(),
    1573             :                                     RES_CHRATR_BEGIN, RES_CHRATR_END-1,
    1574             :                                     RES_TXTATR_INETFMT, RES_TXTATR_INETFMT,
    1575             :                                     RES_TXTATR_CHARFMT, RES_TXTATR_CHARFMT,
    1576             :                                     RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1,
    1577           1 :                                     0 );
    1578           1 :                 aCharSet.Put( *GetpSwAttrSet() );
    1579           1 :                 if( aCharSet.Count() )
    1580             :                 {
    1581           0 :                     pDest->SetAttr( aCharSet, nDestStart, nDestStart );
    1582           1 :                 }
    1583             :             }
    1584             :             else
    1585             :             {
    1586         496 :                 GetpSwAttrSet()->CopyToModify( *pDest );
    1587             :             }
    1588             :         }
    1589        3556 :         return;
    1590             :     }
    1591             : 
    1592             :     // 1. Text kopieren
    1593        1901 :     const sal_Int32 oldLen = pDest->m_Text.getLength();
    1594             :     //JP 15.02.96: Bug 25537 - Attributbehandlung am Ende fehlt! Darum
    1595             :     //              ueber die InsertMethode den Text einfuegen und nicht
    1596             :     //              selbst direkt
    1597             :     pDest->InsertText( m_Text.copy(nTxtStartIdx, nLen), rDestStart,
    1598        1901 :                    IDocumentContentOperations::INS_EMPTYEXPAND );
    1599             : 
    1600             :     // um reale Groesse Updaten !
    1601        1901 :     nLen = pDest->m_Text.getLength() - oldLen;
    1602        1901 :     if ( !nLen ) // string not longer?
    1603           0 :         return;
    1604             : 
    1605        1901 :     SwDoc* const pOtherDoc = (pDest->GetDoc() != GetDoc()) ? pDest->GetDoc() : 0;
    1606             : 
    1607             :     // harte Absatz umspannende Attribute kopieren
    1608        1901 :     if( HasSwAttrSet() )
    1609             :     {
    1610             :         // alle, oder nur die CharAttribute ?
    1611             :         // #i96213#
    1612        1268 :         if ( !bForceCopyOfAllAttrs &&
    1613          35 :              ( nDestStart ||
    1614          67 :                pDest->HasSwAttrSet() ||
    1615          32 :                nLen != pDest->GetTxt().getLength()))
    1616             :         {
    1617           3 :             SfxItemSet aCharSet( pDest->GetDoc()->GetAttrPool(),
    1618             :                 RES_CHRATR_BEGIN, RES_CHRATR_END-1,
    1619             :                 RES_TXTATR_INETFMT, RES_TXTATR_INETFMT,
    1620             :                 RES_TXTATR_CHARFMT, RES_TXTATR_CHARFMT,
    1621             :                 RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1,
    1622           3 :                 0 );
    1623           3 :             aCharSet.Put( *GetpSwAttrSet() );
    1624           3 :             if( aCharSet.Count() )
    1625             :             {
    1626           1 :                 pDest->SetAttr( aCharSet, nDestStart, nDestStart + nLen );
    1627           3 :             }
    1628             :         }
    1629             :         else
    1630             :         {
    1631        1262 :             GetpSwAttrSet()->CopyToModify( *pDest );
    1632             :         }
    1633             :     }
    1634             : 
    1635             :     bool const bUndoNodes = !pOtherDoc
    1636        1901 :                             && GetDoc()->GetIDocumentUndoRedo().IsUndoNodes(GetNodes());
    1637             : 
    1638             :     // Ende erst jetzt holen, weil beim Kopieren in sich selbst der
    1639             :     // Start-Index und alle Attribute vorher aktualisiert werden.
    1640        1901 :     nTxtStartIdx = rStart.GetIndex();
    1641        1901 :     const sal_Int32 nEnd = nTxtStartIdx + nLen;
    1642             : 
    1643             :     // 2. Attribute kopieren
    1644             :     // durch das Attribute-Array, bis der Anfang des Geltungsbereiches
    1645             :     // des Attributs hinter dem zu kopierenden Bereich liegt
    1646        1901 :     const sal_uInt16 nSize = m_pSwpHints ? m_pSwpHints->Count() : 0;
    1647             : 
    1648             :     // wird in sich selbst kopiert, dann kann beim Einfuegen ein
    1649             :     // Attribut geloescht werden. Darum erst ins Tmp-Array kopieren und
    1650             :     // dann erst ins eigene uebertragen.
    1651        1901 :     SwpHts aArr;
    1652             : 
    1653             :     // Del-Array fuer alle RefMarks ohne Ausdehnung
    1654        3802 :     SwpHts aRefMrkArr;
    1655             : 
    1656        1901 :     sal_Int32 nDeletedDummyChars(0);
    1657             :     //Achtung: kann ungueltig sein!!
    1658        3917 :     for (sal_uInt16 n = 0; ( n < nSize ); ++n)
    1659             :     {
    1660        3029 :         const sal_Int32 nAttrStartIdx = *(*m_pSwpHints)[n]->GetStart();
    1661        3029 :         if (!( nAttrStartIdx < nEnd))
    1662        1013 :             break;
    1663             : 
    1664        2016 :         SwTxtAttr * const pHt = m_pSwpHints->GetTextHint(n);
    1665        2016 :         const sal_Int32 * const pEndIdx = pHt->GetEnd();
    1666        2016 :         const sal_uInt16 nWhich = pHt->Which();
    1667             : 
    1668             :         // JP 26.04.94: REFMARK's werden nie kopiert. Hat das Refmark aber
    1669             :         //              keinen Bereich umspannt, so steht im Text ein 255
    1670             :         //              dieses muss entfernt werden. Trick: erst kopieren,
    1671             :         //              erkennen und sammeln, nach dem kopieren Loeschen.
    1672             :         //              Nimmt sein Zeichen mit ins Grab !!
    1673             :         // JP 14.08.95: Duerfen RefMarks gemovt werden?
    1674             :         const bool bCopyRefMark = RES_TXTATR_REFMARK == nWhich
    1675        2016 :                                   && ( bUndoNodes
    1676           0 :                                        || ( !pOtherDoc
    1677           0 :                                             ? GetDoc()->IsCopyIsMove()
    1678        2016 :                                             : 0 == pOtherDoc->GetRefMark( pHt->GetRefMark().GetRefName() ) ) );
    1679             : 
    1680        2016 :         if ( pEndIdx
    1681        1573 :              && RES_TXTATR_REFMARK == nWhich
    1682           0 :              && !bCopyRefMark )
    1683             :         {
    1684           0 :             continue;
    1685             :         }
    1686             : 
    1687             :         // Input Fields are only copied, if completely covered by copied text
    1688        2016 :         if ( nWhich == RES_TXTATR_INPUTFIELD )
    1689             :         {
    1690             :             OSL_ENSURE( pEndIdx != NULL,
    1691             :                     "<SwTxtNode::CopyText(..)> - RES_TXTATR_INPUTFIELD without EndIndex!" );
    1692           0 :             if ( nAttrStartIdx < nTxtStartIdx
    1693           0 :                  || ( pEndIdx != NULL
    1694           0 :                       && *(pEndIdx) > nEnd ) )
    1695             :             {
    1696           0 :                 continue;
    1697             :             }
    1698             :         }
    1699             : 
    1700        2016 :         sal_Int32 nAttrStt = 0;
    1701        2016 :         sal_Int32 nAttrEnd = 0;
    1702             : 
    1703        2016 :         if( nAttrStartIdx < nTxtStartIdx )
    1704             :         {
    1705             :             // start is before selection
    1706             :             // copy hints with end and CH_TXTATR only if dummy char is copied
    1707           0 :             if ( pEndIdx && (*pEndIdx > nTxtStartIdx) && !pHt->HasDummyChar() )
    1708             :             {
    1709             :                 // attribute with extent and the end is in the selection
    1710           0 :                 nAttrStt = nDestStart;
    1711           0 :                 nAttrEnd = (*pEndIdx > nEnd)
    1712             :                     ? rDestStart.GetIndex()
    1713           0 :                     : nDestStart + (*pEndIdx) - nTxtStartIdx;
    1714             :             }
    1715             :             else
    1716             :             {
    1717           0 :                 continue;
    1718             :             }
    1719             :         }
    1720             :         else
    1721             :         {
    1722             :             // start is in the selection
    1723        2016 :             nAttrStt = nDestStart + ( nAttrStartIdx - nTxtStartIdx );
    1724        2016 :             if( pEndIdx )
    1725             :             {
    1726        1573 :                 nAttrEnd = *pEndIdx > nEnd
    1727             :                     ? rDestStart.GetIndex()
    1728        1573 :                     : nDestStart + ( *pEndIdx - nTxtStartIdx );
    1729             :             }
    1730             :             else
    1731             :             {
    1732         443 :                 nAttrEnd = nAttrStt;
    1733             :             }
    1734             :         }
    1735             : 
    1736        2016 :         SwTxtAttr * pNewHt = 0;
    1737             : 
    1738        2016 :         if( pDest == this )
    1739             :         {
    1740             :             // copy the hint here, but insert it later
    1741           0 :             pNewHt = MakeTxtAttr( *GetDoc(), pHt->GetAttr(),
    1742           0 :                     nAttrStt, nAttrEnd, COPY, pDest );
    1743             : 
    1744           0 :             lcl_CopyHint(nWhich, pHt, pNewHt, 0, pDest);
    1745           0 :             aArr.push_back( pNewHt );
    1746             :         }
    1747             :         else
    1748             :         {
    1749             :             pNewHt = pDest->InsertItem(
    1750        2016 :                 pHt->GetAttr(),
    1751             :                 nAttrStt - nDeletedDummyChars,
    1752             :                 nAttrEnd - nDeletedDummyChars,
    1753        4032 :                 nsSetAttrMode::SETATTR_NOTXTATRCHR | nsSetAttrMode::SETATTR_IS_COPY);
    1754        2016 :             if (pNewHt)
    1755             :             {
    1756        2015 :                 lcl_CopyHint( nWhich, pHt, pNewHt, pOtherDoc, pDest );
    1757             :             }
    1758           1 :             else if (pHt->HasDummyChar())
    1759             :             {
    1760             :                 // The attribute that has failed to be copied would insert
    1761             :                 // dummy char, so positions of the following attributes have
    1762             :                 // to be shifted by one to compensate for that missing char.
    1763           0 :                 ++nDeletedDummyChars;
    1764             :             }
    1765             :         }
    1766             : 
    1767        2016 :         if( RES_TXTATR_REFMARK == nWhich && !pEndIdx && !bCopyRefMark )
    1768             :         {
    1769           0 :             aRefMrkArr.push_back( pNewHt );
    1770             :         }
    1771             :     }
    1772             : 
    1773             :     // nur falls im Array Attribute stehen (kann nur beim Kopieren
    1774             :     // sich selbst passieren!!)
    1775        1901 :     for ( sal_uInt16 i = 0; i < aArr.size(); ++i )
    1776             :     {
    1777           0 :         InsertHint( aArr[ i ], nsSetAttrMode::SETATTR_NOTXTATRCHR );
    1778             :     }
    1779             : 
    1780        1901 :     if( pDest->GetpSwpHints() )
    1781             :     {
    1782        1477 :         for ( sal_uInt16 i = 0; i < aRefMrkArr.size(); ++i )
    1783             :         {
    1784           0 :             SwTxtAttr * const pNewHt = aRefMrkArr[i];
    1785           0 :             if( pNewHt->GetEnd() )
    1786             :             {
    1787           0 :                 pDest->GetpSwpHints()->Delete( pNewHt );
    1788           0 :                 pDest->DestroyAttr( pNewHt );
    1789             :             }
    1790             :             else
    1791             :             {
    1792           0 :                 const SwIndex aIdx( pDest, *pNewHt->GetStart() );
    1793           0 :                 pDest->EraseText( aIdx, 1 );
    1794             :             }
    1795             :         }
    1796             :     }
    1797             : 
    1798        1901 :     CHECK_SWPHINTS(this);
    1799             : }
    1800             : 
    1801      102981 : OUString SwTxtNode::InsertText( const OUString & rStr, const SwIndex & rIdx,
    1802             :         const IDocumentContentOperations::InsertFlags nMode )
    1803             : {
    1804             :     assert(rIdx <= m_Text.getLength()); // invalid index
    1805             : 
    1806      102981 :     const sal_Int32 aPos = rIdx.GetIndex();
    1807      102981 :     sal_Int32 nLen = m_Text.getLength() - aPos;
    1808      102981 :     sal_Int32 const nOverflow(rStr.getLength() - GetSpaceLeft());
    1809             :     SAL_WARN_IF(nOverflow > 0, "sw.core",
    1810             :             "SwTxtNode::InsertText: node text with insertion > capacity.");
    1811             :     OUString const sInserted(
    1812      102981 :         (nOverflow > 0) ? rStr.copy(0, rStr.getLength() - nOverflow) : rStr);
    1813      102981 :     if (sInserted.isEmpty())
    1814             :     {
    1815         203 :         return sInserted;
    1816             :     }
    1817      102778 :     m_Text = m_Text.replaceAt(aPos, 0, sInserted);
    1818             :     assert(GetSpaceLeft()>=0);
    1819      102778 :     nLen = m_Text.getLength() - aPos - nLen;
    1820             :     assert(nLen != 0);
    1821             : 
    1822      102778 :     bool bOldExpFlg = IsIgnoreDontExpand();
    1823      102778 :     if (nMode & IDocumentContentOperations::INS_FORCEHINTEXPAND)
    1824             :     {
    1825          61 :         SetIgnoreDontExpand( true );
    1826             :     }
    1827             : 
    1828      102778 :     Update( rIdx, nLen ); // text content changed!
    1829             : 
    1830      102778 :     if (nMode & IDocumentContentOperations::INS_FORCEHINTEXPAND)
    1831             :     {
    1832          61 :         SetIgnoreDontExpand( bOldExpFlg );
    1833             :     }
    1834             : 
    1835             :     // analog zu Insert(char) in txtedt.cxx:
    1836             :     // 1) bei bHintExp leere Hints an rIdx.GetIndex suchen und aufspannen
    1837             :     // 2) bei bHintExp == sal_False mitgezogene Feldattribute zuruecksetzen
    1838             : 
    1839      102778 :     if ( HasHints() )
    1840             :     {
    1841       16824 :         bool bMergePortionsNeeded(false);
    1842      314870 :         for ( sal_uInt16 i = 0; i < m_pSwpHints->Count() &&
    1843      149075 :                 rIdx >= *(*m_pSwpHints)[i]->GetStart(); ++i )
    1844             :         {
    1845      148971 :             SwTxtAttr * const pHt = m_pSwpHints->GetTextHint( i );
    1846      148971 :             sal_Int32 * const pEndIdx = pHt->GetEnd();
    1847      148971 :             if( !pEndIdx )
    1848      114753 :                 continue;
    1849             : 
    1850       34218 :             if( rIdx == *pEndIdx )
    1851             :             {
    1852         459 :                 if (  (nMode & IDocumentContentOperations::INS_NOHINTEXPAND) ||
    1853         225 :                     (!(nMode & IDocumentContentOperations::INS_FORCEHINTEXPAND)
    1854         165 :                      && pHt->DontExpand()) )
    1855             :                 {
    1856             :                     // bei leeren Attributen auch Start veraendern
    1857           9 :                     if( rIdx == *pHt->GetStart() )
    1858           9 :                         *pHt->GetStart() = *pHt->GetStart() - nLen;
    1859           9 :                     *pEndIdx = *pEndIdx - nLen;
    1860           9 :                     m_pSwpHints->DeleteAtPos(i);
    1861             :                     // could be that pHt has IsFormatIgnoreEnd set, and it's
    1862             :                     // not a RSID-only hint - now we have the inserted text
    1863             :                     // between pHt and its continuation... which we don't know.
    1864             :                     // punt the job to MergePortions below.
    1865           9 :                     if (pHt->IsFormatIgnoreEnd())
    1866             :                     {
    1867           0 :                         bMergePortionsNeeded = true;
    1868             :                     }
    1869           9 :                     InsertHint( pHt, nsSetAttrMode::SETATTR_NOHINTADJUST );
    1870             :                 }
    1871             :                 // empty hints at insert position?
    1872         432 :                 else if ( (nMode & IDocumentContentOperations::INS_EMPTYEXPAND)
    1873         216 :                         && (*pEndIdx == *pHt->GetStart()) )
    1874             :                 {
    1875           2 :                     *pHt->GetStart() = *pHt->GetStart() - nLen;
    1876           2 :                     const sal_uInt16 nAktLen = m_pSwpHints->Count();
    1877           2 :                     m_pSwpHints->DeleteAtPos(i);
    1878           2 :                     InsertHint( pHt/* AUTOSTYLES:, nsSetAttrMode::SETATTR_NOHINTADJUST*/ );
    1879           2 :                     if ( nAktLen > m_pSwpHints->Count() && i )
    1880             :                     {
    1881           1 :                         --i;
    1882             :                     }
    1883           2 :                     continue;
    1884             :                 }
    1885             :                 else
    1886             :                 {
    1887         214 :                     continue;
    1888             :                 }
    1889             :             }
    1890      102006 :             if ( !(nMode & IDocumentContentOperations::INS_NOHINTEXPAND) &&
    1891       34214 :                  rIdx == nLen && *pHt->GetStart() == rIdx.GetIndex() &&
    1892         102 :                  !pHt->IsDontExpandStartAttr() )
    1893             :             {
    1894             :                 // Kein Feld, am Absatzanfang, HintExpand
    1895         101 :                 m_pSwpHints->DeleteAtPos(i);
    1896         101 :                 *pHt->GetStart() = *pHt->GetStart() - nLen;
    1897             :                 // no effect on format ignore flags here (para start)
    1898         101 :                 InsertHint( pHt, nsSetAttrMode::SETATTR_NOHINTADJUST );
    1899             :             }
    1900             :         }
    1901       16824 :         if (bMergePortionsNeeded)
    1902             :         {
    1903           0 :             m_pSwpHints->MergePortions(*this);
    1904             :         }
    1905       16824 :         TryDeleteSwpHints();
    1906             :     }
    1907             : 
    1908      102778 :     if ( GetDepends() )
    1909             :     {
    1910        9780 :         SwInsTxt aHint( aPos, nLen );
    1911        9780 :         NotifyClients( 0, &aHint );
    1912             :     }
    1913             : 
    1914             :     // By inserting a character, the hidden flags
    1915             :     // at the TxtNode can become invalid:
    1916      102778 :     SetCalcHiddenCharFlags();
    1917             : 
    1918             :     CHECK_SWPHINTS(this);
    1919      102778 :     return sInserted;
    1920             : }
    1921             : 
    1922             : /*************************************************************************
    1923             : |*
    1924             : |*  SwTxtNode::Cut()
    1925             : |*
    1926             : |*  Beschreibung        text.doc
    1927             : |*
    1928             : *************************************************************************/
    1929             : 
    1930        2468 : void SwTxtNode::CutText( SwTxtNode * const pDest,
    1931             :             const SwIndex & rStart, const sal_Int32 nLen )
    1932             : {
    1933        2468 :     if(nLen == 0)
    1934        4496 :         return;
    1935         440 :     if(pDest)
    1936             :     {
    1937         440 :         SwIndex aDestStt(pDest, pDest->GetTxt().getLength());
    1938         440 :         CutImpl( pDest, aDestStt, rStart, nLen, false );
    1939             :     }
    1940             :     else
    1941             :     {
    1942             :         OSL_FAIL("mst: entering dead and bitrotted code; fasten your seatbelts!");
    1943             :         assert(false);
    1944           0 :         EraseText( rStart, nLen );
    1945             :     }
    1946             : }
    1947             : 
    1948         556 : void SwTxtNode::CutImpl( SwTxtNode * const pDest, const SwIndex & rDestStart,
    1949             :          const SwIndex & rStart, sal_Int32 nLen, const bool bUpdate )
    1950             : {
    1951         556 :     if(!pDest)
    1952             :     {
    1953             :         OSL_FAIL("mst: entering dead and bitrotted code; fasten your seatbelts!");
    1954             :         assert(false);
    1955           0 :         EraseText( rStart, nLen );
    1956          90 :         return;
    1957             :     }
    1958             : 
    1959             :     // nicht im Dokument verschieben ?
    1960         556 :     if( GetDoc() != pDest->GetDoc() )
    1961             :     {
    1962             :         OSL_FAIL("mst: entering dead and bitrotted code; fasten your seatbelts!");
    1963             :         assert(false);
    1964           0 :         CopyText( pDest, rDestStart, rStart, nLen);
    1965           0 :         EraseText(rStart, nLen);
    1966           0 :         return;
    1967             :     }
    1968             : 
    1969         556 :     if( !nLen )
    1970             :     {
    1971             :         // wurde keine Laenge angegeben, dann Kopiere die Attribute
    1972             :         // an der Position rStart.
    1973          90 :         CopyAttr( pDest, rStart.GetIndex(), rDestStart.GetIndex() );
    1974          90 :         return;
    1975             :     }
    1976             : 
    1977         466 :     sal_Int32 nTxtStartIdx = rStart.GetIndex();
    1978         466 :     sal_Int32 nDestStart = rDestStart.GetIndex();      // alte Pos merken
    1979         466 :     const sal_Int32 nInitSize = pDest->m_Text.getLength();
    1980             : 
    1981             :     // wird in sich selbst verschoben, muss es gesondert behandelt werden !!
    1982         466 :     if( pDest == this )
    1983             :     {
    1984             :         OSL_FAIL("mst: entering dead and bitrotted code; fasten your seatbelts!");
    1985             :         assert(false);
    1986           0 :         OUStringBuffer buf(m_Text);
    1987           0 :         buf.insert(nDestStart, m_Text.copy(nTxtStartIdx, nLen));
    1988             :         buf.remove(
    1989           0 :             nTxtStartIdx + ((nDestStart < nTxtStartIdx) ? nLen : 0), nLen);
    1990           0 :         m_Text = buf.makeStringAndClear();
    1991             : 
    1992           0 :         const sal_Int32 nEnd = rStart.GetIndex() + nLen;
    1993             : 
    1994             :         // dann suche mal alle Attribute zusammen, die im verschobenen
    1995             :         // Bereich liegen. Diese werden in das extra Array verschoben,
    1996             :         // damit sich die Indizies beim Updaten nicht veraendern !!!
    1997           0 :         SwpHts aArr;
    1998             : 
    1999             :         // 2. Attribute verschieben
    2000             :         // durch das Attribute-Array, bis der Anfang des Geltungsbereiches
    2001             :         // des Attributs hinter dem zu verschiebenden Bereich liegt
    2002           0 :         sal_uInt16 nAttrCnt = 0;
    2003           0 :         while ( m_pSwpHints && nAttrCnt < m_pSwpHints->Count() )
    2004             :         {
    2005           0 :             SwTxtAttr * const pHt = m_pSwpHints->GetTextHint(nAttrCnt);
    2006           0 :             const sal_Int32 nAttrStartIdx = *pHt->GetStart();
    2007           0 :             if (!( nAttrStartIdx < nEnd ))
    2008           0 :                 break;
    2009           0 :             const sal_Int32 * const pEndIdx = pHt->GetEnd();
    2010           0 :             const sal_uInt16 nWhich = pHt->Which();
    2011           0 :             SwTxtAttr *pNewHt = 0;
    2012             : 
    2013           0 :             if(nAttrStartIdx < nTxtStartIdx)
    2014             :             {
    2015             :                 // Anfang liegt vor dem Bereich
    2016           0 :                 if ( RES_TXTATR_REFMARK != nWhich && !pHt->HasDummyChar() &&
    2017           0 :                     pEndIdx && *pEndIdx > nTxtStartIdx )
    2018             :                 {
    2019             :                     // Attribut mit einem Bereich
    2020             :                     // und das Ende des Attribut liegt im Bereich
    2021           0 :                     pNewHt = MakeTxtAttr( *GetDoc(), pHt->GetAttr(), 0,
    2022           0 :                                         *pEndIdx > nEnd
    2023             :                                             ? nLen
    2024           0 :                                             : *pEndIdx - nTxtStartIdx );
    2025             :                 }
    2026             :             }
    2027             :             else
    2028             :             {
    2029             :                 // der Anfang liegt vollstaendig im Bereich
    2030           0 :                 if( !pEndIdx || *pEndIdx < nEnd )
    2031             :                 {
    2032             :                     // Attribut verschieben
    2033           0 :                     m_pSwpHints->Delete( pHt );
    2034             :                     // die Start/End Indicies neu setzen
    2035           0 :                     *pHt->GetStart() = nAttrStartIdx - nTxtStartIdx;
    2036           0 :                     if( pEndIdx )
    2037           0 :                         *pHt->GetEnd() = *pEndIdx - nTxtStartIdx;
    2038           0 :                     aArr.push_back( pHt );
    2039           0 :                     continue;           // while-Schleife weiter, ohne ++ !
    2040             :                 }
    2041             :                     // das Ende liegt dahinter
    2042           0 :                 else if (RES_TXTATR_REFMARK != nWhich && !pHt->HasDummyChar())
    2043             :                 {
    2044           0 :                     pNewHt = MakeTxtAttr( *GetDoc(),
    2045           0 :                                           pHt->GetAttr(),
    2046             :                                           nAttrStartIdx - nTxtStartIdx,
    2047           0 :                                           ( *pEndIdx > nEnd
    2048             :                                             ? nLen
    2049           0 :                                             : *pEndIdx - nTxtStartIdx ));
    2050             :                 }
    2051             :             }
    2052           0 :             if( pNewHt )
    2053             :             {
    2054             :                 // die Daten kopieren
    2055           0 :                 lcl_CopyHint( nWhich, pHt, pNewHt, 0, this );
    2056           0 :                 aArr.push_back( pNewHt );
    2057             :             }
    2058           0 :             ++nAttrCnt;
    2059             :         }
    2060             : 
    2061           0 :         if( bUpdate )
    2062             :         {
    2063             :             // Update aller Indizies
    2064           0 :             Update( rDestStart, nLen, false, true );
    2065             :         }
    2066             : 
    2067             :         CHECK_SWPHINTS(this);
    2068             : 
    2069           0 :         Update( rStart, nLen, true, true );
    2070             : 
    2071             :         CHECK_SWPHINTS(this);
    2072             : 
    2073             :         // dann setze die kopierten/geloeschten Attribute in den Node
    2074           0 :         if( nDestStart <= nTxtStartIdx )
    2075             :         {
    2076           0 :             nTxtStartIdx = nTxtStartIdx + nLen;
    2077             :         }
    2078             :         else
    2079             :         {
    2080           0 :             nDestStart = nDestStart - nLen;
    2081             :         }
    2082             : 
    2083           0 :         for ( sal_uInt16 n = 0; n < aArr.size(); ++n )
    2084             :         {
    2085           0 :             SwTxtAttr *const pNewHt = aArr[n];
    2086           0 :             *pNewHt->GetStart() = nDestStart + *pNewHt->GetStart();
    2087           0 :             sal_Int32 * const pEndIdx = pNewHt->GetEnd();
    2088           0 :             if ( pEndIdx )
    2089             :             {
    2090           0 :                 *pEndIdx = nDestStart + *pEndIdx;
    2091             :             }
    2092           0 :             InsertHint( pNewHt, nsSetAttrMode::SETATTR_NOTXTATRCHR );
    2093           0 :         }
    2094             :     }
    2095             :     else
    2096             :     {
    2097         932 :         pDest->m_Text = pDest->m_Text.replaceAt(nDestStart, 0,
    2098         466 :                             m_Text.copy(nTxtStartIdx, nLen));
    2099         466 :         m_Text = m_Text.replaceAt(nTxtStartIdx, nLen, "");
    2100         466 :         if (GetSpaceLeft()<0)
    2101             :         {   // FIXME: could only happen when called from SwRangeRedline::Show.
    2102             :             // unfortunately can't really do anything here to handle that...
    2103           0 :             abort();
    2104             :         }
    2105         466 :         nLen = pDest->m_Text.getLength() - nInitSize; // update w/ current size!
    2106         466 :         if( !nLen )                 // String nicht gewachsen ??
    2107           0 :             return;
    2108             : 
    2109         466 :         if( bUpdate )
    2110             :         {
    2111             :             // Update aller Indizies
    2112          26 :             pDest->Update( rDestStart, nLen, false, true);
    2113             :         }
    2114             : 
    2115             :         CHECK_SWPHINTS(pDest);
    2116             : 
    2117         466 :         const sal_Int32 nEnd = rStart.GetIndex() + nLen;
    2118         466 :         SwDoc* const pOtherDoc = (pDest->GetDoc() != GetDoc())
    2119         466 :             ? pDest->GetDoc() : 0;
    2120             :         bool const bUndoNodes = !pOtherDoc
    2121         466 :             && GetDoc()->GetIDocumentUndoRedo().IsUndoNodes(GetNodes());
    2122             : 
    2123             :         OSL_ENSURE(!pOtherDoc,
    2124             :             "mst: entering dead and bitrotted code; fasten your seatbelts!");
    2125             :         assert(!pOtherDoc);
    2126             : 
    2127             :         // harte Absatz umspannende Attribute kopieren
    2128         466 :         if( HasSwAttrSet() )
    2129             :         {
    2130             :             // alle, oder nur die CharAttribute ?
    2131         420 :             if( nInitSize || pDest->HasSwAttrSet() ||
    2132          54 :                 nLen != pDest->GetTxt().getLength())
    2133             :             {
    2134         312 :                 SfxItemSet aCharSet( pDest->GetDoc()->GetAttrPool(),
    2135             :                                     RES_CHRATR_BEGIN, RES_CHRATR_END-1,
    2136             :                                     RES_TXTATR_INETFMT, RES_TXTATR_INETFMT,
    2137             :                                     RES_TXTATR_CHARFMT, RES_TXTATR_CHARFMT,
    2138             :                                     RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1,
    2139         312 :                                     0 );
    2140         312 :                 aCharSet.Put( *GetpSwAttrSet() );
    2141         312 :                 if( aCharSet.Count() )
    2142         263 :                     pDest->SetAttr( aCharSet, nDestStart, nDestStart + nLen );
    2143             :             }
    2144             :             else
    2145             :             {
    2146          54 :                 GetpSwAttrSet()->CopyToModify( *pDest );
    2147             :             }
    2148             :         }
    2149             : 
    2150             :         // 2. Attribute verschieben
    2151             :         // durch das Attribute-Array, bis der Anfang des Geltungsbereiches
    2152             :         // des Attributs hinter dem zu verschiebenden Bereich liegt
    2153         466 :         bool bMergePortionsNeeded(false);
    2154         466 :         sal_uInt16 nAttrCnt = 0;
    2155         976 :         while ( m_pSwpHints && (nAttrCnt < m_pSwpHints->Count()) )
    2156             :         {
    2157          45 :             SwTxtAttr * const pHt = m_pSwpHints->GetTextHint(nAttrCnt);
    2158          45 :             const sal_Int32 nAttrStartIdx = *pHt->GetStart();
    2159          45 :             if (!( nAttrStartIdx < nEnd ))
    2160           1 :                 break;
    2161          44 :             const sal_Int32 * const pEndIdx = pHt->GetEnd();
    2162          44 :             const sal_uInt16 nWhich = pHt->Which();
    2163          44 :             SwTxtAttr *pNewHt = 0;
    2164             : 
    2165             :             // if the hint has a dummy character, then it must not be split!
    2166          44 :             if(nAttrStartIdx < nTxtStartIdx)
    2167             :             {
    2168             :                 // Anfang liegt vor dem Bereich
    2169           0 :                 if( !pHt->HasDummyChar() && ( RES_TXTATR_REFMARK != nWhich
    2170           0 :                     || bUndoNodes ) && pEndIdx && *pEndIdx > nTxtStartIdx )
    2171             :                 {
    2172             :                     // Attribut mit einem Bereich
    2173             :                     // und das Ende des Attribut liegt im Bereich
    2174           0 :                     pNewHt = MakeTxtAttr( *pDest->GetDoc(), pHt->GetAttr(),
    2175             :                                     nDestStart,
    2176             :                                     nDestStart + (
    2177           0 :                                         *pEndIdx > nEnd
    2178             :                                             ? nLen
    2179           0 :                                             : *pEndIdx - nTxtStartIdx ) );
    2180             :                 }
    2181             :             }
    2182             :             else
    2183             :             {
    2184             :                 // der Anfang liegt vollstaendig im Bereich
    2185          85 :                 if( !pEndIdx || *pEndIdx < nEnd ||
    2186          13 :                     (!pOtherDoc && !bUndoNodes && RES_TXTATR_REFMARK == nWhich)
    2187          57 :                     || pHt->HasDummyChar() )
    2188             :                 {
    2189             :                     // do not delete note and later add it -> sidebar flickering
    2190          31 :                     if ( GetDoc()->GetDocShell() )
    2191             :                     {
    2192          31 :                         GetDoc()->GetDocShell()->Broadcast( SfxSimpleHint(SFX_HINT_USER04));
    2193             :                     }
    2194             :                     // Attribut verschieben
    2195          31 :                     m_pSwpHints->Delete( pHt );
    2196             :                     // die Start/End Indicies neu setzen
    2197          31 :                     if (pHt->IsFormatIgnoreStart() || pHt->IsFormatIgnoreEnd())
    2198             :                     {
    2199           0 :                         bMergePortionsNeeded = true;
    2200             :                     }
    2201          31 :                     *pHt->GetStart() =
    2202          31 :                             nDestStart + (nAttrStartIdx - nTxtStartIdx);
    2203          31 :                     if( pEndIdx )
    2204             :                     {
    2205          84 :                         *pHt->GetEnd() = nDestStart + (
    2206          28 :                                         *pEndIdx > nEnd
    2207             :                                             ? nLen
    2208          56 :                                             : *pEndIdx - nTxtStartIdx );
    2209             :                     }
    2210             :                     pDest->InsertHint( pHt,
    2211             :                               nsSetAttrMode::SETATTR_NOTXTATRCHR
    2212          31 :                             | nsSetAttrMode::SETATTR_DONTREPLACE );
    2213          31 :                     if ( GetDoc()->GetDocShell() )
    2214             :                     {
    2215          31 :                         GetDoc()->GetDocShell()->Broadcast( SfxSimpleHint(SFX_HINT_USER04));
    2216             :                     }
    2217          31 :                     continue;           // while-Schleife weiter, ohne ++ !
    2218             :                 }
    2219             :                     // das Ende liegt dahinter
    2220          13 :                 else if( RES_TXTATR_REFMARK != nWhich || bUndoNodes )
    2221             :                 {
    2222          13 :                     pNewHt = MakeTxtAttr( *GetDoc(), pHt->GetAttr(),
    2223          13 :                                           nDestStart + (nAttrStartIdx - nTxtStartIdx),
    2224          13 :                                           nDestStart + ( *pEndIdx > nEnd
    2225             :                                                          ? nLen
    2226          39 :                                                          : *pEndIdx - nTxtStartIdx ));
    2227             :                 }
    2228             :             }
    2229          13 :             if ( pNewHt )
    2230             :             {
    2231             :                 const bool bSuccess( pDest->InsertHint( pNewHt,
    2232             :                               nsSetAttrMode::SETATTR_NOTXTATRCHR
    2233             :                             | nsSetAttrMode::SETATTR_DONTREPLACE
    2234          13 :                             | nsSetAttrMode::SETATTR_IS_COPY) );
    2235          13 :                 if (bSuccess)
    2236             :                 {
    2237          13 :                     lcl_CopyHint( nWhich, pHt, pNewHt, pOtherDoc, pDest );
    2238             :                 }
    2239             :             }
    2240          13 :             ++nAttrCnt;
    2241             :         }
    2242             :         // sollten jetzt noch leere Attribute rumstehen, dann haben diese
    2243             :         // eine hoehere Praezedenz. Also herausholen und das Array updaten.
    2244             :         // Die dabei entstehenden leeren Hints werden von den gesicherten
    2245             :         // "uebergeplaettet".   (Bug: 6977)
    2246         466 :         if( m_pSwpHints && nAttrCnt < m_pSwpHints->Count() )
    2247             :         {
    2248           1 :             SwpHts aArr;
    2249           3 :             while ( nAttrCnt < m_pSwpHints->Count() )
    2250             :             {
    2251           1 :                 SwTxtAttr * const pHt = m_pSwpHints->GetTextHint(nAttrCnt);
    2252           1 :                 if ( nEnd != *pHt->GetStart() )
    2253           0 :                     break;
    2254           1 :                 const sal_Int32 * const pEndIdx = pHt->GetEnd();
    2255           1 :                 if ( pEndIdx && *pEndIdx == nEnd )
    2256             :                 {
    2257           1 :                     aArr.push_back( pHt );
    2258           1 :                     m_pSwpHints->Delete( pHt );
    2259             :                 }
    2260             :                 else
    2261             :                 {
    2262           0 :                     ++nAttrCnt;
    2263             :                 }
    2264             :             }
    2265           1 :             Update( rStart, nLen, true, true );
    2266             : 
    2267           2 :             for ( sal_uInt16 n = 0; n < aArr.size(); ++n )
    2268             :             {
    2269           1 :                 SwTxtAttr * const pHt = aArr[ n ];
    2270           1 :                 *pHt->GetStart() = *pHt->GetEnd() = rStart.GetIndex();
    2271           1 :                 InsertHint( pHt );
    2272           1 :             }
    2273             :         }
    2274             :         else
    2275             :         {
    2276         465 :             Update( rStart, nLen, true, true );
    2277             :         }
    2278             : 
    2279         466 :         if (bMergePortionsNeeded)
    2280             :         {
    2281           0 :             m_pSwpHints->MergePortions(*this);
    2282             :         }
    2283             : 
    2284             :         CHECK_SWPHINTS(this);
    2285             :     }
    2286             : 
    2287         466 :     TryDeleteSwpHints();
    2288             : 
    2289             :     // Frames benachrichtigen;
    2290         466 :     SwInsTxt aInsHint( nDestStart, nLen );
    2291         466 :     pDest->ModifyNotification( 0, &aInsHint );
    2292         932 :     SwDelTxt aDelHint( nTxtStartIdx, nLen );
    2293         932 :     ModifyNotification( 0, &aDelHint );
    2294             : }
    2295             : 
    2296        2250 : void SwTxtNode::EraseText(const SwIndex &rIdx, const sal_Int32 nCount,
    2297             :         const IDocumentContentOperations::InsertFlags nMode )
    2298             : {
    2299             :     assert(rIdx <= m_Text.getLength()); // invalid index
    2300             : 
    2301        2250 :     const sal_Int32 nStartIdx = rIdx.GetIndex();
    2302             :     const sal_Int32 nCnt = (nCount==SAL_MAX_INT32)
    2303        2250 :                       ? m_Text.getLength() - nStartIdx : nCount;
    2304        2250 :     const sal_Int32 nEndIdx = nStartIdx + nCnt;
    2305        2250 :     m_Text = m_Text.replaceAt(nStartIdx, nCnt, "");
    2306             : 
    2307             :     /* GCAttr(); alle leeren weggwerfen ist zu brutal.
    2308             :      * Es duerfen nur die wegggeworfen werden,
    2309             :      * die im Bereich liegen und nicht am Ende des Bereiches liegen
    2310             :      */
    2311             : 
    2312        3904 :     for ( sal_uInt16 i = 0; m_pSwpHints && i < m_pSwpHints->Count(); ++i )
    2313             :     {
    2314        1756 :         SwTxtAttr *pHt = m_pSwpHints->GetTextHint(i);
    2315             : 
    2316        1756 :         const sal_Int32 nHintStart = *pHt->GetStart();
    2317             : 
    2318        1756 :         if ( nHintStart < nStartIdx )
    2319         115 :             continue;
    2320             : 
    2321        1641 :         if ( nHintStart > nEndIdx )
    2322         102 :             break; // hints are sorted by end, so break here
    2323             : 
    2324        1539 :         const sal_Int32* pHtEndIdx = pHt->GetEnd();
    2325        1539 :         const sal_uInt16 nWhich = pHt->Which();
    2326             : 
    2327        1539 :         if( !pHtEndIdx )
    2328             :         {
    2329             :                     // attribute with neither end nor CH_TXTATR?
    2330             :             assert(pHt->HasDummyChar());
    2331        3912 :             if (isTXTATR(nWhich) &&
    2332        2608 :                 (nHintStart >= nStartIdx) && (nHintStart < nEndIdx))
    2333             :             {
    2334        1258 :                 m_pSwpHints->DeleteAtPos(i);
    2335        1258 :                 DestroyAttr( pHt );
    2336        1258 :                 --i;
    2337             :             }
    2338        1304 :             continue;
    2339             :         }
    2340             : 
    2341             :        assert(!( (nHintStart < nEndIdx) && (*pHtEndIdx > nEndIdx)
    2342             :                     && pHt->HasDummyChar() )
    2343             :                 // next line: deleting exactly dummy char: DeleteAttributes
    2344             :                 || ((nHintStart == nStartIdx) && (nHintStart + 1 == nEndIdx)));
    2345             :                 // "ERROR: deleting left-overlapped attribute with CH_TXTATR");
    2346             : 
    2347             :         // Delete the hint if:
    2348             :         // 1. The hint ends before the deletion end position or
    2349             :         // 2. The hint ends at the deletion end position and
    2350             :         //    we are not in empty expand mode and
    2351             :         //    the hint is a [toxmark|refmark|ruby|inputfield] text attribute
    2352             :         // 3. deleting exactly the dummy char of an hint with end and dummy
    2353             :         //    char deletes the hint
    2354         470 :         if (   (*pHtEndIdx < nEndIdx)
    2355         277 :             || ( (*pHtEndIdx == nEndIdx)     &&
    2356         176 :                  !(IDocumentContentOperations::INS_EMPTYEXPAND & nMode)  &&
    2357          88 :                  (  (RES_TXTATR_TOXMARK == nWhich)  ||
    2358          88 :                     (RES_TXTATR_REFMARK == nWhich)  ||
    2359          87 :                     (RES_TXTATR_CJK_RUBY == nWhich) ||
    2360             :                     (RES_TXTATR_INPUTFIELD == nWhich) ) )
    2361         575 :             || ( (nHintStart < nEndIdx)     &&
    2362         152 :                  pHt->HasDummyChar()        )
    2363             :            )
    2364             :         {
    2365          52 :             m_pSwpHints->DeleteAtPos(i);
    2366          52 :             DestroyAttr( pHt );
    2367          52 :             --i;
    2368             :         }
    2369             :     }
    2370             : 
    2371             :     OSL_ENSURE(rIdx.GetIndex() == nStartIdx, "huh? start index has changed?");
    2372             : 
    2373        2250 :     TryDeleteSwpHints();
    2374             : 
    2375        2250 :     Update( rIdx, nCnt, true );
    2376             : 
    2377        2250 :     if( 1 == nCnt )
    2378             :     {
    2379        1730 :         SwDelChr aHint( nStartIdx );
    2380        1730 :         NotifyClients( 0, &aHint );
    2381             :     }
    2382             :     else
    2383             :     {
    2384         520 :         SwDelTxt aHint( nStartIdx, nCnt );
    2385         520 :         NotifyClients( 0, &aHint );
    2386             :     }
    2387             : 
    2388             :     OSL_ENSURE(rIdx.GetIndex() == nStartIdx, "huh? start index has changed?");
    2389             : 
    2390             :     // By deleting a character, the hidden flags
    2391             :     // at the TxtNode can become invalid:
    2392        2250 :     SetCalcHiddenCharFlags();
    2393             : 
    2394             :     CHECK_SWPHINTS(this);
    2395        2250 : }
    2396             : 
    2397             : /***********************************************************************
    2398             : #*  Class       :   SwTxtNode
    2399             : #*  Methode     :   GCAttr
    2400             : #*
    2401             : #*  Beschreibung
    2402             : #*                  text.doc
    2403             : #***********************************************************************/
    2404             : 
    2405           0 : void SwTxtNode::GCAttr()
    2406             : {
    2407           0 :     if ( !HasHints() )
    2408           0 :         return;
    2409             : 
    2410           0 :     bool   bChanged = false;
    2411           0 :     sal_Int32 nMin = m_Text.getLength();
    2412           0 :     sal_Int32 nMax = 0;
    2413           0 :     const bool bAll = nMin != 0; // Bei leeren Absaetzen werden nur die
    2414             :                            // INet-Formate entfernt.
    2415             : 
    2416           0 :     for ( sal_uInt16 i = 0; m_pSwpHints && i < m_pSwpHints->Count(); ++i )
    2417             :     {
    2418           0 :         SwTxtAttr * const pHt = m_pSwpHints->GetTextHint(i);
    2419             : 
    2420             :         // wenn Ende und Start gleich sind --> loeschen
    2421           0 :         const sal_Int32 * const pEndIdx = pHt->GetEnd();
    2422           0 :         if (pEndIdx && !pHt->HasDummyChar() && (*pEndIdx == *pHt->GetStart())
    2423           0 :             && ( bAll || pHt->Which() == RES_TXTATR_INETFMT ) )
    2424             :         {
    2425           0 :             bChanged = true;
    2426           0 :             nMin = std::min( nMin, *pHt->GetStart() );
    2427           0 :             nMax = std::max( nMax, *pHt->GetEnd() );
    2428           0 :             DestroyAttr( m_pSwpHints->Cut(i) );
    2429           0 :             --i;
    2430             :         }
    2431             :         else
    2432             :         {
    2433           0 :             pHt->SetDontExpand( false );
    2434             :         }
    2435             :     }
    2436           0 :     TryDeleteSwpHints();
    2437             : 
    2438           0 :     if(bChanged)
    2439             :     {
    2440             :         //TxtFrm's reagieren auf aHint, andere auf aNew
    2441           0 :         SwUpdateAttr aHint( nMin, nMax, 0 );
    2442           0 :         NotifyClients( 0, &aHint );
    2443           0 :         SwFmtChg aNew( GetTxtColl() );
    2444           0 :         NotifyClients( 0, &aNew );
    2445             :     }
    2446             : }
    2447             : 
    2448             : // #i23726#
    2449      534855 : SwNumRule* SwTxtNode::_GetNumRule(bool bInParent) const
    2450             : {
    2451      534855 :     SwNumRule* pRet = 0;
    2452             : 
    2453      534855 :     const SfxPoolItem* pItem = GetNoCondAttr( RES_PARATR_NUMRULE, bInParent );
    2454      534855 :     bool bNoNumRule = false;
    2455      534855 :     if ( pItem )
    2456             :     {
    2457             :         OUString sNumRuleName =
    2458       50112 :             static_cast<const SwNumRuleItem *>(pItem)->GetValue();
    2459       50112 :         if (!sNumRuleName.isEmpty())
    2460             :         {
    2461       49508 :             pRet = GetDoc()->FindNumRulePtr( sNumRuleName );
    2462             :         }
    2463             :         else // numbering is turned off
    2464         604 :             bNoNumRule = true;
    2465             :     }
    2466             : 
    2467      534855 :     if ( !bNoNumRule )
    2468             :     {
    2469      538313 :         if ( pRet && pRet == GetDoc()->GetOutlineNumRule() &&
    2470        4285 :              ( !HasSwAttrSet() ||
    2471             :                SFX_ITEM_SET !=
    2472        2118 :                 GetpSwAttrSet()->GetItemState( RES_PARATR_NUMRULE, false ) ) )
    2473             :         {
    2474        1895 :             SwTxtFmtColl* pColl = GetTxtColl();
    2475        1895 :             if ( pColl )
    2476             :             {
    2477        1895 :                 const SwNumRuleItem& rDirectItem = pColl->GetNumRule( sal_False );
    2478        1895 :                 if ( rDirectItem.GetValue().isEmpty() )
    2479             :                 {
    2480           0 :                     pRet = 0L;
    2481             :                 }
    2482             :             }
    2483             :         }
    2484             :     }
    2485             : 
    2486      534855 :     return pRet;
    2487             : }
    2488             : 
    2489      534855 : SwNumRule* SwTxtNode::GetNumRule(bool bInParent) const
    2490             : {
    2491      534855 :     return _GetNumRule(bInParent);
    2492             : }
    2493             : 
    2494        1833 : void SwTxtNode::NumRuleChgd()
    2495             : {
    2496        1833 :     if ( IsInList() )
    2497             :     {
    2498        1833 :         SwNumRule* pNumRule = GetNumRule();
    2499        1833 :         if ( pNumRule && pNumRule != GetNum()->GetNumRule() )
    2500             :         {
    2501           0 :             mpNodeNum->ChangeNumRule( *pNumRule );
    2502             :         }
    2503             :     }
    2504             : 
    2505        1833 :     if( IsInCache() )
    2506             :     {
    2507          17 :         SwFrm::GetCache().Delete( this );
    2508          17 :         SetInCache( sal_False );
    2509             :     }
    2510        1833 :     SetInSwFntCache( sal_False );
    2511             : 
    2512             :     // Sending "noop" modify in order to cause invalidations of registered
    2513             :     // <SwTxtFrm> instances to get the list style change respectively the change
    2514             :     // in the list tree reflected in the layout.
    2515             :     // Important note:
    2516             :     {
    2517        1833 :         SvxLRSpaceItem& rLR = (SvxLRSpaceItem&)GetSwAttrSet().GetLRSpace();
    2518        1833 :         NotifyClients( &rLR, &rLR );
    2519             :     }
    2520             : 
    2521        1833 :     SetWordCountDirty( true );
    2522        1833 : }
    2523             : 
    2524             : // -> #i27615#
    2525       62235 : bool SwTxtNode::IsNumbered() const
    2526             : {
    2527       62235 :     SwNumRule* pRule = GetNum() ? GetNum()->GetNumRule() : 0L;
    2528       62235 :     return pRule && IsCountedInList();
    2529             : }
    2530             : 
    2531         143 : bool SwTxtNode::HasMarkedLabel() const
    2532             : {
    2533         143 :     bool bResult = false;
    2534             : 
    2535         143 :     if ( IsInList() )
    2536             :     {
    2537             :         bResult =
    2538         138 :             GetDoc()->getListByName( GetListId() )->IsListLevelMarked( GetActualListLevel() );
    2539             :     }
    2540             : 
    2541         143 :     return bResult;
    2542             : }
    2543             : // <- #i27615#
    2544             : 
    2545       26086 : SwTxtNode* SwTxtNode::_MakeNewTxtNode( const SwNodeIndex& rPos, bool bNext,
    2546             :                                        bool bChgFollow )
    2547             : {
    2548             :     /* hartes PageBreak/PageDesc/ColumnBreak aus AUTO-Set ignorieren */
    2549       26086 :     SwAttrSet* pNewAttrSet = 0;
    2550             :     // #i75353#
    2551       26086 :     bool bClearHardSetNumRuleWhenFmtCollChanges( false );
    2552       26086 :     if( HasSwAttrSet() )
    2553             :     {
    2554        1746 :         pNewAttrSet = new SwAttrSet( *GetpSwAttrSet() );
    2555        1746 :         const SfxItemSet* pTmpSet = GetpSwAttrSet();
    2556             : 
    2557        1746 :         if( bNext )     // der naechste erbt keine Breaks!
    2558        1423 :             pTmpSet = pNewAttrSet;
    2559             : 
    2560             :         // PageBreaks/PageDesc/ColBreak rausschmeissen.
    2561        1746 :         bool bRemoveFromCache = false;
    2562        1746 :         std::vector<sal_uInt16> aClearWhichIds;
    2563        1746 :         if ( bNext )
    2564        1423 :             bRemoveFromCache = ( 0 != pNewAttrSet->ClearItem( RES_PAGEDESC ) );
    2565             :         else
    2566         323 :             aClearWhichIds.push_back( RES_PAGEDESC );
    2567             : 
    2568        1746 :         if( SFX_ITEM_SET == pTmpSet->GetItemState( RES_BREAK, false ) )
    2569             :         {
    2570          92 :             if ( bNext )
    2571          92 :                 pNewAttrSet->ClearItem( RES_BREAK );
    2572             :             else
    2573           0 :                 aClearWhichIds.push_back( RES_BREAK );
    2574          92 :             bRemoveFromCache = true;
    2575             :         }
    2576        1746 :         if( SFX_ITEM_SET == pTmpSet->GetItemState( RES_KEEP, false ) )
    2577             :         {
    2578           1 :             if ( bNext )
    2579           1 :                 pNewAttrSet->ClearItem( RES_KEEP );
    2580             :             else
    2581           0 :                 aClearWhichIds.push_back( RES_KEEP );
    2582           1 :             bRemoveFromCache = true;
    2583             :         }
    2584        1746 :         if( SFX_ITEM_SET == pTmpSet->GetItemState( RES_PARATR_SPLIT, false ) )
    2585             :         {
    2586           0 :             if ( bNext )
    2587           0 :                 pNewAttrSet->ClearItem( RES_PARATR_SPLIT );
    2588             :             else
    2589           0 :                 aClearWhichIds.push_back( RES_PARATR_SPLIT );
    2590           0 :             bRemoveFromCache = true;
    2591             :         }
    2592        1746 :         if(SFX_ITEM_SET == pTmpSet->GetItemState(RES_PARATR_NUMRULE, false))
    2593             :         {
    2594         331 :             SwNumRule * pRule = GetNumRule();
    2595             : 
    2596         331 :             if (pRule && IsOutline())
    2597             :             {
    2598           1 :                 if ( bNext )
    2599           1 :                     pNewAttrSet->ClearItem(RES_PARATR_NUMRULE);
    2600             :                 else
    2601             :                 {
    2602             :                     // #i75353#
    2603             :                     // No clear of hard set numbering rule at an outline paragraph at this point.
    2604             :                     // Only if the paragraph style changes - see below.
    2605           0 :                     bClearHardSetNumRuleWhenFmtCollChanges = true;
    2606             :                 }
    2607           1 :                 bRemoveFromCache = true;
    2608             :             }
    2609             :         }
    2610             : 
    2611        1746 :         if ( !aClearWhichIds.empty() )
    2612         323 :             bRemoveFromCache = 0 != ClearItemsFromAttrSet( aClearWhichIds );
    2613             : 
    2614        1746 :         if( !bNext && bRemoveFromCache && IsInCache() )
    2615             :         {
    2616           0 :             SwFrm::GetCache().Delete( this );
    2617           0 :             SetInCache( sal_False );
    2618        1746 :         }
    2619             :     }
    2620       26086 :     SwNodes& rNds = GetNodes();
    2621             : 
    2622       26086 :     SwTxtFmtColl* pColl = GetTxtColl();
    2623             : 
    2624       26086 :     SwTxtNode *pNode = new SwTxtNode( rPos, pColl, pNewAttrSet );
    2625             : 
    2626       26086 :     delete pNewAttrSet;
    2627             : 
    2628       26086 :     const SwNumRule* pRule = GetNumRule();
    2629       26086 :     if( pRule && pRule == pNode->GetNumRule() && rNds.IsDocNodes() ) // #115901#
    2630             :     {
    2631             :         // #i55459#
    2632             :         // - correction: parameter <bNext> has to be checked, as it was in the
    2633             :         //   previous implementation.
    2634         492 :         if ( !bNext && !IsCountedInList() )
    2635           0 :             SetCountedInList(true);
    2636             :     }
    2637             : 
    2638             :     // jetzt kann es sein, das durch die Nummerierung dem neuen Node eine
    2639             :     // Vorlage aus dem Pool zugewiesen wurde. Dann darf diese nicht
    2640             :     // nochmal uebergeplaettet werden !!
    2641       26086 :     if( pColl != pNode->GetTxtColl() ||
    2642       26029 :         ( bChgFollow && pColl != GetTxtColl() ))
    2643           0 :         return pNode;       // mehr duerfte nicht gemacht werden oder ????
    2644             : 
    2645       26086 :     pNode->_ChgTxtCollUpdateNum( 0, pColl ); // fuer Nummerierung/Gliederung
    2646       26086 :     if( bNext || !bChgFollow )
    2647       25561 :         return pNode;
    2648             : 
    2649         525 :     SwTxtFmtColl *pNextColl = &pColl->GetNextTxtFmtColl();
    2650             :     // #i101870#
    2651             :     // perform action on different paragraph styles before applying the new paragraph style
    2652         525 :     if (pNextColl != pColl)
    2653             :     {
    2654             :         // #i75353#
    2655           1 :         if ( bClearHardSetNumRuleWhenFmtCollChanges )
    2656             :         {
    2657           0 :             std::vector<sal_uInt16> aClearWhichIds;
    2658           0 :             aClearWhichIds.push_back( RES_PARATR_NUMRULE );
    2659           0 :             if ( ClearItemsFromAttrSet( aClearWhichIds ) != 0 && IsInCache() )
    2660             :             {
    2661           0 :                 SwFrm::GetCache().Delete( this );
    2662           0 :                 SetInCache( sal_False );
    2663           0 :             }
    2664             :         }
    2665             :     }
    2666         525 :     ChgFmtColl( pNextColl );
    2667             : 
    2668         525 :     return pNode;
    2669             : }
    2670             : 
    2671       25504 : SwCntntNode* SwTxtNode::AppendNode( const SwPosition & rPos )
    2672             : {
    2673             :     // Position hinter dem eingefuegt wird
    2674       25504 :     SwNodeIndex aIdx( rPos.nNode, 1 );
    2675       25504 :     SwTxtNode* pNew = _MakeNewTxtNode( aIdx, true );
    2676             : 
    2677             :     // reset list attributes at appended text node
    2678       25504 :     pNew->ResetAttr( RES_PARATR_LIST_ISRESTART );
    2679       25504 :     pNew->ResetAttr( RES_PARATR_LIST_RESTARTVALUE );
    2680       25504 :     pNew->ResetAttr( RES_PARATR_LIST_ISCOUNTED );
    2681       25504 :     if ( pNew->GetNumRule() == 0 )
    2682             :     {
    2683       25012 :         pNew->ResetAttr( RES_PARATR_LIST_ID );
    2684       25012 :         pNew->ResetAttr( RES_PARATR_LIST_LEVEL );
    2685             :     }
    2686             : 
    2687       25504 :     if (!IsInList() && GetNumRule() && !GetListId().isEmpty())
    2688             :     {
    2689           0 :         AddToList();
    2690             :     }
    2691             : 
    2692       25504 :     if( GetDepends() )
    2693        1636 :         MakeFrms( *pNew );
    2694       25504 :     return pNew;
    2695             : }
    2696             : 
    2697             : /*************************************************************************
    2698             :  *                      SwTxtNode::GetTxtAttr
    2699             :  *************************************************************************/
    2700             : 
    2701      152558 : SwTxtAttr * SwTxtNode::GetTxtAttrForCharAt(
    2702             :     const sal_Int32 nIndex,
    2703             :     const RES_TXTATR nWhich ) const
    2704             : {
    2705      152558 :     if ( HasHints() )
    2706             :     {
    2707       93534 :         for ( sal_uInt16 i = 0; i < m_pSwpHints->Count(); ++i )
    2708             :         {
    2709       75473 :             SwTxtAttr * const pHint = m_pSwpHints->GetTextHint(i);
    2710       75473 :             const sal_Int32 nStartPos = *pHint->GetStart();
    2711       75473 :             if ( nIndex < nStartPos )
    2712             :             {
    2713       10161 :                 return 0;
    2714             :             }
    2715       65312 :             if ( (nIndex == nStartPos) && pHint->HasDummyChar() )
    2716             :             {
    2717        8640 :                 return ( RES_TXTATR_END == nWhich || nWhich == pHint->Which() )
    2718       25370 :                        ? pHint : 0;
    2719             :             }
    2720             :         }
    2721             :     }
    2722      126429 :     return 0;
    2723             : }
    2724             : 
    2725             : // -> #i29560#
    2726        2890 : bool SwTxtNode::HasNumber() const
    2727             : {
    2728        2890 :     bool bResult = false;
    2729             : 
    2730        2890 :     const SwNumRule* pRule = GetNum() ? GetNum()->GetNumRule() : 0L;
    2731        2890 :     if ( pRule )
    2732             :     {
    2733        2200 :         int nLevel = GetActualListLevel();
    2734             : 
    2735        2200 :         if (nLevel < 0)
    2736           0 :             nLevel = 0;
    2737             : 
    2738        2200 :         if (nLevel >= MAXLEVEL)
    2739           0 :             nLevel = MAXLEVEL - 1;
    2740             : 
    2741        2200 :         SwNumFmt aFmt(pRule->Get(static_cast<sal_uInt16>(nLevel)));
    2742             : 
    2743             :         // #i40041#
    2744        4283 :         bResult = aFmt.IsEnumeration() &&
    2745        4283 :             SVX_NUM_NUMBER_NONE != aFmt.GetNumberingType();
    2746             :     }
    2747             : 
    2748        2890 :     return bResult;
    2749             : }
    2750             : 
    2751        4929 : bool SwTxtNode::HasBullet() const
    2752             : {
    2753        4929 :     bool bResult = false;
    2754             : 
    2755        4929 :     const SwNumRule* pRule = GetNum() ? GetNum()->GetNumRule() : 0L;
    2756        4929 :     if ( pRule )
    2757             :     {
    2758         660 :         int nLevel = GetActualListLevel();
    2759             : 
    2760         660 :         if (nLevel < 0)
    2761           0 :             nLevel = 0;
    2762             : 
    2763         660 :         if (nLevel >= MAXLEVEL)
    2764           0 :             nLevel = MAXLEVEL - 1;
    2765             : 
    2766         660 :         SwNumFmt aFmt(pRule->Get( static_cast<sal_uInt16>(nLevel) ));
    2767             : 
    2768         660 :         bResult = aFmt.IsItemize();
    2769             :     }
    2770             : 
    2771        4929 :     return bResult;
    2772             : }
    2773             : // <- #i29560#
    2774             : 
    2775             : // #128041# - introduce parameter <_bInclPrefixAndSuffixStrings>
    2776             : //i53420 added max outline parameter
    2777        5365 : OUString SwTxtNode::GetNumString( const bool _bInclPrefixAndSuffixStrings,
    2778             :         const unsigned int _nRestrictToThisLevel ) const
    2779             : {
    2780        5365 :     if (GetDoc()->IsClipBoard() && m_pNumStringCache.get())
    2781             :     {
    2782             :         // #i111677# do not expand number strings in clipboard documents
    2783           0 :         return *m_pNumStringCache;
    2784             :     }
    2785        5365 :     const SwNumRule* pRule = GetNum() ? GetNum()->GetNumRule() : 0L;
    2786        7136 :     if ( pRule &&
    2787        1771 :          IsCountedInList() )
    2788             :     {
    2789        1771 :         int nLevel = GetActualListLevel();
    2790             : 
    2791        1771 :         if (nLevel < 0)
    2792           0 :             nLevel = 0;
    2793             : 
    2794        1771 :         if (nLevel >= MAXLEVEL)
    2795           0 :             nLevel = MAXLEVEL - 1;
    2796             : 
    2797             :         SvxNumberType const& rNumberType(
    2798        1771 :                 pRule->Get( static_cast<sal_uInt16>(nLevel) ) );
    2799        1977 :         if (rNumberType.IsTxtFmt() ||
    2800             : 
    2801         206 :             (style::NumberingType::NUMBER_NONE == rNumberType.GetNumberingType()))
    2802             :         {
    2803        1636 :             return pRule->MakeNumString( GetNum()->GetNumberVector(),
    2804             :                                      _bInclPrefixAndSuffixStrings ? sal_True : sal_False,
    2805             :                                      sal_False,
    2806        3272 :                                      _nRestrictToThisLevel );
    2807             :         }
    2808             :     }
    2809             : 
    2810        3729 :     return OUString();
    2811             : }
    2812             : 
    2813      419282 : long SwTxtNode::GetLeftMarginWithNum( bool bTxtLeft ) const
    2814             : {
    2815      419282 :     long nRet = 0;
    2816      419282 :     const SwNumRule* pRule = GetNum() ? GetNum()->GetNumRule() : 0L;
    2817      419282 :     if( pRule )
    2818             :     {
    2819       19480 :         int nLevel = GetActualListLevel();
    2820             : 
    2821       19480 :         if (nLevel < 0)
    2822           0 :             nLevel = 0;
    2823             : 
    2824       19480 :         if (nLevel >= MAXLEVEL)
    2825           0 :             nLevel = MAXLEVEL - 1;
    2826             : 
    2827       19480 :         const SwNumFmt& rFmt = pRule->Get(static_cast<sal_uInt16>(nLevel));
    2828             : 
    2829       19480 :         if ( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
    2830             :         {
    2831        1355 :             nRet = rFmt.GetAbsLSpace();
    2832             : 
    2833        1355 :             if( !bTxtLeft )
    2834             :             {
    2835        2216 :                 if( 0 > rFmt.GetFirstLineOffset() &&
    2836        1108 :                     nRet > -rFmt.GetFirstLineOffset() )
    2837         421 :                     nRet = nRet + rFmt.GetFirstLineOffset();
    2838             :                 else
    2839         687 :                     nRet = 0;
    2840             :             }
    2841             : 
    2842        1355 :             if( pRule->IsAbsSpaces() )
    2843           0 :                 nRet = nRet - GetSwAttrSet().GetLRSpace().GetLeft();
    2844             :         }
    2845       18125 :         else if ( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
    2846             :         {
    2847       18125 :             if ( AreListLevelIndentsApplicable() )
    2848             :             {
    2849       13183 :                 nRet = rFmt.GetIndentAt();
    2850             :                 // #i90401#
    2851             :                 // Only negative first line indents have consider for the left margin
    2852       22632 :                 if ( !bTxtLeft &&
    2853        9449 :                      rFmt.GetFirstLineIndent() < 0 )
    2854             :                 {
    2855        9137 :                     nRet = nRet + rFmt.GetFirstLineIndent();
    2856             :                 }
    2857             :             }
    2858             :         }
    2859             :     }
    2860             : 
    2861      419282 :     return nRet;
    2862             : }
    2863             : 
    2864      112478 : bool SwTxtNode::GetFirstLineOfsWithNum( short& rFLOffset ) const
    2865             : {
    2866             :     // #i95907#
    2867      112478 :     rFLOffset = 0;
    2868             : 
    2869             :     // #i51089#
    2870      112478 :     const SwNumRule* pRule = GetNum() ? GetNum()->GetNumRule() : 0L;
    2871      112478 :     if ( pRule )
    2872             :     {
    2873        5068 :         if ( IsCountedInList() )
    2874             :         {
    2875        5012 :             int nLevel = GetActualListLevel();
    2876             : 
    2877        5012 :             if (nLevel < 0)
    2878           0 :                 nLevel = 0;
    2879             : 
    2880        5012 :             if (nLevel >= MAXLEVEL)
    2881           0 :                 nLevel = MAXLEVEL - 1;
    2882             : 
    2883        5012 :             const SwNumFmt& rFmt = pRule->Get(static_cast<sal_uInt16>(nLevel));
    2884        5012 :             if ( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
    2885             :             {
    2886         247 :                 rFLOffset = rFmt.GetFirstLineOffset();
    2887             : 
    2888         247 :                 if (!getIDocumentSettingAccess()->get(IDocumentSettingAccess::IGNORE_FIRST_LINE_INDENT_IN_NUMBERING))
    2889             :                 {
    2890         247 :                     SvxLRSpaceItem aItem = GetSwAttrSet().GetLRSpace();
    2891         247 :                     rFLOffset = rFLOffset + aItem.GetTxtFirstLineOfst();
    2892             :                 }
    2893             :             }
    2894        4765 :             else if ( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
    2895             :             {
    2896        4765 :                 if ( AreListLevelIndentsApplicable() )
    2897             :                 {
    2898        3734 :                     rFLOffset = static_cast<sal_uInt16>(rFmt.GetFirstLineIndent());
    2899             :                 }
    2900        1031 :                 else if (!getIDocumentSettingAccess()->get(IDocumentSettingAccess::IGNORE_FIRST_LINE_INDENT_IN_NUMBERING))
    2901             :                 {
    2902        1031 :                     SvxLRSpaceItem aItem = GetSwAttrSet().GetLRSpace();
    2903        1031 :                     rFLOffset = aItem.GetTxtFirstLineOfst();
    2904             :                 }
    2905             :             }
    2906             :         }
    2907             : 
    2908        5068 :         return true;
    2909             :     }
    2910             : 
    2911      107410 :     rFLOffset = GetSwAttrSet().GetLRSpace().GetTxtFirstLineOfst();
    2912      107410 :     return false;
    2913             : }
    2914             : 
    2915           0 : SwTwips SwTxtNode::GetAdditionalIndentForStartingNewList() const
    2916             : {
    2917           0 :     SwTwips nAdditionalIndent = 0;
    2918             : 
    2919           0 :     const SwNumRule* pRule = GetNum() ? GetNum()->GetNumRule() : 0L;
    2920           0 :     if ( pRule )
    2921             :     {
    2922           0 :         int nLevel = GetActualListLevel();
    2923             : 
    2924           0 :         if (nLevel < 0)
    2925           0 :             nLevel = 0;
    2926             : 
    2927           0 :         if (nLevel >= MAXLEVEL)
    2928           0 :             nLevel = MAXLEVEL - 1;
    2929             : 
    2930           0 :         const SwNumFmt& rFmt = pRule->Get(static_cast<sal_uInt16>(nLevel));
    2931           0 :         if ( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
    2932             :         {
    2933           0 :             nAdditionalIndent = GetSwAttrSet().GetLRSpace().GetLeft();
    2934             : 
    2935           0 :             if (getIDocumentSettingAccess()->get(IDocumentSettingAccess::IGNORE_FIRST_LINE_INDENT_IN_NUMBERING))
    2936             :             {
    2937           0 :                 nAdditionalIndent = nAdditionalIndent -
    2938           0 :                                     GetSwAttrSet().GetLRSpace().GetTxtFirstLineOfst();
    2939             :             }
    2940             :         }
    2941           0 :         else if ( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
    2942             :         {
    2943           0 :             if ( AreListLevelIndentsApplicable() )
    2944             :             {
    2945           0 :                 nAdditionalIndent = rFmt.GetIndentAt() + rFmt.GetFirstLineIndent();
    2946             :             }
    2947             :             else
    2948             :             {
    2949           0 :                 nAdditionalIndent = GetSwAttrSet().GetLRSpace().GetLeft();
    2950           0 :                 if (getIDocumentSettingAccess()->get(IDocumentSettingAccess::IGNORE_FIRST_LINE_INDENT_IN_NUMBERING))
    2951             :                 {
    2952           0 :                     nAdditionalIndent = nAdditionalIndent -
    2953           0 :                                         GetSwAttrSet().GetLRSpace().GetTxtFirstLineOfst();
    2954             :                 }
    2955             :             }
    2956             :         }
    2957             :     }
    2958             :     else
    2959             :     {
    2960           0 :         nAdditionalIndent = GetSwAttrSet().GetLRSpace().GetLeft();
    2961             :     }
    2962             : 
    2963           0 :     return nAdditionalIndent;
    2964             : }
    2965             : 
    2966             : // #i96772#
    2967       26957 : void SwTxtNode::ClearLRSpaceItemDueToListLevelIndents( SvxLRSpaceItem& o_rLRSpaceItem ) const
    2968             : {
    2969       26957 :     if ( AreListLevelIndentsApplicable() )
    2970             :     {
    2971        2047 :         const SwNumRule* pRule = GetNumRule();
    2972        2047 :         if ( pRule && GetActualListLevel() >= 0 )
    2973             :         {
    2974        2047 :             int nLevel = GetActualListLevel();
    2975             : 
    2976        2047 :             if (nLevel < 0)
    2977           0 :                 nLevel = 0;
    2978             : 
    2979        2047 :             if (nLevel >= MAXLEVEL)
    2980           0 :                 nLevel = MAXLEVEL - 1;
    2981             : 
    2982        2047 :             const SwNumFmt& rFmt = pRule->Get(static_cast<sal_uInt16>(nLevel));
    2983        2047 :             if ( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
    2984             :             {
    2985        2026 :                 SvxLRSpaceItem aLR( RES_LR_SPACE );
    2986        2026 :                 o_rLRSpaceItem = aLR;
    2987             :             }
    2988             :         }
    2989             :     }
    2990       26957 : }
    2991             : 
    2992             : // #i91133#
    2993      112202 : long SwTxtNode::GetLeftMarginForTabCalculation() const
    2994             : {
    2995      112202 :     long nLeftMarginForTabCalc = 0;
    2996             : 
    2997      112202 :     bool bLeftMarginForTabCalcSetToListLevelIndent( false );
    2998      112202 :     const SwNumRule* pRule = GetNum() ? GetNum()->GetNumRule() : 0;
    2999      112202 :     if( pRule )
    3000             :     {
    3001        5068 :         int nLevel = GetActualListLevel();
    3002             : 
    3003        5068 :         if (nLevel < 0)
    3004           0 :             nLevel = 0;
    3005             : 
    3006        5068 :         if (nLevel >= MAXLEVEL)
    3007           0 :             nLevel = MAXLEVEL - 1;
    3008             : 
    3009        5068 :         const SwNumFmt& rFmt = pRule->Get(static_cast<sal_uInt16>(nLevel));
    3010        5068 :         if ( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
    3011             :         {
    3012        4821 :             if ( AreListLevelIndentsApplicable() )
    3013             :             {
    3014        3734 :                 nLeftMarginForTabCalc = rFmt.GetIndentAt();
    3015        3734 :                 bLeftMarginForTabCalcSetToListLevelIndent = true;
    3016             :             }
    3017             :         }
    3018             :     }
    3019      112202 :     if ( !bLeftMarginForTabCalcSetToListLevelIndent )
    3020             :     {
    3021      108468 :         nLeftMarginForTabCalc = GetSwAttrSet().GetLRSpace().GetTxtLeft();
    3022             :     }
    3023             : 
    3024      112202 :     return nLeftMarginForTabCalc;
    3025             : }
    3026             : 
    3027           0 : static void Replace0xFF(
    3028             :     SwTxtNode const& rNode,
    3029             :     OUStringBuffer & rTxt,
    3030             :     sal_Int32 & rTxtStt,
    3031             :     sal_Int32 nEndPos,
    3032             :     sal_Bool const bExpandFlds,
    3033             :     sal_Bool const bExpandFtn = sal_True )
    3034             : {
    3035           0 :     if (rNode.GetpSwpHints())
    3036             :     {
    3037           0 :         sal_Unicode cSrchChr = CH_TXTATR_BREAKWORD;
    3038           0 :         for( int nSrchIter = 0; 2 > nSrchIter; ++nSrchIter, cSrchChr = CH_TXTATR_INWORD )
    3039             :         {
    3040           0 :             sal_Int32 nPos = rTxt.indexOf(cSrchChr);
    3041           0 :             while (-1 != nPos && nPos < nEndPos)
    3042             :             {
    3043             :                 const SwTxtAttr* const pAttr =
    3044           0 :                     rNode.GetTxtAttrForCharAt(rTxtStt + nPos);
    3045           0 :                 if( pAttr )
    3046             :                 {
    3047           0 :                     switch( pAttr->Which() )
    3048             :                     {
    3049             :                     case RES_TXTATR_FIELD:
    3050             :                     case RES_TXTATR_ANNOTATION:
    3051           0 :                         rTxt.remove(nPos, 1);
    3052           0 :                         if( bExpandFlds )
    3053             :                         {
    3054             :                             const OUString aExpand(
    3055           0 :                                 static_cast<SwTxtFld const*>(pAttr)->GetFmtFld().GetField()->ExpandField(true));
    3056           0 :                             rTxt.insert(nPos, aExpand);
    3057           0 :                             nPos = nPos + aExpand.getLength();
    3058           0 :                             nEndPos = nEndPos + aExpand.getLength();
    3059           0 :                             rTxtStt = rTxtStt - aExpand.getLength();
    3060             :                         }
    3061           0 :                         ++rTxtStt;
    3062           0 :                         break;
    3063             : 
    3064             :                     case RES_TXTATR_FTN:
    3065           0 :                         rTxt.remove(nPos, 1);
    3066           0 :                         if( bExpandFlds && bExpandFtn )
    3067             :                         {
    3068           0 :                             const SwFmtFtn& rFtn = pAttr->GetFtn();
    3069           0 :                             OUString sExpand;
    3070           0 :                             if( !rFtn.GetNumStr().isEmpty() )
    3071           0 :                                 sExpand = rFtn.GetNumStr();
    3072           0 :                             else if( rFtn.IsEndNote() )
    3073           0 :                                 sExpand = rNode.GetDoc()->GetEndNoteInfo().aFmt.
    3074           0 :                                                 GetNumStr( rFtn.GetNumber() );
    3075             :                             else
    3076           0 :                                 sExpand = rNode.GetDoc()->GetFtnInfo().aFmt.
    3077           0 :                                                 GetNumStr( rFtn.GetNumber() );
    3078           0 :                             rTxt.insert(nPos, sExpand);
    3079           0 :                             nPos = nPos + sExpand.getLength();
    3080           0 :                             nEndPos = nEndPos + sExpand.getLength();
    3081           0 :                             rTxtStt = rTxtStt - sExpand.getLength();
    3082             :                         }
    3083           0 :                         ++rTxtStt;
    3084           0 :                         break;
    3085             : 
    3086             :                     default:
    3087           0 :                         rTxt.remove(nPos, 1);
    3088           0 :                         ++rTxtStt;
    3089             :                     }
    3090             :                 }
    3091             :                 else
    3092           0 :                     ++nPos, ++nEndPos;
    3093           0 :                 nPos = rTxt.indexOf(cSrchChr, nPos);
    3094             :             }
    3095             :         }
    3096             :     }
    3097           0 : }
    3098             : 
    3099             : /*************************************************************************
    3100             :  *                      SwTxtNode::GetExpandTxt
    3101             :  * Expand fields
    3102             :  *************************************************************************/
    3103             : // #i83479# - handling of new parameters
    3104        2477 : OUString SwTxtNode::GetExpandTxt(  const sal_Int32 nIdx,
    3105             :                                    const sal_Int32 nLen,
    3106             :                                    const bool bWithNum,
    3107             :                                    const bool bAddSpaceAfterListLabelStr,
    3108             :                                    const bool bWithSpacesForLevel,
    3109             :                                    const bool bWithFtn ) const
    3110             : 
    3111             : {
    3112        2477 :     sal_uInt16 eMode = EXPANDFIELDS;
    3113        2477 :     if (bWithFtn)
    3114        2477 :         eMode |= EXPANDFOOTNOTE;
    3115             : 
    3116        2477 :     ModelToViewHelper aConversionMap(*this, eMode);
    3117        4954 :     OUString aExpandText = aConversionMap.getViewText();
    3118        2477 :     const sal_Int32 nExpandBegin = aConversionMap.ConvertToViewPosition( nIdx );
    3119        2477 :     sal_Int32 nEnd = nLen == -1 ? GetTxt().getLength() : nIdx + nLen;
    3120        2477 :     const sal_Int32 nExpandEnd = aConversionMap.ConvertToViewPosition( nEnd );
    3121        4954 :     OUStringBuffer aTxt(aExpandText.copy(nExpandBegin, nExpandEnd-nExpandBegin));
    3122             : 
    3123             :     // remove dummy characters of Input Fields
    3124        2477 :     comphelper::string::remove(aTxt, CH_TXT_ATR_INPUTFIELDSTART);
    3125        2477 :     comphelper::string::remove(aTxt, CH_TXT_ATR_INPUTFIELDEND);
    3126             : 
    3127        2477 :     if( bWithNum )
    3128             :     {
    3129           0 :         if ( !GetNumString().isEmpty() )
    3130             :         {
    3131           0 :             if ( bAddSpaceAfterListLabelStr )
    3132             :             {
    3133           0 :                 const sal_Unicode aSpace = ' ';
    3134           0 :                 aTxt.insert(0, aSpace);
    3135             :             }
    3136           0 :             aTxt.insert(0, GetNumString());
    3137             :         }
    3138             :     }
    3139             : 
    3140        2477 :     if (bWithSpacesForLevel)
    3141             :     {
    3142           0 :         const sal_Unicode aSpace = ' ';
    3143           0 :         for (int nLevel = GetActualListLevel(); nLevel > 0; --nLevel)
    3144             :         {
    3145           0 :             aTxt.insert(0, aSpace);
    3146           0 :             aTxt.insert(0, aSpace);
    3147             :         }
    3148             :     }
    3149             : 
    3150        4954 :     return aTxt.makeStringAndClear();
    3151             : }
    3152             : 
    3153           3 : bool SwTxtNode::GetExpandTxt( SwTxtNode& rDestNd, const SwIndex* pDestIdx,
    3154             :                         sal_Int32 nIdx, sal_Int32 nLen, bool bWithNum,
    3155             :                         bool bWithFtn, bool bReplaceTabsWithSpaces ) const
    3156             : {
    3157           3 :     if( &rDestNd == this )
    3158           0 :         return false;
    3159             : 
    3160           3 :     SwIndex aDestIdx(&rDestNd, rDestNd.GetTxt().getLength());
    3161           3 :     if( pDestIdx )
    3162           3 :         aDestIdx = *pDestIdx;
    3163           3 :     const sal_Int32 nDestStt = aDestIdx.GetIndex();
    3164             : 
    3165             :     // Text einfuegen
    3166           6 :     OUStringBuffer buf(GetTxt());
    3167           3 :     if( bReplaceTabsWithSpaces )
    3168           3 :         buf.replace('\t', ' ');
    3169             : 
    3170             :     // mask hidden characters
    3171           3 :     const sal_Unicode cChar = CH_TXTATR_BREAKWORD;
    3172           3 :     SwScriptInfo::MaskHiddenRanges(*this, buf, 0, buf.getLength(), cChar);
    3173             : 
    3174           3 :     buf.remove(0, nIdx);
    3175           3 :     if (nLen != -1)
    3176             :     {
    3177           0 :         buf.truncate(nLen);
    3178             :     }
    3179             :     // remove dummy characters of Input Fields
    3180             :     {
    3181           3 :         comphelper::string::remove(buf, CH_TXT_ATR_INPUTFIELDSTART);
    3182           3 :         comphelper::string::remove(buf, CH_TXT_ATR_INPUTFIELDEND);
    3183             :     }
    3184           3 :     rDestNd.InsertText(buf.makeStringAndClear(), aDestIdx);
    3185           3 :     nLen = aDestIdx.GetIndex() - nDestStt;
    3186             : 
    3187             :     // alle FontAttribute mit CHARSET Symbol in dem Bereich setzen
    3188           3 :     if ( HasHints() )
    3189             :     {
    3190           0 :         sal_Int32 nInsPos = nDestStt - nIdx;
    3191           0 :         for ( sal_uInt16 i = 0; i < m_pSwpHints->Count(); i++ )
    3192             :         {
    3193           0 :             const SwTxtAttr* pHt = (*m_pSwpHints)[i];
    3194           0 :             const sal_Int32 nAttrStartIdx = *pHt->GetStart();
    3195           0 :             const sal_uInt16 nWhich = pHt->Which();
    3196           0 :             if (nIdx + nLen <= nAttrStartIdx)
    3197           0 :                 break;      // ueber das Textende
    3198             : 
    3199           0 :             const sal_Int32 *pEndIdx = pHt->End();
    3200           0 :             if( pEndIdx && *pEndIdx > nIdx &&
    3201           0 :                 ( RES_CHRATR_FONT == nWhich ||
    3202           0 :                   RES_TXTATR_CHARFMT == nWhich ||
    3203             :                   RES_TXTATR_AUTOFMT == nWhich ))
    3204             :             {
    3205             :                 const SvxFontItem* const pFont =
    3206             :                     static_cast<const SvxFontItem*>(
    3207           0 :                         CharFmt::GetItem( *pHt, RES_CHRATR_FONT ));
    3208           0 :                 if ( pFont && RTL_TEXTENCODING_SYMBOL == pFont->GetCharSet() )
    3209             :                 {
    3210             :                     // attribute in area => copy
    3211             :                     rDestNd.InsertItem( *const_cast<SvxFontItem*>(pFont),
    3212           0 :                             nInsPos + nAttrStartIdx, nInsPos + *pEndIdx );
    3213           0 :                 }
    3214             :             }
    3215           0 :             else if ( pHt->HasDummyChar() && (nAttrStartIdx >= nIdx) )
    3216             :             {
    3217           0 :                 aDestIdx = nInsPos + nAttrStartIdx;
    3218           0 :                 switch( nWhich )
    3219             :                 {
    3220             :                 case RES_TXTATR_FIELD:
    3221             :                 case RES_TXTATR_ANNOTATION:
    3222             :                     {
    3223             :                         OUString const aExpand(
    3224           0 :                             static_cast<SwTxtFld const*>(pHt)->GetFmtFld().GetField()->ExpandField(true) );
    3225           0 :                         if (!aExpand.isEmpty())
    3226             :                         {
    3227           0 :                             ++aDestIdx;     // dahinter einfuegen;
    3228             :                             OUString const ins(
    3229           0 :                                 rDestNd.InsertText( aExpand, aDestIdx));
    3230             :                             SAL_INFO_IF(ins.getLength() != aExpand.getLength(),
    3231             :                                     "sw.core", "GetExpandTxt lossage");
    3232           0 :                             aDestIdx = nInsPos + nAttrStartIdx;
    3233           0 :                             nInsPos += ins.getLength();
    3234             :                         }
    3235           0 :                         rDestNd.EraseText( aDestIdx, 1 );
    3236           0 :                         --nInsPos;
    3237             :                     }
    3238           0 :                     break;
    3239             : 
    3240             :                 case RES_TXTATR_FTN:
    3241             :                     {
    3242           0 :                         if ( bWithFtn )
    3243             :                         {
    3244           0 :                             const SwFmtFtn& rFtn = pHt->GetFtn();
    3245           0 :                             OUString sExpand;
    3246           0 :                             if( !rFtn.GetNumStr().isEmpty() )
    3247           0 :                                 sExpand = rFtn.GetNumStr();
    3248           0 :                             else if( rFtn.IsEndNote() )
    3249           0 :                                 sExpand = GetDoc()->GetEndNoteInfo().aFmt.
    3250           0 :                                 GetNumStr( rFtn.GetNumber() );
    3251             :                             else
    3252           0 :                                 sExpand = GetDoc()->GetFtnInfo().aFmt.
    3253           0 :                                                 GetNumStr( rFtn.GetNumber() );
    3254           0 :                             if( !sExpand.isEmpty() )
    3255             :                             {
    3256           0 :                                 ++aDestIdx;     // insert behind
    3257             :                                 SvxEscapementItem aItem(
    3258           0 :                                         SVX_ESCAPEMENT_SUPERSCRIPT );
    3259             :                                 rDestNd.InsertItem(
    3260             :                                         aItem,
    3261             :                                         aDestIdx.GetIndex(),
    3262           0 :                                         aDestIdx.GetIndex() );
    3263           0 :                                 OUString const ins( rDestNd.InsertText(sExpand, aDestIdx, IDocumentContentOperations::INS_EMPTYEXPAND));
    3264             :                                 SAL_INFO_IF(ins.getLength() != sExpand.getLength(),
    3265             :                                         "sw.core", "GetExpandTxt lossage");
    3266           0 :                                 aDestIdx = nInsPos + nAttrStartIdx;
    3267           0 :                                 nInsPos += ins.getLength();
    3268           0 :                             }
    3269             :                         }
    3270           0 :                         rDestNd.EraseText( aDestIdx, 1 );
    3271           0 :                         --nInsPos;
    3272             :                     }
    3273           0 :                     break;
    3274             : 
    3275             :                 default:
    3276           0 :                     rDestNd.EraseText( aDestIdx, 1 );
    3277           0 :                     --nInsPos;
    3278             :                 }
    3279             :             }
    3280             :         }
    3281             :     }
    3282             : 
    3283           3 :     if( bWithNum )
    3284             :     {
    3285           0 :         aDestIdx = nDestStt;
    3286           0 :         rDestNd.InsertText( GetNumString(), aDestIdx );
    3287             :     }
    3288             : 
    3289           3 :     aDestIdx = 0;
    3290           3 :     sal_Int32 nStartDelete(-1);
    3291          43 :     while (aDestIdx < rDestNd.GetTxt().getLength())
    3292             :     {
    3293          37 :         sal_Unicode const cur(rDestNd.GetTxt()[aDestIdx.GetIndex()]);
    3294          37 :         if (   (cChar == cur) // filter substituted hidden text
    3295          37 :             || (CH_TXT_ATR_FIELDSTART  == cur) // filter all fieldmarks
    3296          37 :             || (CH_TXT_ATR_FIELDEND    == cur)
    3297          37 :             || (CH_TXT_ATR_FORMELEMENT == cur))
    3298             :         {
    3299           0 :             if (-1 == nStartDelete)
    3300             :             {
    3301           0 :                 nStartDelete = aDestIdx.GetIndex(); // start deletion range
    3302             :             }
    3303           0 :             ++aDestIdx;
    3304           0 :             if (aDestIdx < rDestNd.GetTxt().getLength())
    3305             :             {
    3306           0 :                 continue;
    3307             :             } // else: end of paragraph => delete, see below
    3308             :         }
    3309             :         else
    3310             :         {
    3311          37 :             if (-1 == nStartDelete)
    3312             :             {
    3313          37 :                 ++aDestIdx;
    3314          37 :                 continue;
    3315             :             } // else: delete, see below
    3316             :         }
    3317             :         assert(-1 != nStartDelete); // without delete range, would have contined
    3318             :         rDestNd.EraseText(
    3319             :             SwIndex(&rDestNd, nStartDelete),
    3320           0 :             aDestIdx.GetIndex() - nStartDelete);
    3321             :         assert(aDestIdx.GetIndex() == nStartDelete);
    3322           0 :         nStartDelete = -1; // reset
    3323             :     }
    3324             : 
    3325           6 :     return true;
    3326             : }
    3327             : 
    3328           0 : OUString SwTxtNode::GetRedlineTxt( sal_Int32 nIdx, sal_Int32 nLen,
    3329             :                                    bool bExpandFlds, bool bWithNum ) const
    3330             : {
    3331           0 :     std::vector<sal_Int32> aRedlArr;
    3332           0 :     const SwDoc* pDoc = GetDoc();
    3333           0 :     sal_uInt16 nRedlPos = pDoc->GetRedlinePos( *this, nsRedlineType_t::REDLINE_DELETE );
    3334           0 :     if( USHRT_MAX != nRedlPos )
    3335             :     {
    3336             :         // es existiert fuer den Node irgendein Redline-Delete-Object
    3337           0 :         const sal_uLong nNdIdx = GetIndex();
    3338           0 :         for( ; nRedlPos < pDoc->GetRedlineTbl().size() ; ++nRedlPos )
    3339             :         {
    3340           0 :             const SwRangeRedline* pTmp = pDoc->GetRedlineTbl()[ nRedlPos ];
    3341           0 :             if( nsRedlineType_t::REDLINE_DELETE == pTmp->GetType() )
    3342             :             {
    3343           0 :                 const SwPosition *pRStt = pTmp->Start(), *pREnd = pTmp->End();
    3344           0 :                 if( pRStt->nNode < nNdIdx )
    3345             :                 {
    3346           0 :                     if( pREnd->nNode > nNdIdx )
    3347             :                         // Absatz ist komplett geloescht
    3348           0 :                         return OUString();
    3349           0 :                     else if( pREnd->nNode == nNdIdx )
    3350             :                     {
    3351             :                         // von 0 bis nContent ist alles geloescht
    3352           0 :                         aRedlArr.push_back( 0 );
    3353           0 :                         aRedlArr.push_back( pREnd->nContent.GetIndex() );
    3354             :                     }
    3355             :                 }
    3356           0 :                 else if( pRStt->nNode == nNdIdx )
    3357             :                 {
    3358             :                     //aRedlArr.Insert( pRStt->nContent.GetIndex(), aRedlArr.Count() );
    3359           0 :                     aRedlArr.push_back( pRStt->nContent.GetIndex() );
    3360           0 :                     if( pREnd->nNode == nNdIdx )
    3361           0 :                         aRedlArr.push_back( pREnd->nContent.GetIndex() );
    3362             :                     else
    3363             :                     {
    3364           0 :                         aRedlArr.push_back(GetTxt().getLength());
    3365           0 :                         break;      // mehr kann nicht kommen
    3366             :                     }
    3367             :                 }
    3368             :                 else
    3369           0 :                     break;      // mehr kann nicht kommen
    3370             :             }
    3371             :         }
    3372             :     }
    3373             : 
    3374           0 :     OUStringBuffer aTxt((nLen > GetTxt().getLength())
    3375           0 :                 ? GetTxt().copy(nIdx)
    3376           0 :                 : GetTxt().copy(nIdx, nLen));
    3377             : 
    3378           0 :     sal_Int32 nTxtStt = nIdx;
    3379           0 :     sal_Int32 nIdxEnd = nIdx + aTxt.getLength();
    3380           0 :     for( size_t n = 0; n < aRedlArr.size(); n += 2 )
    3381             :     {
    3382           0 :         sal_Int32 nStt = aRedlArr[ n ];
    3383           0 :         sal_Int32 nEnd = aRedlArr[ n+1 ];
    3384           0 :         if( ( nIdx <= nStt && nStt <= nIdxEnd ) ||
    3385           0 :             ( nIdx <= nEnd && nEnd <= nIdxEnd ))
    3386             :         {
    3387           0 :             if( nStt < nIdx ) nStt = nIdx;
    3388           0 :             if( nIdxEnd < nEnd ) nEnd = nIdxEnd;
    3389           0 :             const sal_Int32 nDelCnt = nEnd - nStt;
    3390           0 :             aTxt.remove(nStt - nTxtStt, nDelCnt);
    3391           0 :             Replace0xFF(*this, aTxt, nTxtStt, nStt - nTxtStt, bExpandFlds);
    3392           0 :             nTxtStt += nDelCnt;
    3393             :         }
    3394           0 :         else if( nStt >= nIdxEnd )
    3395           0 :             break;
    3396             :     }
    3397           0 :     Replace0xFF(*this, aTxt, nTxtStt, aTxt.getLength(), bExpandFlds);
    3398             : 
    3399           0 :     if( bWithNum )
    3400           0 :         aTxt.insert(0, GetNumString());
    3401           0 :     return aTxt.makeStringAndClear();
    3402             : }
    3403             : 
    3404             : /*************************************************************************
    3405             :  *                        SwTxtNode::ReplaceText
    3406             :  *************************************************************************/
    3407             : 
    3408          47 : void SwTxtNode::ReplaceText( const SwIndex& rStart, const sal_Int32 nDelLen,
    3409             :                              const OUString & rStr)
    3410             : {
    3411             :     assert( rStart.GetIndex() < m_Text.getLength()     // index out of bounds
    3412             :          && rStart.GetIndex() + nDelLen <= m_Text.getLength());
    3413             : 
    3414          47 :     sal_Int32 const nOverflow(rStr.getLength() - nDelLen - GetSpaceLeft());
    3415             :     SAL_WARN_IF(nOverflow > 0, "sw.core",
    3416             :             "SwTxtNode::ReplaceText: node text with insertion > node capacity.");
    3417             :     OUString const sInserted(
    3418          47 :         (nOverflow > 0) ? rStr.copy(0, rStr.getLength() - nOverflow) : rStr);
    3419          47 :     if (sInserted.isEmpty() && 0 == nDelLen)
    3420             :     {
    3421          47 :         return; // nothing to do
    3422             :     }
    3423             : 
    3424          47 :     const sal_Int32 nStartPos = rStart.GetIndex();
    3425          47 :     sal_Int32 nEndPos = nStartPos + nDelLen;
    3426          47 :     sal_Int32 nLen = nDelLen;
    3427         473 :     for( sal_Int32 nPos = nStartPos; nPos < nEndPos; ++nPos )
    3428             :     {
    3429         852 :         if ((CH_TXTATR_BREAKWORD == m_Text[nPos]) ||
    3430         426 :             (CH_TXTATR_INWORD    == m_Text[nPos]))
    3431             :         {
    3432           0 :             SwTxtAttr *const pHint = GetTxtAttrForCharAt( nPos );
    3433           0 :             if (pHint)
    3434             :             {
    3435             :                assert(!( pHint->GetEnd() && pHint->HasDummyChar()
    3436             :                             && (*pHint->GetStart() < nEndPos)
    3437             :                             && (*pHint->GetEnd()   > nEndPos) ));
    3438             :                     // "deleting left-overlapped attribute with CH_TXTATR"
    3439           0 :                 DeleteAttribute( pHint );
    3440           0 :                 --nEndPos;
    3441           0 :                 --nLen;
    3442             :             }
    3443             :         }
    3444             :     }
    3445             : 
    3446          47 :     bool bOldExpFlg = IsIgnoreDontExpand();
    3447          47 :     SetIgnoreDontExpand( true );
    3448             : 
    3449          47 :     if (nLen && sInserted.getLength())
    3450             :     {
    3451             :         // dann das 1. Zeichen ersetzen den Rest loschen und einfuegen
    3452             :         // Dadurch wird die Attributierung des 1. Zeichen expandiert!
    3453          46 :         m_Text = m_Text.replaceAt(nStartPos, 1, sInserted.copy(0, 1));
    3454             : 
    3455          46 :         ++((SwIndex&)rStart);
    3456          46 :         m_Text = m_Text.replaceAt(rStart.GetIndex(), nLen - 1, "");
    3457          46 :         Update( rStart, nLen - 1, true );
    3458             : 
    3459          46 :         OUString aTmpTxt( sInserted.copy(1) );
    3460          46 :         m_Text = m_Text.replaceAt(rStart.GetIndex(), 0, aTmpTxt);
    3461          46 :         Update( rStart, aTmpTxt.getLength(), false );
    3462             :     }
    3463             :     else
    3464             :     {
    3465           1 :         m_Text = m_Text.replaceAt(nStartPos, nLen, "");
    3466           1 :         Update( rStart, nLen, true );
    3467             : 
    3468           1 :         m_Text = m_Text.replaceAt(nStartPos, 0, sInserted);
    3469           1 :         Update( rStart, sInserted.getLength(), false );
    3470             :     }
    3471             : 
    3472          47 :     SetIgnoreDontExpand( bOldExpFlg );
    3473          94 :     SwDelTxt aDelHint( nStartPos, nDelLen );
    3474          47 :     NotifyClients( 0, &aDelHint );
    3475             : 
    3476          94 :     SwInsTxt aHint( nStartPos, sInserted.getLength() );
    3477          94 :     NotifyClients( 0, &aHint );
    3478             : }
    3479             : 
    3480             : namespace {
    3481         145 :     static void lcl_ResetParAttrs( SwTxtNode &rTxtNode )
    3482             :     {
    3483         145 :         std::set<sal_uInt16> aAttrs;
    3484         145 :         aAttrs.insert( aAttrs.end(), RES_PARATR_LIST_ID );
    3485         145 :         aAttrs.insert( aAttrs.end(), RES_PARATR_LIST_LEVEL );
    3486         145 :         aAttrs.insert( aAttrs.end(), RES_PARATR_LIST_ISRESTART );
    3487         145 :         aAttrs.insert( aAttrs.end(), RES_PARATR_LIST_RESTARTVALUE );
    3488         145 :         aAttrs.insert( aAttrs.end(), RES_PARATR_LIST_ISCOUNTED );
    3489         290 :         SwPaM aPam( rTxtNode );
    3490             :         // #i96644#
    3491             :         // suppress side effect "send data changed events"
    3492         290 :         rTxtNode.GetDoc()->ResetAttrs( aPam, false, aAttrs, false );
    3493         145 :     }
    3494             : 
    3495             :     // Helper method for special handling of modified attributes at text node.
    3496             :     // The following is handled:
    3497             :     // (1) on changing the paragraph style - RES_FMT_CHG:
    3498             :     // Check, if list style of the text node is changed. If yes, add respectively
    3499             :     // remove the text node to the corresponding list.
    3500             :     // (2) on changing the attributes - RES_ATTRSET_CHG:
    3501             :     // Same as (1).
    3502             :     // (3) on changing the list style - RES_PARATR_NUMRULE:
    3503             :     // Same as (1).
    3504      215574 :     void HandleModifyAtTxtNode( SwTxtNode& rTxtNode,
    3505             :                                 const SfxPoolItem* pOldValue,
    3506             :                                 const SfxPoolItem* pNewValue )
    3507             :     {
    3508             :         const sal_uInt16 nWhich = pOldValue ? pOldValue->Which() :
    3509      215574 :                               pNewValue ? pNewValue->Which() : 0 ;
    3510      215574 :         bool bNumRuleSet = false;
    3511      215574 :         bool bParagraphStyleChanged = false;
    3512      215574 :         OUString sNumRule;
    3513      431148 :         OUString sOldNumRule;
    3514      215574 :         switch ( nWhich )
    3515             :         {
    3516             :             case RES_FMT_CHG:
    3517             :             {
    3518       13306 :                 bParagraphStyleChanged = true;
    3519       13306 :                 if( rTxtNode.GetNodes().IsDocNodes() )
    3520             :                 {
    3521             :                     const SwNumRule* pFormerNumRuleAtTxtNode =
    3522       10353 :                         rTxtNode.GetNum() ? rTxtNode.GetNum()->GetNumRule() : 0;
    3523       10353 :                     if ( pFormerNumRuleAtTxtNode )
    3524             :                     {
    3525         214 :                         sOldNumRule = pFormerNumRuleAtTxtNode->GetName();
    3526             :                     }
    3527       10353 :                     if ( rTxtNode.IsEmptyListStyleDueToSetOutlineLevelAttr() )
    3528             :                     {
    3529           0 :                         const SwNumRuleItem& rNumRuleItem = rTxtNode.GetTxtColl()->GetNumRule();
    3530           0 :                         if ( !rNumRuleItem.GetValue().isEmpty() )
    3531             :                         {
    3532           0 :                             rTxtNode.ResetEmptyListStyleDueToResetOutlineLevelAttr();
    3533             :                         }
    3534             :                     }
    3535       10353 :                     const SwNumRule* pNumRuleAtTxtNode = rTxtNode.GetNumRule();
    3536       10353 :                     if ( pNumRuleAtTxtNode )
    3537             :                     {
    3538         209 :                         bNumRuleSet = true;
    3539         209 :                         sNumRule = pNumRuleAtTxtNode->GetName();
    3540             :                     }
    3541             :                 }
    3542       13306 :                 break;
    3543             :             }
    3544             :             case RES_ATTRSET_CHG:
    3545             :             {
    3546      145424 :                 const SfxPoolItem* pItem = 0;
    3547             :                 const SwNumRule* pFormerNumRuleAtTxtNode =
    3548      145424 :                     rTxtNode.GetNum() ? rTxtNode.GetNum()->GetNumRule() : 0;
    3549      145424 :                 if ( pFormerNumRuleAtTxtNode )
    3550             :                 {
    3551        4974 :                     sOldNumRule = pFormerNumRuleAtTxtNode->GetName();
    3552             :                 }
    3553             : 
    3554      145424 :                 if ( dynamic_cast<const SwAttrSetChg*>(pNewValue)->GetChgSet()->GetItemState( RES_PARATR_NUMRULE, false, &pItem ) ==
    3555             :                         SFX_ITEM_SET )
    3556             :                 {
    3557             :                     // #i70748#
    3558         149 :                     rTxtNode.ResetEmptyListStyleDueToResetOutlineLevelAttr();
    3559         149 :                     bNumRuleSet = true;
    3560             :                 }
    3561             :                 // #i70748#
    3562             :                 // The new list style set at the paragraph.
    3563      145424 :                 const SwNumRule* pNumRuleAtTxtNode = rTxtNode.GetNumRule();
    3564      145424 :                 if ( pNumRuleAtTxtNode )
    3565             :                 {
    3566        5121 :                     sNumRule = pNumRuleAtTxtNode->GetName();
    3567             :                 }
    3568      145424 :                 break;
    3569             :             }
    3570             :             case RES_PARATR_NUMRULE:
    3571             :             {
    3572           0 :                 if ( rTxtNode.GetNodes().IsDocNodes() )
    3573             :                 {
    3574             :                     const SwNumRule* pFormerNumRuleAtTxtNode =
    3575           0 :                         rTxtNode.GetNum() ? rTxtNode.GetNum()->GetNumRule() : 0;
    3576           0 :                     if ( pFormerNumRuleAtTxtNode )
    3577             :                     {
    3578           0 :                         sOldNumRule = pFormerNumRuleAtTxtNode->GetName();
    3579             :                     }
    3580             : 
    3581           0 :                     if ( pNewValue )
    3582             :                     {
    3583             :                         // #i70748#
    3584           0 :                         rTxtNode.ResetEmptyListStyleDueToResetOutlineLevelAttr();
    3585           0 :                         bNumRuleSet = true;
    3586             :                     }
    3587             :                     // #i70748#
    3588             :                     // The new list style set at the paragraph.
    3589           0 :                     const SwNumRule* pNumRuleAtTxtNode = rTxtNode.GetNumRule();
    3590           0 :                     if ( pNumRuleAtTxtNode )
    3591             :                     {
    3592           0 :                         sNumRule = pNumRuleAtTxtNode->GetName();
    3593             :                     }
    3594             :                 }
    3595           0 :                 break;
    3596             :             }
    3597             :         }
    3598      215574 :         if ( sNumRule != sOldNumRule )
    3599             :         {
    3600         432 :             if ( bNumRuleSet )
    3601             :             {
    3602         285 :                 if (sNumRule.isEmpty())
    3603             :                 {
    3604           0 :                     rTxtNode.RemoveFromList();
    3605           0 :                     if ( bParagraphStyleChanged )
    3606             :                     {
    3607           0 :                         lcl_ResetParAttrs(rTxtNode);
    3608             :                     }
    3609             :                 }
    3610             :                 else
    3611             :                 {
    3612         285 :                     rTxtNode.RemoveFromList();
    3613             :                     // If new list style is the outline style, apply outline
    3614             :                     // level as the list level.
    3615         285 :                     if (sNumRule==SwNumRule::GetOutlineRuleName())
    3616             :                     {
    3617             :                         // #i70748#
    3618             :                         OSL_ENSURE( rTxtNode.GetTxtColl()->IsAssignedToListLevelOfOutlineStyle(),
    3619             :                                 "<HandleModifyAtTxtNode()> - text node with outline style, but its paragraph style is not assigned to outline style." );
    3620             :                         const int nNewListLevel =
    3621         182 :                             rTxtNode.GetTxtColl()->GetAssignedOutlineStyleLevel();
    3622         182 :                         if ( 0 <= nNewListLevel && nNewListLevel < MAXLEVEL )
    3623             :                         {
    3624         181 :                             rTxtNode.SetAttrListLevel( nNewListLevel );
    3625             :                         }
    3626             :                     }
    3627         285 :                     rTxtNode.AddToList();
    3628             :                 }
    3629             :             }
    3630             :             else // <sNumRule.Len() == 0 && sOldNumRule.Len() != 0>
    3631             :             {
    3632         147 :                 rTxtNode.RemoveFromList();
    3633         147 :                 if ( bParagraphStyleChanged )
    3634             :                 {
    3635         145 :                     lcl_ResetParAttrs(rTxtNode);
    3636             :                     // #i70748#
    3637         145 :                     if ( dynamic_cast<const SfxUInt16Item &>(rTxtNode.GetAttr( RES_PARATR_OUTLINELEVEL, sal_False )).GetValue() > 0 )
    3638             :                     {
    3639           0 :                         rTxtNode.SetEmptyListStyleDueToSetOutlineLevelAttr();
    3640             :                     }
    3641             :                 }
    3642             :             }
    3643             :         }
    3644      215142 :         else if (!sNumRule.isEmpty() && !rTxtNode.IsInList())
    3645             :         {
    3646           0 :             rTxtNode.AddToList();
    3647      215574 :         }
    3648      215574 :     }
    3649             :     // End of method <HandleModifyAtTxtNode>
    3650             : }
    3651             : 
    3652      248163 : void SwTxtNode::Modify( const SfxPoolItem* pOldValue, const SfxPoolItem* pNewValue )
    3653             : {
    3654      248163 :     bool bWasNotifiable = m_bNotifiable;
    3655      248163 :     m_bNotifiable = false;
    3656             : 
    3657             :     // Bug 24616/24617:
    3658             :     //      Modify ueberladen, damit beim Loeschen von Vorlagen diese
    3659             :     //      wieder richtig verwaltet werden (Outline-Numerierung!!)
    3660             :     //  Bug25481:
    3661             :     //      bei Nodes im Undo nie _ChgTxtCollUpdateNum rufen.
    3662      449322 :     if( pOldValue && pNewValue && RES_FMT_CHG == pOldValue->Which() &&
    3663      254254 :         GetRegisteredIn() == ((SwFmtChg*)pNewValue)->pChangedFmt &&
    3664          54 :         GetNodes().IsDocNodes() )
    3665             :     {
    3666             :         _ChgTxtCollUpdateNum(
    3667             :                         (SwTxtFmtColl*)((SwFmtChg*)pOldValue)->pChangedFmt,
    3668          54 :                         (SwTxtFmtColl*)((SwFmtChg*)pNewValue)->pChangedFmt );
    3669             :     }
    3670             : 
    3671      248163 :     if ( !mbInSetOrResetAttr )
    3672             :     {
    3673      208305 :         HandleModifyAtTxtNode( *this, pOldValue, pNewValue );
    3674             :     }
    3675             : 
    3676      248163 :     SwCntntNode::Modify( pOldValue, pNewValue );
    3677             : 
    3678      248163 :     SwDoc * pDoc = GetDoc();
    3679             :     // #125329# - assure that text node is in document nodes array
    3680      248163 :     if ( pDoc && !pDoc->IsInDtor() && &pDoc->GetNodes() == &GetNodes() )
    3681             :     {
    3682      210520 :         pDoc->GetNodes().UpdateOutlineNode(*this);
    3683             :     }
    3684             : 
    3685      248163 :     m_bNotifiable = bWasNotifiable;
    3686             : 
    3687      248163 :     if (pOldValue && (RES_REMOVE_UNO_OBJECT == pOldValue->Which()))
    3688             :     {   // invalidate cached uno object
    3689             :         SetXParagraph(::com::sun::star::uno::Reference<
    3690           0 :                 ::com::sun::star::text::XTextContent>(0));
    3691             :     }
    3692      248163 : }
    3693             : 
    3694       30304 : SwFmtColl* SwTxtNode::ChgFmtColl( SwFmtColl *pNewColl )
    3695             : {
    3696             :     OSL_ENSURE( pNewColl,"ChgFmtColl: Collectionpointer has value 0." );
    3697             :     OSL_ENSURE( HAS_BASE( SwTxtFmtColl, pNewColl ),
    3698             :                 "ChgFmtColl: is not a Text Collection pointer." );
    3699             : 
    3700       30304 :     SwTxtFmtColl *pOldColl = GetTxtColl();
    3701       30304 :     if( pNewColl != pOldColl )
    3702             :     {
    3703        7269 :         SetCalcHiddenCharFlags();
    3704        7269 :         SwCntntNode::ChgFmtColl( pNewColl );
    3705             :         OSL_ENSURE( !mbInSetOrResetAttr,
    3706             :                 "DEBUG OSL_ENSURE(ON - <SwTxtNode::ChgFmtColl(..)> called during <Set/ResetAttr(..)>" );
    3707        7269 :         if ( !mbInSetOrResetAttr )
    3708             :         {
    3709        7269 :             SwFmtChg aTmp1( pOldColl );
    3710       14538 :             SwFmtChg aTmp2( pNewColl );
    3711       14538 :             HandleModifyAtTxtNode( *this, &aTmp1, &aTmp2  );
    3712             :         }
    3713             :     }
    3714             : 
    3715             :     // nur wenn im normalen Nodes-Array
    3716       30304 :     if( GetNodes().IsDocNodes() )
    3717             :     {
    3718       30304 :         _ChgTxtCollUpdateNum( pOldColl, static_cast<SwTxtFmtColl *>(pNewColl) );
    3719             :     }
    3720             : 
    3721       30304 :     GetNodes().UpdateOutlineNode(*this);
    3722             : 
    3723       30304 :     return pOldColl;
    3724             : }
    3725             : 
    3726        3514 : SwNodeNum* SwTxtNode::CreateNum() const
    3727             : {
    3728        3514 :     if ( !mpNodeNum )
    3729             :     {
    3730        3514 :         mpNodeNum = new SwNodeNum( const_cast<SwTxtNode*>(this) );
    3731             :     }
    3732        3514 :     return mpNodeNum;
    3733             : }
    3734             : 
    3735           0 : SwNumberTree::tNumberVector SwTxtNode::GetNumberVector() const
    3736             : {
    3737           0 :     if ( GetNum() )
    3738             :     {
    3739           0 :         return GetNum()->GetNumberVector();
    3740             :     }
    3741             :     else
    3742             :     {
    3743           0 :         SwNumberTree::tNumberVector aResult;
    3744           0 :         return aResult;
    3745             :     }
    3746             : }
    3747             : 
    3748      351771 : bool SwTxtNode::IsOutline() const
    3749             : {
    3750      351771 :     bool bResult = false;
    3751             : 
    3752      351771 :     if ( GetAttrOutlineLevel() > 0 )
    3753             :     {
    3754       10067 :         bResult = !IsInRedlines();
    3755             :     }
    3756             :     else
    3757             :     {
    3758      341704 :         const SwNumRule* pRule( GetNum() ? GetNum()->GetNumRule() : 0L );
    3759      341704 :         if ( pRule && pRule->IsOutlineRule() )
    3760             :         {
    3761           8 :             bResult = !IsInRedlines();
    3762             :         }
    3763             :     }
    3764             : 
    3765      351771 :     return bResult;
    3766             : }
    3767             : 
    3768      340238 : bool SwTxtNode::IsOutlineStateChanged() const
    3769             : {
    3770      340238 :     return IsOutline() != m_bLastOutlineState;
    3771             : }
    3772             : 
    3773        1307 : void SwTxtNode::UpdateOutlineState()
    3774             : {
    3775        1307 :     m_bLastOutlineState = IsOutline();
    3776        1307 : }
    3777             : 
    3778      364782 : int SwTxtNode::GetAttrOutlineLevel() const
    3779             : {
    3780      364782 :     return ((const SfxUInt16Item &)GetAttr(RES_PARATR_OUTLINELEVEL)).GetValue();
    3781             : }
    3782             : 
    3783           0 : void SwTxtNode::SetAttrOutlineLevel(int nLevel)
    3784             : {
    3785             :     assert(0 <= nLevel && nLevel <= MAXLEVEL); // Level Out Of Range
    3786           0 :     if ( 0 <= nLevel && nLevel <= MAXLEVEL )
    3787             :     {
    3788             :         SetAttr( SfxUInt16Item( RES_PARATR_OUTLINELEVEL,
    3789           0 :                                 static_cast<sal_uInt16>(nLevel) ) );
    3790             :     }
    3791           0 : }
    3792             : 
    3793             : // #i70748#
    3794       10353 : bool SwTxtNode::IsEmptyListStyleDueToSetOutlineLevelAttr()
    3795             : {
    3796       10353 :     return mbEmptyListStyleSetDueToSetOutlineLevelAttr;
    3797             : }
    3798             : 
    3799          27 : void SwTxtNode::SetEmptyListStyleDueToSetOutlineLevelAttr()
    3800             : {
    3801          27 :     if ( !mbEmptyListStyleSetDueToSetOutlineLevelAttr )
    3802             :     {
    3803          21 :         SetAttr( SwNumRuleItem() );
    3804          21 :         mbEmptyListStyleSetDueToSetOutlineLevelAttr = true;
    3805             :     }
    3806          27 : }
    3807             : 
    3808        6614 : void SwTxtNode::ResetEmptyListStyleDueToResetOutlineLevelAttr()
    3809             : {
    3810        6614 :     if ( mbEmptyListStyleSetDueToSetOutlineLevelAttr )
    3811             :     {
    3812           6 :         ResetAttr( RES_PARATR_NUMRULE );
    3813           6 :         mbEmptyListStyleSetDueToSetOutlineLevelAttr = false;
    3814             :     }
    3815        6614 : }
    3816             : 
    3817        2956 : void SwTxtNode::SetAttrListLevel( int nLevel )
    3818             : {
    3819        2956 :     if ( nLevel < 0 || nLevel >= MAXLEVEL )
    3820             :     {
    3821             :         assert(false); // invalid level
    3822        2956 :         return;
    3823             :     }
    3824             : 
    3825             :     SfxInt16Item aNewListLevelItem( RES_PARATR_LIST_LEVEL,
    3826        2956 :                                     static_cast<sal_Int16>(nLevel) );
    3827        2956 :     SetAttr( aNewListLevelItem );
    3828             : }
    3829             : 
    3830       28018 : bool SwTxtNode::HasAttrListLevel() const
    3831             : {
    3832       31103 :     return GetpSwAttrSet() &&
    3833       31103 :            GetpSwAttrSet()->GetItemState( RES_PARATR_LIST_LEVEL, false ) == SFX_ITEM_SET;
    3834             : }
    3835             : 
    3836        9855 : int SwTxtNode::GetAttrListLevel() const
    3837             : {
    3838        9855 :     int nAttrListLevel = 0;
    3839             : 
    3840             :     const SfxInt16Item& aListLevelItem =
    3841        9855 :         dynamic_cast<const SfxInt16Item&>(GetAttr( RES_PARATR_LIST_LEVEL ));
    3842        9855 :     nAttrListLevel = static_cast<int>(aListLevelItem.GetValue());
    3843             : 
    3844        9855 :     return nAttrListLevel;
    3845             : }
    3846             : 
    3847       81084 : int SwTxtNode::GetActualListLevel() const
    3848             : {
    3849       81084 :     return GetNum() ? GetNum()->GetLevelInListTree() : -1;
    3850             : }
    3851             : 
    3852           6 : void SwTxtNode::SetListRestart( bool bRestart )
    3853             : {
    3854           6 :     if ( !bRestart )
    3855             :     {
    3856             :         // attribute not contained in paragraph style's attribute set. Thus,
    3857             :         // it can be reset to the attribute pool default by resetting the attribute.
    3858           0 :         ResetAttr( RES_PARATR_LIST_ISRESTART );
    3859             :     }
    3860             :     else
    3861             :     {
    3862             :         SfxBoolItem aNewIsRestartItem( RES_PARATR_LIST_ISRESTART,
    3863           6 :                                        true );
    3864           6 :         SetAttr( aNewIsRestartItem );
    3865             :     }
    3866           6 : }
    3867             : 
    3868       27934 : bool SwTxtNode::IsListRestart() const
    3869             : {
    3870             :     const SfxBoolItem& aIsRestartItem =
    3871       27934 :         dynamic_cast<const SfxBoolItem&>(GetAttr( RES_PARATR_LIST_ISRESTART ));
    3872             : 
    3873       27934 :     return aIsRestartItem.GetValue() ? true : false;
    3874             : }
    3875             : 
    3876             : /** Returns if the paragraph has a visible numbering or bullet.
    3877             :     This includes all kinds of numbering/bullet/outlines.
    3878             :     The concrete list label string has to be checked, too.
    3879             :  */
    3880        8257 : bool SwTxtNode::HasVisibleNumberingOrBullet() const
    3881             : {
    3882        8257 :     const SwNumRule* pRule = GetNum() ? GetNum()->GetNumRule() : 0L;
    3883        8257 :     if ( pRule && IsCountedInList())
    3884             :     {
    3885        8200 :         int nLevel = GetActualListLevel();
    3886             : 
    3887        8200 :         if (nLevel < 0)
    3888           0 :             nLevel = 0;
    3889             : 
    3890        8200 :         if (nLevel >= MAXLEVEL)
    3891           0 :             nLevel = MAXLEVEL - 1;
    3892             : 
    3893             :         // #i87154#
    3894             :         // Correction of #newlistlevelattrs#:
    3895             :         // The numbering type has to be checked for bullet lists.
    3896        8200 :         const SwNumFmt& rFmt = pRule->Get( static_cast<sal_uInt16>(nLevel ));
    3897        8512 :         return SVX_NUM_NUMBER_NONE != rFmt.GetNumberingType() ||
    3898        8512 :                !pRule->MakeNumString( *(GetNum()) ).isEmpty();
    3899             :     }
    3900             : 
    3901          57 :     return false;
    3902             : }
    3903             : 
    3904           7 : void SwTxtNode::SetAttrListRestartValue( SwNumberTree::tSwNumTreeNumber nNumber )
    3905             : {
    3906           7 :     const bool bChanged( HasAttrListRestartValue()
    3907           0 :                          ? GetAttrListRestartValue() != nNumber
    3908           7 :                          : nNumber != USHRT_MAX );
    3909             : 
    3910           7 :     if ( bChanged || !HasAttrListRestartValue() )
    3911             :     {
    3912           7 :         if ( nNumber == USHRT_MAX )
    3913             :         {
    3914           0 :             ResetAttr( RES_PARATR_LIST_RESTARTVALUE );
    3915             :         }
    3916             :         else
    3917             :         {
    3918             :             SfxInt16Item aNewListRestartValueItem( RES_PARATR_LIST_RESTARTVALUE,
    3919           7 :                                                    static_cast<sal_Int16>(nNumber) );
    3920           7 :             SetAttr( aNewListRestartValueItem );
    3921             :         }
    3922             :     }
    3923           7 : }
    3924             : 
    3925       26264 : bool SwTxtNode::HasAttrListRestartValue() const
    3926             : {
    3927       28184 :     return GetpSwAttrSet() &&
    3928       28184 :            GetpSwAttrSet()->GetItemState( RES_PARATR_LIST_RESTARTVALUE, false ) == SFX_ITEM_SET;
    3929             : }
    3930          11 : SwNumberTree::tSwNumTreeNumber SwTxtNode::GetAttrListRestartValue() const
    3931             : {
    3932             :     OSL_ENSURE( HasAttrListRestartValue(),
    3933             :             "<SwTxtNode::GetAttrListRestartValue()> - only ask for list restart value, if attribute is set at text node." );
    3934             : 
    3935             :     const SfxInt16Item& aListRestartValueItem =
    3936          11 :         dynamic_cast<const SfxInt16Item&>(GetAttr( RES_PARATR_LIST_RESTARTVALUE ));
    3937          11 :     return static_cast<SwNumberTree::tSwNumTreeNumber>(aListRestartValueItem.GetValue());
    3938             : }
    3939             : 
    3940          13 : SwNumberTree::tSwNumTreeNumber SwTxtNode::GetActualListStartValue() const
    3941             : {
    3942          13 :     SwNumberTree::tSwNumTreeNumber nListRestartValue = 1;
    3943             : 
    3944          13 :     if ( IsListRestart() && HasAttrListRestartValue() )
    3945             :     {
    3946          11 :         nListRestartValue = GetAttrListRestartValue();
    3947             :     }
    3948             :     else
    3949             :     {
    3950           2 :         SwNumRule* pRule = GetNumRule();
    3951           2 :         if ( pRule )
    3952             :         {
    3953             :             const SwNumFmt* pFmt =
    3954           2 :                     pRule->GetNumFmt( static_cast<sal_uInt16>(GetAttrListLevel()) );
    3955           2 :             if ( pFmt )
    3956             :             {
    3957           2 :                 nListRestartValue = pFmt->GetStart();
    3958             :             }
    3959             :         }
    3960             :     }
    3961             : 
    3962          13 :     return nListRestartValue;
    3963             : }
    3964             : 
    3965       57390 : bool SwTxtNode::IsNotifiable() const
    3966             : {
    3967       57390 :     return m_bNotifiable && IsNotificationEnabled();
    3968             : }
    3969             : 
    3970       61819 : bool SwTxtNode::IsNotificationEnabled() const
    3971             : {
    3972       61819 :     bool bResult = false;
    3973       61819 :     const SwDoc * pDoc = GetDoc();
    3974       61819 :     if( pDoc )
    3975             :     {
    3976       61819 :         bResult = pDoc->IsInReading() || pDoc->IsInDtor() ? false : true;
    3977             :     }
    3978       61819 :     return bResult;
    3979             : }
    3980             : 
    3981         518 : void SwTxtNode::SetCountedInList( bool bCounted )
    3982             : {
    3983         518 :     if ( bCounted )
    3984             :     {
    3985             :         // attribute not contained in paragraph style's attribute set. Thus,
    3986             :         // it can be reset to the attribute pool default by resetting the attribute.
    3987         515 :         ResetAttr( RES_PARATR_LIST_ISCOUNTED );
    3988             :     }
    3989             :     else
    3990             :     {
    3991           3 :         SfxBoolItem aIsCountedInListItem( RES_PARATR_LIST_ISCOUNTED, false );
    3992           3 :         SetAttr( aIsCountedInListItem );
    3993             :     }
    3994         518 : }
    3995             : 
    3996       64010 : bool SwTxtNode::IsCountedInList() const
    3997             : {
    3998             :     const SfxBoolItem& aIsCountedInListItem =
    3999       64010 :         dynamic_cast<const SfxBoolItem&>(GetAttr( RES_PARATR_LIST_ISCOUNTED ));
    4000             : 
    4001       64010 :     return aIsCountedInListItem.GetValue() ? true : false;
    4002             : }
    4003             : 
    4004        3708 : void SwTxtNode::AddToList()
    4005             : {
    4006        3708 :     if ( IsInList() )
    4007             :     {
    4008             :         OSL_FAIL( "<SwTxtNode::AddToList()> - the text node is already added to a list. Serious defect -> please inform OD" );
    4009        3708 :         return;
    4010             :     }
    4011             : 
    4012        3708 :     const OUString sListId = GetListId();
    4013        3708 :     if (!sListId.isEmpty())
    4014             :     {
    4015        3514 :         SwList* pList = GetDoc()->getListByName( sListId );
    4016        3514 :         if ( pList == 0 )
    4017             :         {
    4018             :             // Create corresponding list.
    4019           3 :             SwNumRule* pNumRule = GetNumRule();
    4020           3 :             if ( pNumRule )
    4021             :             {
    4022           3 :                 pList = GetDoc()->createList( sListId, GetNumRule()->GetName() );
    4023             :             }
    4024             :         }
    4025             :         OSL_ENSURE( pList != 0,
    4026             :                 "<SwTxtNode::AddToList()> - no list for given list id. Serious defect -> please inform OD" );
    4027        3514 :         if ( pList )
    4028             :         {
    4029        3514 :             pList->InsertListItem( *CreateNum(), GetAttrListLevel() );
    4030        3514 :             mpList = pList;
    4031             :         }
    4032        3708 :     }
    4033             : }
    4034             : 
    4035       78701 : void SwTxtNode::RemoveFromList()
    4036             : {
    4037       78701 :     if ( IsInList() )
    4038             :     {
    4039        3513 :         mpList->RemoveListItem( *mpNodeNum );
    4040        3513 :         mpList = 0;
    4041        3513 :         delete mpNodeNum;
    4042        3513 :         mpNodeNum = 0L;
    4043             : 
    4044        3513 :         SetWordCountDirty( true );
    4045             :     }
    4046       78701 : }
    4047             : 
    4048      340992 : bool SwTxtNode::IsInList() const
    4049             : {
    4050      340992 :     return GetNum() != 0 && GetNum()->GetParent() != 0;
    4051             : }
    4052             : 
    4053           0 : bool SwTxtNode::IsFirstOfNumRule() const
    4054             : {
    4055           0 :     bool bResult = false;
    4056             : 
    4057           0 :     if ( GetNum() && GetNum()->GetNumRule())
    4058           0 :         bResult = GetNum()->IsFirst();
    4059             : 
    4060           0 :     return bResult;
    4061             : }
    4062             : 
    4063          93 : void SwTxtNode::SetListId(OUString const& rListId)
    4064             : {
    4065             :     const SfxStringItem& rListIdItem =
    4066          93 :             dynamic_cast<const SfxStringItem&>(GetAttr( RES_PARATR_LIST_ID ));
    4067          93 :     if (rListIdItem.GetValue() != rListId)
    4068             :     {
    4069          93 :         if (rListId.isEmpty())
    4070             :         {
    4071           0 :             ResetAttr( RES_PARATR_LIST_ID );
    4072             :         }
    4073             :         else
    4074             :         {
    4075          93 :             SfxStringItem aNewListIdItem(RES_PARATR_LIST_ID, rListId);
    4076          93 :             SetAttr( aNewListIdItem );
    4077             :         }
    4078             :     }
    4079          93 : }
    4080             : 
    4081        6782 : OUString SwTxtNode::GetListId() const
    4082             : {
    4083        6782 :     OUString sListId;
    4084             : 
    4085             :     const SfxStringItem& rListIdItem =
    4086        6782 :                 dynamic_cast<const SfxStringItem&>(GetAttr( RES_PARATR_LIST_ID ));
    4087        6782 :     sListId = rListIdItem.GetValue();
    4088             : 
    4089             :     // As long as no explicit list id attribute is set, use the list id of
    4090             :     // the list, which has been created for the applied list style.
    4091        6782 :     if (sListId.isEmpty())
    4092             :     {
    4093        6455 :         SwNumRule* pRule = GetNumRule();
    4094        6455 :         if ( pRule )
    4095             :         {
    4096        6259 :             sListId = pRule->GetDefaultListId();
    4097             :         }
    4098             :     }
    4099             : 
    4100        6782 :     return sListId;
    4101             : }
    4102             : 
    4103             : /** Determines, if the list level indent attributes can be applied to the
    4104             :     paragraph.
    4105             : 
    4106             :     The list level indents can be applied to the paragraph under the one
    4107             :     of following conditions:
    4108             :     - the list style is directly applied to the paragraph and the paragraph
    4109             :       has no own indent attributes.
    4110             :     - the list style is applied to the paragraph through one of its paragraph
    4111             :       styles, the paragraph has no own indent attributes and on the paragraph
    4112             :       style hierarchy from the paragraph to the paragraph style with the
    4113             :       list style no indent attributes are found.
    4114             : 
    4115             :     @return boolean
    4116             : */
    4117       61884 : bool SwTxtNode::AreListLevelIndentsApplicable() const
    4118             : {
    4119       61884 :     bool bAreListLevelIndentsApplicable( true );
    4120             : 
    4121       61884 :     if ( !GetNum() || !GetNum()->GetNumRule() )
    4122             :     {
    4123             :         // no list style applied to paragraph
    4124       26479 :         bAreListLevelIndentsApplicable = false;
    4125             :     }
    4126       70810 :     else if ( HasSwAttrSet() &&
    4127       35405 :               GetpSwAttrSet()->GetItemState( RES_LR_SPACE, false ) == SFX_ITEM_SET )
    4128             :     {
    4129             :         // paragraph has hard-set indent attributes
    4130        8626 :         bAreListLevelIndentsApplicable = false;
    4131             :     }
    4132       53558 :     else if ( HasSwAttrSet() &&
    4133       26779 :               GetpSwAttrSet()->GetItemState( RES_PARATR_NUMRULE, false ) == SFX_ITEM_SET )
    4134             :     {
    4135             :         // list style is directly applied to paragraph and paragraph has no
    4136             :         // hard-set indent attributes
    4137       25531 :         bAreListLevelIndentsApplicable = true;
    4138             :     }
    4139             :     else
    4140             :     {
    4141             :         // list style is applied through one of the paragraph styles and
    4142             :         // paragraph has no hard-set indent attributes
    4143             : 
    4144             :         // check, paragraph's
    4145        1248 :         const SwTxtFmtColl* pColl = GetTxtColl();
    4146        2496 :         while ( pColl )
    4147             :         {
    4148        1248 :             if ( pColl->GetAttrSet().GetItemState( RES_LR_SPACE, false ) == SFX_ITEM_SET )
    4149             :             {
    4150             :                 // indent attributes found in the paragraph style hierarchy.
    4151          78 :                 bAreListLevelIndentsApplicable = false;
    4152          78 :                 break;
    4153             :             }
    4154             : 
    4155        1170 :             if ( pColl->GetAttrSet().GetItemState( RES_PARATR_NUMRULE, false ) == SFX_ITEM_SET )
    4156             :             {
    4157             :                 // paragraph style with the list style found and until now no
    4158             :                 // indent attributes are found in the paragraph style hierarchy.
    4159        1170 :                 bAreListLevelIndentsApplicable = true;
    4160        1170 :                 break;
    4161             :             }
    4162             : 
    4163           0 :             pColl = dynamic_cast<const SwTxtFmtColl*>(pColl->DerivedFrom());
    4164             :             OSL_ENSURE( pColl,
    4165             :                     "<SwTxtNode::AreListLevelIndentsApplicable()> - something wrong in paragraph's style hierarchy. The applied list style is not found." );
    4166             :         }
    4167             :     }
    4168             : 
    4169       61884 :     return bAreListLevelIndentsApplicable;
    4170             : }
    4171             : 
    4172             : /** Retrieves the list tab stop position, if the paragraph's list level defines
    4173             :     one and this list tab stop has to merged into the tap stops of the paragraph
    4174             : 
    4175             :     @param nListTabStopPosition
    4176             :     output parameter - containing the list tab stop position
    4177             : 
    4178             :     @return boolean - indicating, if a list tab stop position is provided
    4179             : */
    4180      112428 : bool SwTxtNode::GetListTabStopPosition( long& nListTabStopPosition ) const
    4181             : {
    4182      112428 :     bool bListTanStopPositionProvided( false );
    4183             : 
    4184      112428 :     const SwNumRule* pNumRule = GetNum() ? GetNum()->GetNumRule() : 0;
    4185      112428 :     if ( pNumRule && HasVisibleNumberingOrBullet() && GetActualListLevel() >= 0 )
    4186             :     {
    4187        4860 :         const SwNumFmt& rFmt = pNumRule->Get( static_cast<sal_uInt16>(GetActualListLevel()) );
    4188        9473 :         if ( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT &&
    4189        4613 :              rFmt.GetLabelFollowedBy() == SvxNumberFormat::LISTTAB )
    4190             :         {
    4191        4467 :             bListTanStopPositionProvided = true;
    4192        4467 :             nListTabStopPosition = rFmt.GetListtabPos();
    4193             : 
    4194        4467 :             if ( getIDocumentSettingAccess()->get(IDocumentSettingAccess::TABS_RELATIVE_TO_INDENT) )
    4195             :             {
    4196             :                 // tab stop position are treated to be relative to the "before text"
    4197             :                 // indent value of the paragraph. Thus, adjust <nListTabStopPos>.
    4198          80 :                 if ( AreListLevelIndentsApplicable() )
    4199             :                 {
    4200          80 :                     nListTabStopPosition -= rFmt.GetIndentAt();
    4201             :                 }
    4202           0 :                 else if (!getIDocumentSettingAccess()->get(IDocumentSettingAccess::IGNORE_FIRST_LINE_INDENT_IN_NUMBERING))
    4203             :                 {
    4204           0 :                     SvxLRSpaceItem aItem = GetSwAttrSet().GetLRSpace();
    4205           0 :                     nListTabStopPosition -= aItem.GetTxtLeft();
    4206             :                 }
    4207             :             }
    4208             :         }
    4209             :     }
    4210             : 
    4211      112428 :     return bListTanStopPositionProvided;
    4212             : }
    4213             : 
    4214        3184 : OUString SwTxtNode::GetLabelFollowedBy() const
    4215             : {
    4216        3184 :     const SwNumRule* pNumRule = GetNum() ? GetNum()->GetNumRule() : 0;
    4217        3184 :     if ( pNumRule && HasVisibleNumberingOrBullet() && GetActualListLevel() >= 0 )
    4218             :     {
    4219        3184 :         const SwNumFmt& rFmt = pNumRule->Get( static_cast<sal_uInt16>(GetActualListLevel()) );
    4220        3184 :         if ( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
    4221             :         {
    4222        3111 :             switch ( rFmt.GetLabelFollowedBy() )
    4223             :             {
    4224             :                 case SvxNumberFormat::LISTTAB:
    4225             :                 {
    4226        3050 :                     return OUString("\t");
    4227             :                 }
    4228             :                 break;
    4229             :                 case SvxNumberFormat::SPACE:
    4230             :                 {
    4231          59 :                     return OUString(" ");
    4232             :                 }
    4233             :                 break;
    4234             :                 case SvxNumberFormat::NOTHING:
    4235             :                 {
    4236             :                     // intentionally left blank.
    4237             :                 }
    4238           2 :                 break;
    4239             :                 default:
    4240             :                 {
    4241             :                     OSL_FAIL( "<SwTxtNode::GetLabelFollowedBy()> - unknown SvxNumberFormat::GetLabelFollowedBy() return value" );
    4242             :                 }
    4243             :             }
    4244             :         }
    4245             :     }
    4246             : 
    4247          75 :     return OUString();
    4248             : }
    4249             : 
    4250       25347 : void SwTxtNode::CalcHiddenCharFlags() const
    4251             : {
    4252             :     sal_Int32 nStartPos;
    4253             :     sal_Int32 nEndPos;
    4254             :     // Update of the flags is done inside GetBoundsOfHiddenRange()
    4255       25347 :     SwScriptInfo::GetBoundsOfHiddenRange( *this, 0, nStartPos, nEndPos );
    4256       25347 : }
    4257             : 
    4258             : // #i12836# enhanced pdf export
    4259        4673 : bool SwTxtNode::IsHidden() const
    4260             : {
    4261        4673 :     if ( HasHiddenParaField() || HasHiddenCharAttribute( true ) )
    4262           2 :         return true;
    4263             : 
    4264        4671 :     const SwSectionNode* pSectNd = FindSectionNode();
    4265        4671 :     if ( pSectNd && pSectNd->GetSection().IsHiddenFlag() )
    4266           0 :         return true;
    4267             : 
    4268        4671 :     return false;
    4269             : }
    4270             : 
    4271             : namespace {
    4272             :     // Helper class for special handling of setting attributes at text node:
    4273             :     // In constructor an instance of the helper class recognize whose attributes
    4274             :     // are set and perform corresponding actions before the intrinsic set of
    4275             :     // attributes has been taken place.
    4276             :     // In the destructor - after the attributes have been set at the text
    4277             :     // node - corresponding actions are performed.
    4278             :     // The following is handled:
    4279             :     // (1) When the list style attribute - RES_PARATR_NUMRULE - is set,
    4280             :     //     (A) list style attribute is empty -> the text node is removed from
    4281             :     //         its list.
    4282             :     //     (B) list style attribute is not empty
    4283             :     //         (a) text node has no list style -> add text node to its list after
    4284             :     //             the attributes have been set.
    4285             :     //         (b) text node has list style -> change of list style is notified
    4286             :     //             after the attributes have been set.
    4287             :     // (2) When the list id attribute - RES_PARATR_LIST_ID - is set and changed,
    4288             :     //     the text node is removed from its current list before the attributes
    4289             :     //     are set and added to its new list after the attributes have been set.
    4290             :     // (3) Notify list tree, if list level - RES_PARATR_LIST_LEVEL - is set
    4291             :     //     and changed after the attributes have been set
    4292             :     // (4) Notify list tree, if list restart - RES_PARATR_LIST_ISRESTART - is set
    4293             :     //     and changed after the attributes have been set
    4294             :     // (5) Notify list tree, if list restart value - RES_PARATR_LIST_RESTARTVALUE -
    4295             :     //     is set and changed after the attributes have been set
    4296             :     // (6) Notify list tree, if count in list - RES_PARATR_LIST_ISCOUNTED - is set
    4297             :     //     and changed after the attributes have been set
    4298             :     // (7) Set or Reset emtpy list style due to changed outline level - RES_PARATR_OUTLINELEVEL.
    4299             :     class HandleSetAttrAtTxtNode
    4300             :     {
    4301             :         public:
    4302             :             HandleSetAttrAtTxtNode( SwTxtNode& rTxtNode,
    4303             :                                     const SfxPoolItem& pItem );
    4304             :             HandleSetAttrAtTxtNode( SwTxtNode& rTxtNode,
    4305             :                                     const SfxItemSet& rItemSet );
    4306             :             ~HandleSetAttrAtTxtNode();
    4307             : 
    4308             :         private:
    4309             :             SwTxtNode& mrTxtNode;
    4310             :             bool mbAddTxtNodeToList;
    4311             :             bool mbUpdateListLevel;
    4312             :             bool mbUpdateListRestart;
    4313             :             bool mbUpdateListCount;
    4314             :             // #i70748#
    4315             :             bool mbOutlineLevelSet;
    4316             :     };
    4317             : 
    4318        6471 :     HandleSetAttrAtTxtNode::HandleSetAttrAtTxtNode( SwTxtNode& rTxtNode,
    4319             :                                                     const SfxPoolItem& pItem )
    4320             :         : mrTxtNode( rTxtNode ),
    4321             :           mbAddTxtNodeToList( false ),
    4322             :           mbUpdateListLevel( false ),
    4323             :           mbUpdateListRestart( false ),
    4324             :           mbUpdateListCount( false ),
    4325             :           // #i70748#
    4326        6471 :           mbOutlineLevelSet( false )
    4327             :     {
    4328        6471 :         switch ( pItem.Which() )
    4329             :         {
    4330             :             // handle RES_PARATR_NUMRULE
    4331             :             case RES_PARATR_NUMRULE:
    4332             :             {
    4333         313 :                 mrTxtNode.RemoveFromList();
    4334             : 
    4335             :                 const SwNumRuleItem& pNumRuleItem =
    4336         313 :                                 dynamic_cast<const SwNumRuleItem&>(pItem);
    4337         313 :                 if ( !pNumRuleItem.GetValue().isEmpty() )
    4338             :                 {
    4339         251 :                     mbAddTxtNodeToList = true;
    4340             :                     // #i105562#
    4341             : 
    4342         251 :                     mrTxtNode.ResetEmptyListStyleDueToResetOutlineLevelAttr();
    4343             :                 }
    4344             :             }
    4345         313 :             break;
    4346             : 
    4347             :             // handle RES_PARATR_LIST_ID
    4348             :             case RES_PARATR_LIST_ID:
    4349             :             {
    4350             :                 const SfxStringItem& pListIdItem =
    4351          93 :                                         dynamic_cast<const SfxStringItem&>(pItem);
    4352             :                 OSL_ENSURE( pListIdItem.GetValue().getLength() > 0,
    4353             :                         "<HandleSetAttrAtTxtNode(..)> - empty list id attribute not excepted. Serious defect -> please inform OD." );
    4354          93 :                 const OUString sListIdOfTxtNode = rTxtNode.GetListId();
    4355          93 :                 if ( pListIdItem.GetValue() != sListIdOfTxtNode )
    4356             :                 {
    4357           7 :                     mbAddTxtNodeToList = true;
    4358           7 :                     if ( mrTxtNode.IsInList() )
    4359             :                     {
    4360           7 :                         mrTxtNode.RemoveFromList();
    4361             :                     }
    4362          93 :                 }
    4363             :             }
    4364          93 :             break;
    4365             : 
    4366             :             // handle RES_PARATR_LIST_LEVEL
    4367             :             case RES_PARATR_LIST_LEVEL:
    4368             :             {
    4369             :                 const SfxInt16Item& aListLevelItem =
    4370        2956 :                                     dynamic_cast<const SfxInt16Item&>(pItem);
    4371        2956 :                 if ( aListLevelItem.GetValue() != mrTxtNode.GetAttrListLevel() )
    4372             :                 {
    4373         520 :                     mbUpdateListLevel = true;
    4374             :                 }
    4375             :             }
    4376        2956 :             break;
    4377             : 
    4378             :             // handle RES_PARATR_LIST_ISRESTART
    4379             :             case RES_PARATR_LIST_ISRESTART:
    4380             :             {
    4381             :                 const SfxBoolItem& aListIsRestartItem =
    4382           6 :                                     dynamic_cast<const SfxBoolItem&>(pItem);
    4383          12 :                 if ( aListIsRestartItem.GetValue() !=
    4384           6 :                                     mrTxtNode.IsListRestart() )
    4385             :                 {
    4386           6 :                     mbUpdateListRestart = true;
    4387             :                 }
    4388             :             }
    4389           6 :             break;
    4390             : 
    4391             :             // handle RES_PARATR_LIST_RESTARTVALUE
    4392             :             case RES_PARATR_LIST_RESTARTVALUE:
    4393             :             {
    4394             :                 const SfxInt16Item& aListRestartValueItem =
    4395           7 :                                     dynamic_cast<const SfxInt16Item&>(pItem);
    4396           7 :                 if ( !mrTxtNode.HasAttrListRestartValue() ||
    4397           0 :                      aListRestartValueItem.GetValue() != mrTxtNode.GetAttrListRestartValue() )
    4398             :                 {
    4399           7 :                     mbUpdateListRestart = true;
    4400             :                 }
    4401             :             }
    4402           7 :             break;
    4403             : 
    4404             :             // handle RES_PARATR_LIST_ISCOUNTED
    4405             :             case RES_PARATR_LIST_ISCOUNTED:
    4406             :             {
    4407             :                 const SfxBoolItem& aIsCountedInListItem =
    4408           3 :                                     dynamic_cast<const SfxBoolItem&>(pItem);
    4409           6 :                 if ( aIsCountedInListItem.GetValue() !=
    4410           3 :                                     mrTxtNode.IsCountedInList() )
    4411             :                 {
    4412           3 :                     mbUpdateListCount = true;
    4413             :                 }
    4414             :             }
    4415           3 :             break;
    4416             : 
    4417             :             // #i70748#
    4418             :             // handle RES_PARATR_OUTLINELEVEL
    4419             :             case RES_PARATR_OUTLINELEVEL:
    4420             :             {
    4421             :                 const SfxUInt16Item& aOutlineLevelItem =
    4422           0 :                                     dynamic_cast<const SfxUInt16Item&>(pItem);
    4423           0 :                 if ( aOutlineLevelItem.GetValue() != mrTxtNode.GetAttrOutlineLevel() )
    4424             :                 {
    4425           0 :                     mbOutlineLevelSet = true;
    4426             :                 }
    4427             :             }
    4428           0 :             break;
    4429             :         }
    4430             : 
    4431        6471 :     }
    4432             : 
    4433       55859 :     HandleSetAttrAtTxtNode::HandleSetAttrAtTxtNode( SwTxtNode& rTxtNode,
    4434             :                                                     const SfxItemSet& rItemSet )
    4435             :         : mrTxtNode( rTxtNode ),
    4436             :           mbAddTxtNodeToList( false ),
    4437             :           mbUpdateListLevel( false ),
    4438             :           mbUpdateListRestart( false ),
    4439             :           mbUpdateListCount( false ),
    4440             :           // #i70748#
    4441       55859 :           mbOutlineLevelSet( false )
    4442             :     {
    4443       55859 :         const SfxPoolItem* pItem = 0;
    4444             :         // handle RES_PARATR_NUMRULE
    4445       55859 :         if ( rItemSet.GetItemState( RES_PARATR_NUMRULE, false, &pItem ) == SFX_ITEM_SET )
    4446             :         {
    4447        2020 :             mrTxtNode.RemoveFromList();
    4448             : 
    4449             :             const SwNumRuleItem* pNumRuleItem =
    4450        2020 :                             dynamic_cast<const SwNumRuleItem*>(pItem);
    4451        2020 :             if ( !pNumRuleItem->GetValue().isEmpty() )
    4452             :             {
    4453        1973 :                 mbAddTxtNodeToList = true;
    4454             :                 // #i70748#
    4455        1973 :                 mrTxtNode.ResetEmptyListStyleDueToResetOutlineLevelAttr();
    4456             :             }
    4457             :         }
    4458             : 
    4459             :         // handle RES_PARATR_LIST_ID
    4460       55859 :         if ( rItemSet.GetItemState( RES_PARATR_LIST_ID, false, &pItem ) == SFX_ITEM_SET )
    4461             :         {
    4462             :             const SfxStringItem* pListIdItem =
    4463           2 :                                     dynamic_cast<const SfxStringItem*>(pItem);
    4464           2 :             const OUString sListIdOfTxtNode = mrTxtNode.GetListId();
    4465           4 :             if ( pListIdItem &&
    4466           2 :                  pListIdItem->GetValue() != sListIdOfTxtNode )
    4467             :             {
    4468           2 :                 mbAddTxtNodeToList = true;
    4469           2 :                 if ( mrTxtNode.IsInList() )
    4470             :                 {
    4471           0 :                     mrTxtNode.RemoveFromList();
    4472             :                 }
    4473           2 :             }
    4474             :         }
    4475             : 
    4476             :         // handle RES_PARATR_LIST_LEVEL
    4477       55859 :         if ( rItemSet.GetItemState( RES_PARATR_LIST_LEVEL, false, &pItem ) == SFX_ITEM_SET )
    4478             :         {
    4479             :             const SfxInt16Item* pListLevelItem =
    4480        2280 :                                 dynamic_cast<const SfxInt16Item*>(pItem);
    4481        2280 :             if ( pListLevelItem->GetValue() != mrTxtNode.GetAttrListLevel() )
    4482             :             {
    4483        1391 :                 mbUpdateListLevel = true;
    4484             :             }
    4485             :         }
    4486             : 
    4487             :         // handle RES_PARATR_LIST_ISRESTART
    4488       55859 :         if ( rItemSet.GetItemState( RES_PARATR_LIST_ISRESTART, false, &pItem ) == SFX_ITEM_SET )
    4489             :         {
    4490             :             const SfxBoolItem* pListIsRestartItem =
    4491           0 :                                 dynamic_cast<const SfxBoolItem*>(pItem);
    4492           0 :             if ( pListIsRestartItem->GetValue() != mrTxtNode.IsListRestart() )
    4493             :             {
    4494           0 :                 mbUpdateListRestart = true;
    4495             :             }
    4496             :         }
    4497             : 
    4498             :         // handle RES_PARATR_LIST_RESTARTVALUE
    4499       55859 :         if ( rItemSet.GetItemState( RES_PARATR_LIST_RESTARTVALUE, false, &pItem ) == SFX_ITEM_SET )
    4500             :         {
    4501             :             const SfxInt16Item* pListRestartValueItem =
    4502           0 :                                 dynamic_cast<const SfxInt16Item*>(pItem);
    4503           0 :             if ( !mrTxtNode.HasAttrListRestartValue() ||
    4504           0 :                  pListRestartValueItem->GetValue() != mrTxtNode.GetAttrListRestartValue() )
    4505             :             {
    4506           0 :                 mbUpdateListRestart = true;
    4507             :             }
    4508             :         }
    4509             : 
    4510             :         // handle RES_PARATR_LIST_ISCOUNTED
    4511       55859 :         if ( rItemSet.GetItemState( RES_PARATR_LIST_ISCOUNTED, false, &pItem ) == SFX_ITEM_SET )
    4512             :         {
    4513             :             const SfxBoolItem* pIsCountedInListItem =
    4514           0 :                                 dynamic_cast<const SfxBoolItem*>(pItem);
    4515           0 :             if ( pIsCountedInListItem->GetValue() !=
    4516           0 :                                 mrTxtNode.IsCountedInList() )
    4517             :             {
    4518           0 :                 mbUpdateListCount = true;
    4519             :             }
    4520             :         }
    4521             : 
    4522             :         // #i70748#
    4523             :         // handle RES_PARATR_OUTLINELEVEL
    4524       55859 :         if ( rItemSet.GetItemState( RES_PARATR_OUTLINELEVEL, false, &pItem ) == SFX_ITEM_SET )
    4525             :         {
    4526             :             const SfxUInt16Item* pOutlineLevelItem =
    4527          62 :                                 dynamic_cast<const SfxUInt16Item*>(pItem);
    4528          62 :             if ( pOutlineLevelItem->GetValue() != mrTxtNode.GetAttrOutlineLevel() )
    4529             :             {
    4530          41 :                 mbOutlineLevelSet = true;
    4531             :             }
    4532             :         }
    4533       55859 :     }
    4534             : 
    4535       62330 :     HandleSetAttrAtTxtNode::~HandleSetAttrAtTxtNode()
    4536             :     {
    4537       62330 :         if ( mbAddTxtNodeToList )
    4538             :         {
    4539        2231 :             SwNumRule* pNumRuleAtTxtNode = mrTxtNode.GetNumRule();
    4540        2231 :             if ( pNumRuleAtTxtNode )
    4541             :             {
    4542        2231 :                 mrTxtNode.AddToList();
    4543             :             }
    4544             :         }
    4545             :         else
    4546             :         {
    4547       60099 :             if ( mbUpdateListLevel && mrTxtNode.IsInList() )
    4548             :             {
    4549         561 :                 const_cast<SwNodeNum*>(mrTxtNode.GetNum())->SetLevelInListTree(
    4550        1122 :                                                     mrTxtNode.GetAttrListLevel() );
    4551             :             }
    4552             : 
    4553       60099 :             if ( mbUpdateListRestart && mrTxtNode.IsInList() )
    4554             :             {
    4555          12 :                 SwNodeNum* pNodeNum = const_cast<SwNodeNum*>(mrTxtNode.GetNum());
    4556          12 :                 pNodeNum->InvalidateMe();
    4557          12 :                 pNodeNum->NotifyInvalidSiblings();
    4558             :             }
    4559             : 
    4560       60099 :             if ( mbUpdateListCount && mrTxtNode.IsInList() )
    4561             :             {
    4562           3 :                 const_cast<SwNodeNum*>(mrTxtNode.GetNum())->InvalidateAndNotifyTree();
    4563             :             }
    4564             :         }
    4565             : 
    4566             :         // #i70748#
    4567       62330 :         if ( mbOutlineLevelSet )
    4568             :         {
    4569          41 :             if ( mrTxtNode.GetAttrOutlineLevel() == 0 )
    4570             :             {
    4571           0 :                 mrTxtNode.ResetEmptyListStyleDueToResetOutlineLevelAttr();
    4572             :             }
    4573             :             else
    4574             :             {
    4575          41 :                 const SfxPoolItem* pItem = 0;
    4576          82 :                 if ( mrTxtNode.GetSwAttrSet().GetItemState( RES_PARATR_NUMRULE,
    4577          41 :                                                             true, &pItem )
    4578             :                                                                 != SFX_ITEM_SET )
    4579             :                 {
    4580          18 :                     mrTxtNode.SetEmptyListStyleDueToSetOutlineLevelAttr();
    4581             :                 }
    4582             :             }
    4583             :         }
    4584       62330 :     }
    4585             :     // End of class <HandleSetAttrAtTxtNode>
    4586             : }
    4587             : 
    4588        6471 : sal_Bool SwTxtNode::SetAttr( const SfxPoolItem& pItem )
    4589             : {
    4590        6471 :     const bool bOldIsSetOrResetAttr( mbInSetOrResetAttr );
    4591        6471 :     mbInSetOrResetAttr = true;
    4592             : 
    4593        6471 :     HandleSetAttrAtTxtNode aHandleSetAttr( *this, pItem );
    4594             : 
    4595        6471 :     sal_Bool bRet = SwCntntNode::SetAttr( pItem );
    4596             : 
    4597        6471 :     mbInSetOrResetAttr = bOldIsSetOrResetAttr;
    4598             : 
    4599        6471 :     return bRet;
    4600             : }
    4601             : 
    4602       55859 : sal_Bool SwTxtNode::SetAttr( const SfxItemSet& rSet )
    4603             : {
    4604       55859 :     const bool bOldIsSetOrResetAttr( mbInSetOrResetAttr );
    4605       55859 :     mbInSetOrResetAttr = true;
    4606             : 
    4607       55859 :     HandleSetAttrAtTxtNode aHandleSetAttr( *this, rSet );
    4608             : 
    4609       55859 :     sal_Bool bRet = SwCntntNode::SetAttr( rSet );
    4610             : 
    4611       55859 :     mbInSetOrResetAttr = bOldIsSetOrResetAttr;
    4612             : 
    4613       55859 :     return bRet;
    4614             : }
    4615             : 
    4616             : namespace {
    4617             :     // Helper class for special handling of resetting attributes at text node:
    4618             :     // In constructor an instance of the helper class recognize whose attributes
    4619             :     // are reset and perform corresponding actions before the intrinsic reset of
    4620             :     // attributes has been taken place.
    4621             :     // In the destructor - after the attributes have been reset at the text
    4622             :     // node - corresponding actions are performed.
    4623             :     // The following is handled:
    4624             :     // (1) When the list style attribute - RES_PARATR_NUMRULE - is reset,
    4625             :     //     the text is removed from its list before the attributes have been reset.
    4626             :     // (2) When the list id attribute - RES_PARATR_LIST_ID - is reset,
    4627             :     //     the text is removed from its list before the attributes have been reset.
    4628             :     // (3) Notify list tree, if list level - RES_PARATR_LIST_LEVEL - is reset.
    4629             :     // (4) Notify list tree, if list restart - RES_PARATR_LIST_ISRESTART - is reset.
    4630             :     // (5) Notify list tree, if list restart value - RES_PARATR_LIST_RESTARTVALUE - is reset.
    4631             :     // (6) Notify list tree, if count in list - RES_PARATR_LIST_ISCOUNTED - is reset.
    4632             :     // (7) Reset empty list style, if outline level attribute - RES_PARATR_OUTLINELEVEL - is reset.
    4633             :     class HandleResetAttrAtTxtNode
    4634             :     {
    4635             :         public:
    4636             :             HandleResetAttrAtTxtNode( SwTxtNode& rTxtNode,
    4637             :                                       const sal_uInt16 nWhich1,
    4638             :                                       const sal_uInt16 nWhich2 );
    4639             :             HandleResetAttrAtTxtNode( SwTxtNode& rTxtNode,
    4640             :                                       const std::vector<sal_uInt16>& rWhichArr );
    4641             :             HandleResetAttrAtTxtNode( SwTxtNode& rTxtNode );
    4642             : 
    4643             :             ~HandleResetAttrAtTxtNode();
    4644             : 
    4645             :         private:
    4646             :             SwTxtNode& mrTxtNode;
    4647             :             bool mbListStyleOrIdReset;
    4648             :             bool mbUpdateListLevel;
    4649             :             bool mbUpdateListRestart;
    4650             :             bool mbUpdateListCount;
    4651             :     };
    4652             : 
    4653      136993 :     HandleResetAttrAtTxtNode::HandleResetAttrAtTxtNode( SwTxtNode& rTxtNode,
    4654             :                                                         const sal_uInt16 nWhich1,
    4655             :                                                         const sal_uInt16 nWhich2 )
    4656             :         : mrTxtNode( rTxtNode ),
    4657             :           mbListStyleOrIdReset( false ),
    4658             :           mbUpdateListLevel( false ),
    4659             :           mbUpdateListRestart( false ),
    4660      136993 :           mbUpdateListCount( false )
    4661             :     {
    4662      136993 :         bool bRemoveFromList( false );
    4663      136993 :         if ( nWhich2 != 0 && nWhich2 > nWhich1 )
    4664             :         {
    4665             :             // RES_PARATR_NUMRULE and RES_PARATR_LIST_ID
    4666           1 :             if ( nWhich1 <= RES_PARATR_NUMRULE && RES_PARATR_NUMRULE <= nWhich2 )
    4667             :             {
    4668           0 :                 bRemoveFromList = mrTxtNode.GetNumRule() != 0;
    4669           0 :                 mbListStyleOrIdReset = true;
    4670             :             }
    4671           1 :             else if ( nWhich1 <= RES_PARATR_LIST_ID && RES_PARATR_LIST_ID <= nWhich2 )
    4672             :             {
    4673           0 :                 bRemoveFromList = mrTxtNode.GetpSwAttrSet() &&
    4674           0 :                     mrTxtNode.GetpSwAttrSet()->GetItemState( RES_PARATR_LIST_ID, false ) == SFX_ITEM_SET;
    4675             :                 // #i92898#
    4676           0 :                 mbListStyleOrIdReset = true;
    4677             :             }
    4678             : 
    4679           1 :             if ( !bRemoveFromList )
    4680             :             {
    4681             :                 // RES_PARATR_LIST_LEVEL
    4682           0 :                 mbUpdateListLevel = ( nWhich1 <= RES_PARATR_LIST_LEVEL &&
    4683           1 :                                       RES_PARATR_LIST_LEVEL <= nWhich2 &&
    4684           1 :                                       mrTxtNode.HasAttrListLevel() );
    4685             : 
    4686             :                 // RES_PARATR_LIST_ISRESTART and RES_PARATR_LIST_RESTARTVALUE
    4687             :                 mbUpdateListRestart =
    4688           0 :                     ( nWhich1 <= RES_PARATR_LIST_ISRESTART && RES_PARATR_LIST_ISRESTART <= nWhich2 &&
    4689           2 :                       mrTxtNode.IsListRestart() ) ||
    4690           0 :                     ( nWhich1 <= RES_PARATR_LIST_RESTARTVALUE && RES_PARATR_LIST_RESTARTVALUE <= nWhich2 &&
    4691           1 :                       mrTxtNode.HasAttrListRestartValue() );
    4692             : 
    4693             :                 // RES_PARATR_LIST_ISCOUNTED
    4694             :                 mbUpdateListCount =
    4695           1 :                     ( nWhich1 <= RES_PARATR_LIST_ISCOUNTED && RES_PARATR_LIST_ISCOUNTED <= nWhich2 &&
    4696           1 :                       !mrTxtNode.IsCountedInList() );
    4697             :             }
    4698             : 
    4699             :             // #i70748#
    4700             :             // RES_PARATR_OUTLINELEVEL
    4701           2 :             if ( nWhich1 <= RES_PARATR_OUTLINELEVEL && RES_PARATR_OUTLINELEVEL <= nWhich2 )
    4702             :             {
    4703           0 :                 mrTxtNode.ResetEmptyListStyleDueToResetOutlineLevelAttr();
    4704             :             }
    4705             :         }
    4706             :         else
    4707             :         {
    4708             :             // RES_PARATR_NUMRULE and RES_PARATR_LIST_ID
    4709      136992 :             if ( nWhich1 == RES_PARATR_NUMRULE )
    4710             :             {
    4711        6263 :                 bRemoveFromList = mrTxtNode.GetNumRule() != 0;
    4712        6263 :                 mbListStyleOrIdReset = true;
    4713             :             }
    4714      130729 :             else if ( nWhich1 == RES_PARATR_LIST_ID )
    4715             :             {
    4716       27131 :                 bRemoveFromList = mrTxtNode.GetpSwAttrSet() &&
    4717       27131 :                     mrTxtNode.GetpSwAttrSet()->GetItemState( RES_PARATR_LIST_ID, false ) == SFX_ITEM_SET;
    4718             :                 // #i92898#
    4719       25736 :                 mbListStyleOrIdReset = true;
    4720             :             }
    4721             :             // #i70748#
    4722             :             // RES_PARATR_OUTLINELEVEL
    4723      104993 :             else if ( nWhich1 == RES_PARATR_OUTLINELEVEL )
    4724             :             {
    4725           1 :                 mrTxtNode.ResetEmptyListStyleDueToResetOutlineLevelAttr();
    4726             :             }
    4727             : 
    4728      136992 :             if ( !bRemoveFromList )
    4729             :             {
    4730             :                 // RES_PARATR_LIST_LEVEL
    4731      162247 :                 mbUpdateListLevel = nWhich1 == RES_PARATR_LIST_LEVEL &&
    4732      162247 :                                     mrTxtNode.HasAttrListLevel();
    4733             : 
    4734             :                 // RES_PARATR_LIST_ISRESTART and RES_PARATR_LIST_RESTARTVALUE
    4735       26227 :                 mbUpdateListRestart = ( nWhich1 == RES_PARATR_LIST_ISRESTART &&
    4736      273025 :                                         mrTxtNode.IsListRestart() ) ||
    4737       26227 :                                       ( nWhich1 == RES_PARATR_LIST_RESTARTVALUE &&
    4738      162739 :                                         mrTxtNode.HasAttrListRestartValue() );
    4739             : 
    4740             :                 // RES_PARATR_LIST_ISCOUNTED
    4741      163254 :                 mbUpdateListCount = nWhich1 == RES_PARATR_LIST_ISCOUNTED &&
    4742      163254 :                                     !mrTxtNode.IsCountedInList();
    4743             :             }
    4744             :         }
    4745             : 
    4746      136993 :         if ( bRemoveFromList && mrTxtNode.IsInList() )
    4747             :         {
    4748         480 :             mrTxtNode.RemoveFromList();
    4749             :         }
    4750      136993 :     }
    4751             : 
    4752        3113 :     HandleResetAttrAtTxtNode::HandleResetAttrAtTxtNode( SwTxtNode& rTxtNode,
    4753             :                                                         const std::vector<sal_uInt16>& rWhichArr )
    4754             :         : mrTxtNode( rTxtNode ),
    4755             :           mbListStyleOrIdReset( false ),
    4756             :           mbUpdateListLevel( false ),
    4757             :           mbUpdateListRestart( false ),
    4758        3113 :           mbUpdateListCount( false )
    4759             :     {
    4760        3113 :         bool bRemoveFromList( false );
    4761             :         {
    4762        3113 :             std::vector<sal_uInt16>::const_iterator it;
    4763       38737 :             for ( it = rWhichArr.begin(); it != rWhichArr.end(); ++it)
    4764             :             {
    4765             :                 // RES_PARATR_NUMRULE and RES_PARATR_LIST_ID
    4766       35624 :                 if ( *it == RES_PARATR_NUMRULE )
    4767             :                 {
    4768         746 :                     bRemoveFromList = bRemoveFromList ||
    4769         746 :                                       mrTxtNode.GetNumRule() != 0;
    4770         373 :                     mbListStyleOrIdReset = true;
    4771             :                 }
    4772       35251 :                 else if ( *it == RES_PARATR_LIST_ID )
    4773             :                 {
    4774           0 :                     bRemoveFromList = bRemoveFromList ||
    4775           0 :                         ( mrTxtNode.GetpSwAttrSet() &&
    4776           0 :                           mrTxtNode.GetpSwAttrSet()->GetItemState( RES_PARATR_LIST_ID, false ) == SFX_ITEM_SET );
    4777             :                     // #i92898#
    4778           0 :                     mbListStyleOrIdReset = true;
    4779             :                 }
    4780             :                 // #i70748#
    4781             :                 // RES_PARATR_OUTLINELEVEL
    4782       35251 :                 else if ( *it == RES_PARATR_OUTLINELEVEL )
    4783             :                 {
    4784           0 :                     mrTxtNode.ResetEmptyListStyleDueToResetOutlineLevelAttr();
    4785             :                 }
    4786             : 
    4787       35624 :                 if ( !bRemoveFromList )
    4788             :                 {
    4789             :                     // RES_PARATR_LIST_LEVEL
    4790       71788 :                     mbUpdateListLevel = mbUpdateListLevel ||
    4791       36533 :                                         ( *it == RES_PARATR_LIST_LEVEL &&
    4792       36537 :                                           mrTxtNode.HasAttrListLevel() );
    4793             : 
    4794             :                     // RES_PARATR_LIST_ISRESTART and RES_PARATR_LIST_RESTARTVALUE
    4795       35251 :                     mbUpdateListRestart = mbUpdateListRestart ||
    4796       35251 :                                           ( *it == RES_PARATR_LIST_ISRESTART &&
    4797       70502 :                                             mrTxtNode.IsListRestart() ) ||
    4798       35251 :                                           ( *it == RES_PARATR_LIST_RESTARTVALUE &&
    4799       35251 :                                             mrTxtNode.HasAttrListRestartValue() );
    4800             : 
    4801             :                     // RES_PARATR_LIST_ISCOUNTED
    4802       70502 :                     mbUpdateListCount = mbUpdateListCount ||
    4803       35251 :                                         ( *it == RES_PARATR_LIST_ISCOUNTED &&
    4804       35251 :                                           !mrTxtNode.IsCountedInList() );
    4805             :                 }
    4806             :             }
    4807             :         }
    4808             : 
    4809        3113 :         if ( bRemoveFromList && mrTxtNode.IsInList() )
    4810             :         {
    4811         373 :             mrTxtNode.RemoveFromList();
    4812             :         }
    4813        3113 :     }
    4814             : 
    4815        4240 :     HandleResetAttrAtTxtNode::HandleResetAttrAtTxtNode( SwTxtNode& rTxtNode )
    4816             :         : mrTxtNode( rTxtNode ),
    4817             :           mbListStyleOrIdReset( false ),
    4818             :           mbUpdateListLevel( false ),
    4819             :           mbUpdateListRestart( false ),
    4820        4240 :           mbUpdateListCount( false )
    4821             :     {
    4822        4240 :         mbListStyleOrIdReset = true;
    4823        4240 :         if ( rTxtNode.IsInList() )
    4824             :         {
    4825         542 :             rTxtNode.RemoveFromList();
    4826             :         }
    4827             :         // #i70748#
    4828        4240 :         mrTxtNode.ResetEmptyListStyleDueToResetOutlineLevelAttr();
    4829        4240 :     }
    4830             : 
    4831      144346 :     HandleResetAttrAtTxtNode::~HandleResetAttrAtTxtNode()
    4832             :     {
    4833      144346 :         if ( mbListStyleOrIdReset && !mrTxtNode.IsInList() )
    4834             :         {
    4835             :             // check, if in spite of the reset of the list style or the list id
    4836             :             // the paragraph still has to be added to a list.
    4837       36612 :             if (mrTxtNode.GetNumRule() && !mrTxtNode.GetListId().isEmpty())
    4838             :             {
    4839             :                 // #i96062#
    4840             :                 // If paragraph has no list level attribute set and list style
    4841             :                 // is the outline style, apply outline level as the list level.
    4842        4374 :                 if ( !mrTxtNode.HasAttrListLevel() &&
    4843        4176 :                      mrTxtNode.GetNumRule()->GetName()==SwNumRule::GetOutlineRuleName() &&
    4844           3 :                      mrTxtNode.GetTxtColl()->IsAssignedToListLevelOfOutlineStyle() )
    4845             :                 {
    4846           3 :                     int nNewListLevel = mrTxtNode.GetTxtColl()->GetAssignedOutlineStyleLevel();
    4847           3 :                     if ( 0 <= nNewListLevel && nNewListLevel < MAXLEVEL )
    4848             :                     {
    4849           3 :                         mrTxtNode.SetAttrListLevel( nNewListLevel );
    4850             :                     }
    4851             :                 }
    4852         796 :                 mrTxtNode.AddToList();
    4853             :             }
    4854             :             // #i70748#
    4855             :             // #i105562#
    4856       38664 :             else if ( mrTxtNode.GetpSwAttrSet() &&
    4857        2848 :                       dynamic_cast<const SfxUInt16Item &>(mrTxtNode.GetAttr( RES_PARATR_OUTLINELEVEL, sal_False )).GetValue() > 0 )
    4858             :             {
    4859           9 :                 mrTxtNode.SetEmptyListStyleDueToSetOutlineLevelAttr();
    4860             :             }
    4861             :         }
    4862             : 
    4863      144346 :         if ( mrTxtNode.IsInList() )
    4864             :         {
    4865        3247 :             if ( mbUpdateListLevel )
    4866             :             {
    4867         542 :                 SwNodeNum* pNodeNum = const_cast<SwNodeNum*>(mrTxtNode.GetNum());
    4868         542 :                 pNodeNum->SetLevelInListTree( mrTxtNode.GetAttrListLevel() );
    4869             :             }
    4870             : 
    4871        3247 :             if ( mbUpdateListRestart )
    4872             :             {
    4873           0 :                 SwNodeNum* pNodeNum = const_cast<SwNodeNum*>(mrTxtNode.GetNum());
    4874           0 :                 pNodeNum->InvalidateMe();
    4875           0 :                 pNodeNum->NotifyInvalidSiblings();
    4876             :             }
    4877             : 
    4878        3247 :             if ( mbUpdateListCount )
    4879             :             {
    4880           0 :                 SwNodeNum* pNodeNum = const_cast<SwNodeNum*>(mrTxtNode.GetNum());
    4881           0 :                 pNodeNum->InvalidateAndNotifyTree();
    4882             :             }
    4883             :         }
    4884      144346 :     }
    4885             :     // End of class <HandleResetAttrAtTxtNode>
    4886             : }
    4887             : 
    4888      136993 : sal_Bool SwTxtNode::ResetAttr( sal_uInt16 nWhich1, sal_uInt16 nWhich2 )
    4889             : {
    4890      136993 :     const bool bOldIsSetOrResetAttr( mbInSetOrResetAttr );
    4891      136993 :     mbInSetOrResetAttr = true;
    4892             : 
    4893      136993 :     HandleResetAttrAtTxtNode aHandleResetAttr( *this, nWhich1, nWhich2 );
    4894             : 
    4895      136993 :     sal_Bool bRet = SwCntntNode::ResetAttr( nWhich1, nWhich2 );
    4896             : 
    4897      136993 :     mbInSetOrResetAttr = bOldIsSetOrResetAttr;
    4898             : 
    4899      136993 :     return bRet;
    4900             : }
    4901             : 
    4902        3113 : sal_Bool SwTxtNode::ResetAttr( const std::vector<sal_uInt16>& rWhichArr )
    4903             : {
    4904        3113 :     const bool bOldIsSetOrResetAttr( mbInSetOrResetAttr );
    4905        3113 :     mbInSetOrResetAttr = true;
    4906             : 
    4907        3113 :     HandleResetAttrAtTxtNode aHandleResetAttr( *this, rWhichArr );
    4908             : 
    4909        3113 :     sal_Bool bRet = SwCntntNode::ResetAttr( rWhichArr );
    4910             : 
    4911        3113 :     mbInSetOrResetAttr = bOldIsSetOrResetAttr;
    4912             : 
    4913        3113 :     return bRet;
    4914             : }
    4915             : 
    4916        4240 : sal_uInt16 SwTxtNode::ResetAllAttr()
    4917             : {
    4918        4240 :     const bool bOldIsSetOrResetAttr( mbInSetOrResetAttr );
    4919        4240 :     mbInSetOrResetAttr = true;
    4920             : 
    4921        4240 :     HandleResetAttrAtTxtNode aHandleResetAttr( *this );
    4922             : 
    4923        4240 :     sal_uInt16 nRet = SwCntntNode::ResetAllAttr();
    4924             : 
    4925        4240 :     mbInSetOrResetAttr = bOldIsSetOrResetAttr;
    4926             : 
    4927        4240 :     return nRet;
    4928             : }
    4929             : 
    4930           0 : sal_uInt32 SwTxtNode::GetRsid( sal_Int32 nStt, sal_Int32 nEnd ) const
    4931             : {
    4932           0 :     SfxItemSet aSet( (SfxItemPool&) (GetDoc()->GetAttrPool()), RES_CHRATR_RSID, RES_CHRATR_RSID );
    4933           0 :     if ( GetAttr(aSet, nStt, nEnd) )
    4934             :     {
    4935           0 :         SvxRsidItem* pRsid = (SvxRsidItem*)aSet.GetItem(RES_CHRATR_RSID);
    4936           0 :         if( pRsid )
    4937           0 :             return pRsid->GetValue();
    4938             :     }
    4939             : 
    4940           0 :     return 0;
    4941             : }
    4942             : 
    4943         297 : sal_uInt32 SwTxtNode::GetParRsid() const
    4944             : {
    4945         297 :     return reinterpret_cast<const SvxRsidItem&>(GetAttr( RES_PARATR_RSID )).GetValue();
    4946             : }
    4947             : 
    4948           0 : bool SwTxtNode::CompareParRsid( const SwTxtNode &rTxtNode ) const
    4949             : {
    4950           0 :     sal_uInt32 nThisRsid = GetParRsid();
    4951           0 :     sal_uInt32 nRsid = rTxtNode.GetParRsid();
    4952             : 
    4953           0 :     return nThisRsid == nRsid;
    4954             : }
    4955             : 
    4956           0 : bool SwTxtNode::CompareRsid( const SwTxtNode &rTxtNode, sal_Int32 nStt1, sal_Int32 nStt2,
    4957             :                             sal_Int32 nEnd1, sal_Int32 nEnd2 ) const
    4958             : 
    4959             : {
    4960           0 :     sal_uInt32 nThisRsid = GetRsid( nStt1, nEnd1 ? nEnd1 : nStt1 );
    4961           0 :     sal_uInt32 nRsid = rTxtNode.GetRsid( nStt2, nEnd2 ? nEnd2 : nStt2 );
    4962             : 
    4963           0 :     return nThisRsid == nRsid;
    4964             : }
    4965             : 
    4966             : // sw::Metadatable
    4967         124 : ::sfx2::IXmlIdRegistry& SwTxtNode::GetRegistry()
    4968             : {
    4969         124 :     return GetDoc()->GetXmlIdRegistry();
    4970             : }
    4971             : 
    4972        2591 : bool SwTxtNode::IsInClipboard() const
    4973             : {
    4974        2591 :     return GetDoc()->IsClipBoard();
    4975             : }
    4976             : 
    4977        2601 : bool SwTxtNode::IsInUndo() const
    4978             : {
    4979        2601 :     return GetDoc()->GetIDocumentUndoRedo().IsUndoNodes(GetNodes());
    4980             : }
    4981             : 
    4982         158 : bool SwTxtNode::IsInContent() const
    4983             : {
    4984         158 :     return !GetDoc()->IsInHeaderFooter( SwNodeIndex(*this) );
    4985             : }
    4986             : 
    4987          31 : void SwTxtNode::SwClientNotify( const SwModify& rModify, const SfxHint& rHint )
    4988             : {
    4989          31 :     const SwAttrHint* pHint = dynamic_cast<const SwAttrHint*>(&rHint);
    4990          31 :     if ( pHint && pHint->GetId() == RES_CONDTXTFMTCOLL && &rModify == GetRegisteredIn() )
    4991          31 :         ChkCondColl();
    4992          31 : }
    4993             : 
    4994             : #include <unoparagraph.hxx>
    4995             : 
    4996             : uno::Reference< rdf::XMetadatable >
    4997           1 : SwTxtNode::MakeUnoObject()
    4998             : {
    4999             :     const uno::Reference<rdf::XMetadatable> xMeta(
    5000           1 :             SwXParagraph::CreateXParagraph(*GetDoc(), *this), uno::UNO_QUERY);
    5001           1 :     return xMeta;
    5002             : }
    5003             : 
    5004             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10