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 27 //------------------------------------------------------------------------ 28 // 29 // Global header 30 // 31 //------------------------------------------------------------------------ 32 33 #include <limits.h> 34 #include <vector> 35 #include <algorithm> 36 #include <vos/mutex.hxx> 37 #include <vcl/window.hxx> 38 #include <vcl/svapp.hxx> 39 #include <editeng/flditem.hxx> 40 #include <com/sun/star/uno/Any.hxx> 41 #include <com/sun/star/uno/Reference.hxx> 42 #include <com/sun/star/awt/Point.hpp> 43 #include <com/sun/star/awt/Rectangle.hpp> 44 #include <com/sun/star/lang/DisposedException.hpp> 45 #include <com/sun/star/accessibility/AccessibleRole.hpp> 46 #include <com/sun/star/accessibility/AccessibleTextType.hpp> 47 #include <com/sun/star/accessibility/AccessibleStateType.hpp> 48 #include <com/sun/star/accessibility/AccessibleEventId.hpp> 49 #include <comphelper/accessibleeventnotifier.hxx> 50 #include <comphelper/sequenceashashmap.hxx> 51 #include <unotools/accessiblestatesethelper.hxx> 52 #include <unotools/accessiblerelationsethelper.hxx> 53 #include <com/sun/star/accessibility/AccessibleRelationType.hpp> 54 #include <vcl/unohelp.hxx> 55 #include <editeng/editeng.hxx> 56 #include <editeng/unoprnms.hxx> 57 #include <editeng/unoipset.hxx> 58 #include <editeng/outliner.hxx> 59 #include <svl/intitem.hxx> 60 61 //------------------------------------------------------------------------ 62 // 63 // Project-local header 64 // 65 //------------------------------------------------------------------------ 66 67 #include <com/sun/star/beans/PropertyState.hpp> 68 69 //!!!#include <svx/unoshape.hxx> 70 //!!!#include <svx/dialmgr.hxx> 71 //!!!#include "accessibility.hrc" 72 73 #include <editeng/unolingu.hxx> 74 #include <editeng/unopracc.hxx> 75 #include "editeng/AccessibleEditableTextPara.hxx" 76 #include "AccessibleHyperlink.hxx" 77 78 #include <svtools/colorcfg.hxx> 79 #include <algorithm> 80 using namespace std; 81 #include "editeng.hrc" 82 #include <editeng/eerdll.hxx> 83 #include <editeng/numitem.hxx> 84 85 using namespace ::com::sun::star; 86 using namespace ::com::sun::star::beans; 87 using namespace ::com::sun::star::accessibility; 88 89 90 //------------------------------------------------------------------------ 91 // 92 // AccessibleEditableTextPara implementation 93 // 94 //------------------------------------------------------------------------ 95 96 namespace accessibility 97 { 98 99 const SvxItemPropertySet* ImplGetSvxCharAndParaPropertiesSet() 100 { 101 // PropertyMap for character and paragraph properties 102 static const SfxItemPropertyMapEntry aPropMap[] = 103 { 104 SVX_UNOEDIT_OUTLINER_PROPERTIES, 105 SVX_UNOEDIT_CHAR_PROPERTIES, 106 SVX_UNOEDIT_PARA_PROPERTIES, 107 SVX_UNOEDIT_NUMBERING_PROPERTIE, 108 {MAP_CHAR_LEN("TextUserDefinedAttributes"), EE_CHAR_XMLATTRIBS, &::getCppuType((const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >*)0) , 0, 0}, 109 {MAP_CHAR_LEN("ParaUserDefinedAttributes"), EE_PARA_XMLATTRIBS, &::getCppuType((const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >*)0) , 0, 0}, 110 {0,0,0,0,0,0} 111 }; 112 static SvxItemPropertySet aPropSet( aPropMap, EditEngine::GetGlobalItemPool() ); 113 return &aPropSet; 114 } 115 116 117 DBG_NAME( AccessibleEditableTextPara ) 118 119 // --> OD 2006-01-11 #i27138# - add parameter <_pParaManager> 120 AccessibleEditableTextPara::AccessibleEditableTextPara( 121 const uno::Reference< XAccessible >& rParent, 122 const AccessibleParaManager* _pParaManager ) 123 : AccessibleTextParaInterfaceBase( m_aMutex ), 124 mnParagraphIndex( 0 ), 125 mnIndexInParent( 0 ), 126 mpEditSource( NULL ), 127 maEEOffset( 0, 0 ), 128 mxParent( rParent ), 129 // well, that's strictly (UNO) exception safe, though not 130 // really robust. We rely on the fact that this member is 131 // constructed last, and that the constructor body catches 132 // exceptions, thus no chance for exceptions once the Id is 133 // fetched. Nevertheless, normally should employ RAII here... 134 mnNotifierClientId(::comphelper::AccessibleEventNotifier::registerClient()), 135 // --> OD 2006-01-11 #i27138# 136 mpParaManager( _pParaManager ) 137 // <-- 138 { 139 #ifdef DBG_UTIL 140 DBG_CTOR( AccessibleEditableTextPara, NULL ); 141 OSL_TRACE( "AccessibleEditableTextPara received ID: %d\n", mnNotifierClientId ); 142 #endif 143 144 try 145 { 146 // Create the state set. 147 ::utl::AccessibleStateSetHelper* pStateSet = new ::utl::AccessibleStateSetHelper (); 148 mxStateSet = pStateSet; 149 150 // these are always on 151 pStateSet->AddState( AccessibleStateType::MULTI_LINE ); 152 pStateSet->AddState( AccessibleStateType::FOCUSABLE ); 153 pStateSet->AddState( AccessibleStateType::VISIBLE ); 154 pStateSet->AddState( AccessibleStateType::SHOWING ); 155 pStateSet->AddState( AccessibleStateType::ENABLED ); 156 pStateSet->AddState( AccessibleStateType::SENSITIVE ); 157 } 158 catch( const uno::Exception& ) {} 159 } 160 161 AccessibleEditableTextPara::~AccessibleEditableTextPara() 162 { 163 DBG_DTOR( AccessibleEditableTextPara, NULL ); 164 165 // sign off from event notifier 166 if( getNotifierClientId() != -1 ) 167 { 168 try 169 { 170 ::comphelper::AccessibleEventNotifier::revokeClient( getNotifierClientId() ); 171 #ifdef DBG_UTIL 172 OSL_TRACE( "AccessibleEditableTextPara revoked ID: %d\n", mnNotifierClientId ); 173 #endif 174 } 175 catch( const uno::Exception& ) {} 176 } 177 } 178 179 ::rtl::OUString AccessibleEditableTextPara::implGetText() 180 { 181 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 182 183 return GetTextRange( 0, GetTextLen() ); 184 } 185 186 ::com::sun::star::lang::Locale AccessibleEditableTextPara::implGetLocale() 187 { 188 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 189 190 lang::Locale aLocale; 191 192 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 193 "AccessibleEditableTextPara::getLocale: paragraph index value overflow"); 194 195 // return locale of first character in the paragraph 196 return SvxLanguageToLocale(aLocale, GetTextForwarder().GetLanguage( GetParagraphIndex(), 0 )); 197 } 198 199 void AccessibleEditableTextPara::implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex ) 200 { 201 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 202 203 sal_uInt16 nStart, nEnd; 204 205 if( GetSelection( nStart, nEnd ) ) 206 { 207 nStartIndex = nStart; 208 nEndIndex = nEnd; 209 } 210 else 211 { 212 // #102234# No exception, just set to 'invalid' 213 nStartIndex = -1; 214 nEndIndex = -1; 215 } 216 } 217 218 void AccessibleEditableTextPara::implGetParagraphBoundary( ::com::sun::star::i18n::Boundary& rBoundary, sal_Int32 /*nIndex*/ ) 219 { 220 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 221 DBG_WARNING( "AccessibleEditableTextPara::implGetParagraphBoundary: only a base implementation, ignoring the index" ); 222 223 rBoundary.startPos = 0; 224 //rBoundary.endPos = GetTextLen(); 225 ::rtl::OUString sText( implGetText() ); 226 sal_Int32 nLength = sText.getLength(); 227 rBoundary.endPos = nLength; 228 } 229 230 void AccessibleEditableTextPara::implGetLineBoundary( ::com::sun::star::i18n::Boundary& rBoundary, sal_Int32 nIndex ) 231 { 232 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 233 234 SvxTextForwarder& rCacheTF = GetTextForwarder(); 235 const sal_Int32 nParaIndex = GetParagraphIndex(); 236 237 DBG_ASSERT(nParaIndex >= 0 && nParaIndex <= USHRT_MAX, 238 "AccessibleEditableTextPara::implGetLineBoundary: paragraph index value overflow"); 239 240 const sal_Int32 nTextLen = rCacheTF.GetTextLen( nParaIndex ); 241 242 CheckPosition(nIndex); 243 244 rBoundary.startPos = rBoundary.endPos = -1; 245 246 const sal_uInt16 nLineCount=rCacheTF.GetLineCount( static_cast< sal_uInt16 >( nParaIndex ) ); 247 248 if( nIndex == nTextLen ) 249 { 250 // #i17014# Special-casing one-behind-the-end character 251 if( nLineCount <= 1 ) 252 rBoundary.startPos = 0; 253 else 254 rBoundary.startPos = nTextLen - rCacheTF.GetLineLen( static_cast< sal_uInt16 >( nParaIndex ), 255 nLineCount-1 ); 256 257 rBoundary.endPos = nTextLen; 258 } 259 else 260 { 261 // normal line search 262 sal_uInt16 nLine; 263 sal_Int32 nCurIndex; 264 for( nLine=0, nCurIndex=0; nLine<nLineCount; ++nLine ) 265 { 266 nCurIndex += rCacheTF.GetLineLen( static_cast< sal_uInt16 >( nParaIndex ), nLine); 267 268 if( nCurIndex > nIndex ) 269 { 270 rBoundary.startPos = nCurIndex - rCacheTF.GetLineLen(static_cast< sal_uInt16 >( nParaIndex ), nLine); 271 rBoundary.endPos = nCurIndex; 272 break; 273 } 274 } 275 } 276 } 277 278 int AccessibleEditableTextPara::getNotifierClientId() const 279 { 280 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 281 282 return mnNotifierClientId; 283 } 284 285 void AccessibleEditableTextPara::SetIndexInParent( sal_Int32 nIndex ) 286 { 287 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 288 289 mnIndexInParent = nIndex; 290 } 291 292 sal_Int32 AccessibleEditableTextPara::GetIndexInParent() const 293 { 294 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 295 296 return mnIndexInParent; 297 } 298 299 void AccessibleEditableTextPara::SetParagraphIndex( sal_Int32 nIndex ) 300 { 301 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 302 303 sal_Int32 nOldIndex = mnParagraphIndex; 304 305 mnParagraphIndex = nIndex; 306 307 WeakBullet::HardRefType aChild( maImageBullet.get() ); 308 if( aChild.is() ) 309 aChild->SetParagraphIndex(mnParagraphIndex); 310 311 try 312 { 313 if( nOldIndex != nIndex ) 314 { 315 uno::Any aOldDesc; 316 uno::Any aOldName; 317 318 try 319 { 320 aOldDesc <<= getAccessibleDescription(); 321 aOldName <<= getAccessibleName(); 322 } 323 catch( const uno::Exception& ) {} // optional behaviour 324 // index and therefore description changed 325 FireEvent( AccessibleEventId::DESCRIPTION_CHANGED, uno::makeAny( getAccessibleDescription() ), aOldDesc ); 326 FireEvent( AccessibleEventId::NAME_CHANGED, uno::makeAny( getAccessibleName() ), aOldName ); 327 } 328 } 329 catch( const uno::Exception& ) {} // optional behaviour 330 } 331 332 sal_Int32 AccessibleEditableTextPara::GetParagraphIndex() const SAL_THROW((uno::RuntimeException)) 333 { 334 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 335 336 return mnParagraphIndex; 337 } 338 339 void AccessibleEditableTextPara::Dispose() 340 { 341 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 342 343 int nClientId( getNotifierClientId() ); 344 345 // #108212# drop all references before notifying dispose 346 mxParent = NULL; 347 mnNotifierClientId = -1; 348 mpEditSource = NULL; 349 350 // notify listeners 351 if( nClientId != -1 ) 352 { 353 try 354 { 355 uno::Reference < XAccessibleContext > xThis = getAccessibleContext(); 356 357 // #106234# Delegate to EventNotifier 358 ::comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( nClientId, xThis ); 359 #ifdef DBG_UTIL 360 OSL_TRACE( "Disposed ID: %d\n", nClientId ); 361 #endif 362 } 363 catch( const uno::Exception& ) {} 364 } 365 } 366 367 void AccessibleEditableTextPara::SetEditSource( SvxEditSourceAdapter* pEditSource ) 368 { 369 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 370 371 WeakBullet::HardRefType aChild( maImageBullet.get() ); 372 if( aChild.is() ) 373 aChild->SetEditSource(pEditSource); 374 375 if( !pEditSource ) 376 { 377 // going defunc 378 UnSetState( AccessibleStateType::SHOWING ); 379 UnSetState( AccessibleStateType::VISIBLE ); 380 SetState( AccessibleStateType::INVALID ); 381 SetState( AccessibleStateType::DEFUNC ); 382 383 Dispose(); 384 } 385 mpEditSource = pEditSource; 386 // #108900# Init last text content 387 try 388 { 389 TextChanged(); 390 } 391 catch( const uno::RuntimeException& ) {} 392 } 393 394 ESelection AccessibleEditableTextPara::MakeSelection( sal_Int32 nStartEEIndex, sal_Int32 nEndEEIndex ) 395 { 396 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 397 398 // check overflow 399 DBG_ASSERT(nStartEEIndex >= 0 && nStartEEIndex <= USHRT_MAX && 400 nEndEEIndex >= 0 && nEndEEIndex <= USHRT_MAX && 401 GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 402 "AccessibleEditableTextPara::MakeSelection: index value overflow"); 403 404 sal_uInt16 nParaIndex = static_cast< sal_uInt16 >( GetParagraphIndex() ); 405 return ESelection( nParaIndex, static_cast< sal_uInt16 >( nStartEEIndex ), 406 nParaIndex, static_cast< sal_uInt16 >( nEndEEIndex ) ); 407 } 408 409 ESelection AccessibleEditableTextPara::MakeSelection( sal_Int32 nEEIndex ) 410 { 411 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 412 413 return MakeSelection( nEEIndex, nEEIndex+1 ); 414 } 415 416 ESelection AccessibleEditableTextPara::MakeCursor( sal_Int32 nEEIndex ) 417 { 418 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 419 420 return MakeSelection( nEEIndex, nEEIndex ); 421 } 422 423 void AccessibleEditableTextPara::CheckIndex( sal_Int32 nIndex ) SAL_THROW((lang::IndexOutOfBoundsException, uno::RuntimeException)) 424 { 425 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 426 427 if( nIndex < 0 || nIndex >= getCharacterCount() ) 428 throw lang::IndexOutOfBoundsException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleEditableTextPara: character index out of bounds")), 429 uno::Reference< uno::XInterface > 430 ( static_cast< ::cppu::OWeakObject* > (this) ) ); // disambiguate hierarchy 431 } 432 433 void AccessibleEditableTextPara::CheckPosition( sal_Int32 nIndex ) SAL_THROW((lang::IndexOutOfBoundsException, uno::RuntimeException)) 434 { 435 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 436 437 if( nIndex < 0 || nIndex > getCharacterCount() ) 438 throw lang::IndexOutOfBoundsException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleEditableTextPara: character position out of bounds")), 439 uno::Reference< uno::XInterface > 440 ( static_cast< ::cppu::OWeakObject* > (this) ) ); // disambiguate hierarchy 441 } 442 443 void AccessibleEditableTextPara::CheckRange( sal_Int32 nStart, sal_Int32 nEnd ) SAL_THROW((lang::IndexOutOfBoundsException, uno::RuntimeException)) 444 { 445 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 446 447 CheckPosition( nStart ); 448 CheckPosition( nEnd ); 449 } 450 451 sal_Bool AccessibleEditableTextPara::GetSelection( sal_uInt16& nStartPos, sal_uInt16& nEndPos ) SAL_THROW((uno::RuntimeException)) 452 { 453 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 454 455 ESelection aSelection; 456 sal_uInt16 nPara = static_cast< sal_uInt16 > ( GetParagraphIndex() ); 457 if( !GetEditViewForwarder().GetSelection( aSelection ) ) 458 return sal_False; 459 460 if( aSelection.nStartPara < aSelection.nEndPara ) 461 { 462 if( aSelection.nStartPara > nPara || 463 aSelection.nEndPara < nPara ) 464 return sal_False; 465 466 if( nPara == aSelection.nStartPara ) 467 nStartPos = aSelection.nStartPos; 468 else 469 nStartPos = 0; 470 471 if( nPara == aSelection.nEndPara ) 472 nEndPos = aSelection.nEndPos; 473 else 474 nEndPos = GetTextLen(); 475 } 476 else 477 { 478 if( aSelection.nStartPara < nPara || 479 aSelection.nEndPara > nPara ) 480 return sal_False; 481 482 if( nPara == aSelection.nStartPara ) 483 nStartPos = aSelection.nStartPos; 484 else 485 nStartPos = GetTextLen(); 486 487 if( nPara == aSelection.nEndPara ) 488 nEndPos = aSelection.nEndPos; 489 else 490 nEndPos = 0; 491 } 492 493 return sal_True; 494 } 495 496 String AccessibleEditableTextPara::GetText( sal_Int32 nIndex ) SAL_THROW((uno::RuntimeException)) 497 { 498 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 499 500 return GetTextForwarder().GetText( MakeSelection(nIndex) ); 501 } 502 503 String AccessibleEditableTextPara::GetTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) SAL_THROW((uno::RuntimeException)) 504 { 505 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 506 507 return GetTextForwarder().GetText( MakeSelection(nStartIndex, nEndIndex) ); 508 } 509 510 sal_uInt16 AccessibleEditableTextPara::GetTextLen() const SAL_THROW((uno::RuntimeException)) 511 { 512 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 513 514 return GetTextForwarder().GetTextLen( GetParagraphIndex() ); 515 } 516 517 sal_Bool AccessibleEditableTextPara::IsVisible() const 518 { 519 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 520 521 return mpEditSource ? sal_True : sal_False ; 522 } 523 524 uno::Reference< XAccessibleText > AccessibleEditableTextPara::GetParaInterface( sal_Int32 nIndex ) 525 { 526 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 527 528 uno::Reference< XAccessible > xParent = getAccessibleParent(); 529 if( xParent.is() ) 530 { 531 uno::Reference< XAccessibleContext > xParentContext = xParent->getAccessibleContext(); 532 if( xParentContext.is() ) 533 { 534 uno::Reference< XAccessible > xPara = xParentContext->getAccessibleChild( nIndex ); 535 if( xPara.is() ) 536 { 537 return uno::Reference< XAccessibleText > ( xPara, uno::UNO_QUERY ); 538 } 539 } 540 } 541 542 return uno::Reference< XAccessibleText >(); 543 } 544 545 SvxEditSourceAdapter& AccessibleEditableTextPara::GetEditSource() const SAL_THROW((uno::RuntimeException)) 546 { 547 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 548 549 if( mpEditSource ) 550 return *mpEditSource; 551 else 552 throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("No edit source, object is defunct")), 553 uno::Reference< uno::XInterface > 554 ( static_cast< ::cppu::OWeakObject* > 555 ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy 556 } 557 558 SvxAccessibleTextAdapter& AccessibleEditableTextPara::GetTextForwarder() const SAL_THROW((uno::RuntimeException)) 559 { 560 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 561 562 SvxEditSourceAdapter& rEditSource = GetEditSource(); 563 SvxAccessibleTextAdapter* pTextForwarder = rEditSource.GetTextForwarderAdapter(); 564 565 if( !pTextForwarder ) 566 throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Unable to fetch text forwarder, object is defunct")), 567 uno::Reference< uno::XInterface > 568 ( static_cast< ::cppu::OWeakObject* > 569 ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy 570 571 if( pTextForwarder->IsValid() ) 572 return *pTextForwarder; 573 else 574 throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Text forwarder is invalid, object is defunct")), 575 uno::Reference< uno::XInterface > 576 ( static_cast< ::cppu::OWeakObject* > 577 ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy 578 } 579 580 SvxViewForwarder& AccessibleEditableTextPara::GetViewForwarder() const SAL_THROW((uno::RuntimeException)) 581 { 582 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 583 584 SvxEditSource& rEditSource = GetEditSource(); 585 SvxViewForwarder* pViewForwarder = rEditSource.GetViewForwarder(); 586 587 if( !pViewForwarder ) 588 { 589 throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Unable to fetch view forwarder, object is defunct")), 590 uno::Reference< uno::XInterface > 591 ( static_cast< ::cppu::OWeakObject* > 592 ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy 593 } 594 595 if( pViewForwarder->IsValid() ) 596 return *pViewForwarder; 597 else 598 throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("View forwarder is invalid, object is defunct")), 599 uno::Reference< uno::XInterface > 600 ( static_cast< ::cppu::OWeakObject* > 601 ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy 602 } 603 604 SvxAccessibleTextEditViewAdapter& AccessibleEditableTextPara::GetEditViewForwarder( sal_Bool bCreate ) const SAL_THROW((uno::RuntimeException)) 605 { 606 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 607 608 SvxEditSourceAdapter& rEditSource = GetEditSource(); 609 SvxAccessibleTextEditViewAdapter* pTextEditViewForwarder = rEditSource.GetEditViewForwarderAdapter( bCreate ); 610 611 if( !pTextEditViewForwarder ) 612 { 613 if( bCreate ) 614 throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Unable to fetch view forwarder, object is defunct")), 615 uno::Reference< uno::XInterface > 616 ( static_cast< ::cppu::OWeakObject* > 617 ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy 618 else 619 throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("No view forwarder, object not in edit mode")), 620 uno::Reference< uno::XInterface > 621 ( static_cast< ::cppu::OWeakObject* > 622 ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy 623 } 624 625 if( pTextEditViewForwarder->IsValid() ) 626 return *pTextEditViewForwarder; 627 else 628 { 629 if( bCreate ) 630 throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("View forwarder is invalid, object is defunct")), 631 uno::Reference< uno::XInterface > 632 ( static_cast< ::cppu::OWeakObject* > 633 ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy 634 else 635 throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("View forwarder is invalid, object not in edit mode")), 636 uno::Reference< uno::XInterface > 637 ( static_cast< ::cppu::OWeakObject* > 638 ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy 639 } 640 } 641 642 sal_Bool AccessibleEditableTextPara::HaveEditView() const 643 { 644 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 645 646 SvxEditSource& rEditSource = GetEditSource(); 647 SvxEditViewForwarder* pViewForwarder = rEditSource.GetEditViewForwarder(); 648 649 if( !pViewForwarder ) 650 return sal_False; 651 652 if( !pViewForwarder->IsValid() ) 653 return sal_False; 654 655 return sal_True; 656 } 657 658 sal_Bool AccessibleEditableTextPara::HaveChildren() 659 { 660 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 661 662 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 663 "AccessibleEditableTextPara::HaveChildren: paragraph index value overflow"); 664 665 return GetTextForwarder().HaveImageBullet( static_cast< sal_uInt16 >(GetParagraphIndex()) ); 666 } 667 668 sal_Bool AccessibleEditableTextPara::IsActive() const SAL_THROW((uno::RuntimeException)) 669 { 670 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 671 672 SvxEditSource& rEditSource = GetEditSource(); 673 SvxEditViewForwarder* pViewForwarder = rEditSource.GetEditViewForwarder(); 674 675 if( !pViewForwarder ) 676 return sal_False; 677 678 if( pViewForwarder->IsValid() ) 679 return sal_False; 680 else 681 return sal_True; 682 } 683 684 Rectangle AccessibleEditableTextPara::LogicToPixel( const Rectangle& rRect, const MapMode& rMapMode, SvxViewForwarder& rForwarder ) 685 { 686 // convert to screen coordinates 687 return Rectangle( rForwarder.LogicToPixel( rRect.TopLeft(), rMapMode ), 688 rForwarder.LogicToPixel( rRect.BottomRight(), rMapMode ) ); 689 } 690 691 const Point& AccessibleEditableTextPara::GetEEOffset() const 692 { 693 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 694 695 return maEEOffset; 696 } 697 698 void AccessibleEditableTextPara::SetEEOffset( const Point& rOffset ) 699 { 700 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 701 702 WeakBullet::HardRefType aChild( maImageBullet.get() ); 703 if( aChild.is() ) 704 aChild->SetEEOffset(rOffset); 705 706 maEEOffset = rOffset; 707 } 708 709 void AccessibleEditableTextPara::FireEvent(const sal_Int16 nEventId, const uno::Any& rNewValue, const uno::Any& rOldValue) const 710 { 711 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 712 713 uno::Reference < XAccessibleContext > xThis( const_cast< AccessibleEditableTextPara* > (this)->getAccessibleContext() ); 714 715 AccessibleEventObject aEvent(xThis, nEventId, rNewValue, rOldValue); 716 717 // #102261# Call global queue for focus events 718 if( nEventId == AccessibleEventId::STATE_CHANGED ) 719 vcl::unohelper::NotifyAccessibleStateEventGlobally( aEvent ); 720 721 // #106234# Delegate to EventNotifier 722 if( getNotifierClientId() != -1 ) 723 ::comphelper::AccessibleEventNotifier::addEvent( getNotifierClientId(), 724 aEvent ); 725 } 726 727 void AccessibleEditableTextPara::GotPropertyEvent( const uno::Any& rNewValue, const sal_Int16 nEventId ) const 728 { 729 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 730 731 FireEvent( nEventId, rNewValue ); 732 } 733 734 void AccessibleEditableTextPara::LostPropertyEvent( const uno::Any& rOldValue, const sal_Int16 nEventId ) const 735 { 736 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 737 738 FireEvent( nEventId, uno::Any(), rOldValue ); 739 } 740 741 bool AccessibleEditableTextPara::HasState( const sal_Int16 nStateId ) 742 { 743 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 744 745 ::utl::AccessibleStateSetHelper* pStateSet = static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get()); 746 if( pStateSet != NULL ) 747 return pStateSet->contains(nStateId) ? true : false; 748 749 return false; 750 } 751 752 void AccessibleEditableTextPara::SetState( const sal_Int16 nStateId ) 753 { 754 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 755 756 ::utl::AccessibleStateSetHelper* pStateSet = static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get()); 757 if( pStateSet != NULL && 758 !pStateSet->contains(nStateId) ) 759 { 760 pStateSet->AddState( nStateId ); 761 // MT: Removed method IsShapeParaFocusable which was introduced with IA2 - basically it was only about figuring out whether or not the window has the focus, should be solved differently 762 // if(IsShapeParaFocusable()) 763 GotPropertyEvent( uno::makeAny( nStateId ), AccessibleEventId::STATE_CHANGED ); 764 } 765 } 766 767 void AccessibleEditableTextPara::UnSetState( const sal_Int16 nStateId ) 768 { 769 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 770 771 ::utl::AccessibleStateSetHelper* pStateSet = static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get()); 772 if( pStateSet != NULL && 773 pStateSet->contains(nStateId) ) 774 { 775 pStateSet->RemoveState( nStateId ); 776 LostPropertyEvent( uno::makeAny( nStateId ), AccessibleEventId::STATE_CHANGED ); 777 } 778 } 779 780 void AccessibleEditableTextPara::TextChanged() 781 { 782 ::rtl::OUString aCurrentString( OCommonAccessibleText::getText() ); 783 uno::Any aDeleted; 784 uno::Any aInserted; 785 if( OCommonAccessibleText::implInitTextChangedEvent( maLastTextString, aCurrentString, 786 aDeleted, aInserted) ) 787 { 788 FireEvent( AccessibleEventId::TEXT_CHANGED, aInserted, aDeleted ); 789 maLastTextString = aCurrentString; 790 } 791 } 792 793 sal_Bool AccessibleEditableTextPara::GetAttributeRun( sal_uInt16& nStartIndex, sal_uInt16& nEndIndex, sal_Int32 nIndex ) 794 { 795 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 796 797 DBG_ASSERT(nIndex >= 0 && nIndex <= USHRT_MAX, 798 "AccessibleEditableTextPara::GetAttributeRun: index value overflow"); 799 800 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= SAL_MAX_UINT32, 801 "AccessibleEditableTextPara::getLocale: paragraph index value overflow"); 802 803 return GetTextForwarder().GetAttributeRun( nStartIndex, 804 nEndIndex, 805 GetParagraphIndex(), 806 static_cast< sal_uInt16 >(nIndex) ); 807 } 808 809 uno::Any SAL_CALL AccessibleEditableTextPara::queryInterface (const uno::Type & rType) throw (uno::RuntimeException) 810 { 811 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 812 813 uno::Any aRet; 814 815 // must provide XAccesibleText by hand, since it comes publicly inherited by XAccessibleEditableText 816 if ( rType == ::getCppuType((uno::Reference< XAccessibleText > *)0) ) 817 { 818 uno::Reference< XAccessibleText > aAccText = static_cast< XAccessibleEditableText * >(this); 819 aRet <<= aAccText; 820 } 821 else if ( rType == ::getCppuType((uno::Reference< XAccessibleEditableText > *)0) ) 822 { 823 uno::Reference< XAccessibleEditableText > aAccEditText = this; 824 aRet <<= aAccEditText; 825 } 826 else if ( rType == ::getCppuType((uno::Reference< XAccessibleHypertext > *)0) ) 827 { 828 uno::Reference< XAccessibleHypertext > aAccHyperText = this; 829 aRet <<= aAccHyperText; 830 } 831 else 832 { 833 aRet = AccessibleTextParaInterfaceBase::queryInterface(rType); 834 } 835 836 return aRet; 837 } 838 839 // XAccessible 840 uno::Reference< XAccessibleContext > SAL_CALL AccessibleEditableTextPara::getAccessibleContext() throw (uno::RuntimeException) 841 { 842 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 843 844 // We implement the XAccessibleContext interface in the same object 845 return uno::Reference< XAccessibleContext > ( this ); 846 } 847 848 // XAccessibleContext 849 sal_Int32 SAL_CALL AccessibleEditableTextPara::getAccessibleChildCount() throw (uno::RuntimeException) 850 { 851 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 852 853 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 854 855 return HaveChildren() ? 1 : 0; 856 } 857 858 uno::Reference< XAccessible > SAL_CALL AccessibleEditableTextPara::getAccessibleChild( sal_Int32 i ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 859 { 860 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 861 862 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 863 864 if( !HaveChildren() ) 865 throw lang::IndexOutOfBoundsException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("No childs available")), 866 uno::Reference< uno::XInterface > 867 ( static_cast< ::cppu::OWeakObject* > (this) ) ); // static_cast: disambiguate hierarchy 868 869 if( i != 0 ) 870 throw lang::IndexOutOfBoundsException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Invalid child index")), 871 uno::Reference< uno::XInterface > 872 ( static_cast< ::cppu::OWeakObject* > (this) ) ); // static_cast: disambiguate hierarchy 873 874 WeakBullet::HardRefType aChild( maImageBullet.get() ); 875 876 if( !aChild.is() ) 877 { 878 // there is no hard reference available, create object then 879 AccessibleImageBullet* pChild = new AccessibleImageBullet( uno::Reference< XAccessible >( this ) ); 880 uno::Reference< XAccessible > xChild( static_cast< ::cppu::OWeakObject* > (pChild), uno::UNO_QUERY ); 881 882 if( !xChild.is() ) 883 throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Child creation failed")), 884 uno::Reference< uno::XInterface > 885 ( static_cast< ::cppu::OWeakObject* > (this) ) ); 886 887 aChild = WeakBullet::HardRefType( xChild, pChild ); 888 889 aChild->SetEditSource( &GetEditSource() ); 890 aChild->SetParagraphIndex( GetParagraphIndex() ); 891 aChild->SetIndexInParent( i ); 892 893 maImageBullet = aChild; 894 } 895 896 return aChild.getRef(); 897 } 898 899 uno::Reference< XAccessible > SAL_CALL AccessibleEditableTextPara::getAccessibleParent() throw (uno::RuntimeException) 900 { 901 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 902 903 #ifdef DBG_UTIL 904 if( !mxParent.is() ) 905 DBG_TRACE( "AccessibleEditableTextPara::getAccessibleParent: no frontend set, did somebody forgot to call AccessibleTextHelper::SetEventSource()?"); 906 #endif 907 908 return mxParent; 909 } 910 911 sal_Int32 SAL_CALL AccessibleEditableTextPara::getAccessibleIndexInParent() throw (uno::RuntimeException) 912 { 913 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 914 915 return mnIndexInParent; 916 } 917 918 sal_Int16 SAL_CALL AccessibleEditableTextPara::getAccessibleRole() throw (uno::RuntimeException) 919 { 920 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 921 922 return AccessibleRole::PARAGRAPH; 923 } 924 925 ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getAccessibleDescription() throw (uno::RuntimeException) 926 { 927 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 928 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 929 930 // append first 40 characters from text, or first line, if shorter 931 // (writer takes first sentence here, but that's not supported 932 // from EditEngine) 933 // throws if defunc 934 ::rtl::OUString aLine; 935 936 if( getCharacterCount() ) 937 aLine = getTextAtIndex(0, AccessibleTextType::LINE).SegmentText; 938 939 // Get the string from the resource for the specified id. 940 String sStr = ::rtl::OUString( String( EditResId (RID_SVXSTR_A11Y_PARAGRAPH_DESCRIPTION ) ) ); 941 String sParaIndex = ::rtl::OUString::valueOf( GetParagraphIndex() ); 942 sStr.SearchAndReplace( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "$(ARG)" )), 943 sParaIndex ); 944 945 if( aLine.getLength() > MaxDescriptionLen ) 946 { 947 ::rtl::OUString aCurrWord; 948 sal_Int32 i; 949 950 // search backward from MaxDescriptionLen for previous word start 951 for( aCurrWord=getTextAtIndex(MaxDescriptionLen, AccessibleTextType::WORD).SegmentText, 952 i=MaxDescriptionLen, 953 aLine=::rtl::OUString(); 954 i>=0; 955 --i ) 956 { 957 if( getTextAtIndex(i, AccessibleTextType::WORD).SegmentText != aCurrWord ) 958 { 959 if( i == 0 ) 960 // prevent completely empty string 961 aLine = getTextAtIndex(0, AccessibleTextType::WORD).SegmentText; 962 else 963 aLine = getTextRange(0, i); 964 } 965 } 966 } 967 968 return ::rtl::OUString( sStr ) + aLine; 969 } 970 971 ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getAccessibleName() throw (uno::RuntimeException) 972 { 973 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 974 975 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 976 977 // throws if defunc 978 sal_Int32 nPara( GetParagraphIndex() ); 979 980 // Get the string from the resource for the specified id. 981 String sStr = ::rtl::OUString( String( EditResId (RID_SVXSTR_A11Y_PARAGRAPH_NAME) ) ); 982 String sParaIndex = ::rtl::OUString::valueOf( nPara ); 983 sStr.SearchAndReplace( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "$(ARG)" )), 984 sParaIndex ); 985 986 return ::rtl::OUString( sStr ); 987 } 988 989 uno::Reference< XAccessibleRelationSet > SAL_CALL AccessibleEditableTextPara::getAccessibleRelationSet() throw (uno::RuntimeException) 990 { 991 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 992 993 // --> OD 2006-01-11 #i27138# - provide relations CONTENT_FLOWS_FROM 994 // and CONTENT_FLOWS_TO 995 if ( mpParaManager ) 996 { 997 utl::AccessibleRelationSetHelper* pAccRelSetHelper = 998 new utl::AccessibleRelationSetHelper(); 999 sal_Int32 nMyParaIndex( GetParagraphIndex() ); 1000 // relation CONTENT_FLOWS_FROM 1001 if ( nMyParaIndex > 0 && 1002 mpParaManager->IsReferencable( nMyParaIndex - 1 ) ) 1003 { 1004 uno::Sequence<uno::Reference<XInterface> > aSequence(1); 1005 aSequence[0] = 1006 mpParaManager->GetChild( nMyParaIndex - 1 ).first.get().getRef(); 1007 AccessibleRelation aAccRel( AccessibleRelationType::CONTENT_FLOWS_FROM, 1008 aSequence ); 1009 pAccRelSetHelper->AddRelation( aAccRel ); 1010 } 1011 1012 // relation CONTENT_FLOWS_TO 1013 if ( (nMyParaIndex + 1) < (sal_Int32)mpParaManager->GetNum() && 1014 mpParaManager->IsReferencable( nMyParaIndex + 1 ) ) 1015 { 1016 uno::Sequence<uno::Reference<XInterface> > aSequence(1); 1017 aSequence[0] = 1018 mpParaManager->GetChild( nMyParaIndex + 1 ).first.get().getRef(); 1019 AccessibleRelation aAccRel( AccessibleRelationType::CONTENT_FLOWS_TO, 1020 aSequence ); 1021 pAccRelSetHelper->AddRelation( aAccRel ); 1022 } 1023 1024 return pAccRelSetHelper; 1025 } 1026 else 1027 { 1028 // no relations, therefore empty 1029 return uno::Reference< XAccessibleRelationSet >(); 1030 } 1031 // <-- 1032 } 1033 1034 uno::Reference< XAccessibleStateSet > SAL_CALL AccessibleEditableTextPara::getAccessibleStateSet() throw (uno::RuntimeException) 1035 { 1036 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1037 1038 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1039 1040 // Create a copy of the state set and return it. 1041 ::utl::AccessibleStateSetHelper* pStateSet = static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get()); 1042 1043 if( !pStateSet ) 1044 return uno::Reference<XAccessibleStateSet>(); 1045 uno::Reference<XAccessibleStateSet> xParentStates; 1046 if (getAccessibleParent().is()) 1047 { 1048 uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext(); 1049 xParentStates = xParentContext->getAccessibleStateSet(); 1050 } 1051 if (xParentStates.is() && xParentStates->contains(AccessibleStateType::EDITABLE) ) 1052 { 1053 pStateSet->AddState(AccessibleStateType::EDITABLE); 1054 } 1055 return uno::Reference<XAccessibleStateSet>( new ::utl::AccessibleStateSetHelper (*pStateSet) ); 1056 } 1057 1058 lang::Locale SAL_CALL AccessibleEditableTextPara::getLocale() throw (IllegalAccessibleComponentStateException, uno::RuntimeException) 1059 { 1060 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1061 1062 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1063 1064 return implGetLocale(); 1065 } 1066 1067 void SAL_CALL AccessibleEditableTextPara::addEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) throw (uno::RuntimeException) 1068 { 1069 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1070 1071 if( getNotifierClientId() != -1 ) 1072 ::comphelper::AccessibleEventNotifier::addEventListener( getNotifierClientId(), xListener ); 1073 } 1074 1075 void SAL_CALL AccessibleEditableTextPara::removeEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) throw (uno::RuntimeException) 1076 { 1077 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1078 1079 if( getNotifierClientId() != -1 ) 1080 ::comphelper::AccessibleEventNotifier::removeEventListener( getNotifierClientId(), xListener ); 1081 } 1082 1083 // XAccessibleComponent 1084 sal_Bool SAL_CALL AccessibleEditableTextPara::containsPoint( const awt::Point& aTmpPoint ) throw (uno::RuntimeException) 1085 { 1086 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1087 1088 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1089 1090 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 1091 "AccessibleEditableTextPara::contains: index value overflow"); 1092 1093 awt::Rectangle aTmpRect = getBounds(); 1094 Rectangle aRect( Point(aTmpRect.X, aTmpRect.Y), Size(aTmpRect.Width, aTmpRect.Height) ); 1095 Point aPoint( aTmpPoint.X, aTmpPoint.Y ); 1096 1097 return aRect.IsInside( aPoint ); 1098 } 1099 1100 uno::Reference< XAccessible > SAL_CALL AccessibleEditableTextPara::getAccessibleAtPoint( const awt::Point& _aPoint ) throw (uno::RuntimeException) 1101 { 1102 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1103 1104 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1105 1106 if( HaveChildren() ) 1107 { 1108 // #103862# No longer need to make given position relative 1109 Point aPoint( _aPoint.X, _aPoint.Y ); 1110 1111 // respect EditEngine offset to surrounding shape/cell 1112 aPoint -= GetEEOffset(); 1113 1114 // convert to EditEngine coordinate system 1115 SvxTextForwarder& rCacheTF = GetTextForwarder(); 1116 Point aLogPoint( GetViewForwarder().PixelToLogic( aPoint, rCacheTF.GetMapMode() ) ); 1117 1118 EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo( GetParagraphIndex() ); 1119 1120 if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && 1121 aBulletInfo.bVisible && 1122 aBulletInfo.nType == SVX_NUM_BITMAP ) 1123 { 1124 Rectangle aRect = aBulletInfo.aBounds; 1125 1126 if( aRect.IsInside( aLogPoint ) ) 1127 return getAccessibleChild(0); 1128 } 1129 } 1130 1131 // no children at all, or none at given position 1132 return uno::Reference< XAccessible >(); 1133 } 1134 1135 awt::Rectangle SAL_CALL AccessibleEditableTextPara::getBounds() throw (uno::RuntimeException) 1136 { 1137 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1138 1139 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1140 1141 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 1142 "AccessibleEditableTextPara::getBounds: index value overflow"); 1143 1144 SvxTextForwarder& rCacheTF = GetTextForwarder(); 1145 Rectangle aRect = rCacheTF.GetParaBounds( GetParagraphIndex() ); 1146 1147 // convert to screen coordinates 1148 Rectangle aScreenRect = AccessibleEditableTextPara::LogicToPixel( aRect, 1149 rCacheTF.GetMapMode(), 1150 GetViewForwarder() ); 1151 1152 // offset from shape/cell 1153 Point aOffset = GetEEOffset(); 1154 1155 return awt::Rectangle( aScreenRect.Left() + aOffset.X(), 1156 aScreenRect.Top() + aOffset.Y(), 1157 aScreenRect.GetSize().Width(), 1158 aScreenRect.GetSize().Height() ); 1159 } 1160 1161 awt::Point SAL_CALL AccessibleEditableTextPara::getLocation( ) throw (uno::RuntimeException) 1162 { 1163 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1164 1165 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1166 1167 awt::Rectangle aRect = getBounds(); 1168 1169 return awt::Point( aRect.X, aRect.Y ); 1170 } 1171 1172 awt::Point SAL_CALL AccessibleEditableTextPara::getLocationOnScreen( ) throw (uno::RuntimeException) 1173 { 1174 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1175 1176 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1177 1178 // relate us to parent 1179 uno::Reference< XAccessible > xParent = getAccessibleParent(); 1180 if( xParent.is() ) 1181 { 1182 uno::Reference< XAccessibleComponent > xParentComponent( xParent, uno::UNO_QUERY ); 1183 if( xParentComponent.is() ) 1184 { 1185 awt::Point aRefPoint = xParentComponent->getLocationOnScreen(); 1186 awt::Point aPoint = getLocation(); 1187 aPoint.X += aRefPoint.X; 1188 aPoint.Y += aRefPoint.Y; 1189 1190 return aPoint; 1191 } 1192 // --> OD 2009-12-16 #i88070# 1193 // fallback to parent's <XAccessibleContext> instance 1194 else 1195 { 1196 uno::Reference< XAccessibleContext > xParentContext = xParent->getAccessibleContext(); 1197 if ( xParentContext.is() ) 1198 { 1199 uno::Reference< XAccessibleComponent > xParentContextComponent( xParentContext, uno::UNO_QUERY ); 1200 if( xParentContextComponent.is() ) 1201 { 1202 awt::Point aRefPoint = xParentContextComponent->getLocationOnScreen(); 1203 awt::Point aPoint = getLocation(); 1204 aPoint.X += aRefPoint.X; 1205 aPoint.Y += aRefPoint.Y; 1206 1207 return aPoint; 1208 } 1209 } 1210 } 1211 // <-- 1212 } 1213 1214 throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Cannot access parent")), 1215 uno::Reference< uno::XInterface > 1216 ( static_cast< XAccessible* > (this) ) ); // disambiguate hierarchy 1217 } 1218 1219 awt::Size SAL_CALL AccessibleEditableTextPara::getSize( ) throw (uno::RuntimeException) 1220 { 1221 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1222 1223 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1224 1225 awt::Rectangle aRect = getBounds(); 1226 1227 return awt::Size( aRect.Width, aRect.Height ); 1228 } 1229 1230 void SAL_CALL AccessibleEditableTextPara::grabFocus( ) throw (uno::RuntimeException) 1231 { 1232 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1233 1234 // set cursor to this paragraph 1235 setSelection(0,0); 1236 } 1237 1238 sal_Int32 SAL_CALL AccessibleEditableTextPara::getForeground( ) throw (::com::sun::star::uno::RuntimeException) 1239 { 1240 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1241 1242 // #104444# Added to XAccessibleComponent interface 1243 svtools::ColorConfig aColorConfig; 1244 sal_uInt32 nColor = aColorConfig.GetColorValue( svtools::FONTCOLOR ).nColor; 1245 return static_cast<sal_Int32>(nColor); 1246 } 1247 1248 sal_Int32 SAL_CALL AccessibleEditableTextPara::getBackground( ) throw (::com::sun::star::uno::RuntimeException) 1249 { 1250 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1251 1252 // #104444# Added to XAccessibleComponent interface 1253 Color aColor( Application::GetSettings().GetStyleSettings().GetWindowColor().GetColor() ); 1254 1255 // the background is transparent 1256 aColor.SetTransparency( 0xFF); 1257 1258 return static_cast<sal_Int32>( aColor.GetColor() ); 1259 } 1260 1261 // XAccessibleText 1262 sal_Int32 SAL_CALL AccessibleEditableTextPara::getCaretPosition() throw (uno::RuntimeException) 1263 { 1264 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1265 1266 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1267 1268 if( !HaveEditView() ) 1269 return -1; 1270 1271 ESelection aSelection; 1272 if( GetEditViewForwarder().GetSelection( aSelection ) && 1273 GetParagraphIndex() == aSelection.nEndPara ) 1274 { 1275 // caret is always nEndPara,nEndPos 1276 EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo( GetParagraphIndex() ); 1277 if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && 1278 aBulletInfo.bVisible && 1279 aBulletInfo.nType != SVX_NUM_BITMAP ) 1280 { 1281 sal_Int32 nBulletLen = aBulletInfo.aText.Len(); 1282 if( aSelection.nEndPos - nBulletLen >= 0 ) 1283 return aSelection.nEndPos - nBulletLen; 1284 } 1285 return aSelection.nEndPos; 1286 } 1287 1288 // not within this paragraph 1289 return -1; 1290 } 1291 1292 sal_Bool SAL_CALL AccessibleEditableTextPara::setCaretPosition( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 1293 { 1294 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1295 1296 return setSelection(nIndex, nIndex); 1297 } 1298 1299 sal_Unicode SAL_CALL AccessibleEditableTextPara::getCharacter( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 1300 { 1301 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1302 1303 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1304 1305 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 1306 "AccessibleEditableTextPara::getCharacter: index value overflow"); 1307 1308 return OCommonAccessibleText::getCharacter( nIndex ); 1309 } 1310 static uno::Sequence< ::rtl::OUString > getAttributeNames() 1311 { 1312 static uno::Sequence< ::rtl::OUString >* pNames = NULL; 1313 1314 if( pNames == NULL ) 1315 { 1316 uno::Sequence< ::rtl::OUString >* pSeq = new uno::Sequence< ::rtl::OUString >( 21 ); 1317 ::rtl::OUString* pStrings = pSeq->getArray(); 1318 sal_Int32 i = 0; 1319 #define STR(x) pStrings[i++] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(x)) 1320 //STR("CharBackColor"); 1321 STR("CharColor"); 1322 STR("CharContoured"); 1323 STR("CharEmphasis"); 1324 STR("CharEscapement"); 1325 STR("CharFontName"); 1326 STR("CharHeight"); 1327 STR("CharPosture"); 1328 STR("CharShadowed"); 1329 STR("CharStrikeout"); 1330 STR("CharUnderline"); 1331 STR("CharUnderlineColor"); 1332 STR("CharWeight"); 1333 STR("NumberingLevel"); 1334 STR("NumberingRules"); 1335 STR("ParaAdjust"); 1336 STR("ParaBottomMargin"); 1337 STR("ParaFirstLineIndent"); 1338 STR("ParaLeftMargin"); 1339 STR("ParaLineSpacing"); 1340 STR("ParaRightMargin"); 1341 STR("ParaTabStops"); 1342 #undef STR 1343 DBG_ASSERT( i == pSeq->getLength(), "Please adjust length" ); 1344 if( i != pSeq->getLength() ) 1345 pSeq->realloc( i ); 1346 pNames = pSeq; 1347 } 1348 return *pNames; 1349 } 1350 struct IndexCompare 1351 { 1352 const PropertyValue* pValues; 1353 IndexCompare( const PropertyValue* pVals ) : pValues(pVals) {} 1354 bool operator() ( const sal_Int32& a, const sal_Int32& b ) const 1355 { 1356 return (pValues[a].Name < pValues[b].Name) ? true : false; 1357 } 1358 }; 1359 1360 String AccessibleEditableTextPara::GetFieldTypeNameAtIndex(sal_Int32 nIndex) 1361 { 1362 String strFldType; 1363 SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); 1364 //For field object info 1365 sal_Int32 nParaIndex = GetParagraphIndex(); 1366 sal_Int32 nAllFieldLen = 0; 1367 sal_Int32 nField = rCacheTF.GetFieldCount(nParaIndex), nFoundFieldIndex = -1; 1368 EFieldInfo ree; 1369 sal_Int32 reeBegin, reeEnd; 1370 sal_Int32 nFieldType = -1; 1371 for(sal_uInt16 j = 0; j < nField; j++) 1372 { 1373 ree = rCacheTF.GetFieldInfo(nParaIndex, j); 1374 reeBegin = ree.aPosition.nIndex + nAllFieldLen; 1375 reeEnd = reeBegin + ree.aCurrentText.Len(); 1376 nAllFieldLen += (ree.aCurrentText.Len() - 1); 1377 if( reeBegin > nIndex ) 1378 { 1379 break; 1380 } 1381 if( nIndex >= reeBegin && nIndex < reeEnd ) 1382 { 1383 nFoundFieldIndex = j; 1384 break; 1385 } 1386 } 1387 if( nFoundFieldIndex >= 0 ) 1388 { 1389 // So we get a field, check its type now. 1390 nFieldType = ree.pFieldItem->GetField()->GetClassId() ; 1391 } 1392 switch(nFieldType) 1393 { 1394 case SVX_DATEFIELD: 1395 { 1396 const SvxDateField* pDateField = static_cast< const SvxDateField* >(ree.pFieldItem->GetField()); 1397 if (pDateField) 1398 { 1399 if (pDateField->GetType() == SVXDATETYPE_FIX) 1400 strFldType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("date (fixed)")); 1401 else if (pDateField->GetType() == SVXDATETYPE_VAR) 1402 strFldType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("date (variable)")); 1403 } 1404 } 1405 break; 1406 case SVX_PAGEFIELD: 1407 strFldType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("page-number")); 1408 break; 1409 //support the sheet name & pages fields 1410 case SVX_PAGESFIELD: 1411 strFldType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("page-count")); 1412 break; 1413 case SVX_TABLEFIELD: 1414 strFldType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("sheet-name")); 1415 break; 1416 //End 1417 case SVX_TIMEFIELD: 1418 strFldType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("time")); 1419 break; 1420 case SVX_EXT_TIMEFIELD: 1421 { 1422 const SvxExtTimeField* pTimeField = static_cast< const SvxExtTimeField* >(ree.pFieldItem->GetField()); 1423 if (pTimeField) 1424 { 1425 if (pTimeField->GetType() == SVXTIMETYPE_FIX) 1426 strFldType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("time (fixed)")); 1427 else if (pTimeField->GetType() == SVXTIMETYPE_VAR) 1428 strFldType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("time (variable)")); 1429 } 1430 } 1431 break; 1432 case SVX_AUTHORFIELD: 1433 strFldType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("author")); 1434 break; 1435 case SVX_EXT_FILEFIELD: 1436 case SVX_FILEFIELD: 1437 strFldType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("file name")); 1438 default: 1439 break; 1440 } 1441 return strFldType; 1442 } 1443 1444 uno::Sequence< beans::PropertyValue > SAL_CALL AccessibleEditableTextPara::getCharacterAttributes( sal_Int32 nIndex, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rRequestedAttributes ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 1445 { 1446 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1447 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1448 1449 //Skip the bullet range to ingnore the bullet text 1450 SvxTextForwarder& rCacheTF = GetTextForwarder(); 1451 EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo( GetParagraphIndex() ); 1452 if (aBulletInfo.bVisible) 1453 nIndex += aBulletInfo.aText.Len(); 1454 if (nIndex != 0 && nIndex >= getCharacterCount()) 1455 nIndex = getCharacterCount()-1; 1456 // 1457 if (nIndex != 0) 1458 CheckIndex(nIndex); // may throw IndexOutOfBoundsException 1459 1460 bool bSupplementalMode = false; 1461 uno::Sequence< ::rtl::OUString > aPropertyNames = rRequestedAttributes; 1462 if (aPropertyNames.getLength() == 0) 1463 { 1464 bSupplementalMode = true; 1465 aPropertyNames = getAttributeNames(); 1466 } 1467 // get default attribues... 1468 ::comphelper::SequenceAsHashMap aPropHashMap( getDefaultAttributes( aPropertyNames ) ); 1469 1470 // ... and override them with the direct attributes from the specific position 1471 uno::Sequence< beans::PropertyValue > aRunAttribs( getRunAttributes( nIndex, aPropertyNames ) ); 1472 sal_Int32 nRunAttribs = aRunAttribs.getLength(); 1473 const beans::PropertyValue *pRunAttrib = aRunAttribs.getConstArray(); 1474 for (sal_Int32 k = 0; k < nRunAttribs; ++k) 1475 { 1476 const beans::PropertyValue &rRunAttrib = pRunAttrib[k]; 1477 aPropHashMap[ rRunAttrib.Name ] = rRunAttrib.Value; //!! should not only be the value !! 1478 } 1479 #ifdef TL_DEBUG 1480 { 1481 uno::Sequence< rtl::OUString > aNames(1); 1482 aNames.getArray()[0] = rtl::OUString::createFromAscii("CharHeight"); 1483 const rtl::OUString *pNames = aNames.getConstArray(); 1484 const uno::Sequence< beans::PropertyValue > aAttribs( getRunAttributes( nIndex, aNames ) ); 1485 const beans::PropertyValue *pAttribs = aAttribs.getConstArray(); 1486 double d1 = -1.0; 1487 float f1 = -1.0; 1488 if (aAttribs.getLength()) 1489 { 1490 uno::Any aAny( pAttribs[0].Value ); 1491 aAny >>= d1; 1492 aAny >>= f1; 1493 } 1494 int i = 3; 1495 } 1496 #endif 1497 1498 // get resulting sequence 1499 uno::Sequence< beans::PropertyValue > aRes; 1500 aPropHashMap >> aRes; 1501 1502 // since SequenceAsHashMap ignores property handles and property state 1503 // we have to restore the property state here (property handles are 1504 // of no use to the accessibility API). 1505 sal_Int32 nRes = aRes.getLength(); 1506 beans::PropertyValue *pRes = aRes.getArray(); 1507 for (sal_Int32 i = 0; i < nRes; ++i) 1508 { 1509 beans::PropertyValue &rRes = pRes[i]; 1510 sal_Bool bIsDirectVal = sal_False; 1511 for (sal_Int32 k = 0; k < nRunAttribs && !bIsDirectVal; ++k) 1512 { 1513 if (rRes.Name == pRunAttrib[k].Name) 1514 bIsDirectVal = sal_True; 1515 } 1516 rRes.Handle = -1; 1517 rRes.State = bIsDirectVal ? PropertyState_DIRECT_VALUE : PropertyState_DEFAULT_VALUE; 1518 } 1519 if( bSupplementalMode ) 1520 { 1521 _correctValues( nIndex, aRes ); 1522 // NumberingPrefix 1523 nRes = aRes.getLength(); 1524 aRes.realloc( nRes + 1 ); 1525 pRes = aRes.getArray(); 1526 beans::PropertyValue &rRes = pRes[nRes]; 1527 rRes.Name = rtl::OUString::createFromAscii("NumberingPrefix"); 1528 ::rtl::OUString numStr; 1529 if (aBulletInfo.nType != SVX_NUM_CHAR_SPECIAL && aBulletInfo.nType != SVX_NUM_BITMAP) 1530 numStr = (::rtl::OUString)aBulletInfo.aText; 1531 rRes.Value <<= numStr; 1532 rRes.Handle = -1; 1533 rRes.State = PropertyState_DIRECT_VALUE; 1534 //For field object. 1535 String strFieldType = GetFieldTypeNameAtIndex(nIndex); 1536 if (strFieldType.Len() > 0) 1537 { 1538 nRes = aRes.getLength(); 1539 aRes.realloc( nRes + 1 ); 1540 pRes = aRes.getArray(); 1541 beans::PropertyValue &rResField = pRes[nRes]; 1542 beans::PropertyValue aFieldType; 1543 rResField.Name = rtl::OUString::createFromAscii("FieldType"); 1544 rResField.Value <<= rtl::OUString(strFieldType.ToLowerAscii()); 1545 rResField.Handle = -1; 1546 rResField.State = PropertyState_DIRECT_VALUE; 1547 } 1548 //sort property values 1549 // build sorted index array 1550 sal_Int32 nLength = aRes.getLength(); 1551 const beans::PropertyValue* pPairs = aRes.getConstArray(); 1552 sal_Int32* pIndices = new sal_Int32[nLength]; 1553 sal_Int32 i = 0; 1554 for( i = 0; i < nLength; i++ ) 1555 pIndices[i] = i; 1556 sort( &pIndices[0], &pIndices[nLength], IndexCompare(pPairs) ); 1557 // create sorted sequences according to index array 1558 uno::Sequence<beans::PropertyValue> aNewValues( nLength ); 1559 beans::PropertyValue* pNewValues = aNewValues.getArray(); 1560 for( i = 0; i < nLength; i++ ) 1561 { 1562 pNewValues[i] = pPairs[pIndices[i]]; 1563 } 1564 delete[] pIndices; 1565 // 1566 return aNewValues; 1567 } 1568 return aRes; 1569 } 1570 1571 awt::Rectangle SAL_CALL AccessibleEditableTextPara::getCharacterBounds( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 1572 { 1573 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1574 1575 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1576 1577 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 1578 "AccessibleEditableTextPara::getCharacterBounds: index value overflow"); 1579 1580 // #108900# Have position semantics now for nIndex, as 1581 // one-past-the-end values are legal, too. 1582 CheckPosition( nIndex ); 1583 1584 SvxTextForwarder& rCacheTF = GetTextForwarder(); 1585 Rectangle aRect = rCacheTF.GetCharBounds( GetParagraphIndex(), static_cast< sal_uInt16 >( nIndex ) ); 1586 1587 // convert to screen 1588 Rectangle aScreenRect = AccessibleEditableTextPara::LogicToPixel( aRect, 1589 rCacheTF.GetMapMode(), 1590 GetViewForwarder() ); 1591 // #109864# offset from parent (paragraph), but in screen 1592 // coordinates. This makes sure the internal text offset in 1593 // the outline view forwarder gets cancelled out here 1594 awt::Rectangle aParaRect( getBounds() ); 1595 aScreenRect.Move( -aParaRect.X, -aParaRect.Y ); 1596 1597 // offset from shape/cell 1598 Point aOffset = GetEEOffset(); 1599 1600 return awt::Rectangle( aScreenRect.Left() + aOffset.X(), 1601 aScreenRect.Top() + aOffset.Y(), 1602 aScreenRect.GetSize().Width(), 1603 aScreenRect.GetSize().Height() ); 1604 } 1605 1606 sal_Int32 SAL_CALL AccessibleEditableTextPara::getCharacterCount() throw (uno::RuntimeException) 1607 { 1608 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1609 1610 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1611 1612 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 1613 "AccessibleEditableTextPara::getCharacterCount: index value overflow"); 1614 1615 return OCommonAccessibleText::getCharacterCount(); 1616 } 1617 1618 sal_Int32 SAL_CALL AccessibleEditableTextPara::getIndexAtPoint( const awt::Point& rPoint ) throw (uno::RuntimeException) 1619 { 1620 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1621 1622 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1623 if ((rPoint.X <= 0) && (rPoint.Y <= 0)) 1624 return 0; 1625 sal_uInt16 nPara, nIndex; 1626 1627 // offset from surrounding cell/shape 1628 Point aOffset( GetEEOffset() ); 1629 Point aPoint( rPoint.X - aOffset.X(), rPoint.Y - aOffset.Y() ); 1630 1631 // convert to logical coordinates 1632 SvxTextForwarder& rCacheTF = GetTextForwarder(); 1633 Point aLogPoint( GetViewForwarder().PixelToLogic( aPoint, rCacheTF.GetMapMode() ) ); 1634 1635 // re-offset to parent (paragraph) 1636 Rectangle aParaRect = rCacheTF.GetParaBounds( GetParagraphIndex() ); 1637 aLogPoint.Move( aParaRect.Left(), aParaRect.Top() ); 1638 1639 if( rCacheTF.GetIndexAtPoint( aLogPoint, nPara, nIndex ) && 1640 GetParagraphIndex() == nPara ) 1641 { 1642 // #102259# Double-check if we're _really_ on the given character 1643 try 1644 { 1645 awt::Rectangle aRect1( getCharacterBounds(nIndex) ); 1646 Rectangle aRect2( aRect1.X, aRect1.Y, 1647 aRect1.Width + aRect1.X, aRect1.Height + aRect1.Y ); 1648 if( aRect2.IsInside( Point( rPoint.X, rPoint.Y ) ) ) 1649 return nIndex; 1650 else 1651 return -1; 1652 } 1653 catch( const lang::IndexOutOfBoundsException& ) 1654 { 1655 // #103927# Don't throw for invalid nIndex values 1656 return -1; 1657 } 1658 } 1659 else 1660 { 1661 // not within our paragraph 1662 return -1; 1663 } 1664 } 1665 1666 ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getSelectedText() throw (uno::RuntimeException) 1667 { 1668 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1669 1670 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1671 1672 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 1673 "AccessibleEditableTextPara::getSelectedText: index value overflow"); 1674 1675 if( !HaveEditView() ) 1676 return ::rtl::OUString(); 1677 1678 return OCommonAccessibleText::getSelectedText(); 1679 } 1680 1681 sal_Int32 SAL_CALL AccessibleEditableTextPara::getSelectionStart() throw (uno::RuntimeException) 1682 { 1683 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1684 1685 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1686 1687 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 1688 "AccessibleEditableTextPara::getSelectionStart: index value overflow"); 1689 1690 if( !HaveEditView() ) 1691 return -1; 1692 1693 return OCommonAccessibleText::getSelectionStart(); 1694 } 1695 1696 sal_Int32 SAL_CALL AccessibleEditableTextPara::getSelectionEnd() throw (uno::RuntimeException) 1697 { 1698 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1699 1700 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1701 1702 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 1703 "AccessibleEditableTextPara::getSelectionEnd: index value overflow"); 1704 1705 if( !HaveEditView() ) 1706 return -1; 1707 1708 return OCommonAccessibleText::getSelectionEnd(); 1709 } 1710 1711 sal_Bool SAL_CALL AccessibleEditableTextPara::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 1712 { 1713 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1714 1715 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1716 1717 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 1718 "AccessibleEditableTextPara::setSelection: paragraph index value overflow"); 1719 1720 CheckRange(nStartIndex, nEndIndex); 1721 1722 try 1723 { 1724 SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( sal_True ); 1725 return rCacheVF.SetSelection( MakeSelection(nStartIndex, nEndIndex) ); 1726 } 1727 catch( const uno::RuntimeException& ) 1728 { 1729 return sal_False; 1730 } 1731 } 1732 1733 ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getText() throw (uno::RuntimeException) 1734 { 1735 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1736 1737 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1738 1739 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 1740 "AccessibleEditableTextPara::getText: paragraph index value overflow"); 1741 1742 return OCommonAccessibleText::getText(); 1743 } 1744 1745 ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 1746 { 1747 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1748 1749 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1750 1751 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 1752 "AccessibleEditableTextPara::getTextRange: paragraph index value overflow"); 1753 1754 return OCommonAccessibleText::getTextRange(nStartIndex, nEndIndex); 1755 } 1756 void AccessibleEditableTextPara::_correctValues( const sal_Int32 /* nIndex */, 1757 uno::Sequence< PropertyValue >& rValues) 1758 { 1759 SvxTextForwarder& rCacheTF = GetTextForwarder(); 1760 sal_Int32 nRes = rValues.getLength(); 1761 beans::PropertyValue *pRes = rValues.getArray(); 1762 for (sal_Int32 i = 0; i < nRes; ++i) 1763 { 1764 beans::PropertyValue &rRes = pRes[i]; 1765 // Char color 1766 if (rRes.Name.compareTo(::rtl::OUString::createFromAscii("CharColor"))==0) 1767 { 1768 uno::Any &anyChar = rRes.Value; 1769 sal_uInt32 crChar = static_cast<sal_uInt32>( reinterpret_cast<sal_uIntPtr>(anyChar.pReserved)); 1770 if (COL_AUTO == crChar ) 1771 { 1772 uno::Reference< ::com::sun::star::accessibility::XAccessibleComponent > xComponent; 1773 if (mxParent.is()) 1774 { 1775 xComponent.set(mxParent,uno::UNO_QUERY); 1776 } 1777 else 1778 { 1779 xComponent.set(m_xAccInfo,uno::UNO_QUERY); 1780 } 1781 if (xComponent.is()) 1782 { 1783 uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > xContext(xComponent,uno::UNO_QUERY); 1784 if (xContext->getAccessibleRole() == AccessibleRole::SHAPE 1785 || xContext->getAccessibleRole() == AccessibleRole::TABLE_CELL) 1786 { 1787 anyChar <<= COL_BLACK; 1788 } 1789 else 1790 { 1791 Color cr(xComponent->getBackground()); 1792 crChar = cr.IsDark() ? COL_WHITE : COL_BLACK; 1793 anyChar <<= crChar; 1794 } 1795 } 1796 } 1797 continue; 1798 } 1799 // Underline 1800 if(rRes.Name.compareTo(::rtl::OUString::createFromAscii("CharUnderline"))==0) 1801 { 1802 /* 1803 // MT: Implement XAccessibleTextMarkup, mark with TextMarkupType::SPELLCHECK. This way done in SW. 1804 if (IsCurrentEditorEnableAutoSpell( mxParent )) 1805 { 1806 try 1807 { 1808 SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( sal_False ); 1809 sal_Bool bWrong = rCacheVF.IsWrongSpelledWordAtPos( GetParagraphIndex(), nIndex ); 1810 if ( bWrong ) 1811 { 1812 uno::Any &anyUnderLine = pRes[9].Value; 1813 // MT IA2: Not needed? sal_uInt16 crUnderLine = (sal_uInt16)(anyUnderLine.pReserved); 1814 anyUnderLine <<= (sal_uInt16)UNDERLINE_WAVE; 1815 } 1816 } 1817 catch( const uno::RuntimeException& ) 1818 { 1819 } 1820 } 1821 */ 1822 continue; 1823 } 1824 // Underline color && Mis-spell 1825 if(rRes.Name.compareTo(::rtl::OUString::createFromAscii("CharUnderlineColor"))==0) 1826 { 1827 uno::Any &anyCharUnderLine = rRes.Value; 1828 sal_uInt32 crCharUnderLine = static_cast<sal_uInt32>( reinterpret_cast<sal_uIntPtr>( anyCharUnderLine.pReserved)); 1829 if (COL_AUTO == crCharUnderLine ) 1830 { 1831 uno::Reference< ::com::sun::star::accessibility::XAccessibleComponent > xComponent; 1832 if (mxParent.is()) 1833 { 1834 xComponent.set(mxParent,uno::UNO_QUERY); 1835 } 1836 else 1837 { 1838 xComponent.set(m_xAccInfo,uno::UNO_QUERY); 1839 } 1840 if (xComponent.is()) 1841 { 1842 uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > xContext(xComponent,uno::UNO_QUERY); 1843 if (xContext->getAccessibleRole() == AccessibleRole::SHAPE 1844 || xContext->getAccessibleRole() == AccessibleRole::TABLE_CELL) 1845 { 1846 anyCharUnderLine <<= COL_BLACK; 1847 } 1848 else 1849 { 1850 Color cr(xComponent->getBackground()); 1851 crCharUnderLine = cr.IsDark() ? COL_WHITE : COL_BLACK; 1852 anyCharUnderLine <<= crCharUnderLine; 1853 } 1854 } 1855 } 1856 // MT: Implement XAccessibleTextMarkup, mark with TextMarkupType::SPELLCHECK. This way done in SW. 1857 /* 1858 if (IsCurrentEditorEnableAutoSpell( mxParent )) 1859 { 1860 try 1861 { 1862 SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( sal_False ); 1863 sal_Bool bWrong = rCacheVF.IsWrongSpelledWordAtPos( GetParagraphIndex(), nIndex ); 1864 if ( bWrong ) 1865 { 1866 uno::Any &anyUnderLineColor = rRes.Value; 1867 // MT IA2: Not needed? sal_uInt16 crUnderLineColor = (sal_uInt16)(anyUnderLineColor.pReserved); 1868 anyUnderLineColor <<= COL_LIGHTRED; 1869 } 1870 } 1871 catch( const uno::RuntimeException& ) 1872 { 1873 } 1874 } 1875 */ 1876 continue; 1877 } 1878 // NumberingLevel 1879 if(rRes.Name.compareTo(::rtl::OUString::createFromAscii("NumberingLevel"))==0) 1880 { 1881 const SvxNumBulletItem& rNumBullet = ( SvxNumBulletItem& )rCacheTF.GetParaAttribs(GetParagraphIndex()).Get(EE_PARA_NUMBULLET); 1882 if(rNumBullet.GetNumRule()->GetLevelCount()==0) 1883 { 1884 rRes.Value <<= (sal_Int16)-1; 1885 rRes.Handle = -1; 1886 rRes.State = PropertyState_DIRECT_VALUE; 1887 } 1888 else 1889 { 1890 // SvxAccessibleTextPropertySet aPropSet( &GetEditSource(), 1891 // ImplGetSvxCharAndParaPropertiesMap() ); 1892 // MT IA2 TODO: Check if this is the correct replacement for ImplGetSvxCharAndParaPropertiesMap 1893 SvxAccessibleTextPropertySet aPropSet( &GetEditSource(), ImplGetSvxTextPortionSvxPropertySet() ); 1894 1895 aPropSet.SetSelection( MakeSelection( 0, GetTextLen() ) ); 1896 rRes.Value = aPropSet._getPropertyValue( rRes.Name, mnParagraphIndex ); 1897 rRes.State = aPropSet._getPropertyState( rRes.Name, mnParagraphIndex ); 1898 rRes.Handle = -1; 1899 } 1900 continue; 1901 } 1902 // NumberingRules 1903 if(rRes.Name.compareTo(::rtl::OUString::createFromAscii("NumberingRules"))==0) 1904 { 1905 SfxItemSet aAttribs = rCacheTF.GetParaAttribs( GetParagraphIndex() ); 1906 sal_Bool bVis = ((const SfxUInt16Item&)aAttribs.Get( EE_PARA_BULLETSTATE )).GetValue() ? sal_True : sal_False; 1907 if(bVis) 1908 { 1909 rRes.Value <<= (sal_Int16)-1; 1910 rRes.Handle = -1; 1911 rRes.State = PropertyState_DIRECT_VALUE; 1912 } 1913 else 1914 { 1915 // MT IA2 TODO: Check if this is the correct replacement for ImplGetSvxCharAndParaPropertiesMap 1916 SvxAccessibleTextPropertySet aPropSet( &GetEditSource(), ImplGetSvxTextPortionSvxPropertySet() ); 1917 aPropSet.SetSelection( MakeSelection( 0, GetTextLen() ) ); 1918 rRes.Value = aPropSet._getPropertyValue( rRes.Name, mnParagraphIndex ); 1919 rRes.State = aPropSet._getPropertyState( rRes.Name, mnParagraphIndex ); 1920 rRes.Handle = -1; 1921 } 1922 continue; 1923 } 1924 } 1925 } 1926 sal_Int32 AccessibleEditableTextPara::SkipField(sal_Int32 nIndex, sal_Bool bForward) 1927 { 1928 sal_Int32 nParaIndex = GetParagraphIndex(); 1929 SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); 1930 sal_Int32 nAllFieldLen = 0; 1931 sal_Int32 nField = rCacheTF.GetFieldCount(nParaIndex), nFoundFieldIndex = -1; 1932 EFieldInfo ree; 1933 sal_Int32 reeBegin=0, reeEnd=0; 1934 for(sal_uInt16 j = 0; j < nField; j++) 1935 { 1936 ree = rCacheTF.GetFieldInfo(nParaIndex, j); 1937 reeBegin = ree.aPosition.nIndex + nAllFieldLen; 1938 reeEnd = reeBegin + ree.aCurrentText.Len(); 1939 nAllFieldLen += (ree.aCurrentText.Len() - 1); 1940 if( reeBegin > nIndex ) 1941 { 1942 break; 1943 } 1944 if( nIndex >= reeBegin && nIndex < reeEnd ) 1945 { 1946 if(ree.pFieldItem->GetField()->GetClassId() != SVX_URLFIELD) 1947 { 1948 nFoundFieldIndex = j; 1949 break; 1950 } 1951 } 1952 } 1953 if( nFoundFieldIndex >= 0 ) 1954 { 1955 if( bForward ) 1956 return reeEnd - 1; 1957 else 1958 return reeBegin; 1959 } 1960 return nIndex; 1961 } 1962 sal_Bool AccessibleEditableTextPara::ExtendByField( ::com::sun::star::accessibility::TextSegment& Segment ) 1963 { 1964 sal_Int32 nParaIndex = GetParagraphIndex(); 1965 SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); 1966 sal_Int32 nAllFieldLen = 0; 1967 sal_Int32 nField = rCacheTF.GetFieldCount(nParaIndex), nFoundFieldIndex = -1; 1968 EFieldInfo ree; 1969 sal_Int32 reeBegin=0, reeEnd=0; 1970 for(sal_uInt16 j = 0; j < nField; j++) 1971 { 1972 ree = rCacheTF.GetFieldInfo(nParaIndex, j); 1973 reeBegin = ree.aPosition.nIndex + nAllFieldLen; 1974 reeEnd = reeBegin + ree.aCurrentText.Len(); 1975 nAllFieldLen += (ree.aCurrentText.Len() - 1); 1976 if( reeBegin > Segment.SegmentEnd ) 1977 { 1978 break; 1979 } 1980 if( (Segment.SegmentEnd > reeBegin && Segment.SegmentEnd <= reeEnd) || 1981 (Segment.SegmentStart >= reeBegin && Segment.SegmentStart < reeEnd) ) 1982 { 1983 if(ree.pFieldItem->GetField()->GetClassId() != SVX_URLFIELD) 1984 { 1985 nFoundFieldIndex = j; 1986 break; 1987 } 1988 } 1989 } 1990 sal_Bool bExtend = sal_False; 1991 if( nFoundFieldIndex >= 0 ) 1992 { 1993 if( Segment.SegmentEnd < reeEnd ) 1994 { 1995 Segment.SegmentEnd = reeEnd; 1996 bExtend = sal_True; 1997 } 1998 if( Segment.SegmentStart > reeBegin ) 1999 { 2000 Segment.SegmentStart = reeBegin; 2001 bExtend = sal_True; 2002 } 2003 if( bExtend ) 2004 { 2005 //If there is a bullet before the field, should add the bullet length into the segment. 2006 EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo(nParaIndex); 2007 int nBulletLen = aBulletInfo.aText.Len(); 2008 if (nBulletLen > 0) 2009 { 2010 Segment.SegmentEnd += nBulletLen; 2011 if (nFoundFieldIndex > 0) 2012 Segment.SegmentStart += nBulletLen; 2013 Segment.SegmentText = GetTextRange(Segment.SegmentStart, Segment.SegmentEnd); 2014 //After get the correct field name, should restore the offset value which don't contain the bullet. 2015 Segment.SegmentEnd -= nBulletLen; 2016 if (nFoundFieldIndex > 0) 2017 Segment.SegmentStart -= nBulletLen; 2018 } 2019 else 2020 Segment.SegmentText = GetTextRange(Segment.SegmentStart, Segment.SegmentEnd); 2021 } 2022 } 2023 return bExtend; 2024 } 2025 ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleEditableTextPara::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) 2026 { 2027 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 2028 2029 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 2030 2031 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 2032 "AccessibleEditableTextPara::getTextAtIndex: paragraph index value overflow"); 2033 2034 ::com::sun::star::accessibility::TextSegment aResult; 2035 aResult.SegmentStart = -1; 2036 aResult.SegmentEnd = -1; 2037 2038 switch( aTextType ) 2039 { 2040 case AccessibleTextType::CHARACTER: 2041 case AccessibleTextType::WORD: 2042 { 2043 aResult = OCommonAccessibleText::getTextAtIndex( nIndex, aTextType ); 2044 ExtendByField( aResult ); 2045 break; 2046 } 2047 // Not yet handled by OCommonAccessibleText. Missing 2048 // implGetAttributeRunBoundary() method there 2049 case AccessibleTextType::ATTRIBUTE_RUN: 2050 { 2051 const sal_Int32 nTextLen = GetTextForwarder().GetTextLen( GetParagraphIndex() ); 2052 2053 if( nIndex == nTextLen ) 2054 { 2055 // #i17014# Special-casing one-behind-the-end character 2056 aResult.SegmentStart = aResult.SegmentEnd = nTextLen; 2057 } 2058 else 2059 { 2060 sal_uInt16 nStartIndex, nEndIndex; 2061 //For the bullet paragraph, the bullet string is ingnored for IAText::attributes() function. 2062 SvxTextForwarder& rCacheTF = GetTextForwarder(); 2063 // MT IA2: Not used? sal_Int32 nBulletLen = 0; 2064 EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo( GetParagraphIndex() ); 2065 if (aBulletInfo.bVisible) 2066 nIndex += aBulletInfo.aText.Len(); 2067 if (nIndex != 0 && nIndex >= getCharacterCount()) 2068 nIndex = getCharacterCount()-1; 2069 CheckPosition(nIndex); 2070 if( GetAttributeRun(nStartIndex, nEndIndex, nIndex) ) 2071 { 2072 aResult.SegmentText = GetTextRange(nStartIndex, nEndIndex); 2073 if (aBulletInfo.bVisible) 2074 { 2075 nStartIndex -= aBulletInfo.aText.Len(); 2076 nEndIndex -= aBulletInfo.aText.Len(); 2077 } 2078 aResult.SegmentStart = nStartIndex; 2079 aResult.SegmentEnd = nEndIndex; 2080 } 2081 } 2082 break; 2083 } 2084 case AccessibleTextType::LINE: 2085 { 2086 SvxTextForwarder& rCacheTF = GetTextForwarder(); 2087 sal_Int32 nParaIndex = GetParagraphIndex(); 2088 // MT IA2: Not needed? sal_Int32 nTextLen = rCacheTF.GetTextLen( nParaIndex ); 2089 CheckPosition(nIndex); 2090 if (nIndex != 0 && nIndex == getCharacterCount()) 2091 --nIndex; 2092 sal_uInt16 nLine, nLineCount=rCacheTF.GetLineCount( static_cast< sal_uInt16 >( nParaIndex ) ); 2093 sal_Int32 nCurIndex; 2094 //the problem is that rCacheTF.GetLineLen() will include the bullet length. But for the bullet line, 2095 //the text value doesn't contain the bullet characters. all of the bullet and numbering info are exposed 2096 //by the IAText::attributes(). So here must do special support for bullet line. 2097 sal_Int32 nBulletLen = 0; 2098 for( nLine=0, nCurIndex=0; nLine<nLineCount; ++nLine ) 2099 { 2100 if (nLine == 0) 2101 { 2102 EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo( nParaIndex ); 2103 if (aBulletInfo.bVisible) 2104 { 2105 //in bullet or numbering; 2106 nBulletLen = aBulletInfo.aText.Len(); 2107 } 2108 } 2109 //nCurIndex += rCacheTF.GetLineLen( static_cast< sal_uInt16 >( nParaIndex ), nLine); 2110 sal_Int32 nLineLen = rCacheTF.GetLineLen( static_cast< sal_uInt16 >( nParaIndex ), nLine); 2111 if (nLine == 0) 2112 nCurIndex += nLineLen - nBulletLen; 2113 else 2114 nCurIndex += nLineLen; 2115 if( nCurIndex > nIndex ) 2116 { 2117 if (nLine ==0) 2118 { 2119 //aResult.SegmentStart = nCurIndex - rCacheTF.GetLineLen(static_cast< sal_uInt16 >( nParaIndex ), nLine); 2120 aResult.SegmentStart = 0; 2121 aResult.SegmentEnd = nCurIndex; 2122 //aResult.SegmentText = GetTextRange( aResult.SegmentStart, aResult.SegmentEnd ); 2123 aResult.SegmentText = GetTextRange( aResult.SegmentStart, aResult.SegmentEnd + nBulletLen); 2124 break; 2125 } 2126 else 2127 { 2128 //aResult.SegmentStart = nCurIndex - rCacheTF.GetLineLen(static_cast< sal_uInt16 >( nParaIndex ), nLine); 2129 aResult.SegmentStart = nCurIndex - nLineLen; 2130 aResult.SegmentEnd = nCurIndex; 2131 //aResult.SegmentText = GetTextRange( aResult.SegmentStart, aResult.SegmentEnd ); 2132 aResult.SegmentText = GetTextRange( aResult.SegmentStart + nBulletLen, aResult.SegmentEnd + nBulletLen); 2133 break; 2134 } 2135 } 2136 } 2137 break; 2138 } 2139 default: 2140 aResult = OCommonAccessibleText::getTextAtIndex( nIndex, aTextType ); 2141 break; 2142 } /* end of switch( aTextType ) */ 2143 2144 return aResult; 2145 } 2146 2147 ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleEditableTextPara::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) 2148 { 2149 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 2150 2151 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 2152 2153 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 2154 "AccessibleEditableTextPara::getTextBeforeIndex: paragraph index value overflow"); 2155 2156 ::com::sun::star::accessibility::TextSegment aResult; 2157 aResult.SegmentStart = -1; 2158 aResult.SegmentEnd = -1; 2159 i18n::Boundary aBoundary; 2160 switch( aTextType ) 2161 { 2162 // Not yet handled by OCommonAccessibleText. Missing 2163 // implGetAttributeRunBoundary() method there 2164 case AccessibleTextType::ATTRIBUTE_RUN: 2165 { 2166 const sal_Int32 nTextLen = GetTextForwarder().GetTextLen( GetParagraphIndex() ); 2167 sal_uInt16 nStartIndex, nEndIndex; 2168 2169 if( nIndex == nTextLen ) 2170 { 2171 // #i17014# Special-casing one-behind-the-end character 2172 if( nIndex > 0 && 2173 GetAttributeRun(nStartIndex, nEndIndex, nIndex-1) ) 2174 { 2175 aResult.SegmentText = GetTextRange(nStartIndex, nEndIndex); 2176 aResult.SegmentStart = nStartIndex; 2177 aResult.SegmentEnd = nEndIndex; 2178 } 2179 } 2180 else 2181 { 2182 if( GetAttributeRun(nStartIndex, nEndIndex, nIndex) ) 2183 { 2184 // already at the left border? If not, query 2185 // one index further left 2186 if( nStartIndex > 0 && 2187 GetAttributeRun(nStartIndex, nEndIndex, nStartIndex-1) ) 2188 { 2189 aResult.SegmentText = GetTextRange(nStartIndex, nEndIndex); 2190 aResult.SegmentStart = nStartIndex; 2191 aResult.SegmentEnd = nEndIndex; 2192 } 2193 } 2194 } 2195 break; 2196 } 2197 case AccessibleTextType::LINE: 2198 { 2199 SvxTextForwarder& rCacheTF = GetTextForwarder(); 2200 sal_Int32 nParaIndex = GetParagraphIndex(); 2201 // MT IA2 not needed? sal_Int32 nTextLen = rCacheTF.GetTextLen( nParaIndex ); 2202 2203 CheckPosition(nIndex); 2204 2205 sal_uInt16 nLine, nLineCount=rCacheTF.GetLineCount( static_cast< sal_uInt16 >( nParaIndex ) ); 2206 //the problem is that rCacheTF.GetLineLen() will include the bullet length. But for the bullet line, 2207 //the text value doesn't contain the bullet characters. all of the bullet and numbering info are exposed 2208 //by the IAText::attributes(). So here must do special support for bullet line. 2209 sal_Int32 nCurIndex=0, nLastIndex=0, nCurLineLen=0; 2210 sal_Int32 nLastLineLen = 0, nBulletLen = 0;; 2211 // get the line before the line the index points into 2212 for( nLine=0, nCurIndex=0, nLastIndex=0; nLine<nLineCount; ++nLine ) 2213 { 2214 nLastIndex = nCurIndex; 2215 if (nLine == 0) 2216 { 2217 EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo( nParaIndex ); 2218 if (aBulletInfo.bVisible) 2219 { 2220 //in bullet or numbering; 2221 nBulletLen = aBulletInfo.aText.Len(); 2222 } 2223 } 2224 if (nLine == 1) 2225 nLastLineLen = nCurLineLen - nBulletLen; 2226 else 2227 nLastLineLen = nCurLineLen; 2228 nCurLineLen = rCacheTF.GetLineLen(static_cast< sal_uInt16 >( nParaIndex ), nLine); 2229 //nCurIndex += nCurLineLen; 2230 if (nLine == 0) 2231 nCurIndex += nCurLineLen - nBulletLen; 2232 else 2233 nCurIndex += nCurLineLen; 2234 2235 //if( nCurIndex > nIndex && 2236 //nLastIndex > nCurLineLen ) 2237 if (nCurIndex > nIndex) 2238 { 2239 if (nLine == 0) 2240 { 2241 break; 2242 } 2243 else if (nLine == 1) 2244 { 2245 aResult.SegmentStart = 0; 2246 aResult.SegmentEnd = static_cast< sal_uInt16 >( nLastIndex ); 2247 aResult.SegmentText = GetTextRange( aResult.SegmentStart, aResult.SegmentEnd + nBulletLen); 2248 break; 2249 } 2250 else 2251 { 2252 //aResult.SegmentStart = nLastIndex - nCurLineLen; 2253 aResult.SegmentStart = nLastIndex - nLastLineLen; 2254 aResult.SegmentEnd = static_cast< sal_uInt16 >( nLastIndex ); 2255 aResult.SegmentText = GetTextRange( aResult.SegmentStart + nBulletLen, aResult.SegmentEnd + nBulletLen); 2256 break; 2257 } 2258 } 2259 } 2260 2261 break; 2262 } 2263 case AccessibleTextType::WORD: 2264 { 2265 nIndex = SkipField( nIndex, sal_False); 2266 ::rtl::OUString sText( implGetText() ); 2267 sal_Int32 nLength = sText.getLength(); 2268 2269 // get word at index 2270 implGetWordBoundary( aBoundary, nIndex ); 2271 2272 2273 //sal_Int32 curWordStart = aBoundary.startPos; 2274 //sal_Int32 preWordStart = curWordStart; 2275 sal_Int32 curWordStart , preWordStart; 2276 if( aBoundary.startPos == -1 || aBoundary.startPos > nIndex) 2277 curWordStart = preWordStart = nIndex; 2278 else 2279 curWordStart = preWordStart = aBoundary.startPos; 2280 2281 // get previous word 2282 2283 sal_Bool bWord = sal_False; 2284 2285 //while ( preWordStart > 0 && aBoundary.startPos == curWordStart) 2286 while ( (preWordStart >= 0 && !bWord ) || ( aBoundary.endPos > curWordStart ) ) 2287 { 2288 preWordStart--; 2289 bWord = implGetWordBoundary( aBoundary, preWordStart ); 2290 } 2291 if ( bWord && implIsValidBoundary( aBoundary, nLength ) ) 2292 { 2293 aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos ); 2294 aResult.SegmentStart = aBoundary.startPos; 2295 aResult.SegmentEnd = aBoundary.endPos; 2296 ExtendByField( aResult ); 2297 } 2298 } 2299 break; 2300 case AccessibleTextType::CHARACTER: 2301 { 2302 nIndex = SkipField( nIndex, sal_False); 2303 aResult = OCommonAccessibleText::getTextBeforeIndex( nIndex, aTextType ); 2304 ExtendByField( aResult ); 2305 break; 2306 } 2307 default: 2308 aResult = OCommonAccessibleText::getTextBeforeIndex( nIndex, aTextType ); 2309 break; 2310 } /* end of switch( aTextType ) */ 2311 2312 return aResult; 2313 } 2314 2315 ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleEditableTextPara::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) 2316 { 2317 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 2318 2319 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 2320 2321 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 2322 "AccessibleEditableTextPara::getTextBehindIndex: paragraph index value overflow"); 2323 2324 ::com::sun::star::accessibility::TextSegment aResult; 2325 aResult.SegmentStart = -1; 2326 aResult.SegmentEnd = -1; 2327 i18n::Boundary aBoundary; 2328 switch( aTextType ) 2329 { 2330 case AccessibleTextType::ATTRIBUTE_RUN: 2331 { 2332 sal_uInt16 nStartIndex, nEndIndex; 2333 2334 if( GetAttributeRun(nStartIndex, nEndIndex, nIndex) ) 2335 { 2336 // already at the right border? 2337 if( nEndIndex < GetTextLen() ) 2338 { 2339 if( GetAttributeRun(nStartIndex, nEndIndex, nEndIndex) ) 2340 { 2341 aResult.SegmentText = GetTextRange(nStartIndex, nEndIndex); 2342 aResult.SegmentStart = nStartIndex; 2343 aResult.SegmentEnd = nEndIndex; 2344 } 2345 } 2346 } 2347 break; 2348 } 2349 2350 case AccessibleTextType::LINE: 2351 { 2352 SvxTextForwarder& rCacheTF = GetTextForwarder(); 2353 sal_Int32 nParaIndex = GetParagraphIndex(); 2354 // MT IA2 not needed? sal_Int32 nTextLen = rCacheTF.GetTextLen( nParaIndex ); 2355 2356 CheckPosition(nIndex); 2357 2358 sal_uInt16 nLine, nLineCount=rCacheTF.GetLineCount( static_cast< sal_uInt16 >( nParaIndex ) ); 2359 sal_Int32 nCurIndex; 2360 //the problem is that rCacheTF.GetLineLen() will include the bullet length. But for the bullet line, 2361 //the text value doesn't contain the bullet characters. all of the bullet and numbering info are exposed 2362 //by the IAText::attributes(). So here must do special support for bullet line. 2363 sal_Int32 nBulletLen = 0; 2364 // get the line after the line the index points into 2365 for( nLine=0, nCurIndex=0; nLine<nLineCount; ++nLine ) 2366 { 2367 if (nLine == 0) 2368 { 2369 EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo( nParaIndex ); 2370 if (aBulletInfo.bVisible) 2371 { 2372 //in bullet or numbering; 2373 nBulletLen = aBulletInfo.aText.Len(); 2374 } 2375 } 2376 //nCurIndex += rCacheTF.GetLineLen(static_cast< sal_uInt16 >( nParaIndex ), nLine); 2377 sal_Int32 nLineLen = rCacheTF.GetLineLen( static_cast< sal_uInt16 >( nParaIndex ), nLine); 2378 2379 if (nLine == 0) 2380 nCurIndex += nLineLen - nBulletLen; 2381 else 2382 nCurIndex += nLineLen; 2383 2384 if( nCurIndex > nIndex && 2385 nLine < nLineCount-1 ) 2386 { 2387 aResult.SegmentStart = nCurIndex; 2388 aResult.SegmentEnd = nCurIndex + rCacheTF.GetLineLen(static_cast< sal_uInt16 >( nParaIndex ), nLine+1); 2389 aResult.SegmentText = GetTextRange( aResult.SegmentStart + nBulletLen, aResult.SegmentEnd + nBulletLen); 2390 break; 2391 } 2392 } 2393 2394 break; 2395 } 2396 case AccessibleTextType::WORD: 2397 { 2398 nIndex = SkipField( nIndex, sal_True); 2399 ::rtl::OUString sText( implGetText() ); 2400 sal_Int32 nLength = sText.getLength(); 2401 2402 // get word at index 2403 sal_Bool bWord = implGetWordBoundary( aBoundary, nIndex ); 2404 2405 // real current world 2406 sal_Int32 nextWord = nIndex; 2407 //if( nIndex >= aBoundary.startPos && nIndex <= aBoundary.endPos ) 2408 if( nIndex <= aBoundary.endPos ) 2409 { 2410 nextWord = aBoundary.endPos; 2411 if( sText.getStr()[nextWord] == sal_Unicode(' ') ) nextWord++; 2412 bWord = implGetWordBoundary( aBoundary, nextWord ); 2413 } 2414 2415 if ( bWord && implIsValidBoundary( aBoundary, nLength ) ) 2416 { 2417 aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos ); 2418 aResult.SegmentStart = aBoundary.startPos; 2419 aResult.SegmentEnd = aBoundary.endPos; 2420 2421 // If the end position of aBoundary is inside a field, extend the result to the end of the field 2422 2423 ExtendByField( aResult ); 2424 } 2425 } 2426 break; 2427 2428 case AccessibleTextType::CHARACTER: 2429 { 2430 nIndex = SkipField( nIndex, sal_True); 2431 aResult = OCommonAccessibleText::getTextBehindIndex( nIndex, aTextType ); 2432 ExtendByField( aResult ); 2433 break; 2434 } 2435 default: 2436 aResult = OCommonAccessibleText::getTextBehindIndex( nIndex, aTextType ); 2437 break; 2438 } /* end of switch( aTextType ) */ 2439 2440 return aResult; 2441 } 2442 2443 sal_Bool SAL_CALL AccessibleEditableTextPara::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 2444 { 2445 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 2446 2447 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 2448 2449 try 2450 { 2451 SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( sal_True ); 2452 #if OSL_DEBUG_LEVEL > 0 2453 SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs 2454 (void)rCacheTF; 2455 #else 2456 GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs 2457 #endif 2458 2459 sal_Bool aRetVal; 2460 2461 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 2462 "AccessibleEditableTextPara::copyText: index value overflow"); 2463 2464 CheckRange(nStartIndex, nEndIndex); 2465 2466 //Because bullet may occupy one or more characters, the TextAdapter will include bullet to calculate the selection. Add offset to handle bullet 2467 sal_Int32 nBulletLen = 0; 2468 EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo( GetParagraphIndex() ); 2469 if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && aBulletInfo.bVisible ) 2470 nBulletLen = aBulletInfo.aText.Len(); 2471 // save current selection 2472 ESelection aOldSelection; 2473 2474 rCacheVF.GetSelection( aOldSelection ); 2475 //rCacheVF.SetSelection( MakeSelection(nStartIndex, nEndIndex) ); 2476 rCacheVF.SetSelection( MakeSelection(nStartIndex + nBulletLen, nEndIndex + nBulletLen) ); 2477 aRetVal = rCacheVF.Copy(); 2478 rCacheVF.SetSelection( aOldSelection ); // restore 2479 2480 return aRetVal; 2481 } 2482 catch( const uno::RuntimeException& ) 2483 { 2484 return sal_False; 2485 } 2486 } 2487 2488 // XAccessibleEditableText 2489 sal_Bool SAL_CALL AccessibleEditableTextPara::cutText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 2490 { 2491 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 2492 2493 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 2494 2495 try 2496 { 2497 SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( sal_True ); 2498 SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs 2499 2500 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 2501 "AccessibleEditableTextPara::cutText: index value overflow"); 2502 2503 CheckRange(nStartIndex, nEndIndex); 2504 2505 // Because bullet may occupy one or more characters, the TextAdapter will include bullet to calculate the selection. Add offset to handle bullet 2506 sal_Int32 nBulletLen = 0; 2507 EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo( GetParagraphIndex() ); 2508 if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && aBulletInfo.bVisible ) 2509 nBulletLen = aBulletInfo.aText.Len(); 2510 ESelection aSelection = MakeSelection (nStartIndex + nBulletLen, nEndIndex + nBulletLen); 2511 if( !rCacheTF.IsEditable( aSelection ) ) 2512 return sal_False; // non-editable area selected 2513 2514 // don't save selection, might become invalid after cut! 2515 //rCacheVF.SetSelection( MakeSelection(nStartIndex, nEndIndex) ); 2516 rCacheVF.SetSelection( aSelection ); 2517 2518 return rCacheVF.Cut(); 2519 } 2520 catch( const uno::RuntimeException& ) 2521 { 2522 return sal_False; 2523 } 2524 } 2525 2526 sal_Bool SAL_CALL AccessibleEditableTextPara::pasteText( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 2527 { 2528 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 2529 2530 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 2531 2532 try 2533 { 2534 SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( sal_True ); 2535 SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs 2536 2537 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 2538 "AccessibleEditableTextPara::pasteText: index value overflow"); 2539 2540 CheckPosition(nIndex); 2541 2542 // Because bullet may occupy one or more characters, the TextAdapter will include bullet to calculate the selection. Add offset to handle bullet 2543 sal_Int32 nBulletLen = 0; 2544 EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo( GetParagraphIndex() ); 2545 if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && aBulletInfo.bVisible ) 2546 nBulletLen = aBulletInfo.aText.Len(); 2547 //if( !rCacheTF.IsEditable( MakeSelection(nIndex) ) ) 2548 if( !rCacheTF.IsEditable( MakeSelection(nIndex + nBulletLen) ) ) 2549 return sal_False; // non-editable area selected 2550 2551 // #104400# set empty selection (=> cursor) to given index 2552 //rCacheVF.SetSelection( MakeCursor(nIndex) ); 2553 rCacheVF.SetSelection( MakeCursor(nIndex + nBulletLen) ); 2554 2555 return rCacheVF.Paste(); 2556 } 2557 catch( const uno::RuntimeException& ) 2558 { 2559 return sal_False; 2560 } 2561 } 2562 2563 sal_Bool SAL_CALL AccessibleEditableTextPara::deleteText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 2564 { 2565 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 2566 2567 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 2568 2569 try 2570 { 2571 // #102710# Request edit view when doing changes 2572 // AccessibleEmptyEditSource relies on this behaviour 2573 GetEditViewForwarder( sal_True ); 2574 SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs 2575 2576 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 2577 "AccessibleEditableTextPara::deleteText: index value overflow"); 2578 2579 CheckRange(nStartIndex, nEndIndex); 2580 2581 // Because bullet may occupy one or more characters, the TextAdapter will include bullet to calculate the selection. Add offset to handle bullet 2582 sal_Int32 nBulletLen = 0; 2583 EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo( GetParagraphIndex() ); 2584 if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && aBulletInfo.bVisible ) 2585 nBulletLen = aBulletInfo.aText.Len(); 2586 ESelection aSelection = MakeSelection (nStartIndex + nBulletLen, nEndIndex + nBulletLen); 2587 2588 //if( !rCacheTF.IsEditable( MakeSelection(nStartIndex, nEndIndex) ) ) 2589 if( !rCacheTF.IsEditable( aSelection ) ) 2590 return sal_False; // non-editable area selected 2591 2592 //sal_Bool bRet = rCacheTF.Delete( MakeSelection(nStartIndex, nEndIndex) ); 2593 sal_Bool bRet = rCacheTF.Delete( aSelection ); 2594 2595 GetEditSource().UpdateData(); 2596 2597 return bRet; 2598 } 2599 catch( const uno::RuntimeException& ) 2600 { 2601 return sal_False; 2602 } 2603 } 2604 2605 sal_Bool SAL_CALL AccessibleEditableTextPara::insertText( const ::rtl::OUString& sText, sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 2606 { 2607 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 2608 2609 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 2610 2611 try 2612 { 2613 // #102710# Request edit view when doing changes 2614 // AccessibleEmptyEditSource relies on this behaviour 2615 GetEditViewForwarder( sal_True ); 2616 SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs 2617 2618 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 2619 "AccessibleEditableTextPara::insertText: index value overflow"); 2620 2621 CheckPosition(nIndex); 2622 2623 // Because bullet may occupy one or more characters, the TextAdapter will include bullet to calculate the selection. Add offset to handle bullet 2624 sal_Int32 nBulletLen = 0; 2625 EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo( GetParagraphIndex() ); 2626 if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && aBulletInfo.bVisible ) 2627 nBulletLen = aBulletInfo.aText.Len(); 2628 2629 //if( !rCacheTF.IsEditable( MakeSelection(nIndex) ) ) 2630 if( !rCacheTF.IsEditable( MakeSelection(nIndex + nBulletLen) ) ) 2631 return sal_False; // non-editable area selected 2632 2633 // #104400# insert given text at empty selection (=> cursor) 2634 //sal_Bool bRet = rCacheTF.InsertText( sText, MakeCursor(nIndex) ); 2635 sal_Bool bRet = rCacheTF.InsertText( sText, MakeCursor(nIndex + nBulletLen) ); 2636 2637 rCacheTF.QuickFormatDoc(); 2638 GetEditSource().UpdateData(); 2639 2640 return bRet; 2641 } 2642 catch( const uno::RuntimeException& ) 2643 { 2644 return sal_False; 2645 } 2646 } 2647 2648 sal_Bool SAL_CALL AccessibleEditableTextPara::replaceText( sal_Int32 nStartIndex, sal_Int32 nEndIndex, const ::rtl::OUString& sReplacement ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 2649 { 2650 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 2651 2652 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 2653 2654 try 2655 { 2656 // #102710# Request edit view when doing changes 2657 // AccessibleEmptyEditSource relies on this behaviour 2658 GetEditViewForwarder( sal_True ); 2659 SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs 2660 2661 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 2662 "AccessibleEditableTextPara::replaceText: index value overflow"); 2663 2664 CheckRange(nStartIndex, nEndIndex); 2665 2666 // Because bullet may occupy one or more characters, the TextAdapter will include bullet to calculate the selection. Add offset to handle bullet 2667 sal_Int32 nBulletLen = 0; 2668 EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo( GetParagraphIndex() ); 2669 if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && aBulletInfo.bVisible ) 2670 nBulletLen = aBulletInfo.aText.Len(); 2671 ESelection aSelection = MakeSelection (nStartIndex + nBulletLen, nEndIndex + nBulletLen); 2672 2673 //if( !rCacheTF.IsEditable( MakeSelection(nStartIndex, nEndIndex) ) ) 2674 if( !rCacheTF.IsEditable( aSelection ) ) 2675 return sal_False; // non-editable area selected 2676 2677 // insert given text into given range => replace 2678 //sal_Bool bRet = rCacheTF.InsertText( sReplacement, MakeSelection(nStartIndex, nEndIndex) ); 2679 sal_Bool bRet = rCacheTF.InsertText( sReplacement, aSelection ); 2680 2681 rCacheTF.QuickFormatDoc(); 2682 GetEditSource().UpdateData(); 2683 2684 return bRet; 2685 } 2686 catch( const uno::RuntimeException& ) 2687 { 2688 return sal_False; 2689 } 2690 } 2691 2692 sal_Bool SAL_CALL AccessibleEditableTextPara::setAttributes( sal_Int32 nStartIndex, sal_Int32 nEndIndex, const uno::Sequence< beans::PropertyValue >& aAttributeSet ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 2693 { 2694 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 2695 2696 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 2697 2698 try 2699 { 2700 // #102710# Request edit view when doing changes 2701 // AccessibleEmptyEditSource relies on this behaviour 2702 GetEditViewForwarder( sal_True ); 2703 SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs 2704 sal_uInt32 nPara = GetParagraphIndex(); 2705 2706 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 2707 "AccessibleEditableTextPara::setAttributes: index value overflow"); 2708 2709 CheckRange(nStartIndex, nEndIndex); 2710 2711 if( !rCacheTF.IsEditable( MakeSelection(nStartIndex, nEndIndex) ) ) 2712 return sal_False; // non-editable area selected 2713 2714 // do the indices span the whole paragraph? Then use the outliner map 2715 // TODO: hold it as a member? 2716 SvxAccessibleTextPropertySet aPropSet( &GetEditSource(), 2717 0 == nStartIndex && 2718 rCacheTF.GetTextLen(nPara) == nEndIndex ? 2719 ImplGetSvxUnoOutlinerTextCursorSvxPropertySet() : 2720 ImplGetSvxTextPortionSvxPropertySet() ); 2721 2722 aPropSet.SetSelection( MakeSelection(nStartIndex, nEndIndex) ); 2723 2724 // convert from PropertyValue to Any 2725 sal_Int32 i, nLength( aAttributeSet.getLength() ); 2726 const beans::PropertyValue* pPropArray = aAttributeSet.getConstArray(); 2727 for(i=0; i<nLength; ++i) 2728 { 2729 try 2730 { 2731 aPropSet.setPropertyValue(pPropArray->Name, pPropArray->Value); 2732 } 2733 catch( const uno::Exception& ) 2734 { 2735 DBG_ERROR("AccessibleEditableTextPara::setAttributes exception in setPropertyValue"); 2736 } 2737 2738 ++pPropArray; 2739 } 2740 2741 rCacheTF.QuickFormatDoc(); 2742 GetEditSource().UpdateData(); 2743 2744 return sal_True; 2745 } 2746 catch( const uno::RuntimeException& ) 2747 { 2748 return sal_False; 2749 } 2750 } 2751 2752 sal_Bool SAL_CALL AccessibleEditableTextPara::setText( const ::rtl::OUString& sText ) throw (uno::RuntimeException) 2753 { 2754 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 2755 2756 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 2757 2758 return replaceText(0, getCharacterCount(), sText); 2759 } 2760 2761 // XAccessibleTextAttributes 2762 uno::Sequence< beans::PropertyValue > SAL_CALL AccessibleEditableTextPara::getDefaultAttributes( 2763 const uno::Sequence< ::rtl::OUString >& rRequestedAttributes ) 2764 throw (uno::RuntimeException) 2765 { 2766 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 2767 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 2768 2769 #if OSL_DEBUG_LEVEL > 0 2770 SvxAccessibleTextAdapter& rCacheTF = 2771 #endif 2772 GetTextForwarder(); 2773 2774 #if OSL_DEBUG_LEVEL > 0 2775 (void)rCacheTF; 2776 #endif 2777 2778 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 2779 "AccessibleEditableTextPara::getCharacterAttributes: index value overflow"); 2780 2781 // get XPropertySetInfo for paragraph attributes and 2782 // character attributes that span all the paragraphs text. 2783 SvxAccessibleTextPropertySet aPropSet( &GetEditSource(), 2784 ImplGetSvxCharAndParaPropertiesSet() ); 2785 aPropSet.SetSelection( MakeSelection( 0, GetTextLen() ) ); 2786 uno::Reference< beans::XPropertySetInfo > xPropSetInfo = aPropSet.getPropertySetInfo(); 2787 if (!xPropSetInfo.is()) 2788 throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Cannot query XPropertySetInfo")), 2789 uno::Reference< uno::XInterface > 2790 ( static_cast< XAccessible* > (this) ) ); // disambiguate hierarchy 2791 2792 // build sequence of available properties to check 2793 sal_Int32 nLenReqAttr = rRequestedAttributes.getLength(); 2794 uno::Sequence< beans::Property > aProperties; 2795 if (nLenReqAttr) 2796 { 2797 const rtl::OUString *pRequestedAttributes = rRequestedAttributes.getConstArray(); 2798 2799 aProperties.realloc( nLenReqAttr ); 2800 beans::Property *pProperties = aProperties.getArray(); 2801 sal_Int32 nCurLen = 0; 2802 for (sal_Int32 i = 0; i < nLenReqAttr; ++i) 2803 { 2804 beans::Property aProp; 2805 try 2806 { 2807 aProp = xPropSetInfo->getPropertyByName( pRequestedAttributes[i] ); 2808 } 2809 catch (beans::UnknownPropertyException &) 2810 { 2811 continue; 2812 } 2813 pProperties[ nCurLen++ ] = aProp; 2814 } 2815 aProperties.realloc( nCurLen ); 2816 } 2817 else 2818 aProperties = xPropSetInfo->getProperties(); 2819 2820 sal_Int32 nLength = aProperties.getLength(); 2821 const beans::Property *pProperties = aProperties.getConstArray(); 2822 2823 // build resulting sequence 2824 uno::Sequence< beans::PropertyValue > aOutSequence( nLength ); 2825 beans::PropertyValue* pOutSequence = aOutSequence.getArray(); 2826 sal_Int32 nOutLen = 0; 2827 for (sal_Int32 i = 0; i < nLength; ++i) 2828 { 2829 // calling implementation functions: 2830 // _getPropertyState and _getPropertyValue (see below) to provide 2831 // the proper paragraph number when retrieving paragraph attributes 2832 PropertyState eState = aPropSet._getPropertyState( pProperties->Name, mnParagraphIndex ); 2833 if ( eState == PropertyState_AMBIGUOUS_VALUE ) 2834 { 2835 OSL_ENSURE( false, "ambiguous property value encountered" ); 2836 } 2837 2838 //if (eState == PropertyState_DIRECT_VALUE) 2839 // per definition all paragraph properties and all character 2840 // properties spanning the whole paragraph should be returned 2841 // and declared as default value 2842 { 2843 pOutSequence->Name = pProperties->Name; 2844 pOutSequence->Handle = pProperties->Handle; 2845 pOutSequence->Value = aPropSet._getPropertyValue( pProperties->Name, mnParagraphIndex ); 2846 pOutSequence->State = PropertyState_DEFAULT_VALUE; 2847 2848 ++pOutSequence; 2849 ++nOutLen; 2850 } 2851 ++pProperties; 2852 } 2853 aOutSequence.realloc( nOutLen ); 2854 2855 return aOutSequence; 2856 } 2857 2858 2859 uno::Sequence< beans::PropertyValue > SAL_CALL AccessibleEditableTextPara::getRunAttributes( 2860 sal_Int32 nIndex, 2861 const uno::Sequence< ::rtl::OUString >& rRequestedAttributes ) 2862 throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 2863 { 2864 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 2865 2866 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 2867 2868 #if OSL_DEBUG_LEVEL > 0 2869 SvxAccessibleTextAdapter& rCacheTF = 2870 #endif 2871 GetTextForwarder(); 2872 2873 #if OSL_DEBUG_LEVEL > 0 2874 (void)rCacheTF; 2875 #endif 2876 2877 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 2878 "AccessibleEditableTextPara::getCharacterAttributes: index value overflow"); 2879 2880 if( getCharacterCount() > 0 ) 2881 CheckIndex(nIndex); 2882 else 2883 CheckPosition(nIndex); 2884 2885 SvxAccessibleTextPropertySet aPropSet( &GetEditSource(), 2886 ImplGetSvxCharAndParaPropertiesSet() ); 2887 aPropSet.SetSelection( MakeSelection( nIndex ) ); 2888 uno::Reference< beans::XPropertySetInfo > xPropSetInfo = aPropSet.getPropertySetInfo(); 2889 if (!xPropSetInfo.is()) 2890 throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Cannot query XPropertySetInfo")), 2891 uno::Reference< uno::XInterface > 2892 ( static_cast< XAccessible* > (this) ) ); // disambiguate hierarchy 2893 2894 // build sequence of available properties to check 2895 sal_Int32 nLenReqAttr = rRequestedAttributes.getLength(); 2896 uno::Sequence< beans::Property > aProperties; 2897 if (nLenReqAttr) 2898 { 2899 const rtl::OUString *pRequestedAttributes = rRequestedAttributes.getConstArray(); 2900 2901 aProperties.realloc( nLenReqAttr ); 2902 beans::Property *pProperties = aProperties.getArray(); 2903 sal_Int32 nCurLen = 0; 2904 for (sal_Int32 i = 0; i < nLenReqAttr; ++i) 2905 { 2906 beans::Property aProp; 2907 try 2908 { 2909 aProp = xPropSetInfo->getPropertyByName( pRequestedAttributes[i] ); 2910 } 2911 catch (beans::UnknownPropertyException &) 2912 { 2913 continue; 2914 } 2915 pProperties[ nCurLen++ ] = aProp; 2916 } 2917 aProperties.realloc( nCurLen ); 2918 } 2919 else 2920 aProperties = xPropSetInfo->getProperties(); 2921 2922 sal_Int32 nLength = aProperties.getLength(); 2923 const beans::Property *pProperties = aProperties.getConstArray(); 2924 2925 // build resulting sequence 2926 uno::Sequence< beans::PropertyValue > aOutSequence( nLength ); 2927 beans::PropertyValue* pOutSequence = aOutSequence.getArray(); 2928 sal_Int32 nOutLen = 0; 2929 for (sal_Int32 i = 0; i < nLength; ++i) 2930 { 2931 // calling 'regular' functions that will operate on the selection 2932 PropertyState eState = aPropSet.getPropertyState( pProperties->Name ); 2933 if (eState == PropertyState_DIRECT_VALUE) 2934 { 2935 pOutSequence->Name = pProperties->Name; 2936 pOutSequence->Handle = pProperties->Handle; 2937 pOutSequence->Value = aPropSet.getPropertyValue( pProperties->Name ); 2938 pOutSequence->State = eState; 2939 2940 ++pOutSequence; 2941 ++nOutLen; 2942 } 2943 ++pProperties; 2944 } 2945 aOutSequence.realloc( nOutLen ); 2946 2947 return aOutSequence; 2948 } 2949 2950 // XAccessibleHypertext 2951 ::sal_Int32 SAL_CALL AccessibleEditableTextPara::getHyperLinkCount( ) throw (::com::sun::star::uno::RuntimeException) 2952 { 2953 SvxAccessibleTextAdapter& rT = GetTextForwarder(); 2954 const sal_Int32 nPara = GetParagraphIndex(); 2955 2956 sal_uInt16 nHyperLinks = 0; 2957 sal_uInt16 nFields = rT.GetFieldCount( nPara ); 2958 for ( sal_uInt16 n = 0; n < nFields; n++ ) 2959 { 2960 EFieldInfo aField = rT.GetFieldInfo( nPara, n ); 2961 if ( aField.pFieldItem->GetField()->ISA( SvxURLField ) ) 2962 nHyperLinks++; 2963 } 2964 return nHyperLinks; 2965 } 2966 2967 ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleHyperlink > SAL_CALL AccessibleEditableTextPara::getHyperLink( ::sal_Int32 nLinkIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) 2968 { 2969 ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleHyperlink > xRef; 2970 2971 SvxAccessibleTextAdapter& rT = GetTextForwarder(); 2972 const sal_Int32 nPara = GetParagraphIndex(); 2973 2974 sal_uInt16 nHyperLink = 0; 2975 sal_uInt16 nFields = rT.GetFieldCount( nPara ); 2976 for ( sal_uInt16 n = 0; n < nFields; n++ ) 2977 { 2978 EFieldInfo aField = rT.GetFieldInfo( nPara, n ); 2979 if ( aField.pFieldItem->GetField()->ISA( SvxURLField ) ) 2980 { 2981 if ( nHyperLink == nLinkIndex ) 2982 { 2983 sal_uInt16 nEEStart = aField.aPosition.nIndex; 2984 2985 // Translate EE Index to accessible index 2986 sal_uInt16 nStart = rT.CalcEditEngineIndex( nPara, nEEStart ); 2987 sal_uInt16 nEnd = nStart + aField.aCurrentText.Len(); 2988 xRef = new AccessibleHyperlink( rT, new SvxFieldItem( *aField.pFieldItem ), nPara, nEEStart, nStart, nEnd, aField.aCurrentText ); 2989 break; 2990 } 2991 nHyperLink++; 2992 } 2993 } 2994 2995 return xRef; 2996 } 2997 2998 ::sal_Int32 SAL_CALL AccessibleEditableTextPara::getHyperLinkIndex( ::sal_Int32 nCharIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) 2999 { 3000 const sal_Int32 nPara = GetParagraphIndex(); 3001 SvxAccessibleTextAdapter& rT = GetTextForwarder(); 3002 3003 // SvxAccessibleTextIndex aIndex; 3004 // aIndex.SetIndex(nPara, nCharIndex, rT); 3005 // const sal_uInt16 nEEIndex = aIndex.GetEEIndex(); 3006 3007 const sal_uInt16 nEEIndex = rT.CalcEditEngineIndex( nPara, nCharIndex ); 3008 sal_Int32 nHLIndex = -1; //i123620 3009 sal_uInt16 nHyperLink = 0; 3010 sal_uInt16 nFields = rT.GetFieldCount( nPara ); 3011 for ( sal_uInt16 n = 0; n < nFields; n++ ) 3012 { 3013 EFieldInfo aField = rT.GetFieldInfo( nPara, n ); 3014 if ( aField.pFieldItem->GetField()->ISA( SvxURLField ) ) 3015 { 3016 if ( aField.aPosition.nIndex == nEEIndex ) 3017 { 3018 nHLIndex = nHyperLink; 3019 break; 3020 } 3021 nHyperLink++; 3022 } 3023 } 3024 3025 return nHLIndex; 3026 } 3027 3028 // XAccessibleMultiLineText 3029 sal_Int32 SAL_CALL AccessibleEditableTextPara::getLineNumberAtIndex( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 3030 { 3031 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 3032 3033 sal_Int32 nRes = -1; 3034 sal_Int32 nPara = GetParagraphIndex(); 3035 3036 SvxTextForwarder &rCacheTF = GetTextForwarder(); 3037 const bool bValidPara = 0 <= nPara && nPara < rCacheTF.GetParagraphCount(); 3038 DBG_ASSERT( bValidPara, "getLineNumberAtIndex: current paragraph index out of range" ); 3039 if (bValidPara) 3040 { 3041 // we explicitly allow for the index to point at the character right behind the text 3042 if (0 <= nIndex && nIndex <= rCacheTF.GetTextLen( nPara )) 3043 nRes = rCacheTF.GetLineNumberAtIndex( nPara, static_cast< sal_uInt16 >(nIndex) ); 3044 else 3045 throw lang::IndexOutOfBoundsException(); 3046 } 3047 return nRes; 3048 } 3049 3050 // XAccessibleMultiLineText 3051 ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleEditableTextPara::getTextAtLineNumber( sal_Int32 nLineNo ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 3052 { 3053 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 3054 3055 ::com::sun::star::accessibility::TextSegment aResult; 3056 sal_Int32 nPara = GetParagraphIndex(); 3057 SvxTextForwarder &rCacheTF = GetTextForwarder(); 3058 const bool bValidPara = 0 <= nPara && nPara < rCacheTF.GetParagraphCount(); 3059 DBG_ASSERT( bValidPara, "getTextAtLineNumber: current paragraph index out of range" ); 3060 if (bValidPara) 3061 { 3062 if (0 <= nLineNo && nLineNo < rCacheTF.GetLineCount( nPara )) 3063 { 3064 sal_uInt16 nStart = 0, nEnd = 0; 3065 rCacheTF.GetLineBoundaries( nStart, nEnd, nPara, static_cast< sal_uInt16 >(nLineNo) ); 3066 if (nStart != 0xFFFF && nEnd != 0xFFFF) 3067 { 3068 try 3069 { 3070 aResult.SegmentText = getTextRange( nStart, nEnd ); 3071 aResult.SegmentStart = nStart; 3072 aResult.SegmentEnd = nEnd; 3073 } 3074 catch (lang::IndexOutOfBoundsException) 3075 { 3076 // this is not the exception that should be raised in this function ... 3077 DBG_ASSERT( 0, "unexpected exception" ); 3078 } 3079 } 3080 } 3081 else 3082 throw lang::IndexOutOfBoundsException(); 3083 } 3084 return aResult; 3085 } 3086 3087 // XAccessibleMultiLineText 3088 ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleEditableTextPara::getTextAtLineWithCaret( ) throw (uno::RuntimeException) 3089 { 3090 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 3091 3092 ::com::sun::star::accessibility::TextSegment aResult; 3093 try 3094 { 3095 aResult = getTextAtLineNumber( getNumberOfLineWithCaret() ); 3096 } 3097 catch (lang::IndexOutOfBoundsException &) 3098 { 3099 // this one needs to be catched since this interface does not allow for it. 3100 } 3101 return aResult; 3102 } 3103 3104 // XAccessibleMultiLineText 3105 sal_Int32 SAL_CALL AccessibleEditableTextPara::getNumberOfLineWithCaret( ) throw (uno::RuntimeException) 3106 { 3107 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 3108 3109 sal_Int32 nRes = -1; 3110 try 3111 { 3112 nRes = getLineNumberAtIndex( getCaretPosition() ); 3113 } 3114 catch (lang::IndexOutOfBoundsException &) 3115 { 3116 // this one needs to be catched since this interface does not allow for it. 3117 } 3118 return nRes; 3119 } 3120 3121 3122 // XServiceInfo 3123 ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getImplementationName (void) throw (uno::RuntimeException) 3124 { 3125 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 3126 3127 return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("AccessibleEditableTextPara")); 3128 } 3129 3130 sal_Bool SAL_CALL AccessibleEditableTextPara::supportsService (const ::rtl::OUString& sServiceName) throw (uno::RuntimeException) 3131 { 3132 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 3133 3134 // Iterate over all supported service names and return true if on of them 3135 // matches the given name. 3136 uno::Sequence< ::rtl::OUString> aSupportedServices ( 3137 getSupportedServiceNames ()); 3138 for (int i=0; i<aSupportedServices.getLength(); i++) 3139 if (sServiceName == aSupportedServices[i]) 3140 return sal_True; 3141 return sal_False; 3142 } 3143 3144 uno::Sequence< ::rtl::OUString> SAL_CALL AccessibleEditableTextPara::getSupportedServiceNames (void) throw (uno::RuntimeException) 3145 { 3146 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 3147 3148 const ::rtl::OUString sServiceName( getServiceName() ); 3149 return uno::Sequence< ::rtl::OUString > (&sServiceName, 1); 3150 } 3151 3152 // XServiceName 3153 ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getServiceName (void) throw (uno::RuntimeException) 3154 { 3155 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 3156 3157 // #105185# Using correct service now 3158 return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.AccessibleParagraphView")); 3159 } 3160 3161 } // end of namespace accessibility 3162 3163 //------------------------------------------------------------------------ 3164