1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #include "precompiled_sw.hxx" 25 26 #include <textmarkuphelper.hxx> 27 #include <accportions.hxx> 28 29 #include <vector> 30 #include <algorithm> 31 #include <comphelper/stlunosequence.hxx> 32 33 #include <errhdl.hxx> 34 35 #include <com/sun/star/text/TextMarkupType.hpp> 36 #include <com/sun/star/accessibility/TextSegment.hpp> 37 38 #include <ndtxt.hxx> 39 #include <wrong.hxx> 40 41 using namespace com::sun::star; 42 43 // helper functions 44 namespace { 45 const SwWrongList* getTextMarkupList( const SwTxtNode& rTxtNode, 46 const sal_Int32 nTextMarkupType ) 47 throw (::com::sun::star::lang::IllegalArgumentException, 48 ::com::sun::star::uno::RuntimeException) 49 { 50 const SwWrongList* pTextMarkupList( 0 ); 51 switch ( nTextMarkupType ) 52 { 53 case text::TextMarkupType::SPELLCHECK: 54 { 55 pTextMarkupList = rTxtNode.GetWrong(); 56 } 57 break; 58 case text::TextMarkupType::PROOFREADING: 59 { 60 // support not implemented yet 61 pTextMarkupList = 0; 62 } 63 break; 64 case text::TextMarkupType::SMARTTAG: 65 { 66 // support not implemented yet 67 pTextMarkupList = 0; 68 } 69 break; 70 default: 71 { 72 throw lang::IllegalArgumentException(); 73 } 74 } 75 76 return pTextMarkupList; 77 } 78 } 79 80 // implementation of class <SwTextMarkupoHelper> 81 SwTextMarkupHelper::SwTextMarkupHelper( const SwAccessiblePortionData& rPortionData, 82 const SwTxtNode& rTxtNode ) 83 : mrPortionData( rPortionData ) 84 // --> OD 2010-02-19 #i108125# 85 , mpTxtNode( &rTxtNode ) 86 , mpTextMarkupList( 0 ) 87 // <-- 88 { 89 } 90 91 // --> OD 2010-02-19 #i108125# 92 SwTextMarkupHelper::SwTextMarkupHelper( const SwAccessiblePortionData& rPortionData, 93 const SwWrongList& rTextMarkupList ) 94 : mrPortionData( rPortionData ) 95 , mpTxtNode( 0 ) 96 , mpTextMarkupList( &rTextMarkupList ) 97 { 98 } 99 // <-- 100 101 sal_Int32 SwTextMarkupHelper::getTextMarkupCount( const sal_Int32 nTextMarkupType ) 102 throw (::com::sun::star::lang::IllegalArgumentException, 103 ::com::sun::star::uno::RuntimeException) 104 { 105 sal_Int32 nTextMarkupCount( 0 ); 106 107 // --> OD 2010-02-19 #i108125# 108 const SwWrongList* pTextMarkupList = 109 mpTextMarkupList 110 ? mpTextMarkupList 111 : getTextMarkupList( *mpTxtNode, nTextMarkupType ); 112 // <-- 113 if ( pTextMarkupList ) 114 { 115 nTextMarkupCount = pTextMarkupList->Count(); 116 } 117 118 return nTextMarkupCount; 119 } 120 ::com::sun::star::accessibility::TextSegment 121 SwTextMarkupHelper::getTextMarkup( const sal_Int32 nTextMarkupIndex, 122 const sal_Int32 nTextMarkupType ) 123 throw (::com::sun::star::lang::IndexOutOfBoundsException, 124 ::com::sun::star::lang::IllegalArgumentException, 125 ::com::sun::star::uno::RuntimeException) 126 { 127 if ( nTextMarkupIndex >= getTextMarkupCount( nTextMarkupType ) || 128 nTextMarkupIndex < 0 ) 129 { 130 throw lang::IndexOutOfBoundsException(); 131 } 132 133 ::com::sun::star::accessibility::TextSegment aTextMarkupSegment; 134 aTextMarkupSegment.SegmentStart = -1; 135 aTextMarkupSegment.SegmentEnd = -1; 136 137 // --> OD 2010-02-19 #i108125# 138 const SwWrongList* pTextMarkupList = 139 mpTextMarkupList 140 ? mpTextMarkupList 141 : getTextMarkupList( *mpTxtNode, nTextMarkupType ); 142 // <-- 143 if ( pTextMarkupList ) 144 { 145 const SwWrongArea* pTextMarkup = 146 pTextMarkupList->GetElement( static_cast<sal_uInt16>(nTextMarkupIndex) ); 147 if ( pTextMarkup ) 148 { 149 const ::rtl::OUString rText = mrPortionData.GetAccessibleString(); 150 const sal_Int32 nStartPos = 151 mrPortionData.GetAccessiblePosition( pTextMarkup->mnPos ); 152 const sal_Int32 nEndPos = 153 mrPortionData.GetAccessiblePosition( pTextMarkup->mnPos + pTextMarkup->mnLen ); 154 aTextMarkupSegment.SegmentText = rText.copy( nStartPos, nEndPos - nStartPos ); 155 aTextMarkupSegment.SegmentStart = nStartPos; 156 aTextMarkupSegment.SegmentEnd = nEndPos; 157 } 158 else 159 { 160 ASSERT( false, 161 "<SwTextMarkupHelper::getTextMarkup(..)> - missing <SwWrongArea> instance" ); 162 } 163 } 164 165 return aTextMarkupSegment; 166 } 167 168 ::com::sun::star::uno::Sequence< ::com::sun::star::accessibility::TextSegment > 169 SwTextMarkupHelper::getTextMarkupAtIndex( const sal_Int32 nCharIndex, 170 const sal_Int32 nTextMarkupType ) 171 throw (::com::sun::star::lang::IndexOutOfBoundsException, 172 ::com::sun::star::lang::IllegalArgumentException, 173 ::com::sun::star::uno::RuntimeException) 174 { 175 // assumption: 176 // value of <nCharIndex> is in range [0..length of accessible text) 177 178 const sal_uInt16 nCoreCharIndex = mrPortionData.GetModelPosition( nCharIndex ); 179 // Handling of portions with core length == 0 at the beginning of the 180 // paragraph - e.g. numbering portion. 181 if ( mrPortionData.GetAccessiblePosition( nCoreCharIndex ) > nCharIndex ) 182 { 183 return uno::Sequence< ::com::sun::star::accessibility::TextSegment >(); 184 } 185 186 // --> OD 2010-02-19 #i108125# 187 const SwWrongList* pTextMarkupList = 188 mpTextMarkupList 189 ? mpTextMarkupList 190 : getTextMarkupList( *mpTxtNode, nTextMarkupType ); 191 // <-- 192 ::std::vector< ::com::sun::star::accessibility::TextSegment > aTmpTextMarkups; 193 if ( pTextMarkupList ) 194 { 195 const ::rtl::OUString rText = mrPortionData.GetAccessibleString(); 196 197 const sal_uInt16 nTextMarkupCount = pTextMarkupList->Count(); 198 for ( sal_uInt16 nTextMarkupIdx = 0; nTextMarkupIdx < nTextMarkupCount; ++nTextMarkupIdx ) 199 { 200 const SwWrongArea* pTextMarkup = 201 pTextMarkupList->GetElement( static_cast<sal_uInt16>(nTextMarkupIdx) ); 202 ASSERT( pTextMarkup, 203 "<SwTextMarkupHelper::getTextMarkup(..)> - missing <SwWrongArea> instance" ); 204 if ( pTextMarkup && 205 pTextMarkup->mnPos <= nCoreCharIndex && 206 nCoreCharIndex < ( pTextMarkup->mnPos + pTextMarkup->mnLen ) ) 207 { 208 const sal_Int32 nStartPos = 209 mrPortionData.GetAccessiblePosition( pTextMarkup->mnPos ); 210 const sal_Int32 nEndPos = 211 mrPortionData.GetAccessiblePosition( pTextMarkup->mnPos + pTextMarkup->mnLen ); 212 ::com::sun::star::accessibility::TextSegment aTextMarkupSegment; 213 aTextMarkupSegment.SegmentText = rText.copy( nStartPos, nEndPos - nStartPos ); 214 aTextMarkupSegment.SegmentStart = nStartPos; 215 aTextMarkupSegment.SegmentEnd = nEndPos; 216 aTmpTextMarkups.push_back( aTextMarkupSegment ); 217 } 218 } 219 } 220 221 uno::Sequence< ::com::sun::star::accessibility::TextSegment > aTextMarkups( 222 aTmpTextMarkups.size() ); 223 ::std::copy( aTmpTextMarkups.begin(), aTmpTextMarkups.end(), 224 ::comphelper::stl_begin( aTextMarkups ) ); 225 226 return aTextMarkups; 227 } 228