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_starmath.hxx" 26 #include <com/sun/star/accessibility/AccessibleRole.hpp> 27 #include <com/sun/star/accessibility/AccessibleStateType.hpp> 28 #include <com/sun/star/accessibility/AccessibleTextType.hpp> 29 #include <com/sun/star/accessibility/XAccessibleEventListener.hpp> 30 #include <com/sun/star/accessibility/AccessibleEventObject.hpp> 31 #include <com/sun/star/awt/FocusEvent.hpp> 32 #include <com/sun/star/awt/XFocusListener.hpp> 33 #include <unotools/accessiblerelationsethelper.hxx> 34 35 36 #include <com/sun/star/datatransfer/clipboard/XClipboard.hpp> 37 #include <com/sun/star/datatransfer/clipboard/XFlushableClipboard.hpp> 38 #include <com/sun/star/i18n/WordType.hpp> 39 #include <unotools/accessiblestatesethelper.hxx> 40 #include <comphelper/accessibleeventnotifier.hxx> 41 #include <tools/debug.hxx> 42 #include <vcl/svapp.hxx> 43 #include <vcl/window.hxx> 44 #include <vcl/unohelp2.hxx> 45 #include <tools/gen.hxx> 46 #include <vos/mutex.hxx> 47 #include <svl/itemset.hxx> 48 49 #include <editeng/editobj.hxx> 50 #include <editeng/editdata.hxx> 51 #include <editeng/editview.hxx> 52 #include <editeng/eeitem.hxx> 53 #include <editeng/outliner.hxx> 54 #include <editeng/unoedhlp.hxx> 55 56 57 #include "accessibility.hxx" 58 #include <applicat.hxx> 59 #include <document.hxx> 60 #include <view.hxx> 61 62 using namespace rtl; 63 using namespace com::sun::star; 64 using namespace com::sun::star::lang; 65 using namespace com::sun::star::uno; 66 using namespace com::sun::star::accessibility; 67 68 #define A2OU(cChar) rtl::OUString::createFromAscii(cChar) 69 70 ////////////////////////////////////////////////////////////////////// 71 72 static awt::Rectangle lcl_GetBounds( Window *pWin ) 73 { 74 // !! see VCLXAccessibleComponent::implGetBounds() 75 76 //! the coordinates returned are relativ to the parent window ! 77 //! Thus the top-left point may be different from (0, 0) ! 78 79 awt::Rectangle aBounds; 80 if (pWin) 81 { 82 Rectangle aRect = pWin->GetWindowExtentsRelative( NULL ); 83 aBounds.X = aRect.Left(); 84 aBounds.Y = aRect.Top(); 85 aBounds.Width = aRect.GetWidth(); 86 aBounds.Height = aRect.GetHeight(); 87 Window* pParent = pWin->GetAccessibleParentWindow(); 88 if (pParent) 89 { 90 Rectangle aParentRect = pParent->GetWindowExtentsRelative( NULL ); 91 awt::Point aParentScreenLoc( aParentRect.Left(), aParentRect.Top() ); 92 aBounds.X -= aParentScreenLoc.X; 93 aBounds.Y -= aParentScreenLoc.Y; 94 } 95 } 96 return aBounds; 97 } 98 99 static awt::Point lcl_GetLocationOnScreen( Window *pWin ) 100 { 101 // !! see VCLXAccessibleComponent::getLocationOnScreen() 102 103 awt::Point aPos; 104 if (pWin) 105 { 106 Rectangle aRect = pWin->GetWindowExtentsRelative( NULL ); 107 aPos.X = aRect.Left(); 108 aPos.Y = aRect.Top(); 109 } 110 return aPos; 111 } 112 113 ////////////////////////////////////////////////////////////////////// 114 115 SmGraphicAccessible::SmGraphicAccessible( SmGraphicWindow *pGraphicWin ) : 116 aAccName ( String(SmResId(RID_DOCUMENTSTR)) ), 117 nClientId (0), 118 pWin (pGraphicWin) 119 { 120 DBG_ASSERT( pWin, "SmGraphicAccessible: window missing" ); 121 //++aRefCount; 122 } 123 124 125 SmGraphicAccessible::SmGraphicAccessible( const SmGraphicAccessible &rSmAcc ) : 126 SmGraphicAccessibleBaseClass(), 127 aAccName ( String(SmResId(RID_DOCUMENTSTR)) ), 128 nClientId (0) 129 { 130 //vos::OGuard aGuard(Application::GetSolarMutex()); 131 pWin = rSmAcc.pWin; 132 DBG_ASSERT( pWin, "SmGraphicAccessible: window missing" ); 133 //++aRefCount; 134 } 135 136 137 SmGraphicAccessible::~SmGraphicAccessible() 138 { 139 /* 140 vos::OGuard aGuard(Application::GetSolarMutex()); 141 if (--aRefCount == 0) 142 { 143 } 144 */ 145 } 146 147 148 SmDocShell * SmGraphicAccessible::GetDoc_Impl() 149 { 150 SmViewShell *pView = pWin ? pWin->GetView() : 0; 151 return pView ? pView->GetDoc() : 0; 152 } 153 154 String SmGraphicAccessible::GetAccessibleText_Impl() 155 { 156 String aTxt; 157 SmDocShell *pDoc = GetDoc_Impl(); 158 if (pDoc) 159 aTxt = pDoc->GetAccessibleText(); 160 return aTxt; 161 } 162 163 void SmGraphicAccessible::ClearWin() 164 { 165 pWin = 0; // implicitly results in AccessibleStateType::DEFUNC set 166 167 if ( nClientId ) 168 { 169 comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( nClientId, *this ); 170 nClientId = 0; 171 } 172 } 173 174 void SmGraphicAccessible::LaunchEvent( 175 const sal_Int16 nAccesibleEventId, 176 const uno::Any &rOldVal, 177 const uno::Any &rNewVal) 178 { 179 AccessibleEventObject aEvt; 180 aEvt.Source = (XAccessible *) this; 181 aEvt.EventId = nAccesibleEventId; 182 aEvt.OldValue = rOldVal; 183 aEvt.NewValue = rNewVal ; 184 185 // pass event on to event-listener's 186 if (nClientId) 187 comphelper::AccessibleEventNotifier::addEvent( nClientId, aEvt ); 188 } 189 190 uno::Reference< XAccessibleContext > SAL_CALL SmGraphicAccessible::getAccessibleContext() 191 throw (RuntimeException) 192 { 193 vos::OGuard aGuard(Application::GetSolarMutex()); 194 return this; 195 } 196 197 sal_Bool SAL_CALL SmGraphicAccessible::containsPoint( const awt::Point& aPoint ) 198 throw (RuntimeException) 199 { 200 //! the arguments coordinates are relativ to the current window ! 201 //! Thus the top-left point is (0, 0) 202 203 vos::OGuard aGuard(Application::GetSolarMutex()); 204 if (!pWin) 205 throw RuntimeException(); 206 207 Size aSz( pWin->GetSizePixel() ); 208 return aPoint.X >= 0 && aPoint.Y >= 0 && 209 aPoint.X < aSz.Width() && aPoint.Y < aSz.Height(); 210 } 211 212 uno::Reference< XAccessible > SAL_CALL SmGraphicAccessible::getAccessibleAtPoint( 213 const awt::Point& aPoint ) 214 throw (RuntimeException) 215 { 216 vos::OGuard aGuard(Application::GetSolarMutex()); 217 XAccessible *pRes = 0; 218 if (containsPoint( aPoint )) 219 pRes = this; 220 return pRes; 221 } 222 223 awt::Rectangle SAL_CALL SmGraphicAccessible::getBounds() 224 throw (RuntimeException) 225 { 226 vos::OGuard aGuard(Application::GetSolarMutex()); 227 if (!pWin) 228 throw RuntimeException(); 229 DBG_ASSERT(pWin->GetParent()->GetAccessible() == getAccessibleParent(), 230 "mismatch of window parent and accessible parent" ); 231 return lcl_GetBounds( pWin ); 232 } 233 234 awt::Point SAL_CALL SmGraphicAccessible::getLocation() 235 throw (RuntimeException) 236 { 237 vos::OGuard aGuard(Application::GetSolarMutex()); 238 if (!pWin) 239 throw RuntimeException(); 240 DBG_ASSERT(pWin->GetParent()->GetAccessible() == getAccessibleParent(), 241 "mismatch of window parent and accessible parent" ); 242 awt::Rectangle aRect( lcl_GetBounds( pWin ) ); 243 return awt::Point( aRect.X, aRect.Y ); 244 } 245 246 awt::Point SAL_CALL SmGraphicAccessible::getLocationOnScreen() 247 throw (RuntimeException) 248 { 249 vos::OGuard aGuard(Application::GetSolarMutex()); 250 if (!pWin) 251 throw RuntimeException(); 252 DBG_ASSERT(pWin->GetParent()->GetAccessible() == getAccessibleParent(), 253 "mismatch of window parent and accessible parent" ); 254 return lcl_GetLocationOnScreen( pWin ); 255 } 256 257 awt::Size SAL_CALL SmGraphicAccessible::getSize() 258 throw (RuntimeException) 259 { 260 vos::OGuard aGuard(Application::GetSolarMutex()); 261 if (!pWin) 262 throw RuntimeException(); 263 DBG_ASSERT(pWin->GetParent()->GetAccessible() == getAccessibleParent(), 264 "mismatch of window parent and accessible parent" ); 265 266 Size aSz( pWin->GetSizePixel() ); 267 #if OSL_DEBUG_LEVEL > 1 268 awt::Rectangle aRect( lcl_GetBounds( pWin ) ); 269 Size aSz2( aRect.Width, aRect.Height ); 270 DBG_ASSERT( aSz == aSz2, "mismatch in width" ); 271 #endif 272 return awt::Size( aSz.Width(), aSz.Height() ); 273 } 274 275 void SAL_CALL SmGraphicAccessible::grabFocus() 276 throw (RuntimeException) 277 { 278 vos::OGuard aGuard(Application::GetSolarMutex()); 279 if (!pWin) 280 throw RuntimeException(); 281 282 pWin->GrabFocus(); 283 } 284 285 sal_Int32 SAL_CALL SmGraphicAccessible::getForeground() 286 throw (RuntimeException) 287 { 288 vos::OGuard aGuard(Application::GetSolarMutex()); 289 290 if (!pWin) 291 throw RuntimeException(); 292 return (sal_Int32) pWin->GetTextColor().GetColor(); 293 } 294 295 sal_Int32 SAL_CALL SmGraphicAccessible::getBackground() 296 throw (RuntimeException) 297 { 298 vos::OGuard aGuard(Application::GetSolarMutex()); 299 300 if (!pWin) 301 throw RuntimeException(); 302 Wallpaper aWall( pWin->GetDisplayBackground() ); 303 ColorData nCol; 304 if (aWall.IsBitmap() || aWall.IsGradient()) 305 nCol = pWin->GetSettings().GetStyleSettings().GetWindowColor().GetColor(); 306 else 307 nCol = aWall.GetColor().GetColor(); 308 return (sal_Int32) nCol; 309 } 310 311 sal_Int32 SAL_CALL SmGraphicAccessible::getAccessibleChildCount() 312 throw (RuntimeException) 313 { 314 vos::OGuard aGuard(Application::GetSolarMutex()); 315 return 0; 316 } 317 318 Reference< XAccessible > SAL_CALL SmGraphicAccessible::getAccessibleChild( 319 sal_Int32 /*i*/ ) 320 throw (IndexOutOfBoundsException, RuntimeException) 321 { 322 vos::OGuard aGuard(Application::GetSolarMutex()); 323 throw IndexOutOfBoundsException(); // there is no child... 324 /*return 0;*/ 325 } 326 327 Reference< XAccessible > SAL_CALL SmGraphicAccessible::getAccessibleParent() 328 throw (RuntimeException) 329 { 330 vos::OGuard aGuard(Application::GetSolarMutex()); 331 if (!pWin) 332 throw RuntimeException(); 333 334 Window *pAccParent = pWin->GetAccessibleParentWindow(); 335 DBG_ASSERT( pAccParent, "accessible parent missing" ); 336 return pAccParent ? pAccParent->GetAccessible() : Reference< XAccessible >(); 337 } 338 339 sal_Int32 SAL_CALL SmGraphicAccessible::getAccessibleIndexInParent() 340 throw (RuntimeException) 341 { 342 vos::OGuard aGuard(Application::GetSolarMutex()); 343 sal_Int32 nIdx = -1; 344 Window *pAccParent = pWin ? pWin->GetAccessibleParentWindow() : 0; 345 if (pAccParent) 346 { 347 sal_uInt16 nCnt = pAccParent->GetAccessibleChildWindowCount(); 348 for (sal_uInt16 i = 0; i < nCnt && nIdx == -1; ++i) 349 if (pAccParent->GetAccessibleChildWindow( i ) == pWin) 350 nIdx = i; 351 } 352 return nIdx; 353 } 354 355 sal_Int16 SAL_CALL SmGraphicAccessible::getAccessibleRole() 356 throw (RuntimeException) 357 { 358 vos::OGuard aGuard(Application::GetSolarMutex()); 359 return AccessibleRole::DOCUMENT; 360 } 361 362 OUString SAL_CALL SmGraphicAccessible::getAccessibleDescription() 363 throw (RuntimeException) 364 { 365 vos::OGuard aGuard(Application::GetSolarMutex()); 366 SmDocShell *pDoc = GetDoc_Impl(); 367 return pDoc ? OUString(pDoc->GetText()) : OUString(); 368 } 369 370 OUString SAL_CALL SmGraphicAccessible::getAccessibleName() 371 throw (RuntimeException) 372 { 373 vos::OGuard aGuard(Application::GetSolarMutex()); 374 return aAccName; 375 } 376 377 Reference< XAccessibleRelationSet > SAL_CALL SmGraphicAccessible::getAccessibleRelationSet() 378 throw (RuntimeException) 379 { 380 vos::OGuard aGuard(Application::GetSolarMutex()); 381 Reference< XAccessibleRelationSet > xRelSet = new utl::AccessibleRelationSetHelper(); 382 return xRelSet; // empty relation set 383 } 384 385 Reference< XAccessibleStateSet > SAL_CALL SmGraphicAccessible::getAccessibleStateSet() 386 throw (RuntimeException) 387 { 388 vos::OGuard aGuard(Application::GetSolarMutex()); 389 ::utl::AccessibleStateSetHelper *pStateSet = 390 new ::utl::AccessibleStateSetHelper; 391 392 Reference<XAccessibleStateSet> xStateSet( pStateSet ); 393 394 if (!pWin) 395 pStateSet->AddState( AccessibleStateType::DEFUNC ); 396 else 397 { 398 //pStateSet->AddState( AccessibleStateType::EDITABLE ); 399 //pStateSet->AddState( AccessibleStateType::HORIZONTAL ); 400 //pStateSet->AddState( AccessibleStateType::TRANSIENT ); 401 pStateSet->AddState( AccessibleStateType::ENABLED ); 402 pStateSet->AddState( AccessibleStateType::FOCUSABLE ); 403 if (pWin->HasFocus()) 404 pStateSet->AddState( AccessibleStateType::FOCUSED ); 405 if (pWin->IsActive()) 406 pStateSet->AddState( AccessibleStateType::ACTIVE ); 407 if (pWin->IsVisible()) 408 pStateSet->AddState( AccessibleStateType::SHOWING ); 409 if (pWin->IsReallyVisible()) 410 pStateSet->AddState( AccessibleStateType::VISIBLE ); 411 if (COL_TRANSPARENT != pWin->GetBackground().GetColor().GetColor()) 412 pStateSet->AddState( AccessibleStateType::OPAQUE ); 413 } 414 415 return xStateSet; 416 } 417 418 Locale SAL_CALL SmGraphicAccessible::getLocale() 419 throw (IllegalAccessibleComponentStateException, RuntimeException) 420 { 421 vos::OGuard aGuard(Application::GetSolarMutex()); 422 // should be the document language... 423 // We use the language of the localized symbol names here. 424 return Application::GetSettings().GetUILocale(); 425 } 426 427 428 void SAL_CALL SmGraphicAccessible::addEventListener( 429 const Reference< XAccessibleEventListener >& xListener ) 430 throw (RuntimeException) 431 { 432 if (xListener.is()) 433 { 434 vos::OGuard aGuard(Application::GetSolarMutex()); 435 if (pWin) 436 { 437 if (!nClientId) 438 nClientId = comphelper::AccessibleEventNotifier::registerClient( ); 439 comphelper::AccessibleEventNotifier::addEventListener( nClientId, xListener ); 440 } 441 } 442 } 443 444 void SAL_CALL SmGraphicAccessible::removeEventListener( 445 const Reference< XAccessibleEventListener >& xListener ) 446 throw (RuntimeException) 447 { 448 if (xListener.is()) 449 { 450 vos::OGuard aGuard(Application::GetSolarMutex()); 451 sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( nClientId, xListener ); 452 if ( !nListenerCount ) 453 { 454 // no listeners anymore 455 // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client), 456 // and at least to us not firing any events anymore, in case somebody calls 457 // NotifyAccessibleEvent, again 458 comphelper::AccessibleEventNotifier::revokeClient( nClientId ); 459 nClientId = 0; 460 } 461 } 462 } 463 464 sal_Int32 SAL_CALL SmGraphicAccessible::getCaretPosition() 465 throw (RuntimeException) 466 { 467 vos::OGuard aGuard(Application::GetSolarMutex()); 468 return 0; 469 } 470 471 sal_Bool SAL_CALL SmGraphicAccessible::setCaretPosition( sal_Int32 nIndex ) 472 throw (IndexOutOfBoundsException, RuntimeException) 473 { 474 xub_StrLen nIdx = (xub_StrLen) nIndex; 475 String aTxt( GetAccessibleText_Impl() ); 476 if (!(/*0 <= nIdx &&*/ nIdx < aTxt.Len())) 477 throw IndexOutOfBoundsException(); 478 return sal_False; 479 } 480 481 sal_Unicode SAL_CALL SmGraphicAccessible::getCharacter( sal_Int32 nIndex ) 482 throw (IndexOutOfBoundsException, RuntimeException) 483 { 484 vos::OGuard aGuard(Application::GetSolarMutex()); 485 486 xub_StrLen nIdx = (xub_StrLen) nIndex; 487 String aTxt( GetAccessibleText_Impl() ); 488 if (!(/*0 <= nIdx &&*/ nIdx < aTxt.Len())) 489 throw IndexOutOfBoundsException(); 490 return aTxt.GetChar( nIdx ); 491 } 492 493 Sequence< beans::PropertyValue > SAL_CALL SmGraphicAccessible::getCharacterAttributes( 494 sal_Int32 nIndex, 495 const uno::Sequence< ::rtl::OUString > & /*rRequestedAttributes*/ ) 496 throw (IndexOutOfBoundsException, RuntimeException) 497 { 498 vos::OGuard aGuard(Application::GetSolarMutex()); 499 sal_Int32 nLen = GetAccessibleText_Impl().Len(); 500 if (!(0 <= nIndex && nIndex < nLen)) 501 throw IndexOutOfBoundsException(); 502 return Sequence< beans::PropertyValue >(); 503 } 504 505 awt::Rectangle SAL_CALL SmGraphicAccessible::getCharacterBounds( sal_Int32 nIndex ) 506 throw (IndexOutOfBoundsException, RuntimeException) 507 { 508 vos::OGuard aGuard(Application::GetSolarMutex()); 509 510 awt::Rectangle aRes; 511 512 if (!pWin) 513 throw RuntimeException(); 514 else 515 { 516 // get accessible text 517 SmViewShell *pView = pWin->GetView(); 518 SmDocShell *pDoc = pView ? pView->GetDoc() : 0; 519 if (!pDoc) 520 throw RuntimeException(); 521 String aTxt( GetAccessibleText_Impl() ); 522 if (!(0 <= nIndex && nIndex <= aTxt.Len())) // #108812# aTxt.Len() is valid 523 throw IndexOutOfBoundsException(); 524 525 // #108812# find a reasonable rectangle for position aTxt.Len(). 526 bool bWasBehindText = (nIndex == aTxt.Len()); 527 if (bWasBehindText && nIndex) 528 --nIndex; 529 530 const SmNode *pTree = pDoc->GetFormulaTree(); 531 const SmNode *pNode = pTree->FindNodeWithAccessibleIndex( (xub_StrLen) nIndex ); 532 //! pNode may be 0 if the index belongs to a char that was inserted 533 //! only for the accessible text! 534 if (pNode) 535 { 536 sal_Int32 nAccIndex = pNode->GetAccessibleIndex(); 537 DBG_ASSERT( nAccIndex >= 0, "invalid accessible index" ); 538 DBG_ASSERT( nIndex >= nAccIndex, "index out of range" ); 539 540 String aNodeText; 541 pNode->GetAccessibleText( aNodeText ); 542 sal_Int32 nNodeIndex = nIndex - nAccIndex; 543 if (0 <= nNodeIndex && nNodeIndex < aNodeText.Len()) 544 { 545 // get appropriate rectangle 546 Point aOffset(pNode->GetTopLeft() - pTree->GetTopLeft()); 547 Point aTLPos (pWin->GetFormulaDrawPos() + aOffset); 548 // aTLPos.X() -= pNode->GetItalicLeftSpace(); 549 // Size aSize (pNode->GetItalicSize()); 550 aTLPos.X() -= 0; 551 Size aSize (pNode->GetSize()); 552 553 sal_Int32 *pXAry = new sal_Int32[ aNodeText.Len() ]; 554 pWin->SetFont( pNode->GetFont() ); 555 pWin->GetTextArray( aNodeText, pXAry, 0, aNodeText.Len() ); 556 aTLPos.X() += nNodeIndex > 0 ? pXAry[nNodeIndex - 1] : 0; 557 aSize.Width() = nNodeIndex > 0 ? pXAry[nNodeIndex] - pXAry[nNodeIndex - 1] : pXAry[nNodeIndex]; 558 delete[] pXAry; 559 560 #if OSL_DEBUG_LEVEL > 1 561 Point aLP00( pWin->LogicToPixel( Point(0,0)) ); 562 Point aPL00( pWin->PixelToLogic( Point(0,0)) ); 563 #endif 564 aTLPos = pWin->LogicToPixel( aTLPos ); 565 aSize = pWin->LogicToPixel( aSize ); 566 aRes.X = aTLPos.X(); 567 aRes.Y = aTLPos.Y(); 568 aRes.Width = aSize.Width(); 569 aRes.Height = aSize.Height(); 570 } 571 } 572 573 // #108812# take rectangle from last character and move it to the right 574 if (bWasBehindText) 575 aRes.X += aRes.Width; 576 } 577 578 return aRes; 579 } 580 581 sal_Int32 SAL_CALL SmGraphicAccessible::getCharacterCount() 582 throw (RuntimeException) 583 { 584 vos::OGuard aGuard(Application::GetSolarMutex()); 585 return GetAccessibleText_Impl().Len(); 586 } 587 588 sal_Int32 SAL_CALL SmGraphicAccessible::getIndexAtPoint( const awt::Point& aPoint ) 589 throw (RuntimeException) 590 { 591 vos::OGuard aGuard(Application::GetSolarMutex()); 592 593 sal_Int32 nRes = -1; 594 if (pWin) 595 { 596 const SmNode *pTree = pWin->GetView()->GetDoc()->GetFormulaTree(); 597 //! kann NULL sein! ZB wenn bereits beim laden des Dokuments (bevor der 598 //! Parser angeworfen wurde) ins Fenster geklickt wird. 599 if (!pTree) 600 return nRes; 601 602 // get position relativ to formula draw position 603 Point aPos( aPoint.X, aPoint.Y ); 604 aPos = pWin->PixelToLogic( aPos ); 605 aPos -= pWin->GetFormulaDrawPos(); 606 607 // if it was inside the formula then get the appropriate node 608 const SmNode *pNode = 0; 609 if (pTree->OrientedDist(aPos) <= 0) 610 pNode = pTree->FindRectClosestTo(aPos); 611 612 if (pNode) 613 { 614 // get appropriate rectangle 615 Point aOffset( pNode->GetTopLeft() - pTree->GetTopLeft() ); 616 Point aTLPos ( /*pWin->GetFormulaDrawPos() +*/ aOffset ); 617 // aTLPos.X() -= pNode->GetItalicLeftSpace(); 618 // Size aSize( pNode->GetItalicSize() ); 619 aTLPos.X() -= 0; 620 Size aSize( pNode->GetSize() ); 621 #if OSL_DEBUG_LEVEL > 1 622 Point aLP00( pWin->LogicToPixel( Point(0,0)) ); 623 Point aPL00( pWin->PixelToLogic( Point(0,0)) ); 624 #endif 625 626 Rectangle aRect( aTLPos, aSize ); 627 if (aRect.IsInside( aPos )) 628 { 629 DBG_ASSERT( pNode->IsVisible(), "node is not a leaf" ); 630 String aTxt; 631 pNode->GetAccessibleText( aTxt ); 632 DBG_ASSERT( aTxt.Len(), "no accessible text available" ); 633 634 long nNodeX = pNode->GetLeft(); 635 636 sal_Int32 *pXAry = new sal_Int32[ aTxt.Len() ]; 637 pWin->SetFont( pNode->GetFont() ); 638 pWin->GetTextArray( aTxt, pXAry, 0, aTxt.Len() ); 639 for (sal_Int32 i = 0; i < aTxt.Len() && nRes == -1; ++i) 640 { 641 if (pXAry[i] + nNodeX > aPos.X()) 642 nRes = i; 643 } 644 delete[] pXAry; 645 DBG_ASSERT( nRes >= 0 && nRes < aTxt.Len(), "index out of range" ); 646 DBG_ASSERT( pNode->GetAccessibleIndex() >= 0, 647 "invalid accessible index" ); 648 649 nRes = pNode->GetAccessibleIndex() + nRes; 650 } 651 } 652 } 653 return nRes; 654 } 655 656 OUString SAL_CALL SmGraphicAccessible::getSelectedText() 657 throw (RuntimeException) 658 { 659 vos::OGuard aGuard(Application::GetSolarMutex()); 660 return OUString(); 661 } 662 663 sal_Int32 SAL_CALL SmGraphicAccessible::getSelectionStart() 664 throw (RuntimeException) 665 { 666 vos::OGuard aGuard(Application::GetSolarMutex()); 667 return -1; 668 } 669 670 sal_Int32 SAL_CALL SmGraphicAccessible::getSelectionEnd() 671 throw (RuntimeException) 672 { 673 vos::OGuard aGuard(Application::GetSolarMutex()); 674 return -1; 675 } 676 677 sal_Bool SAL_CALL SmGraphicAccessible::setSelection( 678 sal_Int32 nStartIndex, 679 sal_Int32 nEndIndex ) 680 throw (IndexOutOfBoundsException, RuntimeException) 681 { 682 vos::OGuard aGuard(Application::GetSolarMutex()); 683 sal_Int32 nLen = GetAccessibleText_Impl().Len(); 684 if (!(0 <= nStartIndex && nStartIndex < nLen) || 685 !(0 <= nEndIndex && nEndIndex < nLen)) 686 throw IndexOutOfBoundsException(); 687 return sal_False; 688 } 689 690 OUString SAL_CALL SmGraphicAccessible::getText() 691 throw (RuntimeException) 692 { 693 vos::OGuard aGuard(Application::GetSolarMutex()); 694 return GetAccessibleText_Impl(); 695 } 696 697 OUString SAL_CALL SmGraphicAccessible::getTextRange( 698 sal_Int32 nStartIndex, 699 sal_Int32 nEndIndex ) 700 throw (IndexOutOfBoundsException, RuntimeException) 701 { 702 //!! nEndIndex may be the string length per definition of the interface !! 703 //!! text should be copied exclusive that end index though. And arguments 704 //!! may be switched. 705 706 vos::OGuard aGuard(Application::GetSolarMutex()); 707 String aTxt( GetAccessibleText_Impl() ); 708 xub_StrLen nStart = (xub_StrLen) Min(nStartIndex, nEndIndex); 709 xub_StrLen nEnd = (xub_StrLen) Max(nStartIndex, nEndIndex); 710 if (!(/*0 <= nStart &&*/ nStart <= aTxt.Len()) || 711 !(/*0 <= nEnd &&*/ nEnd <= aTxt.Len())) 712 throw IndexOutOfBoundsException(); 713 return aTxt.Copy( nStart, nEnd - nStart ); 714 } 715 716 ::com::sun::star::accessibility::TextSegment SAL_CALL SmGraphicAccessible::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) 717 { 718 vos::OGuard aGuard(Application::GetSolarMutex()); 719 String aTxt( GetAccessibleText_Impl() ); 720 xub_StrLen nIdx = (xub_StrLen) nIndex; 721 //!! nIndex is allowed to be the string length 722 if (!(/*0 <= nIdx &&*/ nIdx <= aTxt.Len())) 723 throw IndexOutOfBoundsException(); 724 725 ::com::sun::star::accessibility::TextSegment aResult; 726 aResult.SegmentStart = -1; 727 aResult.SegmentEnd = -1; 728 if ( (AccessibleTextType::CHARACTER == aTextType) && (nIdx < aTxt.Len()) ) 729 { 730 aResult.SegmentText = aTxt.Copy(nIdx, 1); 731 aResult.SegmentStart = nIdx; 732 aResult.SegmentEnd = nIdx+1; 733 } 734 return aResult; 735 } 736 737 ::com::sun::star::accessibility::TextSegment SAL_CALL SmGraphicAccessible::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) 738 { 739 vos::OGuard aGuard(Application::GetSolarMutex()); 740 String aTxt( GetAccessibleText_Impl() ); 741 xub_StrLen nIdx = (xub_StrLen) nIndex; 742 //!! nIndex is allowed to be the string length 743 if (!(/*0 <= nIdx &&*/ nIdx <= aTxt.Len())) 744 throw IndexOutOfBoundsException(); 745 746 ::com::sun::star::accessibility::TextSegment aResult; 747 aResult.SegmentStart = -1; 748 aResult.SegmentEnd = -1; 749 750 if ( (AccessibleTextType::CHARACTER == aTextType) && nIdx ) 751 { 752 aResult.SegmentText = aTxt.Copy(nIdx-1, 1); 753 aResult.SegmentStart = nIdx-1; 754 aResult.SegmentEnd = nIdx; 755 } 756 return aResult; 757 } 758 759 ::com::sun::star::accessibility::TextSegment SAL_CALL SmGraphicAccessible::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) 760 { 761 vos::OGuard aGuard(Application::GetSolarMutex()); 762 String aTxt( GetAccessibleText_Impl() ); 763 xub_StrLen nIdx = (xub_StrLen) nIndex; 764 //!! nIndex is allowed to be the string length 765 if (!(/*0 <= nIdx &&*/ nIdx <= aTxt.Len())) 766 throw IndexOutOfBoundsException(); 767 768 ::com::sun::star::accessibility::TextSegment aResult; 769 aResult.SegmentStart = -1; 770 aResult.SegmentEnd = -1; 771 772 nIdx++; // text *behind* 773 if ( (AccessibleTextType::CHARACTER == aTextType) && (nIdx < aTxt.Len()) ) 774 { 775 aResult.SegmentText = aTxt.Copy(nIdx, 1); 776 aResult.SegmentStart = nIdx; 777 aResult.SegmentEnd = nIdx+1; 778 } 779 return aResult; 780 } 781 782 sal_Bool SAL_CALL SmGraphicAccessible::copyText( 783 sal_Int32 nStartIndex, 784 sal_Int32 nEndIndex ) 785 throw (IndexOutOfBoundsException, RuntimeException) 786 { 787 vos::OGuard aGuard(Application::GetSolarMutex()); 788 sal_Bool bReturn = sal_False; 789 790 if (!pWin) 791 throw RuntimeException(); 792 else 793 { 794 Reference< datatransfer::clipboard::XClipboard > xClipboard = pWin->GetClipboard(); 795 if ( xClipboard.is() ) 796 { 797 ::rtl::OUString sText( getTextRange(nStartIndex, nEndIndex) ); 798 799 ::vcl::unohelper::TextDataObject* pDataObj = new ::vcl::unohelper::TextDataObject( sText ); 800 const sal_uInt32 nRef = Application::ReleaseSolarMutex(); 801 xClipboard->setContents( pDataObj, NULL ); 802 803 Reference< datatransfer::clipboard::XFlushableClipboard > xFlushableClipboard( xClipboard, uno::UNO_QUERY ); 804 if( xFlushableClipboard.is() ) 805 xFlushableClipboard->flushClipboard(); 806 807 Application::AcquireSolarMutex( nRef ); 808 809 bReturn = sal_True; 810 } 811 } 812 813 return bReturn; 814 } 815 816 OUString SAL_CALL SmGraphicAccessible::getImplementationName() 817 throw (RuntimeException) 818 { 819 //vos::OGuard aGuard(Application::GetSolarMutex()); 820 return A2OU("SmGraphicAccessible"); 821 } 822 823 sal_Bool SAL_CALL SmGraphicAccessible::supportsService( 824 const OUString& rServiceName ) 825 throw (RuntimeException) 826 { 827 //vos::OGuard aGuard(Application::GetSolarMutex()); 828 return rServiceName == A2OU( "com::sun::star::accessibility::Accessible" ) || 829 rServiceName == A2OU( "com::sun::star::accessibility::AccessibleComponent" ) || 830 rServiceName == A2OU( "com::sun::star::accessibility::AccessibleContext" ) || 831 rServiceName == A2OU( "com::sun::star::accessibility::AccessibleText" ); 832 } 833 834 Sequence< OUString > SAL_CALL SmGraphicAccessible::getSupportedServiceNames() 835 throw (RuntimeException) 836 { 837 //vos::OGuard aGuard(Application::GetSolarMutex()); 838 Sequence< OUString > aNames(4); 839 OUString *pNames = aNames.getArray(); 840 pNames[0] = A2OU( "com::sun::star::accessibility::Accessible" ); 841 pNames[1] = A2OU( "com::sun::star::accessibility::AccessibleComponent" ); 842 pNames[2] = A2OU( "com::sun::star::accessibility::AccessibleContext" ); 843 pNames[3] = A2OU( "com::sun::star::accessibility::AccessibleText" ); 844 return aNames; 845 } 846 847 ////////////////////////////////////////////////////////////////////// 848 849 //------------------------------------------------------------------------ 850 851 SmEditSource::SmEditSource( SmEditWindow * /*pWin*/, SmEditAccessible &rAcc ) : 852 aViewFwd (rAcc), 853 aTextFwd (rAcc, *this), 854 aEditViewFwd(rAcc), 855 rEditAcc (rAcc) 856 { 857 } 858 859 SmEditSource::SmEditSource( const SmEditSource &rSrc ) : 860 SvxEditSource(), 861 aViewFwd (rSrc.rEditAcc), 862 aTextFwd (rSrc.rEditAcc, *this), 863 aEditViewFwd(rSrc.rEditAcc), 864 rEditAcc (rSrc.rEditAcc) 865 { 866 //aBroadCaster; can be completely new 867 } 868 869 SmEditSource::~SmEditSource() 870 { 871 } 872 873 SvxEditSource* SmEditSource::Clone() const 874 { 875 return new SmEditSource( *this ); 876 } 877 878 SvxTextForwarder* SmEditSource::GetTextForwarder() 879 { 880 return &aTextFwd; 881 } 882 883 SvxViewForwarder* SmEditSource::GetViewForwarder() 884 { 885 return &aViewFwd; 886 } 887 888 SvxEditViewForwarder* SmEditSource::GetEditViewForwarder( sal_Bool /*bCreate*/ ) 889 { 890 return &aEditViewFwd; 891 } 892 893 void SmEditSource::UpdateData() 894 { 895 // would possibly only by needed if the XText inteface is implemented 896 // and its text needs to be updated. 897 } 898 899 SfxBroadcaster & SmEditSource::GetBroadcaster() const 900 { 901 return ((SmEditSource *) this)->aBroadCaster; 902 } 903 904 //------------------------------------------------------------------------ 905 906 SmViewForwarder::SmViewForwarder( SmEditAccessible &rAcc ) : 907 rEditAcc(rAcc) 908 { 909 } 910 911 SmViewForwarder::~SmViewForwarder() 912 { 913 } 914 915 sal_Bool SmViewForwarder::IsValid() const 916 { 917 return rEditAcc.GetEditView() != 0; 918 } 919 920 Rectangle SmViewForwarder::GetVisArea() const 921 { 922 EditView *pEditView = rEditAcc.GetEditView(); 923 OutputDevice* pOutDev = pEditView ? pEditView->GetWindow() : 0; 924 925 if( pOutDev && pEditView) 926 { 927 Rectangle aVisArea = pEditView->GetVisArea(); 928 929 // figure out map mode from edit engine 930 EditEngine* pEditEngine = pEditView->GetEditEngine(); 931 932 if( pEditEngine ) 933 { 934 MapMode aMapMode(pOutDev->GetMapMode()); 935 aVisArea = OutputDevice::LogicToLogic( aVisArea, 936 pEditEngine->GetRefMapMode(), 937 aMapMode.GetMapUnit() ); 938 aMapMode.SetOrigin(Point()); 939 return pOutDev->LogicToPixel( aVisArea, aMapMode ); 940 } 941 } 942 943 return Rectangle(); 944 } 945 946 Point SmViewForwarder::LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const 947 { 948 EditView *pEditView = rEditAcc.GetEditView(); 949 OutputDevice* pOutDev = pEditView ? pEditView->GetWindow() : 0; 950 951 if( pOutDev ) 952 { 953 MapMode aMapMode(pOutDev->GetMapMode()); 954 Point aPoint( OutputDevice::LogicToLogic( rPoint, rMapMode, 955 aMapMode.GetMapUnit() ) ); 956 aMapMode.SetOrigin(Point()); 957 return pOutDev->LogicToPixel( aPoint, aMapMode ); 958 } 959 960 return Point(); 961 } 962 963 Point SmViewForwarder::PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const 964 { 965 EditView *pEditView = rEditAcc.GetEditView(); 966 OutputDevice* pOutDev = pEditView ? pEditView->GetWindow() : 0; 967 968 if( pOutDev ) 969 { 970 MapMode aMapMode(pOutDev->GetMapMode()); 971 aMapMode.SetOrigin(Point()); 972 Point aPoint( pOutDev->PixelToLogic( rPoint, aMapMode ) ); 973 return OutputDevice::LogicToLogic( aPoint, 974 aMapMode.GetMapUnit(), 975 rMapMode ); 976 } 977 978 return Point(); 979 } 980 981 982 //------------------------------------------------------------------------ 983 984 SmTextForwarder::SmTextForwarder( SmEditAccessible& rAcc, SmEditSource & rSource) : 985 rEditAcc ( rAcc ), 986 rEditSource (rSource) 987 { 988 EditEngine *pEditEngine = rEditAcc.GetEditEngine(); 989 if (pEditEngine) 990 pEditEngine->SetNotifyHdl( LINK(this, SmTextForwarder, NotifyHdl) ); 991 } 992 993 SmTextForwarder::~SmTextForwarder() 994 { 995 EditEngine *pEditEngine = rEditAcc.GetEditEngine(); 996 if (pEditEngine) 997 pEditEngine->SetNotifyHdl( Link() ); 998 } 999 1000 IMPL_LINK(SmTextForwarder, NotifyHdl, EENotify*, aNotify) 1001 { 1002 if (aNotify) 1003 { 1004 ::std::auto_ptr< SfxHint > aHint = SvxEditSourceHelper::EENotification2Hint( aNotify ); 1005 if (aHint.get()) 1006 rEditSource.GetBroadcaster().Broadcast( *aHint.get() ); 1007 } 1008 1009 return 0; 1010 } 1011 1012 sal_uInt32 SmTextForwarder::GetParagraphCount() const 1013 { 1014 EditEngine *pEditEngine = rEditAcc.GetEditEngine(); 1015 return pEditEngine ? pEditEngine->GetParagraphCount() : 0; 1016 } 1017 1018 sal_uInt16 SmTextForwarder::GetTextLen( sal_uInt32 nParagraph ) const 1019 { 1020 EditEngine *pEditEngine = rEditAcc.GetEditEngine(); 1021 return pEditEngine ? pEditEngine->GetTextLen( nParagraph ) : 0; 1022 } 1023 1024 String SmTextForwarder::GetText( const ESelection& rSel ) const 1025 { 1026 EditEngine *pEditEngine = rEditAcc.GetEditEngine(); 1027 String aRet; 1028 if (pEditEngine) 1029 aRet = pEditEngine->GetText( rSel, LINEEND_LF ); 1030 aRet.ConvertLineEnd(); 1031 return aRet; 1032 } 1033 1034 SfxItemSet SmTextForwarder::GetAttribs( const ESelection& rSel, sal_Bool bOnlyHardAttrib ) const 1035 { 1036 EditEngine *pEditEngine = rEditAcc.GetEditEngine(); 1037 DBG_ASSERT( pEditEngine, "EditEngine missing" ); 1038 if( rSel.nStartPara == rSel.nEndPara ) 1039 { 1040 sal_uInt8 nFlags = 0; 1041 switch( bOnlyHardAttrib ) 1042 { 1043 case EditEngineAttribs_All: 1044 nFlags = GETATTRIBS_ALL; 1045 break; 1046 case EditEngineAttribs_HardAndPara: 1047 nFlags = GETATTRIBS_PARAATTRIBS|GETATTRIBS_CHARATTRIBS; 1048 break; 1049 case EditEngineAttribs_OnlyHard: 1050 nFlags = GETATTRIBS_CHARATTRIBS; 1051 break; 1052 default: 1053 DBG_ERROR("unknown flags for SmTextForwarder::GetAttribs"); 1054 } 1055 1056 return pEditEngine->GetAttribs( rSel.nStartPara, rSel.nStartPos, rSel.nEndPos, nFlags ); 1057 } 1058 else 1059 { 1060 return pEditEngine->GetAttribs( rSel, bOnlyHardAttrib ); 1061 } 1062 } 1063 1064 SfxItemSet SmTextForwarder::GetParaAttribs( sal_uInt32 nPara ) const 1065 { 1066 EditEngine *pEditEngine = rEditAcc.GetEditEngine(); 1067 DBG_ASSERT( pEditEngine, "EditEngine missing" ); 1068 1069 SfxItemSet aSet( pEditEngine->GetParaAttribs( nPara ) ); 1070 1071 sal_uInt16 nWhich = EE_PARA_START; 1072 while( nWhich <= EE_PARA_END ) 1073 { 1074 if( aSet.GetItemState( nWhich, sal_True ) != SFX_ITEM_ON ) 1075 { 1076 if( pEditEngine->HasParaAttrib( nPara, nWhich ) ) 1077 aSet.Put( pEditEngine->GetParaAttrib( nPara, nWhich ) ); 1078 } 1079 nWhich++; 1080 } 1081 1082 return aSet; 1083 } 1084 1085 void SmTextForwarder::SetParaAttribs( sal_uInt32 nPara, const SfxItemSet& rSet ) 1086 { 1087 EditEngine *pEditEngine = rEditAcc.GetEditEngine(); 1088 if (pEditEngine) 1089 pEditEngine->SetParaAttribs( nPara, rSet ); 1090 } 1091 1092 SfxItemPool* SmTextForwarder::GetPool() const 1093 { 1094 EditEngine *pEditEngine = rEditAcc.GetEditEngine(); 1095 return pEditEngine ? pEditEngine->GetEmptyItemSet().GetPool() : 0; 1096 } 1097 1098 void SmTextForwarder::RemoveAttribs( const ESelection& rSelection, sal_Bool bRemoveParaAttribs, sal_uInt16 nWhich ) 1099 { 1100 EditEngine *pEditEngine = rEditAcc.GetEditEngine(); 1101 if (pEditEngine) 1102 pEditEngine->RemoveAttribs( rSelection, bRemoveParaAttribs, nWhich ); 1103 } 1104 1105 void SmTextForwarder::GetPortions( sal_uInt32 nPara, SvUShorts& rList ) const 1106 { 1107 EditEngine *pEditEngine = rEditAcc.GetEditEngine(); 1108 if (pEditEngine) 1109 pEditEngine->GetPortions( nPara, rList ); 1110 } 1111 1112 void SmTextForwarder::QuickInsertText( const String& rText, const ESelection& rSel ) 1113 { 1114 EditEngine *pEditEngine = rEditAcc.GetEditEngine(); 1115 if (pEditEngine) 1116 pEditEngine->QuickInsertText( rText, rSel ); 1117 } 1118 1119 void SmTextForwarder::QuickInsertLineBreak( const ESelection& rSel ) 1120 { 1121 EditEngine *pEditEngine = rEditAcc.GetEditEngine(); 1122 if (pEditEngine) 1123 pEditEngine->QuickInsertLineBreak( rSel ); 1124 } 1125 1126 void SmTextForwarder::QuickInsertField( const SvxFieldItem& rFld, const ESelection& rSel ) 1127 { 1128 EditEngine *pEditEngine = rEditAcc.GetEditEngine(); 1129 if (pEditEngine) 1130 pEditEngine->QuickInsertField( rFld, rSel ); 1131 } 1132 1133 void SmTextForwarder::QuickSetAttribs( const SfxItemSet& rSet, const ESelection& rSel ) 1134 { 1135 EditEngine *pEditEngine = rEditAcc.GetEditEngine(); 1136 if (pEditEngine) 1137 pEditEngine->QuickSetAttribs( rSet, rSel ); 1138 } 1139 1140 sal_Bool SmTextForwarder::IsValid() const 1141 { 1142 EditEngine *pEditEngine = rEditAcc.GetEditEngine(); 1143 // cannot reliably query EditEngine state 1144 // while in the middle of an update 1145 return pEditEngine ? pEditEngine->GetUpdateMode() : sal_False; 1146 } 1147 1148 XubString SmTextForwarder::CalcFieldValue( const SvxFieldItem& rField, sal_uInt32 nPara, sal_uInt16 nPos, Color*& rpTxtColor, Color*& rpFldColor ) 1149 { 1150 XubString aTxt; 1151 EditEngine *pEditEngine = rEditAcc.GetEditEngine(); 1152 if (pEditEngine) 1153 aTxt = pEditEngine->CalcFieldValue( rField, nPara, nPos, rpTxtColor, rpFldColor ); 1154 return aTxt; 1155 } 1156 1157 void SmTextForwarder::FieldClicked(const SvxFieldItem&, sal_uInt32, sal_uInt16) 1158 { 1159 } 1160 1161 sal_uInt16 GetSvxEditEngineItemState( EditEngine& rEditEngine, const ESelection& rSel, sal_uInt16 nWhich ) 1162 { 1163 EECharAttribArray aAttribs; 1164 1165 const SfxPoolItem* pLastItem = NULL; 1166 1167 SfxItemState eState = SFX_ITEM_DEFAULT; 1168 1169 // check all paragraphs inside the selection 1170 for( sal_uInt32 nPara = rSel.nStartPara; nPara <= rSel.nEndPara; nPara++ ) 1171 { 1172 SfxItemState eParaState = SFX_ITEM_DEFAULT; 1173 1174 // calculate start and endpos for this paragraph 1175 sal_uInt16 nPos = 0; 1176 if( rSel.nStartPara == nPara ) 1177 nPos = rSel.nStartPos; 1178 1179 sal_uInt16 nEndPos = rSel.nEndPos; 1180 if( rSel.nEndPara != nPara ) 1181 nEndPos = rEditEngine.GetTextLen( nPara ); 1182 1183 1184 // get list of char attribs 1185 rEditEngine.GetCharAttribs( nPara, aAttribs ); 1186 1187 sal_Bool bEmpty = sal_True; // we found no item inside the selektion of this paragraph 1188 sal_Bool bGaps = sal_False; // we found items but theire gaps between them 1189 sal_uInt16 nLastEnd = nPos; 1190 1191 const SfxPoolItem* pParaItem = NULL; 1192 1193 for( sal_uInt16 nAttrib = 0; nAttrib < aAttribs.Count(); nAttrib++ ) 1194 { 1195 struct EECharAttrib aAttrib = aAttribs.GetObject( nAttrib ); 1196 DBG_ASSERT( aAttrib.pAttr, "GetCharAttribs gives corrupt data" ); 1197 1198 const sal_Bool bEmptyPortion = aAttrib.nStart == aAttrib.nEnd; 1199 if( (!bEmptyPortion && (aAttrib.nStart >= nEndPos)) || (bEmptyPortion && (aAttrib.nStart > nEndPos)) ) 1200 break; // break if we are already behind our selektion 1201 1202 if( (!bEmptyPortion && (aAttrib.nEnd <= nPos)) || (bEmptyPortion && (aAttrib.nEnd < nPos)) ) 1203 continue; // or if the attribute ends before our selektion 1204 1205 if( aAttrib.pAttr->Which() != nWhich ) 1206 continue; // skip if is not the searched item 1207 1208 // if we already found an item 1209 if( pParaItem ) 1210 { 1211 // ... and its different to this one than the state is dont care 1212 if( *pParaItem != *aAttrib.pAttr ) 1213 return SFX_ITEM_DONTCARE; 1214 } 1215 else 1216 { 1217 pParaItem = aAttrib.pAttr; 1218 } 1219 1220 if( bEmpty ) 1221 bEmpty = sal_False; 1222 1223 if( !bGaps && aAttrib.nStart > nLastEnd ) 1224 bGaps = sal_True; 1225 1226 nLastEnd = aAttrib.nEnd; 1227 } 1228 1229 if( !bEmpty && !bGaps && nLastEnd < ( nEndPos - 1 ) ) 1230 bGaps = sal_True; 1231 /* 1232 // since we have no portion with our item or if there were gaps 1233 if( bEmpty || bGaps ) 1234 { 1235 // we need to check the paragraph item 1236 const SfxItemSet& rParaSet = rEditEngine.GetParaAttribs( nPara ); 1237 if( rParaSet.GetItemState( nWhich ) == SFX_ITEM_SET ) 1238 { 1239 eState = SFX_ITEM_SET; 1240 // get item from the paragraph 1241 const SfxPoolItem* pTempItem = rParaSet.GetItem( nWhich ); 1242 if( pParaItem ) 1243 { 1244 if( *pParaItem != *pTempItem ) 1245 return SFX_ITEM_DONTCARE; 1246 } 1247 else 1248 { 1249 pParaItem = pTempItem; 1250 } 1251 1252 // set if theres no last item or if its the same 1253 eParaState = SFX_ITEM_SET; 1254 } 1255 else if( bEmpty ) 1256 { 1257 eParaState = SFX_ITEM_DEFAULT; 1258 } 1259 else if( bGaps ) 1260 { 1261 // gaps and item not set in paragraph, that's a dont care 1262 return SFX_ITEM_DONTCARE; 1263 } 1264 } 1265 else 1266 { 1267 eParaState = SFX_ITEM_SET; 1268 } 1269 */ 1270 if( bEmpty ) 1271 eParaState = SFX_ITEM_DEFAULT; 1272 else if( bGaps ) 1273 eParaState = SFX_ITEM_DONTCARE; 1274 else 1275 eParaState = SFX_ITEM_SET; 1276 1277 // if we already found an item check if we found the same 1278 if( pLastItem ) 1279 { 1280 if( (pParaItem == NULL) || (*pLastItem != *pParaItem) ) 1281 return SFX_ITEM_DONTCARE; 1282 } 1283 else 1284 { 1285 pLastItem = pParaItem; 1286 eState = eParaState; 1287 } 1288 } 1289 1290 return eState; 1291 } 1292 1293 sal_uInt16 SmTextForwarder::GetItemState( const ESelection& rSel, sal_uInt16 nWhich ) const 1294 { 1295 sal_uInt16 nState = SFX_ITEM_DISABLED; 1296 EditEngine *pEditEngine = rEditAcc.GetEditEngine(); 1297 if (pEditEngine) 1298 nState = GetSvxEditEngineItemState( *pEditEngine, rSel, nWhich ); 1299 return nState; 1300 } 1301 1302 sal_uInt16 SmTextForwarder::GetItemState( sal_uInt16 nPara, sal_uInt16 nWhich ) const 1303 { 1304 sal_uInt16 nState = SFX_ITEM_DISABLED; 1305 EditEngine *pEditEngine = rEditAcc.GetEditEngine(); 1306 if (pEditEngine) 1307 { 1308 const SfxItemSet& rSet = pEditEngine->GetParaAttribs( nPara ); 1309 nState = rSet.GetItemState( nWhich ); 1310 } 1311 return nState; 1312 } 1313 1314 LanguageType SmTextForwarder::GetLanguage( sal_uInt16 nPara, sal_uInt16 nIndex ) const 1315 { 1316 EditEngine *pEditEngine = rEditAcc.GetEditEngine(); 1317 return pEditEngine ? pEditEngine->GetLanguage(nPara, nIndex) : LANGUAGE_NONE; 1318 } 1319 1320 sal_uInt16 SmTextForwarder::GetFieldCount( sal_uInt32 nPara ) const 1321 { 1322 EditEngine *pEditEngine = rEditAcc.GetEditEngine(); 1323 return pEditEngine ? pEditEngine->GetFieldCount(nPara) : 0; 1324 } 1325 1326 EFieldInfo SmTextForwarder::GetFieldInfo( sal_uInt32 nPara, sal_uInt16 nField ) const 1327 { 1328 EditEngine *pEditEngine = rEditAcc.GetEditEngine(); 1329 return pEditEngine ? pEditEngine->GetFieldInfo( nPara, nField ) : EFieldInfo(); 1330 } 1331 1332 EBulletInfo SmTextForwarder::GetBulletInfo( sal_uInt32 /*nPara*/ ) const 1333 { 1334 return EBulletInfo(); 1335 } 1336 1337 Rectangle SmTextForwarder::GetCharBounds( sal_uInt32 nPara, sal_uInt16 nIndex ) const 1338 { 1339 Rectangle aRect(0,0,0,0); 1340 EditEngine *pEditEngine = rEditAcc.GetEditEngine(); 1341 1342 if (pEditEngine) 1343 { 1344 // #108900# Handle virtual position one-past-the end of the string 1345 if( nIndex >= pEditEngine->GetTextLen(nPara) ) 1346 { 1347 if( nIndex ) 1348 aRect = pEditEngine->GetCharacterBounds( EPosition(nPara, nIndex-1) ); 1349 1350 aRect.Move( aRect.Right() - aRect.Left(), 0 ); 1351 aRect.SetSize( Size(1, pEditEngine->GetTextHeight()) ); 1352 } 1353 else 1354 { 1355 aRect = pEditEngine->GetCharacterBounds( EPosition(nPara, nIndex) ); 1356 } 1357 } 1358 return aRect; 1359 } 1360 1361 Rectangle SmTextForwarder::GetParaBounds( sal_uInt32 nPara ) const 1362 { 1363 Rectangle aRect(0,0,0,0); 1364 EditEngine *pEditEngine = rEditAcc.GetEditEngine(); 1365 1366 if (pEditEngine) 1367 { 1368 const Point aPnt = pEditEngine->GetDocPosTopLeft( nPara ); 1369 const sal_uLong nWidth = pEditEngine->CalcTextWidth(); 1370 const sal_uLong nHeight = pEditEngine->GetTextHeight( nPara ); 1371 aRect = Rectangle( aPnt.X(), aPnt.Y(), aPnt.X() + nWidth, aPnt.Y() + nHeight ); 1372 } 1373 1374 return aRect; 1375 } 1376 1377 MapMode SmTextForwarder::GetMapMode() const 1378 { 1379 EditEngine *pEditEngine = rEditAcc.GetEditEngine(); 1380 return pEditEngine ? pEditEngine->GetRefMapMode() : MapMode( MAP_100TH_MM ); 1381 } 1382 1383 OutputDevice* SmTextForwarder::GetRefDevice() const 1384 { 1385 EditEngine *pEditEngine = rEditAcc.GetEditEngine(); 1386 return pEditEngine ? pEditEngine->GetRefDevice() : 0; 1387 } 1388 1389 sal_Bool SmTextForwarder::GetIndexAtPoint( const Point& rPos, sal_uInt32& nPara, sal_uInt16& nIndex ) const 1390 { 1391 sal_Bool bRes = sal_False; 1392 EditEngine *pEditEngine = rEditAcc.GetEditEngine(); 1393 if (pEditEngine) 1394 { 1395 EPosition aDocPos = pEditEngine->FindDocPosition( rPos ); 1396 nPara = aDocPos.nPara; 1397 nIndex = aDocPos.nIndex; 1398 bRes = sal_True; 1399 } 1400 return bRes; 1401 } 1402 1403 sal_Bool SmTextForwarder::GetWordIndices( sal_uInt32 nPara, sal_uInt16 nIndex, sal_uInt16& nStart, sal_uInt16& nEnd ) const 1404 { 1405 sal_Bool bRes = sal_False; 1406 EditEngine *pEditEngine = rEditAcc.GetEditEngine(); 1407 if (pEditEngine) 1408 { 1409 ESelection aRes = pEditEngine->GetWord( ESelection(nPara, nIndex, nPara, nIndex), com::sun::star::i18n::WordType::DICTIONARY_WORD ); 1410 1411 if( aRes.nStartPara == nPara && 1412 aRes.nStartPara == aRes.nEndPara ) 1413 { 1414 nStart = aRes.nStartPos; 1415 nEnd = aRes.nEndPos; 1416 1417 bRes = sal_True; 1418 } 1419 } 1420 1421 return bRes; 1422 } 1423 1424 sal_Bool SmTextForwarder::GetAttributeRun( sal_uInt16& nStartIndex, sal_uInt16& nEndIndex, sal_uInt32 nPara, sal_uInt16 nIndex, sal_Bool bInCell ) const 1425 { 1426 EditEngine *pEditEngine = rEditAcc.GetEditEngine(); 1427 return pEditEngine ? 1428 SvxEditSourceHelper::GetAttributeRun( nStartIndex, nEndIndex, *pEditEngine, nPara, nIndex, bInCell ) 1429 : sal_False; 1430 } 1431 1432 sal_uInt16 SmTextForwarder::GetLineCount( sal_uInt32 nPara ) const 1433 { 1434 EditEngine *pEditEngine = rEditAcc.GetEditEngine(); 1435 return pEditEngine ? pEditEngine->GetLineCount(nPara) : 0; 1436 } 1437 1438 sal_uInt16 SmTextForwarder::GetLineLen( sal_uInt32 nPara, sal_uInt16 nLine ) const 1439 { 1440 EditEngine *pEditEngine = rEditAcc.GetEditEngine(); 1441 return pEditEngine ? pEditEngine->GetLineLen(nPara, nLine) : 0; 1442 } 1443 1444 void SmTextForwarder::GetLineBoundaries( /*out*/sal_uInt16 &rStart, /*out*/sal_uInt16 &rEnd, sal_uInt32 nPara, sal_uInt16 nLine ) const 1445 { 1446 EditEngine *pEditEngine = rEditAcc.GetEditEngine(); 1447 pEditEngine->GetLineBoundaries(rStart, rEnd, nPara, nLine); 1448 } 1449 1450 sal_uInt16 SmTextForwarder::GetLineNumberAtIndex( sal_uInt16 nPara, sal_uInt16 nIndex ) const 1451 { 1452 EditEngine *pEditEngine = rEditAcc.GetEditEngine(); 1453 return pEditEngine ? pEditEngine->GetLineNumberAtIndex(nPara, nIndex) : 0; 1454 } 1455 1456 sal_Bool SmTextForwarder::QuickFormatDoc( sal_Bool /*bFull*/ ) 1457 { 1458 sal_Bool bRes = sal_False; 1459 EditEngine *pEditEngine = rEditAcc.GetEditEngine(); 1460 if (pEditEngine) 1461 { 1462 pEditEngine->QuickFormatDoc(); 1463 bRes = sal_True; 1464 } 1465 return bRes; 1466 } 1467 1468 sal_Int16 SmTextForwarder::GetDepth( sal_uInt16 /*nPara*/ ) const 1469 { 1470 // math has no outliner... 1471 return -1; 1472 } 1473 1474 sal_Bool SmTextForwarder::SetDepth( sal_uInt16 /*nPara*/, sal_Int16 nNewDepth ) 1475 { 1476 // math has no outliner... 1477 return -1 == nNewDepth; // is it the value from 'GetDepth' ? 1478 } 1479 1480 sal_Bool SmTextForwarder::Delete( const ESelection& rSelection ) 1481 { 1482 sal_Bool bRes = sal_False; 1483 EditEngine *pEditEngine = rEditAcc.GetEditEngine(); 1484 if (pEditEngine) 1485 { 1486 pEditEngine->QuickDelete( rSelection ); 1487 pEditEngine->QuickFormatDoc(); 1488 bRes = sal_True; 1489 } 1490 return bRes; 1491 } 1492 1493 sal_Bool SmTextForwarder::InsertText( const String& rStr, const ESelection& rSelection ) 1494 { 1495 sal_Bool bRes = sal_False; 1496 EditEngine *pEditEngine = rEditAcc.GetEditEngine(); 1497 if (pEditEngine) 1498 { 1499 pEditEngine->QuickInsertText( rStr, rSelection ); 1500 pEditEngine->QuickFormatDoc(); 1501 bRes = sal_True; 1502 } 1503 return bRes; 1504 } 1505 1506 const SfxItemSet* SmTextForwarder::GetEmptyItemSetPtr() 1507 { 1508 const SfxItemSet *pItemSet = 0; 1509 EditEngine *pEditEngine = rEditAcc.GetEditEngine(); 1510 if (pEditEngine) 1511 { 1512 pItemSet = &pEditEngine->GetEmptyItemSet(); 1513 } 1514 return pItemSet; 1515 } 1516 1517 void SmTextForwarder::AppendParagraph() 1518 { 1519 // append an empty paragraph 1520 EditEngine *pEditEngine = rEditAcc.GetEditEngine(); 1521 if (pEditEngine) 1522 { 1523 sal_uInt32 nParaCount = pEditEngine->GetParagraphCount(); 1524 pEditEngine->InsertParagraph( nParaCount, String() ); 1525 } 1526 } 1527 1528 xub_StrLen SmTextForwarder::AppendTextPortion( sal_uInt16 nPara, const String &rText, const SfxItemSet &rSet ) 1529 { 1530 xub_StrLen nRes = 0; 1531 EditEngine *pEditEngine = rEditAcc.GetEditEngine(); 1532 if (pEditEngine && nPara < pEditEngine->GetParagraphCount()) 1533 { 1534 // append text 1535 ESelection aSel( nPara, pEditEngine->GetTextLen( nPara ) ); 1536 pEditEngine->QuickInsertText( rText, aSel ); 1537 1538 // set attributes for new appended text 1539 nRes = aSel.nEndPos = pEditEngine->GetTextLen( nPara ); 1540 pEditEngine->QuickSetAttribs( rSet, aSel ); 1541 } 1542 return nRes; 1543 } 1544 1545 void SmTextForwarder::CopyText(const SvxTextForwarder& rSource) 1546 { 1547 1548 const SmTextForwarder* pSourceForwarder = dynamic_cast< const SmTextForwarder* >( &rSource ); 1549 if( !pSourceForwarder ) 1550 return; 1551 EditEngine* pSourceEditEngine = pSourceForwarder->rEditAcc.GetEditEngine(); 1552 EditEngine *pEditEngine = rEditAcc.GetEditEngine(); 1553 if (pEditEngine && pSourceEditEngine ) 1554 { 1555 EditTextObject* pNewTextObject = pSourceEditEngine->CreateTextObject(); 1556 pEditEngine->SetText( *pNewTextObject ); 1557 delete pNewTextObject; 1558 } 1559 } 1560 1561 //------------------------------------------------------------------------ 1562 1563 SmEditViewForwarder::SmEditViewForwarder( SmEditAccessible& rAcc ) : 1564 rEditAcc( rAcc ) 1565 { 1566 } 1567 1568 SmEditViewForwarder::~SmEditViewForwarder() 1569 { 1570 } 1571 1572 sal_Bool SmEditViewForwarder::IsValid() const 1573 { 1574 return rEditAcc.GetEditView() != 0; 1575 } 1576 1577 Rectangle SmEditViewForwarder::GetVisArea() const 1578 { 1579 Rectangle aRect(0,0,0,0); 1580 1581 EditView *pEditView = rEditAcc.GetEditView(); 1582 OutputDevice* pOutDev = pEditView ? pEditView->GetWindow() : 0; 1583 1584 if( pOutDev && pEditView) 1585 { 1586 Rectangle aVisArea = pEditView->GetVisArea(); 1587 1588 // figure out map mode from edit engine 1589 EditEngine* pEditEngine = pEditView->GetEditEngine(); 1590 1591 if( pEditEngine ) 1592 { 1593 MapMode aMapMode(pOutDev->GetMapMode()); 1594 aVisArea = OutputDevice::LogicToLogic( aVisArea, 1595 pEditEngine->GetRefMapMode(), 1596 aMapMode.GetMapUnit() ); 1597 aMapMode.SetOrigin(Point()); 1598 aRect = pOutDev->LogicToPixel( aVisArea, aMapMode ); 1599 } 1600 } 1601 1602 return aRect; 1603 } 1604 1605 Point SmEditViewForwarder::LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const 1606 { 1607 EditView *pEditView = rEditAcc.GetEditView(); 1608 OutputDevice* pOutDev = pEditView ? pEditView->GetWindow() : 0; 1609 1610 if( pOutDev ) 1611 { 1612 MapMode aMapMode(pOutDev->GetMapMode()); 1613 Point aPoint( OutputDevice::LogicToLogic( rPoint, rMapMode, 1614 aMapMode.GetMapUnit() ) ); 1615 aMapMode.SetOrigin(Point()); 1616 return pOutDev->LogicToPixel( aPoint, aMapMode ); 1617 } 1618 1619 return Point(); 1620 } 1621 1622 Point SmEditViewForwarder::PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const 1623 { 1624 EditView *pEditView = rEditAcc.GetEditView(); 1625 OutputDevice* pOutDev = pEditView ? pEditView->GetWindow() : 0; 1626 1627 if( pOutDev ) 1628 { 1629 MapMode aMapMode(pOutDev->GetMapMode()); 1630 aMapMode.SetOrigin(Point()); 1631 Point aPoint( pOutDev->PixelToLogic( rPoint, aMapMode ) ); 1632 return OutputDevice::LogicToLogic( aPoint, 1633 aMapMode.GetMapUnit(), 1634 rMapMode ); 1635 } 1636 1637 return Point(); 1638 } 1639 1640 sal_Bool SmEditViewForwarder::GetSelection( ESelection& rSelection ) const 1641 { 1642 sal_Bool bRes = sal_False; 1643 EditView *pEditView = rEditAcc.GetEditView(); 1644 if (pEditView) 1645 { 1646 rSelection = pEditView->GetSelection(); 1647 bRes = sal_True; 1648 } 1649 return bRes; 1650 } 1651 1652 sal_Bool SmEditViewForwarder::SetSelection( const ESelection& rSelection ) 1653 { 1654 sal_Bool bRes = sal_False; 1655 EditView *pEditView = rEditAcc.GetEditView(); 1656 if (pEditView) 1657 { 1658 pEditView->SetSelection( rSelection ); 1659 bRes = sal_True; 1660 } 1661 return bRes; 1662 } 1663 1664 sal_Bool SmEditViewForwarder::Copy() 1665 { 1666 sal_Bool bRes = sal_False; 1667 EditView *pEditView = rEditAcc.GetEditView(); 1668 if (pEditView) 1669 { 1670 pEditView->Copy(); 1671 bRes = sal_True; 1672 } 1673 return bRes; 1674 } 1675 1676 sal_Bool SmEditViewForwarder::Cut() 1677 { 1678 sal_Bool bRes = sal_False; 1679 EditView *pEditView = rEditAcc.GetEditView(); 1680 if (pEditView) 1681 { 1682 pEditView->Cut(); 1683 bRes = sal_True; 1684 } 1685 return bRes; 1686 } 1687 1688 sal_Bool SmEditViewForwarder::Paste() 1689 { 1690 sal_Bool bRes = sal_False; 1691 EditView *pEditView = rEditAcc.GetEditView(); 1692 if (pEditView) 1693 { 1694 pEditView->Paste(); 1695 bRes = sal_True; 1696 } 1697 return bRes; 1698 } 1699 1700 //------------------------------------------------------------------------ 1701 1702 SmEditAccessible::SmEditAccessible( SmEditWindow *pEditWin ) : 1703 aAccName ( String(SmResId(STR_CMDBOXWINDOW)) ), 1704 pTextHelper (0), 1705 pWin (pEditWin) 1706 { 1707 DBG_ASSERT( pWin, "SmEditAccessible: window missing" ); 1708 //++aRefCount; 1709 } 1710 1711 1712 SmEditAccessible::SmEditAccessible( const SmEditAccessible &rSmAcc ) : 1713 SmEditAccessibleBaseClass(), 1714 aAccName ( String(SmResId(STR_CMDBOXWINDOW)) ) 1715 { 1716 //vos::OGuard aGuard(Application::GetSolarMutex()); 1717 pWin = rSmAcc.pWin; 1718 DBG_ASSERT( pWin, "SmEditAccessible: window missing" ); 1719 //++aRefCount; 1720 } 1721 1722 SmEditAccessible::~SmEditAccessible() 1723 { 1724 delete pTextHelper; 1725 /* 1726 vos::OGuard aGuard(Application::GetSolarMutex()); 1727 if (--aRefCount == 0) 1728 { 1729 } 1730 */ 1731 } 1732 1733 void SmEditAccessible::Init() 1734 { 1735 DBG_ASSERT( pWin, "SmEditAccessible: window missing" ); 1736 if (pWin) 1737 { 1738 EditEngine *pEditEngine = pWin->GetEditEngine(); 1739 EditView *pEditView = pWin->GetEditView(); 1740 if (pEditEngine && pEditView) 1741 { 1742 ::std::auto_ptr< SvxEditSource > pEditSource( 1743 new SmEditSource( pWin, *this ) ); 1744 pTextHelper = new ::accessibility::AccessibleTextHelper( pEditSource ); 1745 pTextHelper->SetEventSource( this ); 1746 } 1747 } 1748 } 1749 1750 #ifdef TL_NOT_YET_USED 1751 SmDocShell * SmEditAccessible::GetDoc_Impl() 1752 { 1753 SmViewShell *pView = pWin ? pWin->GetView() : 0; 1754 return pView ? pView->GetDoc() : 0; 1755 } 1756 #endif // TL_NOT_YET_USED 1757 1758 void SmEditAccessible::ClearWin() 1759 { 1760 // #112565# remove handler before current object gets destroyed 1761 // (avoid handler being called for already dead object) 1762 EditEngine *pEditEngine = GetEditEngine(); 1763 if (pEditEngine) 1764 pEditEngine->SetNotifyHdl( Link() ); 1765 1766 pWin = 0; // implicitly results in AccessibleStateType::DEFUNC set 1767 1768 //! make TextHelper implicitly release C++ references to some core objects 1769 pTextHelper->SetEditSource( ::std::auto_ptr<SvxEditSource>(NULL) ); 1770 //! make TextHelper release references 1771 //! (e.g. the one set by the 'SetEventSource' call) 1772 pTextHelper->Dispose(); 1773 delete pTextHelper; pTextHelper = 0; 1774 } 1775 1776 // XAccessible 1777 uno::Reference< XAccessibleContext > SAL_CALL SmEditAccessible::getAccessibleContext( ) 1778 throw (RuntimeException) 1779 { 1780 vos::OGuard aGuard(Application::GetSolarMutex()); 1781 return this; 1782 } 1783 1784 // XAccessibleComponent 1785 sal_Bool SAL_CALL SmEditAccessible::containsPoint( const awt::Point& aPoint ) 1786 throw (RuntimeException) 1787 { 1788 //! the arguments coordinates are relativ to the current window ! 1789 //! Thus the top left-point is (0, 0) 1790 1791 vos::OGuard aGuard(Application::GetSolarMutex()); 1792 if (!pWin) 1793 throw RuntimeException(); 1794 1795 Size aSz( pWin->GetSizePixel() ); 1796 return aPoint.X >= 0 && aPoint.Y >= 0 && 1797 aPoint.X < aSz.Width() && aPoint.Y < aSz.Height(); 1798 } 1799 1800 uno::Reference< XAccessible > SAL_CALL SmEditAccessible::getAccessibleAtPoint( const awt::Point& aPoint ) 1801 throw (RuntimeException) 1802 { 1803 vos::OGuard aGuard(Application::GetSolarMutex()); 1804 if (!pTextHelper) 1805 throw RuntimeException(); 1806 return pTextHelper->GetAt( aPoint ); 1807 } 1808 1809 awt::Rectangle SAL_CALL SmEditAccessible::getBounds( ) 1810 throw (RuntimeException) 1811 { 1812 vos::OGuard aGuard(Application::GetSolarMutex()); 1813 if (!pWin) 1814 throw RuntimeException(); 1815 DBG_ASSERT(pWin->GetParent()->GetAccessible() == getAccessibleParent(), 1816 "mismatch of window parent and accessible parent" ); 1817 return lcl_GetBounds( pWin ); 1818 } 1819 1820 awt::Point SAL_CALL SmEditAccessible::getLocation( ) 1821 throw (RuntimeException) 1822 { 1823 vos::OGuard aGuard(Application::GetSolarMutex()); 1824 if (!pWin) 1825 throw RuntimeException(); 1826 DBG_ASSERT(pWin->GetParent()->GetAccessible() == getAccessibleParent(), 1827 "mismatch of window parent and accessible parent" ); 1828 awt::Rectangle aRect( lcl_GetBounds( pWin ) ); 1829 return awt::Point( aRect.X, aRect.Y ); 1830 } 1831 1832 awt::Point SAL_CALL SmEditAccessible::getLocationOnScreen( ) 1833 throw (RuntimeException) 1834 { 1835 vos::OGuard aGuard(Application::GetSolarMutex()); 1836 if (!pWin) 1837 throw RuntimeException(); 1838 DBG_ASSERT(pWin->GetParent()->GetAccessible() == getAccessibleParent(), 1839 "mismatch of window parent and accessible parent" ); 1840 return lcl_GetLocationOnScreen( pWin ); 1841 } 1842 1843 awt::Size SAL_CALL SmEditAccessible::getSize( ) 1844 throw (RuntimeException) 1845 { 1846 vos::OGuard aGuard(Application::GetSolarMutex()); 1847 if (!pWin) 1848 throw RuntimeException(); 1849 DBG_ASSERT(pWin->GetParent()->GetAccessible() == getAccessibleParent(), 1850 "mismatch of window parent and accessible parent" ); 1851 1852 Size aSz( pWin->GetSizePixel() ); 1853 #if OSL_DEBUG_LEVEL > 1 1854 awt::Rectangle aRect( lcl_GetBounds( pWin ) ); 1855 Size aSz2( aRect.Width, aRect.Height ); 1856 DBG_ASSERT( aSz == aSz2, "mismatch in width" ); 1857 #endif 1858 return awt::Size( aSz.Width(), aSz.Height() ); 1859 } 1860 1861 void SAL_CALL SmEditAccessible::grabFocus( ) 1862 throw (RuntimeException) 1863 { 1864 vos::OGuard aGuard(Application::GetSolarMutex()); 1865 if (!pWin) 1866 throw RuntimeException(); 1867 1868 pWin->GrabFocus(); 1869 } 1870 1871 sal_Int32 SAL_CALL SmEditAccessible::getForeground() 1872 throw (RuntimeException) 1873 { 1874 vos::OGuard aGuard(Application::GetSolarMutex()); 1875 1876 if (!pWin) 1877 throw RuntimeException(); 1878 return (sal_Int32) pWin->GetTextColor().GetColor(); 1879 } 1880 1881 sal_Int32 SAL_CALL SmEditAccessible::getBackground() 1882 throw (RuntimeException) 1883 { 1884 vos::OGuard aGuard(Application::GetSolarMutex()); 1885 1886 if (!pWin) 1887 throw RuntimeException(); 1888 Wallpaper aWall( pWin->GetDisplayBackground() ); 1889 ColorData nCol; 1890 if (aWall.IsBitmap() || aWall.IsGradient()) 1891 nCol = pWin->GetSettings().GetStyleSettings().GetWindowColor().GetColor(); 1892 else 1893 nCol = aWall.GetColor().GetColor(); 1894 return (sal_Int32) nCol; 1895 } 1896 1897 // XAccessibleContext 1898 sal_Int32 SAL_CALL SmEditAccessible::getAccessibleChildCount( ) 1899 throw (RuntimeException) 1900 { 1901 vos::OGuard aGuard(Application::GetSolarMutex()); 1902 if (!pTextHelper) 1903 throw RuntimeException(); 1904 return pTextHelper->GetChildCount(); 1905 } 1906 1907 uno::Reference< XAccessible > SAL_CALL SmEditAccessible::getAccessibleChild( sal_Int32 i ) 1908 throw (IndexOutOfBoundsException, RuntimeException) 1909 { 1910 vos::OGuard aGuard(Application::GetSolarMutex()); 1911 if (!pTextHelper) 1912 throw RuntimeException(); 1913 return pTextHelper->GetChild( i ); 1914 } 1915 1916 uno::Reference< XAccessible > SAL_CALL SmEditAccessible::getAccessibleParent( ) 1917 throw (RuntimeException) 1918 { 1919 vos::OGuard aGuard(Application::GetSolarMutex()); 1920 if (!pWin) 1921 throw RuntimeException(); 1922 1923 Window *pAccParent = pWin->GetAccessibleParentWindow(); 1924 DBG_ASSERT( pAccParent, "accessible parent missing" ); 1925 return pAccParent ? pAccParent->GetAccessible() : Reference< XAccessible >(); 1926 } 1927 1928 sal_Int32 SAL_CALL SmEditAccessible::getAccessibleIndexInParent( ) 1929 throw (RuntimeException) 1930 { 1931 vos::OGuard aGuard(Application::GetSolarMutex()); 1932 sal_Int32 nIdx = -1; 1933 Window *pAccParent = pWin ? pWin->GetAccessibleParentWindow() : 0; 1934 if (pAccParent) 1935 { 1936 sal_uInt16 nCnt = pAccParent->GetAccessibleChildWindowCount(); 1937 for (sal_uInt16 i = 0; i < nCnt && nIdx == -1; ++i) 1938 if (pAccParent->GetAccessibleChildWindow( i ) == pWin) 1939 nIdx = i; 1940 } 1941 return nIdx; 1942 } 1943 1944 sal_Int16 SAL_CALL SmEditAccessible::getAccessibleRole( ) 1945 throw (RuntimeException) 1946 { 1947 vos::OGuard aGuard(Application::GetSolarMutex()); 1948 return AccessibleRole::PANEL /*TEXT ?*/; 1949 } 1950 1951 rtl::OUString SAL_CALL SmEditAccessible::getAccessibleDescription( ) 1952 throw (RuntimeException) 1953 { 1954 vos::OGuard aGuard(Application::GetSolarMutex()); 1955 return OUString(); // empty as agreed with product-management 1956 } 1957 1958 rtl::OUString SAL_CALL SmEditAccessible::getAccessibleName( ) 1959 throw (RuntimeException) 1960 { 1961 vos::OGuard aGuard(Application::GetSolarMutex()); 1962 // same name as displayed by the window when not docked 1963 return aAccName; 1964 } 1965 1966 uno::Reference< XAccessibleRelationSet > SAL_CALL SmEditAccessible::getAccessibleRelationSet( ) 1967 throw (RuntimeException) 1968 { 1969 vos::OGuard aGuard(Application::GetSolarMutex()); 1970 Reference< XAccessibleRelationSet > xRelSet = new utl::AccessibleRelationSetHelper(); 1971 return xRelSet; // empty relation set 1972 } 1973 1974 uno::Reference< XAccessibleStateSet > SAL_CALL SmEditAccessible::getAccessibleStateSet( ) 1975 throw (RuntimeException) 1976 { 1977 vos::OGuard aGuard(Application::GetSolarMutex()); 1978 ::utl::AccessibleStateSetHelper *pStateSet = 1979 new ::utl::AccessibleStateSetHelper; 1980 1981 Reference<XAccessibleStateSet> xStateSet( pStateSet ); 1982 1983 if (!pWin || !pTextHelper) 1984 pStateSet->AddState( AccessibleStateType::DEFUNC ); 1985 else 1986 { 1987 //pStateSet->AddState( AccessibleStateType::EDITABLE ); 1988 pStateSet->AddState( AccessibleStateType::MULTI_LINE ); 1989 //pStateSet->AddState( AccessibleStateType::HORIZONTAL ); 1990 //pStateSet->AddState( AccessibleStateType::TRANSIENT ); 1991 pStateSet->AddState( AccessibleStateType::ENABLED ); 1992 pStateSet->AddState( AccessibleStateType::FOCUSABLE ); 1993 if (pWin->HasFocus()) 1994 pStateSet->AddState( AccessibleStateType::FOCUSED ); 1995 if (pWin->IsActive()) 1996 pStateSet->AddState( AccessibleStateType::ACTIVE ); 1997 if (pWin->IsVisible()) 1998 pStateSet->AddState( AccessibleStateType::SHOWING ); 1999 if (pWin->IsReallyVisible()) 2000 pStateSet->AddState( AccessibleStateType::VISIBLE ); 2001 if (COL_TRANSPARENT != pWin->GetBackground().GetColor().GetColor()) 2002 pStateSet->AddState( AccessibleStateType::OPAQUE ); 2003 } 2004 2005 return xStateSet; 2006 } 2007 2008 Locale SAL_CALL SmEditAccessible::getLocale( ) 2009 throw (IllegalAccessibleComponentStateException, RuntimeException) 2010 { 2011 vos::OGuard aGuard(Application::GetSolarMutex()); 2012 // should be the document language... 2013 // We use the language of the localized symbol names here. 2014 return Application::GetSettings().GetUILocale(); 2015 } 2016 2017 2018 // XAccessibleEventBroadcaster 2019 void SAL_CALL SmEditAccessible::addEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) 2020 throw (RuntimeException) 2021 { 2022 //vos::OGuard aGuard(Application::GetSolarMutex()); if (pTextHelper) // not disposing (about to destroy view shell) 2023 pTextHelper->AddEventListener( xListener ); 2024 } 2025 2026 void SAL_CALL SmEditAccessible::removeEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) 2027 throw (RuntimeException) 2028 { 2029 //vos::OGuard aGuard(Application::GetSolarMutex()); 2030 if (pTextHelper) // not disposing (about to destroy view shell) 2031 pTextHelper->RemoveEventListener( xListener ); 2032 } 2033 2034 OUString SAL_CALL SmEditAccessible::getImplementationName() 2035 throw (RuntimeException) 2036 { 2037 //vos::OGuard aGuard(Application::GetSolarMutex()); 2038 return A2OU("SmEditAccessible"); 2039 } 2040 2041 sal_Bool SAL_CALL SmEditAccessible::supportsService( 2042 const OUString& rServiceName ) 2043 throw (RuntimeException) 2044 { 2045 //vos::OGuard aGuard(Application::GetSolarMutex()); 2046 return rServiceName == A2OU( "com::sun::star::accessibility::Accessible" ) || 2047 rServiceName == A2OU( "com::sun::star::accessibility::AccessibleComponent" ) || 2048 rServiceName == A2OU( "com::sun::star::accessibility::AccessibleContext" ); 2049 } 2050 2051 Sequence< OUString > SAL_CALL SmEditAccessible::getSupportedServiceNames() 2052 throw (RuntimeException) 2053 { 2054 //vos::OGuard aGuard(Application::GetSolarMutex()); 2055 Sequence< OUString > aNames(3); 2056 OUString *pNames = aNames.getArray(); 2057 pNames[0] = A2OU( "com::sun::star::accessibility::Accessible" ); 2058 pNames[1] = A2OU( "com::sun::star::accessibility::AccessibleComponent" ); 2059 pNames[2] = A2OU( "com::sun::star::accessibility::AccessibleContext" ); 2060 return aNames; 2061 } 2062 2063 ////////////////////////////////////////////////////////////////////// 2064 2065