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_sd.hxx" 26 #include "AccessibleDrawDocumentView.hxx" 27 #include <com/sun/star/drawing/XDrawPage.hpp> 28 #include <com/sun/star/drawing/XDrawView.hpp> 29 #include <com/sun/star/drawing/XDrawPagesSupplier.hpp> 30 #include <com/sun/star/drawing/XShapes.hpp> 31 #include <com/sun/star/container/XChild.hpp> 32 #include <com/sun/star/frame/XController.hpp> 33 #include <com/sun/star/frame/XFrame.hpp> 34 #include <com/sun/star/document/XEventBroadcaster.hpp> 35 #include <com/sun/star/beans/XPropertySet.hpp> 36 #include <com/sun/star/accessibility/AccessibleEventId.hpp> 37 #include <com/sun/star/accessibility/AccessibleStateType.hpp> 38 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 39 #include <rtl/ustring.h> 40 #include<sfx2/viewfrm.hxx> 41 42 #include <svx/AccessibleShape.hxx> 43 44 #include <svx/svdobj.hxx> 45 #include <svx/svdmodel.hxx> 46 #include <svx/unoapi.hxx> 47 #include <svx/unoshcol.hxx> 48 #include <toolkit/helper/vclunohelper.hxx> 49 #include "Window.hxx" 50 #include <vcl/svapp.hxx> 51 52 53 #include "ViewShell.hxx" 54 #include "View.hxx" 55 #include "DrawDocShell.hxx" 56 #include <drawdoc.hxx> 57 #include <algorithm> 58 #include "sdpage.hxx" 59 #include "slideshow.hxx" 60 #include "anminfo.hxx" 61 #include <memory> 62 63 #include "accessibility.hrc" 64 #include "sdresid.hxx" 65 #include <vos/mutex.hxx> 66 67 using ::rtl::OUString; 68 using namespace ::com::sun::star; 69 using namespace ::com::sun::star::uno; 70 using namespace ::com::sun::star::accessibility; 71 72 class SfxViewFrame; 73 74 #define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString))) 75 76 namespace accessibility { 77 78 79 struct XShapePosCompareHelper 80 { 81 bool operator() ( const uno::Reference<drawing::XShape>& xshape1, 82 const uno::Reference<drawing::XShape>& xshape2 ) const 83 { 84 // modify the compare method to return the Z-Order, not layout order 85 SdrObject* pObj1 = GetSdrObjectFromXShape(xshape1); 86 SdrObject* pObj2 = GetSdrObjectFromXShape(xshape2); 87 if(pObj1 && pObj2) 88 return pObj1->GetOrdNum() < pObj2->GetOrdNum(); 89 else 90 return 0; 91 } 92 }; 93 //===== internal ============================================================ 94 95 AccessibleDrawDocumentView::AccessibleDrawDocumentView ( 96 ::sd::Window* pSdWindow, 97 ::sd::ViewShell* pViewShell, 98 const uno::Reference<frame::XController>& rxController, 99 const uno::Reference<XAccessible>& rxParent) 100 : AccessibleDocumentViewBase (pSdWindow, pViewShell, rxController, rxParent), 101 mpSdViewSh( pViewShell ), 102 mpChildrenManager (NULL) 103 { 104 OSL_TRACE ("AccessibleDrawDocumentView"); 105 UpdateAccessibleName(); 106 } 107 108 109 110 111 AccessibleDrawDocumentView::~AccessibleDrawDocumentView (void) 112 { 113 OSL_TRACE ("~AccessibleDrawDocumentView"); 114 DBG_ASSERT (rBHelper.bDisposed || rBHelper.bInDispose, 115 "~AccessibleDrawDocumentView: object has not been disposed"); 116 } 117 118 119 120 121 void AccessibleDrawDocumentView::Init (void) 122 { 123 AccessibleDocumentViewBase::Init (); 124 125 // Determine the list of shapes on the current page. 126 uno::Reference<drawing::XShapes> xShapeList; 127 uno::Reference<drawing::XDrawView> xView (mxController, uno::UNO_QUERY); 128 if (xView.is()) 129 xShapeList = uno::Reference<drawing::XShapes> ( 130 xView->getCurrentPage(), uno::UNO_QUERY); 131 132 // Create the children manager. 133 mpChildrenManager = new ChildrenManager(this, xShapeList, maShapeTreeInfo, *this); 134 if (mpChildrenManager != NULL) 135 { 136 // Create the page shape and initialize it. The shape is acquired 137 // before initialization and released after transferring ownership 138 // to the children manager to prevent premature disposing of the 139 // shape. 140 AccessiblePageShape* pPage = CreateDrawPageShape(); 141 if (pPage != NULL) 142 { 143 pPage->acquire(); 144 pPage->Init(); 145 mpChildrenManager->AddAccessibleShape ( 146 std::auto_ptr<AccessibleShape>(pPage)); 147 pPage->release(); 148 mpChildrenManager->Update (); 149 } 150 mpChildrenManager->UpdateSelection (); 151 } 152 } 153 154 155 156 157 void AccessibleDrawDocumentView::ViewForwarderChanged (ChangeType aChangeType, 158 const IAccessibleViewForwarder* pViewForwarder) 159 { 160 AccessibleDocumentViewBase::ViewForwarderChanged (aChangeType, pViewForwarder); 161 if (mpChildrenManager != NULL) 162 mpChildrenManager->ViewForwarderChanged (aChangeType, pViewForwarder); 163 } 164 165 166 167 168 /** The page shape is created on every call at the moment (provided that 169 every thing goes well). 170 */ 171 AccessiblePageShape* AccessibleDrawDocumentView::CreateDrawPageShape (void) 172 { 173 AccessiblePageShape* pShape = NULL; 174 175 // Create a shape that represents the actual draw page. 176 uno::Reference<drawing::XDrawView> xView (mxController, uno::UNO_QUERY); 177 if (xView.is()) 178 { 179 uno::Reference<beans::XPropertySet> xSet ( 180 uno::Reference<beans::XPropertySet> (xView->getCurrentPage(), uno::UNO_QUERY)); 181 if (xSet.is()) 182 { 183 // Create a rectangle shape that will represent the draw page. 184 uno::Reference<lang::XMultiServiceFactory> xFactory (mxModel, uno::UNO_QUERY); 185 uno::Reference<drawing::XShape> xRectangle; 186 if (xFactory.is()) 187 xRectangle = uno::Reference<drawing::XShape>(xFactory->createInstance ( 188 OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.RectangleShape"))), 189 uno::UNO_QUERY); 190 191 // Set the shape's size and position. 192 if (xRectangle.is()) 193 { 194 uno::Any aValue; 195 awt::Point aPosition; 196 awt::Size aSize; 197 198 // Set size and position of the shape to those of the draw 199 // page. 200 aValue = xSet->getPropertyValue ( 201 OUString (RTL_CONSTASCII_USTRINGPARAM("BorderLeft"))); 202 aValue >>= aPosition.X; 203 aValue = xSet->getPropertyValue ( 204 OUString (RTL_CONSTASCII_USTRINGPARAM("BorderTop"))); 205 aValue >>= aPosition.Y; 206 xRectangle->setPosition (aPosition); 207 208 aValue = xSet->getPropertyValue ( 209 OUString (RTL_CONSTASCII_USTRINGPARAM("Width"))); 210 aValue >>= aSize.Width; 211 aValue = xSet->getPropertyValue ( 212 OUString (RTL_CONSTASCII_USTRINGPARAM("Height"))); 213 aValue >>= aSize.Height; 214 xRectangle->setSize (aSize); 215 216 // Create the accessible object for the shape and 217 // initialize it. 218 pShape = new AccessiblePageShape ( 219 xView->getCurrentPage(), this, maShapeTreeInfo); 220 } 221 } 222 } 223 return pShape; 224 } 225 226 227 228 229 //===== XAccessibleContext ================================================== 230 231 sal_Int32 SAL_CALL 232 AccessibleDrawDocumentView::getAccessibleChildCount (void) 233 throw (uno::RuntimeException) 234 { 235 ThrowIfDisposed (); 236 237 long mpChildCount = AccessibleDocumentViewBase::getAccessibleChildCount(); 238 239 // Forward request to children manager. 240 if (mpChildrenManager != NULL) 241 mpChildCount += mpChildrenManager->GetChildCount (); 242 243 return mpChildCount; 244 } 245 246 247 248 249 uno::Reference<XAccessible> SAL_CALL 250 AccessibleDrawDocumentView::getAccessibleChild (sal_Int32 nIndex) 251 throw (uno::RuntimeException, lang::IndexOutOfBoundsException) 252 { 253 ThrowIfDisposed (); 254 255 ::osl::ClearableMutexGuard aGuard (maMutex); 256 257 // Take care of children of the base class. 258 sal_Int32 nCount = AccessibleDocumentViewBase::getAccessibleChildCount(); 259 if (nCount > 0) 260 { 261 if (nIndex < nCount) 262 return AccessibleDocumentViewBase::getAccessibleChild(nIndex); 263 else 264 nIndex -= nCount; 265 } 266 267 // Create a copy of the pointer to the children manager and release the 268 // mutex before calling any of its methods. 269 ChildrenManager* pChildrenManager = mpChildrenManager; 270 aGuard.clear(); 271 272 // Forward request to children manager. 273 if (pChildrenManager != NULL) 274 { 275 return pChildrenManager->GetChild (nIndex); 276 } 277 else 278 throw lang::IndexOutOfBoundsException ( 279 ::rtl::OUString::createFromAscii ("no accessible child with index ") 280 + rtl::OUString::valueOf(nIndex), 281 static_cast<uno::XWeak*>(this)); 282 } 283 284 OUString SAL_CALL 285 AccessibleDrawDocumentView::getAccessibleName(void) 286 throw (::com::sun::star::uno::RuntimeException) 287 { 288 OUString sName = String( SdResId(SID_SD_A11Y_D_PRESENTATION) ); 289 ::sd::View* pSdView = static_cast< ::sd::View* >( maShapeTreeInfo.GetSdrView() ); 290 if ( pSdView ) 291 { 292 SdDrawDocument* pDoc = pSdView->GetDoc(); 293 if ( pDoc ) 294 { 295 rtl::OUString sFileName = pDoc->getDocAccTitle(); 296 if ( !sFileName.getLength() ) 297 { 298 ::sd::DrawDocShell* pDocSh = pSdView->GetDocSh(); 299 if ( pDocSh ) 300 { 301 sFileName = pDocSh->GetTitle( SFX_TITLE_APINAME ); 302 } 303 } 304 305 OUString sReadOnly; 306 if(pDoc->getDocReadOnly()) 307 { 308 sReadOnly = String(SdResId(SID_SD_A11Y_D_PRESENTATION_READONLY)); 309 } 310 311 if ( sFileName.getLength() ) 312 { 313 sName = sFileName + sReadOnly + OUString(RTL_CONSTASCII_USTRINGPARAM(" - ")) + sName; 314 } 315 } 316 } 317 318 return sName; 319 } 320 //===== XEventListener ====================================================== 321 322 void SAL_CALL 323 AccessibleDrawDocumentView::disposing (const lang::EventObject& rEventObject) 324 throw (::com::sun::star::uno::RuntimeException) 325 { 326 ThrowIfDisposed (); 327 328 AccessibleDocumentViewBase::disposing (rEventObject); 329 if (rEventObject.Source == mxModel) 330 { 331 ::osl::Guard< ::osl::Mutex> aGuard (::osl::Mutex::getGlobalMutex()); 332 // maShapeTreeInfo has been modified in base class. 333 if (mpChildrenManager != NULL) 334 mpChildrenManager->SetInfo (maShapeTreeInfo); 335 } 336 } 337 338 339 340 341 //===== XPropertyChangeListener ============================================= 342 343 void SAL_CALL 344 AccessibleDrawDocumentView::propertyChange (const beans::PropertyChangeEvent& rEventObject) 345 throw (::com::sun::star::uno::RuntimeException) 346 { 347 ThrowIfDisposed (); 348 349 AccessibleDocumentViewBase::propertyChange (rEventObject); 350 351 OSL_TRACE ("AccessibleDrawDocumentView::propertyChange"); 352 // add page switch event for slide show mode 353 if (rEventObject.PropertyName == OUString (RTL_CONSTASCII_USTRINGPARAM("CurrentPage")) || 354 rEventObject.PropertyName == OUString (RTL_CONSTASCII_USTRINGPARAM("PageChange")) ) 355 { 356 OSL_TRACE (" current page changed"); 357 358 // Update the accessible name to reflect the current slide. 359 UpdateAccessibleName(); 360 361 // The current page changed. Update the children manager accordingly. 362 uno::Reference<drawing::XDrawView> xView (mxController, uno::UNO_QUERY); 363 if (xView.is() && mpChildrenManager!=NULL) 364 { 365 // Inform the children manager to forget all children and give 366 // him the new ones. 367 mpChildrenManager->ClearAccessibleShapeList (); 368 mpChildrenManager->SetShapeList (uno::Reference<drawing::XShapes> ( 369 xView->getCurrentPage(), uno::UNO_QUERY)); 370 371 // Create the page shape and initialize it. The shape is 372 // acquired before initialization and released after 373 // transferring ownership to the children manager to prevent 374 // premature disposing of the shape. 375 AccessiblePageShape* pPage = CreateDrawPageShape (); 376 if (pPage != NULL) 377 { 378 pPage->acquire(); 379 pPage->Init(); 380 mpChildrenManager->AddAccessibleShape ( 381 std::auto_ptr<AccessibleShape>(pPage)); 382 mpChildrenManager->Update (false); 383 pPage->release(); 384 } 385 } 386 else 387 OSL_TRACE ("View invalid"); 388 CommitChange(AccessibleEventId::PAGE_CHANGED,rEventObject.NewValue,rEventObject.OldValue); 389 } 390 else if (rEventObject.PropertyName == OUString (RTL_CONSTASCII_USTRINGPARAM("VisibleArea"))) 391 { 392 OSL_TRACE (" visible area changed"); 393 if (mpChildrenManager != NULL) 394 mpChildrenManager->ViewForwarderChanged ( 395 IAccessibleViewForwarderListener::VISIBLE_AREA, 396 &maViewForwarder); 397 } 398 else if (rEventObject.PropertyName == OUString (RTL_CONSTASCII_USTRINGPARAM("ActiveLayer"))) 399 { 400 CommitChange(AccessibleEventId::PAGE_CHANGED,rEventObject.NewValue,rEventObject.OldValue); 401 } 402 else if (rEventObject.PropertyName == OUString (RTL_CONSTASCII_USTRINGPARAM("UpdateAcc"))) 403 { 404 OSL_TRACE (" acc on current page should be updated"); 405 406 // The current page changed. Update the children manager accordingly. 407 uno::Reference<drawing::XDrawView> xView (mxController, uno::UNO_QUERY); 408 if (xView.is() && mpChildrenManager!=NULL) 409 { 410 // Inform the children manager to forget all children and give 411 // him the new ones. 412 mpChildrenManager->ClearAccessibleShapeList (); 413 // update the slide show page's accessible info 414 //mpChildrenManager->SetShapeList (uno::Reference<drawing::XShapes> ( 415 // xView->getCurrentPage(), uno::UNO_QUERY)); 416 rtl::Reference< sd::SlideShow > xSlideshow( sd::SlideShow::GetSlideShow( mpSdViewSh->GetViewShellBase() ) ); 417 if( xSlideshow.is() && xSlideshow->isRunning() && xSlideshow->isFullScreen() ) 418 { 419 ::com::sun::star::uno::Reference< drawing::XDrawPage > xSlide; 420 // MT IA2: Not used... 421 // sal_Int32 currentPageIndex = xSlideshow->getCurrentPageIndex(); 422 ::com::sun::star::uno::Reference< ::com::sun::star::presentation::XSlideShowController > mpSlideController = xSlideshow->getController(); 423 if( mpSlideController.is() ) 424 { 425 xSlide = mpSlideController->getCurrentSlide(); 426 if (xSlide.is()) 427 { 428 mpChildrenManager->SetShapeList (uno::Reference<drawing::XShapes> ( 429 xSlide, uno::UNO_QUERY)); 430 } 431 } 432 } 433 // Create the page shape and initialize it. The shape is 434 // acquired before initialization and released after 435 // transferring ownership to the children manager to prevent 436 // premature disposing of the shape. 437 AccessiblePageShape* pPage = CreateDrawPageShape (); 438 if (pPage != NULL) 439 { 440 pPage->acquire(); 441 pPage->Init(); 442 mpChildrenManager->AddAccessibleShape ( 443 std::auto_ptr<AccessibleShape>(pPage)); 444 mpChildrenManager->Update (false); 445 pPage->release(); 446 } 447 } 448 } 449 else 450 { 451 OSL_TRACE (" unhandled"); 452 } 453 OSL_TRACE (" done"); 454 } 455 456 457 458 //===== XServiceInfo ======================================================== 459 460 ::rtl::OUString SAL_CALL 461 AccessibleDrawDocumentView::getImplementationName (void) 462 throw (::com::sun::star::uno::RuntimeException) 463 { 464 return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 465 "AccessibleDrawDocumentView")); 466 } 467 468 469 470 471 ::com::sun::star::uno::Sequence< ::rtl::OUString> SAL_CALL 472 AccessibleDrawDocumentView::getSupportedServiceNames (void) 473 throw (::com::sun::star::uno::RuntimeException) 474 { 475 ThrowIfDisposed(); 476 // Get list of supported service names from base class... 477 uno::Sequence<OUString> aServiceNames = 478 AccessibleDocumentViewBase::getSupportedServiceNames(); 479 sal_Int32 nCount (aServiceNames.getLength()); 480 481 // ...and add additional names. 482 aServiceNames.realloc (nCount + 1); 483 static const OUString sAdditionalServiceName (RTL_CONSTASCII_USTRINGPARAM( 484 "com.sun.star.drawing.AccessibleDrawDocumentView")); 485 aServiceNames[nCount] = sAdditionalServiceName; 486 487 return aServiceNames; 488 } 489 490 //===== XInterface ========================================================== 491 492 uno::Any SAL_CALL 493 AccessibleDrawDocumentView::queryInterface (const uno::Type & rType) 494 throw (uno::RuntimeException) 495 { 496 uno::Any aReturn = AccessibleDocumentViewBase::queryInterface (rType); 497 if ( ! aReturn.hasValue()) 498 aReturn = ::cppu::queryInterface (rType, 499 static_cast<XAccessibleGroupPosition*>(this) 500 ); 501 return aReturn; 502 } 503 504 void SAL_CALL 505 AccessibleDrawDocumentView::acquire (void) 506 throw () 507 { 508 AccessibleDocumentViewBase::acquire (); 509 } 510 void SAL_CALL 511 AccessibleDrawDocumentView::release (void) 512 throw () 513 { 514 AccessibleDocumentViewBase::release (); 515 } 516 //===== XAccessibleGroupPosition ========================================= 517 uno::Sequence< sal_Int32 > SAL_CALL 518 AccessibleDrawDocumentView::getGroupPosition( const uno::Any& rAny ) 519 throw (uno::RuntimeException) 520 { 521 // we will return the: 522 // [0] group level(always be 0 now) 523 // [1] similar items counts in the group 524 // [2] the position of the object in the group 525 uno::Sequence< sal_Int32 > aRet( 3 ); 526 //get the xShape of the current selected drawing object 527 uno::Reference<XAccessibleContext> xAccContent; 528 rAny >>= xAccContent; 529 if ( !xAccContent.is() ) 530 { 531 return aRet; 532 } 533 AccessibleShape* pAcc = AccessibleShape::getImplementation( xAccContent ); 534 if ( !pAcc ) 535 { 536 return aRet; 537 } 538 uno::Reference< drawing::XShape > xCurShape = pAcc->GetXShape(); 539 if ( !xCurShape.is() ) 540 { 541 return aRet; 542 } 543 //find all the child in the page, insert them into a vector and sort 544 if ( mpChildrenManager == NULL ) 545 { 546 return aRet; 547 } 548 std::vector< uno::Reference<drawing::XShape> > vXShapes; 549 sal_Int32 nCount = mpChildrenManager->GetChildCount(); 550 //get pointer of SdView & SdrPageView for further use. 551 SdrPageView* pPV = NULL; 552 ::sd::View* pSdView = NULL; 553 if ( mpSdViewSh ) 554 { 555 pSdView = mpSdViewSh->GetView(); 556 pPV = pSdView->GetSdrPageView(); 557 } 558 for ( sal_Int32 i = 0; i < nCount; i++ ) 559 { 560 uno::Reference< drawing::XShape > xShape = mpChildrenManager->GetChildShape(i); 561 if ( xShape.is() ) 562 { 563 //if the object is visable in the page, we add it into the group list. 564 SdrObject* pObj = GetSdrObjectFromXShape(xShape); 565 if ( pObj && pPV && pSdView && pSdView->IsObjMarkable( pObj, pPV ) ) 566 { 567 vXShapes.push_back( xShape ); 568 } 569 } 570 } 571 std::sort( vXShapes.begin(), vXShapes.end(), XShapePosCompareHelper() ); 572 //get the the index of the selected object in the group 573 std::vector< uno::Reference<drawing::XShape> >::iterator aIter; 574 //we start counting position from 1 575 sal_Int32 nPos = 1; 576 for ( aIter = vXShapes.begin(); aIter != vXShapes.end(); aIter++, nPos++ ) 577 { 578 if ( (*aIter).get() == xCurShape.get() ) 579 { 580 sal_Int32* pArray = aRet.getArray(); 581 pArray[0] = 1; //it should be 1 based, not 0 based. 582 pArray[1] = vXShapes.size(); 583 pArray[2] = nPos; 584 break; 585 } 586 } 587 return aRet; 588 } 589 ::rtl::OUString AccessibleDrawDocumentView::getObjectLink( const uno::Any& rAny ) 590 throw (uno::RuntimeException) 591 { 592 ::rtl::OUString aRet; 593 //get the xShape of the current selected drawing object 594 uno::Reference<XAccessibleContext> xAccContent; 595 rAny >>= xAccContent; 596 if ( !xAccContent.is() ) 597 { 598 return aRet; 599 } 600 AccessibleShape* pAcc = AccessibleShape::getImplementation( xAccContent ); 601 if ( !pAcc ) 602 { 603 return aRet; 604 } 605 uno::Reference< drawing::XShape > xCurShape = pAcc->GetXShape(); 606 if ( !xCurShape.is() ) 607 { 608 return aRet; 609 } 610 SdrObject* pObj = GetSdrObjectFromXShape(xCurShape); 611 if (pObj) 612 { 613 SdAnimationInfo* pInfo = SdDrawDocument::GetShapeUserData(*pObj); 614 if( pInfo && (pInfo->meClickAction == presentation::ClickAction_DOCUMENT) ) 615 aRet = (::rtl::OUString)pInfo->GetBookmark(); 616 } 617 return aRet; 618 } 619 /// Create a name for this view. 620 ::rtl::OUString 621 AccessibleDrawDocumentView::CreateAccessibleName (void) 622 throw (::com::sun::star::uno::RuntimeException) 623 { 624 rtl::OUString sName; 625 626 uno::Reference<lang::XServiceInfo> xInfo (mxController, uno::UNO_QUERY); 627 if (xInfo.is()) 628 { 629 uno::Sequence< ::rtl::OUString > aServices( xInfo->getSupportedServiceNames() ); 630 OUString sFirstService = aServices[0]; 631 if (sFirstService == OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.DrawingDocumentDrawView"))) 632 { 633 if( aServices.getLength() >= 2 && 634 aServices[1] == OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.presentation.PresentationView"))) 635 { 636 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 637 638 sName = String( SdResId(SID_SD_A11Y_I_DRAWVIEW_N) ); 639 } 640 else 641 { 642 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 643 644 sName = String( SdResId(SID_SD_A11Y_D_DRAWVIEW_N) ); 645 } 646 } 647 else if (sFirstService == OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.presentation.NotesView"))) 648 { 649 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 650 651 sName = String( SdResId(SID_SD_A11Y_I_NOTESVIEW_N) ); 652 } 653 else if (sFirstService == OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.presentation.HandoutView"))) 654 { 655 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 656 657 sName = String( SdResId(SID_SD_A11Y_I_HANDOUTVIEW_N) ); 658 } 659 else 660 { 661 sName = sFirstService; 662 } 663 } 664 else 665 { 666 sName = OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleDrawDocumentView")); 667 } 668 return sName; 669 } 670 671 672 673 674 /** Create a description for this view. Use the model's description or URL 675 if a description is not available. 676 */ 677 ::rtl::OUString 678 AccessibleDrawDocumentView::CreateAccessibleDescription (void) 679 throw (::com::sun::star::uno::RuntimeException) 680 { 681 rtl::OUString sDescription; 682 683 uno::Reference<lang::XServiceInfo> xInfo (mxController, uno::UNO_QUERY); 684 if (xInfo.is()) 685 { 686 uno::Sequence< ::rtl::OUString > aServices( xInfo->getSupportedServiceNames() ); 687 OUString sFirstService = aServices[0]; 688 if (sFirstService == OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.DrawingDocumentDrawView"))) 689 { 690 if( aServices.getLength() >= 2 && 691 aServices[1] == OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.presentation.PresentationView"))) 692 { 693 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 694 695 sDescription = String( SdResId(SID_SD_A11Y_I_DRAWVIEW_D) ); 696 } 697 else 698 { 699 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 700 701 sDescription = String( SdResId(SID_SD_A11Y_D_DRAWVIEW_D) ); 702 } 703 } 704 else if (sFirstService == OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.presentation.NotesView"))) 705 { 706 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 707 708 sDescription = String( SdResId(SID_SD_A11Y_I_NOTESVIEW_D) ); 709 } 710 else if (sFirstService == OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.presentation.HandoutView"))) 711 { 712 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 713 714 sDescription = String( SdResId(SID_SD_A11Y_I_HANDOUTVIEW_D) ); 715 } 716 else 717 { 718 sDescription = sFirstService; 719 } 720 } 721 else 722 { 723 sDescription = OUString(RTL_CONSTASCII_USTRINGPARAM("Accessible Draw Document")); 724 } 725 return sDescription; 726 } 727 728 729 730 731 /** Return selection state of specified child 732 */ 733 sal_Bool 734 AccessibleDrawDocumentView::implIsSelected( sal_Int32 nAccessibleChildIndex ) 735 throw (uno::RuntimeException) 736 { 737 const vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 738 uno::Reference< view::XSelectionSupplier > xSel( mxController, uno::UNO_QUERY ); 739 sal_Bool bRet = sal_False; 740 741 OSL_ENSURE( 0 <= nAccessibleChildIndex, "AccessibleDrawDocumentView::implIsSelected: invalid index!" ); 742 743 if( xSel.is() && ( 0 <= nAccessibleChildIndex ) ) 744 { 745 uno::Any aAny( xSel->getSelection() ); 746 uno::Reference< drawing::XShapes > xShapes; 747 748 aAny >>= xShapes; 749 750 if( xShapes.is() ) 751 { 752 AccessibleShape* pAcc = AccessibleShape::getImplementation( getAccessibleChild( nAccessibleChildIndex ) ); 753 754 if( pAcc ) 755 { 756 uno::Reference< drawing::XShape > xShape( pAcc->GetXShape() ); 757 758 if( xShape.is() ) 759 { 760 for( sal_Int32 i = 0, nCount = xShapes->getCount(); ( i < nCount ) && !bRet; ++i ) 761 if( xShapes->getByIndex( i ) == xShape ) 762 bRet = sal_True; 763 } 764 } 765 } 766 } 767 768 return( bRet ); 769 } 770 771 772 773 774 /** Select or delselect the specified shapes. The corresponding accessible 775 shapes are notified over the selection change listeners registered with 776 the XSelectionSupplier of the controller. 777 */ 778 void 779 AccessibleDrawDocumentView::implSelect( sal_Int32 nAccessibleChildIndex, sal_Bool bSelect ) 780 throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 781 { 782 const vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 783 uno::Reference< view::XSelectionSupplier > xSel( mxController, uno::UNO_QUERY ); 784 AccessibleShape* pAccessibleChild; 785 786 if( xSel.is() ) 787 { 788 uno::Any aAny; 789 790 if( ACCESSIBLE_SELECTION_CHILD_ALL == nAccessibleChildIndex ) 791 { 792 // Select or deselect all children. 793 794 if( !bSelect ) 795 xSel->select( aAny ); 796 else 797 { 798 uno::Reference< drawing::XShapes > xShapes( new SvxShapeCollection() ); 799 800 for(sal_Int32 i = 0, nCount = getAccessibleChildCount(); i < nCount; ++i ) 801 { 802 AccessibleShape* pAcc = AccessibleShape::getImplementation( getAccessibleChild( i ) ); 803 804 if( pAcc && pAcc->GetXShape().is() ) 805 { 806 xShapes->add( pAcc->GetXShape() ); 807 pAccessibleChild = pAcc; 808 } 809 } 810 811 if( xShapes->getCount() ) 812 { 813 aAny <<= xShapes; 814 xSel->select( aAny ); 815 } 816 } 817 } 818 else if( nAccessibleChildIndex >= 0 ) 819 { 820 // Select or deselect only the child with index 821 // nAccessibleChildIndex. 822 823 AccessibleShape* pAcc = AccessibleShape::getImplementation( 824 getAccessibleChild( nAccessibleChildIndex )); 825 pAccessibleChild = pAcc; 826 827 // Add or remove the shape that is made accessible from the 828 // selection of the controller. 829 if( pAcc ) 830 { 831 uno::Reference< drawing::XShape > xShape( pAcc->GetXShape() ); 832 833 if( xShape.is() ) 834 { 835 uno::Reference< drawing::XShapes > xShapes; 836 sal_Bool bFound = sal_False; 837 838 aAny = xSel->getSelection(); 839 aAny >>= xShapes; 840 841 // Search shape to be selected in current selection. 842 if (xShapes.is()) 843 { 844 sal_Int32 nCount = xShapes->getCount(); 845 for (sal_Int32 i=0; ( i < nCount ) && !bFound; ++i ) 846 if( xShapes->getByIndex( i ) == xShape ) 847 bFound = sal_True; 848 } 849 else 850 // Create an empty selection to add the shape to. 851 xShapes = new SvxShapeCollection(); 852 853 // Update the selection. 854 if( !bFound && bSelect ) 855 xShapes->add( xShape ); 856 else if( bFound && !bSelect ) 857 xShapes->remove( xShape ); 858 859 aAny <<= xShapes; 860 xSel->select( aAny ); 861 } 862 } 863 } 864 } 865 } 866 867 868 869 870 void AccessibleDrawDocumentView::Activated (void) 871 { 872 if (mpChildrenManager != NULL) 873 { 874 //mpChildrenManager->UpdateSelection(); 875 sal_Bool bChange = sal_False; 876 // When none of the children has the focus then claim it for the 877 // view. 878 if ( ! mpChildrenManager->HasFocus()) 879 { 880 SetState (AccessibleStateType::FOCUSED); 881 bChange = sal_True; 882 } 883 else 884 ResetState (AccessibleStateType::FOCUSED); 885 mpChildrenManager->UpdateSelection(); 886 // if the child gets focus in UpdateSelection(), needs to reset the focus on document. 887 if (mpChildrenManager->HasFocus() && bChange) 888 ResetState (AccessibleStateType::FOCUSED); 889 } 890 } 891 892 893 894 895 void AccessibleDrawDocumentView::Deactivated (void) 896 { 897 if (mpChildrenManager != NULL) 898 mpChildrenManager->RemoveFocus(); 899 ResetState (AccessibleStateType::FOCUSED); 900 } 901 902 903 904 905 void AccessibleDrawDocumentView::impl_dispose (void) 906 { 907 if (mpChildrenManager != NULL) 908 { 909 delete mpChildrenManager; 910 mpChildrenManager = NULL; 911 } 912 913 AccessibleDocumentViewBase::impl_dispose(); 914 } 915 916 917 918 /** This method is called from the component helper base class while 919 disposing. 920 */ 921 void SAL_CALL AccessibleDrawDocumentView::disposing (void) 922 { 923 924 // Release resources. 925 if (mpChildrenManager != NULL) 926 { 927 delete mpChildrenManager; 928 mpChildrenManager = NULL; 929 } 930 931 // Forward call to base classes. 932 AccessibleDocumentViewBase::disposing (); 933 } 934 935 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > 936 SAL_CALL AccessibleDrawDocumentView::get_AccFlowTo(const ::com::sun::star::uno::Any& rAny, sal_Int32 nType) 937 throw ( ::com::sun::star::uno::RuntimeException ) 938 { 939 const sal_Int32 SPELLCHECKFLOWTO = 1; 940 const sal_Int32 FINDREPLACEFLOWTO = 2; 941 if ( nType == SPELLCHECKFLOWTO ) 942 { 943 uno::Reference< ::com::sun::star::drawing::XShape > xShape; 944 rAny >>= xShape; 945 if ( mpChildrenManager && xShape.is() ) 946 { 947 uno::Reference < XAccessible > xAcc = mpChildrenManager->GetChild(xShape); 948 uno::Reference < XAccessibleSelection > xAccSelection( xAcc, uno::UNO_QUERY ); 949 if ( xAccSelection.is() ) 950 { 951 if ( xAccSelection->getSelectedAccessibleChildCount() ) 952 { 953 uno::Reference < XAccessible > xSel = xAccSelection->getSelectedAccessibleChild( 0 ); 954 if ( xSel.is() ) 955 { 956 uno::Reference < XAccessibleContext > xSelContext( xSel->getAccessibleContext() ); 957 if ( xSelContext.is() ) 958 { 959 //if in sw we find the selected paragraph here 960 if ( xSelContext->getAccessibleRole() == AccessibleRole::PARAGRAPH ) 961 { 962 uno::Sequence<uno::Any> aRet( 1 ); 963 aRet[0] = uno::makeAny( xSel ); 964 return aRet; 965 } 966 } 967 } 968 } 969 } 970 uno::Reference<XAccessible> xPara = GetSelAccContextInTable(); 971 if ( xPara.is() ) 972 { 973 uno::Sequence<uno::Any> aRet( 1 ); 974 aRet[0] = uno::makeAny( xPara ); 975 return aRet; 976 } 977 } 978 else 979 { 980 goto Rt; 981 } 982 } 983 else if ( nType == FINDREPLACEFLOWTO ) 984 { 985 sal_Int32 nChildCount = getSelectedAccessibleChildCount(); 986 if ( nChildCount ) 987 { 988 uno::Reference < XAccessible > xSel = getSelectedAccessibleChild( 0 ); 989 if ( xSel.is() ) 990 { 991 uno::Reference < XAccessibleSelection > xAccChildSelection( xSel, uno::UNO_QUERY ); 992 if ( xAccChildSelection.is() ) 993 { 994 if ( xAccChildSelection->getSelectedAccessibleChildCount() ) 995 { 996 uno::Reference < XAccessible > xChildSel = xAccChildSelection->getSelectedAccessibleChild( 0 ); 997 if ( xChildSel.is() ) 998 { 999 uno::Reference < XAccessibleContext > xChildSelContext( xChildSel->getAccessibleContext() ); 1000 if ( xChildSelContext.is() && 1001 xChildSelContext->getAccessibleRole() == AccessibleRole::PARAGRAPH ) 1002 { 1003 uno::Sequence<uno::Any> aRet( 1 ); 1004 aRet[0] = uno::makeAny( xChildSel ); 1005 return aRet; 1006 } 1007 } 1008 } 1009 } 1010 } 1011 } 1012 else 1013 { 1014 uno::Reference<XAccessible> xPara = GetSelAccContextInTable(); 1015 if ( xPara.is() ) 1016 { 1017 uno::Sequence<uno::Any> aRet( 1 ); 1018 aRet[0] = uno::makeAny( xPara ); 1019 return aRet; 1020 } 1021 } 1022 } 1023 1024 Rt: 1025 ::com::sun::star::uno::Sequence< uno::Any> aRet; 1026 return aRet; 1027 } 1028 uno::Reference<XAccessible> AccessibleDrawDocumentView::GetSelAccContextInTable() 1029 { 1030 uno::Reference<XAccessible> xRet; 1031 sal_Int32 nCount = mpChildrenManager ? mpChildrenManager->GetChildCount() : 0; 1032 if ( nCount ) 1033 { 1034 for ( sal_Int32 i = 0; i < nCount; i++ ) 1035 { 1036 try 1037 { 1038 uno::Reference<XAccessible> xObj = mpChildrenManager->GetChild(i); 1039 if ( xObj.is() ) 1040 { 1041 uno::Reference<XAccessibleContext> xObjContext( xObj, uno::UNO_QUERY ); 1042 if ( xObjContext.is() && xObjContext->getAccessibleRole() == AccessibleRole::TABLE ) 1043 { 1044 uno::Reference<XAccessibleSelection> xObjSelection( xObj, uno::UNO_QUERY ); 1045 if ( xObjSelection.is() && xObjSelection->getSelectedAccessibleChildCount() ) 1046 { 1047 uno::Reference<XAccessible> xCell = xObjSelection->getSelectedAccessibleChild(0); 1048 if ( xCell.is() ) 1049 { 1050 uno::Reference<XAccessibleSelection> xCellSel( xCell, uno::UNO_QUERY ); 1051 if ( xCellSel.is() && xCellSel->getSelectedAccessibleChildCount() ) 1052 { 1053 uno::Reference<XAccessible> xPara = xCellSel->getSelectedAccessibleChild( 0 ); 1054 if ( xPara.is() ) 1055 { 1056 uno::Reference<XAccessibleContext> xParaContext( xPara, uno::UNO_QUERY ); 1057 if ( xParaContext.is() && 1058 xParaContext->getAccessibleRole() == AccessibleRole::PARAGRAPH ) 1059 { 1060 xRet = xPara; 1061 return xRet; 1062 } 1063 } 1064 } 1065 } 1066 } 1067 } 1068 } 1069 } 1070 catch ( lang::IndexOutOfBoundsException ) 1071 { 1072 uno::Reference<XAccessible> xEmpty; 1073 return xEmpty; 1074 } 1075 catch ( uno::RuntimeException ) 1076 { 1077 uno::Reference<XAccessible> xEmpty; 1078 return xEmpty; 1079 } 1080 } 1081 } 1082 1083 return xRet; 1084 } 1085 1086 void AccessibleDrawDocumentView::UpdateAccessibleName (void) 1087 { 1088 OUString sNewName (CreateAccessibleName()); 1089 sNewName += A2S(": "); 1090 1091 // Add the number of the current slide. 1092 uno::Reference<drawing::XDrawView> xView (mxController, uno::UNO_QUERY); 1093 if (xView.is()) 1094 { 1095 uno::Reference<beans::XPropertySet> xProperties (xView->getCurrentPage(), UNO_QUERY); 1096 if (xProperties.is()) 1097 try 1098 { 1099 sal_Int16 nPageNumber (0); 1100 if (xProperties->getPropertyValue(A2S("Number")) >>= nPageNumber) 1101 { 1102 sNewName += OUString::valueOf(sal_Int32(nPageNumber)); 1103 } 1104 } 1105 catch (beans::UnknownPropertyException&) 1106 { 1107 } 1108 } 1109 1110 // Add the number of pages/slides. 1111 Reference<drawing::XDrawPagesSupplier> xPagesSupplier (mxModel, UNO_QUERY); 1112 if (xPagesSupplier.is()) 1113 { 1114 Reference<container::XIndexAccess> xPages (xPagesSupplier->getDrawPages(), UNO_QUERY); 1115 if (xPages.is()) 1116 { 1117 sNewName += A2S(" / "); 1118 sNewName += OUString::valueOf(xPages->getCount()); 1119 } 1120 } 1121 1122 SetAccessibleName (sNewName, AutomaticallyCreated); 1123 } 1124 1125 1126 1127 1128 } // end of namespace accessibility 1129