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 = new utl::AccessibleRelationSetHelper; 456 uno::Sequence< uno::Reference< uno::XInterface > > aSequence(1); 457 aSequence[0] = mpParent->GetAccessibleCaption(mxShape); 458 459 //this mxshape is the captioned shape, only for sw 460 if(aSequence[0].get()) 461 { 462 pRelationSet->AddRelation( 463 AccessibleRelation( AccessibleRelationType::DESCRIBED_BY, aSequence ) ); 464 } 465 466 if (pRelationSet != NULL) 467 { 468 return uno::Reference<XAccessibleRelationSet> ( 469 new ::utl::AccessibleRelationSetHelper (*pRelationSet)); 470 } 471 else 472 { 473 return uno::Reference<XAccessibleRelationSet>(NULL); 474 } 475 476 return uno::Reference<XAccessibleRelationSet>(); 477 } 478 //-----IAccessibility2 Implementation 2009 479 480 /** Return a copy of the state set. 481 Possible states are: 482 ENABLED 483 SHOWING 484 VISIBLE 485 */ 486 uno::Reference<XAccessibleStateSet> SAL_CALL 487 AccessibleShape::getAccessibleStateSet (void) 488 throw (::com::sun::star::uno::RuntimeException) 489 { 490 ::osl::MutexGuard aGuard (maMutex); 491 Reference<XAccessibleStateSet> xStateSet; 492 493 if (rBHelper.bDisposed || mpText == NULL) 494 // Return a minimal state set that only contains the DEFUNC state. 495 //IAccessibility2 Implementation 2009----- 496 //xStateSet = AccessibleContextBase::getAccessibleStateSet (); 497 { 498 xStateSet = AccessibleContextBase::getAccessibleStateSet (); 499 ::utl::AccessibleStateSetHelper* pStateSet = 500 static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get()); 501 ::com::sun::star::uno::Reference<XAccessible> xTempAcc = getAccessibleParent(); 502 if( xTempAcc.is() ) 503 { 504 ::com::sun::star::uno::Reference<XAccessibleContext> 505 xTempAccContext = xTempAcc->getAccessibleContext(); 506 if( xTempAccContext.is() ) 507 { 508 ::com::sun::star::uno::Reference<XAccessibleStateSet> rState = 509 xTempAccContext->getAccessibleStateSet(); 510 if( rState.is() ) { 511 com::sun::star::uno::Sequence<short> pStates = rState->getStates(); 512 int count = pStates.getLength(); 513 for( int iIndex = 0;iIndex < count;iIndex++ ) 514 { 515 if( pStates[iIndex] == AccessibleStateType::EDITABLE ) 516 { 517 pStateSet->AddState (AccessibleStateType::EDITABLE); 518 pStateSet->AddState (AccessibleStateType::RESIZABLE); 519 pStateSet->AddState (AccessibleStateType::MOVEABLE); 520 break; 521 } 522 } 523 } 524 } 525 } 526 xStateSet = Reference<XAccessibleStateSet>( 527 new ::utl::AccessibleStateSetHelper (*pStateSet)); 528 //-----IAccessibility2 Implementation 2009 529 }else 530 { 531 ::utl::AccessibleStateSetHelper* pStateSet = 532 static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get()); 533 534 if (pStateSet != NULL) 535 { 536 // Merge current FOCUSED state from edit engine. 537 if (mpText != NULL) 538 { 539 if (mpText->HaveFocus()) 540 pStateSet->AddState (AccessibleStateType::FOCUSED); 541 else 542 pStateSet->RemoveState (AccessibleStateType::FOCUSED); 543 } 544 //IAccessibility2 Implementation 2009----- 545 //Solution:Just when the document is not read-only,set states EDITABLE,RESIZABLE,MOVEABLE 546 ::com::sun::star::uno::Reference<XAccessible> xTempAcc = getAccessibleParent(); 547 if( xTempAcc.is() ) 548 { 549 ::com::sun::star::uno::Reference<XAccessibleContext> 550 xTempAccContext = xTempAcc->getAccessibleContext(); 551 if( xTempAccContext.is() ) 552 { 553 ::com::sun::star::uno::Reference<XAccessibleStateSet> rState = 554 xTempAccContext->getAccessibleStateSet(); 555 if( rState.is() ) { 556 com::sun::star::uno::Sequence<short> pStates = rState->getStates(); 557 int count = pStates.getLength(); 558 for( int iIndex = 0;iIndex < count;iIndex++ ) 559 { 560 if( pStates[iIndex] == AccessibleStateType::EDITABLE ) 561 { 562 pStateSet->AddState (AccessibleStateType::EDITABLE); 563 pStateSet->AddState (AccessibleStateType::RESIZABLE); 564 pStateSet->AddState (AccessibleStateType::MOVEABLE); 565 break; 566 } 567 } 568 } 569 } 570 } 571 //-----IAccessibility2 Implementation 2009 572 // Create a copy of the state set that may be modified by the 573 // caller without affecting the current state set. 574 xStateSet = Reference<XAccessibleStateSet>( 575 new ::utl::AccessibleStateSetHelper (*pStateSet)); 576 } 577 } 578 //IAccessibility2 Implementation 2009----- 579 UpdateDocumentAllSelState(xStateSet); 580 //-----IAccessibility2 Implementation 2009 581 return xStateSet; 582 } 583 584 585 586 587 //===== XAccessibleComponent ================================================ 588 589 /** The implementation below is at the moment straightforward. It iterates 590 over all children (and thereby instances all children which have not 591 been already instatiated) until a child covering the specifed point is 592 found. 593 This leaves room for improvement. For instance, first iterate only over 594 the already instantiated children and only if no match is found 595 instantiate the remaining ones. 596 */ 597 uno::Reference<XAccessible > SAL_CALL 598 AccessibleShape::getAccessibleAtPoint ( 599 const awt::Point& aPoint) 600 throw (uno::RuntimeException) 601 { 602 ::osl::MutexGuard aGuard (maMutex); 603 604 sal_Int32 nChildCount = getAccessibleChildCount (); 605 for (sal_Int32 i=0; i<nChildCount; ++i) 606 { 607 Reference<XAccessible> xChild (getAccessibleChild (i)); 608 if (xChild.is()) 609 { 610 Reference<XAccessibleComponent> xChildComponent ( 611 xChild->getAccessibleContext(), uno::UNO_QUERY); 612 if (xChildComponent.is()) 613 { 614 awt::Rectangle aBBox (xChildComponent->getBounds()); 615 if ( (aPoint.X >= aBBox.X) 616 && (aPoint.Y >= aBBox.Y) 617 && (aPoint.X < aBBox.X+aBBox.Width) 618 && (aPoint.Y < aBBox.Y+aBBox.Height) ) 619 return xChild; 620 } 621 } 622 } 623 624 // Have not found a child under the given point. Returning empty 625 // reference to indicate this. 626 return uno::Reference<XAccessible>(); 627 } 628 629 630 631 632 awt::Rectangle SAL_CALL AccessibleShape::getBounds (void) 633 throw (::com::sun::star::uno::RuntimeException) 634 { 635 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex()); 636 ::osl::MutexGuard aGuard (maMutex); 637 638 ThrowIfDisposed (); 639 awt::Rectangle aBoundingBox; 640 if ( mxShape.is() ) 641 { 642 643 static const OUString sBoundRectName ( 644 RTL_CONSTASCII_USTRINGPARAM("BoundRect")); 645 static const OUString sAnchorPositionName ( 646 RTL_CONSTASCII_USTRINGPARAM("AnchorPosition")); 647 648 // Get the shape's bounding box in internal coordinates (in 100th of 649 // mm). Use the property BoundRect. Only if that is not supported ask 650 // the shape for its position and size directly. 651 Reference<beans::XPropertySet> xSet (mxShape, uno::UNO_QUERY); 652 Reference<beans::XPropertySetInfo> xSetInfo; 653 bool bFoundBoundRect = false; 654 if (xSet.is()) 655 { 656 xSetInfo = xSet->getPropertySetInfo (); 657 if (xSetInfo.is()) 658 { 659 if (xSetInfo->hasPropertyByName (sBoundRectName)) 660 { 661 try 662 { 663 uno::Any aValue = xSet->getPropertyValue (sBoundRectName); 664 aValue >>= aBoundingBox; 665 bFoundBoundRect = true; 666 } 667 catch (beans::UnknownPropertyException e) 668 { 669 // Handled below (bFoundBoundRect stays false). 670 } 671 } 672 else 673 OSL_TRACE (" no property BoundRect"); 674 } 675 } 676 677 // Fallback when there is no BoundRect Property. 678 if ( ! bFoundBoundRect ) 679 { 680 awt::Point aPosition (mxShape->getPosition()); 681 awt::Size aSize (mxShape->getSize()); 682 aBoundingBox = awt::Rectangle ( 683 aPosition.X, aPosition.Y, 684 aSize.Width, aSize.Height); 685 686 // While BoundRects have absolute positions, the position returned 687 // by XPosition::getPosition is relative. Get the anchor position 688 // (usually not (0,0) for Writer shapes). 689 if (xSetInfo.is()) 690 { 691 if (xSetInfo->hasPropertyByName (sAnchorPositionName)) 692 { 693 uno::Any aPos = xSet->getPropertyValue (sAnchorPositionName); 694 awt::Point aAnchorPosition; 695 aPos >>= aAnchorPosition; 696 aBoundingBox.X += aAnchorPosition.X; 697 aBoundingBox.Y += aAnchorPosition.Y; 698 } 699 } 700 } 701 702 // Transform coordinates from internal to pixel. 703 if (maShapeTreeInfo.GetViewForwarder() == NULL) 704 throw uno::RuntimeException (::rtl::OUString ( 705 RTL_CONSTASCII_USTRINGPARAM( 706 "AccessibleShape has no valid view forwarder")), 707 static_cast<uno::XWeak*>(this)); 708 ::Size aPixelSize = maShapeTreeInfo.GetViewForwarder()->LogicToPixel ( 709 ::Size (aBoundingBox.Width, aBoundingBox.Height)); 710 ::Point aPixelPosition = maShapeTreeInfo.GetViewForwarder()->LogicToPixel ( 711 ::Point (aBoundingBox.X, aBoundingBox.Y)); 712 713 // Clip the shape's bounding box with the bounding box of its parent. 714 Reference<XAccessibleComponent> xParentComponent ( 715 getAccessibleParent(), uno::UNO_QUERY); 716 if (xParentComponent.is()) 717 { 718 // Make the coordinates relative to the parent. 719 awt::Point aParentLocation (xParentComponent->getLocationOnScreen()); 720 int x = aPixelPosition.getX() - aParentLocation.X; 721 int y = aPixelPosition.getY() - aParentLocation.Y; 722 723 /* // The following block is a workarround for bug #99889# (property 724 // BoundRect returnes coordinates relative to document window 725 // instead of absolute coordinates for shapes in Writer). Has to 726 // be removed as soon as bug is fixed. 727 728 // Use a non-null anchor position as flag that the shape is in a 729 // Writer document. 730 if (xSetInfo.is()) 731 if (xSetInfo->hasPropertyByName (sAnchorPositionName)) 732 { 733 uno::Any aPos = xSet->getPropertyValue (sAnchorPositionName); 734 awt::Point aAnchorPosition; 735 aPos >>= aAnchorPosition; 736 if (aAnchorPosition.X > 0) 737 { 738 x = aPixelPosition.getX(); 739 y = aPixelPosition.getY(); 740 } 741 } 742 // End of workarround. 743 */ 744 // Clip with parent (with coordinates relative to itself). 745 ::Rectangle aBBox ( 746 x, y, x + aPixelSize.getWidth(), y + aPixelSize.getHeight()); 747 awt::Size aParentSize (xParentComponent->getSize()); 748 ::Rectangle aParentBBox (0,0, aParentSize.Width, aParentSize.Height); 749 aBBox = aBBox.GetIntersection (aParentBBox); 750 aBoundingBox = awt::Rectangle ( 751 aBBox.getX(), 752 aBBox.getY(), 753 aBBox.getWidth(), 754 aBBox.getHeight()); 755 } 756 else 757 { 758 OSL_TRACE ("parent does not support component"); 759 aBoundingBox = awt::Rectangle ( 760 aPixelPosition.getX(), aPixelPosition.getY(), 761 aPixelSize.getWidth(), aPixelSize.getHeight()); 762 } 763 } 764 765 return aBoundingBox; 766 } 767 768 769 770 771 awt::Point SAL_CALL AccessibleShape::getLocation (void) 772 throw (::com::sun::star::uno::RuntimeException) 773 { 774 ThrowIfDisposed (); 775 awt::Rectangle aBoundingBox (getBounds()); 776 return awt::Point (aBoundingBox.X, aBoundingBox.Y); 777 } 778 779 780 781 782 awt::Point SAL_CALL AccessibleShape::getLocationOnScreen (void) 783 throw (::com::sun::star::uno::RuntimeException) 784 { 785 ThrowIfDisposed (); 786 787 // Get relative position... 788 awt::Point aLocation (getLocation ()); 789 790 // ... and add absolute position of the parent. 791 uno::Reference<XAccessibleComponent> xParentComponent ( 792 getAccessibleParent(), uno::UNO_QUERY); 793 if (xParentComponent.is()) 794 { 795 awt::Point aParentLocation (xParentComponent->getLocationOnScreen()); 796 aLocation.X += aParentLocation.X; 797 aLocation.Y += aParentLocation.Y; 798 } 799 else 800 OSL_TRACE ("getLocation: parent does not support XAccessibleComponent"); 801 return aLocation; 802 } 803 804 805 806 807 awt::Size SAL_CALL AccessibleShape::getSize (void) 808 throw (uno::RuntimeException) 809 { 810 ThrowIfDisposed (); 811 awt::Rectangle aBoundingBox (getBounds()); 812 return awt::Size (aBoundingBox.Width, aBoundingBox.Height); 813 } 814 815 816 817 818 sal_Int32 SAL_CALL AccessibleShape::getForeground (void) 819 throw (::com::sun::star::uno::RuntimeException) 820 { 821 ThrowIfDisposed (); 822 sal_Int32 nColor (0x0ffffffL); 823 824 try 825 { 826 uno::Reference<beans::XPropertySet> aSet (mxShape, uno::UNO_QUERY); 827 if (aSet.is()) 828 { 829 uno::Any aColor; 830 aColor = aSet->getPropertyValue (OUString::createFromAscii ("LineColor")); 831 aColor >>= nColor; 832 } 833 } 834 catch (::com::sun::star::beans::UnknownPropertyException) 835 { 836 // Ignore exception and return default color. 837 } 838 return nColor; 839 } 840 841 842 843 844 sal_Int32 SAL_CALL AccessibleShape::getBackground (void) 845 throw (::com::sun::star::uno::RuntimeException) 846 { 847 ThrowIfDisposed (); 848 sal_Int32 nColor (0L); 849 850 try 851 { 852 uno::Reference<beans::XPropertySet> aSet (mxShape, uno::UNO_QUERY); 853 if (aSet.is()) 854 { 855 uno::Any aColor; 856 aColor = aSet->getPropertyValue (OUString::createFromAscii ("FillColor")); 857 aColor >>= nColor; 858 //IAccessibility2 Implementation 2009----- 859 aColor = aSet->getPropertyValue (OUString::createFromAscii ("FillTransparence")); 860 short nTrans=0; 861 aColor >>= nTrans; 862 Color crBk(nColor); 863 if (nTrans == 0 ) 864 { 865 crBk.SetTransparency(0xff); 866 } 867 else 868 { 869 nTrans = short(256 - nTrans / 100. * 256); 870 crBk.SetTransparency(sal_uInt8(nTrans)); 871 } 872 nColor = crBk.GetColor(); 873 //-----IAccessibility2 Implementation 2009 874 } 875 } 876 catch (::com::sun::star::beans::UnknownPropertyException) 877 { 878 // Ignore exception and return default color. 879 } 880 return nColor; 881 } 882 883 884 885 886 //===== XAccessibleEventBroadcaster ========================================= 887 888 void SAL_CALL AccessibleShape::addEventListener ( 889 const Reference<XAccessibleEventListener >& rxListener) 890 throw (uno::RuntimeException) 891 { 892 if (rBHelper.bDisposed || rBHelper.bInDispose) 893 { 894 uno::Reference<uno::XInterface> xThis ( 895 (lang::XComponent *)this, uno::UNO_QUERY); 896 rxListener->disposing (lang::EventObject (xThis)); 897 } 898 else 899 { 900 AccessibleContextBase::addEventListener (rxListener); 901 if (mpText != NULL) 902 mpText->AddEventListener (rxListener); 903 } 904 } 905 906 907 908 909 void SAL_CALL AccessibleShape::removeEventListener ( 910 const Reference<XAccessibleEventListener >& rxListener) 911 throw (uno::RuntimeException) 912 { 913 AccessibleContextBase::removeEventListener (rxListener); 914 if (mpText != NULL) 915 mpText->RemoveEventListener (rxListener); 916 } 917 918 919 920 921 //===== XInterface ========================================================== 922 923 com::sun::star::uno::Any SAL_CALL 924 AccessibleShape::queryInterface (const com::sun::star::uno::Type & rType) 925 throw (::com::sun::star::uno::RuntimeException) 926 { 927 ::com::sun::star::uno::Any aReturn = AccessibleContextBase::queryInterface (rType); 928 if ( ! aReturn.hasValue()) 929 aReturn = ::cppu::queryInterface (rType, 930 static_cast<XAccessibleComponent*>(this), 931 static_cast<XAccessibleExtendedComponent*>(this), 932 //IAccessibility2 Implementation 2009----- 933 static_cast< ::com::sun::star::accessibility::XAccessibleSelection* >(this), 934 935 static_cast< ::com::sun::star::accessibility::XAccessibleExtendedAttributes* >(this), 936 //-----IAccessibility2 Implementation 2009 937 static_cast<lang::XEventListener*>(this), 938 static_cast<document::XEventListener*>(this), 939 static_cast<lang::XUnoTunnel*>(this), 940 //IAccessibility2 Implementation 2009----- 941 static_cast<XAccessibleGroupPosition*>(this), 942 static_cast<XAccessibleHypertext*>(this) 943 //-----IAccessibility2 Implementation 2009 944 ); 945 return aReturn; 946 } 947 948 949 950 951 void SAL_CALL 952 AccessibleShape::acquire (void) 953 throw () 954 { 955 AccessibleContextBase::acquire (); 956 } 957 958 959 960 961 void SAL_CALL 962 AccessibleShape::release (void) 963 throw () 964 { 965 AccessibleContextBase::release (); 966 } 967 //IAccessibility2 Implementation 2009----- 968 // 969 //===== XAccessibleSelection ============================================ 970 // 971 972 //-------------------------------------------------------------------------------- 973 void SAL_CALL AccessibleShape::selectAccessibleChild( sal_Int32 ) 974 throw ( IndexOutOfBoundsException, RuntimeException ) 975 { 976 } 977 978 //---------------------------------------------------------------------------------- 979 sal_Bool SAL_CALL AccessibleShape::isAccessibleChildSelected( sal_Int32 nChildIndex ) 980 throw ( IndexOutOfBoundsException, 981 RuntimeException ) 982 { 983 uno::Reference<XAccessible> xAcc = getAccessibleChild( nChildIndex ); 984 uno::Reference<XAccessibleContext> xContext; 985 if( xAcc.is() ) 986 { 987 xContext = xAcc->getAccessibleContext(); 988 } 989 990 if( xContext.is() ) 991 { 992 if( xContext->getAccessibleRole() == AccessibleRole::PARAGRAPH ) 993 { 994 uno::Reference< ::com::sun::star::accessibility::XAccessibleText > 995 xText(xAcc, uno::UNO_QUERY); 996 if( xText.is() ) 997 { 998 if( xText->getSelectionStart() >= 0 ) return sal_True; 999 } 1000 } 1001 else if( xContext->getAccessibleRole() == AccessibleRole::SHAPE ) 1002 { 1003 Reference< XAccessibleStateSet > pRState = xContext->getAccessibleStateSet(); 1004 if( !pRState.is() ) 1005 return sal_False; 1006 1007 uno::Sequence<short> pStates = pRState->getStates(); 1008 int nCount = pStates.getLength(); 1009 for( int i = 0; i < nCount; i++ ) 1010 { 1011 if(pStates[i] == AccessibleStateType::SELECTED) 1012 return sal_True; 1013 } 1014 return sal_False; 1015 } 1016 } 1017 1018 return sal_False; 1019 } 1020 1021 //--------------------------------------------------------------------- 1022 void SAL_CALL AccessibleShape::clearAccessibleSelection( ) 1023 throw ( RuntimeException ) 1024 { 1025 } 1026 1027 //------------------------------------------------------------------------- 1028 void SAL_CALL AccessibleShape::selectAllAccessibleChildren( ) 1029 throw ( RuntimeException ) 1030 { 1031 } 1032 1033 //---------------------------------------------------------------------------- 1034 sal_Int32 SAL_CALL AccessibleShape::getSelectedAccessibleChildCount() 1035 throw ( RuntimeException ) 1036 { 1037 sal_Int32 nCount = 0; 1038 sal_Int32 TotalCount = getAccessibleChildCount(); 1039 for( sal_Int32 i = 0; i < TotalCount; i++ ) 1040 if( isAccessibleChildSelected(i) ) nCount++; 1041 1042 return nCount; 1043 } 1044 1045 //-------------------------------------------------------------------------------------- 1046 Reference<XAccessible> SAL_CALL AccessibleShape::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) 1047 throw ( IndexOutOfBoundsException, RuntimeException) 1048 { 1049 if ( nSelectedChildIndex > getSelectedAccessibleChildCount() ) 1050 throw IndexOutOfBoundsException(); 1051 sal_Int32 i1, i2; 1052 for( i1 = 0, i2 = 0; i1 < getAccessibleChildCount(); i1++ ) 1053 if( isAccessibleChildSelected(i1) ) 1054 { 1055 if( i2 == nSelectedChildIndex ) 1056 return getAccessibleChild( i1 ); 1057 i2++; 1058 } 1059 return Reference<XAccessible>(); 1060 } 1061 1062 //---------------------------------------------------------------------------------- 1063 void SAL_CALL AccessibleShape::deselectAccessibleChild( sal_Int32 ) 1064 throw ( IndexOutOfBoundsException, 1065 RuntimeException ) 1066 { 1067 1068 } 1069 1070 //===== XAccessibleExtendedAttributes ======================================================== 1071 uno::Any SAL_CALL AccessibleShape::getExtendedAttributes() 1072 throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) 1073 { 1074 uno::Any strRet; 1075 ::rtl::OUString style; 1076 if( getAccessibleRole() != AccessibleRole::SHAPE ) return strRet; 1077 if( m_pShape ) 1078 { 1079 //style = ::rtl::OUString::createFromAscii("style="); 1080 style = ::rtl::OUString::createFromAscii("style:"); 1081 style += GetStyle(); 1082 } 1083 style += ::rtl::OUString::createFromAscii(";"); 1084 strRet <<= style; 1085 return strRet; 1086 } 1087 //-----IAccessibility2 Implementation 2009 1088 //===== XServiceInfo ======================================================== 1089 1090 ::rtl::OUString SAL_CALL 1091 AccessibleShape::getImplementationName (void) 1092 throw (::com::sun::star::uno::RuntimeException) 1093 { 1094 return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleShape")); 1095 } 1096 1097 1098 1099 1100 uno::Sequence<OUString> SAL_CALL 1101 AccessibleShape::getSupportedServiceNames (void) 1102 throw (::com::sun::star::uno::RuntimeException) 1103 { 1104 ThrowIfDisposed (); 1105 // Get list of supported service names from base class... 1106 uno::Sequence<OUString> aServiceNames = 1107 AccessibleContextBase::getSupportedServiceNames(); 1108 sal_Int32 nCount (aServiceNames.getLength()); 1109 1110 // ...and add additional names. 1111 aServiceNames.realloc (nCount + 1); 1112 static const OUString sAdditionalServiceName (RTL_CONSTASCII_USTRINGPARAM( 1113 "com.sun.star.drawing.AccessibleShape")); 1114 aServiceNames[nCount] = sAdditionalServiceName; 1115 1116 return aServiceNames; 1117 } 1118 1119 1120 1121 1122 1123 //===== XTypeProvider =================================================== 1124 1125 uno::Sequence<uno::Type> SAL_CALL 1126 AccessibleShape::getTypes (void) 1127 throw (uno::RuntimeException) 1128 { 1129 ThrowIfDisposed (); 1130 // Get list of types from the context base implementation, ... 1131 uno::Sequence<uno::Type> aTypeList (AccessibleContextBase::getTypes()); 1132 // ... get list of types from component base implementation, ... 1133 uno::Sequence<uno::Type> aComponentTypeList (AccessibleComponentBase::getTypes()); 1134 // ... define local types, ... 1135 const uno::Type aLangEventListenerType = 1136 ::getCppuType((const uno::Reference<lang::XEventListener>*)0); 1137 const uno::Type aDocumentEventListenerType = 1138 ::getCppuType((const uno::Reference<document::XEventListener>*)0); 1139 const uno::Type aUnoTunnelType = 1140 ::getCppuType((const uno::Reference<lang::XUnoTunnel>*)0); 1141 // const uno::Type aStateSetType = 1142 // ::getCppuType((const uno::Reference<XAccessibleStateSet>*)0); 1143 1144 // ... and merge them all into one list. 1145 sal_Int32 nTypeCount (aTypeList.getLength()), 1146 nComponentTypeCount (aComponentTypeList.getLength()); 1147 int i; 1148 1149 aTypeList.realloc (nTypeCount + nComponentTypeCount + 3); 1150 1151 for (i=0; i<nComponentTypeCount; i++) 1152 aTypeList[nTypeCount + i] = aComponentTypeList[i]; 1153 1154 aTypeList[nTypeCount + i++ ] = aLangEventListenerType; 1155 aTypeList[nTypeCount + i++ ] = aDocumentEventListenerType; 1156 aTypeList[nTypeCount + i ] = aUnoTunnelType; 1157 1158 return aTypeList; 1159 } 1160 1161 1162 1163 1164 //===== lang::XEventListener ================================================ 1165 1166 /** Disposing calls are accepted only from the model: Just reset the 1167 reference to the model in the shape tree info. Otherwise this object 1168 remains functional. 1169 */ 1170 void SAL_CALL 1171 AccessibleShape::disposing (const lang::EventObject& aEvent) 1172 throw (uno::RuntimeException) 1173 { 1174 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex()); 1175 ::osl::MutexGuard aGuard (maMutex); 1176 1177 try 1178 { 1179 if (aEvent.Source == maShapeTreeInfo.GetModelBroadcaster()) 1180 { 1181 // Remove reference to model broadcaster to allow it to pass 1182 // away. 1183 maShapeTreeInfo.SetModelBroadcaster(NULL); 1184 } 1185 1186 } 1187 catch (uno::RuntimeException e) 1188 { 1189 OSL_TRACE ("caught exception while disposing"); 1190 } 1191 } 1192 1193 1194 1195 1196 //===== document::XEventListener ============================================ 1197 1198 void SAL_CALL 1199 AccessibleShape::notifyEvent (const document::EventObject& rEventObject) 1200 throw (uno::RuntimeException) 1201 { 1202 static const OUString sShapeModified ( 1203 RTL_CONSTASCII_USTRINGPARAM("ShapeModified")); 1204 1205 // First check if the event is for us. 1206 uno::Reference<drawing::XShape> xShape ( 1207 rEventObject.Source, uno::UNO_QUERY); 1208 if ( xShape.get() == mxShape.get() ) 1209 { 1210 if (rEventObject.EventName.equals (sShapeModified)) 1211 { 1212 //Need to update text children when receiving ShapeModified hint when exiting edit mode for text box 1213 if (mpText) 1214 mpText->UpdateChildren(); 1215 1216 1217 // Some property of a shape has been modified. Send an event 1218 // that indicates a change of the visible data to all listeners. 1219 CommitChange ( 1220 AccessibleEventId::VISIBLE_DATA_CHANGED, 1221 uno::Any(), 1222 uno::Any()); 1223 1224 // Name and Description may have changed. Update the local 1225 // values accordingly. 1226 UpdateNameAndDescription(); 1227 } 1228 } 1229 } 1230 1231 1232 1233 1234 //===== lang::XUnoTunnel ================================================ 1235 1236 const uno::Sequence< sal_Int8 >& 1237 AccessibleShape::getUnoTunnelImplementationId() 1238 throw() 1239 { 1240 static uno::Sequence< sal_Int8 >* pSeq = 0; 1241 1242 if( !pSeq ) 1243 { 1244 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); 1245 1246 if( !pSeq ) 1247 { 1248 static uno::Sequence< sal_Int8 > aSeq( 16 ); 1249 rtl_createUuid( (sal_uInt8*) aSeq.getArray(), 0, sal_True ); 1250 pSeq = &aSeq; 1251 } 1252 } 1253 1254 return( *pSeq ); 1255 } 1256 1257 //------------------------------------------------------------------------------ 1258 AccessibleShape* 1259 AccessibleShape::getImplementation( const uno::Reference< uno::XInterface >& rxIFace ) 1260 throw() 1261 { 1262 uno::Reference< lang::XUnoTunnel > xTunnel( rxIFace, uno::UNO_QUERY ); 1263 AccessibleShape* pReturn = NULL; 1264 1265 if( xTunnel.is() ) 1266 pReturn = reinterpret_cast< AccessibleShape* >( xTunnel->getSomething( getUnoTunnelImplementationId() ) ); 1267 1268 return( pReturn ); 1269 } 1270 1271 //------------------------------------------------------------------------------ 1272 sal_Int64 SAL_CALL 1273 AccessibleShape::getSomething( const uno::Sequence< sal_Int8 >& rIdentifier ) 1274 throw(uno::RuntimeException) 1275 { 1276 sal_Int64 nReturn( 0 ); 1277 1278 if( ( rIdentifier.getLength() == 16 ) && ( 0 == rtl_compareMemory( getUnoTunnelImplementationId().getConstArray(), rIdentifier.getConstArray(), 16 ) ) ) 1279 nReturn = reinterpret_cast< sal_Int64 >( this ); 1280 1281 return( nReturn ); 1282 } 1283 1284 //===== IAccessibleViewForwarderListener ==================================== 1285 1286 void AccessibleShape::ViewForwarderChanged (ChangeType aChangeType, 1287 const IAccessibleViewForwarder* pViewForwarder) 1288 { 1289 // Inform all listeners that the graphical representation (i.e. size 1290 // and/or position) of the shape has changed. 1291 CommitChange (AccessibleEventId::VISIBLE_DATA_CHANGED, 1292 uno::Any(), 1293 uno::Any()); 1294 1295 // Tell children manager of the modified view forwarder. 1296 if (mpChildrenManager != NULL) 1297 mpChildrenManager->ViewForwarderChanged (aChangeType, pViewForwarder); 1298 1299 // update our children that our screen position might have changed 1300 if( mpText ) 1301 mpText->UpdateChildren(); 1302 } 1303 1304 1305 1306 1307 //===== protected internal ================================================== 1308 /// Set this object's name if is different to the current name. 1309 ::rtl::OUString 1310 AccessibleShape::CreateAccessibleBaseName (void) 1311 throw (::com::sun::star::uno::RuntimeException) 1312 { 1313 return ShapeTypeHandler::CreateAccessibleBaseName( mxShape ); 1314 } 1315 1316 1317 ::rtl::OUString 1318 AccessibleShape::CreateAccessibleName (void) 1319 throw (::com::sun::star::uno::RuntimeException) 1320 { 1321 //OUString sName (CreateAccessibleBaseName()); 1322 //IAccessibility2 Implementation 2009----- 1323 OUString sName; 1324 sName = GetFullAccessibleName(this); 1325 return sName; 1326 } 1327 1328 ::rtl::OUString 1329 AccessibleShape::GetFullAccessibleName (AccessibleShape *shape) 1330 throw (::com::sun::star::uno::RuntimeException) 1331 { 1332 OUString sName (shape->CreateAccessibleBaseName()); 1333 // Append the shape's index to the name to disambiguate between shapes 1334 // of the same type. If such an index where not given to the 1335 // constructor then use the z-order instead. If even that does not exist 1336 // we throw an exception. 1337 //long nIndex = mnIndex; 1338 //if (nIndex == -1) 1339 //{ 1340 // try 1341 // { 1342 // uno::Reference<beans::XPropertySet> xSet (mxShape, uno::UNO_QUERY); 1343 // if (xSet.is()) 1344 // { 1345 // uno::Any aZOrder (xSet->getPropertyValue (::rtl::OUString::createFromAscii ("ZOrder"))); 1346 // aZOrder >>= nIndex; 1347 1348 // // Add one to be not zero based. 1349 // nIndex += 1; 1350 // } 1351 // } 1352 // catch (beans::UnknownPropertyException) 1353 // { 1354 // // We throw our own exception that is a bit more informative. 1355 // throw uno::RuntimeException (::rtl::OUString ( 1356 // RTL_CONSTASCII_USTRINGPARAM("AccessibleShape has invalid index and no ZOrder property")), 1357 // static_cast<uno::XWeak*>(this)); 1358 // } 1359 1360 //} 1361 1362 //// Put a space between name and index because of Gnopernicus othewise 1363 //// spells the name. 1364 //sName += OUString (RTL_CONSTASCII_USTRINGPARAM(" ")) + OUString::valueOf (nIndex); 1365 1366 //return sName; 1367 1368 XubString nameStr; 1369 if(shape->m_pShape) 1370 nameStr = shape->m_pShape->GetName(); 1371 if(nameStr.Len() == 0) 1372 { 1373 sName += OUString( RTL_CONSTASCII_USTRINGPARAM( " " )); 1374 } 1375 else 1376 { 1377 sName = nameStr; 1378 } 1379 /* 1380 sal_Int32 nChildCount = shape->getAccessibleChildCount(); 1381 if(nChildCount > 0) 1382 { 1383 for (sal_Int32 i=0; i<nChildCount; ++i) 1384 { 1385 Reference<XAccessible> xChild (shape->getAccessibleChild (i)); 1386 if (xChild.is()) 1387 { 1388 uno::Reference <XAccessibleContext> xChildContext(xChild->getAccessibleContext()); 1389 if (xChildContext->getAccessibleRole() == AccessibleRole::PARAGRAPH) 1390 { 1391 uno::Reference<XAccessibleText> xText = uno::Reference<XAccessibleText> ( xChild, uno::UNO_QUERY ); 1392 sName += OUString( RTL_CONSTASCII_USTRINGPARAM( " " )) + xText->getText(); 1393 } 1394 else if (xChildContext->getAccessibleRole() == AccessibleRole::SHAPE) 1395 { 1396 sName += OUString( RTL_CONSTASCII_USTRINGPARAM( " " )) + GetFullAccessibleName(static_cast< AccessibleShape*>( xChild.get())); 1397 } 1398 } 1399 } 1400 } 1401 */ 1402 //Solution:If the new produced name if not the same with last,notify name changed 1403 // Event 1404 if( aAccName != sName && aAccName.getLength() != 0 ) 1405 { 1406 uno::Any aOldValue, aNewValue; 1407 aOldValue <<= aAccName; 1408 aNewValue <<= sName; 1409 CommitChange( 1410 AccessibleEventId::NAME_CHANGED, 1411 aNewValue, 1412 aOldValue); 1413 } 1414 aAccName = sName; 1415 return sName; 1416 } 1417 //-----IAccessibility2 Implementation 2009 1418 ::rtl::OUString 1419 AccessibleShape::CreateAccessibleDescription (void) 1420 throw (::com::sun::star::uno::RuntimeException) 1421 { 1422 DescriptionGenerator aDG (mxShape); 1423 aDG.Initialize (CreateAccessibleBaseName()); 1424 switch (ShapeTypeHandler::Instance().GetTypeId (mxShape)) 1425 { 1426 case DRAWING_3D_CUBE: 1427 case DRAWING_3D_EXTRUDE: 1428 case DRAWING_3D_LATHE: 1429 case DRAWING_3D_SPHERE: 1430 aDG.Add3DProperties (); 1431 break; 1432 1433 case DRAWING_3D_SCENE: 1434 case DRAWING_GROUP: 1435 case DRAWING_PAGE: 1436 // No further information is appended. 1437 break; 1438 1439 case DRAWING_CAPTION: 1440 case DRAWING_CLOSED_BEZIER: 1441 case DRAWING_CLOSED_FREEHAND: 1442 case DRAWING_ELLIPSE: 1443 case DRAWING_POLY_POLYGON: 1444 case DRAWING_POLY_POLYGON_PATH: 1445 case DRAWING_RECTANGLE: 1446 aDG.AddLineProperties (); 1447 aDG.AddFillProperties (); 1448 break; 1449 1450 case DRAWING_CONNECTOR: 1451 case DRAWING_LINE: 1452 case DRAWING_MEASURE: 1453 case DRAWING_OPEN_BEZIER: 1454 case DRAWING_OPEN_FREEHAND: 1455 case DRAWING_POLY_LINE: 1456 case DRAWING_POLY_LINE_PATH: 1457 aDG.AddLineProperties (); 1458 break; 1459 1460 case DRAWING_CONTROL: 1461 aDG.AddProperty (OUString::createFromAscii ("ControlBackground"), 1462 DescriptionGenerator::COLOR, 1463 OUString()); 1464 aDG.AddProperty (OUString::createFromAscii ("ControlBorder"), 1465 DescriptionGenerator::INTEGER, 1466 OUString()); 1467 break; 1468 1469 case DRAWING_TEXT: 1470 aDG.AddTextProperties (); 1471 break; 1472 1473 default: 1474 aDG.Initialize (::rtl::OUString ( 1475 RTL_CONSTASCII_USTRINGPARAM("Unknown accessible shape"))); 1476 uno::Reference<drawing::XShapeDescriptor> xDescriptor (mxShape, uno::UNO_QUERY); 1477 if (xDescriptor.is()) 1478 { 1479 aDG.AppendString (::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("service name="))); 1480 aDG.AppendString (xDescriptor->getShapeType()); 1481 } 1482 } 1483 1484 return aDG(); 1485 } 1486 1487 1488 1489 1490 uno::Reference< drawing::XShape > AccessibleShape::GetXShape() 1491 { 1492 return( mxShape ); 1493 } 1494 1495 1496 1497 // protected 1498 void AccessibleShape::disposing (void) 1499 { 1500 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex()); 1501 ::osl::MutexGuard aGuard (maMutex); 1502 1503 // Make sure to send an event that this object looses the focus in the 1504 // case that it has the focus. 1505 ::utl::AccessibleStateSetHelper* pStateSet = 1506 static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get()); 1507 if (pStateSet != NULL) 1508 pStateSet->RemoveState (AccessibleStateType::FOCUSED); 1509 1510 // Unregister from broadcasters. 1511 Reference<lang::XComponent> xComponent (mxShape, uno::UNO_QUERY); 1512 if (xComponent.is()) 1513 xComponent->removeEventListener (this); 1514 1515 // Unregister from model. 1516 if (maShapeTreeInfo.GetModelBroadcaster().is()) 1517 maShapeTreeInfo.GetModelBroadcaster()->removeEventListener ( 1518 static_cast<document::XEventListener*>(this)); 1519 1520 // Release the child containers. 1521 if (mpChildrenManager != NULL) 1522 { 1523 delete mpChildrenManager; 1524 mpChildrenManager = NULL; 1525 } 1526 if (mpText != NULL) 1527 { 1528 mpText->Dispose(); 1529 delete mpText; 1530 mpText = NULL; 1531 } 1532 1533 // Cleanup. Remove references to objects to allow them to be 1534 // destroyed. 1535 mxShape = NULL; 1536 maShapeTreeInfo = AccessibleShapeTreeInfo(); 1537 1538 // Call base classes. 1539 AccessibleContextBase::dispose (); 1540 } 1541 1542 sal_Int32 SAL_CALL 1543 AccessibleShape::getAccessibleIndexInParent (void) 1544 throw (::com::sun::star::uno::RuntimeException) 1545 { 1546 ThrowIfDisposed (); 1547 // Use a simple but slow solution for now. Optimize later. 1548 1549 sal_Int32 nIndex = m_nIndexInParent; 1550 if ( -1 == nIndex ) 1551 nIndex = AccessibleContextBase::getAccessibleIndexInParent(); 1552 return nIndex; 1553 } 1554 1555 1556 1557 1558 void AccessibleShape::UpdateNameAndDescription (void) 1559 { 1560 // Ignore missing title, name, or description. There are fallbacks for 1561 // them. 1562 try 1563 { 1564 Reference<beans::XPropertySet> xSet (mxShape, uno::UNO_QUERY_THROW); 1565 OUString sString; 1566 1567 // Get the accessible name. 1568 sString = GetOptionalProperty(xSet, OUString(RTL_CONSTASCII_USTRINGPARAM("Title"))); 1569 if (sString.getLength() > 0) 1570 { 1571 SetAccessibleName(sString, AccessibleContextBase::FromShape); 1572 } 1573 else 1574 { 1575 sString = GetOptionalProperty(xSet, OUString(RTL_CONSTASCII_USTRINGPARAM("Name"))); 1576 if (sString.getLength() > 0) 1577 SetAccessibleName(sString, AccessibleContextBase::FromShape); 1578 } 1579 1580 // Get the accessible description. 1581 sString = GetOptionalProperty(xSet, OUString(RTL_CONSTASCII_USTRINGPARAM("Description"))); 1582 if (sString.getLength() > 0) 1583 SetAccessibleDescription(sString, AccessibleContextBase::FromShape); 1584 } 1585 catch (uno::RuntimeException&) 1586 { 1587 } 1588 } 1589 //IAccessibility2 Implementation 2009----- 1590 // Return this object's role. 1591 sal_Int16 SAL_CALL AccessibleShape::getAccessibleRole (void) 1592 throw (::com::sun::star::uno::RuntimeException) 1593 { 1594 sal_Int16 nAccessibleRole = AccessibleRole::SHAPE ; 1595 switch (ShapeTypeHandler::Instance().GetTypeId (mxShape)) 1596 { 1597 case DRAWING_GRAPHIC_OBJECT: 1598 nAccessibleRole = AccessibleRole::GRAPHIC ; break; 1599 case DRAWING_OLE: 1600 nAccessibleRole = AccessibleRole::EMBEDDED_OBJECT ; break; 1601 1602 default: 1603 nAccessibleRole = AccessibleContextBase::getAccessibleRole(); 1604 break; 1605 } 1606 1607 return nAccessibleRole; 1608 } 1609 1610 1611 void AccessibleShape::UpdateDocumentAllSelState(Reference<XAccessibleStateSet> &xStateSet) 1612 { 1613 if (mpParent && mpParent->IsDocumentSelAll()) 1614 { 1615 ::utl::AccessibleStateSetHelper* pStateSet = 1616 static_cast< ::utl::AccessibleStateSetHelper*>(xStateSet.get()); 1617 pStateSet->AddState (AccessibleStateType::SELECTED); 1618 1619 //uno::Any NewValue; 1620 //NewValue <<= AccessibleStateType::SELECTED; 1621 1622 //CommitChange(AccessibleEventId::STATE_CHANGED,NewValue,uno::Any()); 1623 } 1624 } 1625 1626 //sort the drawing objects from up to down, from left to right 1627 struct XShapePosCompareHelper 1628 { 1629 bool operator() ( const uno::Reference<drawing::XShape>& xshape1, 1630 const uno::Reference<drawing::XShape>& xshape2 ) const 1631 { 1632 SdrObject* pObj1 = GetSdrObjectFromXShape(xshape1); 1633 SdrObject* pObj2 = GetSdrObjectFromXShape(xshape2); 1634 if(pObj1 && pObj2) 1635 return pObj1->GetOrdNum() < pObj2->GetOrdNum(); 1636 else 1637 return 0; 1638 } 1639 }; 1640 //end of group position 1641 1642 //===== XAccessibleGroupPosition ========================================= 1643 uno::Sequence< sal_Int32 > SAL_CALL 1644 AccessibleShape::getGroupPosition( const uno::Any& ) 1645 throw (uno::RuntimeException) 1646 { 1647 // we will return the: 1648 // [0] group level 1649 // [1] similar items counts in the group 1650 // [2] the position of the object in the group 1651 uno::Sequence< sal_Int32 > aRet( 3 ); 1652 aRet[0] = 0; 1653 aRet[1] = 0; 1654 aRet[2] = 0; 1655 1656 ::com::sun::star::uno::Reference<XAccessible> xParent = getAccessibleParent(); 1657 if (!xParent.is()) 1658 { 1659 return aRet; 1660 } 1661 SdrObject *pObj = GetSdrObjectFromXShape(mxShape); 1662 1663 1664 if(pObj == NULL ) 1665 { 1666 return aRet; 1667 } 1668 1669 // Compute object's group level. 1670 sal_Int32 nGroupLevel = 0; 1671 SdrObject * pUper = pObj->GetUpGroup(); 1672 while( pUper ) 1673 { 1674 ++nGroupLevel; 1675 pUper = pUper->GetUpGroup(); 1676 } 1677 1678 ::com::sun::star::uno::Reference<XAccessibleContext> xParentContext = xParent->getAccessibleContext(); 1679 if( xParentContext->getAccessibleRole() == AccessibleRole::DOCUMENT)//Document 1680 { 1681 Reference< XAccessibleGroupPosition > xGroupPosition( xParent,uno::UNO_QUERY ); 1682 if ( xGroupPosition.is() ) 1683 { 1684 aRet = xGroupPosition->getGroupPosition( uno::makeAny( getAccessibleContext() ) ); 1685 } 1686 return aRet; 1687 } 1688 if (xParentContext->getAccessibleRole() != AccessibleRole::SHAPE) 1689 { 1690 return aRet; 1691 } 1692 1693 SdrObjList *pGrpList = NULL; 1694 if( pObj->GetUpGroup() ) 1695 pGrpList = pObj->GetUpGroup()->GetSubList(); 1696 else 1697 return aRet; 1698 1699 std::vector< uno::Reference<drawing::XShape> > vXShapes; 1700 if (pGrpList) 1701 { 1702 const sal_Int32 nObj = pGrpList->GetObjCount(); 1703 for(sal_Int32 i = 0 ; i < nObj ; ++i) 1704 { 1705 SdrObject *pSubObj = pGrpList->GetObj(i); 1706 //IAccessibility2 Implementation 2009----- 1707 if (pSubObj && 1708 xParentContext->getAccessibleChild(i)->getAccessibleContext()->getAccessibleRole() != AccessibleRole::GROUP_BOX) 1709 //-----IAccessibility2 Implementation 2009 1710 { 1711 vXShapes.push_back( GetXShapeForSdrObject(pSubObj) ); 1712 } 1713 } 1714 } 1715 1716 std::sort( vXShapes.begin(), vXShapes.end(), XShapePosCompareHelper() ); 1717 1718 //get the the index of the selected object in the group 1719 std::vector< uno::Reference<drawing::XShape> >::iterator aIter; 1720 //we start counting position from 1 1721 sal_Int32 nPos = 1; 1722 for ( aIter = vXShapes.begin(); aIter != vXShapes.end(); aIter++, nPos++ ) 1723 { 1724 if ( (*aIter).get() == mxShape.get() ) 1725 { 1726 sal_Int32* pArray = aRet.getArray(); 1727 pArray[0] = nGroupLevel; 1728 pArray[1] = vXShapes.size(); 1729 pArray[2] = nPos; 1730 break; 1731 } 1732 } 1733 1734 return aRet; 1735 } 1736 1737 ::rtl::OUString AccessibleShape::getObjectLink( const uno::Any& ) 1738 throw (uno::RuntimeException) 1739 { 1740 ::rtl::OUString aRet; 1741 1742 SdrObject *pObj = GetSdrObjectFromXShape(mxShape); 1743 if(pObj == NULL ) 1744 { 1745 return aRet; 1746 } 1747 if (maShapeTreeInfo.GetDocumentWindow().is()) 1748 { 1749 Reference< XAccessibleGroupPosition > xGroupPosition( maShapeTreeInfo.GetDocumentWindow(), uno::UNO_QUERY ); 1750 if (xGroupPosition.is()) 1751 { 1752 aRet = xGroupPosition->getObjectLink( uno::makeAny( getAccessibleContext() ) ); 1753 } 1754 } 1755 return aRet; 1756 } 1757 1758 //===== XAccesibleHypertext ================================================== 1759 sal_Int32 SAL_CALL AccessibleShape::getHyperLinkCount() 1760 throw (::com::sun::star::uno::RuntimeException) 1761 { 1762 // MT: Introduced with IA2 CWS, but SvxAccessibleHyperlink was redundant to svx::AccessibleHyperlink which we introduced meanwhile. 1763 // Code need to be adapted.... 1764 return 0; 1765 1766 /* 1767 SvxAccessibleHyperlink* pLink = new SvxAccessibleHyperlink(m_pShape,this); 1768 if (pLink->IsValidHyperlink()) 1769 return 1; 1770 else 1771 return 0; 1772 */ 1773 } 1774 uno::Reference< XAccessibleHyperlink > SAL_CALL 1775 AccessibleShape::getHyperLink( sal_Int32 ) 1776 throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) 1777 { 1778 uno::Reference< XAccessibleHyperlink > xRet; 1779 // MT: Introduced with IA2 CWS, but SvxAccessibleHyperlink was redundant to svx::AccessibleHyperlink which we introduced meanwhile. 1780 // Code need to be adapted.... 1781 /* 1782 SvxAccessibleHyperlink* pLink = new SvxAccessibleHyperlink(m_pShape,this); 1783 if (pLink->IsValidHyperlink()) 1784 xRet = pLink; 1785 if( !xRet.is() ) 1786 throw ::com::sun::star::lang::IndexOutOfBoundsException(); 1787 */ 1788 return xRet; 1789 } 1790 sal_Int32 SAL_CALL AccessibleShape::getHyperLinkIndex( sal_Int32 ) 1791 throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) 1792 { 1793 sal_Int32 nRet = 0; 1794 return nRet; 1795 } 1796 //===== XAccesibleText ================================================== 1797 sal_Int32 SAL_CALL AccessibleShape::getCaretPosition( ) throw (::com::sun::star::uno::RuntimeException){return 0;} 1798 sal_Bool SAL_CALL AccessibleShape::setCaretPosition( sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException){return 0;} 1799 sal_Unicode SAL_CALL AccessibleShape::getCharacter( sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException){return 0;} 1800 ::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) 1801 { 1802 uno::Sequence< ::com::sun::star::beans::PropertyValue > aValues(0); 1803 return aValues; 1804 } 1805 ::com::sun::star::awt::Rectangle SAL_CALL AccessibleShape::getCharacterBounds( sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) 1806 { 1807 return com::sun::star::awt::Rectangle(0, 0, 0, 0 ); 1808 } 1809 sal_Int32 SAL_CALL AccessibleShape::getCharacterCount( ) throw (::com::sun::star::uno::RuntimeException){return 0;} 1810 sal_Int32 SAL_CALL AccessibleShape::getIndexAtPoint( const ::com::sun::star::awt::Point& ) throw (::com::sun::star::uno::RuntimeException){return 0;} 1811 ::rtl::OUString SAL_CALL AccessibleShape::getSelectedText( ) throw (::com::sun::star::uno::RuntimeException){return OUString();} 1812 sal_Int32 SAL_CALL AccessibleShape::getSelectionStart( ) throw (::com::sun::star::uno::RuntimeException){return 0;} 1813 sal_Int32 SAL_CALL AccessibleShape::getSelectionEnd( ) throw (::com::sun::star::uno::RuntimeException){return 0;} 1814 sal_Bool SAL_CALL AccessibleShape::setSelection( sal_Int32, sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException){return sal_True;} 1815 ::rtl::OUString SAL_CALL AccessibleShape::getText( ) throw (::com::sun::star::uno::RuntimeException){return OUString();} 1816 ::rtl::OUString SAL_CALL AccessibleShape::getTextRange( sal_Int32, sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException){return OUString();} 1817 ::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) 1818 { 1819 ::com::sun::star::accessibility::TextSegment aResult; 1820 return aResult; 1821 } 1822 ::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) 1823 { 1824 ::com::sun::star::accessibility::TextSegment aResult; 1825 return aResult; 1826 } 1827 ::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) 1828 { 1829 ::com::sun::star::accessibility::TextSegment aResult; 1830 return aResult; 1831 } 1832 sal_Bool SAL_CALL AccessibleShape::copyText( sal_Int32, sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException){return sal_True;} 1833 1834 //-----IAccessibility2 Implementation 2009 1835 } // end of namespace accessibility 1836