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