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

Generated by: LCOV version 1.10