LCOV - code coverage report
Current view: top level - comphelper/source/misc - accessibletexthelper.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 186 374 49.7 %
Date: 2014-11-03 Functions: 30 40 75.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 <comphelper/accessibletexthelper.hxx>
      21             : #include <com/sun/star/accessibility/AccessibleTextType.hpp>
      22             : #include <com/sun/star/i18n/BreakIterator.hpp>
      23             : #include <com/sun/star/i18n/CharacterIteratorMode.hpp>
      24             : #include <com/sun/star/i18n/CharacterClassification.hpp>
      25             : #include <com/sun/star/i18n/WordType.hpp>
      26             : #include <com/sun/star/i18n/KCharacterType.hpp>
      27             : #include <comphelper/processfactory.hxx>
      28             : #include <com/sun/star/accessibility/TextSegment.hpp>
      29             : 
      30             : #include <algorithm>
      31             : 
      32             : 
      33             : namespace comphelper
      34             : {
      35             : 
      36             : 
      37             :     using namespace ::com::sun::star;
      38             :     using namespace ::com::sun::star::uno;
      39             :     using namespace ::com::sun::star::lang;
      40             :     using namespace ::com::sun::star::beans;
      41             :     using namespace ::com::sun::star::accessibility;
      42             : 
      43             : 
      44             :     // OCommonAccessibleText
      45             : 
      46             : 
      47        4789 :     OCommonAccessibleText::OCommonAccessibleText()
      48             :     {
      49        4789 :     }
      50             : 
      51             : 
      52             : 
      53        4415 :     OCommonAccessibleText::~OCommonAccessibleText()
      54             :     {
      55        4415 :     }
      56             : 
      57             : 
      58             : 
      59           4 :     Reference < i18n::XBreakIterator > OCommonAccessibleText::implGetBreakIterator()
      60             :     {
      61           4 :         if ( !m_xBreakIter.is() )
      62             :         {
      63           4 :             Reference< uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
      64           4 :             m_xBreakIter = i18n::BreakIterator::create(xContext);
      65             :         }
      66             : 
      67           4 :         return m_xBreakIter;
      68             :     }
      69             : 
      70             : 
      71             : 
      72           4 :     Reference < i18n::XCharacterClassification > OCommonAccessibleText::implGetCharacterClassification()
      73             :     {
      74           4 :         if ( !m_xCharClass.is() )
      75             :         {
      76           4 :             m_xCharClass = i18n::CharacterClassification::create( ::comphelper::getProcessComponentContext() );
      77             :         }
      78             : 
      79           4 :         return m_xCharClass;
      80             :     }
      81             : 
      82             : 
      83             : 
      84          10 :     bool OCommonAccessibleText::implIsValidBoundary( i18n::Boundary& rBoundary, sal_Int32 nLength )
      85             :     {
      86          10 :         return ( rBoundary.startPos >= 0 ) && ( rBoundary.startPos < nLength ) && ( rBoundary.endPos >= 0 ) && ( rBoundary.endPos <= nLength );
      87             :     }
      88             : 
      89             : 
      90             : 
      91         482 :     bool OCommonAccessibleText::implIsValidIndex( sal_Int32 nIndex, sal_Int32 nLength )
      92             :     {
      93         482 :         return ( nIndex >= 0 ) && ( nIndex < nLength );
      94             :     }
      95             : 
      96             : 
      97             : 
      98          54 :     bool OCommonAccessibleText::implIsValidRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex, sal_Int32 nLength )
      99             :     {
     100          54 :         return ( nStartIndex >= 0 ) && ( nStartIndex <= nLength ) && ( nEndIndex >= 0 ) && ( nEndIndex <= nLength );
     101             :     }
     102             : 
     103             : 
     104             : 
     105           0 :     void OCommonAccessibleText::implGetGlyphBoundary( i18n::Boundary& rBoundary, sal_Int32 nIndex )
     106             :     {
     107           0 :         OUString sText( implGetText() );
     108             : 
     109           0 :         if ( implIsValidIndex( nIndex, sText.getLength() ) )
     110             :         {
     111           0 :             Reference < i18n::XBreakIterator > xBreakIter = implGetBreakIterator();
     112           0 :             if ( xBreakIter.is() )
     113             :             {
     114           0 :                 sal_Int32 nCount = 1;
     115             :                 sal_Int32 nDone;
     116           0 :                 sal_Int32 nStartIndex = xBreakIter->previousCharacters( sText, nIndex, implGetLocale(), i18n::CharacterIteratorMode::SKIPCELL, nCount, nDone );
     117           0 :                 if ( nDone != 0 )
     118           0 :                     nStartIndex = xBreakIter->nextCharacters( sText, nStartIndex, implGetLocale(), i18n::CharacterIteratorMode::SKIPCELL, nCount, nDone );
     119           0 :                 sal_Int32 nEndIndex = xBreakIter->nextCharacters( sText, nStartIndex, implGetLocale(), i18n::CharacterIteratorMode::SKIPCELL, nCount, nDone );
     120           0 :                 if ( nDone != 0 )
     121             :                 {
     122           0 :                     rBoundary.startPos = nStartIndex;
     123           0 :                     rBoundary.endPos = nEndIndex;
     124             :                 }
     125           0 :             }
     126             :         }
     127             :         else
     128             :         {
     129           0 :             rBoundary.startPos = nIndex;
     130           0 :             rBoundary.endPos = nIndex;
     131           0 :         }
     132           0 :     }
     133             : 
     134             : 
     135             : 
     136          14 :     bool OCommonAccessibleText::implGetWordBoundary( i18n::Boundary& rBoundary, sal_Int32 nIndex )
     137             :     {
     138          14 :         bool bWord = false;
     139          14 :         OUString sText( implGetText() );
     140             : 
     141          14 :         if ( implIsValidIndex( nIndex, sText.getLength() ) )
     142             :         {
     143           4 :             Reference < i18n::XBreakIterator > xBreakIter = implGetBreakIterator();
     144           4 :             if ( xBreakIter.is() )
     145             :             {
     146           4 :                 rBoundary = xBreakIter->getWordBoundary( sText, nIndex, implGetLocale(), i18n::WordType::ANY_WORD, sal_True );
     147             : 
     148             :                 // it's a word, if the first character is an alpha-numeric character
     149           4 :                 Reference< i18n::XCharacterClassification > xCharClass = implGetCharacterClassification();
     150           4 :                 if ( xCharClass.is() )
     151             :                 {
     152           4 :                     sal_Int32 nType = xCharClass->getCharacterType( sText, rBoundary.startPos, implGetLocale() );
     153           4 :                     if ( ( nType & ( i18n::KCharacterType::LETTER | i18n::KCharacterType::DIGIT ) ) != 0 )
     154           4 :                         bWord = true;
     155           4 :                 }
     156           4 :             }
     157             :         }
     158             :         else
     159             :         {
     160          10 :             rBoundary.startPos = nIndex;
     161          10 :             rBoundary.endPos = nIndex;
     162             :         }
     163             : 
     164          14 :         return bWord;
     165             :     }
     166             : 
     167             : 
     168             : 
     169           0 :     void OCommonAccessibleText::implGetSentenceBoundary( i18n::Boundary& rBoundary, sal_Int32 nIndex )
     170             :     {
     171           0 :         OUString sText( implGetText() );
     172             : 
     173           0 :         if ( implIsValidIndex( nIndex, sText.getLength() ) )
     174             :         {
     175           0 :             Locale aLocale = implGetLocale();
     176           0 :             Reference < i18n::XBreakIterator > xBreakIter = implGetBreakIterator();
     177           0 :             if ( xBreakIter.is() )
     178             :             {
     179           0 :                 rBoundary.endPos = xBreakIter->endOfSentence( sText, nIndex, aLocale );
     180           0 :                 rBoundary.startPos = xBreakIter->beginOfSentence( sText, rBoundary.endPos, aLocale );
     181           0 :             }
     182             :         }
     183             :         else
     184             :         {
     185           0 :             rBoundary.startPos = nIndex;
     186           0 :             rBoundary.endPos = nIndex;
     187           0 :         }
     188           0 :     }
     189             : 
     190             : 
     191             : 
     192          16 :     void OCommonAccessibleText::implGetParagraphBoundary( i18n::Boundary& rBoundary, sal_Int32 nIndex )
     193             :     {
     194          16 :         OUString sText( implGetText() );
     195             : 
     196          16 :         if ( implIsValidIndex( nIndex, sText.getLength() ) )
     197             :         {
     198          12 :             rBoundary.startPos = 0;
     199          12 :             rBoundary.endPos = sText.getLength();
     200             : 
     201          12 :             sal_Int32 nFound = sText.lastIndexOf( (sal_Unicode)'\n', nIndex );
     202          12 :             if ( nFound != -1 )
     203           0 :                 rBoundary.startPos = nFound + 1;
     204             : 
     205          12 :             nFound = sText.indexOf( (sal_Unicode)'\n', nIndex );
     206          12 :             if ( nFound != -1 )
     207           0 :                 rBoundary.endPos = nFound + 1;
     208             :         }
     209             :         else
     210             :         {
     211           4 :             rBoundary.startPos = nIndex;
     212           4 :             rBoundary.endPos = nIndex;
     213          16 :         }
     214          16 :     }
     215             : 
     216             : 
     217             : 
     218           0 :     void OCommonAccessibleText::implGetLineBoundary( i18n::Boundary& rBoundary, sal_Int32 nIndex )
     219             :     {
     220           0 :         OUString sText( implGetText() );
     221           0 :         sal_Int32 nLength = sText.getLength();
     222             : 
     223           0 :         if ( implIsValidIndex( nIndex, nLength ) || nIndex == nLength )
     224             :         {
     225           0 :             rBoundary.startPos = 0;
     226           0 :             rBoundary.endPos = nLength;
     227             :         }
     228             :         else
     229             :         {
     230           0 :             rBoundary.startPos = nIndex;
     231           0 :             rBoundary.endPos = nIndex;
     232           0 :         }
     233           0 :     }
     234             : 
     235             : 
     236             : 
     237          80 :     sal_Unicode OCommonAccessibleText::getCharacter( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException)
     238             :     {
     239          80 :         OUString sText( implGetText() );
     240             : 
     241          80 :         if ( !implIsValidIndex( nIndex, sText.getLength() ) )
     242          12 :             throw IndexOutOfBoundsException();
     243             : 
     244          80 :         return sText[nIndex];
     245             :     }
     246             : 
     247             : 
     248             : 
     249         110 :     sal_Int32 OCommonAccessibleText::getCharacterCount() throw (RuntimeException)
     250             :     {
     251         110 :         return implGetText().getLength();
     252             :     }
     253             : 
     254             : 
     255             : 
     256           0 :     OUString OCommonAccessibleText::getSelectedText() throw (RuntimeException)
     257             :     {
     258           0 :         OUString sText;
     259             :         sal_Int32 nStartIndex;
     260             :         sal_Int32 nEndIndex;
     261             : 
     262           0 :         implGetSelection( nStartIndex, nEndIndex );
     263             : 
     264             :         try
     265             :         {
     266           0 :             sText = getTextRange( nStartIndex, nEndIndex );
     267             :         }
     268           0 :         catch ( IndexOutOfBoundsException& )
     269             :         {
     270             :         }
     271             : 
     272           0 :         return sText;
     273             :     }
     274             : 
     275             : 
     276             : 
     277          32 :     sal_Int32 OCommonAccessibleText::getSelectionStart() throw (RuntimeException)
     278             :     {
     279             :         sal_Int32 nStartIndex;
     280             :         sal_Int32 nEndIndex;
     281             : 
     282          32 :         implGetSelection( nStartIndex, nEndIndex );
     283             : 
     284          32 :         return nStartIndex;
     285             :     }
     286             : 
     287             : 
     288             : 
     289          32 :     sal_Int32 OCommonAccessibleText::getSelectionEnd() throw (RuntimeException)
     290             :     {
     291             :         sal_Int32 nStartIndex;
     292             :         sal_Int32 nEndIndex;
     293             : 
     294          32 :         implGetSelection( nStartIndex, nEndIndex );
     295             : 
     296          32 :         return nEndIndex;
     297             :     }
     298             : 
     299             : 
     300             : 
     301          82 :     OUString OCommonAccessibleText::getText() throw (RuntimeException)
     302             :     {
     303          82 :         return implGetText();
     304             :     }
     305             : 
     306             : 
     307             : 
     308          42 :     OUString OCommonAccessibleText::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (IndexOutOfBoundsException, RuntimeException)
     309             :     {
     310          42 :         OUString sText( implGetText() );
     311             : 
     312          42 :         if ( !implIsValidRange( nStartIndex, nEndIndex, sText.getLength() ) )
     313          18 :             throw IndexOutOfBoundsException();
     314             : 
     315          24 :         sal_Int32 nMinIndex = ::std::min( nStartIndex, nEndIndex );
     316          24 :         sal_Int32 nMaxIndex = ::std::max( nStartIndex, nEndIndex );
     317             : 
     318          42 :         return sText.copy( nMinIndex, nMaxIndex - nMinIndex );
     319             :     }
     320             : 
     321             : 
     322             : 
     323          88 :     TextSegment OCommonAccessibleText::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (IndexOutOfBoundsException, IllegalArgumentException, RuntimeException)
     324             :     {
     325          88 :         OUString sText( implGetText() );
     326          88 :         sal_Int32 nLength = sText.getLength();
     327             : 
     328          88 :         if ( !implIsValidIndex( nIndex, nLength ) && nIndex != nLength )
     329          12 :             throw IndexOutOfBoundsException();
     330             : 
     331          76 :         i18n::Boundary aBoundary;
     332          76 :         TextSegment aResult;
     333          76 :         aResult.SegmentStart = -1;
     334          76 :         aResult.SegmentEnd = -1;
     335             : 
     336          76 :         switch ( aTextType )
     337             :         {
     338             :             case AccessibleTextType::CHARACTER:
     339             :             {
     340          64 :                 if ( implIsValidIndex( nIndex, nLength ) )
     341             :                 {
     342          64 :                     aResult.SegmentText = sText.copy( nIndex, 1 );
     343          64 :                     aResult.SegmentStart = nIndex;
     344          64 :                     aResult.SegmentEnd = nIndex+1;
     345             :                 }
     346             :             }
     347          64 :             break;
     348             :             case AccessibleTextType::GLYPH:
     349             :             {
     350             :                 // get glyph at index
     351           0 :                 implGetGlyphBoundary( aBoundary, nIndex );
     352           0 :                 if ( implIsValidBoundary( aBoundary, nLength ) )
     353             :                 {
     354           0 :                     aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
     355           0 :                     aResult.SegmentStart = aBoundary.startPos;
     356           0 :                     aResult.SegmentEnd = aBoundary.endPos;
     357             :                 }
     358             :             }
     359           0 :             break;
     360             :             case AccessibleTextType::WORD:
     361             :             {
     362             :                 // get word at index
     363           6 :                 bool bWord = implGetWordBoundary( aBoundary, nIndex );
     364           6 :                 if ( bWord && implIsValidBoundary( aBoundary, nLength ) )
     365             :                 {
     366           0 :                     aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
     367           0 :                     aResult.SegmentStart = aBoundary.startPos;
     368           0 :                     aResult.SegmentEnd = aBoundary.endPos;
     369             :                 }
     370             :             }
     371           6 :             break;
     372             :             case AccessibleTextType::SENTENCE:
     373             :             {
     374             :                 // get sentence at index
     375           0 :                 implGetSentenceBoundary( aBoundary, nIndex );
     376           0 :                 if ( implIsValidBoundary( aBoundary, nLength ) )
     377             :                 {
     378           0 :                     aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
     379           0 :                     aResult.SegmentStart = aBoundary.startPos;
     380           0 :                     aResult.SegmentEnd = aBoundary.endPos;
     381             :                 }
     382             :             }
     383           0 :             break;
     384             :             case AccessibleTextType::PARAGRAPH:
     385             :             {
     386             :                 // get paragraph at index
     387           6 :                 implGetParagraphBoundary( aBoundary, nIndex );
     388           6 :                 if ( implIsValidBoundary( aBoundary, nLength ) )
     389             :                 {
     390           6 :                     aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
     391           6 :                     aResult.SegmentStart = aBoundary.startPos;
     392           6 :                     aResult.SegmentEnd = aBoundary.endPos;
     393             :                 }
     394             :             }
     395           6 :             break;
     396             :             case AccessibleTextType::LINE:
     397             :             {
     398             :                 // get line at index
     399           0 :                 implGetLineBoundary( aBoundary, nIndex );
     400           0 :                 if ( implIsValidBoundary( aBoundary, nLength ) )
     401             :                 {
     402           0 :                     aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
     403           0 :                     aResult.SegmentStart = aBoundary.startPos;
     404           0 :                     aResult.SegmentEnd = aBoundary.endPos;
     405             :                 }
     406             :             }
     407           0 :             break;
     408             :             case AccessibleTextType::ATTRIBUTE_RUN:
     409             :             {
     410             :                 // TODO: implGetAttributeRunBoundary() (incompatible!)
     411             : 
     412           0 :                 aResult.SegmentText = sText;
     413           0 :                 aResult.SegmentStart = 0;
     414           0 :                 aResult.SegmentEnd = nLength;
     415             :             }
     416           0 :             break;
     417             :             default:
     418             :             {
     419             :                 // unknown text type
     420             :             }
     421             :         }
     422             : 
     423          88 :         return aResult;
     424             :     }
     425             : 
     426             : 
     427             : 
     428          32 :     TextSegment OCommonAccessibleText::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (IndexOutOfBoundsException, IllegalArgumentException, RuntimeException)
     429             :     {
     430          32 :         OUString sText( implGetText() );
     431          32 :         sal_Int32 nLength = sText.getLength();
     432             : 
     433          32 :         if ( !implIsValidIndex( nIndex, nLength ) && nIndex != nLength )
     434          12 :             throw IndexOutOfBoundsException();
     435             : 
     436          20 :         i18n::Boundary aBoundary;
     437          20 :         TextSegment aResult;
     438          20 :         aResult.SegmentStart = -1;
     439          20 :         aResult.SegmentEnd = -1;
     440             : 
     441          20 :         switch ( aTextType )
     442             :         {
     443             :             case AccessibleTextType::CHARACTER:
     444             :             {
     445          12 :                 if ( implIsValidIndex( nIndex - 1, nLength ) )
     446             :                 {
     447          12 :                     aResult.SegmentText = sText.copy( nIndex - 1, 1 );
     448          12 :                     aResult.SegmentStart = nIndex-1;
     449          12 :                     aResult.SegmentEnd = nIndex;
     450             :                 }
     451             :             }
     452          12 :             break;
     453             :             case AccessibleTextType::GLYPH:
     454             :             {
     455             :                 // get glyph at index
     456           0 :                 implGetGlyphBoundary( aBoundary, nIndex );
     457             :                 // get previous glyph
     458           0 :                 if ( aBoundary.startPos > 0 )
     459             :                 {
     460           0 :                     implGetGlyphBoundary( aBoundary, aBoundary.startPos - 1 );
     461           0 :                     if ( implIsValidBoundary( aBoundary, nLength ) )
     462             :                     {
     463           0 :                         aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
     464           0 :                         aResult.SegmentStart = aBoundary.startPos;
     465           0 :                         aResult.SegmentEnd = aBoundary.endPos;
     466             :                     }
     467             :                 }
     468             :             }
     469           0 :             break;
     470             :             case AccessibleTextType::WORD:
     471             :             {
     472             :                 // get word at index
     473           2 :                 implGetWordBoundary( aBoundary, nIndex );
     474             :                 // get previous word
     475           2 :                 bool bWord = false;
     476           6 :                 while ( !bWord && aBoundary.startPos > 0 )
     477           2 :                     bWord = implGetWordBoundary( aBoundary, aBoundary.startPos - 1 );
     478           2 :                 if ( bWord && implIsValidBoundary( aBoundary, nLength ) )
     479             :                 {
     480           2 :                     aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
     481           2 :                     aResult.SegmentStart = aBoundary.startPos;
     482           2 :                     aResult.SegmentEnd = aBoundary.endPos;
     483             :                 }
     484             :             }
     485           2 :             break;
     486             :             case AccessibleTextType::SENTENCE:
     487             :             {
     488             :                 // get sentence at index
     489           0 :                 implGetSentenceBoundary( aBoundary, nIndex );
     490             :                 // get previous sentence
     491           0 :                 if ( aBoundary.startPos > 0 )
     492             :                 {
     493           0 :                     implGetSentenceBoundary( aBoundary, aBoundary.startPos - 1 );
     494           0 :                     if ( implIsValidBoundary( aBoundary, nLength ) )
     495             :                     {
     496           0 :                         aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
     497           0 :                         aResult.SegmentStart = aBoundary.startPos;
     498           0 :                         aResult.SegmentEnd = aBoundary.endPos;
     499             :                     }
     500             :                 }
     501             :             }
     502           0 :             break;
     503             :             case AccessibleTextType::PARAGRAPH:
     504             :             {
     505             :                 // get paragraph at index
     506           6 :                 implGetParagraphBoundary( aBoundary, nIndex );
     507             :                 // get previous paragraph
     508           6 :                 if ( aBoundary.startPos > 0 )
     509             :                 {
     510           0 :                     implGetParagraphBoundary( aBoundary, aBoundary.startPos - 1 );
     511           0 :                     if ( implIsValidBoundary( aBoundary, nLength ) )
     512             :                     {
     513           0 :                         aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
     514           0 :                         aResult.SegmentStart = aBoundary.startPos;
     515           0 :                         aResult.SegmentEnd = aBoundary.endPos;
     516             :                     }
     517             :                 }
     518             :             }
     519           6 :             break;
     520             :             case AccessibleTextType::LINE:
     521             :             {
     522             :                 // get line at index
     523           0 :                 implGetLineBoundary( aBoundary, nIndex );
     524             :                 // get previous line
     525           0 :                 if ( aBoundary.startPos > 0 )
     526             :                 {
     527           0 :                     implGetLineBoundary( aBoundary, aBoundary.startPos - 1 );
     528           0 :                     if ( implIsValidBoundary( aBoundary, nLength ) )
     529             :                     {
     530           0 :                         aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
     531           0 :                         aResult.SegmentStart = aBoundary.startPos;
     532           0 :                         aResult.SegmentEnd = aBoundary.endPos;
     533             :                     }
     534             :                 }
     535             :             }
     536           0 :             break;
     537             :             case AccessibleTextType::ATTRIBUTE_RUN:
     538             :             {
     539             :                 // TODO: implGetAttributeRunBoundary() (incompatible!)
     540             :             }
     541           0 :             break;
     542             :             default:
     543             :             {
     544             :                 // unknown text type
     545             :             }
     546             :         }
     547             : 
     548          32 :         return aResult;
     549             :     }
     550             : 
     551             : 
     552             : 
     553          36 :     TextSegment OCommonAccessibleText::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (IndexOutOfBoundsException, IllegalArgumentException, RuntimeException)
     554             :     {
     555          36 :         OUString sText( implGetText() );
     556          36 :         sal_Int32 nLength = sText.getLength();
     557             : 
     558          36 :         if ( !implIsValidIndex( nIndex, nLength ) && nIndex != nLength )
     559          12 :             throw IndexOutOfBoundsException();
     560             : 
     561          24 :         i18n::Boundary aBoundary;
     562          24 :         TextSegment aResult;
     563          24 :         aResult.SegmentStart = -1;
     564          24 :         aResult.SegmentEnd = -1;
     565             : 
     566          24 :         switch ( aTextType )
     567             :         {
     568             :             case AccessibleTextType::CHARACTER:
     569             :             {
     570          12 :                 if ( implIsValidIndex( nIndex + 1, nLength ) )
     571             :                 {
     572          12 :                     aResult.SegmentText = sText.copy( nIndex + 1, 1 );
     573          12 :                     aResult.SegmentStart = nIndex+1;
     574          12 :                     aResult.SegmentEnd = nIndex+2;
     575             :                 }
     576             :             }
     577          12 :             break;
     578             :             case AccessibleTextType::GLYPH:
     579             :             {
     580             :                 // get glyph at index
     581           0 :                 implGetGlyphBoundary( aBoundary, nIndex );
     582             :                 // get next glyph
     583           0 :                 if ( aBoundary.endPos < nLength )
     584             :                 {
     585           0 :                     implGetGlyphBoundary( aBoundary, aBoundary.endPos );
     586           0 :                     if ( implIsValidBoundary( aBoundary, nLength ) )
     587             :                     {
     588           0 :                         aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
     589           0 :                         aResult.SegmentStart = aBoundary.startPos;
     590           0 :                         aResult.SegmentEnd = aBoundary.endPos;
     591             :                     }
     592             :                 }
     593             :             }
     594           0 :             break;
     595             :             case AccessibleTextType::WORD:
     596             :             {
     597             :                 // get word at index
     598           0 :                 implGetWordBoundary( aBoundary, nIndex );
     599             :                 // get next word
     600           0 :                 bool bWord = false;
     601           0 :                 while ( !bWord && aBoundary.endPos < nLength )
     602           0 :                     bWord = implGetWordBoundary( aBoundary, aBoundary.endPos );
     603           0 :                 if ( bWord && implIsValidBoundary( aBoundary, nLength ) )
     604             :                 {
     605           0 :                     aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
     606           0 :                     aResult.SegmentStart = aBoundary.startPos;
     607           0 :                     aResult.SegmentEnd = aBoundary.endPos;
     608             :                 }
     609             :             }
     610           0 :             break;
     611             :             case AccessibleTextType::SENTENCE:
     612             :             {
     613             :                 // get sentence at index
     614           0 :                 implGetSentenceBoundary( aBoundary, nIndex );
     615             :                 // get next sentence
     616           0 :                 sal_Int32 nEnd = aBoundary.endPos;
     617           0 :                 sal_Int32 nI = aBoundary.endPos;
     618           0 :                 bool bFound = false;
     619           0 :                 while ( !bFound && ++nI < nLength )
     620             :                 {
     621           0 :                     implGetSentenceBoundary( aBoundary, nI );
     622           0 :                     bFound = ( aBoundary.endPos > nEnd );
     623             :                 }
     624           0 :                 if ( bFound && implIsValidBoundary( aBoundary, nLength ) )
     625             :                 {
     626           0 :                     aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
     627           0 :                     aResult.SegmentStart = aBoundary.startPos;
     628           0 :                     aResult.SegmentEnd = aBoundary.endPos;
     629             :                 }
     630             :             }
     631           0 :             break;
     632             :             case AccessibleTextType::PARAGRAPH:
     633             :             {
     634             :                 // get paragraph at index
     635          12 :                 implGetParagraphBoundary( aBoundary, nIndex );
     636             :                 // get next paragraph
     637          12 :                 if ( aBoundary.endPos < nLength )
     638             :                 {
     639           0 :                     implGetParagraphBoundary( aBoundary, aBoundary.endPos );
     640           0 :                     if ( implIsValidBoundary( aBoundary, nLength ) )
     641             :                     {
     642           0 :                         aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
     643           0 :                         aResult.SegmentStart = aBoundary.startPos;
     644           0 :                         aResult.SegmentEnd = aBoundary.endPos;
     645             :                     }
     646             :                 }
     647             :             }
     648          12 :             break;
     649             :             case AccessibleTextType::LINE:
     650             :             {
     651             :                 // get line at index
     652           0 :                 implGetLineBoundary( aBoundary, nIndex );
     653             :                 // get next line
     654           0 :                 if ( aBoundary.endPos < nLength )
     655             :                 {
     656           0 :                     implGetLineBoundary( aBoundary, aBoundary.endPos );
     657           0 :                     if ( implIsValidBoundary( aBoundary, nLength ) )
     658             :                     {
     659           0 :                         aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
     660           0 :                         aResult.SegmentStart = aBoundary.startPos;
     661           0 :                         aResult.SegmentEnd = aBoundary.endPos;
     662             :                     }
     663             :                 }
     664             :             }
     665           0 :             break;
     666             :             case AccessibleTextType::ATTRIBUTE_RUN:
     667             :             {
     668             :                 // TODO: implGetAttributeRunBoundary() (incompatible!)
     669             :             }
     670           0 :             break;
     671             :             default:
     672             :             {
     673             :                 // unknown text type
     674             :             }
     675             :         }
     676             : 
     677          36 :         return aResult;
     678             :     }
     679             : 
     680             : 
     681          62 :     bool OCommonAccessibleText::implInitTextChangedEvent(
     682             :         const OUString& rOldString,
     683             :         const OUString& rNewString,
     684             :         ::com::sun::star::uno::Any& rDeleted,
     685             :         ::com::sun::star::uno::Any& rInserted) // throw()
     686             :     {
     687          62 :         sal_uInt32 nLenOld = rOldString.getLength();
     688          62 :         sal_uInt32 nLenNew = rNewString.getLength();
     689             : 
     690             :         // equal
     691          62 :         if ((0 == nLenOld) && (0 == nLenNew))
     692          20 :             return false;
     693             : 
     694          42 :         TextSegment aDeletedText;
     695          84 :         TextSegment aInsertedText;
     696             : 
     697          42 :         aDeletedText.SegmentStart = -1;
     698          42 :         aDeletedText.SegmentEnd = -1;
     699          42 :         aInsertedText.SegmentStart = -1;
     700          42 :         aInsertedText.SegmentEnd = -1;
     701             : 
     702             :         // insert only
     703          42 :         if ((0 == nLenOld) && (nLenNew > 0))
     704             :         {
     705          42 :             aInsertedText.SegmentStart = 0;
     706          42 :             aInsertedText.SegmentEnd = nLenNew;
     707          42 :             aInsertedText.SegmentText = rNewString.copy( aInsertedText.SegmentStart, aInsertedText.SegmentEnd - aInsertedText.SegmentStart );
     708             : 
     709          42 :             rInserted <<= aInsertedText;
     710          42 :             return true;
     711             :         }
     712             : 
     713             :         // delete only
     714           0 :         if ((nLenOld > 0) && (0 == nLenNew))
     715             :         {
     716           0 :             aDeletedText.SegmentStart = 0;
     717           0 :             aDeletedText.SegmentEnd = nLenOld;
     718           0 :             aDeletedText.SegmentText = rOldString.copy( aDeletedText.SegmentStart, aDeletedText.SegmentEnd - aDeletedText.SegmentStart );
     719             : 
     720           0 :             rDeleted <<= aDeletedText;
     721           0 :             return true;
     722             :         }
     723             : 
     724           0 :         const sal_Unicode* pFirstDiffOld = rOldString.getStr();
     725           0 :         const sal_Unicode* pLastDiffOld  = rOldString.getStr() + nLenOld;
     726           0 :         const sal_Unicode* pFirstDiffNew = rNewString.getStr();
     727           0 :         const sal_Unicode* pLastDiffNew  = rNewString.getStr() + nLenNew;
     728             : 
     729             :         // find first difference
     730           0 :         while ((*pFirstDiffOld == *pFirstDiffNew) &&
     731           0 :                (pFirstDiffOld  <  pLastDiffOld) &&
     732             :                (pFirstDiffNew  <  pLastDiffNew))
     733             :         {
     734           0 :             pFirstDiffOld++;
     735           0 :             pFirstDiffNew++;
     736             :         }
     737             : 
     738             :         // equality test
     739           0 :         if ((0 == *pFirstDiffOld) && (0 == *pFirstDiffNew))
     740           0 :             return false;
     741             : 
     742             :         // find last difference
     743           0 :         while ( ( pLastDiffOld > pFirstDiffOld) &&
     744           0 :                 ( pLastDiffNew > pFirstDiffNew) &&
     745           0 :                 (pLastDiffOld[-1]  == pLastDiffNew[-1]))
     746             :         {
     747           0 :             pLastDiffOld--;
     748           0 :             pLastDiffNew--;
     749             :         }
     750             : 
     751           0 :         if (pFirstDiffOld < pLastDiffOld)
     752             :         {
     753           0 :             aDeletedText.SegmentStart = pFirstDiffOld - rOldString.getStr();
     754           0 :             aDeletedText.SegmentEnd = pLastDiffOld  - rOldString.getStr();
     755           0 :             aDeletedText.SegmentText = rOldString.copy( aDeletedText.SegmentStart, aDeletedText.SegmentEnd - aDeletedText.SegmentStart );
     756             : 
     757           0 :             rDeleted <<= aDeletedText;
     758             :         }
     759             : 
     760           0 :         if (pFirstDiffNew < pLastDiffNew)
     761             :         {
     762           0 :             aInsertedText.SegmentStart = pFirstDiffNew - rNewString.getStr();
     763           0 :             aInsertedText.SegmentEnd = pLastDiffNew  - rNewString.getStr();
     764           0 :             aInsertedText.SegmentText = rNewString.copy( aInsertedText.SegmentStart, aInsertedText.SegmentEnd - aInsertedText.SegmentStart );
     765             : 
     766           0 :             rInserted <<= aInsertedText;
     767             :         }
     768          42 :         return true;
     769             :     }
     770             : 
     771             : 
     772             :     // OAccessibleTextHelper
     773             : 
     774             : 
     775         776 :     OAccessibleTextHelper::OAccessibleTextHelper( IMutex* _pExternalLock )
     776         776 :         :OAccessibleExtendedComponentHelper( _pExternalLock )
     777             :     {
     778         776 :     }
     779             : 
     780             : 
     781             :     // XInterface
     782             : 
     783             : 
     784       28204 :     IMPLEMENT_FORWARD_XINTERFACE2( OAccessibleTextHelper, OAccessibleExtendedComponentHelper, OAccessibleTextHelper_Base )
     785             : 
     786             : 
     787             :     // XTypeProvider
     788             : 
     789             : 
     790           0 :     IMPLEMENT_FORWARD_XTYPEPROVIDER2( OAccessibleTextHelper, OAccessibleExtendedComponentHelper, OAccessibleTextHelper_Base )
     791             : 
     792             : 
     793             :     // XAccessibleText
     794             : 
     795             : 
     796          46 :     sal_Unicode OAccessibleTextHelper::getCharacter( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException, std::exception)
     797             :     {
     798          46 :         OExternalLockGuard aGuard( this );
     799             : 
     800          46 :         return OCommonAccessibleText::getCharacter( nIndex );
     801             :     }
     802             : 
     803             : 
     804             : 
     805           2 :     sal_Int32 OAccessibleTextHelper::getCharacterCount() throw (RuntimeException, std::exception)
     806             :     {
     807           2 :         OExternalLockGuard aGuard( this );
     808             : 
     809           2 :         return OCommonAccessibleText::getCharacterCount();
     810             :     }
     811             : 
     812             : 
     813             : 
     814           0 :     OUString OAccessibleTextHelper::getSelectedText() throw (RuntimeException, std::exception)
     815             :     {
     816           0 :         OExternalLockGuard aGuard( this );
     817             : 
     818           0 :         return OCommonAccessibleText::getSelectedText();
     819             :     }
     820             : 
     821             : 
     822             : 
     823           0 :     sal_Int32 OAccessibleTextHelper::getSelectionStart() throw (RuntimeException, std::exception)
     824             :     {
     825           0 :         OExternalLockGuard aGuard( this );
     826             : 
     827           0 :         return OCommonAccessibleText::getSelectionStart();
     828             :     }
     829             : 
     830             : 
     831             : 
     832           0 :     sal_Int32 OAccessibleTextHelper::getSelectionEnd() throw (RuntimeException, std::exception)
     833             :     {
     834           0 :         OExternalLockGuard aGuard( this );
     835             : 
     836           0 :         return OCommonAccessibleText::getSelectionEnd();
     837             :     }
     838             : 
     839             : 
     840             : 
     841           4 :     OUString OAccessibleTextHelper::getText() throw (RuntimeException, std::exception)
     842             :     {
     843           4 :         OExternalLockGuard aGuard( this );
     844             : 
     845           4 :         return OCommonAccessibleText::getText();
     846             :     }
     847             : 
     848             : 
     849             : 
     850          14 :     OUString OAccessibleTextHelper::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (IndexOutOfBoundsException, RuntimeException, std::exception)
     851             :     {
     852          14 :         OExternalLockGuard aGuard( this );
     853             : 
     854          14 :         return OCommonAccessibleText::getTextRange( nStartIndex, nEndIndex );
     855             :     }
     856             : 
     857             : 
     858             : 
     859          48 :     TextSegment OAccessibleTextHelper::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (IndexOutOfBoundsException, IllegalArgumentException, RuntimeException, std::exception)
     860             :     {
     861          48 :         OExternalLockGuard aGuard( this );
     862             : 
     863          48 :         return OCommonAccessibleText::getTextAtIndex( nIndex, aTextType );
     864             :     }
     865             : 
     866             : 
     867             : 
     868          10 :     TextSegment OAccessibleTextHelper::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (IndexOutOfBoundsException, IllegalArgumentException, RuntimeException, std::exception)
     869             :     {
     870          10 :         OExternalLockGuard aGuard( this );
     871             : 
     872          10 :         return OCommonAccessibleText::getTextBeforeIndex( nIndex, aTextType );
     873             :     }
     874             : 
     875             : 
     876             : 
     877          12 :     TextSegment OAccessibleTextHelper::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (IndexOutOfBoundsException, IllegalArgumentException, RuntimeException, std::exception)
     878             :     {
     879          12 :         OExternalLockGuard aGuard( this );
     880             : 
     881          12 :         return OCommonAccessibleText::getTextBehindIndex( nIndex, aTextType );
     882             :     }
     883             : 
     884             : 
     885             : 
     886             : 
     887             : }   // namespace comphelper
     888             : 
     889             : 
     890             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10