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

Generated by: LCOV version 1.10