1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #include "precompiled_sw.hxx" 29 30 #include <textmarkuphelper.hxx> 31 #include <accportions.hxx> 32 33 #include <vector> 34 #include <algorithm> 35 #include <comphelper/stlunosequence.hxx> 36 37 #include <errhdl.hxx> 38 39 #include <com/sun/star/text/TextMarkupType.hpp> 40 #include <com/sun/star/accessibility/TextSegment.hpp> 41 42 #include <ndtxt.hxx> 43 #include <wrong.hxx> 44 45 using namespace com::sun::star; 46 47 // helper functions 48 namespace { 49 const SwWrongList* getTextMarkupList( const SwTxtNode& rTxtNode, 50 const sal_Int32 nTextMarkupType ) 51 throw (::com::sun::star::lang::IllegalArgumentException, 52 ::com::sun::star::uno::RuntimeException) 53 { 54 const SwWrongList* pTextMarkupList( 0 ); 55 switch ( nTextMarkupType ) 56 { 57 case text::TextMarkupType::SPELLCHECK: 58 { 59 pTextMarkupList = rTxtNode.GetWrong(); 60 } 61 break; 62 case text::TextMarkupType::PROOFREADING: 63 { 64 // support not implemented yet 65 pTextMarkupList = 0; 66 } 67 break; 68 case text::TextMarkupType::SMARTTAG: 69 { 70 // support not implemented yet 71 pTextMarkupList = 0; 72 } 73 break; 74 default: 75 { 76 throw lang::IllegalArgumentException(); 77 } 78 } 79 80 return pTextMarkupList; 81 } 82 } 83 84 // implementation of class <SwTextMarkupoHelper> 85 SwTextMarkupHelper::SwTextMarkupHelper( const SwAccessiblePortionData& rPortionData, 86 const SwTxtNode& rTxtNode ) 87 : mrPortionData( rPortionData ) 88 // --> OD 2010-02-19 #i108125# 89 , mpTxtNode( &rTxtNode ) 90 , mpTextMarkupList( 0 ) 91 // <-- 92 { 93 } 94 95 // --> OD 2010-02-19 #i108125# 96 SwTextMarkupHelper::SwTextMarkupHelper( const SwAccessiblePortionData& rPortionData, 97 const SwWrongList& rTextMarkupList ) 98 : mrPortionData( rPortionData ) 99 , mpTxtNode( 0 ) 100 , mpTextMarkupList( &rTextMarkupList ) 101 { 102 } 103 // <-- 104 105 sal_Int32 SwTextMarkupHelper::getTextMarkupCount( const sal_Int32 nTextMarkupType ) 106 throw (::com::sun::star::lang::IllegalArgumentException, 107 ::com::sun::star::uno::RuntimeException) 108 { 109 sal_Int32 nTextMarkupCount( 0 ); 110 111 // --> OD 2010-02-19 #i108125# 112 const SwWrongList* pTextMarkupList = 113 mpTextMarkupList 114 ? mpTextMarkupList 115 : getTextMarkupList( *mpTxtNode, nTextMarkupType ); 116 // <-- 117 if ( pTextMarkupList ) 118 { 119 nTextMarkupCount = pTextMarkupList->Count(); 120 } 121 122 return nTextMarkupCount; 123 } 124 ::com::sun::star::accessibility::TextSegment 125 SwTextMarkupHelper::getTextMarkup( const sal_Int32 nTextMarkupIndex, 126 const sal_Int32 nTextMarkupType ) 127 throw (::com::sun::star::lang::IndexOutOfBoundsException, 128 ::com::sun::star::lang::IllegalArgumentException, 129 ::com::sun::star::uno::RuntimeException) 130 { 131 if ( nTextMarkupIndex >= getTextMarkupCount( nTextMarkupType ) || 132 nTextMarkupIndex < 0 ) 133 { 134 throw lang::IndexOutOfBoundsException(); 135 } 136 137 ::com::sun::star::accessibility::TextSegment aTextMarkupSegment; 138 aTextMarkupSegment.SegmentStart = -1; 139 aTextMarkupSegment.SegmentEnd = -1; 140 141 // --> OD 2010-02-19 #i108125# 142 const SwWrongList* pTextMarkupList = 143 mpTextMarkupList 144 ? mpTextMarkupList 145 : getTextMarkupList( *mpTxtNode, nTextMarkupType ); 146 // <-- 147 if ( pTextMarkupList ) 148 { 149 const SwWrongArea* pTextMarkup = 150 pTextMarkupList->GetElement( static_cast<sal_uInt16>(nTextMarkupIndex) ); 151 if ( pTextMarkup ) 152 { 153 const ::rtl::OUString rText = mrPortionData.GetAccessibleString(); 154 const sal_Int32 nStartPos = 155 mrPortionData.GetAccessiblePosition( pTextMarkup->mnPos ); 156 const sal_Int32 nEndPos = 157 mrPortionData.GetAccessiblePosition( pTextMarkup->mnPos + pTextMarkup->mnLen ); 158 aTextMarkupSegment.SegmentText = rText.copy( nStartPos, nEndPos - nStartPos ); 159 aTextMarkupSegment.SegmentStart = nStartPos; 160 aTextMarkupSegment.SegmentEnd = nEndPos; 161 } 162 else 163 { 164 ASSERT( false, 165 "<SwTextMarkupHelper::getTextMarkup(..)> - missing <SwWrongArea> instance" ); 166 } 167 } 168 169 return aTextMarkupSegment; 170 } 171 172 ::com::sun::star::uno::Sequence< ::com::sun::star::accessibility::TextSegment > 173 SwTextMarkupHelper::getTextMarkupAtIndex( const sal_Int32 nCharIndex, 174 const sal_Int32 nTextMarkupType ) 175 throw (::com::sun::star::lang::IndexOutOfBoundsException, 176 ::com::sun::star::lang::IllegalArgumentException, 177 ::com::sun::star::uno::RuntimeException) 178 { 179 // assumption: 180 // value of <nCharIndex> is in range [0..length of accessible text) 181 182 const sal_uInt16 nCoreCharIndex = mrPortionData.GetModelPosition( nCharIndex ); 183 // Handling of portions with core length == 0 at the beginning of the 184 // paragraph - e.g. numbering portion. 185 if ( mrPortionData.GetAccessiblePosition( nCoreCharIndex ) > nCharIndex ) 186 { 187 return uno::Sequence< ::com::sun::star::accessibility::TextSegment >(); 188 } 189 190 // --> OD 2010-02-19 #i108125# 191 const SwWrongList* pTextMarkupList = 192 mpTextMarkupList 193 ? mpTextMarkupList 194 : getTextMarkupList( *mpTxtNode, nTextMarkupType ); 195 // <-- 196 ::std::vector< ::com::sun::star::accessibility::TextSegment > aTmpTextMarkups; 197 if ( pTextMarkupList ) 198 { 199 const ::rtl::OUString rText = mrPortionData.GetAccessibleString(); 200 201 const sal_uInt16 nTextMarkupCount = pTextMarkupList->Count(); 202 for ( sal_uInt16 nTextMarkupIdx = 0; nTextMarkupIdx < nTextMarkupCount; ++nTextMarkupIdx ) 203 { 204 const SwWrongArea* pTextMarkup = 205 pTextMarkupList->GetElement( static_cast<sal_uInt16>(nTextMarkupIdx) ); 206 ASSERT( pTextMarkup, 207 "<SwTextMarkupHelper::getTextMarkup(..)> - missing <SwWrongArea> instance" ); 208 if ( pTextMarkup && 209 pTextMarkup->mnPos <= nCoreCharIndex && 210 nCoreCharIndex < ( pTextMarkup->mnPos + pTextMarkup->mnLen ) ) 211 { 212 const sal_Int32 nStartPos = 213 mrPortionData.GetAccessiblePosition( pTextMarkup->mnPos ); 214 const sal_Int32 nEndPos = 215 mrPortionData.GetAccessiblePosition( pTextMarkup->mnPos + pTextMarkup->mnLen ); 216 ::com::sun::star::accessibility::TextSegment aTextMarkupSegment; 217 aTextMarkupSegment.SegmentText = rText.copy( nStartPos, nEndPos - nStartPos ); 218 aTextMarkupSegment.SegmentStart = nStartPos; 219 aTextMarkupSegment.SegmentEnd = nEndPos; 220 aTmpTextMarkups.push_back( aTextMarkupSegment ); 221 } 222 } 223 } 224 225 uno::Sequence< ::com::sun::star::accessibility::TextSegment > aTextMarkups( 226 aTmpTextMarkups.size() ); 227 ::std::copy( aTmpTextMarkups.begin(), aTmpTextMarkups.end(), 228 ::comphelper::stl_begin( aTextMarkups ) ); 229 230 return aTextMarkups; 231 } 232