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