LCOV - code coverage report
Current view: top level - vcl/source/edit - textdoc.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 305 0.0 %
Date: 2014-04-14 Functions: 0 36 0.0 %
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 <textdoc.hxx>
      21             : #include <stdlib.h>
      22             : 
      23             : // compare function called by QuickSort
      24           0 : static bool CompareStart( const TextCharAttrib* pFirst, const TextCharAttrib* pSecond )
      25             : {
      26           0 :     return pFirst->GetStart() < pSecond->GetStart();
      27             : }
      28             : 
      29           0 : TextCharAttrib::TextCharAttrib( const TextAttrib& rAttr, sal_uInt16 nStart, sal_uInt16 nEnd )
      30             : {
      31           0 :     mpAttr = rAttr.Clone();
      32             :     mnStart = nStart,
      33           0 :     mnEnd = nEnd;
      34           0 : }
      35             : 
      36           0 : TextCharAttrib::TextCharAttrib( const TextCharAttrib& rTextCharAttrib )
      37             : {
      38           0 :     mpAttr = rTextCharAttrib.GetAttr().Clone();
      39           0 :     mnStart = rTextCharAttrib.mnStart;
      40           0 :     mnEnd = rTextCharAttrib.mnEnd;
      41           0 : }
      42             : 
      43           0 : TextCharAttrib::~TextCharAttrib()
      44             : {
      45           0 :     delete mpAttr;
      46           0 : }
      47             : 
      48           0 : TextCharAttribList::TextCharAttribList()
      49             : {
      50           0 :     mbHasEmptyAttribs = false;
      51           0 : }
      52             : 
      53           0 : TextCharAttribList::~TextCharAttribList()
      54             : {
      55             :     // PTRARR_DEL
      56           0 : }
      57             : 
      58           0 : void TextCharAttribList::Clear( bool bDestroyAttribs )
      59             : {
      60           0 :     if ( bDestroyAttribs )
      61           0 :         for(iterator it = begin(); it != end(); ++it)
      62           0 :             delete *it;
      63           0 :     TextCharAttribs::clear();
      64           0 : }
      65             : 
      66           0 : void TextCharAttribList::InsertAttrib( TextCharAttrib* pAttrib )
      67             : {
      68           0 :     if ( pAttrib->IsEmpty() )
      69           0 :         mbHasEmptyAttribs = true;
      70             : 
      71           0 :     const sal_uInt16 nCount = size();
      72           0 :     const sal_uInt16 nStart = pAttrib->GetStart(); // maybe better for Comp.Opt.
      73           0 :     bool bInserted = false;
      74           0 :     for ( sal_uInt16 x = 0; x < nCount; x++ )
      75             :     {
      76           0 :         TextCharAttrib* pCurAttrib = GetAttrib( x );
      77           0 :         if ( pCurAttrib->GetStart() > nStart )
      78             :         {
      79           0 :             insert( begin() + x, pAttrib );
      80           0 :             bInserted = true;
      81           0 :             break;
      82             :         }
      83             :     }
      84           0 :     if ( !bInserted )
      85           0 :         push_back( pAttrib );
      86           0 : }
      87             : 
      88           0 : void TextCharAttribList::ResortAttribs()
      89             : {
      90           0 :     if ( !empty() )
      91           0 :         std::sort( begin(), end(), CompareStart );
      92           0 : }
      93             : 
      94           0 : TextCharAttrib* TextCharAttribList::FindAttrib( sal_uInt16 nWhich, sal_uInt16 nPos )
      95             : {
      96             :     // backwards; if one ends there and the next starts there
      97             :     // ==> the starting one counts
      98           0 :     for ( sal_uInt16 nAttr = size(); nAttr; )
      99             :     {
     100           0 :         TextCharAttrib* pAttr = GetAttrib( --nAttr );
     101             : 
     102           0 :         if ( pAttr->GetEnd() < nPos )
     103           0 :             return 0;
     104             : 
     105           0 :         if ( ( pAttr->Which() == nWhich ) && pAttr->IsIn(nPos) )
     106           0 :             return pAttr;
     107             :     }
     108           0 :     return NULL;
     109             : }
     110             : 
     111           0 : TextCharAttrib* TextCharAttribList::FindNextAttrib( sal_uInt16 nWhich, sal_uInt16 nFromPos, sal_uInt16 nMaxPos ) const
     112             : {
     113             :     DBG_ASSERT( nWhich, "FindNextAttrib: Which?" );
     114           0 :     const sal_uInt16 nAttribs = size();
     115           0 :     for ( sal_uInt16 nAttr = 0; nAttr < nAttribs; nAttr++ )
     116             :     {
     117           0 :         TextCharAttrib* pAttr = GetAttrib( nAttr );
     118           0 :         if ( ( pAttr->GetStart() >= nFromPos ) &&
     119           0 :              ( pAttr->GetEnd() <= nMaxPos ) &&
     120           0 :              ( pAttr->Which() == nWhich ) )
     121           0 :             return pAttr;
     122             :     }
     123           0 :     return NULL;
     124             : }
     125             : 
     126           0 : bool TextCharAttribList::HasAttrib( sal_uInt16 nWhich ) const
     127             : {
     128           0 :     for ( sal_uInt16 nAttr = size(); nAttr; )
     129             :     {
     130           0 :         const TextCharAttrib* pAttr = GetAttrib( --nAttr );
     131           0 :         if ( pAttr->Which() == nWhich )
     132           0 :             return true;
     133             :     }
     134           0 :     return false;
     135             : }
     136             : 
     137           0 : bool TextCharAttribList::HasBoundingAttrib( sal_uInt16 nBound )
     138             : {
     139             :     // backwards; if one ends there and the next starts there
     140             :     // ==> the starting one counts
     141           0 :     for ( sal_uInt16 nAttr = size(); nAttr; )
     142             :     {
     143           0 :         TextCharAttrib* pAttr = GetAttrib( --nAttr );
     144             : 
     145           0 :         if ( pAttr->GetEnd() < nBound )
     146           0 :             return false;
     147             : 
     148           0 :         if ( ( pAttr->GetStart() == nBound ) || ( pAttr->GetEnd() == nBound ) )
     149           0 :             return true;
     150             :     }
     151           0 :     return false;
     152             : }
     153             : 
     154           0 : TextCharAttrib* TextCharAttribList::FindEmptyAttrib( sal_uInt16 nWhich, sal_uInt16 nPos )
     155             : {
     156           0 :     if ( !mbHasEmptyAttribs )
     157           0 :         return 0;
     158             : 
     159           0 :     const sal_uInt16 nAttribs = size();
     160           0 :     for ( sal_uInt16 nAttr = 0; nAttr < nAttribs; nAttr++ )
     161             :     {
     162           0 :         TextCharAttrib* pAttr = GetAttrib( nAttr );
     163           0 :         if ( pAttr->GetStart() > nPos )
     164           0 :             return 0;
     165             : 
     166           0 :         if ( ( pAttr->GetStart() == nPos ) && ( pAttr->GetEnd() == nPos ) && ( pAttr->Which() == nWhich ) )
     167           0 :             return pAttr;
     168             :     }
     169           0 :     return 0;
     170             : }
     171             : 
     172           0 : void TextCharAttribList::DeleteEmptyAttribs()
     173             : {
     174           0 :     for ( sal_uInt16 nAttr = 0; nAttr < size(); nAttr++ )
     175             :     {
     176           0 :         TextCharAttrib* pAttr = GetAttrib( nAttr );
     177           0 :         if ( pAttr->IsEmpty() )
     178             :         {
     179           0 :             erase( begin() + nAttr );
     180           0 :             delete pAttr;
     181           0 :             nAttr--;
     182             :         }
     183             :     }
     184           0 :     mbHasEmptyAttribs = false;
     185           0 : }
     186             : 
     187           0 : TextNode::TextNode( const OUString& rText ) :
     188           0 :     maText( rText )
     189             : {
     190           0 : }
     191             : 
     192           0 : void TextNode::ExpandAttribs( sal_uInt16 nIndex, sal_uInt16 nNew )
     193             : {
     194           0 :     if ( !nNew )
     195           0 :         return;
     196             : 
     197           0 :     bool bResort = false;
     198           0 :     sal_uInt16 nAttribs = maCharAttribs.Count();
     199           0 :     for ( sal_uInt16 nAttr = 0; nAttr < nAttribs; nAttr++ )
     200             :     {
     201           0 :         TextCharAttrib* pAttrib = maCharAttribs.GetAttrib( nAttr );
     202           0 :         if ( pAttrib->GetEnd() >= nIndex )
     203             :         {
     204             :             // move all attributes that are behind the cursor
     205           0 :             if ( pAttrib->GetStart() > nIndex )
     206             :             {
     207           0 :                 pAttrib->MoveForward( nNew );
     208             :             }
     209             :             // 0: expand empty attribute, if at cursor
     210           0 :             else if ( pAttrib->IsEmpty() )
     211             :             {
     212             :                 // Do not check the index; empty one may only be here.
     213             :                 // If checking later anyway, special case:
     214             :                 // Start == 0; AbsLen == 1, nNew = 1 => Expand due to new paragraph!
     215             :                 // Start <= nIndex, End >= nIndex => Start=End=nIndex!
     216           0 :                 pAttrib->Expand( nNew );
     217             :             }
     218             :             // 1: attribute starts before and reaches up to index
     219           0 :             else if ( pAttrib->GetEnd() == nIndex ) // start must be before
     220             :             {
     221             :                 // Only expand if no feature and not in Exclude list!
     222             :                 // Otherwise e.g. an UL would go until the new ULDB, thus expand both.
     223           0 :                 if ( !maCharAttribs.FindEmptyAttrib( pAttrib->Which(), nIndex ) )
     224             :                 {
     225           0 :                     pAttrib->Expand( nNew );
     226             :                 }
     227             :                 else
     228           0 :                     bResort = true;
     229             :             }
     230             :             // 2: attribute starts before and reaches past the index
     231           0 :             else if ( ( pAttrib->GetStart() < nIndex ) && ( pAttrib->GetEnd() > nIndex ) )
     232             :             {
     233           0 :                 pAttrib->Expand( nNew );
     234             :             }
     235             :             // 3: attribute starts at Index
     236           0 :             else if ( pAttrib->GetStart() == nIndex )
     237             :             {
     238           0 :                 if ( nIndex == 0 )
     239             :                 {
     240           0 :                     pAttrib->Expand( nNew );
     241             :                 }
     242             :                 else
     243           0 :                     pAttrib->MoveForward( nNew );
     244             :             }
     245             :         }
     246             : 
     247             :         DBG_ASSERT( pAttrib->GetStart() <= pAttrib->GetEnd(), "Expand: Attribut verdreht!" );
     248             :         DBG_ASSERT( ( pAttrib->GetEnd() <= maText.getLength() ), "Expand: Attrib groesser als Absatz!" );
     249             :         DBG_ASSERT( !pAttrib->IsEmpty(), "Leeres Attribut nach ExpandAttribs?" );
     250             :     }
     251             : 
     252           0 :     if ( bResort )
     253           0 :         maCharAttribs.ResortAttribs();
     254             : }
     255             : 
     256           0 : void TextNode::CollapsAttribs( sal_uInt16 nIndex, sal_uInt16 nDeleted )
     257             : {
     258           0 :     if ( !nDeleted )
     259           0 :         return;
     260             : 
     261           0 :     bool bResort = false;
     262           0 :     sal_uInt16 nEndChanges = nIndex+nDeleted;
     263             : 
     264           0 :     for ( sal_uInt16 nAttr = 0; nAttr < maCharAttribs.Count(); nAttr++ )
     265             :     {
     266           0 :         TextCharAttrib* pAttrib = maCharAttribs.GetAttrib( nAttr );
     267           0 :         bool bDelAttr = false;
     268           0 :         if ( pAttrib->GetEnd() >= nIndex )
     269             :         {
     270             :             // move all attributes that are behind the cursor
     271           0 :             if ( pAttrib->GetStart() >= nEndChanges )
     272             :             {
     273           0 :                 pAttrib->MoveBackward( nDeleted );
     274             :             }
     275             :             // 1. delete inner attributes
     276           0 :             else if ( ( pAttrib->GetStart() >= nIndex ) && ( pAttrib->GetEnd() <= nEndChanges ) )
     277             :             {
     278             :                 // special case: attribute covers the region exactly
     279             :                 // => keep as an empty attribute
     280           0 :                 if ( ( pAttrib->GetStart() == nIndex ) && ( pAttrib->GetEnd() == nEndChanges ) )
     281           0 :                     pAttrib->GetEnd() = nIndex; // empty
     282             :                 else
     283           0 :                     bDelAttr = true;
     284             :             }
     285             :             // 2. attribute starts before, ends inside or after
     286           0 :             else if ( ( pAttrib->GetStart() <= nIndex ) && ( pAttrib->GetEnd() > nIndex ) )
     287             :             {
     288           0 :                 if ( pAttrib->GetEnd() <= nEndChanges ) // ends inside
     289           0 :                     pAttrib->GetEnd() = nIndex;
     290             :                 else
     291           0 :                     pAttrib->Collaps( nDeleted );       // ends after
     292             :             }
     293             :             // 3. attribute starts inside, ends after
     294           0 :             else if ( ( pAttrib->GetStart() >= nIndex ) && ( pAttrib->GetEnd() > nEndChanges ) )
     295             :             {
     296             :                 // features are not allowed to expand!
     297           0 :                 pAttrib->GetStart() = nEndChanges;
     298           0 :                 pAttrib->MoveBackward( nDeleted );
     299             :             }
     300             :         }
     301             : 
     302             :         DBG_ASSERT( pAttrib->GetStart() <= pAttrib->GetEnd(), "Collaps: Attribut verdreht!" );
     303             :         DBG_ASSERT( ( pAttrib->GetEnd() <= maText.getLength()) || bDelAttr, "Collaps: Attrib groesser als Absatz!" );
     304           0 :         if ( bDelAttr /* || pAttrib->IsEmpty() */ )
     305             :         {
     306           0 :             bResort = true;
     307           0 :             maCharAttribs.RemoveAttrib( nAttr );
     308           0 :             delete pAttrib;
     309           0 :             nAttr--;
     310             :         }
     311           0 :         else if ( pAttrib->IsEmpty() )
     312           0 :             maCharAttribs.HasEmptyAttribs() = true;
     313             :     }
     314             : 
     315           0 :     if ( bResort )
     316           0 :         maCharAttribs.ResortAttribs();
     317             : }
     318             : 
     319           0 : void TextNode::InsertText( sal_uInt16 nPos, const OUString& rText )
     320             : {
     321           0 :     maText = maText.replaceAt( nPos, 0, rText );
     322           0 :     ExpandAttribs( nPos, rText.getLength() );
     323           0 : }
     324             : 
     325           0 : void TextNode::InsertText( sal_uInt16 nPos, sal_Unicode c )
     326             : {
     327           0 :     maText = maText.replaceAt( nPos, 0, OUString(c) );
     328           0 :     ExpandAttribs( nPos, 1 );
     329           0 : }
     330             : 
     331           0 : void TextNode::RemoveText( sal_uInt16 nPos, sal_uInt16 nChars )
     332             : {
     333           0 :     maText = maText.replaceAt( nPos, nChars, "" );
     334           0 :     CollapsAttribs( nPos, nChars );
     335           0 : }
     336             : 
     337           0 : TextNode* TextNode::Split( sal_uInt16 nPos, bool bKeepEndingAttribs )
     338             : {
     339           0 :     OUString aNewText;
     340           0 :     if ( nPos < maText.getLength() )
     341             :     {
     342           0 :         aNewText = maText.copy( nPos );
     343           0 :         maText = maText.copy(0, nPos);
     344             :     }
     345           0 :     TextNode* pNew = new TextNode( aNewText );
     346             : 
     347           0 :     for ( sal_uInt16 nAttr = 0; nAttr < maCharAttribs.Count(); nAttr++ )
     348             :     {
     349           0 :         TextCharAttrib* pAttrib = maCharAttribs.GetAttrib( nAttr );
     350           0 :         if ( pAttrib->GetEnd() < nPos )
     351             :         {
     352             :             // no change
     353             :             ;
     354             :         }
     355           0 :         else if ( pAttrib->GetEnd() == nPos )
     356             :         {
     357             :             // must be copied as an empty attribute
     358             :             // !FindAttrib only sensible if traversing backwards through the list!
     359           0 :             if ( bKeepEndingAttribs && !pNew->maCharAttribs.FindAttrib( pAttrib->Which(), 0 ) )
     360             :             {
     361           0 :                 TextCharAttrib* pNewAttrib = new TextCharAttrib( *pAttrib );
     362           0 :                 pNewAttrib->GetStart() = 0;
     363           0 :                 pNewAttrib->GetEnd() = 0;
     364           0 :                 pNew->maCharAttribs.InsertAttrib( pNewAttrib );
     365             :             }
     366             :         }
     367           0 :         else if ( pAttrib->IsInside( nPos ) || ( !nPos && !pAttrib->GetStart() ) )
     368             :         {
     369             :             // If cutting at the very beginning, the attribute has to be
     370             :             // copied and changed
     371           0 :             TextCharAttrib* pNewAttrib = new TextCharAttrib( *pAttrib );
     372           0 :             pNewAttrib->GetStart() = 0;
     373           0 :             pNewAttrib->GetEnd() = pAttrib->GetEnd()-nPos;
     374           0 :             pNew->maCharAttribs.InsertAttrib( pNewAttrib );
     375             :             // trim
     376           0 :             pAttrib->GetEnd() = nPos;
     377             :         }
     378             :         else
     379             :         {
     380             :             DBG_ASSERT( pAttrib->GetStart() >= nPos, "Start < nPos!" );
     381             :             DBG_ASSERT( pAttrib->GetEnd() >= nPos, "End < nPos!" );
     382             :             // move all into the new node (this)
     383           0 :             maCharAttribs.RemoveAttrib( nAttr );
     384           0 :             pNew->maCharAttribs.InsertAttrib( pAttrib );
     385           0 :             pAttrib->GetStart() = pAttrib->GetStart() - nPos;
     386           0 :             pAttrib->GetEnd() = pAttrib->GetEnd() - nPos;
     387           0 :             nAttr--;
     388             :         }
     389             :     }
     390           0 :     return pNew;
     391             : }
     392             : 
     393           0 : void TextNode::Append( const TextNode& rNode )
     394             : {
     395           0 :     sal_Int32 nOldLen = maText.getLength();
     396             : 
     397           0 :     maText += rNode.GetText();
     398             : 
     399           0 :     const sal_uInt16 nAttribs = rNode.GetCharAttribs().Count();
     400           0 :     for ( sal_uInt16 nAttr = 0; nAttr < nAttribs; nAttr++ )
     401             :     {
     402           0 :         TextCharAttrib* pAttrib = rNode.GetCharAttribs().GetAttrib( nAttr );
     403           0 :         bool bMelted = false;
     404           0 :         if ( pAttrib->GetStart() == 0 )
     405             :         {
     406             :             // potentially merge attributes
     407           0 :             sal_uInt16 nTmpAttribs = maCharAttribs.Count();
     408           0 :             for ( sal_uInt16 nTmpAttr = 0; nTmpAttr < nTmpAttribs; nTmpAttr++ )
     409             :             {
     410           0 :                 TextCharAttrib* pTmpAttrib = maCharAttribs.GetAttrib( nTmpAttr );
     411             : 
     412           0 :                 if ( pTmpAttrib->GetEnd() == nOldLen )
     413             :                 {
     414           0 :                     if ( ( pTmpAttrib->Which() == pAttrib->Which() ) &&
     415           0 :                          ( pTmpAttrib->GetAttr() == pAttrib->GetAttr() ) )
     416             :                     {
     417           0 :                         pTmpAttrib->GetEnd() =
     418           0 :                             pTmpAttrib->GetEnd() + pAttrib->GetLen();
     419           0 :                         bMelted = true;
     420           0 :                         break;  // there can be only one of this type at this position
     421             :                     }
     422             :                 }
     423             :             }
     424             :         }
     425             : 
     426           0 :         if ( !bMelted )
     427             :         {
     428           0 :             TextCharAttrib* pNewAttrib = new TextCharAttrib( *pAttrib );
     429           0 :             pNewAttrib->GetStart() = pNewAttrib->GetStart() + nOldLen;
     430           0 :             pNewAttrib->GetEnd() = pNewAttrib->GetEnd() + nOldLen;
     431           0 :             maCharAttribs.InsertAttrib( pNewAttrib );
     432             :         }
     433             :     }
     434           0 : }
     435             : 
     436           0 : TextDoc::TextDoc()
     437             : {
     438           0 :     mnLeftMargin = 0;
     439           0 : };
     440             : 
     441           0 : TextDoc::~TextDoc()
     442             : {
     443           0 :     DestroyTextNodes();
     444           0 : }
     445             : 
     446           0 : void TextDoc::Clear()
     447             : {
     448           0 :     DestroyTextNodes();
     449           0 : }
     450             : 
     451           0 : void TextDoc::DestroyTextNodes()
     452             : {
     453           0 :     for ( sal_uLong nNode = 0; nNode < maTextNodes.Count(); nNode++ )
     454           0 :         delete maTextNodes.GetObject( nNode );
     455           0 :     maTextNodes.clear();
     456           0 : }
     457             : 
     458           0 : OUString TextDoc::GetText( const sal_Unicode* pSep ) const
     459             : {
     460           0 :     sal_uLong nNodes = maTextNodes.Count();
     461             : 
     462           0 :     OUString aASCIIText;
     463           0 :     sal_uLong nLastNode = nNodes-1;
     464           0 :     for ( sal_uLong nNode = 0; nNode < nNodes; nNode++ )
     465             :     {
     466           0 :         TextNode* pNode = maTextNodes.GetObject( nNode );
     467           0 :         OUString aTmp( pNode->GetText() );
     468           0 :         aASCIIText += aTmp;
     469           0 :         if ( pSep && ( nNode != nLastNode ) )
     470           0 :             aASCIIText += pSep;
     471           0 :     }
     472             : 
     473           0 :     return aASCIIText;
     474             : }
     475             : 
     476           0 : OUString TextDoc::GetText( sal_uLong nPara ) const
     477             : {
     478           0 :     OUString aText;
     479             : 
     480           0 :     TextNode* pNode = ( nPara < maTextNodes.Count() ) ? maTextNodes.GetObject( nPara ) : 0;
     481           0 :     if ( pNode )
     482           0 :         aText = pNode->GetText();
     483             : 
     484           0 :     return aText;
     485             : }
     486             : 
     487           0 : sal_uLong TextDoc::GetTextLen( const sal_Unicode* pSep, const TextSelection* pSel ) const
     488             : {
     489           0 :     sal_uLong nLen = 0;
     490           0 :     sal_uLong nNodes = maTextNodes.Count();
     491           0 :     if ( nNodes )
     492             :     {
     493           0 :         sal_uLong nStartNode = 0;
     494           0 :         sal_uLong nEndNode = nNodes-1;
     495           0 :         if ( pSel )
     496             :         {
     497           0 :             nStartNode = pSel->GetStart().GetPara();
     498           0 :             nEndNode = pSel->GetEnd().GetPara();
     499             :         }
     500             : 
     501           0 :         for ( sal_uLong nNode = nStartNode; nNode <= nEndNode; nNode++ )
     502             :         {
     503           0 :             TextNode* pNode = maTextNodes.GetObject( nNode );
     504             : 
     505           0 :             sal_uInt16 nS = 0;
     506           0 :             sal_Int32 nE = pNode->GetText().getLength();
     507           0 :             if ( pSel && ( nNode == pSel->GetStart().GetPara() ) )
     508           0 :                 nS = pSel->GetStart().GetIndex();
     509           0 :             if ( pSel && ( nNode == pSel->GetEnd().GetPara() ) )
     510           0 :                 nE = pSel->GetEnd().GetIndex();
     511             : 
     512           0 :             nLen += ( nE - nS );
     513             :         }
     514             : 
     515           0 :         if ( pSep )
     516           0 :             nLen += (nEndNode-nStartNode) * rtl_ustr_getLength(pSep);
     517             :     }
     518             : 
     519           0 :     return nLen;
     520             : }
     521             : 
     522           0 : TextPaM TextDoc::InsertText( const TextPaM& rPaM, sal_Unicode c )
     523             : {
     524             :     DBG_ASSERT( c != 0x0A, "TextDoc::InsertText: Zeilentrenner in Absatz nicht erlaubt!" );
     525             :     DBG_ASSERT( c != 0x0D, "TextDoc::InsertText: Zeilentrenner in Absatz nicht erlaubt!" );
     526             : 
     527           0 :     TextNode* pNode = maTextNodes.GetObject( rPaM.GetPara() );
     528           0 :     pNode->InsertText( rPaM.GetIndex(), c );
     529             : 
     530           0 :     TextPaM aPaM( rPaM.GetPara(), rPaM.GetIndex()+1 );
     531           0 :     return aPaM;
     532             : }
     533             : 
     534           0 : TextPaM TextDoc::InsertText( const TextPaM& rPaM, const OUString& rStr )
     535             : {
     536             :     DBG_ASSERT( rStr.indexOf( 0x0A ) == -1, "TextDoc::InsertText: Zeilentrenner in Absatz nicht erlaubt!" );
     537             :     DBG_ASSERT( rStr.indexOf( 0x0D ) == -1, "TextDoc::InsertText: Zeilentrenner in Absatz nicht erlaubt!" );
     538             : 
     539           0 :     TextNode* pNode = maTextNodes.GetObject( rPaM.GetPara() );
     540           0 :     pNode->InsertText( rPaM.GetIndex(), rStr );
     541             : 
     542           0 :     TextPaM aPaM( rPaM.GetPara(), rPaM.GetIndex()+rStr.getLength() );
     543           0 :     return aPaM;
     544             : }
     545             : 
     546           0 : TextPaM TextDoc::InsertParaBreak( const TextPaM& rPaM, bool bKeepEndingAttribs )
     547             : {
     548           0 :     TextNode* pNode = maTextNodes.GetObject( rPaM.GetPara() );
     549           0 :     TextNode* pNew = pNode->Split( rPaM.GetIndex(), bKeepEndingAttribs );
     550             : 
     551           0 :     maTextNodes.Insert( pNew, rPaM.GetPara()+1 );
     552             : 
     553           0 :     TextPaM aPaM( rPaM.GetPara()+1, 0 );
     554           0 :     return aPaM;
     555             : }
     556             : 
     557           0 : TextPaM TextDoc::ConnectParagraphs( TextNode* pLeft, TextNode* pRight )
     558             : {
     559           0 :     sal_Int32 nPrevLen = pLeft->GetText().getLength();
     560           0 :     pLeft->Append( *pRight );
     561             : 
     562             :     // the paragraph on the right vanishes
     563           0 :     sal_uLong nRight = maTextNodes.GetPos( pRight );
     564           0 :     maTextNodes.Remove( nRight );
     565           0 :     delete pRight;
     566             : 
     567           0 :     sal_uLong nLeft = maTextNodes.GetPos( pLeft );
     568           0 :     TextPaM aPaM( nLeft, nPrevLen );
     569           0 :     return aPaM;
     570             : }
     571             : 
     572           0 : TextPaM TextDoc::RemoveChars( const TextPaM& rPaM, sal_uInt16 nChars )
     573             : {
     574           0 :     TextNode* pNode = maTextNodes.GetObject( rPaM.GetPara() );
     575           0 :     pNode->RemoveText( rPaM.GetIndex(), nChars );
     576             : 
     577           0 :     return rPaM;
     578             : }
     579             : 
     580           0 : bool TextDoc::IsValidPaM( const TextPaM& rPaM )
     581             : {
     582           0 :     if ( rPaM.GetPara() >= maTextNodes.Count() )
     583             :     {
     584             :         OSL_FAIL( "PaM: Para out of range" );
     585           0 :         return false;
     586             :     }
     587           0 :     TextNode * pNode = maTextNodes.GetObject( rPaM.GetPara() );
     588           0 :     if ( rPaM.GetIndex() > pNode->GetText().getLength() )
     589             :     {
     590             :         OSL_FAIL( "PaM: Index out of range" );
     591           0 :         return false;
     592             :     }
     593           0 :     return true;
     594             : }
     595             : 
     596             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10