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