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 <svx/AccessibleShape.hxx> 27 #include "svx/DescriptionGenerator.hxx" 28 #include <svx/AccessibleShapeInfo.hxx> 29 #include <com/sun/star/view/XSelectionSupplier.hpp> 30 #include <rtl/uuid.h> 31 #ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLE_ROLE_HPP_ 32 #include <com/sun/star/accessibility/AccessibleRole.hpp> 33 #endif 34 //IAccessibility2 Implementation 2009----- 35 #ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLETEXTTYPE_HPP_ 36 #include <com/sun/star/accessibility/AccessibleTextType.hpp> 37 #endif 38 //-----IAccessibility2 Implementation 2009 39 #ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLE_STATE_TYPE_HPP_ 40 #include <com/sun/star/accessibility/AccessibleStateType.hpp> 41 #endif 42 #include <com/sun/star/beans/XPropertySet.hpp> 43 #include <com/sun/star/container/XChild.hpp> 44 #include <com/sun/star/drawing/XShapes.hpp> 45 #include <com/sun/star/drawing/XShapeDescriptor.hpp> 46 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp> 47 #include <com/sun/star/drawing/FillStyle.hpp> 48 #include <com/sun/star/text/XText.hpp> 49 #include <editeng/outlobj.hxx> 50 #include <rtl/ref.hxx> 51 #include <editeng/unoedsrc.hxx> 52 #include <svx/unoshtxt.hxx> 53 #include <svx/svdobj.hxx> 54 #include <svx/svdmodel.hxx> 55 #include "svx/unoapi.hxx" 56 #include <com/sun/star/uno/Exception.hpp> 57 #include <svx/ShapeTypeHandler.hxx> 58 #include <svx/SvxShapeTypes.hxx> 59 60 #ifndef _SVX_ACCESSIBILITY_HRC 61 #include "accessibility.hrc" 62 #endif 63 #include "svx/svdstr.hrc" 64 #include <svx/dialmgr.hxx> 65 #include <vcl/svapp.hxx> 66 #include <unotools/accessiblestatesethelper.hxx> 67 #include <svx/svdview.hxx> 68 #include "AccessibleEmptyEditSource.hxx" 69 //IAccessibility2 Implementation 2009----- 70 #include <svx/svdpage.hxx> 71 #ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLERELATIONTYPE_HPP_ 72 #include <com/sun/star/accessibility/AccessibleRelationType.hpp> 73 #endif 74 #ifndef _UTL_ACCESSIBLERELATIONSETHELPER_HXX_ 75 #include <unotools/accessiblerelationsethelper.hxx> 76 #endif 77 //-----IAccessibility2 Implementation 2009 78 using namespace ::com::sun::star; 79 using namespace ::com::sun::star::accessibility; 80 //IAccessibility2 Implementation 2009----- 81 using ::com::sun::star::lang::IndexOutOfBoundsException; 82 using ::com::sun::star::uno::RuntimeException; 83 //-----IAccessibility2 Implementation 2009 84 using ::com::sun::star::uno::Reference; 85 using ::rtl::OUString; 86 //IAccessibility2 Implementation 2009----- 87 #include <algorithm> 88 89 // #include <Accessiblehyperlink.hxx> 90 //-----IAccessibility2 Implementation 2009 91 namespace accessibility { 92 93 namespace { 94 95 OUString GetOptionalProperty ( 96 const Reference<beans::XPropertySet>& rxSet, 97 const OUString& rsPropertyName) 98 { 99 OUString sValue; 100 101 if (rxSet.is()) 102 { 103 const Reference<beans::XPropertySetInfo> xInfo (rxSet->getPropertySetInfo()); 104 if ( ! xInfo.is() || xInfo->hasPropertyByName(rsPropertyName)) 105 { 106 try 107 { 108 rxSet->getPropertyValue(rsPropertyName) >>= sValue; 109 } 110 catch (beans::UnknownPropertyException&) 111 { 112 // This exception should only be thrown when the property 113 // does not exits (of course) and the XPropertySetInfo is 114 // not available. 115 } 116 } 117 } 118 return sValue; 119 } 120 121 } // end of anonymous namespace 122 123 124 125 126 //===== internal ============================================================ 127 128 AccessibleShape::AccessibleShape ( 129 const AccessibleShapeInfo& rShapeInfo, 130 const AccessibleShapeTreeInfo& rShapeTreeInfo) 131 //IAccessibility2 Implementation 2009----- 132 : AccessibleContextBase (rShapeInfo.mxParent,AccessibleRole::SHAPE), 133 //-----IAccessibility2 Implementation 2009 134 mpChildrenManager(NULL), 135 mxShape (rShapeInfo.mxShape), 136 maShapeTreeInfo (rShapeTreeInfo), 137 mnIndex (rShapeInfo.mnIndex), 138 m_nIndexInParent(-1), 139 mpText (NULL), 140 mpParent (rShapeInfo.mpChildrenManager) 141 { 142 m_pShape = GetSdrObjectFromXShape(mxShape); 143 UpdateNameAndDescription(); 144 } 145 //IAccessibility2 Implementation 2009----- 146 AccessibleShape::AccessibleShape ( 147 const ::com::sun::star::uno::Reference< 148 ::com::sun::star::drawing::XShape>& rxShape, 149 const ::com::sun::star::uno::Reference< 150 ::com::sun::star::accessibility::XAccessible>& rxParent, 151 const AccessibleShapeTreeInfo& rShapeTreeInfo, 152 sal_Int32 nIndex) 153 : AccessibleContextBase (rxParent,AccessibleRole::SHAPE), 154 mpChildrenManager(NULL), 155 mxShape (rxShape), 156 maShapeTreeInfo (rShapeTreeInfo), 157 mnIndex (nIndex), 158 m_nIndexInParent(-1), 159 mpText (NULL), 160 mpParent (NULL) 161 { 162 m_pShape = GetSdrObjectFromXShape(mxShape); 163 } 164 //-----IAccessibility2 Implementation 2009 165 AccessibleShape::~AccessibleShape (void) 166 { 167 if (mpChildrenManager != NULL) 168 delete mpChildrenManager; 169 if (mpText != NULL) 170 delete mpText; 171 OSL_TRACE ("~AccessibleShape"); 172 173 // Unregistering from the various broadcasters should be unnecessary 174 // since this destructor would not have been called if one of the 175 // broadcasters would still hold a strong reference to this object. 176 } 177 178 179 180 181 void AccessibleShape::Init (void) 182 { 183 // Update the OPAQUE and SELECTED shape. 184 UpdateStates (); 185 186 // Create a children manager when this shape has children of its own. 187 Reference<drawing::XShapes> xShapes (mxShape, uno::UNO_QUERY); 188 if (xShapes.is() && xShapes->getCount() > 0) 189 mpChildrenManager = new ChildrenManager ( 190 this, xShapes, maShapeTreeInfo, *this); 191 if (mpChildrenManager != NULL) 192 mpChildrenManager->Update(); 193 194 // Register at model as document::XEventListener. 195 if (maShapeTreeInfo.GetModelBroadcaster().is()) 196 maShapeTreeInfo.GetModelBroadcaster()->addEventListener ( 197 static_cast<document::XEventListener*>(this)); 198 199 // Beware! Here we leave the paths of the UNO API and descend into the 200 // depths of the core. Necessary for makeing the edit engine 201 // accessible. 202 Reference<text::XText> xText (mxShape, uno::UNO_QUERY); 203 if (xText.is()) 204 { 205 SdrView* pView = maShapeTreeInfo.GetSdrView (); 206 const Window* pWindow = maShapeTreeInfo.GetWindow (); 207 if (pView != NULL && pWindow != NULL && mxShape.is()) 208 { 209 // #107948# Determine whether shape text is empty 210 SdrObject* pSdrObject = GetSdrObjectFromXShape(mxShape); 211 if( pSdrObject ) 212 { 213 SdrTextObj* pTextObj = PTR_CAST( SdrTextObj, pSdrObject ); 214 OutlinerParaObject* pOutlinerParaObject = NULL; 215 216 if( pTextObj ) 217 pOutlinerParaObject = pTextObj->GetEditOutlinerParaObject(); // Get the OutlinerParaObject if text edit is active 218 219 bool bOwnParaObj = pOutlinerParaObject != NULL; 220 221 if( !pOutlinerParaObject && pSdrObject ) 222 pOutlinerParaObject = pSdrObject->GetOutlinerParaObject(); 223 224 // create AccessibleTextHelper to handle this shape's text 225 if( !pOutlinerParaObject ) 226 { 227 // empty text -> use proxy edit source to delay creation of EditEngine 228 ::std::auto_ptr<SvxEditSource> pEditSource( new AccessibleEmptyEditSource ( *pSdrObject, *pView, *pWindow) ); 229 mpText = new AccessibleTextHelper( pEditSource ); 230 } 231 else 232 { 233 // non-empty text -> use full-fledged edit source right away 234 ::std::auto_ptr<SvxEditSource> pEditSource( new SvxTextEditSource ( *pSdrObject, 0, *pView, *pWindow) ); 235 mpText = new AccessibleTextHelper( pEditSource ); 236 } 237 238 if( bOwnParaObj ) 239 delete pOutlinerParaObject; 240 241 mpText->SetEventSource(this); 242 } 243 } 244 } 245 } 246 247 248 249 250 void AccessibleShape::UpdateStates (void) 251 { 252 ::utl::AccessibleStateSetHelper* pStateSet = 253 static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get()); 254 if (pStateSet == NULL) 255 return; 256 257 // Set the opaque state for certain shape types when their fill style is 258 // solid. 259 bool bShapeIsOpaque = false; 260 switch (ShapeTypeHandler::Instance().GetTypeId (mxShape)) 261 { 262 case DRAWING_PAGE: 263 case DRAWING_RECTANGLE: 264 case DRAWING_TEXT: 265 { 266 uno::Reference<beans::XPropertySet> xSet (mxShape, uno::UNO_QUERY); 267 if (xSet.is()) 268 { 269 try 270 { 271 drawing::FillStyle aFillStyle; 272 bShapeIsOpaque = ( xSet->getPropertyValue (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FillStyle"))) >>= aFillStyle) 273 && aFillStyle == drawing::FillStyle_SOLID; 274 } 275 catch (::com::sun::star::beans::UnknownPropertyException&) 276 { 277 // Ignore. 278 } 279 } 280 } 281 } 282 if (bShapeIsOpaque) 283 pStateSet->AddState (AccessibleStateType::OPAQUE); 284 else 285 pStateSet->RemoveState (AccessibleStateType::OPAQUE); 286 287 // Set the selected state. 288 bool bShapeIsSelected = false; 289 // XXX fix_me this has to be done with an extra interface later on 290 if ( m_pShape && maShapeTreeInfo.GetSdrView() ) 291 { 292 bShapeIsSelected = maShapeTreeInfo.GetSdrView()->IsObjMarked(m_pShape) == sal_True; 293 } 294 295 if (bShapeIsSelected) 296 pStateSet->AddState (AccessibleStateType::SELECTED); 297 else 298 pStateSet->RemoveState (AccessibleStateType::SELECTED); 299 } 300 //IAccessibility2 Implementation 2009----- 301 ::rtl::OUString AccessibleShape::GetStyle() 302 { 303 return ShapeTypeHandler::CreateAccessibleBaseName( mxShape ); 304 } 305 306 //-----IAccessibility2 Implementation 2009 307 bool AccessibleShape::operator== (const AccessibleShape& rShape) 308 { 309 return this==&rShape; 310 } 311 312 313 314 315 sal_Bool AccessibleShape::SetState (sal_Int16 aState) 316 { 317 sal_Bool bStateHasChanged = sal_False; 318 319 if (aState == AccessibleStateType::FOCUSED && mpText != NULL) 320 { 321 // Offer FOCUSED state to edit engine and detect whether the state 322 // changes. 323 sal_Bool bIsFocused = mpText->HaveFocus (); 324 mpText->SetFocus (sal_True); 325 bStateHasChanged = (bIsFocused != mpText->HaveFocus ()); 326 } 327 else 328 bStateHasChanged = AccessibleContextBase::SetState (aState); 329 330 return bStateHasChanged; 331 } 332 333 334 335 336 sal_Bool AccessibleShape::ResetState (sal_Int16 aState) 337 { 338 sal_Bool bStateHasChanged = sal_False; 339 340 if (aState == AccessibleStateType::FOCUSED && mpText != NULL) 341 { 342 // Try to remove FOCUSED state from the edit engine and detect 343 // whether the state changes. 344 sal_Bool bIsFocused = mpText->HaveFocus (); 345 mpText->SetFocus (sal_False); 346 bStateHasChanged = (bIsFocused != mpText->HaveFocus ()); 347 } 348 else 349 bStateHasChanged = AccessibleContextBase::ResetState (aState); 350 351 return bStateHasChanged; 352 } 353 354 355 356 357 sal_Bool AccessibleShape::GetState (sal_Int16 aState) 358 { 359 if (aState == AccessibleStateType::FOCUSED && mpText != NULL) 360 { 361 // Just delegate the call to the edit engine. The state is not 362 // merged into the state set. 363 return mpText->HaveFocus(); 364 } 365 else 366 return AccessibleContextBase::GetState (aState); 367 } 368 //IAccessibility2 Implementation 2009----- 369 // Solution: OverWrite the parent's getAccessibleName method 370 ::rtl::OUString SAL_CALL AccessibleShape::getAccessibleName (void) 371 throw (::com::sun::star::uno::RuntimeException) 372 { 373 ThrowIfDisposed (); 374 if( m_pShape && m_pShape->GetTitle().Len() > 0) 375 return CreateAccessibleName() + ::rtl::OUString(' ') + m_pShape->GetTitle(); 376 else 377 return CreateAccessibleName(); 378 } 379 380 ::rtl::OUString SAL_CALL AccessibleShape::getAccessibleDescription (void) 381 throw (::com::sun::star::uno::RuntimeException) 382 { 383 ThrowIfDisposed (); 384 if( m_pShape && m_pShape->GetDescription().Len() > 0) 385 return m_pShape->GetDescription() ; 386 else 387 return OUString( RTL_CONSTASCII_USTRINGPARAM( " " )); 388 } 389 //-----IAccessibility2 Implementation 2009 390 //===== XAccessibleContext ================================================== 391 392 /** The children of this shape come from two sources: The children from 393 group or scene shapes and the paragraphs of text. 394 */ 395 sal_Int32 SAL_CALL 396 AccessibleShape::getAccessibleChildCount () 397 throw (::com::sun::star::uno::RuntimeException) 398 { 399 ThrowIfDisposed (); 400 sal_Int32 nChildCount = 0; 401 402 // Add the number of shapes that are children of this shape. 403 if (mpChildrenManager != NULL) 404 nChildCount += mpChildrenManager->GetChildCount (); 405 // Add the number text paragraphs. 406 if (mpText != NULL) 407 nChildCount += mpText->GetChildCount (); 408 409 return nChildCount; 410 } 411 412 413 414 415 /** Forward the request to the shape. Return the requested shape or throw 416 an exception for a wrong index. 417 */ 418 uno::Reference<XAccessible> SAL_CALL 419 AccessibleShape::getAccessibleChild (sal_Int32 nIndex) 420 throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) 421 { 422 ThrowIfDisposed (); 423 424 uno::Reference<XAccessible> xChild; 425 426 // Depending on the index decide whether to delegate this call to the 427 // children manager or the edit engine. 428 if ((mpChildrenManager != NULL) 429 && (nIndex < mpChildrenManager->GetChildCount())) 430 { 431 xChild = mpChildrenManager->GetChild (nIndex); 432 } 433 else if (mpText != NULL) 434 { 435 sal_Int32 nI = nIndex; 436 if (mpChildrenManager != NULL) 437 nI -= mpChildrenManager->GetChildCount(); 438 xChild = mpText->GetChild (nI); 439 } 440 else 441 throw lang::IndexOutOfBoundsException ( 442 ::rtl::OUString::createFromAscii ("shape has no child with index ") 443 + rtl::OUString::valueOf(nIndex), 444 static_cast<uno::XWeak*>(this)); 445 446 return xChild; 447 } 448 449 //IAccessibility2 Implementation 2009----- 450 uno::Reference<XAccessibleRelationSet> SAL_CALL 451 AccessibleShape::getAccessibleRelationSet (void) 452 throw (::com::sun::star::uno::RuntimeException) 453 { 454 ::osl::MutexGuard aGuard (maMutex); 455 ::utl::AccessibleRelationSetHelper* pRelationSet = 456 new utl::AccessibleRelationSetHelper; 457 SdrObject* pCaptionSdr = const_cast < SdrObject* > ( m_pShape->GetCaptionObj() ) ; 458 if(pCaptionSdr!=NULL) 459 { 460 uno::Sequence< uno::Reference< uno::XInterface > > aSequence(1); 461 uno::Reference<drawing::XShape> xCaptionShape ( pCaptionSdr->getUnoShape(),uno::UNO_QUERY); 462 if(xCaptionShape.is()) 463 { 464 aSequence[0] = mpParent->GetAccessibleCaption(xCaptionShape); 465 pRelationSet->AddRelation( AccessibleRelation( AccessibleRelationType::DESCRIBED_BY, aSequence ) ); 466 } 467 } 468 else 469 { 470 //this mxshape is the captioned shape, only for sw 471 if(mpParent->GetAccessibleCaption(mxShape).get()) 472 { 473 uno::Sequence< uno::Reference< uno::XInterface > > aSequence(1); 474 aSequence[0] = mpParent->GetAccessibleCaption(mxShape); 475 pRelationSet->AddRelation( AccessibleRelation( AccessibleRelationType::DESCRIBED_BY, aSequence ) ); 476 } 477 } 478 if (pRelationSet != NULL) 479 { 480 return uno::Reference<XAccessibleRelationSet> ( 481 new ::utl::AccessibleRelationSetHelper (*pRelationSet)); 482 } 483 else 484 return uno::Reference<XAccessibleRelationSet>(NULL); 485 return uno::Reference<XAccessibleRelationSet>(); 486 } 487 //-----IAccessibility2 Implementation 2009 488 489 /** Return a copy of the state set. 490 Possible states are: 491 ENABLED 492 SHOWING 493 VISIBLE 494 */ 495 uno::Reference<XAccessibleStateSet> SAL_CALL 496 AccessibleShape::getAccessibleStateSet (void) 497 throw (::com::sun::star::uno::RuntimeException) 498 { 499 ::osl::MutexGuard aGuard (maMutex); 500 Reference<XAccessibleStateSet> xStateSet; 501 502 if (rBHelper.bDisposed || mpText == NULL) 503 // Return a minimal state set that only contains the DEFUNC state. 504 //IAccessibility2 Implementation 2009----- 505 //xStateSet = AccessibleContextBase::getAccessibleStateSet (); 506 { 507 xStateSet = AccessibleContextBase::getAccessibleStateSet (); 508 ::utl::AccessibleStateSetHelper* pStateSet = 509 static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get()); 510 ::com::sun::star::uno::Reference<XAccessible> xTempAcc = getAccessibleParent(); 511 if( xTempAcc.is() ) 512 { 513 ::com::sun::star::uno::Reference<XAccessibleContext> 514 xTempAccContext = xTempAcc->getAccessibleContext(); 515 if( xTempAccContext.is() ) 516 { 517 ::com::sun::star::uno::Reference<XAccessibleStateSet> rState = 518 xTempAccContext->getAccessibleStateSet(); 519 if( rState.is() ) { 520 com::sun::star::uno::Sequence<short> pStates = rState->getStates(); 521 int count = pStates.getLength(); 522 for( int iIndex = 0;iIndex < count;iIndex++ ) 523 { 524 if( pStates[iIndex] == AccessibleStateType::EDITABLE ) 525 { 526 pStateSet->AddState (AccessibleStateType::EDITABLE); 527 pStateSet->AddState (AccessibleStateType::RESIZABLE); 528 pStateSet->AddState (AccessibleStateType::MOVEABLE); 529 break; 530 } 531 } 532 } 533 } 534 } 535 xStateSet = Reference<XAccessibleStateSet>( 536 new ::utl::AccessibleStateSetHelper (*pStateSet)); 537 //-----IAccessibility2 Implementation 2009 538 }else 539 { 540 ::utl::AccessibleStateSetHelper* pStateSet = 541 static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get()); 542 543 if (pStateSet != NULL) 544 { 545 // Merge current FOCUSED state from edit engine. 546 if (mpText != NULL) 547 { 548 if (mpText->HaveFocus()) 549 pStateSet->AddState (AccessibleStateType::FOCUSED); 550 else 551 pStateSet->RemoveState (AccessibleStateType::FOCUSED); 552 } 553 //IAccessibility2 Implementation 2009----- 554 //Solution:Just when the document is not read-only,set states EDITABLE,RESIZABLE,MOVEABLE 555 ::com::sun::star::uno::Reference<XAccessible> xTempAcc = getAccessibleParent(); 556 if( xTempAcc.is() ) 557 { 558 ::com::sun::star::uno::Reference<XAccessibleContext> 559 xTempAccContext = xTempAcc->getAccessibleContext(); 560 if( xTempAccContext.is() ) 561 { 562 ::com::sun::star::uno::Reference<XAccessibleStateSet> rState = 563 xTempAccContext->getAccessibleStateSet(); 564 if( rState.is() ) { 565 com::sun::star::uno::Sequence<short> pStates = rState->getStates(); 566 int count = pStates.getLength(); 567 for( int iIndex = 0;iIndex < count;iIndex++ ) 568 { 569 if( pStates[iIndex] == AccessibleStateType::EDITABLE ) 570 { 571 pStateSet->AddState (AccessibleStateType::EDITABLE); 572 pStateSet->AddState (AccessibleStateType::RESIZABLE); 573 pStateSet->AddState (AccessibleStateType::MOVEABLE); 574 break; 575 } 576 } 577 } 578 } 579 } 580 //-----IAccessibility2 Implementation 2009 581 // Create a copy of the state set that may be modified by the 582 // caller without affecting the current state set. 583 xStateSet = Reference<XAccessibleStateSet>( 584 new ::utl::AccessibleStateSetHelper (*pStateSet)); 585 } 586 } 587 //IAccessibility2 Implementation 2009----- 588 UpdateDocumentAllSelState(xStateSet); 589 //-----IAccessibility2 Implementation 2009 590 return xStateSet; 591 } 592 593 594 595 596 //===== XAccessibleComponent ================================================ 597 598 /** The implementation below is at the moment straightforward. It iterates 599 over all children (and thereby instances all children which have not 600 been already instatiated) until a child covering the specifed point is 601 found. 602 This leaves room for improvement. For instance, first iterate only over 603 the already instantiated children and only if no match is found 604 instantiate the remaining ones. 605 */ 606 uno::Reference<XAccessible > SAL_CALL 607 AccessibleShape::getAccessibleAtPoint ( 608 const awt::Point& aPoint) 609 throw (uno::RuntimeException) 610 { 611 ::osl::MutexGuard aGuard (maMutex); 612 613 sal_Int32 nChildCount = getAccessibleChildCount (); 614 for (sal_Int32 i=0; i<nChildCount; ++i) 615 { 616 Reference<XAccessible> xChild (getAccessibleChild (i)); 617 if (xChild.is()) 618 { 619 Reference<XAccessibleComponent> xChildComponent ( 620 xChild->getAccessibleContext(), uno::UNO_QUERY); 621 if (xChildComponent.is()) 622 { 623 awt::Rectangle aBBox (xChildComponent->getBounds()); 624 if ( (aPoint.X >= aBBox.X) 625 && (aPoint.Y >= aBBox.Y) 626 && (aPoint.X < aBBox.X+aBBox.Width) 627 && (aPoint.Y < aBBox.Y+aBBox.Height) ) 628 return xChild; 629 } 630 } 631 } 632 633 // Have not found a child under the given point. Returning empty 634 // reference to indicate this. 635 return uno::Reference<XAccessible>(); 636 } 637 638 639 640 641 awt::Rectangle SAL_CALL AccessibleShape::getBounds (void) 642 throw (::com::sun::star::uno::RuntimeException) 643 { 644 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex()); 645 ::osl::MutexGuard aGuard (maMutex); 646 647 ThrowIfDisposed (); 648 awt::Rectangle aBoundingBox; 649 if ( mxShape.is() ) 650 { 651 652 static const OUString sBoundRectName ( 653 RTL_CONSTASCII_USTRINGPARAM("BoundRect")); 654 static const OUString sAnchorPositionName ( 655 RTL_CONSTASCII_USTRINGPARAM("AnchorPosition")); 656 657 // Get the shape's bounding box in internal coordinates (in 100th of 658 // mm). Use the property BoundRect. Only if that is not supported ask 659 // the shape for its position and size directly. 660 Reference<beans::XPropertySet> xSet (mxShape, uno::UNO_QUERY); 661 Reference<beans::XPropertySetInfo> xSetInfo; 662 bool bFoundBoundRect = false; 663 if (xSet.is()) 664 { 665 xSetInfo = xSet->getPropertySetInfo (); 666 if (xSetInfo.is()) 667 { 668 if (xSetInfo->hasPropertyByName (sBoundRectName)) 669 { 670 try 671 { 672 uno::Any aValue = xSet->getPropertyValue (sBoundRectName); 673 aValue >>= aBoundingBox; 674 bFoundBoundRect = true; 675 } 676 catch (beans::UnknownPropertyException e) 677 { 678 // Handled below (bFoundBoundRect stays false). 679 } 680 } 681 else 682 OSL_TRACE (" no property BoundRect"); 683 } 684 } 685 686 // Fallback when there is no BoundRect Property. 687 if ( ! bFoundBoundRect ) 688 { 689 awt::Point aPosition (mxShape->getPosition()); 690 awt::Size aSize (mxShape->getSize()); 691 aBoundingBox = awt::Rectangle ( 692 aPosition.X, aPosition.Y, 693 aSize.Width, aSize.Height); 694 695 // While BoundRects have absolute positions, the position returned 696 // by XPosition::getPosition is relative. Get the anchor position 697 // (usually not (0,0) for Writer shapes). 698 if (xSetInfo.is()) 699 { 700 if (xSetInfo->hasPropertyByName (sAnchorPositionName)) 701 { 702 uno::Any aPos = xSet->getPropertyValue (sAnchorPositionName); 703 awt::Point aAnchorPosition; 704 aPos >>= aAnchorPosition; 705 aBoundingBox.X += aAnchorPosition.X; 706 aBoundingBox.Y += aAnchorPosition.Y; 707 } 708 } 709 } 710 711 // Transform coordinates from internal to pixel. 712 if (maShapeTreeInfo.GetViewForwarder() == NULL) 713 throw uno::RuntimeException (::rtl::OUString ( 714 RTL_CONSTASCII_USTRINGPARAM( 715 "AccessibleShape has no valid view forwarder")), 716 static_cast<uno::XWeak*>(this)); 717 ::Size aPixelSize = maShapeTreeInfo.GetViewForwarder()->LogicToPixel ( 718 ::Size (aBoundingBox.Width, aBoundingBox.Height)); 719 ::Point aPixelPosition = maShapeTreeInfo.GetViewForwarder()->LogicToPixel ( 720 ::Point (aBoundingBox.X, aBoundingBox.Y)); 721 722 // Clip the shape's bounding box with the bounding box of its parent. 723 Reference<XAccessibleComponent> xParentComponent ( 724 getAccessibleParent(), uno::UNO_QUERY); 725 if (xParentComponent.is()) 726 { 727 // Make the coordinates relative to the parent. 728 awt::Point aParentLocation (xParentComponent->getLocationOnScreen()); 729 int x = aPixelPosition.getX() - aParentLocation.X; 730 int y = aPixelPosition.getY() - aParentLocation.Y; 731 732 /* // The following block is a workarround for bug #99889# (property 733 // BoundRect returnes coordinates relative to document window 734 // instead of absolute coordinates for shapes in Writer). Has to 735 // be removed as soon as bug is fixed. 736 737 // Use a non-null anchor position as flag that the shape is in a 738 // Writer document. 739 if (xSetInfo.is()) 740 if (xSetInfo->hasPropertyByName (sAnchorPositionName)) 741 { 742 uno::Any aPos = xSet->getPropertyValue (sAnchorPositionName); 743 awt::Point aAnchorPosition; 744 aPos >>= aAnchorPosition; 745 if (aAnchorPosition.X > 0) 746 { 747 x = aPixelPosition.getX(); 748 y = aPixelPosition.getY(); 749 } 750 } 751 // End of workarround. 752 */ 753 // Clip with parent (with coordinates relative to itself). 754 ::Rectangle aBBox ( 755 x, y, x + aPixelSize.getWidth(), y + aPixelSize.getHeight()); 756 awt::Size aParentSize (xParentComponent->getSize()); 757 ::Rectangle aParentBBox (0,0, aParentSize.Width, aParentSize.Height); 758 aBBox = aBBox.GetIntersection (aParentBBox); 759 aBoundingBox = awt::Rectangle ( 760 aBBox.getX(), 761 aBBox.getY(), 762 aBBox.getWidth(), 763 aBBox.getHeight()); 764 } 765 else 766 { 767 OSL_TRACE ("parent does not support component"); 768 aBoundingBox = awt::Rectangle ( 769 aPixelPosition.getX(), aPixelPosition.getY(), 770 aPixelSize.getWidth(), aPixelSize.getHeight()); 771 } 772 } 773 774 return aBoundingBox; 775 } 776 777 778 779 780 awt::Point SAL_CALL AccessibleShape::getLocation (void) 781 throw (::com::sun::star::uno::RuntimeException) 782 { 783 ThrowIfDisposed (); 784 awt::Rectangle aBoundingBox (getBounds()); 785 return awt::Point (aBoundingBox.X, aBoundingBox.Y); 786 } 787 788 789 790 791 awt::Point SAL_CALL AccessibleShape::getLocationOnScreen (void) 792 throw (::com::sun::star::uno::RuntimeException) 793 { 794 ThrowIfDisposed (); 795 796 // Get relative position... 797 awt::Point aLocation (getLocation ()); 798 799 // ... and add absolute position of the parent. 800 uno::Reference<XAccessibleComponent> xParentComponent ( 801 getAccessibleParent(), uno::UNO_QUERY); 802 if (xParentComponent.is()) 803 { 804 awt::Point aParentLocation (xParentComponent->getLocationOnScreen()); 805 aLocation.X += aParentLocation.X; 806 aLocation.Y += aParentLocation.Y; 807 } 808 else 809 OSL_TRACE ("getLocation: parent does not support XAccessibleComponent"); 810 return aLocation; 811 } 812 813 814 815 816 awt::Size SAL_CALL AccessibleShape::getSize (void) 817 throw (uno::RuntimeException) 818 { 819 ThrowIfDisposed (); 820 awt::Rectangle aBoundingBox (getBounds()); 821 return awt::Size (aBoundingBox.Width, aBoundingBox.Height); 822 } 823 824 825 826 827 sal_Int32 SAL_CALL AccessibleShape::getForeground (void) 828 throw (::com::sun::star::uno::RuntimeException) 829 { 830 ThrowIfDisposed (); 831 sal_Int32 nColor (0x0ffffffL); 832 833 try 834 { 835 uno::Reference<beans::XPropertySet> aSet (mxShape, uno::UNO_QUERY); 836 if (aSet.is()) 837 { 838 uno::Any aColor; 839 aColor = aSet->getPropertyValue (OUString::createFromAscii ("LineColor")); 840 aColor >>= nColor; 841 } 842 } 843 catch (::com::sun::star::beans::UnknownPropertyException) 844 { 845 // Ignore exception and return default color. 846 } 847 return nColor; 848 } 849 850 851 852 853 sal_Int32 SAL_CALL AccessibleShape::getBackground (void) 854 throw (::com::sun::star::uno::RuntimeException) 855 { 856 ThrowIfDisposed (); 857 sal_Int32 nColor (0L); 858 859 try 860 { 861 uno::Reference<beans::XPropertySet> aSet (mxShape, uno::UNO_QUERY); 862 if (aSet.is()) 863 { 864 uno::Any aColor; 865 aColor = aSet->getPropertyValue (OUString::createFromAscii ("FillColor")); 866 aColor >>= nColor; 867 //IAccessibility2 Implementation 2009----- 868 aColor = aSet->getPropertyValue (OUString::createFromAscii ("FillTransparence")); 869 short nTrans=0; 870 aColor >>= nTrans; 871 Color crBk(nColor); 872 if (nTrans == 0 ) 873 { 874 crBk.SetTransparency(0xff); 875 } 876 else 877 { 878 nTrans = short(256 - nTrans / 100. * 256); 879 crBk.SetTransparency(sal_uInt8(nTrans)); 880 } 881 nColor = crBk.GetColor(); 882 //-----IAccessibility2 Implementation 2009 883 } 884 } 885 catch (::com::sun::star::beans::UnknownPropertyException) 886 { 887 // Ignore exception and return default color. 888 } 889 return nColor; 890 } 891 892 893 894 895 //===== XAccessibleEventBroadcaster ========================================= 896 897 void SAL_CALL AccessibleShape::addEventListener ( 898 const Reference<XAccessibleEventListener >& rxListener) 899 throw (uno::RuntimeException) 900 { 901 if (rBHelper.bDisposed || rBHelper.bInDispose) 902 { 903 uno::Reference<uno::XInterface> xThis ( 904 (lang::XComponent *)this, uno::UNO_QUERY); 905 rxListener->disposing (lang::EventObject (xThis)); 906 } 907 else 908 { 909 AccessibleContextBase::addEventListener (rxListener); 910 if (mpText != NULL) 911 mpText->AddEventListener (rxListener); 912 } 913 } 914 915 916 917 918 void SAL_CALL AccessibleShape::removeEventListener ( 919 const Reference<XAccessibleEventListener >& rxListener) 920 throw (uno::RuntimeException) 921 { 922 AccessibleContextBase::removeEventListener (rxListener); 923 if (mpText != NULL) 924 mpText->RemoveEventListener (rxListener); 925 } 926 927 928 929 930 //===== XInterface ========================================================== 931 932 com::sun::star::uno::Any SAL_CALL 933 AccessibleShape::queryInterface (const com::sun::star::uno::Type & rType) 934 throw (::com::sun::star::uno::RuntimeException) 935 { 936 ::com::sun::star::uno::Any aReturn = AccessibleContextBase::queryInterface (rType); 937 if ( ! aReturn.hasValue()) 938 aReturn = ::cppu::queryInterface (rType, 939 static_cast<XAccessibleComponent*>(this), 940 static_cast<XAccessibleExtendedComponent*>(this), 941 //IAccessibility2 Implementation 2009----- 942 static_cast< ::com::sun::star::accessibility::XAccessibleSelection* >(this), 943 944 static_cast< ::com::sun::star::accessibility::XAccessibleExtendedAttributes* >(this), 945 //-----IAccessibility2 Implementation 2009 946 static_cast<lang::XEventListener*>(this), 947 static_cast<document::XEventListener*>(this), 948 static_cast<lang::XUnoTunnel*>(this), 949 //IAccessibility2 Implementation 2009----- 950 static_cast<XAccessibleGroupPosition*>(this), 951 static_cast<XAccessibleHypertext*>(this) 952 //-----IAccessibility2 Implementation 2009 953 ); 954 return aReturn; 955 } 956 957 958 959 960 void SAL_CALL 961 AccessibleShape::acquire (void) 962 throw () 963 { 964 AccessibleContextBase::acquire (); 965 } 966 967 968 969 970 void SAL_CALL 971 AccessibleShape::release (void) 972 throw () 973 { 974 AccessibleContextBase::release (); 975 } 976 //IAccessibility2 Implementation 2009----- 977 // 978 //===== XAccessibleSelection ============================================ 979 // 980 981 //-------------------------------------------------------------------------------- 982 void SAL_CALL AccessibleShape::selectAccessibleChild( sal_Int32 ) 983 throw ( IndexOutOfBoundsException, RuntimeException ) 984 { 985 } 986 987 //---------------------------------------------------------------------------------- 988 sal_Bool SAL_CALL AccessibleShape::isAccessibleChildSelected( sal_Int32 nChildIndex ) 989 throw ( IndexOutOfBoundsException, 990 RuntimeException ) 991 { 992 uno::Reference<XAccessible> xAcc = getAccessibleChild( nChildIndex ); 993 uno::Reference<XAccessibleContext> xContext; 994 if( xAcc.is() ) 995 { 996 xContext = xAcc->getAccessibleContext(); 997 } 998 999 if( xContext.is() ) 1000 { 1001 if( xContext->getAccessibleRole() == AccessibleRole::PARAGRAPH ) 1002 { 1003 uno::Reference< ::com::sun::star::accessibility::XAccessibleText > 1004 xText(xAcc, uno::UNO_QUERY); 1005 if( xText.is() ) 1006 { 1007 if( xText->getSelectionStart() >= 0 ) return sal_True; 1008 } 1009 } 1010 else if( xContext->getAccessibleRole() == AccessibleRole::SHAPE ) 1011 { 1012 Reference< XAccessibleStateSet > pRState = xContext->getAccessibleStateSet(); 1013 if( !pRState.is() ) 1014 return sal_False; 1015 1016 uno::Sequence<short> pStates = pRState->getStates(); 1017 int nCount = pStates.getLength(); 1018 for( int i = 0; i < nCount; i++ ) 1019 { 1020 if(pStates[i] == AccessibleStateType::SELECTED) 1021 return sal_True; 1022 } 1023 return sal_False; 1024 } 1025 } 1026 1027 return sal_False; 1028 } 1029 1030 //--------------------------------------------------------------------- 1031 void SAL_CALL AccessibleShape::clearAccessibleSelection( ) 1032 throw ( RuntimeException ) 1033 { 1034 } 1035 1036 //------------------------------------------------------------------------- 1037 void SAL_CALL AccessibleShape::selectAllAccessibleChildren( ) 1038 throw ( RuntimeException ) 1039 { 1040 } 1041 1042 //---------------------------------------------------------------------------- 1043 sal_Int32 SAL_CALL AccessibleShape::getSelectedAccessibleChildCount() 1044 throw ( RuntimeException ) 1045 { 1046 sal_Int32 nCount = 0; 1047 sal_Int32 TotalCount = getAccessibleChildCount(); 1048 for( sal_Int32 i = 0; i < TotalCount; i++ ) 1049 if( isAccessibleChildSelected(i) ) nCount++; 1050 1051 return nCount; 1052 } 1053 1054 //-------------------------------------------------------------------------------------- 1055 Reference<XAccessible> SAL_CALL AccessibleShape::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) 1056 throw ( IndexOutOfBoundsException, RuntimeException) 1057 { 1058 if ( nSelectedChildIndex > getSelectedAccessibleChildCount() ) 1059 throw IndexOutOfBoundsException(); 1060 sal_Int32 i1, i2; 1061 for( i1 = 0, i2 = 0; i1 < getAccessibleChildCount(); i1++ ) 1062 if( isAccessibleChildSelected(i1) ) 1063 { 1064 if( i2 == nSelectedChildIndex ) 1065 return getAccessibleChild( i1 ); 1066 i2++; 1067 } 1068 return Reference<XAccessible>(); 1069 } 1070 1071 //---------------------------------------------------------------------------------- 1072 void SAL_CALL AccessibleShape::deselectAccessibleChild( sal_Int32 ) 1073 throw ( IndexOutOfBoundsException, 1074 RuntimeException ) 1075 { 1076 1077 } 1078 1079 //===== XAccessibleExtendedAttributes ======================================================== 1080 uno::Any SAL_CALL AccessibleShape::getExtendedAttributes() 1081 throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) 1082 { 1083 uno::Any strRet; 1084 ::rtl::OUString style; 1085 if( getAccessibleRole() != AccessibleRole::SHAPE ) return strRet; 1086 if( m_pShape ) 1087 { 1088 //style = ::rtl::OUString::createFromAscii("style="); 1089 style = ::rtl::OUString::createFromAscii("style:"); 1090 style += GetStyle(); 1091 } 1092 style += ::rtl::OUString::createFromAscii(";"); 1093 strRet <<= style; 1094 return strRet; 1095 } 1096 //-----IAccessibility2 Implementation 2009 1097 //===== XServiceInfo ======================================================== 1098 1099 ::rtl::OUString SAL_CALL 1100 AccessibleShape::getImplementationName (void) 1101 throw (::com::sun::star::uno::RuntimeException) 1102 { 1103 return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleShape")); 1104 } 1105 1106 1107 1108 1109 uno::Sequence<OUString> SAL_CALL 1110 AccessibleShape::getSupportedServiceNames (void) 1111 throw (::com::sun::star::uno::RuntimeException) 1112 { 1113 ThrowIfDisposed (); 1114 // Get list of supported service names from base class... 1115 uno::Sequence<OUString> aServiceNames = 1116 AccessibleContextBase::getSupportedServiceNames(); 1117 sal_Int32 nCount (aServiceNames.getLength()); 1118 1119 // ...and add additional names. 1120 aServiceNames.realloc (nCount + 1); 1121 static const OUString sAdditionalServiceName (RTL_CONSTASCII_USTRINGPARAM( 1122 "com.sun.star.drawing.AccessibleShape")); 1123 aServiceNames[nCount] = sAdditionalServiceName; 1124 1125 return aServiceNames; 1126 } 1127 1128 1129 1130 1131 1132 //===== XTypeProvider =================================================== 1133 1134 uno::Sequence<uno::Type> SAL_CALL 1135 AccessibleShape::getTypes (void) 1136 throw (uno::RuntimeException) 1137 { 1138 ThrowIfDisposed (); 1139 // Get list of types from the context base implementation, ... 1140 uno::Sequence<uno::Type> aTypeList (AccessibleContextBase::getTypes()); 1141 // ... get list of types from component base implementation, ... 1142 uno::Sequence<uno::Type> aComponentTypeList (AccessibleComponentBase::getTypes()); 1143 // ... define local types, ... 1144 const uno::Type aLangEventListenerType = 1145 ::getCppuType((const uno::Reference<lang::XEventListener>*)0); 1146 const uno::Type aDocumentEventListenerType = 1147 ::getCppuType((const uno::Reference<document::XEventListener>*)0); 1148 const uno::Type aUnoTunnelType = 1149 ::getCppuType((const uno::Reference<lang::XUnoTunnel>*)0); 1150 // const uno::Type aStateSetType = 1151 // ::getCppuType((const uno::Reference<XAccessibleStateSet>*)0); 1152 1153 // ... and merge them all into one list. 1154 sal_Int32 nTypeCount (aTypeList.getLength()), 1155 nComponentTypeCount (aComponentTypeList.getLength()); 1156 int i; 1157 1158 aTypeList.realloc (nTypeCount + nComponentTypeCount + 3); 1159 1160 for (i=0; i<nComponentTypeCount; i++) 1161 aTypeList[nTypeCount + i] = aComponentTypeList[i]; 1162 1163 aTypeList[nTypeCount + i++ ] = aLangEventListenerType; 1164 aTypeList[nTypeCount + i++ ] = aDocumentEventListenerType; 1165 aTypeList[nTypeCount + i ] = aUnoTunnelType; 1166 1167 return aTypeList; 1168 } 1169 1170 1171 1172 1173 //===== lang::XEventListener ================================================ 1174 1175 /** Disposing calls are accepted only from the model: Just reset the 1176 reference to the model in the shape tree info. Otherwise this object 1177 remains functional. 1178 */ 1179 void SAL_CALL 1180 AccessibleShape::disposing (const lang::EventObject& aEvent) 1181 throw (uno::RuntimeException) 1182 { 1183 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex()); 1184 ::osl::MutexGuard aGuard (maMutex); 1185 1186 try 1187 { 1188 if (aEvent.Source == maShapeTreeInfo.GetModelBroadcaster()) 1189 { 1190 // Remove reference to model broadcaster to allow it to pass 1191 // away. 1192 maShapeTreeInfo.SetModelBroadcaster(NULL); 1193 } 1194 1195 } 1196 catch (uno::RuntimeException e) 1197 { 1198 OSL_TRACE ("caught exception while disposing"); 1199 } 1200 } 1201 1202 1203 1204 1205 //===== document::XEventListener ============================================ 1206 1207 void SAL_CALL 1208 AccessibleShape::notifyEvent (const document::EventObject& rEventObject) 1209 throw (uno::RuntimeException) 1210 { 1211 static const OUString sShapeModified ( 1212 RTL_CONSTASCII_USTRINGPARAM("ShapeModified")); 1213 1214 // First check if the event is for us. 1215 uno::Reference<drawing::XShape> xShape ( 1216 rEventObject.Source, uno::UNO_QUERY); 1217 if ( xShape.get() == mxShape.get() ) 1218 { 1219 if (rEventObject.EventName.equals (sShapeModified)) 1220 { 1221 //Need to update text children when receiving ShapeModified hint when exiting edit mode for text box 1222 if (mpText) 1223 mpText->UpdateChildren(); 1224 1225 1226 // Some property of a shape has been modified. Send an event 1227 // that indicates a change of the visible data to all listeners. 1228 CommitChange ( 1229 AccessibleEventId::VISIBLE_DATA_CHANGED, 1230 uno::Any(), 1231 uno::Any()); 1232 1233 // Name and Description may have changed. Update the local 1234 // values accordingly. 1235 UpdateNameAndDescription(); 1236 } 1237 } 1238 } 1239 1240 1241 1242 1243 //===== lang::XUnoTunnel ================================================ 1244 1245 const uno::Sequence< sal_Int8 >& 1246 AccessibleShape::getUnoTunnelImplementationId() 1247 throw() 1248 { 1249 static uno::Sequence< sal_Int8 >* pSeq = 0; 1250 1251 if( !pSeq ) 1252 { 1253 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); 1254 1255 if( !pSeq ) 1256 { 1257 static uno::Sequence< sal_Int8 > aSeq( 16 ); 1258 rtl_createUuid( (sal_uInt8*) aSeq.getArray(), 0, sal_True ); 1259 pSeq = &aSeq; 1260 } 1261 } 1262 1263 return( *pSeq ); 1264 } 1265 1266 //------------------------------------------------------------------------------ 1267 AccessibleShape* 1268 AccessibleShape::getImplementation( const uno::Reference< uno::XInterface >& rxIFace ) 1269 throw() 1270 { 1271 uno::Reference< lang::XUnoTunnel > xTunnel( rxIFace, uno::UNO_QUERY ); 1272 AccessibleShape* pReturn = NULL; 1273 1274 if( xTunnel.is() ) 1275 pReturn = reinterpret_cast< AccessibleShape* >( xTunnel->getSomething( getUnoTunnelImplementationId() ) ); 1276 1277 return( pReturn ); 1278 } 1279 1280 //------------------------------------------------------------------------------ 1281 sal_Int64 SAL_CALL 1282 AccessibleShape::getSomething( const uno::Sequence< sal_Int8 >& rIdentifier ) 1283 throw(uno::RuntimeException) 1284 { 1285 sal_Int64 nReturn( 0 ); 1286 1287 if( ( rIdentifier.getLength() == 16 ) && ( 0 == rtl_compareMemory( getUnoTunnelImplementationId().getConstArray(), rIdentifier.getConstArray(), 16 ) ) ) 1288 nReturn = reinterpret_cast< sal_Int64 >( this ); 1289 1290 return( nReturn ); 1291 } 1292 1293 //===== IAccessibleViewForwarderListener ==================================== 1294 1295 void AccessibleShape::ViewForwarderChanged (ChangeType aChangeType, 1296 const IAccessibleViewForwarder* pViewForwarder) 1297 { 1298 // Inform all listeners that the graphical representation (i.e. size 1299 // and/or position) of the shape has changed. 1300 CommitChange (AccessibleEventId::VISIBLE_DATA_CHANGED, 1301 uno::Any(), 1302 uno::Any()); 1303 1304 // Tell children manager of the modified view forwarder. 1305 if (mpChildrenManager != NULL) 1306 mpChildrenManager->ViewForwarderChanged (aChangeType, pViewForwarder); 1307 1308 // update our children that our screen position might have changed 1309 if( mpText ) 1310 mpText->UpdateChildren(); 1311 } 1312 1313 1314 1315 1316 //===== protected internal ================================================== 1317 /// Set this object's name if is different to the current name. 1318 ::rtl::OUString 1319 AccessibleShape::CreateAccessibleBaseName (void) 1320 throw (::com::sun::star::uno::RuntimeException) 1321 { 1322 return ShapeTypeHandler::CreateAccessibleBaseName( mxShape ); 1323 } 1324 1325 1326 ::rtl::OUString 1327 AccessibleShape::CreateAccessibleName (void) 1328 throw (::com::sun::star::uno::RuntimeException) 1329 { 1330 //OUString sName (CreateAccessibleBaseName()); 1331 //IAccessibility2 Implementation 2009----- 1332 OUString sName; 1333 sName = GetFullAccessibleName(this); 1334 return sName; 1335 } 1336 1337 ::rtl::OUString 1338 AccessibleShape::GetFullAccessibleName (AccessibleShape *shape) 1339 throw (::com::sun::star::uno::RuntimeException) 1340 { 1341 OUString sName (shape->CreateAccessibleBaseName()); 1342 // Append the shape's index to the name to disambiguate between shapes 1343 // of the same type. If such an index where not given to the 1344 // constructor then use the z-order instead. If even that does not exist 1345 // we throw an exception. 1346 //long nIndex = mnIndex; 1347 //if (nIndex == -1) 1348 //{ 1349 // try 1350 // { 1351 // uno::Reference<beans::XPropertySet> xSet (mxShape, uno::UNO_QUERY); 1352 // if (xSet.is()) 1353 // { 1354 // uno::Any aZOrder (xSet->getPropertyValue (::rtl::OUString::createFromAscii ("ZOrder"))); 1355 // aZOrder >>= nIndex; 1356 1357 // // Add one to be not zero based. 1358 // nIndex += 1; 1359 // } 1360 // } 1361 // catch (beans::UnknownPropertyException) 1362 // { 1363 // // We throw our own exception that is a bit more informative. 1364 // throw uno::RuntimeException (::rtl::OUString ( 1365 // RTL_CONSTASCII_USTRINGPARAM("AccessibleShape has invalid index and no ZOrder property")), 1366 // static_cast<uno::XWeak*>(this)); 1367 // } 1368 1369 //} 1370 1371 //// Put a space between name and index because of Gnopernicus othewise 1372 //// spells the name. 1373 //sName += OUString (RTL_CONSTASCII_USTRINGPARAM(" ")) + OUString::valueOf (nIndex); 1374 1375 //return sName; 1376 1377 XubString nameStr; 1378 if(shape->m_pShape) 1379 nameStr = shape->m_pShape->GetName(); 1380 if(nameStr.Len() == 0) 1381 { 1382 sName += OUString( RTL_CONSTASCII_USTRINGPARAM( " " )); 1383 } 1384 else 1385 { 1386 sName = nameStr; 1387 } 1388 /* 1389 sal_Int32 nChildCount = shape->getAccessibleChildCount(); 1390 if(nChildCount > 0) 1391 { 1392 for (sal_Int32 i=0; i<nChildCount; ++i) 1393 { 1394 Reference<XAccessible> xChild (shape->getAccessibleChild (i)); 1395 if (xChild.is()) 1396 { 1397 uno::Reference <XAccessibleContext> xChildContext(xChild->getAccessibleContext()); 1398 if (xChildContext->getAccessibleRole() == AccessibleRole::PARAGRAPH) 1399 { 1400 uno::Reference<XAccessibleText> xText = uno::Reference<XAccessibleText> ( xChild, uno::UNO_QUERY ); 1401 sName += OUString( RTL_CONSTASCII_USTRINGPARAM( " " )) + xText->getText(); 1402 } 1403 else if (xChildContext->getAccessibleRole() == AccessibleRole::SHAPE) 1404 { 1405 sName += OUString( RTL_CONSTASCII_USTRINGPARAM( " " )) + GetFullAccessibleName(static_cast< AccessibleShape*>( xChild.get())); 1406 } 1407 } 1408 } 1409 } 1410 */ 1411 //Solution:If the new produced name if not the same with last,notify name changed 1412 // Event 1413 if( aAccName != sName && aAccName.getLength() != 0 ) 1414 { 1415 uno::Any aOldValue, aNewValue; 1416 aOldValue <<= aAccName; 1417 aNewValue <<= sName; 1418 CommitChange( 1419 AccessibleEventId::NAME_CHANGED, 1420 aNewValue, 1421 aOldValue); 1422 } 1423 aAccName = sName; 1424 return sName; 1425 } 1426 //-----IAccessibility2 Implementation 2009 1427 ::rtl::OUString 1428 AccessibleShape::CreateAccessibleDescription (void) 1429 throw (::com::sun::star::uno::RuntimeException) 1430 { 1431 DescriptionGenerator aDG (mxShape); 1432 aDG.Initialize (CreateAccessibleBaseName()); 1433 switch (ShapeTypeHandler::Instance().GetTypeId (mxShape)) 1434 { 1435 case DRAWING_3D_CUBE: 1436 case DRAWING_3D_EXTRUDE: 1437 case DRAWING_3D_LATHE: 1438 case DRAWING_3D_SPHERE: 1439 aDG.Add3DProperties (); 1440 break; 1441 1442 case DRAWING_3D_SCENE: 1443 case DRAWING_GROUP: 1444 case DRAWING_PAGE: 1445 // No further information is appended. 1446 break; 1447 1448 case DRAWING_CAPTION: 1449 case DRAWING_CLOSED_BEZIER: 1450 case DRAWING_CLOSED_FREEHAND: 1451 case DRAWING_ELLIPSE: 1452 case DRAWING_POLY_POLYGON: 1453 case DRAWING_POLY_POLYGON_PATH: 1454 case DRAWING_RECTANGLE: 1455 aDG.AddLineProperties (); 1456 aDG.AddFillProperties (); 1457 break; 1458 1459 case DRAWING_CONNECTOR: 1460 case DRAWING_LINE: 1461 case DRAWING_MEASURE: 1462 case DRAWING_OPEN_BEZIER: 1463 case DRAWING_OPEN_FREEHAND: 1464 case DRAWING_POLY_LINE: 1465 case DRAWING_POLY_LINE_PATH: 1466 aDG.AddLineProperties (); 1467 break; 1468 1469 case DRAWING_CONTROL: 1470 aDG.AddProperty (OUString::createFromAscii ("ControlBackground"), 1471 DescriptionGenerator::COLOR, 1472 OUString()); 1473 aDG.AddProperty (OUString::createFromAscii ("ControlBorder"), 1474 DescriptionGenerator::INTEGER, 1475 OUString()); 1476 break; 1477 1478 case DRAWING_TEXT: 1479 aDG.AddTextProperties (); 1480 break; 1481 1482 default: 1483 aDG.Initialize (::rtl::OUString ( 1484 RTL_CONSTASCII_USTRINGPARAM("Unknown accessible shape"))); 1485 uno::Reference<drawing::XShapeDescriptor> xDescriptor (mxShape, uno::UNO_QUERY); 1486 if (xDescriptor.is()) 1487 { 1488 aDG.AppendString (::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("service name="))); 1489 aDG.AppendString (xDescriptor->getShapeType()); 1490 } 1491 } 1492 1493 return aDG(); 1494 } 1495 1496 1497 1498 1499 uno::Reference< drawing::XShape > AccessibleShape::GetXShape() 1500 { 1501 return( mxShape ); 1502 } 1503 1504 1505 1506 // protected 1507 void AccessibleShape::disposing (void) 1508 { 1509 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex()); 1510 ::osl::MutexGuard aGuard (maMutex); 1511 1512 // Make sure to send an event that this object looses the focus in the 1513 // case that it has the focus. 1514 ::utl::AccessibleStateSetHelper* pStateSet = 1515 static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get()); 1516 if (pStateSet != NULL) 1517 pStateSet->RemoveState (AccessibleStateType::FOCUSED); 1518 1519 // Unregister from broadcasters. 1520 Reference<lang::XComponent> xComponent (mxShape, uno::UNO_QUERY); 1521 if (xComponent.is()) 1522 xComponent->removeEventListener (this); 1523 1524 // Unregister from model. 1525 if (maShapeTreeInfo.GetModelBroadcaster().is()) 1526 maShapeTreeInfo.GetModelBroadcaster()->removeEventListener ( 1527 static_cast<document::XEventListener*>(this)); 1528 1529 // Release the child containers. 1530 if (mpChildrenManager != NULL) 1531 { 1532 delete mpChildrenManager; 1533 mpChildrenManager = NULL; 1534 } 1535 if (mpText != NULL) 1536 { 1537 mpText->Dispose(); 1538 delete mpText; 1539 mpText = NULL; 1540 } 1541 1542 // Cleanup. Remove references to objects to allow them to be 1543 // destroyed. 1544 mxShape = NULL; 1545 maShapeTreeInfo = AccessibleShapeTreeInfo(); 1546 1547 // Call base classes. 1548 AccessibleContextBase::dispose (); 1549 } 1550 1551 sal_Int32 SAL_CALL 1552 AccessibleShape::getAccessibleIndexInParent (void) 1553 throw (::com::sun::star::uno::RuntimeException) 1554 { 1555 ThrowIfDisposed (); 1556 // Use a simple but slow solution for now. Optimize later. 1557 1558 sal_Int32 nIndex = m_nIndexInParent; 1559 if ( -1 == nIndex ) 1560 nIndex = AccessibleContextBase::getAccessibleIndexInParent(); 1561 return nIndex; 1562 } 1563 1564 1565 1566 1567 void AccessibleShape::UpdateNameAndDescription (void) 1568 { 1569 // Ignore missing title, name, or description. There are fallbacks for 1570 // them. 1571 try 1572 { 1573 Reference<beans::XPropertySet> xSet (mxShape, uno::UNO_QUERY_THROW); 1574 OUString sString; 1575 1576 // Get the accessible name. 1577 sString = GetOptionalProperty(xSet, OUString(RTL_CONSTASCII_USTRINGPARAM("Title"))); 1578 if (sString.getLength() > 0) 1579 { 1580 SetAccessibleName(sString, AccessibleContextBase::FromShape); 1581 } 1582 else 1583 { 1584 sString = GetOptionalProperty(xSet, OUString(RTL_CONSTASCII_USTRINGPARAM("Name"))); 1585 if (sString.getLength() > 0) 1586 SetAccessibleName(sString, AccessibleContextBase::FromShape); 1587 } 1588 1589 // Get the accessible description. 1590 sString = GetOptionalProperty(xSet, OUString(RTL_CONSTASCII_USTRINGPARAM("Description"))); 1591 if (sString.getLength() > 0) 1592 SetAccessibleDescription(sString, AccessibleContextBase::FromShape); 1593 } 1594 catch (uno::RuntimeException&) 1595 { 1596 } 1597 } 1598 //IAccessibility2 Implementation 2009----- 1599 // Return this object's role. 1600 sal_Int16 SAL_CALL AccessibleShape::getAccessibleRole (void) 1601 throw (::com::sun::star::uno::RuntimeException) 1602 { 1603 sal_Int16 nAccessibleRole = AccessibleRole::SHAPE ; 1604 switch (ShapeTypeHandler::Instance().GetTypeId (mxShape)) 1605 { 1606 case DRAWING_GRAPHIC_OBJECT: 1607 nAccessibleRole = AccessibleRole::GRAPHIC ; break; 1608 case DRAWING_OLE: 1609 nAccessibleRole = AccessibleRole::EMBEDDED_OBJECT ; break; 1610 1611 default: 1612 nAccessibleRole = AccessibleContextBase::getAccessibleRole(); 1613 break; 1614 } 1615 1616 return nAccessibleRole; 1617 } 1618 1619 1620 void AccessibleShape::UpdateDocumentAllSelState(Reference<XAccessibleStateSet> &xStateSet) 1621 { 1622 if (mpParent && mpParent->IsDocumentSelAll()) 1623 { 1624 ::utl::AccessibleStateSetHelper* pStateSet = 1625 static_cast< ::utl::AccessibleStateSetHelper*>(xStateSet.get()); 1626 pStateSet->AddState (AccessibleStateType::SELECTED); 1627 1628 //uno::Any NewValue; 1629 //NewValue <<= AccessibleStateType::SELECTED; 1630 1631 //CommitChange(AccessibleEventId::STATE_CHANGED,NewValue,uno::Any()); 1632 } 1633 } 1634 1635 //sort the drawing objects from up to down, from left to right 1636 struct XShapePosCompareHelper 1637 { 1638 bool operator() ( const uno::Reference<drawing::XShape>& xshape1, 1639 const uno::Reference<drawing::XShape>& xshape2 ) const 1640 { 1641 SdrObject* pObj1 = GetSdrObjectFromXShape(xshape1); 1642 SdrObject* pObj2 = GetSdrObjectFromXShape(xshape2); 1643 if(pObj1 && pObj2) 1644 return pObj1->GetOrdNum() < pObj2->GetOrdNum(); 1645 else 1646 return 0; 1647 } 1648 }; 1649 //end of group position 1650 1651 //===== XAccessibleGroupPosition ========================================= 1652 uno::Sequence< sal_Int32 > SAL_CALL 1653 AccessibleShape::getGroupPosition( const uno::Any& ) 1654 throw (uno::RuntimeException) 1655 { 1656 // we will return the: 1657 // [0] group level 1658 // [1] similar items counts in the group 1659 // [2] the position of the object in the group 1660 uno::Sequence< sal_Int32 > aRet( 3 ); 1661 aRet[0] = 0; 1662 aRet[1] = 0; 1663 aRet[2] = 0; 1664 1665 ::com::sun::star::uno::Reference<XAccessible> xParent = getAccessibleParent(); 1666 if (!xParent.is()) 1667 { 1668 return aRet; 1669 } 1670 SdrObject *pObj = GetSdrObjectFromXShape(mxShape); 1671 1672 1673 if(pObj == NULL ) 1674 { 1675 return aRet; 1676 } 1677 1678 // Compute object's group level. 1679 sal_Int32 nGroupLevel = 0; 1680 SdrObject * pUper = pObj->GetUpGroup(); 1681 while( pUper ) 1682 { 1683 ++nGroupLevel; 1684 pUper = pUper->GetUpGroup(); 1685 } 1686 1687 ::com::sun::star::uno::Reference<XAccessibleContext> xParentContext = xParent->getAccessibleContext(); 1688 if( xParentContext->getAccessibleRole() == AccessibleRole::DOCUMENT)//Document 1689 { 1690 Reference< XAccessibleGroupPosition > xGroupPosition( xParent,uno::UNO_QUERY ); 1691 if ( xGroupPosition.is() ) 1692 { 1693 aRet = xGroupPosition->getGroupPosition( uno::makeAny( getAccessibleContext() ) ); 1694 } 1695 return aRet; 1696 } 1697 if (xParentContext->getAccessibleRole() != AccessibleRole::SHAPE) 1698 { 1699 return aRet; 1700 } 1701 1702 SdrObjList *pGrpList = NULL; 1703 if( pObj->GetUpGroup() ) 1704 pGrpList = pObj->GetUpGroup()->GetSubList(); 1705 else 1706 return aRet; 1707 1708 std::vector< uno::Reference<drawing::XShape> > vXShapes; 1709 if (pGrpList) 1710 { 1711 const sal_Int32 nObj = pGrpList->GetObjCount(); 1712 for(sal_Int32 i = 0 ; i < nObj ; ++i) 1713 { 1714 SdrObject *pSubObj = pGrpList->GetObj(i); 1715 //IAccessibility2 Implementation 2009----- 1716 if (pSubObj && 1717 xParentContext->getAccessibleChild(i)->getAccessibleContext()->getAccessibleRole() != AccessibleRole::GROUP_BOX) 1718 //-----IAccessibility2 Implementation 2009 1719 { 1720 vXShapes.push_back( GetXShapeForSdrObject(pSubObj) ); 1721 } 1722 } 1723 } 1724 1725 std::sort( vXShapes.begin(), vXShapes.end(), XShapePosCompareHelper() ); 1726 1727 //get the the index of the selected object in the group 1728 std::vector< uno::Reference<drawing::XShape> >::iterator aIter; 1729 //we start counting position from 1 1730 sal_Int32 nPos = 1; 1731 for ( aIter = vXShapes.begin(); aIter != vXShapes.end(); aIter++, nPos++ ) 1732 { 1733 if ( (*aIter).get() == mxShape.get() ) 1734 { 1735 sal_Int32* pArray = aRet.getArray(); 1736 pArray[0] = nGroupLevel; 1737 pArray[1] = vXShapes.size(); 1738 pArray[2] = nPos; 1739 break; 1740 } 1741 } 1742 1743 return aRet; 1744 } 1745 1746 ::rtl::OUString AccessibleShape::getObjectLink( const uno::Any& ) 1747 throw (uno::RuntimeException) 1748 { 1749 ::rtl::OUString aRet; 1750 1751 SdrObject *pObj = GetSdrObjectFromXShape(mxShape); 1752 if(pObj == NULL ) 1753 { 1754 return aRet; 1755 } 1756 if (maShapeTreeInfo.GetDocumentWindow().is()) 1757 { 1758 Reference< XAccessibleGroupPosition > xGroupPosition( maShapeTreeInfo.GetDocumentWindow(), uno::UNO_QUERY ); 1759 if (xGroupPosition.is()) 1760 { 1761 aRet = xGroupPosition->getObjectLink( uno::makeAny( getAccessibleContext() ) ); 1762 } 1763 } 1764 return aRet; 1765 } 1766 1767 //===== XAccesibleHypertext ================================================== 1768 sal_Int32 SAL_CALL AccessibleShape::getHyperLinkCount() 1769 throw (::com::sun::star::uno::RuntimeException) 1770 { 1771 // MT: Introduced with IA2 CWS, but SvxAccessibleHyperlink was redundant to svx::AccessibleHyperlink which we introduced meanwhile. 1772 // Code need to be adapted.... 1773 return 0; 1774 1775 /* 1776 SvxAccessibleHyperlink* pLink = new SvxAccessibleHyperlink(m_pShape,this); 1777 if (pLink->IsValidHyperlink()) 1778 return 1; 1779 else 1780 return 0; 1781 */ 1782 } 1783 uno::Reference< XAccessibleHyperlink > SAL_CALL 1784 AccessibleShape::getHyperLink( sal_Int32 ) 1785 throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) 1786 { 1787 uno::Reference< XAccessibleHyperlink > xRet; 1788 // MT: Introduced with IA2 CWS, but SvxAccessibleHyperlink was redundant to svx::AccessibleHyperlink which we introduced meanwhile. 1789 // Code need to be adapted.... 1790 /* 1791 SvxAccessibleHyperlink* pLink = new SvxAccessibleHyperlink(m_pShape,this); 1792 if (pLink->IsValidHyperlink()) 1793 xRet = pLink; 1794 if( !xRet.is() ) 1795 throw ::com::sun::star::lang::IndexOutOfBoundsException(); 1796 */ 1797 return xRet; 1798 } 1799 sal_Int32 SAL_CALL AccessibleShape::getHyperLinkIndex( sal_Int32 ) 1800 throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) 1801 { 1802 sal_Int32 nRet = 0; 1803 return nRet; 1804 } 1805 //===== XAccesibleText ================================================== 1806 sal_Int32 SAL_CALL AccessibleShape::getCaretPosition( ) throw (::com::sun::star::uno::RuntimeException){return 0;} 1807 sal_Bool SAL_CALL AccessibleShape::setCaretPosition( sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException){return 0;} 1808 sal_Unicode SAL_CALL AccessibleShape::getCharacter( sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException){return 0;} 1809 ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL AccessibleShape::getCharacterAttributes( sal_Int32, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) 1810 { 1811 uno::Sequence< ::com::sun::star::beans::PropertyValue > aValues(0); 1812 return aValues; 1813 } 1814 ::com::sun::star::awt::Rectangle SAL_CALL AccessibleShape::getCharacterBounds( sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) 1815 { 1816 return com::sun::star::awt::Rectangle(0, 0, 0, 0 ); 1817 } 1818 sal_Int32 SAL_CALL AccessibleShape::getCharacterCount( ) throw (::com::sun::star::uno::RuntimeException){return 0;} 1819 sal_Int32 SAL_CALL AccessibleShape::getIndexAtPoint( const ::com::sun::star::awt::Point& ) throw (::com::sun::star::uno::RuntimeException){return 0;} 1820 ::rtl::OUString SAL_CALL AccessibleShape::getSelectedText( ) throw (::com::sun::star::uno::RuntimeException){return OUString();} 1821 sal_Int32 SAL_CALL AccessibleShape::getSelectionStart( ) throw (::com::sun::star::uno::RuntimeException){return 0;} 1822 sal_Int32 SAL_CALL AccessibleShape::getSelectionEnd( ) throw (::com::sun::star::uno::RuntimeException){return 0;} 1823 sal_Bool SAL_CALL AccessibleShape::setSelection( sal_Int32, sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException){return sal_True;} 1824 ::rtl::OUString SAL_CALL AccessibleShape::getText( ) throw (::com::sun::star::uno::RuntimeException){return OUString();} 1825 ::rtl::OUString SAL_CALL AccessibleShape::getTextRange( sal_Int32, sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException){return OUString();} 1826 ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleShape::getTextAtIndex( sal_Int32, sal_Int16 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) 1827 { 1828 ::com::sun::star::accessibility::TextSegment aResult; 1829 return aResult; 1830 } 1831 ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleShape::getTextBeforeIndex( sal_Int32, sal_Int16 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) 1832 { 1833 ::com::sun::star::accessibility::TextSegment aResult; 1834 return aResult; 1835 } 1836 ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleShape::getTextBehindIndex( sal_Int32, sal_Int16 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) 1837 { 1838 ::com::sun::star::accessibility::TextSegment aResult; 1839 return aResult; 1840 } 1841 sal_Bool SAL_CALL AccessibleShape::copyText( sal_Int32, sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException){return sal_True;} 1842 1843 //-----IAccessibility2 Implementation 2009 1844 } // end of namespace accessibility 1845