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_svx.hxx" 26 #include <com/sun/star/accessibility/AccessibleRole.hpp> 27 #include <com/sun/star/accessibility/AccessibleEventId.hpp> 28 #include <com/sun/star/accessibility/AccessibleStateType.hpp> 29 #include <com/sun/star/lang/DisposedException.hpp> 30 #include <com/sun/star/beans/PropertyChangeEvent.hpp> 31 #include <com/sun/star/awt/XWindow.hpp> 32 #include <unotools/accessiblestatesethelper.hxx> 33 #include <cppuhelper/typeprovider.hxx> 34 #include <toolkit/helper/vclunohelper.hxx> 35 #include <vcl/svapp.hxx> 36 #include <osl/mutex.hxx> 37 #include <rtl/uuid.h> 38 #include <tools/debug.hxx> 39 #include <tools/gen.hxx> 40 #include <svl/smplhint.hxx> 41 #include <toolkit/helper/convert.hxx> 42 #include <svtools/colorcfg.hxx> 43 #include <comphelper/accessibleeventnotifier.hxx> 44 #include <svx/sdrpaintwindow.hxx> 45 46 //===== local includes ======================================================== 47 #include <svx/ShapeTypeHandler.hxx> 48 #include <svx/AccessibleShapeInfo.hxx> 49 #include "GraphCtlAccessibleContext.hxx" 50 #include <svx/graphctl.hxx> 51 #ifndef _SVX_DIALOGS_HRC 52 #include <svx/dialogs.hrc> 53 #endif 54 #ifndef _SVX_ACCESSIBILITY_HRC 55 #include "accessibility.hrc" 56 #endif 57 #include <svx/svdpage.hxx> 58 #include <svx/unomod.hxx> 59 #include <svx/dialmgr.hxx> 60 #include <svx/svdetc.hxx> 61 #include <svx/sdrhittesthelper.hxx> 62 63 //===== namespaces =========================================================== 64 65 using namespace ::vos; 66 using namespace ::cppu; 67 using namespace ::osl; 68 using ::rtl::OUString; 69 using namespace ::accessibility; 70 using namespace ::com::sun::star; 71 using namespace ::com::sun::star::uno; 72 using namespace ::com::sun::star::drawing; 73 using namespace ::com::sun::star::lang; 74 using namespace ::com::sun::star::accessibility; 75 76 //===== internal ============================================================ 77 78 /** initialize this component and set default values */ 79 SvxGraphCtrlAccessibleContext::SvxGraphCtrlAccessibleContext( 80 const Reference< XAccessible >& rxParent, 81 GraphCtrl& rRepr, 82 const OUString* pName, 83 const OUString* pDesc ) : 84 85 SvxGraphCtrlAccessibleContext_Base( m_aMutex ), 86 mxParent( rxParent ), 87 mpControl( &rRepr ), 88 mpModel (NULL), 89 mpPage (NULL), 90 mpView (NULL), 91 mnClientId( 0 ), 92 mbDisposed( sal_False ) 93 { 94 if (mpControl != NULL) 95 { 96 mpModel = mpControl->GetSdrModel(); 97 if (mpModel != NULL) 98 mpPage = (SdrPage*)mpModel->GetPage( 0 ); 99 mpView = mpControl->GetSdrView(); 100 101 if( mpModel == NULL || mpPage == NULL || mpView == NULL ) 102 { 103 mbDisposed = true; 104 // Set all the pointers to NULL just in case they are used as 105 // a disposed flag. 106 mpModel = NULL; 107 mpPage = NULL; 108 mpView = NULL; 109 } 110 } 111 112 if( pName ) 113 { 114 msName = *pName; 115 } 116 else 117 { 118 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 119 msName = SVX_RESSTR( RID_SVXSTR_GRAPHCTRL_ACC_NAME ); 120 } 121 122 if( pDesc ) 123 { 124 msDescription = *pDesc; 125 } 126 else 127 { 128 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 129 msDescription = SVX_RESSTR( RID_SVXSTR_GRAPHCTRL_ACC_DESCRIPTION ); 130 } 131 132 maTreeInfo.SetSdrView( mpView ); 133 maTreeInfo.SetWindow( mpControl ); 134 maTreeInfo.SetViewForwarder( const_cast<SvxGraphCtrlAccessibleContext*>(this) ); 135 } 136 137 //----------------------------------------------------------------------------- 138 139 /** on destruction, this component is disposed and all dispose listeners 140 are called, except if this component was already disposed */ 141 SvxGraphCtrlAccessibleContext::~SvxGraphCtrlAccessibleContext() 142 { 143 disposing(); 144 } 145 146 //----------------------------------------------------------------------------- 147 148 /** returns the XAccessible interface for a given SdrObject. 149 Multiple calls for the same SdrObject return the same XAccessible. 150 */ 151 Reference< XAccessible > SAL_CALL SvxGraphCtrlAccessibleContext::getAccessible( const SdrObject* pObj ) 152 { 153 Reference<XAccessible> xAccessibleShape; 154 155 if( pObj ) 156 { 157 // see if we already created an XAccessible for the given SdrObject 158 ShapesMapType::iterator iter = mxShapes.find( pObj ); 159 160 if( iter != mxShapes.end() ) 161 { 162 // if we already have one, return it 163 xAccessibleShape = (*iter).second; 164 } 165 else 166 { 167 // create a new one and remember in our internal map 168 Reference< XShape > xShape( Reference< XShape >::query( (const_cast<SdrObject*>(pObj))->getUnoShape() ) ); 169 170 AccessibleShapeInfo aShapeInfo (xShape,mxParent); 171 // Create accessible object that corresponds to the descriptor's shape. 172 AccessibleShape* pAcc = ShapeTypeHandler::Instance().CreateAccessibleObject( 173 aShapeInfo, maTreeInfo); 174 xAccessibleShape = pAcc; 175 if (pAcc != NULL) 176 { 177 pAcc->acquire(); 178 // Now that we acquired the new accessible shape we can 179 // safely call its Init() method. 180 pAcc->Init (); 181 } 182 mxShapes[pObj] = pAcc; 183 184 // Create event and inform listeners of the object creation. 185 CommitChange( AccessibleEventId::CHILD, makeAny( xAccessibleShape ), makeAny( Reference<XAccessible>() ) ); 186 } 187 } 188 189 return xAccessibleShape; 190 } 191 192 //===== XAccessible ========================================================= 193 194 Reference< XAccessibleContext > SAL_CALL SvxGraphCtrlAccessibleContext::getAccessibleContext( void ) throw( RuntimeException ) 195 { 196 return this; 197 } 198 199 //===== XAccessibleComponent ================================================ 200 201 sal_Bool SAL_CALL SvxGraphCtrlAccessibleContext::containsPoint( const awt::Point& rPoint ) throw( RuntimeException ) 202 { 203 // no guard -> done in getSize() 204 awt::Size aSize (getSize()); 205 return (rPoint.X >= 0) 206 && (rPoint.X < aSize.Width) 207 && (rPoint.Y >= 0) 208 && (rPoint.Y < aSize.Height); 209 } 210 211 //----------------------------------------------------------------------------- 212 213 Reference< XAccessible > SAL_CALL SvxGraphCtrlAccessibleContext::getAccessibleAtPoint( const awt::Point& rPoint ) throw( RuntimeException ) 214 { 215 ::osl::MutexGuard aGuard( m_aMutex ); 216 217 Reference< XAccessible > xAccessible; 218 219 if( mpControl ) 220 { 221 Point aPnt( rPoint.X, rPoint.Y ); 222 mpControl->PixelToLogic( aPnt ); 223 224 SdrObject* pObj = 0; 225 226 if(mpView && mpView->GetSdrPageView()) 227 { 228 pObj = SdrObjListPrimitiveHit(*mpPage, aPnt, 1, *mpView->GetSdrPageView(), 0, false); 229 } 230 231 if( pObj ) 232 xAccessible = getAccessible( pObj ); 233 } 234 else 235 { 236 throw DisposedException(); 237 } 238 239 return xAccessible; 240 } 241 242 //----------------------------------------------------------------------------- 243 244 awt::Rectangle SAL_CALL SvxGraphCtrlAccessibleContext::getBounds() throw( RuntimeException ) 245 { 246 // no guard -> done in GetBoundingBox() 247 Rectangle aCoreBounds( GetBoundingBox() ); 248 awt::Rectangle aBounds; 249 aBounds.X = aCoreBounds.getX(); 250 aBounds.Y = aCoreBounds.getY(); 251 aBounds.Width = aCoreBounds.getWidth(); 252 aBounds.Height = aCoreBounds.getHeight(); 253 return aBounds; 254 } 255 256 //----------------------------------------------------------------------------- 257 258 awt::Point SAL_CALL SvxGraphCtrlAccessibleContext::getLocation() throw( RuntimeException ) 259 { 260 // no guard -> done in GetBoundingBox() 261 Rectangle aRect( GetBoundingBox() ); 262 return awt::Point( aRect.getX(), aRect.getY() ); 263 } 264 265 //----------------------------------------------------------------------------- 266 267 awt::Point SAL_CALL SvxGraphCtrlAccessibleContext::getLocationOnScreen() throw( RuntimeException ) 268 { 269 // no guard -> done in GetBoundingBoxOnScreen() 270 Rectangle aRect( GetBoundingBoxOnScreen() ); 271 return awt::Point( aRect.getX(), aRect.getY() ); 272 } 273 274 //----------------------------------------------------------------------------- 275 276 awt::Size SAL_CALL SvxGraphCtrlAccessibleContext::getSize() throw( RuntimeException ) 277 { 278 // no guard -> done in GetBoundingBox() 279 Rectangle aRect( GetBoundingBox() ); 280 return awt::Size( aRect.getWidth(), aRect.getHeight() ); 281 } 282 283 284 //===== XAccessibleContext ================================================== 285 286 sal_Int32 SAL_CALL SvxGraphCtrlAccessibleContext::getAccessibleChildCount( void ) throw( RuntimeException ) 287 { 288 OGuard aGuard( Application::GetSolarMutex() ); 289 290 if( NULL == mpPage ) 291 throw DisposedException(); 292 293 return mpPage->GetObjCount(); 294 } 295 296 //----------------------------------------------------------------------------- 297 298 /** returns the SdrObject at index nIndex from the model of this graph */ 299 SdrObject* SvxGraphCtrlAccessibleContext::getSdrObject( sal_Int32 nIndex ) 300 throw( RuntimeException, lang::IndexOutOfBoundsException ) 301 { 302 OGuard aGuard( Application::GetSolarMutex() ); 303 304 if( NULL == mpPage ) 305 throw DisposedException(); 306 307 if( (nIndex < 0) || ( static_cast<sal_uInt32>(nIndex) >= mpPage->GetObjCount() ) ) 308 throw lang::IndexOutOfBoundsException(); 309 310 return mpPage->GetObj( nIndex ); 311 } 312 313 //----------------------------------------------------------------------------- 314 315 /** sends an AccessibleEventObject to all added XAccessibleEventListeners */ 316 void SvxGraphCtrlAccessibleContext::CommitChange ( 317 sal_Int16 nEventId, 318 const uno::Any& rNewValue, 319 const uno::Any& rOldValue) 320 { 321 AccessibleEventObject aEvent ( 322 static_cast<uno::XWeak*>(this), 323 nEventId, 324 rNewValue, 325 rOldValue); 326 327 FireEvent (aEvent); 328 } 329 330 /** sends an AccessibleEventObject to all added XAccessibleEventListeners */ 331 void SvxGraphCtrlAccessibleContext::FireEvent (const AccessibleEventObject& aEvent) 332 { 333 if (mnClientId) 334 comphelper::AccessibleEventNotifier::addEvent( mnClientId, aEvent ); 335 } 336 337 //----------------------------------------------------------------------------- 338 339 Reference< XAccessible > SAL_CALL SvxGraphCtrlAccessibleContext::getAccessibleChild( sal_Int32 nIndex ) 340 throw( RuntimeException, lang::IndexOutOfBoundsException ) 341 { 342 OGuard aGuard( Application::GetSolarMutex() ); 343 344 return getAccessible( getSdrObject( nIndex ) ); 345 } 346 347 //----------------------------------------------------------------------------- 348 349 Reference< XAccessible > SAL_CALL SvxGraphCtrlAccessibleContext::getAccessibleParent( void ) throw( RuntimeException ) 350 { 351 return mxParent; 352 } 353 354 //----------------------------------------------------------------------------- 355 356 sal_Int32 SAL_CALL SvxGraphCtrlAccessibleContext::getAccessibleIndexInParent( void ) throw( RuntimeException ) 357 { 358 OGuard aGuard( Application::GetSolarMutex() ); 359 // Use a simple but slow solution for now. Optimize later. 360 361 // Iterate over all the parent's children and search for this object. 362 if( mxParent.is() ) 363 { 364 Reference< XAccessibleContext > xParentContext( mxParent->getAccessibleContext() ); 365 if( xParentContext.is() ) 366 { 367 sal_Int32 nChildCount = xParentContext->getAccessibleChildCount(); 368 for( sal_Int32 i = 0 ; i < nChildCount ; ++i ) 369 { 370 Reference< XAccessible > xChild( xParentContext->getAccessibleChild( i ) ); 371 if( xChild.is() ) 372 { 373 Reference< XAccessibleContext > xChildContext = xChild->getAccessibleContext(); 374 if( xChildContext == ( XAccessibleContext* ) this ) 375 return i; 376 } 377 } 378 } 379 } 380 381 // Return -1 to indicate that this object's parent does not know about the 382 // object. 383 return -1; 384 } 385 386 //----------------------------------------------------------------------------- 387 388 sal_Int16 SAL_CALL SvxGraphCtrlAccessibleContext::getAccessibleRole( void ) throw( RuntimeException ) 389 { 390 return AccessibleRole::PANEL; 391 } 392 393 //----------------------------------------------------------------------------- 394 395 OUString SAL_CALL SvxGraphCtrlAccessibleContext::getAccessibleDescription( void ) throw( RuntimeException ) 396 { 397 OGuard aGuard( Application::GetSolarMutex() ); 398 return msDescription; 399 } 400 401 //----------------------------------------------------------------------------- 402 403 OUString SAL_CALL SvxGraphCtrlAccessibleContext::getAccessibleName( void ) throw( RuntimeException ) 404 { 405 OGuard aGuard( Application::GetSolarMutex() ); 406 return msName; 407 } 408 409 //----------------------------------------------------------------------------- 410 411 /** Return empty reference to indicate that the relation set is not 412 supported. 413 */ 414 Reference< XAccessibleRelationSet > SAL_CALL SvxGraphCtrlAccessibleContext::getAccessibleRelationSet( void ) throw( RuntimeException ) 415 { 416 return Reference< XAccessibleRelationSet >(); 417 } 418 419 //----------------------------------------------------------------------------- 420 421 Reference< XAccessibleStateSet > SAL_CALL SvxGraphCtrlAccessibleContext::getAccessibleStateSet( void ) throw( RuntimeException ) 422 { 423 OGuard aGuard( Application::GetSolarMutex() ); 424 425 utl::AccessibleStateSetHelper* pStateSetHelper = new utl::AccessibleStateSetHelper; 426 427 if ( rBHelper.bDisposed || mbDisposed ) 428 { 429 pStateSetHelper->AddState( AccessibleStateType::DEFUNC ); 430 } 431 else 432 { 433 // pStateSetHelper->AddState( AccessibleStateType::ENABLED ); 434 // pStateSetHelper->AddState( AccessibleStateType::SENSITIVE ); 435 pStateSetHelper->AddState( AccessibleStateType::FOCUSABLE ); 436 if( mpControl->HasFocus() ) 437 pStateSetHelper->AddState( AccessibleStateType::FOCUSED ); 438 pStateSetHelper->AddState( AccessibleStateType::OPAQUE ); 439 pStateSetHelper->AddState( AccessibleStateType::SHOWING ); 440 pStateSetHelper->AddState( AccessibleStateType::VISIBLE ); 441 } 442 443 return pStateSetHelper; 444 } 445 446 //----------------------------------------------------------------------------- 447 448 lang::Locale SAL_CALL SvxGraphCtrlAccessibleContext::getLocale( void ) throw( IllegalAccessibleComponentStateException, RuntimeException ) 449 { 450 OGuard aGuard( Application::GetSolarMutex() ); 451 452 if( mxParent.is() ) 453 { 454 Reference< XAccessibleContext > xParentContext( mxParent->getAccessibleContext() ); 455 if( xParentContext.is() ) 456 return xParentContext->getLocale(); 457 } 458 459 // No parent. Therefore throw exception to indicate this cluelessness. 460 throw IllegalAccessibleComponentStateException(); 461 } 462 463 //===== XAccessibleEventListener ============================================ 464 465 void SAL_CALL SvxGraphCtrlAccessibleContext::addEventListener( const Reference< XAccessibleEventListener >& xListener ) 466 throw( RuntimeException ) 467 { 468 if (xListener.is()) 469 { 470 OGuard aGuard( Application::GetSolarMutex() ); 471 if (!mnClientId) 472 mnClientId = comphelper::AccessibleEventNotifier::registerClient( ); 473 comphelper::AccessibleEventNotifier::addEventListener( mnClientId, xListener ); 474 } 475 } 476 477 //----------------------------------------------------------------------------- 478 479 void SAL_CALL SvxGraphCtrlAccessibleContext::removeEventListener( const Reference< XAccessibleEventListener >& xListener ) 480 throw( RuntimeException ) 481 { 482 if (xListener.is()) 483 { 484 OGuard aGuard( Application::GetSolarMutex() ); 485 486 sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( mnClientId, xListener ); 487 if ( !nListenerCount ) 488 { 489 // no listeners anymore 490 // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client), 491 // and at least to us not firing any events anymore, in case somebody calls 492 // NotifyAccessibleEvent, again 493 comphelper::AccessibleEventNotifier::revokeClient( mnClientId ); 494 mnClientId = 0; 495 } 496 } 497 } 498 499 //----------------------------------------------------------------------------- 500 501 void SAL_CALL SvxGraphCtrlAccessibleContext::addFocusListener( const Reference< awt::XFocusListener >& xListener ) 502 throw( RuntimeException ) 503 { 504 OGuard aGuard( Application::GetSolarMutex() ); 505 506 if( xListener.is() ) 507 { 508 Reference< ::com::sun::star::awt::XWindow > xWindow( VCLUnoHelper::GetInterface( mpControl ) ); 509 if( xWindow.is() ) 510 xWindow->addFocusListener( xListener ); 511 } 512 } 513 514 //----------------------------------------------------------------------------- 515 516 void SAL_CALL SvxGraphCtrlAccessibleContext::removeFocusListener( const Reference< awt::XFocusListener >& xListener ) 517 throw (RuntimeException) 518 { 519 OGuard aGuard( Application::GetSolarMutex() ); 520 521 if( xListener.is() ) 522 { 523 Reference< ::com::sun::star::awt::XWindow > xWindow = VCLUnoHelper::GetInterface( mpControl ); 524 if( xWindow.is() ) 525 xWindow->removeFocusListener( xListener ); 526 } 527 } 528 529 //----------------------------------------------------------------------------- 530 531 void SAL_CALL SvxGraphCtrlAccessibleContext::grabFocus() throw( RuntimeException ) 532 { 533 OGuard aGuard( Application::GetSolarMutex() ); 534 535 if( NULL == mpControl ) 536 throw DisposedException(); 537 538 mpControl->GrabFocus(); 539 } 540 541 //----------------------------------------------------------------------------- 542 543 Any SAL_CALL SvxGraphCtrlAccessibleContext::getAccessibleKeyBinding() throw( RuntimeException ) 544 { 545 // here is no implementation, because here are no KeyBindings for every object 546 return Any(); 547 } 548 549 550 551 552 553 sal_Int32 SAL_CALL SvxGraphCtrlAccessibleContext::getForeground (void) 554 throw (::com::sun::star::uno::RuntimeException) 555 { 556 svtools::ColorConfig aColorConfig; 557 sal_uInt32 nColor = aColorConfig.GetColorValue( svtools::FONTCOLOR ).nColor; 558 return static_cast<sal_Int32>(nColor); 559 } 560 561 562 563 564 sal_Int32 SAL_CALL SvxGraphCtrlAccessibleContext::getBackground (void) 565 throw (::com::sun::star::uno::RuntimeException) 566 { 567 sal_uInt32 nColor = Application::GetSettings().GetStyleSettings().GetWindowColor().GetColor(); 568 return static_cast<sal_Int32>(nColor); 569 } 570 571 572 //===== XServiceInfo ======================================================== 573 574 OUString SAL_CALL SvxGraphCtrlAccessibleContext::getImplementationName( void ) throw( RuntimeException ) 575 { 576 return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.ui.SvxGraphCtrlAccessibleContext" ) ); 577 } 578 579 //----------------------------------------------------------------------------- 580 581 sal_Bool SAL_CALL SvxGraphCtrlAccessibleContext::supportsService( const OUString& sServiceName ) throw( RuntimeException ) 582 { 583 OGuard aGuard( Application::GetSolarMutex() ); 584 // Iterate over all supported service names and return true if on of them 585 // matches the given name. 586 Sequence< OUString > aSupportedServices( getSupportedServiceNames() ); 587 int nLenght = aSupportedServices.getLength(); 588 589 for( int i = 0 ; i < nLenght ; ++i ) 590 { 591 if( sServiceName == aSupportedServices[ i ] ) 592 return sal_True; 593 } 594 595 return sal_False; 596 } 597 598 //----------------------------------------------------------------------------- 599 600 Sequence< OUString > SAL_CALL SvxGraphCtrlAccessibleContext::getSupportedServiceNames( void ) throw( RuntimeException ) 601 { 602 Sequence< OUString > aSNs( 3 ); 603 604 aSNs[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.accessibility.Accessible" ) ); 605 aSNs[1] = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.accessibility.AccessibleContext" ) ); 606 aSNs[2] = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.AccessibleGraphControl" ) ); 607 608 return aSNs; 609 } 610 611 //===== XTypeProvider ======================================================= 612 613 Sequence<sal_Int8> SAL_CALL SvxGraphCtrlAccessibleContext::getImplementationId( void ) throw( RuntimeException ) 614 { 615 OGuard aGuard( Application::GetSolarMutex() ); 616 return getUniqueId(); 617 } 618 619 //===== XServiceName ======================================================== 620 621 OUString SvxGraphCtrlAccessibleContext::getServiceName( void ) throw( RuntimeException ) 622 { 623 return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.accessibility.AccessibleContext" ) ); 624 } 625 626 //===== XAccessibleSelection ============================================= 627 628 void SAL_CALL SvxGraphCtrlAccessibleContext::selectAccessibleChild( sal_Int32 nIndex ) throw( lang::IndexOutOfBoundsException, RuntimeException ) 629 { 630 OGuard aGuard( Application::GetSolarMutex() ); 631 632 if( NULL == mpView ) 633 throw DisposedException(); 634 635 SdrObject* pObj = getSdrObject( nIndex ); 636 637 if( pObj ) 638 mpView->MarkObj( pObj, mpView->GetSdrPageView()); 639 } 640 641 //----------------------------------------------------------------------------- 642 643 sal_Bool SAL_CALL SvxGraphCtrlAccessibleContext::isAccessibleChildSelected( sal_Int32 nIndex ) throw( lang::IndexOutOfBoundsException, RuntimeException ) 644 { 645 OGuard aGuard( Application::GetSolarMutex() ); 646 647 if( NULL == mpView ) 648 throw DisposedException(); 649 650 return mpView->IsObjMarked( getSdrObject( nIndex ) ); 651 } 652 653 //----------------------------------------------------------------------------- 654 655 void SAL_CALL SvxGraphCtrlAccessibleContext::clearAccessibleSelection() throw( RuntimeException ) 656 { 657 OGuard aGuard( Application::GetSolarMutex() ); 658 659 if( NULL == mpView ) 660 throw DisposedException(); 661 662 mpView->UnmarkAllObj(); 663 } 664 665 //----------------------------------------------------------------------------- 666 667 void SAL_CALL SvxGraphCtrlAccessibleContext::selectAllAccessibleChildren() throw( RuntimeException ) 668 { 669 OGuard aGuard( Application::GetSolarMutex() ); 670 671 if( NULL == mpView ) 672 throw DisposedException(); 673 674 mpView->MarkAllObj(); 675 } 676 677 //----------------------------------------------------------------------------- 678 679 sal_Int32 SAL_CALL SvxGraphCtrlAccessibleContext::getSelectedAccessibleChildCount() throw( RuntimeException ) 680 { 681 OGuard aGuard( Application::GetSolarMutex() ); 682 683 if( NULL == mpView ) 684 throw DisposedException(); 685 686 const SdrMarkList& rList = mpView->GetMarkedObjectList(); 687 return rList.GetMarkCount(); 688 } 689 690 //----------------------------------------------------------------------------- 691 692 Reference< XAccessible > SAL_CALL SvxGraphCtrlAccessibleContext::getSelectedAccessibleChild( sal_Int32 nIndex ) 693 throw( lang::IndexOutOfBoundsException, RuntimeException ) 694 { 695 OGuard aGuard( Application::GetSolarMutex() ); 696 697 checkChildIndexOnSelection( nIndex ); 698 699 Reference< XAccessible > xAccessible; 700 701 const SdrMarkList& rList = mpView->GetMarkedObjectList(); 702 SdrObject* pObj = rList.GetMark(nIndex)->GetMarkedSdrObj(); 703 if( pObj ) 704 xAccessible = getAccessible( pObj ); 705 706 return xAccessible; 707 } 708 709 //----------------------------------------------------------------------------- 710 711 void SAL_CALL SvxGraphCtrlAccessibleContext::deselectAccessibleChild( sal_Int32 nIndex ) throw( lang::IndexOutOfBoundsException, RuntimeException ) 712 { 713 OGuard aGuard( Application::GetSolarMutex() ); 714 715 checkChildIndexOnSelection( nIndex ); 716 717 if( mpView ) 718 { 719 const SdrMarkList& rList = mpView->GetMarkedObjectList(); 720 721 SdrObject* pObj = getSdrObject( nIndex ); 722 if( pObj ) 723 { 724 SdrMarkList aRefList( rList ); 725 726 SdrPageView* pPV = mpView->GetSdrPageView(); 727 mpView->UnmarkAllObj( pPV ); 728 729 sal_uInt32 nCount = aRefList.GetMarkCount(); 730 sal_uInt32 nMark; 731 for( nMark = 0; nMark < nCount; nMark++ ) 732 { 733 if( aRefList.GetMark(nMark)->GetMarkedSdrObj() != pObj ) 734 mpView->MarkObj( aRefList.GetMark(nMark)->GetMarkedSdrObj(), pPV ); 735 } 736 } 737 } 738 } 739 740 //===== internals ======================================================== 741 742 void SvxGraphCtrlAccessibleContext::checkChildIndex( long nIndex ) throw( lang::IndexOutOfBoundsException ) 743 { 744 if( nIndex < 0 || nIndex >= getAccessibleChildCount() ) 745 throw lang::IndexOutOfBoundsException(); 746 } 747 748 //----------------------------------------------------------------------------- 749 750 void SvxGraphCtrlAccessibleContext::checkChildIndexOnSelection( long nIndex ) throw( lang::IndexOutOfBoundsException ) 751 { 752 if( nIndex < 0 || nIndex >= getSelectedAccessibleChildCount() ) 753 throw lang::IndexOutOfBoundsException(); 754 } 755 756 //----------------------------------------------------------------------------- 757 758 void SvxGraphCtrlAccessibleContext::setName( const OUString& rName ) 759 { 760 OGuard aGuard( Application::GetSolarMutex() ); 761 762 msName = rName; 763 } 764 765 //----------------------------------------------------------------------------- 766 767 void SvxGraphCtrlAccessibleContext::setDescription( const OUString& rDescr ) 768 { 769 OGuard aGuard( Application::GetSolarMutex() ); 770 771 msDescription = rDescr; 772 } 773 774 775 776 777 /** Replace the model, page, and view pointers by the ones provided 778 (explicitly and implicitly). 779 */ 780 void SvxGraphCtrlAccessibleContext::setModelAndView ( 781 SdrModel* pModel, 782 SdrView* pView) 783 { 784 OGuard aGuard (Application::GetSolarMutex()); 785 786 mpModel = pModel; 787 if (mpModel != NULL) 788 mpPage = (SdrPage*)mpModel->GetPage( 0 ); 789 mpView = pView; 790 791 if (mpModel == NULL || mpPage == NULL || mpView == NULL) 792 { 793 mbDisposed = true; 794 795 // Set all the pointers to NULL just in case they are used as 796 // a disposed flag. 797 mpModel = NULL; 798 mpPage = NULL; 799 mpView = NULL; 800 } 801 802 maTreeInfo.SetSdrView (mpView); 803 } 804 805 806 807 //----------------------------------------------------------------------------- 808 809 void SAL_CALL SvxGraphCtrlAccessibleContext::disposing() 810 { 811 OGuard aGuard( Application::GetSolarMutex() ); 812 813 if( mbDisposed ) 814 return; 815 816 mbDisposed = sal_True; 817 818 mpControl = NULL; // object dies with representation 819 mpView = NULL; 820 mpPage = NULL; 821 822 { 823 ShapesMapType::iterator I; 824 825 for (I=mxShapes.begin(); I!=mxShapes.end(); I++) 826 { 827 XAccessible* pAcc = (*I).second; 828 Reference< XComponent > xComp( pAcc, UNO_QUERY ); 829 if( xComp.is() ) 830 xComp->dispose(); 831 832 (*I).second->release(); 833 } 834 835 mxShapes.clear(); 836 } 837 838 // Send a disposing to all listeners. 839 if ( mnClientId ) 840 { 841 comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( mnClientId, *this ); 842 mnClientId = 0; 843 } 844 } 845 846 //----------------------------------------------------------------------------- 847 848 Rectangle SvxGraphCtrlAccessibleContext::GetBoundingBoxOnScreen( void ) throw( RuntimeException ) 849 { 850 OGuard aGuard( Application::GetSolarMutex() ); 851 852 if( NULL == mpControl ) 853 throw DisposedException(); 854 855 return Rectangle( 856 mpControl->GetAccessibleParentWindow()->OutputToAbsoluteScreenPixel( 857 mpControl->GetPosPixel() ), 858 mpControl->GetSizePixel() ); 859 } 860 861 //----------------------------------------------------------------------------- 862 863 /** Calculate the relative coordinates of the bounding box as difference 864 between the absolute coordinates of the bounding boxes of this control 865 and its parent in the accessibility tree. 866 */ 867 Rectangle SvxGraphCtrlAccessibleContext::GetBoundingBox( void ) throw( RuntimeException ) 868 { 869 OGuard aGuard( Application::GetSolarMutex() ); 870 871 Rectangle aBounds ( 0, 0, 0, 0 ); 872 873 Window* pWindow = mpControl; 874 if (pWindow != NULL) 875 { 876 aBounds = pWindow->GetWindowExtentsRelative (NULL); 877 Window* pParent = pWindow->GetAccessibleParentWindow(); 878 if (pParent != NULL) 879 { 880 Rectangle aParentRect = pParent->GetWindowExtentsRelative (NULL); 881 aBounds -= aParentRect.TopLeft(); 882 } 883 } 884 else 885 throw DisposedException(); 886 887 return aBounds; 888 } 889 890 //----------------------------------------------------------------------------- 891 892 Sequence< sal_Int8 > SvxGraphCtrlAccessibleContext::getUniqueId( void ) 893 { 894 // no guard because it's private -> has to guarded when using it! 895 static OImplementationId* pId = 0; 896 if( !pId ) 897 { 898 OGuard aGuard( Application::GetSolarMutex() ); 899 if( !pId) 900 { 901 static OImplementationId aId; 902 pId = &aId; 903 } 904 } 905 return pId->getImplementationId(); 906 } 907 908 //----------------------------------------------------------------------------- 909 910 void SvxGraphCtrlAccessibleContext::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint ) 911 { 912 const SdrHint* pSdrHint = PTR_CAST( SdrHint, &rHint ); 913 914 if( pSdrHint ) 915 { 916 switch( pSdrHint->GetKind() ) 917 { 918 case HINT_OBJCHG: 919 { 920 ShapesMapType::iterator iter = mxShapes.find( pSdrHint->GetObject() ); 921 922 if( iter != mxShapes.end() ) 923 { 924 // if we already have one, return it 925 AccessibleShape* pShape = (*iter).second; 926 927 if( NULL != pShape ) 928 pShape->CommitChange( AccessibleEventId::VISIBLE_DATA_CHANGED, uno::Any(), uno::Any() ); 929 } 930 } 931 break; 932 933 case HINT_OBJINSERTED: 934 CommitChange( AccessibleEventId::CHILD, makeAny( getAccessible( pSdrHint->GetObject() ) ) , uno::Any()); 935 break; 936 case HINT_OBJREMOVED: 937 CommitChange( AccessibleEventId::CHILD, uno::Any(), makeAny( getAccessible( pSdrHint->GetObject() ) ) ); 938 break; 939 case HINT_MODELCLEARED: 940 dispose(); 941 break; 942 default: 943 break; 944 } 945 } 946 else 947 { 948 const SfxSimpleHint* pSfxHint = PTR_CAST(SfxSimpleHint, &rHint ); 949 950 // ist unser SdDrawDocument gerade gestorben? 951 if(pSfxHint && pSfxHint->GetId() == SFX_HINT_DYING) 952 { 953 dispose(); 954 } 955 } 956 } 957 958 //===== IAccessibleViewforwarder ======================================== 959 960 sal_Bool SvxGraphCtrlAccessibleContext::IsValid (void) const 961 { 962 return sal_True; 963 } 964 965 //----------------------------------------------------------------------------- 966 967 Rectangle SvxGraphCtrlAccessibleContext::GetVisibleArea (void) const 968 { 969 Rectangle aVisArea; 970 971 if( mpView && mpView->PaintWindowCount()) 972 { 973 SdrPaintWindow* pPaintWindow = mpView->GetPaintWindow(0L); 974 aVisArea = pPaintWindow->GetVisibleArea(); 975 } 976 977 return aVisArea; 978 } 979 980 //----------------------------------------------------------------------------- 981 982 Point SvxGraphCtrlAccessibleContext::LogicToPixel (const Point& rPoint) const 983 { 984 if( mpControl ) 985 { 986 Rectangle aBBox(mpControl->GetWindowExtentsRelative(NULL)); 987 return mpControl->LogicToPixel (rPoint) + aBBox.TopLeft(); 988 } 989 else 990 { 991 return rPoint; 992 } 993 } 994 995 //----------------------------------------------------------------------------- 996 997 Size SvxGraphCtrlAccessibleContext::LogicToPixel (const Size& rSize) const 998 { 999 if( mpControl ) 1000 return mpControl->LogicToPixel (rSize); 1001 else 1002 return rSize; 1003 } 1004 1005 //----------------------------------------------------------------------------- 1006 1007 Point SvxGraphCtrlAccessibleContext::PixelToLogic (const Point& rPoint) const 1008 { 1009 if( mpControl ) 1010 return mpControl->PixelToLogic (rPoint); 1011 else 1012 return rPoint; 1013 } 1014 1015 //----------------------------------------------------------------------------- 1016 1017 Size SvxGraphCtrlAccessibleContext::PixelToLogic (const Size& rSize) const 1018 { 1019 if( mpControl ) 1020 return mpControl->PixelToLogic (rSize); 1021 else 1022 return rSize; 1023 } 1024