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