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( static_cast< sal_uInt16 >( 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( static_cast< sal_uInt16 >( 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( static_cast< sal_uInt16 >( 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 wether 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() <= USHRT_MAX, 801 "AccessibleEditableTextPara::getLocale: paragraph index value overflow"); 802 803 return GetTextForwarder().GetAttributeRun( nStartIndex, 804 nEndIndex, 805 static_cast< sal_uInt16 >(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 = this; 819 uno::Reference< XAccessibleText > aAccText = static_cast< XAccessibleEditableText * >(this); 820 aRet <<= aAccText; 821 } 822 else if ( rType == ::getCppuType((uno::Reference< XAccessibleEditableText > *)0) ) 823 { 824 uno::Reference< XAccessibleEditableText > aAccEditText = this; 825 aRet <<= aAccEditText; 826 } 827 else if ( rType == ::getCppuType((uno::Reference< XAccessibleHypertext > *)0) ) 828 { 829 uno::Reference< XAccessibleHypertext > aAccHyperText = this; 830 aRet <<= aAccHyperText; 831 } 832 else 833 { 834 aRet = AccessibleTextParaInterfaceBase::queryInterface(rType); 835 } 836 837 return aRet; 838 } 839 840 // XAccessible 841 uno::Reference< XAccessibleContext > SAL_CALL AccessibleEditableTextPara::getAccessibleContext() throw (uno::RuntimeException) 842 { 843 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 844 845 // We implement the XAccessibleContext interface in the same object 846 return uno::Reference< XAccessibleContext > ( this ); 847 } 848 849 // XAccessibleContext 850 sal_Int32 SAL_CALL AccessibleEditableTextPara::getAccessibleChildCount() throw (uno::RuntimeException) 851 { 852 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 853 854 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 855 856 return HaveChildren() ? 1 : 0; 857 } 858 859 uno::Reference< XAccessible > SAL_CALL AccessibleEditableTextPara::getAccessibleChild( sal_Int32 i ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 860 { 861 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 862 863 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 864 865 if( !HaveChildren() ) 866 throw lang::IndexOutOfBoundsException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("No childs available")), 867 uno::Reference< uno::XInterface > 868 ( static_cast< ::cppu::OWeakObject* > (this) ) ); // static_cast: disambiguate hierarchy 869 870 if( i != 0 ) 871 throw lang::IndexOutOfBoundsException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Invalid child index")), 872 uno::Reference< uno::XInterface > 873 ( static_cast< ::cppu::OWeakObject* > (this) ) ); // static_cast: disambiguate hierarchy 874 875 WeakBullet::HardRefType aChild( maImageBullet.get() ); 876 877 if( !aChild.is() ) 878 { 879 // there is no hard reference available, create object then 880 AccessibleImageBullet* pChild = new AccessibleImageBullet( uno::Reference< XAccessible >( this ) ); 881 uno::Reference< XAccessible > xChild( static_cast< ::cppu::OWeakObject* > (pChild), uno::UNO_QUERY ); 882 883 if( !xChild.is() ) 884 throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Child creation failed")), 885 uno::Reference< uno::XInterface > 886 ( static_cast< ::cppu::OWeakObject* > (this) ) ); 887 888 aChild = WeakBullet::HardRefType( xChild, pChild ); 889 890 aChild->SetEditSource( &GetEditSource() ); 891 aChild->SetParagraphIndex( GetParagraphIndex() ); 892 aChild->SetIndexInParent( i ); 893 894 maImageBullet = aChild; 895 } 896 897 return aChild.getRef(); 898 } 899 900 uno::Reference< XAccessible > SAL_CALL AccessibleEditableTextPara::getAccessibleParent() throw (uno::RuntimeException) 901 { 902 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 903 904 #ifdef DBG_UTIL 905 if( !mxParent.is() ) 906 DBG_TRACE( "AccessibleEditableTextPara::getAccessibleParent: no frontend set, did somebody forgot to call AccessibleTextHelper::SetEventSource()?"); 907 #endif 908 909 return mxParent; 910 } 911 912 sal_Int32 SAL_CALL AccessibleEditableTextPara::getAccessibleIndexInParent() throw (uno::RuntimeException) 913 { 914 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 915 916 return mnIndexInParent; 917 } 918 919 sal_Int16 SAL_CALL AccessibleEditableTextPara::getAccessibleRole() throw (uno::RuntimeException) 920 { 921 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 922 923 return AccessibleRole::PARAGRAPH; 924 } 925 926 ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getAccessibleDescription() throw (uno::RuntimeException) 927 { 928 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 929 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 930 931 // append first 40 characters from text, or first line, if shorter 932 // (writer takes first sentence here, but that's not supported 933 // from EditEngine) 934 // throws if defunc 935 ::rtl::OUString aLine; 936 937 if( getCharacterCount() ) 938 aLine = getTextAtIndex(0, AccessibleTextType::LINE).SegmentText; 939 940 // Get the string from the resource for the specified id. 941 String sStr = ::rtl::OUString( String( EditResId (RID_SVXSTR_A11Y_PARAGRAPH_DESCRIPTION ) ) ); 942 String sParaIndex = ::rtl::OUString::valueOf( GetParagraphIndex() ); 943 sStr.SearchAndReplace( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "$(ARG)" )), 944 sParaIndex ); 945 946 if( aLine.getLength() > MaxDescriptionLen ) 947 { 948 ::rtl::OUString aCurrWord; 949 sal_Int32 i; 950 951 // search backward from MaxDescriptionLen for previous word start 952 for( aCurrWord=getTextAtIndex(MaxDescriptionLen, AccessibleTextType::WORD).SegmentText, 953 i=MaxDescriptionLen, 954 aLine=::rtl::OUString(); 955 i>=0; 956 --i ) 957 { 958 if( getTextAtIndex(i, AccessibleTextType::WORD).SegmentText != aCurrWord ) 959 { 960 if( i == 0 ) 961 // prevent completely empty string 962 aLine = getTextAtIndex(0, AccessibleTextType::WORD).SegmentText; 963 else 964 aLine = getTextRange(0, i); 965 } 966 } 967 } 968 969 return ::rtl::OUString( sStr ) + aLine; 970 } 971 972 ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getAccessibleName() throw (uno::RuntimeException) 973 { 974 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 975 976 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 977 978 // throws if defunc 979 sal_Int32 nPara( GetParagraphIndex() ); 980 981 // Get the string from the resource for the specified id. 982 String sStr = ::rtl::OUString( String( EditResId (RID_SVXSTR_A11Y_PARAGRAPH_NAME) ) ); 983 String sParaIndex = ::rtl::OUString::valueOf( nPara ); 984 sStr.SearchAndReplace( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "$(ARG)" )), 985 sParaIndex ); 986 987 return ::rtl::OUString( sStr ); 988 } 989 990 uno::Reference< XAccessibleRelationSet > SAL_CALL AccessibleEditableTextPara::getAccessibleRelationSet() throw (uno::RuntimeException) 991 { 992 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 993 994 // --> OD 2006-01-11 #i27138# - provide relations CONTENT_FLOWS_FROM 995 // and CONTENT_FLOWS_TO 996 if ( mpParaManager ) 997 { 998 utl::AccessibleRelationSetHelper* pAccRelSetHelper = 999 new utl::AccessibleRelationSetHelper(); 1000 sal_Int32 nMyParaIndex( GetParagraphIndex() ); 1001 // relation CONTENT_FLOWS_FROM 1002 if ( nMyParaIndex > 0 && 1003 mpParaManager->IsReferencable( nMyParaIndex - 1 ) ) 1004 { 1005 uno::Sequence<uno::Reference<XInterface> > aSequence(1); 1006 aSequence[0] = 1007 mpParaManager->GetChild( nMyParaIndex - 1 ).first.get().getRef(); 1008 AccessibleRelation aAccRel( AccessibleRelationType::CONTENT_FLOWS_FROM, 1009 aSequence ); 1010 pAccRelSetHelper->AddRelation( aAccRel ); 1011 } 1012 1013 // relation CONTENT_FLOWS_TO 1014 if ( (nMyParaIndex + 1) < (sal_Int32)mpParaManager->GetNum() && 1015 mpParaManager->IsReferencable( nMyParaIndex + 1 ) ) 1016 { 1017 uno::Sequence<uno::Reference<XInterface> > aSequence(1); 1018 aSequence[0] = 1019 mpParaManager->GetChild( nMyParaIndex + 1 ).first.get().getRef(); 1020 AccessibleRelation aAccRel( AccessibleRelationType::CONTENT_FLOWS_TO, 1021 aSequence ); 1022 pAccRelSetHelper->AddRelation( aAccRel ); 1023 } 1024 1025 return pAccRelSetHelper; 1026 } 1027 else 1028 { 1029 // no relations, therefore empty 1030 return uno::Reference< XAccessibleRelationSet >(); 1031 } 1032 // <-- 1033 } 1034 1035 uno::Reference< XAccessibleStateSet > SAL_CALL AccessibleEditableTextPara::getAccessibleStateSet() throw (uno::RuntimeException) 1036 { 1037 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1038 1039 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1040 1041 // Create a copy of the state set and return it. 1042 ::utl::AccessibleStateSetHelper* pStateSet = static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get()); 1043 1044 if( !pStateSet ) 1045 return uno::Reference<XAccessibleStateSet>(); 1046 uno::Reference<XAccessibleStateSet> xParentStates; 1047 if (getAccessibleParent().is()) 1048 { 1049 uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext(); 1050 xParentStates = xParentContext->getAccessibleStateSet(); 1051 } 1052 if (xParentStates.is() && xParentStates->contains(AccessibleStateType::EDITABLE) ) 1053 { 1054 pStateSet->AddState(AccessibleStateType::EDITABLE); 1055 } 1056 return uno::Reference<XAccessibleStateSet>( new ::utl::AccessibleStateSetHelper (*pStateSet) ); 1057 } 1058 1059 lang::Locale SAL_CALL AccessibleEditableTextPara::getLocale() throw (IllegalAccessibleComponentStateException, uno::RuntimeException) 1060 { 1061 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1062 1063 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1064 1065 return implGetLocale(); 1066 } 1067 1068 void SAL_CALL AccessibleEditableTextPara::addEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) throw (uno::RuntimeException) 1069 { 1070 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1071 1072 if( getNotifierClientId() != -1 ) 1073 ::comphelper::AccessibleEventNotifier::addEventListener( getNotifierClientId(), xListener ); 1074 } 1075 1076 void SAL_CALL AccessibleEditableTextPara::removeEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) throw (uno::RuntimeException) 1077 { 1078 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1079 1080 if( getNotifierClientId() != -1 ) 1081 ::comphelper::AccessibleEventNotifier::removeEventListener( getNotifierClientId(), xListener ); 1082 } 1083 1084 // XAccessibleComponent 1085 sal_Bool SAL_CALL AccessibleEditableTextPara::containsPoint( const awt::Point& aTmpPoint ) throw (uno::RuntimeException) 1086 { 1087 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1088 1089 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1090 1091 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 1092 "AccessibleEditableTextPara::contains: index value overflow"); 1093 1094 awt::Rectangle aTmpRect = getBounds(); 1095 Rectangle aRect( Point(aTmpRect.X, aTmpRect.Y), Size(aTmpRect.Width, aTmpRect.Height) ); 1096 Point aPoint( aTmpPoint.X, aTmpPoint.Y ); 1097 1098 return aRect.IsInside( aPoint ); 1099 } 1100 1101 uno::Reference< XAccessible > SAL_CALL AccessibleEditableTextPara::getAccessibleAtPoint( const awt::Point& _aPoint ) throw (uno::RuntimeException) 1102 { 1103 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1104 1105 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1106 1107 if( HaveChildren() ) 1108 { 1109 // #103862# No longer need to make given position relative 1110 Point aPoint( _aPoint.X, _aPoint.Y ); 1111 1112 // respect EditEngine offset to surrounding shape/cell 1113 aPoint -= GetEEOffset(); 1114 1115 // convert to EditEngine coordinate system 1116 SvxTextForwarder& rCacheTF = GetTextForwarder(); 1117 Point aLogPoint( GetViewForwarder().PixelToLogic( aPoint, rCacheTF.GetMapMode() ) ); 1118 1119 EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo( static_cast< sal_uInt16 > (GetParagraphIndex()) ); 1120 1121 if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && 1122 aBulletInfo.bVisible && 1123 aBulletInfo.nType == SVX_NUM_BITMAP ) 1124 { 1125 Rectangle aRect = aBulletInfo.aBounds; 1126 1127 if( aRect.IsInside( aLogPoint ) ) 1128 return getAccessibleChild(0); 1129 } 1130 } 1131 1132 // no children at all, or none at given position 1133 return uno::Reference< XAccessible >(); 1134 } 1135 1136 awt::Rectangle SAL_CALL AccessibleEditableTextPara::getBounds() throw (uno::RuntimeException) 1137 { 1138 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1139 1140 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1141 1142 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 1143 "AccessibleEditableTextPara::getBounds: index value overflow"); 1144 1145 SvxTextForwarder& rCacheTF = GetTextForwarder(); 1146 Rectangle aRect = rCacheTF.GetParaBounds( static_cast< sal_uInt16 >( GetParagraphIndex() ) ); 1147 1148 // convert to screen coordinates 1149 Rectangle aScreenRect = AccessibleEditableTextPara::LogicToPixel( aRect, 1150 rCacheTF.GetMapMode(), 1151 GetViewForwarder() ); 1152 1153 // offset from shape/cell 1154 Point aOffset = GetEEOffset(); 1155 1156 return awt::Rectangle( aScreenRect.Left() + aOffset.X(), 1157 aScreenRect.Top() + aOffset.Y(), 1158 aScreenRect.GetSize().Width(), 1159 aScreenRect.GetSize().Height() ); 1160 } 1161 1162 awt::Point SAL_CALL AccessibleEditableTextPara::getLocation( ) throw (uno::RuntimeException) 1163 { 1164 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1165 1166 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1167 1168 awt::Rectangle aRect = getBounds(); 1169 1170 return awt::Point( aRect.X, aRect.Y ); 1171 } 1172 1173 awt::Point SAL_CALL AccessibleEditableTextPara::getLocationOnScreen( ) throw (uno::RuntimeException) 1174 { 1175 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1176 1177 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1178 1179 // relate us to parent 1180 uno::Reference< XAccessible > xParent = getAccessibleParent(); 1181 if( xParent.is() ) 1182 { 1183 uno::Reference< XAccessibleComponent > xParentComponent( xParent, uno::UNO_QUERY ); 1184 if( xParentComponent.is() ) 1185 { 1186 awt::Point aRefPoint = xParentComponent->getLocationOnScreen(); 1187 awt::Point aPoint = getLocation(); 1188 aPoint.X += aRefPoint.X; 1189 aPoint.Y += aRefPoint.Y; 1190 1191 return aPoint; 1192 } 1193 // --> OD 2009-12-16 #i88070# 1194 // fallback to parent's <XAccessibleContext> instance 1195 else 1196 { 1197 uno::Reference< XAccessibleContext > xParentContext = xParent->getAccessibleContext(); 1198 if ( xParentContext.is() ) 1199 { 1200 uno::Reference< XAccessibleComponent > xParentContextComponent( xParentContext, uno::UNO_QUERY ); 1201 if( xParentContextComponent.is() ) 1202 { 1203 awt::Point aRefPoint = xParentContextComponent->getLocationOnScreen(); 1204 awt::Point aPoint = getLocation(); 1205 aPoint.X += aRefPoint.X; 1206 aPoint.Y += aRefPoint.Y; 1207 1208 return aPoint; 1209 } 1210 } 1211 } 1212 // <-- 1213 } 1214 1215 throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Cannot access parent")), 1216 uno::Reference< uno::XInterface > 1217 ( static_cast< XAccessible* > (this) ) ); // disambiguate hierarchy 1218 } 1219 1220 awt::Size SAL_CALL AccessibleEditableTextPara::getSize( ) throw (uno::RuntimeException) 1221 { 1222 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1223 1224 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1225 1226 awt::Rectangle aRect = getBounds(); 1227 1228 return awt::Size( aRect.Width, aRect.Height ); 1229 } 1230 1231 void SAL_CALL AccessibleEditableTextPara::grabFocus( ) throw (uno::RuntimeException) 1232 { 1233 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1234 1235 // set cursor to this paragraph 1236 setSelection(0,0); 1237 } 1238 1239 sal_Int32 SAL_CALL AccessibleEditableTextPara::getForeground( ) throw (::com::sun::star::uno::RuntimeException) 1240 { 1241 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1242 1243 // #104444# Added to XAccessibleComponent interface 1244 svtools::ColorConfig aColorConfig; 1245 sal_uInt32 nColor = aColorConfig.GetColorValue( svtools::FONTCOLOR ).nColor; 1246 return static_cast<sal_Int32>(nColor); 1247 } 1248 1249 sal_Int32 SAL_CALL AccessibleEditableTextPara::getBackground( ) throw (::com::sun::star::uno::RuntimeException) 1250 { 1251 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1252 1253 // #104444# Added to XAccessibleComponent interface 1254 Color aColor( Application::GetSettings().GetStyleSettings().GetWindowColor().GetColor() ); 1255 1256 // the background is transparent 1257 aColor.SetTransparency( 0xFF); 1258 1259 return static_cast<sal_Int32>( aColor.GetColor() ); 1260 } 1261 1262 // XAccessibleText 1263 sal_Int32 SAL_CALL AccessibleEditableTextPara::getCaretPosition() throw (uno::RuntimeException) 1264 { 1265 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1266 1267 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1268 1269 if( !HaveEditView() ) 1270 return -1; 1271 1272 ESelection aSelection; 1273 if( GetEditViewForwarder().GetSelection( aSelection ) && 1274 GetParagraphIndex() == aSelection.nEndPara ) 1275 { 1276 // caret is always nEndPara,nEndPos 1277 EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo( static_cast< sal_uInt16 >(GetParagraphIndex()) ); 1278 if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && 1279 aBulletInfo.bVisible && 1280 aBulletInfo.nType != SVX_NUM_BITMAP ) 1281 { 1282 sal_Int32 nBulletLen = aBulletInfo.aText.Len(); 1283 if( aSelection.nEndPos - nBulletLen >= 0 ) 1284 return aSelection.nEndPos - nBulletLen; 1285 } 1286 return aSelection.nEndPos; 1287 } 1288 1289 // not within this paragraph 1290 return -1; 1291 } 1292 1293 sal_Bool SAL_CALL AccessibleEditableTextPara::setCaretPosition( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 1294 { 1295 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1296 1297 return setSelection(nIndex, nIndex); 1298 } 1299 1300 sal_Unicode SAL_CALL AccessibleEditableTextPara::getCharacter( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 1301 { 1302 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1303 1304 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1305 1306 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 1307 "AccessibleEditableTextPara::getCharacter: index value overflow"); 1308 1309 return OCommonAccessibleText::getCharacter( nIndex ); 1310 } 1311 static uno::Sequence< ::rtl::OUString > getAttributeNames() 1312 { 1313 static uno::Sequence< ::rtl::OUString >* pNames = NULL; 1314 1315 if( pNames == NULL ) 1316 { 1317 uno::Sequence< ::rtl::OUString >* pSeq = new uno::Sequence< ::rtl::OUString >( 21 ); 1318 ::rtl::OUString* pStrings = pSeq->getArray(); 1319 sal_Int32 i = 0; 1320 #define STR(x) pStrings[i++] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(x)) 1321 //STR("CharBackColor"); 1322 STR("CharColor"); 1323 STR("CharContoured"); 1324 STR("CharEmphasis"); 1325 STR("CharEscapement"); 1326 STR("CharFontName"); 1327 STR("CharHeight"); 1328 STR("CharPosture"); 1329 STR("CharShadowed"); 1330 STR("CharStrikeout"); 1331 STR("CharUnderline"); 1332 STR("CharUnderlineColor"); 1333 STR("CharWeight"); 1334 STR("NumberingLevel"); 1335 STR("NumberingRules"); 1336 STR("ParaAdjust"); 1337 STR("ParaBottomMargin"); 1338 STR("ParaFirstLineIndent"); 1339 STR("ParaLeftMargin"); 1340 STR("ParaLineSpacing"); 1341 STR("ParaRightMargin"); 1342 STR("ParaTabStops"); 1343 #undef STR 1344 DBG_ASSERT( i == pSeq->getLength(), "Please adjust length" ); 1345 if( i != pSeq->getLength() ) 1346 pSeq->realloc( i ); 1347 pNames = pSeq; 1348 } 1349 return *pNames; 1350 } 1351 struct IndexCompare 1352 { 1353 const PropertyValue* pValues; 1354 IndexCompare( const PropertyValue* pVals ) : pValues(pVals) {} 1355 bool operator() ( const sal_Int32& a, const sal_Int32& b ) const 1356 { 1357 return (pValues[a].Name < pValues[b].Name) ? true : false; 1358 } 1359 }; 1360 1361 String AccessibleEditableTextPara::GetFieldTypeNameAtIndex(sal_Int32 nIndex) 1362 { 1363 String strFldType; 1364 SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); 1365 //For field object info 1366 sal_Int32 nParaIndex = GetParagraphIndex(); 1367 sal_Int32 nAllFieldLen = 0; 1368 sal_Int32 nField = rCacheTF.GetFieldCount(sal_uInt16(nParaIndex)), nFoundFieldIndex = -1; 1369 EFieldInfo ree; 1370 sal_Int32 reeBegin, reeEnd; 1371 sal_Int32 nFieldType = -1; 1372 for(sal_uInt16 j = 0; j < nField; j++) 1373 { 1374 ree = rCacheTF.GetFieldInfo(sal_uInt16(nParaIndex), j); 1375 reeBegin = ree.aPosition.nIndex + nAllFieldLen; 1376 reeEnd = reeBegin + ree.aCurrentText.Len(); 1377 nAllFieldLen += (ree.aCurrentText.Len() - 1); 1378 if( reeBegin > nIndex ) 1379 { 1380 break; 1381 } 1382 if( nIndex >= reeBegin && nIndex < reeEnd ) 1383 { 1384 nFoundFieldIndex = j; 1385 break; 1386 } 1387 } 1388 if( nFoundFieldIndex >= 0 ) 1389 { 1390 // So we get a field, check its type now. 1391 nFieldType = ree.pFieldItem->GetField()->GetClassId() ; 1392 } 1393 switch(nFieldType) 1394 { 1395 case SVX_DATEFIELD: 1396 { 1397 const SvxDateField* pDateField = static_cast< const SvxDateField* >(ree.pFieldItem->GetField()); 1398 if (pDateField) 1399 { 1400 if (pDateField->GetType() == SVXDATETYPE_FIX) 1401 strFldType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("date (fixed)")); 1402 else if (pDateField->GetType() == SVXDATETYPE_VAR) 1403 strFldType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("date (variable)")); 1404 } 1405 } 1406 break; 1407 case SVX_PAGEFIELD: 1408 strFldType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("page-number")); 1409 break; 1410 //support the sheet name & pages fields 1411 case SVX_PAGESFIELD: 1412 strFldType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("page-count")); 1413 break; 1414 case SVX_TABLEFIELD: 1415 strFldType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("sheet-name")); 1416 break; 1417 //End 1418 case SVX_TIMEFIELD: 1419 strFldType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("time")); 1420 break; 1421 case SVX_EXT_TIMEFIELD: 1422 { 1423 const SvxExtTimeField* pTimeField = static_cast< const SvxExtTimeField* >(ree.pFieldItem->GetField()); 1424 if (pTimeField) 1425 { 1426 if (pTimeField->GetType() == SVXTIMETYPE_FIX) 1427 strFldType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("time (fixed)")); 1428 else if (pTimeField->GetType() == SVXTIMETYPE_VAR) 1429 strFldType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("time (variable)")); 1430 } 1431 } 1432 break; 1433 case SVX_AUTHORFIELD: 1434 strFldType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("author")); 1435 break; 1436 case SVX_EXT_FILEFIELD: 1437 case SVX_FILEFIELD: 1438 strFldType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("file name")); 1439 default: 1440 break; 1441 } 1442 return strFldType; 1443 } 1444 1445 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) 1446 { 1447 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1448 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1449 1450 //Skip the bullet range to ingnore the bullet text 1451 SvxTextForwarder& rCacheTF = GetTextForwarder(); 1452 EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo( static_cast< sal_uInt16 >(GetParagraphIndex()) ); 1453 if (aBulletInfo.bVisible) 1454 nIndex += aBulletInfo.aText.Len(); 1455 if (nIndex != 0 && nIndex >= getCharacterCount()) 1456 nIndex = getCharacterCount()-1; 1457 // 1458 if (nIndex != 0) 1459 CheckIndex(nIndex); // may throw IndexOutOfBoundsException 1460 1461 bool bSupplementalMode = false; 1462 uno::Sequence< ::rtl::OUString > aPropertyNames = rRequestedAttributes; 1463 if (aPropertyNames.getLength() == 0) 1464 { 1465 bSupplementalMode = true; 1466 aPropertyNames = getAttributeNames(); 1467 } 1468 // get default attribues... 1469 ::comphelper::SequenceAsHashMap aPropHashMap( getDefaultAttributes( aPropertyNames ) ); 1470 1471 // ... and override them with the direct attributes from the specific position 1472 uno::Sequence< beans::PropertyValue > aRunAttribs( getRunAttributes( nIndex, aPropertyNames ) ); 1473 sal_Int32 nRunAttribs = aRunAttribs.getLength(); 1474 const beans::PropertyValue *pRunAttrib = aRunAttribs.getConstArray(); 1475 for (sal_Int32 k = 0; k < nRunAttribs; ++k) 1476 { 1477 const beans::PropertyValue &rRunAttrib = pRunAttrib[k]; 1478 aPropHashMap[ rRunAttrib.Name ] = rRunAttrib.Value; //!! should not only be the value !! 1479 } 1480 #ifdef TL_DEBUG 1481 { 1482 uno::Sequence< rtl::OUString > aNames(1); 1483 aNames.getArray()[0] = rtl::OUString::createFromAscii("CharHeight"); 1484 const rtl::OUString *pNames = aNames.getConstArray(); 1485 const uno::Sequence< beans::PropertyValue > aAttribs( getRunAttributes( nIndex, aNames ) ); 1486 const beans::PropertyValue *pAttribs = aAttribs.getConstArray(); 1487 double d1 = -1.0; 1488 float f1 = -1.0; 1489 if (aAttribs.getLength()) 1490 { 1491 uno::Any aAny( pAttribs[0].Value ); 1492 aAny >>= d1; 1493 aAny >>= f1; 1494 } 1495 int i = 3; 1496 } 1497 #endif 1498 1499 // get resulting sequence 1500 uno::Sequence< beans::PropertyValue > aRes; 1501 aPropHashMap >> aRes; 1502 1503 // since SequenceAsHashMap ignores property handles and property state 1504 // we have to restore the property state here (property handles are 1505 // of no use to the accessibility API). 1506 sal_Int32 nRes = aRes.getLength(); 1507 beans::PropertyValue *pRes = aRes.getArray(); 1508 for (sal_Int32 i = 0; i < nRes; ++i) 1509 { 1510 beans::PropertyValue &rRes = pRes[i]; 1511 sal_Bool bIsDirectVal = sal_False; 1512 for (sal_Int32 k = 0; k < nRunAttribs && !bIsDirectVal; ++k) 1513 { 1514 if (rRes.Name == pRunAttrib[k].Name) 1515 bIsDirectVal = sal_True; 1516 } 1517 rRes.Handle = -1; 1518 rRes.State = bIsDirectVal ? PropertyState_DIRECT_VALUE : PropertyState_DEFAULT_VALUE; 1519 } 1520 if( bSupplementalMode ) 1521 { 1522 _correctValues( nIndex, aRes ); 1523 // NumberingPrefix 1524 nRes = aRes.getLength(); 1525 aRes.realloc( nRes + 1 ); 1526 pRes = aRes.getArray(); 1527 beans::PropertyValue &rRes = pRes[nRes]; 1528 rRes.Name = rtl::OUString::createFromAscii("NumberingPrefix"); 1529 ::rtl::OUString numStr; 1530 if (aBulletInfo.nType != SVX_NUM_CHAR_SPECIAL && aBulletInfo.nType != SVX_NUM_BITMAP) 1531 numStr = (::rtl::OUString)aBulletInfo.aText; 1532 rRes.Value <<= numStr; 1533 rRes.Handle = -1; 1534 rRes.State = PropertyState_DIRECT_VALUE; 1535 //For field object. 1536 String strFieldType = GetFieldTypeNameAtIndex(nIndex); 1537 if (strFieldType.Len() > 0) 1538 { 1539 nRes = aRes.getLength(); 1540 aRes.realloc( nRes + 1 ); 1541 pRes = aRes.getArray(); 1542 beans::PropertyValue &rResField = pRes[nRes]; 1543 beans::PropertyValue aFieldType; 1544 rResField.Name = rtl::OUString::createFromAscii("FieldType"); 1545 rResField.Value <<= rtl::OUString(strFieldType.ToLowerAscii()); 1546 rResField.Handle = -1; 1547 rResField.State = PropertyState_DIRECT_VALUE; 1548 } 1549 //sort property values 1550 // build sorted index array 1551 sal_Int32 nLength = aRes.getLength(); 1552 const beans::PropertyValue* pPairs = aRes.getConstArray(); 1553 sal_Int32* pIndices = new sal_Int32[nLength]; 1554 sal_Int32 i = 0; 1555 for( i = 0; i < nLength; i++ ) 1556 pIndices[i] = i; 1557 sort( &pIndices[0], &pIndices[nLength], IndexCompare(pPairs) ); 1558 // create sorted sequences accoring to index array 1559 uno::Sequence<beans::PropertyValue> aNewValues( nLength ); 1560 beans::PropertyValue* pNewValues = aNewValues.getArray(); 1561 for( i = 0; i < nLength; i++ ) 1562 { 1563 pNewValues[i] = pPairs[pIndices[i]]; 1564 } 1565 delete[] pIndices; 1566 // 1567 return aNewValues; 1568 } 1569 return aRes; 1570 } 1571 1572 awt::Rectangle SAL_CALL AccessibleEditableTextPara::getCharacterBounds( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 1573 { 1574 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1575 1576 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1577 1578 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 1579 "AccessibleEditableTextPara::getCharacterBounds: index value overflow"); 1580 1581 // #108900# Have position semantics now for nIndex, as 1582 // one-past-the-end values are legal, too. 1583 CheckPosition( nIndex ); 1584 1585 SvxTextForwarder& rCacheTF = GetTextForwarder(); 1586 Rectangle aRect = rCacheTF.GetCharBounds( static_cast< sal_uInt16 >( GetParagraphIndex() ), static_cast< sal_uInt16 >( nIndex ) ); 1587 1588 // convert to screen 1589 Rectangle aScreenRect = AccessibleEditableTextPara::LogicToPixel( aRect, 1590 rCacheTF.GetMapMode(), 1591 GetViewForwarder() ); 1592 // #109864# offset from parent (paragraph), but in screen 1593 // coordinates. This makes sure the internal text offset in 1594 // the outline view forwarder gets cancelled out here 1595 awt::Rectangle aParaRect( getBounds() ); 1596 aScreenRect.Move( -aParaRect.X, -aParaRect.Y ); 1597 1598 // offset from shape/cell 1599 Point aOffset = GetEEOffset(); 1600 1601 return awt::Rectangle( aScreenRect.Left() + aOffset.X(), 1602 aScreenRect.Top() + aOffset.Y(), 1603 aScreenRect.GetSize().Width(), 1604 aScreenRect.GetSize().Height() ); 1605 } 1606 1607 sal_Int32 SAL_CALL AccessibleEditableTextPara::getCharacterCount() throw (uno::RuntimeException) 1608 { 1609 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1610 1611 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1612 1613 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 1614 "AccessibleEditableTextPara::getCharacterCount: index value overflow"); 1615 1616 return OCommonAccessibleText::getCharacterCount(); 1617 } 1618 1619 sal_Int32 SAL_CALL AccessibleEditableTextPara::getIndexAtPoint( const awt::Point& rPoint ) throw (uno::RuntimeException) 1620 { 1621 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1622 1623 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1624 if ((rPoint.X <= 0) && (rPoint.Y <= 0)) 1625 return 0; 1626 sal_uInt16 nPara, nIndex; 1627 1628 // offset from surrounding cell/shape 1629 Point aOffset( GetEEOffset() ); 1630 Point aPoint( rPoint.X - aOffset.X(), rPoint.Y - aOffset.Y() ); 1631 1632 // convert to logical coordinates 1633 SvxTextForwarder& rCacheTF = GetTextForwarder(); 1634 Point aLogPoint( GetViewForwarder().PixelToLogic( aPoint, rCacheTF.GetMapMode() ) ); 1635 1636 // re-offset to parent (paragraph) 1637 Rectangle aParaRect = rCacheTF.GetParaBounds( static_cast< sal_uInt16 >( GetParagraphIndex() ) ); 1638 aLogPoint.Move( aParaRect.Left(), aParaRect.Top() ); 1639 1640 if( rCacheTF.GetIndexAtPoint( aLogPoint, nPara, nIndex ) && 1641 GetParagraphIndex() == nPara ) 1642 { 1643 // #102259# Double-check if we're _really_ on the given character 1644 try 1645 { 1646 awt::Rectangle aRect1( getCharacterBounds(nIndex) ); 1647 Rectangle aRect2( aRect1.X, aRect1.Y, 1648 aRect1.Width + aRect1.X, aRect1.Height + aRect1.Y ); 1649 if( aRect2.IsInside( Point( rPoint.X, rPoint.Y ) ) ) 1650 return nIndex; 1651 else 1652 return -1; 1653 } 1654 catch( const lang::IndexOutOfBoundsException& ) 1655 { 1656 // #103927# Don't throw for invalid nIndex values 1657 return -1; 1658 } 1659 } 1660 else 1661 { 1662 // not within our paragraph 1663 return -1; 1664 } 1665 } 1666 1667 ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getSelectedText() throw (uno::RuntimeException) 1668 { 1669 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1670 1671 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1672 1673 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 1674 "AccessibleEditableTextPara::getSelectedText: index value overflow"); 1675 1676 if( !HaveEditView() ) 1677 return ::rtl::OUString(); 1678 1679 return OCommonAccessibleText::getSelectedText(); 1680 } 1681 1682 sal_Int32 SAL_CALL AccessibleEditableTextPara::getSelectionStart() throw (uno::RuntimeException) 1683 { 1684 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1685 1686 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1687 1688 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 1689 "AccessibleEditableTextPara::getSelectionStart: index value overflow"); 1690 1691 if( !HaveEditView() ) 1692 return -1; 1693 1694 return OCommonAccessibleText::getSelectionStart(); 1695 } 1696 1697 sal_Int32 SAL_CALL AccessibleEditableTextPara::getSelectionEnd() throw (uno::RuntimeException) 1698 { 1699 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1700 1701 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1702 1703 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 1704 "AccessibleEditableTextPara::getSelectionEnd: index value overflow"); 1705 1706 if( !HaveEditView() ) 1707 return -1; 1708 1709 return OCommonAccessibleText::getSelectionEnd(); 1710 } 1711 1712 sal_Bool SAL_CALL AccessibleEditableTextPara::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 1713 { 1714 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1715 1716 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1717 1718 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 1719 "AccessibleEditableTextPara::setSelection: paragraph index value overflow"); 1720 1721 CheckRange(nStartIndex, nEndIndex); 1722 1723 try 1724 { 1725 SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( sal_True ); 1726 return rCacheVF.SetSelection( MakeSelection(nStartIndex, nEndIndex) ); 1727 } 1728 catch( const uno::RuntimeException& ) 1729 { 1730 return sal_False; 1731 } 1732 } 1733 1734 ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getText() throw (uno::RuntimeException) 1735 { 1736 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1737 1738 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1739 1740 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 1741 "AccessibleEditableTextPara::getText: paragraph index value overflow"); 1742 1743 return OCommonAccessibleText::getText(); 1744 } 1745 1746 ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 1747 { 1748 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 1749 1750 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 1751 1752 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 1753 "AccessibleEditableTextPara::getTextRange: paragraph index value overflow"); 1754 1755 return OCommonAccessibleText::getTextRange(nStartIndex, nEndIndex); 1756 } 1757 void AccessibleEditableTextPara::_correctValues( const sal_Int32 /* nIndex */, 1758 uno::Sequence< PropertyValue >& rValues) 1759 { 1760 SvxTextForwarder& rCacheTF = GetTextForwarder(); 1761 sal_Int32 nRes = rValues.getLength(); 1762 beans::PropertyValue *pRes = rValues.getArray(); 1763 for (sal_Int32 i = 0; i < nRes; ++i) 1764 { 1765 beans::PropertyValue &rRes = pRes[i]; 1766 // Char color 1767 if (rRes.Name.compareTo(::rtl::OUString::createFromAscii("CharColor"))==0) 1768 { 1769 uno::Any &anyChar = rRes.Value; 1770 sal_uInt32 crChar = static_cast<sal_uInt32>( reinterpret_cast<sal_uIntPtr>(anyChar.pReserved)); 1771 if (COL_AUTO == crChar ) 1772 { 1773 uno::Reference< ::com::sun::star::accessibility::XAccessibleComponent > xComponent; 1774 if (mxParent.is()) 1775 { 1776 xComponent.set(mxParent,uno::UNO_QUERY); 1777 } 1778 else 1779 { 1780 xComponent.set(m_xAccInfo,uno::UNO_QUERY); 1781 } 1782 if (xComponent.is()) 1783 { 1784 uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > xContext(xComponent,uno::UNO_QUERY); 1785 if (xContext->getAccessibleRole() == AccessibleRole::SHAPE 1786 || xContext->getAccessibleRole() == AccessibleRole::TABLE_CELL) 1787 { 1788 anyChar <<= COL_BLACK; 1789 } 1790 else 1791 { 1792 Color cr(xComponent->getBackground()); 1793 crChar = cr.IsDark() ? COL_WHITE : COL_BLACK; 1794 anyChar <<= crChar; 1795 } 1796 } 1797 } 1798 continue; 1799 } 1800 // Underline 1801 if(rRes.Name.compareTo(::rtl::OUString::createFromAscii("CharUnderline"))==0) 1802 { 1803 /* 1804 // MT: Implement XAccessibleTextMarkup, mark with TextMarkupType::SPELLCHECK. This way done in SW. 1805 if (IsCurrentEditorEnableAutoSpell( mxParent )) 1806 { 1807 try 1808 { 1809 SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( sal_False ); 1810 sal_Bool bWrong = rCacheVF.IsWrongSpelledWordAtPos( GetParagraphIndex(), nIndex ); 1811 if ( bWrong ) 1812 { 1813 uno::Any &anyUnderLine = pRes[9].Value; 1814 // MT IA2: Not needed? sal_uInt16 crUnderLine = (sal_uInt16)(anyUnderLine.pReserved); 1815 anyUnderLine <<= (sal_uInt16)UNDERLINE_WAVE; 1816 } 1817 } 1818 catch( const uno::RuntimeException& ) 1819 { 1820 } 1821 } 1822 */ 1823 continue; 1824 } 1825 // Underline color && Mis-spell 1826 if(rRes.Name.compareTo(::rtl::OUString::createFromAscii("CharUnderlineColor"))==0) 1827 { 1828 uno::Any &anyCharUnderLine = rRes.Value; 1829 sal_uInt32 crCharUnderLine = static_cast<sal_uInt32>( reinterpret_cast<sal_uIntPtr>( anyCharUnderLine.pReserved)); 1830 if (COL_AUTO == crCharUnderLine ) 1831 { 1832 uno::Reference< ::com::sun::star::accessibility::XAccessibleComponent > xComponent; 1833 if (mxParent.is()) 1834 { 1835 xComponent.set(mxParent,uno::UNO_QUERY); 1836 } 1837 else 1838 { 1839 xComponent.set(m_xAccInfo,uno::UNO_QUERY); 1840 } 1841 if (xComponent.is()) 1842 { 1843 uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > xContext(xComponent,uno::UNO_QUERY); 1844 if (xContext->getAccessibleRole() == AccessibleRole::SHAPE 1845 || xContext->getAccessibleRole() == AccessibleRole::TABLE_CELL) 1846 { 1847 anyCharUnderLine <<= COL_BLACK; 1848 } 1849 else 1850 { 1851 Color cr(xComponent->getBackground()); 1852 crCharUnderLine = cr.IsDark() ? COL_WHITE : COL_BLACK; 1853 anyCharUnderLine <<= crCharUnderLine; 1854 } 1855 } 1856 } 1857 // MT: Implement XAccessibleTextMarkup, mark with TextMarkupType::SPELLCHECK. This way done in SW. 1858 /* 1859 if (IsCurrentEditorEnableAutoSpell( mxParent )) 1860 { 1861 try 1862 { 1863 SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( sal_False ); 1864 sal_Bool bWrong = rCacheVF.IsWrongSpelledWordAtPos( GetParagraphIndex(), nIndex ); 1865 if ( bWrong ) 1866 { 1867 uno::Any &anyUnderLineColor = rRes.Value; 1868 // MT IA2: Not needed? sal_uInt16 crUnderLineColor = (sal_uInt16)(anyUnderLineColor.pReserved); 1869 anyUnderLineColor <<= COL_LIGHTRED; 1870 } 1871 } 1872 catch( const uno::RuntimeException& ) 1873 { 1874 } 1875 } 1876 */ 1877 continue; 1878 } 1879 // NumberingLevel 1880 if(rRes.Name.compareTo(::rtl::OUString::createFromAscii("NumberingLevel"))==0) 1881 { 1882 const SvxNumBulletItem& rNumBullet = ( SvxNumBulletItem& )rCacheTF.GetParaAttribs(static_cast< sal_uInt16 >(GetParagraphIndex())).Get(EE_PARA_NUMBULLET); 1883 if(rNumBullet.GetNumRule()->GetLevelCount()==0) 1884 { 1885 rRes.Value <<= (sal_Int16)-1; 1886 rRes.Handle = -1; 1887 rRes.State = PropertyState_DIRECT_VALUE; 1888 } 1889 else 1890 { 1891 // SvxAccessibleTextPropertySet aPropSet( &GetEditSource(), 1892 // ImplGetSvxCharAndParaPropertiesMap() ); 1893 // MT IA2 TODO: Check if this is the correct replacement for ImplGetSvxCharAndParaPropertiesMap 1894 SvxAccessibleTextPropertySet aPropSet( &GetEditSource(), ImplGetSvxTextPortionSvxPropertySet() ); 1895 1896 aPropSet.SetSelection( MakeSelection( 0, GetTextLen() ) ); 1897 rRes.Value = aPropSet._getPropertyValue( rRes.Name, mnParagraphIndex ); 1898 rRes.State = aPropSet._getPropertyState( rRes.Name, mnParagraphIndex ); 1899 rRes.Handle = -1; 1900 } 1901 continue; 1902 } 1903 // NumberingRules 1904 if(rRes.Name.compareTo(::rtl::OUString::createFromAscii("NumberingRules"))==0) 1905 { 1906 SfxItemSet aAttribs = rCacheTF.GetParaAttribs( static_cast< sal_uInt16 >(GetParagraphIndex()) ); 1907 sal_Bool bVis = ((const SfxUInt16Item&)aAttribs.Get( EE_PARA_BULLETSTATE )).GetValue() ? sal_True : sal_False; 1908 if(bVis) 1909 { 1910 rRes.Value <<= (sal_Int16)-1; 1911 rRes.Handle = -1; 1912 rRes.State = PropertyState_DIRECT_VALUE; 1913 } 1914 else 1915 { 1916 // MT IA2 TODO: Check if this is the correct replacement for ImplGetSvxCharAndParaPropertiesMap 1917 SvxAccessibleTextPropertySet aPropSet( &GetEditSource(), ImplGetSvxTextPortionSvxPropertySet() ); 1918 aPropSet.SetSelection( MakeSelection( 0, GetTextLen() ) ); 1919 rRes.Value = aPropSet._getPropertyValue( rRes.Name, mnParagraphIndex ); 1920 rRes.State = aPropSet._getPropertyState( rRes.Name, mnParagraphIndex ); 1921 rRes.Handle = -1; 1922 } 1923 continue; 1924 } 1925 } 1926 } 1927 sal_Int32 AccessibleEditableTextPara::SkipField(sal_Int32 nIndex, sal_Bool bForward) 1928 { 1929 sal_Int32 nParaIndex = GetParagraphIndex(); 1930 SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); 1931 sal_Int32 nAllFieldLen = 0; 1932 sal_Int32 nField = rCacheTF.GetFieldCount(sal_uInt16(nParaIndex)), nFoundFieldIndex = -1; 1933 EFieldInfo ree; 1934 sal_Int32 reeBegin=0, reeEnd=0; 1935 for(sal_uInt16 j = 0; j < nField; j++) 1936 { 1937 ree = rCacheTF.GetFieldInfo(sal_uInt16(nParaIndex), j); 1938 reeBegin = ree.aPosition.nIndex + nAllFieldLen; 1939 reeEnd = reeBegin + ree.aCurrentText.Len(); 1940 nAllFieldLen += (ree.aCurrentText.Len() - 1); 1941 if( reeBegin > nIndex ) 1942 { 1943 break; 1944 } 1945 if( nIndex >= reeBegin && nIndex < reeEnd ) 1946 { 1947 if(ree.pFieldItem->GetField()->GetClassId() != SVX_URLFIELD) 1948 { 1949 nFoundFieldIndex = j; 1950 break; 1951 } 1952 } 1953 } 1954 if( nFoundFieldIndex >= 0 ) 1955 { 1956 if( bForward ) 1957 return reeEnd - 1; 1958 else 1959 return reeBegin; 1960 } 1961 return nIndex; 1962 } 1963 sal_Bool AccessibleEditableTextPara::ExtendByField( ::com::sun::star::accessibility::TextSegment& Segment ) 1964 { 1965 sal_Int32 nParaIndex = GetParagraphIndex(); 1966 SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); 1967 sal_Int32 nAllFieldLen = 0; 1968 sal_Int32 nField = rCacheTF.GetFieldCount(sal_uInt16(nParaIndex)), nFoundFieldIndex = -1; 1969 EFieldInfo ree; 1970 sal_Int32 reeBegin=0, reeEnd=0; 1971 for(sal_uInt16 j = 0; j < nField; j++) 1972 { 1973 ree = rCacheTF.GetFieldInfo(sal_uInt16(nParaIndex), j); 1974 reeBegin = ree.aPosition.nIndex + nAllFieldLen; 1975 reeEnd = reeBegin + ree.aCurrentText.Len(); 1976 nAllFieldLen += (ree.aCurrentText.Len() - 1); 1977 if( reeBegin > Segment.SegmentEnd ) 1978 { 1979 break; 1980 } 1981 if( (Segment.SegmentEnd > reeBegin && Segment.SegmentEnd <= reeEnd) || 1982 (Segment.SegmentStart >= reeBegin && Segment.SegmentStart < reeEnd) ) 1983 { 1984 if(ree.pFieldItem->GetField()->GetClassId() != SVX_URLFIELD) 1985 { 1986 nFoundFieldIndex = j; 1987 break; 1988 } 1989 } 1990 } 1991 sal_Bool bExtend = sal_False; 1992 if( nFoundFieldIndex >= 0 ) 1993 { 1994 if( Segment.SegmentEnd < reeEnd ) 1995 { 1996 Segment.SegmentEnd = reeEnd; 1997 bExtend = sal_True; 1998 } 1999 if( Segment.SegmentStart > reeBegin ) 2000 { 2001 Segment.SegmentStart = reeBegin; 2002 bExtend = sal_True; 2003 } 2004 if( bExtend ) 2005 { 2006 //If there is a bullet before the field, should add the bullet length into the segment. 2007 EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo(sal_uInt16(nParaIndex)); 2008 int nBulletLen = aBulletInfo.aText.Len(); 2009 if (nBulletLen > 0) 2010 { 2011 Segment.SegmentEnd += nBulletLen; 2012 if (nFoundFieldIndex > 0) 2013 Segment.SegmentStart += nBulletLen; 2014 Segment.SegmentText = GetTextRange(Segment.SegmentStart, Segment.SegmentEnd); 2015 //After get the correct field name, should restore the offset value which don't contain the bullet. 2016 Segment.SegmentEnd -= nBulletLen; 2017 if (nFoundFieldIndex > 0) 2018 Segment.SegmentStart -= nBulletLen; 2019 } 2020 else 2021 Segment.SegmentText = GetTextRange(Segment.SegmentStart, Segment.SegmentEnd); 2022 } 2023 } 2024 return bExtend; 2025 } 2026 ::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) 2027 { 2028 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 2029 2030 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 2031 2032 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 2033 "AccessibleEditableTextPara::getTextAtIndex: paragraph index value overflow"); 2034 2035 ::com::sun::star::accessibility::TextSegment aResult; 2036 aResult.SegmentStart = -1; 2037 aResult.SegmentEnd = -1; 2038 2039 switch( aTextType ) 2040 { 2041 case AccessibleTextType::CHARACTER: 2042 case AccessibleTextType::WORD: 2043 { 2044 aResult = OCommonAccessibleText::getTextAtIndex( nIndex, aTextType ); 2045 ExtendByField( aResult ); 2046 break; 2047 } 2048 // Not yet handled by OCommonAccessibleText. Missing 2049 // implGetAttributeRunBoundary() method there 2050 case AccessibleTextType::ATTRIBUTE_RUN: 2051 { 2052 const sal_Int32 nTextLen = GetTextForwarder().GetTextLen( static_cast< sal_uInt16 >( GetParagraphIndex() ) ); 2053 2054 if( nIndex == nTextLen ) 2055 { 2056 // #i17014# Special-casing one-behind-the-end character 2057 aResult.SegmentStart = aResult.SegmentEnd = nTextLen; 2058 } 2059 else 2060 { 2061 sal_uInt16 nStartIndex, nEndIndex; 2062 //For the bullet paragraph, the bullet string is ingnored for IAText::attributes() function. 2063 SvxTextForwarder& rCacheTF = GetTextForwarder(); 2064 // MT IA2: Not used? sal_Int32 nBulletLen = 0; 2065 EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo( static_cast< sal_uInt16 >(GetParagraphIndex()) ); 2066 if (aBulletInfo.bVisible) 2067 nIndex += aBulletInfo.aText.Len(); 2068 if (nIndex != 0 && nIndex >= getCharacterCount()) 2069 nIndex = getCharacterCount()-1; 2070 CheckPosition(nIndex); 2071 if( GetAttributeRun(nStartIndex, nEndIndex, nIndex) ) 2072 { 2073 aResult.SegmentText = GetTextRange(nStartIndex, nEndIndex); 2074 if (aBulletInfo.bVisible) 2075 { 2076 nStartIndex -= aBulletInfo.aText.Len(); 2077 nEndIndex -= aBulletInfo.aText.Len(); 2078 } 2079 aResult.SegmentStart = nStartIndex; 2080 aResult.SegmentEnd = nEndIndex; 2081 } 2082 } 2083 break; 2084 } 2085 case AccessibleTextType::LINE: 2086 { 2087 SvxTextForwarder& rCacheTF = GetTextForwarder(); 2088 sal_Int32 nParaIndex = GetParagraphIndex(); 2089 // MT IA2: Not needed? sal_Int32 nTextLen = rCacheTF.GetTextLen( static_cast< sal_uInt16 >( nParaIndex ) ); 2090 CheckPosition(nIndex); 2091 if (nIndex != 0 && nIndex == getCharacterCount()) 2092 --nIndex; 2093 sal_uInt16 nLine, nLineCount=rCacheTF.GetLineCount( static_cast< sal_uInt16 >( nParaIndex ) ); 2094 sal_Int32 nCurIndex; 2095 //the problem is that rCacheTF.GetLineLen() will include the bullet length. But for the bullet line, 2096 //the text value doesn't contain the bullet characters. all of the bullet and numbering info are exposed 2097 //by the IAText::attributes(). So here must do special support for bullet line. 2098 sal_Int32 nBulletLen = 0; 2099 for( nLine=0, nCurIndex=0; nLine<nLineCount; ++nLine ) 2100 { 2101 if (nLine == 0) 2102 { 2103 EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo( static_cast< sal_uInt16 >(nParaIndex) ); 2104 if (aBulletInfo.bVisible) 2105 { 2106 //in bullet or numbering; 2107 nBulletLen = aBulletInfo.aText.Len(); 2108 } 2109 } 2110 //nCurIndex += rCacheTF.GetLineLen( static_cast< sal_uInt16 >( nParaIndex ), nLine); 2111 sal_Int32 nLineLen = rCacheTF.GetLineLen( static_cast< sal_uInt16 >( nParaIndex ), nLine); 2112 if (nLine == 0) 2113 nCurIndex += nLineLen - nBulletLen; 2114 else 2115 nCurIndex += nLineLen; 2116 if( nCurIndex > nIndex ) 2117 { 2118 if (nLine ==0) 2119 { 2120 //aResult.SegmentStart = nCurIndex - rCacheTF.GetLineLen(static_cast< sal_uInt16 >( nParaIndex ), nLine); 2121 aResult.SegmentStart = 0; 2122 aResult.SegmentEnd = nCurIndex; 2123 //aResult.SegmentText = GetTextRange( aResult.SegmentStart, aResult.SegmentEnd ); 2124 aResult.SegmentText = GetTextRange( aResult.SegmentStart, aResult.SegmentEnd + nBulletLen); 2125 break; 2126 } 2127 else 2128 { 2129 //aResult.SegmentStart = nCurIndex - rCacheTF.GetLineLen(static_cast< sal_uInt16 >( nParaIndex ), nLine); 2130 aResult.SegmentStart = nCurIndex - nLineLen; 2131 aResult.SegmentEnd = nCurIndex; 2132 //aResult.SegmentText = GetTextRange( aResult.SegmentStart, aResult.SegmentEnd ); 2133 aResult.SegmentText = GetTextRange( aResult.SegmentStart + nBulletLen, aResult.SegmentEnd + nBulletLen); 2134 break; 2135 } 2136 } 2137 } 2138 break; 2139 } 2140 default: 2141 aResult = OCommonAccessibleText::getTextAtIndex( nIndex, aTextType ); 2142 break; 2143 } /* end of switch( aTextType ) */ 2144 2145 return aResult; 2146 } 2147 2148 ::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) 2149 { 2150 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 2151 2152 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 2153 2154 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 2155 "AccessibleEditableTextPara::getTextBeforeIndex: paragraph index value overflow"); 2156 2157 ::com::sun::star::accessibility::TextSegment aResult; 2158 aResult.SegmentStart = -1; 2159 aResult.SegmentEnd = -1; 2160 i18n::Boundary aBoundary; 2161 switch( aTextType ) 2162 { 2163 // Not yet handled by OCommonAccessibleText. Missing 2164 // implGetAttributeRunBoundary() method there 2165 case AccessibleTextType::ATTRIBUTE_RUN: 2166 { 2167 const sal_Int32 nTextLen = GetTextForwarder().GetTextLen( static_cast< sal_uInt16 >( GetParagraphIndex() ) ); 2168 sal_uInt16 nStartIndex, nEndIndex; 2169 2170 if( nIndex == nTextLen ) 2171 { 2172 // #i17014# Special-casing one-behind-the-end character 2173 if( nIndex > 0 && 2174 GetAttributeRun(nStartIndex, nEndIndex, nIndex-1) ) 2175 { 2176 aResult.SegmentText = GetTextRange(nStartIndex, nEndIndex); 2177 aResult.SegmentStart = nStartIndex; 2178 aResult.SegmentEnd = nEndIndex; 2179 } 2180 } 2181 else 2182 { 2183 if( GetAttributeRun(nStartIndex, nEndIndex, nIndex) ) 2184 { 2185 // already at the left border? If not, query 2186 // one index further left 2187 if( nStartIndex > 0 && 2188 GetAttributeRun(nStartIndex, nEndIndex, nStartIndex-1) ) 2189 { 2190 aResult.SegmentText = GetTextRange(nStartIndex, nEndIndex); 2191 aResult.SegmentStart = nStartIndex; 2192 aResult.SegmentEnd = nEndIndex; 2193 } 2194 } 2195 } 2196 break; 2197 } 2198 case AccessibleTextType::LINE: 2199 { 2200 SvxTextForwarder& rCacheTF = GetTextForwarder(); 2201 sal_Int32 nParaIndex = GetParagraphIndex(); 2202 // MT IA2 not needed? sal_Int32 nTextLen = rCacheTF.GetTextLen( static_cast< sal_uInt16 >( nParaIndex ) ); 2203 2204 CheckPosition(nIndex); 2205 2206 sal_uInt16 nLine, nLineCount=rCacheTF.GetLineCount( static_cast< sal_uInt16 >( nParaIndex ) ); 2207 //the problem is that rCacheTF.GetLineLen() will include the bullet length. But for the bullet line, 2208 //the text value doesn't contain the bullet characters. all of the bullet and numbering info are exposed 2209 //by the IAText::attributes(). So here must do special support for bullet line. 2210 sal_Int32 nCurIndex=0, nLastIndex=0, nCurLineLen=0; 2211 sal_Int32 nLastLineLen = 0, nBulletLen = 0;; 2212 // get the line before the line the index points into 2213 for( nLine=0, nCurIndex=0, nLastIndex=0; nLine<nLineCount; ++nLine ) 2214 { 2215 nLastIndex = nCurIndex; 2216 if (nLine == 0) 2217 { 2218 EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo( static_cast< sal_uInt16 >(nParaIndex) ); 2219 if (aBulletInfo.bVisible) 2220 { 2221 //in bullet or numbering; 2222 nBulletLen = aBulletInfo.aText.Len(); 2223 } 2224 } 2225 if (nLine == 1) 2226 nLastLineLen = nCurLineLen - nBulletLen; 2227 else 2228 nLastLineLen = nCurLineLen; 2229 nCurLineLen = rCacheTF.GetLineLen(static_cast< sal_uInt16 >( nParaIndex ), nLine); 2230 //nCurIndex += nCurLineLen; 2231 if (nLine == 0) 2232 nCurIndex += nCurLineLen - nBulletLen; 2233 else 2234 nCurIndex += nCurLineLen; 2235 2236 //if( nCurIndex > nIndex && 2237 //nLastIndex > nCurLineLen ) 2238 if (nCurIndex > nIndex) 2239 { 2240 if (nLine == 0) 2241 { 2242 break; 2243 } 2244 else if (nLine == 1) 2245 { 2246 aResult.SegmentStart = 0; 2247 aResult.SegmentEnd = static_cast< sal_uInt16 >( nLastIndex ); 2248 aResult.SegmentText = GetTextRange( aResult.SegmentStart, aResult.SegmentEnd + nBulletLen); 2249 break; 2250 } 2251 else 2252 { 2253 //aResult.SegmentStart = nLastIndex - nCurLineLen; 2254 aResult.SegmentStart = nLastIndex - nLastLineLen; 2255 aResult.SegmentEnd = static_cast< sal_uInt16 >( nLastIndex ); 2256 aResult.SegmentText = GetTextRange( aResult.SegmentStart + nBulletLen, aResult.SegmentEnd + nBulletLen); 2257 break; 2258 } 2259 } 2260 } 2261 2262 break; 2263 } 2264 case AccessibleTextType::WORD: 2265 { 2266 nIndex = SkipField( nIndex, sal_False); 2267 ::rtl::OUString sText( implGetText() ); 2268 sal_Int32 nLength = sText.getLength(); 2269 2270 // get word at index 2271 implGetWordBoundary( aBoundary, nIndex ); 2272 2273 2274 //sal_Int32 curWordStart = aBoundary.startPos; 2275 //sal_Int32 preWordStart = curWordStart; 2276 sal_Int32 curWordStart , preWordStart; 2277 if( aBoundary.startPos == -1 || aBoundary.startPos > nIndex) 2278 curWordStart = preWordStart = nIndex; 2279 else 2280 curWordStart = preWordStart = aBoundary.startPos; 2281 2282 // get previous word 2283 2284 sal_Bool bWord = sal_False; 2285 2286 //while ( preWordStart > 0 && aBoundary.startPos == curWordStart) 2287 while ( (preWordStart >= 0 && !bWord ) || ( aBoundary.endPos > curWordStart ) ) 2288 { 2289 preWordStart--; 2290 bWord = implGetWordBoundary( aBoundary, preWordStart ); 2291 } 2292 if ( bWord && implIsValidBoundary( aBoundary, nLength ) ) 2293 { 2294 aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos ); 2295 aResult.SegmentStart = aBoundary.startPos; 2296 aResult.SegmentEnd = aBoundary.endPos; 2297 ExtendByField( aResult ); 2298 } 2299 } 2300 break; 2301 case AccessibleTextType::CHARACTER: 2302 { 2303 nIndex = SkipField( nIndex, sal_False); 2304 aResult = OCommonAccessibleText::getTextBeforeIndex( nIndex, aTextType ); 2305 ExtendByField( aResult ); 2306 break; 2307 } 2308 default: 2309 aResult = OCommonAccessibleText::getTextBeforeIndex( nIndex, aTextType ); 2310 break; 2311 } /* end of switch( aTextType ) */ 2312 2313 return aResult; 2314 } 2315 2316 ::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) 2317 { 2318 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 2319 2320 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 2321 2322 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 2323 "AccessibleEditableTextPara::getTextBehindIndex: paragraph index value overflow"); 2324 2325 ::com::sun::star::accessibility::TextSegment aResult; 2326 aResult.SegmentStart = -1; 2327 aResult.SegmentEnd = -1; 2328 i18n::Boundary aBoundary; 2329 switch( aTextType ) 2330 { 2331 case AccessibleTextType::ATTRIBUTE_RUN: 2332 { 2333 sal_uInt16 nStartIndex, nEndIndex; 2334 2335 if( GetAttributeRun(nStartIndex, nEndIndex, nIndex) ) 2336 { 2337 // already at the right border? 2338 if( nEndIndex < GetTextLen() ) 2339 { 2340 if( GetAttributeRun(nStartIndex, nEndIndex, nEndIndex) ) 2341 { 2342 aResult.SegmentText = GetTextRange(nStartIndex, nEndIndex); 2343 aResult.SegmentStart = nStartIndex; 2344 aResult.SegmentEnd = nEndIndex; 2345 } 2346 } 2347 } 2348 break; 2349 } 2350 2351 case AccessibleTextType::LINE: 2352 { 2353 SvxTextForwarder& rCacheTF = GetTextForwarder(); 2354 sal_Int32 nParaIndex = GetParagraphIndex(); 2355 // MT IA2 not needed? sal_Int32 nTextLen = rCacheTF.GetTextLen( static_cast< sal_uInt16 >( nParaIndex ) ); 2356 2357 CheckPosition(nIndex); 2358 2359 sal_uInt16 nLine, nLineCount=rCacheTF.GetLineCount( static_cast< sal_uInt16 >( nParaIndex ) ); 2360 sal_Int32 nCurIndex; 2361 //the problem is that rCacheTF.GetLineLen() will include the bullet length. But for the bullet line, 2362 //the text value doesn't contain the bullet characters. all of the bullet and numbering info are exposed 2363 //by the IAText::attributes(). So here must do special support for bullet line. 2364 sal_Int32 nBulletLen = 0; 2365 // get the line after the line the index points into 2366 for( nLine=0, nCurIndex=0; nLine<nLineCount; ++nLine ) 2367 { 2368 if (nLine == 0) 2369 { 2370 EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo( static_cast< sal_uInt16 >(nParaIndex) ); 2371 if (aBulletInfo.bVisible) 2372 { 2373 //in bullet or numbering; 2374 nBulletLen = aBulletInfo.aText.Len(); 2375 } 2376 } 2377 //nCurIndex += rCacheTF.GetLineLen(static_cast< sal_uInt16 >( nParaIndex ), nLine); 2378 sal_Int32 nLineLen = rCacheTF.GetLineLen( static_cast< sal_uInt16 >( nParaIndex ), nLine); 2379 2380 if (nLine == 0) 2381 nCurIndex += nLineLen - nBulletLen; 2382 else 2383 nCurIndex += nLineLen; 2384 2385 if( nCurIndex > nIndex && 2386 nLine < nLineCount-1 ) 2387 { 2388 aResult.SegmentStart = nCurIndex; 2389 aResult.SegmentEnd = nCurIndex + rCacheTF.GetLineLen(static_cast< sal_uInt16 >( nParaIndex ), nLine+1); 2390 aResult.SegmentText = GetTextRange( aResult.SegmentStart + nBulletLen, aResult.SegmentEnd + nBulletLen); 2391 break; 2392 } 2393 } 2394 2395 break; 2396 } 2397 case AccessibleTextType::WORD: 2398 { 2399 nIndex = SkipField( nIndex, sal_True); 2400 ::rtl::OUString sText( implGetText() ); 2401 sal_Int32 nLength = sText.getLength(); 2402 2403 // get word at index 2404 sal_Bool bWord = implGetWordBoundary( aBoundary, nIndex ); 2405 2406 // real current world 2407 sal_Int32 nextWord = nIndex; 2408 //if( nIndex >= aBoundary.startPos && nIndex <= aBoundary.endPos ) 2409 if( nIndex <= aBoundary.endPos ) 2410 { 2411 nextWord = aBoundary.endPos; 2412 if( sText.getStr()[nextWord] == sal_Unicode(' ') ) nextWord++; 2413 bWord = implGetWordBoundary( aBoundary, nextWord ); 2414 } 2415 2416 if ( bWord && implIsValidBoundary( aBoundary, nLength ) ) 2417 { 2418 aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos ); 2419 aResult.SegmentStart = aBoundary.startPos; 2420 aResult.SegmentEnd = aBoundary.endPos; 2421 2422 // If the end position of aBoundary is inside a field, extend the result to the end of the field 2423 2424 ExtendByField( aResult ); 2425 } 2426 } 2427 break; 2428 2429 case AccessibleTextType::CHARACTER: 2430 { 2431 nIndex = SkipField( nIndex, sal_True); 2432 aResult = OCommonAccessibleText::getTextBehindIndex( nIndex, aTextType ); 2433 ExtendByField( aResult ); 2434 break; 2435 } 2436 default: 2437 aResult = OCommonAccessibleText::getTextBehindIndex( nIndex, aTextType ); 2438 break; 2439 } /* end of switch( aTextType ) */ 2440 2441 return aResult; 2442 } 2443 2444 sal_Bool SAL_CALL AccessibleEditableTextPara::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 2445 { 2446 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 2447 2448 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 2449 2450 try 2451 { 2452 SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( sal_True ); 2453 #if OSL_DEBUG_LEVEL > 0 2454 SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs 2455 (void)rCacheTF; 2456 #else 2457 GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs 2458 #endif 2459 2460 sal_Bool aRetVal; 2461 2462 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 2463 "AccessibleEditableTextPara::copyText: index value overflow"); 2464 2465 CheckRange(nStartIndex, nEndIndex); 2466 2467 //Because bullet may occupy one or more characters, the TextAdapter will include bullet to calculate the selection. Add offset to handle bullet 2468 sal_Int32 nBulletLen = 0; 2469 EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo( static_cast< sal_uInt16 >(GetParagraphIndex()) ); 2470 if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && aBulletInfo.bVisible ) 2471 nBulletLen = aBulletInfo.aText.Len(); 2472 // save current selection 2473 ESelection aOldSelection; 2474 2475 rCacheVF.GetSelection( aOldSelection ); 2476 //rCacheVF.SetSelection( MakeSelection(nStartIndex, nEndIndex) ); 2477 rCacheVF.SetSelection( MakeSelection(nStartIndex + nBulletLen, nEndIndex + nBulletLen) ); 2478 aRetVal = rCacheVF.Copy(); 2479 rCacheVF.SetSelection( aOldSelection ); // restore 2480 2481 return aRetVal; 2482 } 2483 catch( const uno::RuntimeException& ) 2484 { 2485 return sal_False; 2486 } 2487 } 2488 2489 // XAccessibleEditableText 2490 sal_Bool SAL_CALL AccessibleEditableTextPara::cutText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 2491 { 2492 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 2493 2494 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 2495 2496 try 2497 { 2498 SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( sal_True ); 2499 SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs 2500 2501 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 2502 "AccessibleEditableTextPara::cutText: index value overflow"); 2503 2504 CheckRange(nStartIndex, nEndIndex); 2505 2506 // Because bullet may occupy one or more characters, the TextAdapter will include bullet to calculate the selection. Add offset to handle bullet 2507 sal_Int32 nBulletLen = 0; 2508 EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo( static_cast< sal_uInt16 >(GetParagraphIndex()) ); 2509 if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && aBulletInfo.bVisible ) 2510 nBulletLen = aBulletInfo.aText.Len(); 2511 ESelection aSelection = MakeSelection (nStartIndex + nBulletLen, nEndIndex + nBulletLen); 2512 //if( !rCacheTF.IsEditable( MakeSelection(nStartIndex, nEndIndex) ) ) 2513 if( !rCacheTF.IsEditable( aSelection ) ) 2514 return sal_False; // non-editable area selected 2515 2516 // don't save selection, might become invalid after cut! 2517 //rCacheVF.SetSelection( MakeSelection(nStartIndex, nEndIndex) ); 2518 rCacheVF.SetSelection( aSelection ); 2519 2520 return rCacheVF.Cut(); 2521 } 2522 catch( const uno::RuntimeException& ) 2523 { 2524 return sal_False; 2525 } 2526 } 2527 2528 sal_Bool SAL_CALL AccessibleEditableTextPara::pasteText( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 2529 { 2530 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 2531 2532 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 2533 2534 try 2535 { 2536 SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( sal_True ); 2537 SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs 2538 2539 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 2540 "AccessibleEditableTextPara::pasteText: index value overflow"); 2541 2542 CheckPosition(nIndex); 2543 2544 // Because bullet may occupy one or more characters, the TextAdapter will include bullet to calculate the selection. Add offset to handle bullet 2545 sal_Int32 nBulletLen = 0; 2546 EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo( static_cast< sal_uInt16 >(GetParagraphIndex()) ); 2547 if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && aBulletInfo.bVisible ) 2548 nBulletLen = aBulletInfo.aText.Len(); 2549 //if( !rCacheTF.IsEditable( MakeSelection(nIndex) ) ) 2550 if( !rCacheTF.IsEditable( MakeSelection(nIndex + nBulletLen) ) ) 2551 return sal_False; // non-editable area selected 2552 2553 // #104400# set empty selection (=> cursor) to given index 2554 //rCacheVF.SetSelection( MakeCursor(nIndex) ); 2555 rCacheVF.SetSelection( MakeCursor(nIndex + nBulletLen) ); 2556 2557 return rCacheVF.Paste(); 2558 } 2559 catch( const uno::RuntimeException& ) 2560 { 2561 return sal_False; 2562 } 2563 } 2564 2565 sal_Bool SAL_CALL AccessibleEditableTextPara::deleteText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 2566 { 2567 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 2568 2569 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 2570 2571 try 2572 { 2573 // #102710# Request edit view when doing changes 2574 // AccessibleEmptyEditSource relies on this behaviour 2575 GetEditViewForwarder( sal_True ); 2576 SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs 2577 2578 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 2579 "AccessibleEditableTextPara::deleteText: index value overflow"); 2580 2581 CheckRange(nStartIndex, nEndIndex); 2582 2583 // Because bullet may occupy one or more characters, the TextAdapter will include bullet to calculate the selection. Add offset to handle bullet 2584 sal_Int32 nBulletLen = 0; 2585 EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo( static_cast< sal_uInt16 >(GetParagraphIndex()) ); 2586 if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && aBulletInfo.bVisible ) 2587 nBulletLen = aBulletInfo.aText.Len(); 2588 ESelection aSelection = MakeSelection (nStartIndex + nBulletLen, nEndIndex + nBulletLen); 2589 2590 //if( !rCacheTF.IsEditable( MakeSelection(nStartIndex, nEndIndex) ) ) 2591 if( !rCacheTF.IsEditable( aSelection ) ) 2592 return sal_False; // non-editable area selected 2593 2594 //sal_Bool bRet = rCacheTF.Delete( MakeSelection(nStartIndex, nEndIndex) ); 2595 sal_Bool bRet = rCacheTF.Delete( aSelection ); 2596 2597 GetEditSource().UpdateData(); 2598 2599 return bRet; 2600 } 2601 catch( const uno::RuntimeException& ) 2602 { 2603 return sal_False; 2604 } 2605 } 2606 2607 sal_Bool SAL_CALL AccessibleEditableTextPara::insertText( const ::rtl::OUString& sText, sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 2608 { 2609 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 2610 2611 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 2612 2613 try 2614 { 2615 // #102710# Request edit view when doing changes 2616 // AccessibleEmptyEditSource relies on this behaviour 2617 GetEditViewForwarder( sal_True ); 2618 SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs 2619 2620 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 2621 "AccessibleEditableTextPara::insertText: index value overflow"); 2622 2623 CheckPosition(nIndex); 2624 2625 // Because bullet may occupy one or more characters, the TextAdapter will include bullet to calculate the selection. Add offset to handle bullet 2626 sal_Int32 nBulletLen = 0; 2627 EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo( static_cast< sal_uInt16 >(GetParagraphIndex()) ); 2628 if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && aBulletInfo.bVisible ) 2629 nBulletLen = aBulletInfo.aText.Len(); 2630 2631 //if( !rCacheTF.IsEditable( MakeSelection(nIndex) ) ) 2632 if( !rCacheTF.IsEditable( MakeSelection(nIndex + nBulletLen) ) ) 2633 return sal_False; // non-editable area selected 2634 2635 // #104400# insert given text at empty selection (=> cursor) 2636 //sal_Bool bRet = rCacheTF.InsertText( sText, MakeCursor(nIndex) ); 2637 sal_Bool bRet = rCacheTF.InsertText( sText, MakeCursor(nIndex + nBulletLen) ); 2638 2639 rCacheTF.QuickFormatDoc(); 2640 GetEditSource().UpdateData(); 2641 2642 return bRet; 2643 } 2644 catch( const uno::RuntimeException& ) 2645 { 2646 return sal_False; 2647 } 2648 } 2649 2650 sal_Bool SAL_CALL AccessibleEditableTextPara::replaceText( sal_Int32 nStartIndex, sal_Int32 nEndIndex, const ::rtl::OUString& sReplacement ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 2651 { 2652 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 2653 2654 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 2655 2656 try 2657 { 2658 // #102710# Request edit view when doing changes 2659 // AccessibleEmptyEditSource relies on this behaviour 2660 GetEditViewForwarder( sal_True ); 2661 SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs 2662 2663 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 2664 "AccessibleEditableTextPara::replaceText: index value overflow"); 2665 2666 CheckRange(nStartIndex, nEndIndex); 2667 2668 // Because bullet may occupy one or more characters, the TextAdapter will include bullet to calculate the selection. Add offset to handle bullet 2669 sal_Int32 nBulletLen = 0; 2670 EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo( static_cast< sal_uInt16 >(GetParagraphIndex()) ); 2671 if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && aBulletInfo.bVisible ) 2672 nBulletLen = aBulletInfo.aText.Len(); 2673 ESelection aSelection = MakeSelection (nStartIndex + nBulletLen, nEndIndex + nBulletLen); 2674 2675 //if( !rCacheTF.IsEditable( MakeSelection(nStartIndex, nEndIndex) ) ) 2676 if( !rCacheTF.IsEditable( aSelection ) ) 2677 return sal_False; // non-editable area selected 2678 2679 // insert given text into given range => replace 2680 //sal_Bool bRet = rCacheTF.InsertText( sReplacement, MakeSelection(nStartIndex, nEndIndex) ); 2681 sal_Bool bRet = rCacheTF.InsertText( sReplacement, aSelection ); 2682 2683 rCacheTF.QuickFormatDoc(); 2684 GetEditSource().UpdateData(); 2685 2686 return bRet; 2687 } 2688 catch( const uno::RuntimeException& ) 2689 { 2690 return sal_False; 2691 } 2692 } 2693 2694 sal_Bool SAL_CALL AccessibleEditableTextPara::setAttributes( sal_Int32 nStartIndex, sal_Int32 nEndIndex, const uno::Sequence< beans::PropertyValue >& aAttributeSet ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 2695 { 2696 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 2697 2698 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 2699 2700 try 2701 { 2702 // #102710# Request edit view when doing changes 2703 // AccessibleEmptyEditSource relies on this behaviour 2704 GetEditViewForwarder( sal_True ); 2705 SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs 2706 sal_uInt16 nPara = static_cast< sal_uInt16 >( GetParagraphIndex() ); 2707 2708 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 2709 "AccessibleEditableTextPara::setAttributes: index value overflow"); 2710 2711 CheckRange(nStartIndex, nEndIndex); 2712 2713 if( !rCacheTF.IsEditable( MakeSelection(nStartIndex, nEndIndex) ) ) 2714 return sal_False; // non-editable area selected 2715 2716 // do the indices span the whole paragraph? Then use the outliner map 2717 // TODO: hold it as a member? 2718 SvxAccessibleTextPropertySet aPropSet( &GetEditSource(), 2719 0 == nStartIndex && 2720 rCacheTF.GetTextLen(nPara) == nEndIndex ? 2721 ImplGetSvxUnoOutlinerTextCursorSvxPropertySet() : 2722 ImplGetSvxTextPortionSvxPropertySet() ); 2723 2724 aPropSet.SetSelection( MakeSelection(nStartIndex, nEndIndex) ); 2725 2726 // convert from PropertyValue to Any 2727 sal_Int32 i, nLength( aAttributeSet.getLength() ); 2728 const beans::PropertyValue* pPropArray = aAttributeSet.getConstArray(); 2729 for(i=0; i<nLength; ++i) 2730 { 2731 try 2732 { 2733 aPropSet.setPropertyValue(pPropArray->Name, pPropArray->Value); 2734 } 2735 catch( const uno::Exception& ) 2736 { 2737 DBG_ERROR("AccessibleEditableTextPara::setAttributes exception in setPropertyValue"); 2738 } 2739 2740 ++pPropArray; 2741 } 2742 2743 rCacheTF.QuickFormatDoc(); 2744 GetEditSource().UpdateData(); 2745 2746 return sal_True; 2747 } 2748 catch( const uno::RuntimeException& ) 2749 { 2750 return sal_False; 2751 } 2752 } 2753 2754 sal_Bool SAL_CALL AccessibleEditableTextPara::setText( const ::rtl::OUString& sText ) throw (uno::RuntimeException) 2755 { 2756 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 2757 2758 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 2759 2760 return replaceText(0, getCharacterCount(), sText); 2761 } 2762 2763 // XAccessibleTextAttributes 2764 uno::Sequence< beans::PropertyValue > SAL_CALL AccessibleEditableTextPara::getDefaultAttributes( 2765 const uno::Sequence< ::rtl::OUString >& rRequestedAttributes ) 2766 throw (uno::RuntimeException) 2767 { 2768 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 2769 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 2770 2771 #if OSL_DEBUG_LEVEL > 0 2772 SvxAccessibleTextAdapter& rCacheTF = 2773 #endif 2774 GetTextForwarder(); 2775 2776 #if OSL_DEBUG_LEVEL > 0 2777 (void)rCacheTF; 2778 #endif 2779 2780 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 2781 "AccessibleEditableTextPara::getCharacterAttributes: index value overflow"); 2782 2783 // get XPropertySetInfo for paragraph attributes and 2784 // character attributes that span all the paragraphs text. 2785 SvxAccessibleTextPropertySet aPropSet( &GetEditSource(), 2786 ImplGetSvxCharAndParaPropertiesSet() ); 2787 aPropSet.SetSelection( MakeSelection( 0, GetTextLen() ) ); 2788 uno::Reference< beans::XPropertySetInfo > xPropSetInfo = aPropSet.getPropertySetInfo(); 2789 if (!xPropSetInfo.is()) 2790 throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Cannot query XPropertySetInfo")), 2791 uno::Reference< uno::XInterface > 2792 ( static_cast< XAccessible* > (this) ) ); // disambiguate hierarchy 2793 2794 // build sequence of available properties to check 2795 sal_Int32 nLenReqAttr = rRequestedAttributes.getLength(); 2796 uno::Sequence< beans::Property > aProperties; 2797 if (nLenReqAttr) 2798 { 2799 const rtl::OUString *pRequestedAttributes = rRequestedAttributes.getConstArray(); 2800 2801 aProperties.realloc( nLenReqAttr ); 2802 beans::Property *pProperties = aProperties.getArray(); 2803 sal_Int32 nCurLen = 0; 2804 for (sal_Int32 i = 0; i < nLenReqAttr; ++i) 2805 { 2806 beans::Property aProp; 2807 try 2808 { 2809 aProp = xPropSetInfo->getPropertyByName( pRequestedAttributes[i] ); 2810 } 2811 catch (beans::UnknownPropertyException &) 2812 { 2813 continue; 2814 } 2815 pProperties[ nCurLen++ ] = aProp; 2816 } 2817 aProperties.realloc( nCurLen ); 2818 } 2819 else 2820 aProperties = xPropSetInfo->getProperties(); 2821 2822 sal_Int32 nLength = aProperties.getLength(); 2823 const beans::Property *pProperties = aProperties.getConstArray(); 2824 2825 // build resulting sequence 2826 uno::Sequence< beans::PropertyValue > aOutSequence( nLength ); 2827 beans::PropertyValue* pOutSequence = aOutSequence.getArray(); 2828 sal_Int32 nOutLen = 0; 2829 for (sal_Int32 i = 0; i < nLength; ++i) 2830 { 2831 // calling implementation functions: 2832 // _getPropertyState and _getPropertyValue (see below) to provide 2833 // the proper paragraph number when retrieving paragraph attributes 2834 PropertyState eState = aPropSet._getPropertyState( pProperties->Name, mnParagraphIndex ); 2835 if ( eState == PropertyState_AMBIGUOUS_VALUE ) 2836 { 2837 OSL_ENSURE( false, "ambiguous property value encountered" ); 2838 } 2839 2840 //if (eState == PropertyState_DIRECT_VALUE) 2841 // per definition all paragraph properties and all character 2842 // properties spanning the whole paragraph should be returned 2843 // and declared as default value 2844 { 2845 pOutSequence->Name = pProperties->Name; 2846 pOutSequence->Handle = pProperties->Handle; 2847 pOutSequence->Value = aPropSet._getPropertyValue( pProperties->Name, mnParagraphIndex ); 2848 pOutSequence->State = PropertyState_DEFAULT_VALUE; 2849 2850 ++pOutSequence; 2851 ++nOutLen; 2852 } 2853 ++pProperties; 2854 } 2855 aOutSequence.realloc( nOutLen ); 2856 2857 return aOutSequence; 2858 } 2859 2860 2861 uno::Sequence< beans::PropertyValue > SAL_CALL AccessibleEditableTextPara::getRunAttributes( 2862 sal_Int32 nIndex, 2863 const uno::Sequence< ::rtl::OUString >& rRequestedAttributes ) 2864 throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 2865 { 2866 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 2867 2868 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 2869 2870 #if OSL_DEBUG_LEVEL > 0 2871 SvxAccessibleTextAdapter& rCacheTF = 2872 #endif 2873 GetTextForwarder(); 2874 2875 #if OSL_DEBUG_LEVEL > 0 2876 (void)rCacheTF; 2877 #endif 2878 2879 DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, 2880 "AccessibleEditableTextPara::getCharacterAttributes: index value overflow"); 2881 2882 if( getCharacterCount() > 0 ) 2883 CheckIndex(nIndex); 2884 else 2885 CheckPosition(nIndex); 2886 2887 SvxAccessibleTextPropertySet aPropSet( &GetEditSource(), 2888 ImplGetSvxCharAndParaPropertiesSet() ); 2889 aPropSet.SetSelection( MakeSelection( nIndex ) ); 2890 uno::Reference< beans::XPropertySetInfo > xPropSetInfo = aPropSet.getPropertySetInfo(); 2891 if (!xPropSetInfo.is()) 2892 throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Cannot query XPropertySetInfo")), 2893 uno::Reference< uno::XInterface > 2894 ( static_cast< XAccessible* > (this) ) ); // disambiguate hierarchy 2895 2896 // build sequence of available properties to check 2897 sal_Int32 nLenReqAttr = rRequestedAttributes.getLength(); 2898 uno::Sequence< beans::Property > aProperties; 2899 if (nLenReqAttr) 2900 { 2901 const rtl::OUString *pRequestedAttributes = rRequestedAttributes.getConstArray(); 2902 2903 aProperties.realloc( nLenReqAttr ); 2904 beans::Property *pProperties = aProperties.getArray(); 2905 sal_Int32 nCurLen = 0; 2906 for (sal_Int32 i = 0; i < nLenReqAttr; ++i) 2907 { 2908 beans::Property aProp; 2909 try 2910 { 2911 aProp = xPropSetInfo->getPropertyByName( pRequestedAttributes[i] ); 2912 } 2913 catch (beans::UnknownPropertyException &) 2914 { 2915 continue; 2916 } 2917 pProperties[ nCurLen++ ] = aProp; 2918 } 2919 aProperties.realloc( nCurLen ); 2920 } 2921 else 2922 aProperties = xPropSetInfo->getProperties(); 2923 2924 sal_Int32 nLength = aProperties.getLength(); 2925 const beans::Property *pProperties = aProperties.getConstArray(); 2926 2927 // build resulting sequence 2928 uno::Sequence< beans::PropertyValue > aOutSequence( nLength ); 2929 beans::PropertyValue* pOutSequence = aOutSequence.getArray(); 2930 sal_Int32 nOutLen = 0; 2931 for (sal_Int32 i = 0; i < nLength; ++i) 2932 { 2933 // calling 'regular' functions that will operate on the selection 2934 PropertyState eState = aPropSet.getPropertyState( pProperties->Name ); 2935 if (eState == PropertyState_DIRECT_VALUE) 2936 { 2937 pOutSequence->Name = pProperties->Name; 2938 pOutSequence->Handle = pProperties->Handle; 2939 pOutSequence->Value = aPropSet.getPropertyValue( pProperties->Name ); 2940 pOutSequence->State = eState; 2941 2942 ++pOutSequence; 2943 ++nOutLen; 2944 } 2945 ++pProperties; 2946 } 2947 aOutSequence.realloc( nOutLen ); 2948 2949 return aOutSequence; 2950 } 2951 2952 // XAccessibleHypertext 2953 ::sal_Int32 SAL_CALL AccessibleEditableTextPara::getHyperLinkCount( ) throw (::com::sun::star::uno::RuntimeException) 2954 { 2955 SvxAccessibleTextAdapter& rT = GetTextForwarder(); 2956 const sal_Int32 nPara = GetParagraphIndex(); 2957 2958 sal_uInt16 nHyperLinks = 0; 2959 sal_uInt16 nFields = rT.GetFieldCount( nPara ); 2960 for ( sal_uInt16 n = 0; n < nFields; n++ ) 2961 { 2962 EFieldInfo aField = rT.GetFieldInfo( nPara, n ); 2963 if ( aField.pFieldItem->GetField()->ISA( SvxURLField ) ) 2964 nHyperLinks++; 2965 } 2966 return nHyperLinks; 2967 } 2968 2969 ::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) 2970 { 2971 ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleHyperlink > xRef; 2972 2973 SvxAccessibleTextAdapter& rT = GetTextForwarder(); 2974 const sal_Int32 nPara = GetParagraphIndex(); 2975 2976 sal_uInt16 nHyperLink = 0; 2977 sal_uInt16 nFields = rT.GetFieldCount( nPara ); 2978 for ( sal_uInt16 n = 0; n < nFields; n++ ) 2979 { 2980 EFieldInfo aField = rT.GetFieldInfo( nPara, n ); 2981 if ( aField.pFieldItem->GetField()->ISA( SvxURLField ) ) 2982 { 2983 if ( nHyperLink == nLinkIndex ) 2984 { 2985 sal_uInt16 nEEStart = aField.aPosition.nIndex; 2986 2987 // Translate EE Index to accessible index 2988 sal_uInt16 nStart = rT.CalcEditEngineIndex( nPara, nEEStart ); 2989 sal_uInt16 nEnd = nStart + aField.aCurrentText.Len(); 2990 xRef = new AccessibleHyperlink( rT, new SvxFieldItem( *aField.pFieldItem ), nPara, nEEStart, nStart, nEnd, aField.aCurrentText ); 2991 break; 2992 } 2993 nHyperLink++; 2994 } 2995 } 2996 2997 return xRef; 2998 } 2999 3000 ::sal_Int32 SAL_CALL AccessibleEditableTextPara::getHyperLinkIndex( ::sal_Int32 nCharIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) 3001 { 3002 const sal_Int32 nPara = GetParagraphIndex(); 3003 SvxAccessibleTextAdapter& rT = GetTextForwarder(); 3004 3005 // SvxAccessibleTextIndex aIndex; 3006 // aIndex.SetIndex(nPara, nCharIndex, rT); 3007 // const sal_uInt16 nEEIndex = aIndex.GetEEIndex(); 3008 3009 const sal_uInt16 nEEIndex = rT.CalcEditEngineIndex( nPara, nCharIndex ); 3010 sal_Int32 nHLIndex = 0; 3011 sal_uInt16 nHyperLink = 0; 3012 sal_uInt16 nFields = rT.GetFieldCount( nPara ); 3013 for ( sal_uInt16 n = 0; n < nFields; n++ ) 3014 { 3015 EFieldInfo aField = rT.GetFieldInfo( nPara, n ); 3016 if ( aField.pFieldItem->GetField()->ISA( SvxURLField ) ) 3017 { 3018 if ( aField.aPosition.nIndex == nEEIndex ) 3019 { 3020 nHLIndex = nHyperLink; 3021 break; 3022 } 3023 nHyperLink++; 3024 } 3025 } 3026 3027 return nHLIndex; 3028 } 3029 3030 // XAccessibleMultiLineText 3031 sal_Int32 SAL_CALL AccessibleEditableTextPara::getLineNumberAtIndex( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 3032 { 3033 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 3034 3035 sal_Int32 nRes = -1; 3036 sal_Int32 nPara = GetParagraphIndex(); 3037 3038 SvxTextForwarder &rCacheTF = GetTextForwarder(); 3039 const bool bValidPara = 0 <= nPara && nPara < rCacheTF.GetParagraphCount(); 3040 DBG_ASSERT( bValidPara, "getLineNumberAtIndex: current paragraph index out of range" ); 3041 if (bValidPara) 3042 { 3043 // we explicitly allow for the index to point at the character right behind the text 3044 if (0 <= nIndex && nIndex <= rCacheTF.GetTextLen( static_cast< sal_uInt16 >(nPara) )) 3045 nRes = rCacheTF.GetLineNumberAtIndex( static_cast< sal_uInt16 >(nPara), static_cast< sal_uInt16 >(nIndex) ); 3046 else 3047 throw lang::IndexOutOfBoundsException(); 3048 } 3049 return nRes; 3050 } 3051 3052 // XAccessibleMultiLineText 3053 ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleEditableTextPara::getTextAtLineNumber( sal_Int32 nLineNo ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 3054 { 3055 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 3056 3057 ::com::sun::star::accessibility::TextSegment aResult; 3058 sal_Int32 nPara = GetParagraphIndex(); 3059 SvxTextForwarder &rCacheTF = GetTextForwarder(); 3060 const bool bValidPara = 0 <= nPara && nPara < rCacheTF.GetParagraphCount(); 3061 DBG_ASSERT( bValidPara, "getTextAtLineNumber: current paragraph index out of range" ); 3062 if (bValidPara) 3063 { 3064 if (0 <= nLineNo && nLineNo < rCacheTF.GetLineCount( static_cast< sal_uInt16 >(nPara) )) 3065 { 3066 sal_uInt16 nStart = 0, nEnd = 0; 3067 rCacheTF.GetLineBoundaries( nStart, nEnd, static_cast< sal_uInt16 >(nPara), static_cast< sal_uInt16 >(nLineNo) ); 3068 if (nStart != 0xFFFF && nEnd != 0xFFFF) 3069 { 3070 try 3071 { 3072 aResult.SegmentText = getTextRange( nStart, nEnd ); 3073 aResult.SegmentStart = nStart; 3074 aResult.SegmentEnd = nEnd; 3075 } 3076 catch (lang::IndexOutOfBoundsException) 3077 { 3078 // this is not the exception that should be raised in this function ... 3079 DBG_ASSERT( 0, "unexpected exception" ); 3080 } 3081 } 3082 } 3083 else 3084 throw lang::IndexOutOfBoundsException(); 3085 } 3086 return aResult; 3087 } 3088 3089 // XAccessibleMultiLineText 3090 ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleEditableTextPara::getTextAtLineWithCaret( ) throw (uno::RuntimeException) 3091 { 3092 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 3093 3094 ::com::sun::star::accessibility::TextSegment aResult; 3095 try 3096 { 3097 aResult = getTextAtLineNumber( getNumberOfLineWithCaret() ); 3098 } 3099 catch (lang::IndexOutOfBoundsException &) 3100 { 3101 // this one needs to be catched since this interface does not allow for it. 3102 } 3103 return aResult; 3104 } 3105 3106 // XAccessibleMultiLineText 3107 sal_Int32 SAL_CALL AccessibleEditableTextPara::getNumberOfLineWithCaret( ) throw (uno::RuntimeException) 3108 { 3109 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 3110 3111 sal_Int32 nRes = -1; 3112 try 3113 { 3114 nRes = getLineNumberAtIndex( getCaretPosition() ); 3115 } 3116 catch (lang::IndexOutOfBoundsException &) 3117 { 3118 // this one needs to be catched since this interface does not allow for it. 3119 } 3120 return nRes; 3121 } 3122 3123 3124 // XServiceInfo 3125 ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getImplementationName (void) throw (uno::RuntimeException) 3126 { 3127 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 3128 3129 return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("AccessibleEditableTextPara")); 3130 } 3131 3132 sal_Bool SAL_CALL AccessibleEditableTextPara::supportsService (const ::rtl::OUString& sServiceName) throw (uno::RuntimeException) 3133 { 3134 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 3135 3136 // Iterate over all supported service names and return true if on of them 3137 // matches the given name. 3138 uno::Sequence< ::rtl::OUString> aSupportedServices ( 3139 getSupportedServiceNames ()); 3140 for (int i=0; i<aSupportedServices.getLength(); i++) 3141 if (sServiceName == aSupportedServices[i]) 3142 return sal_True; 3143 return sal_False; 3144 } 3145 3146 uno::Sequence< ::rtl::OUString> SAL_CALL AccessibleEditableTextPara::getSupportedServiceNames (void) throw (uno::RuntimeException) 3147 { 3148 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 3149 3150 const ::rtl::OUString sServiceName( getServiceName() ); 3151 return uno::Sequence< ::rtl::OUString > (&sServiceName, 1); 3152 } 3153 3154 // XServiceName 3155 ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getServiceName (void) throw (uno::RuntimeException) 3156 { 3157 DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); 3158 3159 // #105185# Using correct service now 3160 return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.AccessibleParagraphView")); 3161 } 3162 3163 } // end of namespace accessibility 3164 3165 //------------------------------------------------------------------------ 3166