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 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_editeng.hxx" 26 #include <tools/debug.hxx> 27 28 #include <editeng/unoedhlp.hxx> 29 #include <editeng/editdata.hxx> 30 #include <editeng/editeng.hxx> 31 //IAccessibility2 Implementation 2009----- 32 #include <svl/itemset.hxx> 33 34 //-----IAccessibility2 Implementation 2009 35 //------------------------------------------------------------------------ 36 37 TYPEINIT1( SvxEditSourceHint, TextHint ); 38 39 SvxEditSourceHint::SvxEditSourceHint( sal_uLong _nId ) : 40 TextHint( _nId ), 41 mnStart( 0 ), 42 mnEnd( 0 ) 43 { 44 } 45 46 SvxEditSourceHint::SvxEditSourceHint( sal_uLong _nId, sal_uLong nValue, sal_uLong nStart, sal_uLong nEnd ) : 47 TextHint( _nId, nValue ), 48 mnStart( nStart), 49 mnEnd( nEnd ) 50 { 51 } 52 53 sal_uLong SvxEditSourceHint::GetValue() const 54 { 55 return TextHint::GetValue(); 56 } 57 58 sal_uLong SvxEditSourceHint::GetStartValue() const 59 { 60 return mnStart; 61 } 62 63 sal_uLong SvxEditSourceHint::GetEndValue() const 64 { 65 return mnEnd; 66 } 67 68 void SvxEditSourceHint::SetValue( sal_uLong n ) 69 { 70 TextHint::SetValue( n ); 71 } 72 73 void SvxEditSourceHint::SetStartValue( sal_uLong n ) 74 { 75 mnStart = n; 76 } 77 78 void SvxEditSourceHint::SetEndValue( sal_uLong n ) 79 { 80 mnEnd = n; 81 } 82 //IAccessibility2 Implementation 2009----- 83 TYPEINIT1( SvxEditSourceHintEndPara , SvxEditSourceHint ); 84 //-----IAccessibility2 Implementation 2009 85 //------------------------------------------------------------------------ 86 87 ::std::auto_ptr<SfxHint> SvxEditSourceHelper::EENotification2Hint( EENotify* aNotify ) 88 { 89 if( aNotify ) 90 { 91 switch( aNotify->eNotificationType ) 92 { 93 case EE_NOTIFY_TEXTMODIFIED: 94 return ::std::auto_ptr<SfxHint>( new TextHint( TEXT_HINT_MODIFIED, aNotify->nParagraph ) ); 95 96 case EE_NOTIFY_PARAGRAPHINSERTED: 97 return ::std::auto_ptr<SfxHint>( new TextHint( TEXT_HINT_PARAINSERTED, aNotify->nParagraph ) ); 98 99 case EE_NOTIFY_PARAGRAPHREMOVED: 100 return ::std::auto_ptr<SfxHint>( new TextHint( TEXT_HINT_PARAREMOVED, aNotify->nParagraph ) ); 101 102 case EE_NOTIFY_PARAGRAPHSMOVED: 103 return ::std::auto_ptr<SfxHint>( new SvxEditSourceHint( EDITSOURCE_HINT_PARASMOVED, aNotify->nParagraph, aNotify->nParam1, aNotify->nParam2 ) ); 104 105 case EE_NOTIFY_TEXTHEIGHTCHANGED: 106 return ::std::auto_ptr<SfxHint>( new TextHint( TEXT_HINT_TEXTHEIGHTCHANGED, aNotify->nParagraph ) ); 107 108 case EE_NOTIFY_TEXTVIEWSCROLLED: 109 return ::std::auto_ptr<SfxHint>( new TextHint( TEXT_HINT_VIEWSCROLLED ) ); 110 111 case EE_NOTIFY_TEXTVIEWSELECTIONCHANGED: 112 return ::std::auto_ptr<SfxHint>( new SvxEditSourceHint( EDITSOURCE_HINT_SELECTIONCHANGED ) ); 113 114 case EE_NOTIFY_BLOCKNOTIFICATION_START: 115 return ::std::auto_ptr<SfxHint>( new TextHint( TEXT_HINT_BLOCKNOTIFICATION_START, 0 ) ); 116 117 case EE_NOTIFY_BLOCKNOTIFICATION_END: 118 return ::std::auto_ptr<SfxHint>( new TextHint( TEXT_HINT_BLOCKNOTIFICATION_END, 0 ) ); 119 120 case EE_NOTIFY_INPUT_START: 121 return ::std::auto_ptr<SfxHint>( new TextHint( TEXT_HINT_INPUT_START, 0 ) ); 122 123 case EE_NOTIFY_INPUT_END: 124 return ::std::auto_ptr<SfxHint>( new TextHint( TEXT_HINT_INPUT_END, 0 ) ); 125 //IAccessibility2 Implementation 2009----- 126 case EE_NOTIFY_TEXTVIEWSELECTIONCHANGED_ENDD_PARA: 127 return ::std::auto_ptr<SfxHint>( new SvxEditSourceHintEndPara( EDITSOURCE_HINT_SELECTIONCHANGED ) ); 128 //-----IAccessibility2 Implementation 2009 129 default: 130 DBG_ERROR( "SvxEditSourceHelper::EENotification2Hint unknown notification" ); 131 break; 132 } 133 } 134 135 return ::std::auto_ptr<SfxHint>( new SfxHint() ); 136 } 137 sal_Bool SvxEditSourceHelper::GetAttributeRun( sal_uInt16& nStartIndex, sal_uInt16& nEndIndex, const EditEngine& rEE, sal_uInt16 nPara, sal_uInt16 nIndex, sal_Bool bInCell ) 138 { 139 // IA2 CWS introduced bInCell, but also did many other changes here. 140 // Need to verify implementation with AT (IA2 and ATK) 141 // Old implementation at the end of the method for reference... 142 143 #if 1 // IA2 CWS 144 145 //added dummy attributes for the default text 146 EECharAttribArray aCharAttribs, aTempCharAttribs; 147 rEE.GetCharAttribs( nPara, aTempCharAttribs ); 148 if ( aTempCharAttribs.Count() ) 149 { 150 sal_uInt32 nIndex2 = 0; 151 sal_uInt32 nParaLen = rEE.GetTextLen(nPara); 152 for ( sal_uInt16 nAttr = 0; nAttr < aTempCharAttribs.Count(); nAttr++ ) 153 { 154 if ( nIndex2 < aTempCharAttribs[nAttr].nStart ) 155 { 156 EECharAttrib aEEAttr; 157 aEEAttr.nStart = sal_uInt16(nIndex2); 158 aEEAttr.nEnd = aTempCharAttribs[nAttr].nStart; 159 aCharAttribs.Insert( aEEAttr, nAttr ); 160 } 161 nIndex2 = aTempCharAttribs[nAttr].nEnd; 162 aCharAttribs.Insert( aTempCharAttribs[nAttr], aCharAttribs.Count() ); 163 } 164 if ( nIndex2 != nParaLen ) 165 { 166 EECharAttrib aEEAttr; 167 aEEAttr.nStart = sal_uInt16(nIndex2); 168 aEEAttr.nEnd = sal_uInt16(nParaLen); 169 aCharAttribs.Insert( aEEAttr, aCharAttribs.Count() ); 170 } 171 } 172 // find closest index in front of nIndex 173 sal_uInt16 nAttr, nCurrIndex; 174 sal_Int32 nClosestStartIndex; 175 sal_Int32 nClosestStartIndex_s, nClosestStartIndex_e; 176 for( nAttr=0, nClosestStartIndex_s=0, nClosestStartIndex_e=0; nAttr<aCharAttribs.Count(); ++nAttr ) 177 { 178 nCurrIndex = aCharAttribs[nAttr].nStart; 179 180 //if( nCurrIndex > nIndex ) 181 // break; // aCharAttribs array is sorted in increasing order for nStart values 182 183 if( nCurrIndex > nClosestStartIndex_s && 184 nCurrIndex <= nIndex) 185 { 186 nClosestStartIndex_s = nCurrIndex; 187 } 188 nCurrIndex = aCharAttribs[nAttr].nEnd; 189 if ( nCurrIndex > nClosestStartIndex_e && 190 nCurrIndex < nIndex ) 191 { 192 nClosestStartIndex_e = nCurrIndex; 193 } 194 } 195 nClosestStartIndex = nClosestStartIndex_s > nClosestStartIndex_e ? nClosestStartIndex_s : nClosestStartIndex_e; 196 197 // find closest index behind of nIndex 198 sal_Int32 nClosestEndIndex; 199 sal_Int32 nClosestEndIndex_s, nClosestEndIndex_e; 200 for( nAttr=0, nClosestEndIndex_s=nClosestEndIndex_e=rEE.GetTextLen(nPara); nAttr<aCharAttribs.Count(); ++nAttr ) 201 { 202 nCurrIndex = aCharAttribs[nAttr].nEnd; 203 204 if( nCurrIndex > nIndex && 205 nCurrIndex < nClosestEndIndex_e ) 206 { 207 nClosestEndIndex_e = nCurrIndex; 208 } 209 nCurrIndex = aCharAttribs[nAttr].nStart; 210 if ( nCurrIndex > nIndex && 211 nCurrIndex < nClosestEndIndex_s) 212 { 213 nClosestEndIndex_s = nCurrIndex; 214 } 215 } 216 nClosestEndIndex = nClosestEndIndex_s < nClosestEndIndex_e ? nClosestEndIndex_s : nClosestEndIndex_e; 217 218 nStartIndex = static_cast<sal_uInt16>( nClosestStartIndex ); 219 nEndIndex = static_cast<sal_uInt16>( nClosestEndIndex ); 220 if ( bInCell ) 221 { 222 EPosition aStartPos( nPara, nStartIndex ), aEndPos( nPara, nEndIndex ); 223 sal_uInt32 nParaCount = rEE.GetParagraphCount(); 224 sal_uInt32 nCrrntParaLen = rEE.GetTextLen(nPara); 225 //need to find closest index in front of nIndex in the previous paragraphs 226 if ( aStartPos.nIndex == 0 ) 227 { 228 SfxItemSet aCrrntSet = rEE.GetAttribs( nPara, 0, 1, GETATTRIBS_CHARATTRIBS ); 229 for ( sal_Int32 nParaIdx = nPara-1; nParaIdx >= 0; nParaIdx-- ) 230 { 231 sal_uInt32 nLen = rEE.GetTextLen( sal_uInt16(nParaIdx) ); 232 if ( nLen ) 233 { 234 sal_uInt16 nStartIdx, nEndIdx; 235 GetAttributeRun( nStartIdx, nEndIdx, rEE, sal_uInt16(nParaIdx), sal_uInt16(nLen), sal_False ); 236 SfxItemSet aSet = rEE.GetAttribs( sal_uInt16(nParaIdx), sal_uInt16(nLen-1), sal_uInt16(nLen), GETATTRIBS_CHARATTRIBS ); 237 if ( aSet == aCrrntSet ) 238 { 239 aStartPos.nPara = sal_uInt16(nParaIdx); 240 aStartPos.nIndex = nStartIdx; 241 if ( aStartPos.nIndex != 0 ) 242 { 243 break; 244 } 245 } 246 } 247 } 248 } 249 //need find closest index behind nIndex in the following paragrphs 250 if ( aEndPos.nIndex == nCrrntParaLen ) 251 { 252 SfxItemSet aCrrntSet = rEE.GetAttribs( nPara, sal_uInt16(nCrrntParaLen-1), sal_uInt16(nCrrntParaLen), GETATTRIBS_CHARATTRIBS ); 253 for ( sal_uInt32 nParaIdx = nPara+1; nParaIdx < nParaCount; nParaIdx++ ) 254 { 255 sal_uInt32 nLen = rEE.GetTextLen( sal_uInt16(nParaIdx) ); 256 if ( nLen ) 257 { 258 sal_uInt16 nStartIdx, nEndIdx; 259 GetAttributeRun( nStartIdx, nEndIdx, rEE, sal_uInt16(nParaIdx), 0, sal_False ); 260 SfxItemSet aSet = rEE.GetAttribs( sal_uInt16(nParaIdx), 0, 1, GETATTRIBS_CHARATTRIBS ); 261 if ( aSet == aCrrntSet ) 262 { 263 aEndPos.nPara = sal_uInt16(nParaIdx); 264 aEndPos.nIndex = nEndIdx; 265 if ( aEndPos.nIndex != nLen ) 266 { 267 break; 268 } 269 } 270 } 271 } 272 } 273 nStartIndex = 0; 274 if ( aStartPos.nPara > 0 ) 275 { 276 for ( sal_uInt16 i = 0; i < aStartPos.nPara; i++ ) 277 { 278 nStartIndex += rEE.GetTextLen(i)+1; 279 } 280 } 281 nStartIndex += aStartPos.nIndex; 282 nEndIndex = 0; 283 if ( aEndPos.nPara > 0 ) 284 { 285 for ( sal_uInt16 i = 0; i < aEndPos.nPara; i++ ) 286 { 287 nEndIndex += rEE.GetTextLen(i)+1; 288 } 289 } 290 nEndIndex += aEndPos.nIndex; 291 } 292 293 return sal_True; 294 295 #else // old implementation 296 297 EECharAttribArray aCharAttribs; 298 299 rEE.GetCharAttribs( nPara, aCharAttribs ); 300 301 // find closest index in front of nIndex 302 sal_uInt16 nAttr, nCurrIndex; 303 sal_Int32 nClosestStartIndex; 304 for( nAttr=0, nClosestStartIndex=0; nAttr<aCharAttribs.Count(); ++nAttr ) 305 { 306 nCurrIndex = aCharAttribs[nAttr].nStart; 307 308 if( nCurrIndex > nIndex ) 309 break; // aCharAttribs array is sorted in increasing order for nStart values 310 311 if( nCurrIndex > nClosestStartIndex ) 312 { 313 nClosestStartIndex = nCurrIndex; 314 } 315 } 316 317 // find closest index behind of nIndex 318 sal_Int32 nClosestEndIndex; 319 for( nAttr=0, nClosestEndIndex=rEE.GetTextLen(nPara); nAttr<aCharAttribs.Count(); ++nAttr ) 320 { 321 nCurrIndex = aCharAttribs[nAttr].nEnd; 322 323 if( nCurrIndex > nIndex && 324 nCurrIndex < nClosestEndIndex ) 325 { 326 nClosestEndIndex = nCurrIndex; 327 } 328 } 329 330 nStartIndex = static_cast<sal_uInt16>( nClosestStartIndex ); 331 nEndIndex = static_cast<sal_uInt16>( nClosestEndIndex ); 332 333 return sal_True; 334 335 #endif 336 } 337 338 Point SvxEditSourceHelper::EEToUserSpace( const Point& rPoint, const Size& rEESize, bool bIsVertical ) 339 { 340 return bIsVertical ? Point( -rPoint.Y() + rEESize.Height(), rPoint.X() ) : rPoint; 341 } 342 343 Point SvxEditSourceHelper::UserSpaceToEE( const Point& rPoint, const Size& rEESize, bool bIsVertical ) 344 { 345 return bIsVertical ? Point( rPoint.Y(), -rPoint.X() + rEESize.Height() ) : rPoint; 346 } 347 348 Rectangle SvxEditSourceHelper::EEToUserSpace( const Rectangle& rRect, const Size& rEESize, bool bIsVertical ) 349 { 350 // #106775# Don't touch rect if not vertical 351 return bIsVertical ? Rectangle( EEToUserSpace(rRect.BottomLeft(), rEESize, bIsVertical), 352 EEToUserSpace(rRect.TopRight(), rEESize, bIsVertical) ) : rRect; 353 } 354 355 Rectangle SvxEditSourceHelper::UserSpaceToEE( const Rectangle& rRect, const Size& rEESize, bool bIsVertical ) 356 { 357 // #106775# Don't touch rect if not vertical 358 return bIsVertical ? Rectangle( UserSpaceToEE(rRect.TopRight(), rEESize, bIsVertical), 359 UserSpaceToEE(rRect.BottomLeft(), rEESize, bIsVertical) ) : rRect; 360 } 361