LCOV - code coverage report
Current view: top level - libreoffice/sw/source/core/doc - docruby.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 148 0.0 %
Date: 2012-12-17 Functions: 0 4 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             : 
      21             : #include <string.h>         // for strchr()
      22             : 
      23             : #include <com/sun/star/i18n/UnicodeType.hpp>
      24             : #include <com/sun/star/i18n/WordType.hpp>
      25             : 
      26             : #include <unotools/charclass.hxx>
      27             : 
      28             : #include <hintids.hxx>
      29             : #include <doc.hxx>
      30             : #include <IDocumentUndoRedo.hxx>
      31             : #include <docary.hxx>
      32             : #include <mvsave.hxx>       // structures for Saving by Move/Delete
      33             : #include <ndtxt.hxx>
      34             : #include <txatbase.hxx>
      35             : #include <rubylist.hxx>
      36             : #include <pam.hxx>
      37             : #include <swundo.hxx>       // for the UndoIds
      38             : #include <breakit.hxx>
      39             : #include <crsskip.hxx>
      40             : 
      41             : using namespace ::com::sun::star::i18n;
      42             : 
      43             : 
      44             : /*
      45             :  * Members in the list:
      46             :  *   - String - the orig text
      47             :  *   - SwFmtRuby - the ruby attribut
      48             :  *
      49             :  *
      50             :  */
      51           0 : sal_uInt16 SwDoc::FillRubyList( const SwPaM& rPam, SwRubyList& rList,
      52             :                             sal_uInt16 nMode )
      53             : {
      54           0 :     const SwPaM *_pStartCrsr = (SwPaM*)rPam.GetNext(),
      55           0 :                 *__pStartCrsr = _pStartCrsr;
      56           0 :     bool bCheckEmpty = &rPam != _pStartCrsr;
      57           0 :     do {
      58           0 :         const SwPosition* pStt = _pStartCrsr->Start(),
      59           0 :                         * pEnd = pStt == _pStartCrsr->GetPoint()
      60             :                                                 ? _pStartCrsr->GetMark()
      61           0 :                                                 : _pStartCrsr->GetPoint();
      62           0 :         if( !bCheckEmpty || ( pStt != pEnd && *pStt != *pEnd ))
      63             :         {
      64           0 :             SwPaM aPam( *pStt );
      65           0 :             do {
      66           0 :                 SwRubyListEntry* pNew = new SwRubyListEntry;
      67           0 :                 if( pEnd != pStt )
      68             :                 {
      69           0 :                     aPam.SetMark();
      70           0 :                     *aPam.GetMark() = *pEnd;
      71             :                 }
      72           0 :                 if( _SelectNextRubyChars( aPam, *pNew, nMode ))
      73             :                 {
      74           0 :                     rList.push_back( pNew );
      75           0 :                     aPam.DeleteMark();
      76             :                 }
      77             :                 else
      78             :                 {
      79           0 :                     delete pNew;
      80           0 :                      if( *aPam.GetPoint() < *pEnd )
      81             :                      {
      82             :                         // goto next paragraph
      83           0 :                         aPam.DeleteMark();
      84           0 :                         aPam.Move( fnMoveForward, fnGoNode );
      85             :                      }
      86             :                      else
      87           0 :                         break;
      88             :                 }
      89           0 :             } while( 30 > rList.size() && *aPam.GetPoint() < *pEnd );
      90             :         }
      91           0 :     } while( 30 > rList.size() &&
      92           0 :         (_pStartCrsr=(SwPaM *)_pStartCrsr->GetNext()) != __pStartCrsr );
      93             : 
      94           0 :     return rList.size();
      95             : }
      96             : 
      97           0 : sal_uInt16 SwDoc::SetRubyList( const SwPaM& rPam, const SwRubyList& rList,
      98             :                             sal_uInt16 nMode )
      99             : {
     100           0 :     GetIDocumentUndoRedo().StartUndo( UNDO_SETRUBYATTR, NULL );
     101           0 :     std::set<sal_uInt16> aDelArr;
     102           0 :     aDelArr.insert( RES_TXTATR_CJK_RUBY );
     103             : 
     104           0 :     sal_uInt16 nListEntry = 0;
     105             : 
     106           0 :     const SwPaM *_pStartCrsr = (SwPaM*)rPam.GetNext(),
     107           0 :                 *__pStartCrsr = _pStartCrsr;
     108           0 :     bool bCheckEmpty = &rPam != _pStartCrsr;
     109           0 :     do {
     110           0 :         const SwPosition* pStt = _pStartCrsr->Start(),
     111           0 :                         * pEnd = pStt == _pStartCrsr->GetPoint()
     112             :                                                 ? _pStartCrsr->GetMark()
     113           0 :                                                 : _pStartCrsr->GetPoint();
     114           0 :         if( !bCheckEmpty || ( pStt != pEnd && *pStt != *pEnd ))
     115             :         {
     116             : 
     117           0 :             SwPaM aPam( *pStt );
     118           0 :             do {
     119           0 :                 SwRubyListEntry aCheckEntry;
     120           0 :                 if( pEnd != pStt )
     121             :                 {
     122           0 :                     aPam.SetMark();
     123           0 :                     *aPam.GetMark() = *pEnd;
     124             :                 }
     125           0 :                 if( _SelectNextRubyChars( aPam, aCheckEntry, nMode ))
     126             :                 {
     127           0 :                     const SwRubyListEntry* pEntry = &rList[ nListEntry++ ];
     128           0 :                     if( aCheckEntry.GetRubyAttr() != pEntry->GetRubyAttr() )
     129             :                     {
     130             :                         // set/reset the attribut
     131           0 :                         if( pEntry->GetRubyAttr().GetText().Len() )
     132             :                         {
     133           0 :                             InsertPoolItem( aPam, pEntry->GetRubyAttr(), 0 );
     134             :                         }
     135             :                         else
     136             :                         {
     137           0 :                             ResetAttrs( aPam, true, aDelArr );
     138             :                         }
     139             :                     }
     140             : 
     141           0 :                     if( aCheckEntry.GetText() != pEntry->GetText() &&
     142           0 :                         pEntry->GetText().Len() )
     143             :                     {
     144             :                         // text is changed, so replace the original
     145           0 :                         ReplaceRange( aPam, pEntry->GetText(), false );
     146             :                     }
     147           0 :                     aPam.DeleteMark();
     148             :                 }
     149             :                 else
     150             :                 {
     151           0 :                      if( *aPam.GetPoint() < *pEnd )
     152             :                      {
     153             :                         // goto next paragraph
     154           0 :                         aPam.DeleteMark();
     155           0 :                         aPam.Move( fnMoveForward, fnGoNode );
     156             :                      }
     157             :                      else
     158             :                     {
     159           0 :                         const SwRubyListEntry* pEntry = &rList[ nListEntry++ ];
     160             : 
     161             :                         // set/reset the attribut
     162           0 :                         if( pEntry->GetRubyAttr().GetText().Len() &&
     163           0 :                             pEntry->GetText().Len() )
     164             :                         {
     165           0 :                             InsertString( aPam, pEntry->GetText() );
     166           0 :                             aPam.SetMark();
     167           0 :                             aPam.GetMark()->nContent -= pEntry->GetText().Len();
     168           0 :                             InsertPoolItem( aPam, pEntry->GetRubyAttr(),
     169           0 :                                     nsSetAttrMode::SETATTR_DONTEXPAND );
     170             :                         }
     171             :                         else
     172             :                             break;
     173           0 :                         aPam.DeleteMark();
     174             :                     }
     175           0 :                 }
     176           0 :             } while( nListEntry < rList.size() && *aPam.GetPoint() < *pEnd );
     177             :         }
     178           0 :     } while( 30 > rList.size() &&
     179           0 :         (_pStartCrsr=(SwPaM *)_pStartCrsr->GetNext()) != __pStartCrsr );
     180             : 
     181           0 :     GetIDocumentUndoRedo().EndUndo( UNDO_SETRUBYATTR, NULL );
     182             : 
     183           0 :     return nListEntry;
     184             : }
     185             : 
     186           0 : sal_Bool SwDoc::_SelectNextRubyChars( SwPaM& rPam, SwRubyListEntry& rEntry, sal_uInt16 )
     187             : {
     188             :     // Point must be the startposition, Mark is optional the end position
     189           0 :     SwPosition* pPos = rPam.GetPoint();
     190           0 :        const SwTxtNode* pTNd = pPos->nNode.GetNode().GetTxtNode();
     191           0 :     const String* pTxt = &pTNd->GetTxt();
     192           0 :     xub_StrLen nStart = pPos->nContent.GetIndex(), nEnd = pTxt->Len();
     193             : 
     194           0 :     sal_Bool bHasMark = rPam.HasMark();
     195           0 :     if( bHasMark )
     196             :     {
     197             :         // in the same node?
     198           0 :         if( rPam.GetMark()->nNode == pPos->nNode )
     199             :         {
     200             :             // then use that end
     201           0 :             xub_StrLen nTEnd = rPam.GetMark()->nContent.GetIndex();
     202           0 :             if( nTEnd < nEnd )
     203           0 :                 nEnd = nTEnd;
     204             :         }
     205           0 :         rPam.DeleteMark();
     206             :     }
     207             : 
     208             :     // ----- search the start
     209             :     // --- look where a ruby attribut starts
     210           0 :     sal_uInt16 nHtIdx = USHRT_MAX;
     211           0 :     const SwpHints* pHts = pTNd->GetpSwpHints();
     212           0 :     const SwTxtAttr* pAttr = 0;
     213           0 :     if( pHts )
     214             :     {
     215             :         const SwTxtAttr* pHt;
     216           0 :         for( nHtIdx = 0; nHtIdx < pHts->Count(); ++nHtIdx )
     217           0 :             if( RES_TXTATR_CJK_RUBY == ( pHt = (*pHts)[ nHtIdx ])->Which() &&
     218           0 :                 *pHt->GetAnyEnd() > nStart )
     219             :             {
     220           0 :                 if( *pHt->GetStart() < nEnd )
     221             :                 {
     222           0 :                     pAttr = pHt;
     223           0 :                     if( !bHasMark && nStart > *pAttr->GetStart() )
     224             :                     {
     225           0 :                         nStart = *pAttr->GetStart();
     226           0 :                         pPos->nContent = nStart;
     227             :                     }
     228             :                 }
     229           0 :                 break;
     230             :             }
     231             :     }
     232             : 
     233           0 :     if( !bHasMark && nStart && ( !pAttr || nStart != *pAttr->GetStart()) )
     234             :     {
     235             :         // skip to the word begin!
     236           0 :         long nWordStt = pBreakIt->GetBreakIter()->getWordBoundary(
     237             :                             *pTxt, nStart,
     238           0 :                             pBreakIt->GetLocale( pTNd->GetLang( nStart )),
     239             :                             WordType::ANYWORD_IGNOREWHITESPACES,
     240           0 :                             sal_True ).startPos;
     241           0 :         if( nWordStt < nStart && -1 != nWordStt )
     242             :         {
     243           0 :             nStart = (xub_StrLen)nWordStt;
     244           0 :             pPos->nContent = nStart;
     245             :         }
     246             :     }
     247             : 
     248           0 :     bool bAlphaNum = false;
     249           0 :     long nWordEnd = nEnd;
     250           0 :     CharClass& rCC = GetAppCharClass();
     251           0 :     while(  nStart < nEnd )
     252             :     {
     253           0 :         if( pAttr && nStart == *pAttr->GetStart() )
     254             :         {
     255           0 :             pPos->nContent = nStart;
     256           0 :             if( !rPam.HasMark() )
     257             :             {
     258           0 :                 rPam.SetMark();
     259           0 :                 pPos->nContent = *pAttr->GetAnyEnd();
     260           0 :                 if( pPos->nContent.GetIndex() > nEnd )
     261           0 :                     pPos->nContent = nEnd;
     262           0 :                 rEntry.SetRubyAttr( pAttr->GetRuby() );
     263             :             }
     264           0 :             break;
     265             :         }
     266             : 
     267           0 :         sal_Int32 nChType = rCC.getType( *pTxt, nStart );
     268           0 :         bool bIgnoreChar = false, bIsAlphaNum = false, bChkNxtWrd = false;
     269           0 :         switch( nChType )
     270             :         {
     271             :         case UnicodeType::UPPERCASE_LETTER:
     272             :         case UnicodeType::LOWERCASE_LETTER:
     273             :         case UnicodeType::TITLECASE_LETTER:
     274             :         case UnicodeType::DECIMAL_DIGIT_NUMBER:
     275           0 :                 bChkNxtWrd = bIsAlphaNum = true;
     276           0 :                 break;
     277             : 
     278             :         case UnicodeType::SPACE_SEPARATOR:
     279             :         case UnicodeType::CONTROL:
     280             : /*??*/  case UnicodeType::PRIVATE_USE:
     281             :         case UnicodeType::START_PUNCTUATION:
     282             :         case UnicodeType::END_PUNCTUATION:
     283           0 :             bIgnoreChar = true;
     284           0 :             break;
     285             : 
     286             : 
     287             :         case UnicodeType::OTHER_LETTER:
     288           0 :             bChkNxtWrd = true;
     289             : 
     290             :         default:
     291           0 :                 bIsAlphaNum = false;
     292           0 :                 break;
     293             :         }
     294             : 
     295           0 :         if( rPam.HasMark() )
     296             :         {
     297           0 :             if( bIgnoreChar || bIsAlphaNum != bAlphaNum || nStart >= nWordEnd )
     298           0 :                 break;
     299             :         }
     300           0 :         else if( !bIgnoreChar )
     301             :         {
     302           0 :             rPam.SetMark();
     303           0 :             bAlphaNum = bIsAlphaNum;
     304           0 :             if( bChkNxtWrd && pBreakIt->GetBreakIter().is() )
     305             :             {
     306             :                 // search the end of this word
     307           0 :                 nWordEnd = pBreakIt->GetBreakIter()->getWordBoundary(
     308             :                             *pTxt, nStart,
     309           0 :                             pBreakIt->GetLocale( pTNd->GetLang( nStart )),
     310             :                             WordType::ANYWORD_IGNOREWHITESPACES,
     311           0 :                             sal_True ).endPos;
     312           0 :                 if( 0 > nWordEnd || nWordEnd > nEnd || nWordEnd == nStart )
     313           0 :                     nWordEnd = nEnd;
     314             :             }
     315             :         }
     316           0 :         pTNd->GoNext( &pPos->nContent, CRSR_SKIP_CHARS );
     317           0 :         nStart = pPos->nContent.GetIndex();
     318             :     }
     319             : 
     320           0 :     nStart = rPam.GetMark()->nContent.GetIndex();
     321             :     rEntry.SetText( pTxt->Copy( nStart,
     322           0 :                            rPam.GetPoint()->nContent.GetIndex() - nStart ));
     323           0 :     return rPam.HasMark();
     324             : }
     325             : 
     326           0 : SwRubyListEntry::~SwRubyListEntry()
     327             : {
     328           0 : }
     329             : 
     330             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10