LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sw/source/core/undo - unovwr.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 1 247 0.4 %
Date: 2013-07-09 Functions: 2 21 9.5 %
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 <UndoOverwrite.hxx>
      21             : #include <tools/resid.hxx>
      22             : #include <unotools/charclass.hxx>
      23             : #include <unotools/transliterationwrapper.hxx>
      24             : #include <comphelper/processfactory.hxx>
      25             : #include <doc.hxx>
      26             : #include <IDocumentUndoRedo.hxx>
      27             : #include <IShellCursorSupplier.hxx>
      28             : #include <swundo.hxx>
      29             : #include <pam.hxx>
      30             : #include <ndtxt.hxx>
      31             : #include <UndoCore.hxx>
      32             : #include <rolbck.hxx>
      33             : #include <acorrect.hxx>
      34             : #include <docary.hxx>
      35             : #include <comcore.hrc> // #111827#
      36             : #include <undo.hrc>
      37             : 
      38             : using namespace ::com::sun::star;
      39             : using namespace ::com::sun::star::i18n;
      40             : using namespace ::com::sun::star::uno;
      41             : 
      42           0 : SwUndoOverwrite::SwUndoOverwrite( SwDoc* pDoc, SwPosition& rPos,
      43             :                                     sal_Unicode cIns )
      44             :     : SwUndo(UNDO_OVERWRITE),
      45           0 :       pRedlSaveData( 0 ), bGroup( sal_False )
      46             : {
      47           0 :     if( !pDoc->IsIgnoreRedline() && !pDoc->GetRedlineTbl().empty() )
      48             :     {
      49           0 :         SwPaM aPam( rPos.nNode, rPos.nContent.GetIndex(),
      50           0 :                     rPos.nNode, rPos.nContent.GetIndex()+1 );
      51           0 :         pRedlSaveData = new SwRedlineSaveDatas;
      52           0 :         if( !FillSaveData( aPam, *pRedlSaveData, sal_False ))
      53           0 :             delete pRedlSaveData, pRedlSaveData = 0;
      54             :     }
      55             : 
      56           0 :     nSttNode = rPos.nNode.GetIndex();
      57           0 :     nSttCntnt = rPos.nContent.GetIndex();
      58             : 
      59           0 :     SwTxtNode* pTxtNd = rPos.nNode.GetNode().GetTxtNode();
      60             :     OSL_ENSURE( pTxtNd, "Overwrite not in a TextNode?" );
      61             : 
      62           0 :     bInsChar = sal_True;
      63           0 :     xub_StrLen nTxtNdLen = pTxtNd->GetTxt().getLength();
      64           0 :     if( nSttCntnt < nTxtNdLen )     // no pure insert?
      65             :     {
      66           0 :         aDelStr.Insert( pTxtNd->GetTxt()[nSttCntnt] );
      67           0 :         if( !pHistory )
      68           0 :             pHistory = new SwHistory;
      69           0 :         SwRegHistory aRHst( *pTxtNd, pHistory );
      70             :         pHistory->CopyAttr( pTxtNd->GetpSwpHints(), nSttNode, 0,
      71           0 :                             nTxtNdLen, false );
      72           0 :         rPos.nContent++;
      73           0 :         bInsChar = sal_False;
      74             :     }
      75             : 
      76           0 :     bool bOldExpFlg = pTxtNd->IsIgnoreDontExpand();
      77           0 :     pTxtNd->SetIgnoreDontExpand( true );
      78             : 
      79             :     pTxtNd->InsertText( OUString(cIns), rPos.nContent,
      80           0 :             IDocumentContentOperations::INS_EMPTYEXPAND );
      81           0 :     aInsStr.Insert( cIns );
      82             : 
      83           0 :     if( !bInsChar )
      84             :     {
      85           0 :         const SwIndex aTmpIndex( rPos.nContent, -2 );
      86           0 :         pTxtNd->EraseText( aTmpIndex, 1 );
      87             :     }
      88           0 :     pTxtNd->SetIgnoreDontExpand( bOldExpFlg );
      89             : 
      90           0 :     bCacheComment = false;
      91           0 : }
      92             : 
      93           0 : SwUndoOverwrite::~SwUndoOverwrite()
      94             : {
      95           0 :     delete pRedlSaveData;
      96           0 : }
      97             : 
      98           0 : sal_Bool SwUndoOverwrite::CanGrouping( SwDoc* pDoc, SwPosition& rPos,
      99             :                                     sal_Unicode cIns )
     100             : {
     101             : // What is with only inserted characters?
     102             : 
     103             :     // Only deletion of single chars can be combined.
     104           0 :     if( rPos.nNode != nSttNode || !aInsStr.Len()  ||
     105           0 :         ( !bGroup && aInsStr.Len() != 1 ))
     106           0 :         return sal_False;
     107             : 
     108             :     // Is the node a TextNode at all?
     109           0 :     SwTxtNode * pDelTxtNd = rPos.nNode.GetNode().GetTxtNode();
     110           0 :     if( !pDelTxtNd ||
     111           0 :         (pDelTxtNd->GetTxt().getLength() != rPos.nContent.GetIndex() &&
     112           0 :             rPos.nContent.GetIndex() != ( nSttCntnt + aInsStr.Len() )))
     113           0 :         return sal_False;
     114             : 
     115           0 :     CharClass& rCC = GetAppCharClass();
     116             : 
     117             :     // ask the char that should be inserted
     118           0 :     if (( CH_TXTATR_BREAKWORD == cIns || CH_TXTATR_INWORD == cIns ) ||
     119           0 :         rCC.isLetterNumeric( OUString( cIns ), 0 ) !=
     120           0 :         rCC.isLetterNumeric( aInsStr, aInsStr.Len()-1 ) )
     121           0 :         return sal_False;
     122             : 
     123             :     {
     124           0 :         SwRedlineSaveDatas* pTmpSav = new SwRedlineSaveDatas;
     125           0 :         SwPaM aPam( rPos.nNode, rPos.nContent.GetIndex(),
     126           0 :                     rPos.nNode, rPos.nContent.GetIndex()+1 );
     127             : 
     128           0 :         if( !FillSaveData( aPam, *pTmpSav, sal_False ))
     129           0 :             delete pTmpSav, pTmpSav = 0;
     130             : 
     131           0 :         bool bOk = ( !pRedlSaveData && !pTmpSav ) ||
     132           0 :                    ( pRedlSaveData && pTmpSav &&
     133             :                         SwUndo::CanRedlineGroup( *pRedlSaveData, *pTmpSav,
     134           0 :                             nSttCntnt > rPos.nContent.GetIndex() ));
     135           0 :         delete pTmpSav;
     136           0 :         if( !bOk )
     137           0 :             return sal_False;
     138             : 
     139           0 :         pDoc->DeleteRedline( aPam, false, USHRT_MAX );
     140             :     }
     141             : 
     142             :     // both 'overwrites' can be combined so 'move' the corresponding character
     143           0 :     if( !bInsChar )
     144             :     {
     145           0 :         if (rPos.nContent.GetIndex() < pDelTxtNd->GetTxt().getLength())
     146             :         {
     147           0 :             aDelStr.Insert(pDelTxtNd->GetTxt()[rPos.nContent.GetIndex()]);
     148           0 :             rPos.nContent++;
     149             :         }
     150             :         else
     151           0 :             bInsChar = sal_True;
     152             :     }
     153             : 
     154           0 :     bool bOldExpFlg = pDelTxtNd->IsIgnoreDontExpand();
     155           0 :     pDelTxtNd->SetIgnoreDontExpand( true );
     156             : 
     157             :     OUString const ins( pDelTxtNd->InsertText(OUString(cIns), rPos.nContent,
     158           0 :             IDocumentContentOperations::INS_EMPTYEXPAND) );
     159             :     assert(ins.getLength() == 1); // check in SwDoc::Overwrite => cannot fail
     160           0 :     aInsStr.Insert( cIns );
     161             : 
     162           0 :     if( !bInsChar )
     163             :     {
     164           0 :         const SwIndex aTmpIndex( rPos.nContent, -2 );
     165           0 :         pDelTxtNd->EraseText( aTmpIndex, 1 );
     166             :     }
     167           0 :     pDelTxtNd->SetIgnoreDontExpand( bOldExpFlg );
     168             : 
     169           0 :     bGroup = sal_True;
     170           0 :     return sal_True;
     171             : }
     172             : 
     173           0 : void SwUndoOverwrite::UndoImpl(::sw::UndoRedoContext & rContext)
     174             : {
     175           0 :     SwDoc *const pDoc = & rContext.GetDoc();
     176           0 :     SwPaM *const pAktPam(& rContext.GetCursorSupplier().CreateNewShellCursor());
     177             : 
     178           0 :     pAktPam->DeleteMark();
     179           0 :     pAktPam->GetPoint()->nNode = nSttNode;
     180           0 :     SwTxtNode* pTxtNd = pAktPam->GetNode()->GetTxtNode();
     181             :     OSL_ENSURE( pTxtNd, "Overwrite not in a TextNode?" );
     182           0 :     SwIndex& rIdx = pAktPam->GetPoint()->nContent;
     183           0 :     rIdx.Assign( pTxtNd, nSttCntnt );
     184             : 
     185           0 :     SwAutoCorrExceptWord* pACEWord = pDoc->GetAutoCorrExceptWord();
     186           0 :     if( pACEWord )
     187             :     {
     188           0 :         if( 1 == aInsStr.Len() && 1 == aDelStr.Len() )
     189           0 :             pACEWord->CheckChar( *pAktPam->GetPoint(), aDelStr.GetChar( 0 ) );
     190           0 :         pDoc->SetAutoCorrExceptWord( 0 );
     191             :     }
     192             : 
     193             :     // If there was not only a overwrite but also an insert, delete the surplus
     194           0 :     if( aInsStr.Len() > aDelStr.Len() )
     195             :     {
     196           0 :         rIdx += aDelStr.Len();
     197           0 :         pTxtNd->EraseText( rIdx, aInsStr.Len() - aDelStr.Len() );
     198           0 :         rIdx = nSttCntnt;
     199             :     }
     200             : 
     201           0 :     if( aDelStr.Len() )
     202             :     {
     203           0 :         String aTmpStr = OUString('1');
     204           0 :         sal_Unicode* pTmpStr = aTmpStr.GetBufferAccess();
     205             : 
     206           0 :         bool bOldExpFlg = pTxtNd->IsIgnoreDontExpand();
     207           0 :         pTxtNd->SetIgnoreDontExpand( true );
     208             : 
     209           0 :         ++rIdx;
     210           0 :         for( xub_StrLen n = 0; n < aDelStr.Len(); n++  )
     211             :         {
     212             :             // do it individually, to keep the attributes!
     213           0 :             *pTmpStr = aDelStr.GetChar( n );
     214           0 :             OUString const ins( pTxtNd->InsertText(aTmpStr, rIdx) );
     215             :             assert(ins.getLength() == 1); // cannot fail
     216           0 :             rIdx -= 2;
     217           0 :             pTxtNd->EraseText( rIdx, 1 );
     218           0 :             rIdx += 2;
     219           0 :         }
     220           0 :         pTxtNd->SetIgnoreDontExpand( bOldExpFlg );
     221           0 :         rIdx--;
     222             :     }
     223             : 
     224           0 :     if( pHistory )
     225             :     {
     226           0 :         if( pTxtNd->GetpSwpHints() )
     227           0 :             pTxtNd->ClearSwpHintsArr( false );
     228           0 :         pHistory->TmpRollback( pDoc, 0, false );
     229             :     }
     230             : 
     231           0 :     if( pAktPam->GetMark()->nContent.GetIndex() != nSttCntnt )
     232             :     {
     233           0 :         pAktPam->SetMark();
     234           0 :         pAktPam->GetMark()->nContent = nSttCntnt;
     235             :     }
     236             : 
     237           0 :     if( pRedlSaveData )
     238           0 :         SetSaveData( *pDoc, *pRedlSaveData );
     239           0 : }
     240             : 
     241           0 : void SwUndoOverwrite::RepeatImpl(::sw::RepeatContext & rContext)
     242             : {
     243           0 :     SwPaM *const pAktPam = & rContext.GetRepeatPaM();
     244           0 :     if( !aInsStr.Len() || pAktPam->HasMark() )
     245           0 :         return;
     246             : 
     247           0 :     SwDoc & rDoc = rContext.GetDoc();
     248             : 
     249             :     {
     250           0 :         ::sw::GroupUndoGuard const undoGuard(rDoc.GetIDocumentUndoRedo());
     251           0 :         rDoc.Overwrite(*pAktPam, OUString(aInsStr.GetChar(0)));
     252             :     }
     253           0 :     for( xub_StrLen n = 1; n < aInsStr.Len(); ++n )
     254           0 :         rDoc.Overwrite( *pAktPam, OUString(aInsStr.GetChar(n)) );
     255             : }
     256             : 
     257           0 : void SwUndoOverwrite::RedoImpl(::sw::UndoRedoContext & rContext)
     258             : {
     259           0 :     SwDoc *const pDoc = & rContext.GetDoc();
     260           0 :     SwPaM *const pAktPam(& rContext.GetCursorSupplier().CreateNewShellCursor());
     261             : 
     262           0 :     pAktPam->DeleteMark();
     263           0 :     pAktPam->GetPoint()->nNode = nSttNode;
     264           0 :     SwTxtNode* pTxtNd = pAktPam->GetNode()->GetTxtNode();
     265             :     OSL_ENSURE( pTxtNd, "Overwrite not in TextNode?" );
     266           0 :     SwIndex& rIdx = pAktPam->GetPoint()->nContent;
     267             : 
     268           0 :     if( pRedlSaveData )
     269             :     {
     270           0 :         rIdx.Assign( pTxtNd, nSttCntnt );
     271           0 :         pAktPam->SetMark();
     272           0 :         pAktPam->GetMark()->nContent += aInsStr.Len();
     273           0 :         pDoc->DeleteRedline( *pAktPam, false, USHRT_MAX );
     274           0 :         pAktPam->DeleteMark();
     275             :     }
     276           0 :     rIdx.Assign( pTxtNd, aDelStr.Len() ? nSttCntnt+1 : nSttCntnt );
     277             : 
     278           0 :     bool bOldExpFlg = pTxtNd->IsIgnoreDontExpand();
     279           0 :     pTxtNd->SetIgnoreDontExpand( true );
     280             : 
     281           0 :     for( xub_StrLen n = 0; n < aInsStr.Len(); n++  )
     282             :     {
     283             :         // do it individually, to keep the attributes!
     284             :         OUString const ins(
     285           0 :                 pTxtNd->InsertText( OUString(aInsStr.GetChar(n)), rIdx,
     286           0 :                 IDocumentContentOperations::INS_EMPTYEXPAND) );
     287             :         assert(ins.getLength() == 1); // cannot fail
     288           0 :         if( n < aDelStr.Len() )
     289             :         {
     290           0 :             rIdx -= 2;
     291           0 :             pTxtNd->EraseText( rIdx, 1 );
     292           0 :             rIdx += n+1 < aDelStr.Len() ? 2 : 1;
     293             :         }
     294           0 :     }
     295           0 :     pTxtNd->SetIgnoreDontExpand( bOldExpFlg );
     296             : 
     297             :     // get back old start position from UndoNodes array
     298           0 :     if( pHistory )
     299           0 :         pHistory->SetTmpEnd( pHistory->Count() );
     300           0 :     if( pAktPam->GetMark()->nContent.GetIndex() != nSttCntnt )
     301             :     {
     302           0 :         pAktPam->SetMark();
     303           0 :         pAktPam->GetMark()->nContent = nSttCntnt;
     304             :     }
     305           0 : }
     306             : 
     307           0 : SwRewriter SwUndoOverwrite::GetRewriter() const
     308             : {
     309           0 :     SwRewriter aResult;
     310             : 
     311           0 :     String aString;
     312             : 
     313           0 :     aString += String(SW_RES(STR_START_QUOTE));
     314           0 :     aString += ShortenString(aInsStr, nUndoStringLength,
     315           0 :                              String(SW_RES(STR_LDOTS)));
     316           0 :     aString += String(SW_RES(STR_END_QUOTE));
     317             : 
     318           0 :     aResult.AddRule(UndoArg1, aString);
     319             : 
     320           0 :     return aResult;
     321             : }
     322             : 
     323             : struct _UndoTransliterate_Data
     324             : {
     325             :     String          sText;
     326             :     SwHistory*      pHistory;
     327             :     Sequence< sal_Int32 >*  pOffsets;
     328             :     sal_uLong           nNdIdx;
     329             :     xub_StrLen      nStart, nLen;
     330             : 
     331           0 :     _UndoTransliterate_Data( sal_uLong nNd, xub_StrLen nStt, xub_StrLen nStrLen, const String& rTxt )
     332             :         : sText( rTxt ), pHistory( 0 ), pOffsets( 0 ),
     333           0 :         nNdIdx( nNd ), nStart( nStt ), nLen( nStrLen )
     334           0 :     {}
     335           0 :     ~_UndoTransliterate_Data() { delete pOffsets; delete pHistory; }
     336             : 
     337             :     void SetChangeAtNode( SwDoc& rDoc );
     338             : };
     339             : 
     340           0 : SwUndoTransliterate::SwUndoTransliterate(
     341             :     const SwPaM& rPam,
     342             :     const utl::TransliterationWrapper& rTrans )
     343           0 :     : SwUndo( UNDO_TRANSLITERATE ), SwUndRng( rPam ), nType( rTrans.getType() )
     344             : {
     345           0 : }
     346             : 
     347           0 : SwUndoTransliterate::~SwUndoTransliterate()
     348             : {
     349           0 :     for (size_t i = 0; i < aChanges.size();  ++i)
     350           0 :         delete aChanges[i];
     351           0 : }
     352             : 
     353           0 : void SwUndoTransliterate::UndoImpl(::sw::UndoRedoContext & rContext)
     354             : {
     355           0 :     SwDoc & rDoc = rContext.GetDoc();
     356             : 
     357             :     // since the changes were added to the vector from the end of the string/node towards
     358             :     // the start, we need to revert them from the start towards the end now to keep the
     359             :     // offset information of the undo data in sync with the changing text.
     360             :     // Thus we need to iterate from the end of the vector to the start
     361           0 :     for (sal_Int32 i = aChanges.size() - 1; i >= 0;  --i)
     362           0 :         aChanges[i]->SetChangeAtNode( rDoc );
     363             : 
     364           0 :     AddUndoRedoPaM(rContext, true);
     365           0 : }
     366             : 
     367           0 : void SwUndoTransliterate::RedoImpl(::sw::UndoRedoContext & rContext)
     368             : {
     369           0 :     SwPaM & rPam( AddUndoRedoPaM(rContext) );
     370           0 :     DoTransliterate(rContext.GetDoc(), rPam);
     371           0 : }
     372             : 
     373           0 : void SwUndoTransliterate::RepeatImpl(::sw::RepeatContext & rContext)
     374             : {
     375           0 :     DoTransliterate(rContext.GetDoc(), rContext.GetRepeatPaM());
     376           0 : }
     377             : 
     378           0 : void SwUndoTransliterate::DoTransliterate(SwDoc & rDoc, SwPaM & rPam)
     379             : {
     380           0 :     utl::TransliterationWrapper aTrans( ::comphelper::getProcessComponentContext(), nType );
     381           0 :     rDoc.TransliterateText( rPam, aTrans );
     382           0 : }
     383             : 
     384           0 : void SwUndoTransliterate::AddChanges( SwTxtNode& rTNd,
     385             :                     xub_StrLen nStart, xub_StrLen nLen,
     386             :                     uno::Sequence <sal_Int32>& rOffsets )
     387             : {
     388           0 :     long nOffsLen = rOffsets.getLength();
     389             :     _UndoTransliterate_Data* pNew = new _UndoTransliterate_Data(
     390           0 :                         rTNd.GetIndex(), nStart, (xub_StrLen)nOffsLen,
     391           0 :                         rTNd.GetTxt().copy(nStart, nLen));
     392             : 
     393           0 :     aChanges.push_back( pNew );
     394             : 
     395           0 :     const sal_Int32* pOffsets = rOffsets.getConstArray();
     396             :     // where did we need less memory ?
     397           0 :     const sal_Int32* p = pOffsets;
     398           0 :     for( long n = 0; n < nOffsLen; ++n, ++p )
     399           0 :     if( *p != ( nStart + n ))
     400             :     {
     401             :         // create the Offset array
     402           0 :         pNew->pOffsets = new Sequence <sal_Int32> ( nLen );
     403           0 :         sal_Int32* pIdx = pNew->pOffsets->getArray();
     404           0 :         p = pOffsets;
     405           0 :         long nMyOff, nNewVal = nStart;
     406           0 :         for( n = 0, nMyOff = nStart; n < nOffsLen; ++p, ++n, ++nMyOff )
     407             :         {
     408           0 :             if( *p < nMyOff )
     409             :             {
     410             :                 // something is deleted
     411           0 :                 nMyOff = *p;
     412           0 :                 *(pIdx-1) = nNewVal++;
     413             :             }
     414           0 :             else if( *p > nMyOff )
     415             :             {
     416           0 :                 for( ; *p > nMyOff; ++nMyOff )
     417           0 :                     *pIdx++ = nNewVal;
     418           0 :                 --nMyOff;
     419           0 :                 --n;
     420           0 :                 --p;
     421             :             }
     422             :             else
     423           0 :                 *pIdx++ = nNewVal++;
     424             :         }
     425             : 
     426             :         // and then we need to save the attributes/bookmarks
     427             :         // but this data must moved every time to the last in the chain!
     428           0 :         for (size_t i = 0; i + 1 < aChanges.size(); ++i)    // check all changes but not the current one
     429             :         {
     430           0 :             _UndoTransliterate_Data* pD = aChanges[i];
     431           0 :             if( pD->nNdIdx == pNew->nNdIdx && pD->pHistory )
     432             :             {
     433             :                 // same node and have a history?
     434           0 :                 pNew->pHistory = pD->pHistory;
     435           0 :                 pD->pHistory = 0;
     436           0 :                 break;          // more can't exist
     437             :             }
     438             :         }
     439             : 
     440           0 :         if( !pNew->pHistory )
     441             :         {
     442           0 :             pNew->pHistory = new SwHistory;
     443           0 :             SwRegHistory aRHst( rTNd, pNew->pHistory );
     444             :             pNew->pHistory->CopyAttr( rTNd.GetpSwpHints(),
     445           0 :                     pNew->nNdIdx, 0, rTNd.GetTxt().getLength(), false );
     446             :         }
     447           0 :         break;
     448             :     }
     449           0 : }
     450             : 
     451           0 : void _UndoTransliterate_Data::SetChangeAtNode( SwDoc& rDoc )
     452             : {
     453           0 :     SwTxtNode* pTNd = rDoc.GetNodes()[ nNdIdx ]->GetTxtNode();
     454           0 :     if( pTNd )
     455             :     {
     456           0 :         Sequence <sal_Int32> aOffsets( pOffsets ? pOffsets->getLength() : nLen );
     457           0 :         if( pOffsets )
     458           0 :             aOffsets = *pOffsets;
     459             :         else
     460             :         {
     461           0 :             sal_Int32* p = aOffsets.getArray();
     462           0 :             for( xub_StrLen n = 0; n < nLen; ++n, ++p )
     463           0 :                 *p = n + nStart;
     464             :         }
     465           0 :         pTNd->ReplaceTextOnly( nStart, nLen, sText, aOffsets );
     466             : 
     467           0 :         if( pHistory )
     468             :         {
     469           0 :             if( pTNd->GetpSwpHints() )
     470           0 :                 pTNd->ClearSwpHintsArr( false );
     471           0 :             pHistory->TmpRollback( &rDoc, 0, false );
     472           0 :             pHistory->SetTmpEnd( pHistory->Count() );
     473           0 :         }
     474             :     }
     475          99 : }
     476             : 
     477             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10