1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #include "precompiled_sdext.hxx" 29 30 #include "PresenterAccessibility.hxx" 31 #include "PresenterTextView.hxx" 32 #include "PresenterConfigurationAccess.hxx" 33 #include "PresenterNotesView.hxx" 34 #include "PresenterPaneBase.hxx" 35 #include "PresenterPaneContainer.hxx" 36 #include "PresenterPaneFactory.hxx" 37 #include "PresenterViewFactory.hxx" 38 39 #include <com/sun/star/accessibility/AccessibleEventId.hpp> 40 #include <com/sun/star/accessibility/AccessibleRelationType.hpp> 41 #include <com/sun/star/accessibility/AccessibleRole.hpp> 42 #include <com/sun/star/accessibility/XAccessibleComponent.hpp> 43 #include <com/sun/star/accessibility/XAccessibleContext.hpp> 44 #include <com/sun/star/accessibility/XAccessibleEditableText.hpp> 45 #include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp> 46 #include <com/sun/star/accessibility/XAccessibleText.hpp> 47 #include <com/sun/star/drawing/framework/ResourceId.hpp> 48 #include <com/sun/star/drawing/framework/XPane.hpp> 49 #include <com/sun/star/drawing/framework/XView.hpp> 50 #include <cppuhelper/compbase1.hxx> 51 #include <cppuhelper/compbase5.hxx> 52 #include <cppuhelper/implbase1.hxx> 53 #include <boost/bind.hpp> 54 55 using namespace ::com::sun::star; 56 using namespace ::com::sun::star::accessibility; 57 using namespace ::com::sun::star::uno; 58 using namespace ::com::sun::star::drawing::framework; 59 using ::rtl::OUString; 60 61 #define A2S(s) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s))) 62 63 #define VERBOSE 64 65 //===== PresenterAccessibleObject ============================================= 66 67 namespace sdext { namespace presenter { 68 69 namespace { 70 typedef ::cppu::WeakComponentImplHelper5 < 71 cssa::XAccessible, 72 cssa::XAccessibleContext, 73 cssa::XAccessibleComponent, 74 cssa::XAccessibleEventBroadcaster, 75 css::awt::XWindowListener 76 > PresenterAccessibleObjectInterfaceBase; 77 } 78 79 class PresenterAccessible::AccessibleObject 80 : public ::cppu::BaseMutex, 81 public PresenterAccessibleObjectInterfaceBase 82 { 83 public: 84 AccessibleObject ( 85 const css::lang::Locale aLocale, 86 const sal_Int16 nRole, 87 const ::rtl::OUString& rsName); 88 void LateInitialization (void); 89 90 virtual ~AccessibleObject (void); 91 92 virtual void SetWindow ( 93 const cssu::Reference<css::awt::XWindow>& rxContentWindow, 94 const cssu::Reference<css::awt::XWindow>& rxBorderWindow); 95 void SetAccessibleParent (const cssu::Reference<cssa::XAccessible>& rxAccessibleParent); 96 97 virtual void SAL_CALL disposing (void); 98 99 void NotifyCurrentSlideChange (const sal_Int32 nCurrentSlideIndex); 100 101 void AddChild (const ::rtl::Reference<AccessibleObject>& rpChild); 102 void RemoveChild (const ::rtl::Reference<AccessibleObject>& rpChild); 103 104 void SetIsFocused (const bool bIsFocused); 105 void SetAccessibleName (const ::rtl::OUString& rsName); 106 107 void FireAccessibleEvent ( 108 const sal_Int16 nEventId, 109 const cssu::Any& rOldValue, 110 const cssu::Any& rNewValue); 111 112 void UpdateStateSet (void); 113 114 115 //----- XAccessible ------------------------------------------------------- 116 117 virtual cssu::Reference<cssa::XAccessibleContext> SAL_CALL 118 getAccessibleContext (void) 119 throw (cssu::RuntimeException); 120 121 122 //----- XAccessibleContext ---------------------------------------------- 123 124 virtual sal_Int32 SAL_CALL getAccessibleChildCount (void) 125 throw (cssu::RuntimeException); 126 127 virtual cssu::Reference< cssa::XAccessible> SAL_CALL 128 getAccessibleChild (sal_Int32 nIndex) 129 throw (css::lang::IndexOutOfBoundsException, cssu::RuntimeException); 130 131 virtual cssu::Reference< cssa::XAccessible> SAL_CALL getAccessibleParent (void) 132 throw (cssu::RuntimeException); 133 134 virtual sal_Int32 SAL_CALL getAccessibleIndexInParent (void) 135 throw (cssu::RuntimeException); 136 137 virtual sal_Int16 SAL_CALL getAccessibleRole (void) 138 throw (cssu::RuntimeException); 139 140 virtual ::rtl::OUString SAL_CALL getAccessibleDescription (void) 141 throw (cssu::RuntimeException); 142 143 virtual ::rtl::OUString SAL_CALL getAccessibleName (void) 144 throw (cssu::RuntimeException); 145 146 virtual cssu::Reference<cssa::XAccessibleRelationSet> SAL_CALL 147 getAccessibleRelationSet (void) 148 throw (cssu::RuntimeException); 149 150 virtual cssu::Reference<cssa::XAccessibleStateSet> SAL_CALL 151 getAccessibleStateSet (void) 152 throw (cssu::RuntimeException); 153 154 virtual css::lang::Locale SAL_CALL getLocale (void) 155 throw (cssu::RuntimeException, 156 cssa::IllegalAccessibleComponentStateException); 157 158 159 //----- XAccessibleComponent -------------------------------------------- 160 161 virtual sal_Bool SAL_CALL containsPoint ( 162 const css::awt::Point& aPoint) 163 throw (cssu::RuntimeException); 164 165 virtual cssu::Reference<cssa::XAccessible> SAL_CALL 166 getAccessibleAtPoint ( 167 const css::awt::Point& aPoint) 168 throw (cssu::RuntimeException); 169 170 virtual css::awt::Rectangle SAL_CALL getBounds (void) 171 throw (cssu::RuntimeException); 172 173 virtual css::awt::Point SAL_CALL getLocation (void) 174 throw (cssu::RuntimeException); 175 176 virtual css::awt::Point SAL_CALL getLocationOnScreen (void) 177 throw (cssu::RuntimeException); 178 179 virtual css::awt::Size SAL_CALL getSize (void) 180 throw (cssu::RuntimeException); 181 182 virtual void SAL_CALL grabFocus (void) 183 throw (cssu::RuntimeException); 184 185 virtual sal_Int32 SAL_CALL getForeground (void) 186 throw (cssu::RuntimeException); 187 188 virtual sal_Int32 SAL_CALL getBackground (void) 189 throw (cssu::RuntimeException); 190 191 192 //----- XAccessibleEventBroadcaster -------------------------------------- 193 194 virtual void SAL_CALL addEventListener ( 195 const cssu::Reference<cssa::XAccessibleEventListener>& rxListener) 196 throw (cssu::RuntimeException); 197 198 virtual void SAL_CALL removeEventListener ( 199 const cssu::Reference<cssa::XAccessibleEventListener>& rxListener) 200 throw (cssu::RuntimeException); 201 202 using PresenterAccessibleObjectInterfaceBase::addEventListener; 203 using PresenterAccessibleObjectInterfaceBase::removeEventListener; 204 205 //----- XWindowListener --------------------------------------------------- 206 207 virtual void SAL_CALL windowResized (const css::awt::WindowEvent& rEvent) 208 throw (cssu::RuntimeException); 209 210 virtual void SAL_CALL windowMoved (const css::awt::WindowEvent& rEvent) 211 throw (cssu::RuntimeException); 212 213 virtual void SAL_CALL windowShown (const css::lang::EventObject& rEvent) 214 throw (cssu::RuntimeException); 215 216 virtual void SAL_CALL windowHidden (const css::lang::EventObject& rEvent) 217 throw (cssu::RuntimeException); 218 219 220 //----- XEventListener ---------------------------------------------------- 221 222 virtual void SAL_CALL disposing (const css::lang::EventObject& rEvent) 223 throw (cssu::RuntimeException); 224 225 226 protected: 227 ::rtl::OUString msName; 228 cssu::Reference<css::awt::XWindow2> mxContentWindow; 229 cssu::Reference<css::awt::XWindow2> mxBorderWindow; 230 const css::lang::Locale maLocale; 231 const sal_Int16 mnRole; 232 sal_uInt32 mnStateSet; 233 bool mbIsFocused; 234 cssu::Reference<cssa::XAccessible> mxParentAccessible; 235 ::std::vector<rtl::Reference<AccessibleObject> > maChildren; 236 ::std::vector<Reference<XAccessibleEventListener> > maListeners; 237 238 virtual awt::Point GetRelativeLocation (void); 239 virtual awt::Size GetSize (void); 240 virtual awt::Point GetAbsoluteParentLocation (void); 241 242 virtual bool GetWindowState (const sal_Int16 nType) const; 243 244 void UpdateState (const sal_Int16 aState, const bool bValue); 245 246 sal_Bool IsDisposed (void) const; 247 248 void ThrowIfDisposed (void) const 249 throw (css::lang::DisposedException); 250 251 enum ExceptionType { ET_Runtime, ET_Disposed, ET_IndexOutOfBounds }; 252 void ThrowException (const sal_Char* pMessage, const ExceptionType eExceptionType) const; 253 }; 254 255 256 257 258 //===== AccessibleStateSet ==================================================== 259 260 namespace { 261 typedef ::cppu::WeakComponentImplHelper1 < 262 cssa::XAccessibleStateSet 263 > AccessibleStateSetInterfaceBase; 264 } 265 266 class AccessibleStateSet 267 : public ::cppu::BaseMutex, 268 public AccessibleStateSetInterfaceBase 269 { 270 public: 271 AccessibleStateSet (const sal_Int32 nStateSet); 272 virtual ~AccessibleStateSet (void); 273 274 static sal_uInt32 GetStateMask (const sal_Int16 nType); 275 276 //----- XAccessibleStateSet ----------------------------------------------- 277 278 virtual sal_Bool SAL_CALL isEmpty (void) 279 throw (cssu::RuntimeException); 280 281 virtual sal_Bool SAL_CALL contains (sal_Int16 nState) 282 throw (cssu::RuntimeException); 283 284 virtual sal_Bool SAL_CALL containsAll (const cssu::Sequence<sal_Int16>& rStateSet) 285 throw (cssu::RuntimeException); 286 287 virtual cssu::Sequence<sal_Int16> SAL_CALL getStates (void) 288 throw (cssu::RuntimeException); 289 290 private: 291 const sal_Int32 mnStateSet; 292 }; 293 294 295 296 297 //===== AccessibleRelationSet ================================================= 298 299 namespace { 300 typedef ::cppu::WeakComponentImplHelper1 < 301 cssa::XAccessibleRelationSet 302 > AccessibleRelationSetInterfaceBase; 303 } 304 305 class AccessibleRelationSet 306 : public ::cppu::BaseMutex, 307 public AccessibleRelationSetInterfaceBase 308 { 309 public: 310 AccessibleRelationSet (void); 311 virtual ~AccessibleRelationSet (void); 312 313 void AddRelation ( 314 const sal_Int16 nRelationType, 315 const Reference<XInterface>& rxObject); 316 317 318 //----- XAccessibleRelationSet -------------------------------------------- 319 320 virtual sal_Int32 SAL_CALL getRelationCount (void) 321 throw (cssu::RuntimeException); 322 323 virtual AccessibleRelation SAL_CALL getRelation (sal_Int32 nIndex) 324 throw (cssu::RuntimeException, css::lang::IndexOutOfBoundsException); 325 326 virtual sal_Bool SAL_CALL containsRelation (sal_Int16 nRelationType) 327 throw (cssu::RuntimeException); 328 329 virtual AccessibleRelation SAL_CALL getRelationByType (sal_Int16 nRelationType) 330 throw (cssu::RuntimeException); 331 332 private: 333 ::std::vector<AccessibleRelation> maRelations; 334 }; 335 336 337 338 339 //===== PresenterAccessibleParagraph ========================================== 340 341 namespace { 342 typedef ::cppu::ImplInheritanceHelper1 < 343 PresenterAccessible::AccessibleObject, 344 cssa::XAccessibleText 345 > PresenterAccessibleParagraphInterfaceBase; 346 } 347 348 349 350 351 class PresenterAccessible::AccessibleParagraph 352 : public PresenterAccessibleParagraphInterfaceBase 353 { 354 public: 355 AccessibleParagraph ( 356 const css::lang::Locale aLocale, 357 const sal_Int16 nRole, 358 const ::rtl::OUString& rsName, 359 const SharedPresenterTextParagraph& rpParagraph, 360 const sal_Int32 nParagraphIndex); 361 362 virtual ~AccessibleParagraph (void); 363 364 365 //----- XAccessibleContext ------------------------------------------------ 366 367 virtual cssu::Reference<cssa::XAccessibleRelationSet> SAL_CALL 368 getAccessibleRelationSet (void) 369 throw (cssu::RuntimeException); 370 371 372 //----- XAccessibleText --------------------------------------------------- 373 374 virtual sal_Int32 SAL_CALL getCaretPosition (void) 375 throw (cssu::RuntimeException); 376 377 virtual sal_Bool SAL_CALL setCaretPosition (sal_Int32 nIndex) 378 throw (::com::sun::star::lang::IndexOutOfBoundsException, cssu::RuntimeException); 379 380 virtual sal_Unicode SAL_CALL getCharacter (sal_Int32 nIndex) 381 throw (::com::sun::star::lang::IndexOutOfBoundsException, cssu::RuntimeException); 382 383 virtual cssu::Sequence<css::beans::PropertyValue> SAL_CALL 384 getCharacterAttributes ( 385 ::sal_Int32 nIndex, 386 const cssu::Sequence<rtl::OUString>& rRequestedAttributes) 387 throw (css::lang::IndexOutOfBoundsException, cssu::RuntimeException); 388 389 virtual css::awt::Rectangle SAL_CALL getCharacterBounds (sal_Int32 nIndex) 390 throw (css::lang::IndexOutOfBoundsException, cssu::RuntimeException); 391 392 virtual sal_Int32 SAL_CALL getCharacterCount (void) 393 throw (cssu::RuntimeException); 394 395 virtual sal_Int32 SAL_CALL getIndexAtPoint (const css::awt::Point& rPoint) 396 throw (cssu::RuntimeException); 397 398 virtual ::rtl::OUString SAL_CALL getSelectedText (void) 399 throw (cssu::RuntimeException); 400 401 virtual sal_Int32 SAL_CALL getSelectionStart (void) 402 throw (cssu::RuntimeException); 403 404 virtual sal_Int32 SAL_CALL getSelectionEnd (void) 405 throw (cssu::RuntimeException); 406 407 virtual sal_Bool SAL_CALL setSelection (sal_Int32 nStartIndex, sal_Int32 nEndIndex) 408 throw (css::lang::IndexOutOfBoundsException, cssu::RuntimeException); 409 410 virtual ::rtl::OUString SAL_CALL getText (void) 411 throw (cssu::RuntimeException); 412 413 virtual ::rtl::OUString SAL_CALL getTextRange ( 414 sal_Int32 nStartIndex, 415 sal_Int32 nEndIndex) 416 throw (css::lang::IndexOutOfBoundsException, cssu::RuntimeException); 417 418 virtual cssa::TextSegment SAL_CALL getTextAtIndex ( 419 sal_Int32 nIndex, 420 sal_Int16 nTextType) 421 throw (css::lang::IndexOutOfBoundsException, 422 css::lang::IllegalArgumentException, 423 cssu::RuntimeException); 424 425 virtual cssa::TextSegment SAL_CALL getTextBeforeIndex ( 426 sal_Int32 nIndex, 427 sal_Int16 nTextType) 428 throw (css::lang::IndexOutOfBoundsException, 429 css::lang::IllegalArgumentException, 430 cssu::RuntimeException); 431 432 virtual cssa::TextSegment SAL_CALL getTextBehindIndex ( 433 sal_Int32 nIndex, 434 sal_Int16 nTextType) 435 throw (css::lang::IndexOutOfBoundsException, 436 css::lang::IllegalArgumentException, 437 cssu::RuntimeException); 438 439 virtual ::sal_Bool SAL_CALL copyText (sal_Int32 nStartIndex, sal_Int32 nEndIndex) 440 throw (css::lang::IndexOutOfBoundsException, cssu::RuntimeException); 441 442 443 protected: 444 virtual awt::Point GetRelativeLocation (void); 445 virtual awt::Size GetSize (void); 446 virtual awt::Point GetAbsoluteParentLocation (void); 447 virtual bool GetWindowState (const sal_Int16 nType) const; 448 449 private: 450 SharedPresenterTextParagraph mpParagraph; 451 const sal_Int32 mnParagraphIndex; 452 }; 453 454 455 456 457 //===== AccessibleConsole ===================================================== 458 459 class AccessibleConsole 460 { 461 public: 462 static rtl::Reference<PresenterAccessible::AccessibleObject> Create ( 463 const css::uno::Reference<css::uno::XComponentContext>& rxContext, 464 const lang::Locale aLocale) 465 { 466 OUString sName (A2S("Presenter Console")); 467 PresenterConfigurationAccess aConfiguration ( 468 rxContext, 469 OUString::createFromAscii("/org.openoffice.Office.extension.PresenterScreen/"), 470 PresenterConfigurationAccess::READ_ONLY); 471 aConfiguration.GetConfigurationNode(A2S("Presenter/Accessibility/Console/String")) 472 >>= sName; 473 474 rtl::Reference<PresenterAccessible::AccessibleObject> pObject ( 475 new PresenterAccessible::AccessibleObject( 476 aLocale, AccessibleRole::PANEL, sName)); 477 pObject->LateInitialization(); 478 pObject->UpdateStateSet(); 479 480 return pObject; 481 } 482 }; 483 484 485 486 487 //===== AccessiblePreview ===================================================== 488 489 class AccessiblePreview 490 { 491 public: 492 static rtl::Reference<PresenterAccessible::AccessibleObject> Create ( 493 const Reference<css::uno::XComponentContext>& rxContext, 494 const lang::Locale aLocale, 495 const Reference<awt::XWindow>& rxContentWindow, 496 const Reference<awt::XWindow>& rxBorderWindow) 497 { 498 OUString sName (A2S("Presenter Notes Window")); 499 { 500 PresenterConfigurationAccess aConfiguration ( 501 rxContext, 502 OUString::createFromAscii("/org.openoffice.Office.extension.PresenterScreen/"), 503 PresenterConfigurationAccess::READ_ONLY); 504 aConfiguration.GetConfigurationNode(A2S("Presenter/Accessibility/Preview/String")) 505 >>= sName; 506 } 507 508 rtl::Reference<PresenterAccessible::AccessibleObject> pObject ( 509 new PresenterAccessible::AccessibleObject( 510 aLocale, 511 AccessibleRole::LABEL, 512 sName)); 513 pObject->LateInitialization(); 514 pObject->UpdateStateSet(); 515 pObject->SetWindow(rxContentWindow, rxBorderWindow); 516 517 return pObject; 518 } 519 }; 520 521 522 523 524 //===== AccessibleNotes ======================================================= 525 526 class AccessibleNotes : public PresenterAccessible::AccessibleObject 527 { 528 public: 529 AccessibleNotes ( 530 const css::lang::Locale aLocale, 531 const sal_Int16 nRole, 532 const ::rtl::OUString& rsName); 533 534 535 static rtl::Reference<PresenterAccessible::AccessibleObject> Create ( 536 const css::uno::Reference<css::uno::XComponentContext>& rxContext, 537 const lang::Locale aLocale, 538 const Reference<awt::XWindow>& rxContentWindow, 539 const Reference<awt::XWindow>& rxBorderWindow, 540 const ::boost::shared_ptr<PresenterTextView>& rpTextView); 541 542 void SetTextView (const ::boost::shared_ptr<PresenterTextView>& rpTextView); 543 544 virtual void SetWindow ( 545 const cssu::Reference<css::awt::XWindow>& rxContentWindow, 546 const cssu::Reference<css::awt::XWindow>& rxBorderWindow); 547 548 private: 549 ::boost::shared_ptr<PresenterTextView> mpTextView; 550 551 void NotifyCaretChange ( 552 const sal_Int32 nOldParagraphIndex, 553 const sal_Int32 nOldCharacterIndex, 554 const sal_Int32 nNewParagraphIndex, 555 const sal_Int32 nNewCharacterIndex); 556 void HandleTextChange (void); 557 }; 558 559 560 561 562 //===== AccessibleFocusManager ================================================ 563 564 /** A singleton class that makes sure that only one accessibility object in 565 the PresenterConsole hierarchy has the focus. 566 */ 567 class AccessibleFocusManager 568 { 569 public: 570 static ::boost::shared_ptr<AccessibleFocusManager> Instance (void); 571 572 void AddFocusableObject (const ::rtl::Reference<PresenterAccessible::AccessibleObject>& rpObject); 573 void RemoveFocusableObject (const ::rtl::Reference<PresenterAccessible::AccessibleObject>& rpObject); 574 575 void FocusObject (const ::rtl::Reference<PresenterAccessible::AccessibleObject>& rpObject); 576 577 private: 578 static ::boost::shared_ptr<AccessibleFocusManager> mpInstance; 579 ::std::vector<rtl::Reference<PresenterAccessible::AccessibleObject> > maFocusableObjects; 580 581 AccessibleFocusManager (void); 582 }; 583 584 585 586 587 //===== PresenterAccessible =================================================== 588 589 PresenterAccessible::PresenterAccessible ( 590 const css::uno::Reference<css::uno::XComponentContext>& rxContext, 591 const ::rtl::Reference<PresenterController>& rpPresenterController, 592 const Reference<drawing::framework::XPane>& rxMainPane) 593 : PresenterAccessibleInterfaceBase(m_aMutex), 594 mxComponentContext(rxContext), 595 mpPresenterController(rpPresenterController), 596 mxMainPaneId(rxMainPane.is() ? rxMainPane->getResourceId() : Reference<XResourceId>()), 597 mxMainPane(rxMainPane, UNO_QUERY), 598 mxMainWindow(), 599 mxPreviewContentWindow(), 600 mxPreviewBorderWindow(), 601 mxNotesContentWindow(), 602 mxNotesBorderWindow(), 603 mpAccessibleConsole(), 604 mpAccessiblePreview(), 605 mpAccessibleNotes(), 606 mxAccessibleParent() 607 { 608 if (mxMainPane.is()) 609 mxMainPane->setAccessible(this); 610 } 611 612 613 614 615 PresenterAccessible::~PresenterAccessible (void) 616 { 617 } 618 619 620 621 622 PresenterPaneContainer::SharedPaneDescriptor PresenterAccessible::GetPreviewPane (void) const 623 { 624 PresenterPaneContainer::SharedPaneDescriptor pPreviewPane; 625 626 if ( ! mpPresenterController.is()) 627 return pPreviewPane; 628 629 rtl::Reference<PresenterPaneContainer> pContainer (mpPresenterController->GetPaneContainer()); 630 if ( ! pContainer.is()) 631 return pPreviewPane; 632 633 pPreviewPane = pContainer->FindPaneURL(PresenterPaneFactory::msCurrentSlidePreviewPaneURL); 634 Reference<drawing::framework::XPane> xPreviewPane; 635 if (pPreviewPane) 636 xPreviewPane = pPreviewPane->mxPane.get(); 637 if ( ! xPreviewPane.is()) 638 { 639 pPreviewPane = pContainer->FindPaneURL(PresenterPaneFactory::msSlideSorterPaneURL); 640 } 641 return pPreviewPane; 642 } 643 644 645 646 647 void PresenterAccessible::UpdateAccessibilityHierarchy (void) 648 { 649 if ( ! mpPresenterController.is()) 650 return; 651 652 Reference<drawing::framework::XConfigurationController> xConfigurationController( 653 mpPresenterController->GetConfigurationController()); 654 if ( ! xConfigurationController.is()) 655 return; 656 657 rtl::Reference<PresenterPaneContainer> pPaneContainer ( 658 mpPresenterController->GetPaneContainer()); 659 if ( ! pPaneContainer.is()) 660 return; 661 662 if ( ! mpAccessibleConsole.is()) 663 return; 664 665 // Get the preview pane (standard or notes view) or the slide overview 666 // pane. 667 PresenterPaneContainer::SharedPaneDescriptor pPreviewPane(GetPreviewPane()); 668 Reference<drawing::framework::XPane> xPreviewPane; 669 if (pPreviewPane) 670 xPreviewPane = pPreviewPane->mxPane.get(); 671 672 // Get the notes pane. 673 PresenterPaneContainer::SharedPaneDescriptor pNotesPane( 674 pPaneContainer->FindPaneURL(PresenterPaneFactory::msNotesPaneURL)); 675 Reference<drawing::framework::XPane> xNotesPane; 676 if (pNotesPane) 677 xNotesPane = pNotesPane->mxPane.get(); 678 679 // Get the notes view. 680 Reference<drawing::framework::XView> xNotesView; 681 if (pNotesPane) 682 xNotesView = pNotesPane->mxView; 683 rtl::Reference<PresenterNotesView> pNotesView ( 684 dynamic_cast<PresenterNotesView*>(xNotesView.get())); 685 686 UpdateAccessibilityHierarchy( 687 pPreviewPane ? pPreviewPane->mxContentWindow : Reference<awt::XWindow>(), 688 pPreviewPane ? pPreviewPane->mxBorderWindow : Reference<awt::XWindow>(), 689 (pPreviewPane&&pPreviewPane->mxPane.is()) ? pPreviewPane->mxPane->GetTitle() : OUString(), 690 pNotesPane ? pNotesPane->mxContentWindow : Reference<awt::XWindow>(), 691 pNotesPane ? pNotesPane->mxBorderWindow : Reference<awt::XWindow>(), 692 pNotesView.is() 693 ? pNotesView->GetTextView() 694 : ::boost::shared_ptr<PresenterTextView>()); 695 } 696 697 698 699 700 701 void PresenterAccessible::UpdateAccessibilityHierarchy ( 702 const Reference<awt::XWindow>& rxPreviewContentWindow, 703 const Reference<awt::XWindow>& rxPreviewBorderWindow, 704 const ::rtl::OUString& rsTitle, 705 const Reference<awt::XWindow>& rxNotesContentWindow, 706 const Reference<awt::XWindow>& rxNotesBorderWindow, 707 const ::boost::shared_ptr<PresenterTextView>& rpNotesTextView) 708 { 709 if ( ! mpAccessibleConsole.is()) 710 return; 711 712 if (mxPreviewContentWindow != rxPreviewContentWindow) 713 { 714 if (mpAccessiblePreview.is()) 715 { 716 mpAccessibleConsole->RemoveChild(mpAccessiblePreview); 717 mpAccessiblePreview = NULL; 718 } 719 720 mxPreviewContentWindow = rxPreviewContentWindow; 721 mxPreviewBorderWindow = rxPreviewBorderWindow; 722 723 if (mxPreviewContentWindow.is()) 724 { 725 mpAccessiblePreview = AccessiblePreview::Create( 726 mxComponentContext, 727 lang::Locale(), 728 mxPreviewContentWindow, 729 mxPreviewBorderWindow); 730 mpAccessibleConsole->AddChild(mpAccessiblePreview); 731 mpAccessiblePreview->SetAccessibleName(rsTitle); 732 } 733 } 734 735 if (mxNotesContentWindow != rxNotesContentWindow) 736 { 737 if (mpAccessibleNotes.is()) 738 { 739 mpAccessibleConsole->RemoveChild(mpAccessibleConsole.get()); 740 mpAccessibleNotes = NULL; 741 } 742 743 mxNotesContentWindow = rxNotesContentWindow; 744 mxNotesBorderWindow = rxNotesBorderWindow; 745 746 if (mxNotesContentWindow.is()) 747 { 748 mpAccessibleNotes = AccessibleNotes::Create( 749 mxComponentContext, 750 lang::Locale(), 751 mxNotesContentWindow, 752 mxNotesBorderWindow, 753 rpNotesTextView); 754 mpAccessibleConsole->AddChild(mpAccessibleNotes.get()); 755 } 756 } 757 } 758 759 760 761 762 void PresenterAccessible::NotifyCurrentSlideChange ( 763 const sal_Int32 nCurrentSlideIndex, 764 const sal_Int32 nSlideCount) 765 { 766 (void)nCurrentSlideIndex; 767 (void)nSlideCount; 768 769 if (mpAccessiblePreview.is()) 770 { 771 PresenterPaneContainer::SharedPaneDescriptor pPreviewPane (GetPreviewPane()); 772 mpAccessiblePreview->SetAccessibleName( 773 (pPreviewPane&&pPreviewPane->mxPane.is() 774 ? pPreviewPane->mxPane->GetTitle() 775 : rtl::OUString())); 776 } 777 778 // Play some focus ping-pong to trigger AT tools. 779 //AccessibleFocusManager::Instance()->FocusObject(mpAccessibleConsole); 780 AccessibleFocusManager::Instance()->FocusObject(mpAccessiblePreview); 781 } 782 783 784 785 786 bool PresenterAccessible::IsAccessibilityActive (void) const 787 { 788 return mpAccessibleConsole.is(); 789 } 790 791 792 793 794 void SAL_CALL PresenterAccessible::disposing (void) 795 { 796 UpdateAccessibilityHierarchy( 797 NULL, 798 NULL, 799 OUString(), 800 NULL, 801 NULL, 802 ::boost::shared_ptr<PresenterTextView>()); 803 804 if (mxMainWindow.is()) 805 { 806 mxMainWindow->removeFocusListener(this); 807 808 if (mxMainPane.is()) 809 mxMainPane->setAccessible(NULL); 810 } 811 812 mpAccessiblePreview = NULL; 813 mpAccessibleNotes = NULL; 814 mpAccessibleConsole = NULL; 815 } 816 817 818 819 820 //----- XAccessible ----------------------------------------------------------- 821 822 Reference<XAccessibleContext> SAL_CALL PresenterAccessible::getAccessibleContext (void) 823 throw (cssu::RuntimeException) 824 { 825 if ( ! mpAccessibleConsole.is()) 826 { 827 Reference<XPane> xMainPane (mxMainPane, UNO_QUERY); 828 if (xMainPane.is()) 829 { 830 mxMainWindow = Reference<awt::XWindow>(xMainPane->getWindow(), UNO_QUERY); 831 mxMainWindow->addFocusListener(this); 832 } 833 mpAccessibleConsole = AccessibleConsole::Create( 834 mxComponentContext, css::lang::Locale()); 835 mpAccessibleConsole->SetWindow(mxMainWindow, NULL); 836 mpAccessibleConsole->SetAccessibleParent(mxAccessibleParent); 837 UpdateAccessibilityHierarchy(); 838 if (mpPresenterController.is()) 839 mpPresenterController->SetAccessibilityActiveState(true); 840 } 841 return mpAccessibleConsole->getAccessibleContext(); 842 } 843 844 845 846 847 848 //----- XFocusListener ---------------------------------------------------- 849 850 void SAL_CALL PresenterAccessible::focusGained (const css::awt::FocusEvent& rEvent) 851 throw (cssu::RuntimeException) 852 { 853 (void)rEvent; 854 855 #ifdef VERBOSE 856 OSL_TRACE("PresenterAccessible::focusGained at %x and window %x\r", this, 857 mxMainWindow.get()); 858 #endif 859 860 AccessibleFocusManager::Instance()->FocusObject(mpAccessibleConsole); 861 } 862 863 864 865 866 void SAL_CALL PresenterAccessible::focusLost (const css::awt::FocusEvent& rEvent) 867 throw (cssu::RuntimeException) 868 { 869 (void)rEvent; 870 871 #ifdef VERBOSE 872 OSL_TRACE("PresenterAccessible::focusLost at %x\r", this); 873 #endif 874 875 AccessibleFocusManager::Instance()->FocusObject(NULL); 876 } 877 878 879 880 881 //----- XEventListener ---------------------------------------------------- 882 883 void SAL_CALL PresenterAccessible::disposing (const css::lang::EventObject& rEvent) 884 throw (cssu::RuntimeException) 885 { 886 if (rEvent.Source == mxMainWindow) 887 mxMainWindow = NULL; 888 } 889 890 891 892 893 //----- XInitialize ----------------------------------------------------------- 894 895 void SAL_CALL PresenterAccessible::initialize (const cssu::Sequence<cssu::Any>& rArguments) 896 throw (cssu::RuntimeException) 897 { 898 if (rArguments.getLength() >= 1) 899 { 900 mxAccessibleParent = Reference<XAccessible>(rArguments[0], UNO_QUERY); 901 if (mpAccessibleConsole.is()) 902 mpAccessibleConsole->SetAccessibleParent(mxAccessibleParent); 903 } 904 } 905 906 907 908 909 //===== PresenterAccessible::AccessibleObject ========================================= 910 911 PresenterAccessible::AccessibleObject::AccessibleObject ( 912 const lang::Locale aLocale, 913 const sal_Int16 nRole, 914 const OUString& rsName) 915 : PresenterAccessibleObjectInterfaceBase(m_aMutex), 916 msName(rsName), 917 mxContentWindow(), 918 mxBorderWindow(), 919 maLocale(aLocale), 920 mnRole(nRole), 921 mnStateSet(0), 922 mbIsFocused(false), 923 mxParentAccessible(), 924 maChildren(), 925 maListeners() 926 { 927 } 928 929 930 931 932 void PresenterAccessible::AccessibleObject::LateInitialization (void) 933 { 934 AccessibleFocusManager::Instance()->AddFocusableObject(this); 935 } 936 937 938 939 940 PresenterAccessible::AccessibleObject::~AccessibleObject (void) 941 { 942 } 943 944 945 946 947 void PresenterAccessible::AccessibleObject::SetWindow ( 948 const Reference<awt::XWindow>& rxContentWindow, 949 const Reference<awt::XWindow>& rxBorderWindow) 950 { 951 Reference<awt::XWindow2> xContentWindow (rxContentWindow, UNO_QUERY); 952 953 if (mxContentWindow.get() != xContentWindow.get()) 954 { 955 if (mxContentWindow.is()) 956 { 957 mxContentWindow->removeWindowListener(this); 958 } 959 960 mxContentWindow = xContentWindow; 961 mxBorderWindow = Reference<awt::XWindow2>(rxBorderWindow, UNO_QUERY); 962 963 if (mxContentWindow.is()) 964 { 965 mxContentWindow->addWindowListener(this); 966 } 967 968 UpdateStateSet(); 969 } 970 } 971 972 973 974 975 void PresenterAccessible::AccessibleObject::SetAccessibleParent ( 976 const Reference<XAccessible>& rxAccessibleParent) 977 { 978 mxParentAccessible = rxAccessibleParent; 979 } 980 981 982 983 984 void SAL_CALL PresenterAccessible::AccessibleObject::disposing (void) 985 { 986 AccessibleFocusManager::Instance()->RemoveFocusableObject(this); 987 SetWindow(NULL, NULL); 988 } 989 990 991 992 993 //----- XAccessible ------------------------------------------------------- 994 995 Reference<XAccessibleContext> SAL_CALL 996 PresenterAccessible::AccessibleObject::getAccessibleContext (void) 997 throw (RuntimeException) 998 { 999 ThrowIfDisposed(); 1000 1001 return this; 1002 } 1003 1004 1005 1006 1007 //----- XAccessibleContext ---------------------------------------------- 1008 1009 sal_Int32 SAL_CALL PresenterAccessible::AccessibleObject::getAccessibleChildCount (void) 1010 throw (cssu::RuntimeException) 1011 { 1012 ThrowIfDisposed(); 1013 1014 const sal_Int32 nChildCount (maChildren.size()); 1015 1016 return nChildCount; 1017 } 1018 1019 1020 1021 1022 Reference<XAccessible> SAL_CALL 1023 PresenterAccessible::AccessibleObject::getAccessibleChild (sal_Int32 nIndex) 1024 throw (lang::IndexOutOfBoundsException, RuntimeException) 1025 { 1026 ThrowIfDisposed(); 1027 1028 if (nIndex<0 || nIndex>=sal_Int32(maChildren.size())) 1029 ThrowException("invalid child index", ET_IndexOutOfBounds); 1030 1031 return Reference<XAccessible>(maChildren[nIndex].get()); 1032 } 1033 1034 1035 1036 1037 Reference<XAccessible> SAL_CALL 1038 PresenterAccessible::AccessibleObject::getAccessibleParent (void) 1039 throw (RuntimeException) 1040 { 1041 ThrowIfDisposed(); 1042 1043 return mxParentAccessible; 1044 } 1045 1046 1047 1048 1049 sal_Int32 SAL_CALL 1050 PresenterAccessible::AccessibleObject::getAccessibleIndexInParent (void) 1051 throw (RuntimeException) 1052 { 1053 ThrowIfDisposed(); 1054 1055 const Reference<XAccessible> xThis (this); 1056 if (mxParentAccessible.is()) 1057 { 1058 const Reference<XAccessibleContext> xContext (mxParentAccessible->getAccessibleContext()); 1059 for (sal_Int32 nIndex=0,nCount=xContext->getAccessibleChildCount(); 1060 nIndex<nCount; 1061 ++nIndex) 1062 { 1063 if (xContext->getAccessibleChild(nIndex) == xThis) 1064 return nIndex; 1065 } 1066 } 1067 1068 return 0; 1069 } 1070 1071 1072 1073 1074 sal_Int16 SAL_CALL 1075 PresenterAccessible::AccessibleObject::getAccessibleRole (void) 1076 throw (RuntimeException) 1077 { 1078 ThrowIfDisposed(); 1079 1080 return mnRole; 1081 } 1082 1083 1084 1085 1086 OUString SAL_CALL 1087 PresenterAccessible::AccessibleObject::getAccessibleDescription (void) 1088 throw (RuntimeException) 1089 { 1090 ThrowIfDisposed(); 1091 1092 return msName; 1093 } 1094 1095 1096 1097 1098 OUString SAL_CALL 1099 PresenterAccessible::AccessibleObject::getAccessibleName (void) 1100 throw (cssu::RuntimeException) 1101 { 1102 ThrowIfDisposed(); 1103 1104 return msName; 1105 } 1106 1107 1108 1109 1110 Reference<XAccessibleRelationSet> SAL_CALL 1111 PresenterAccessible::AccessibleObject::getAccessibleRelationSet (void) 1112 throw (RuntimeException) 1113 { 1114 ThrowIfDisposed(); 1115 1116 return NULL; 1117 } 1118 1119 1120 1121 1122 Reference<XAccessibleStateSet> SAL_CALL 1123 PresenterAccessible::AccessibleObject::getAccessibleStateSet (void) 1124 throw (RuntimeException) 1125 { 1126 ThrowIfDisposed(); 1127 1128 return Reference<XAccessibleStateSet>(new AccessibleStateSet(mnStateSet)); 1129 } 1130 1131 1132 1133 1134 lang::Locale SAL_CALL 1135 PresenterAccessible::AccessibleObject::getLocale (void) 1136 throw (RuntimeException, 1137 IllegalAccessibleComponentStateException) 1138 { 1139 ThrowIfDisposed(); 1140 1141 if (mxParentAccessible.is()) 1142 { 1143 Reference<XAccessibleContext> xParentContext (mxParentAccessible->getAccessibleContext()); 1144 if (xParentContext.is()) 1145 return xParentContext->getLocale(); 1146 } 1147 return maLocale; 1148 } 1149 1150 1151 1152 1153 //----- XAccessibleComponent ------------------------------------------------ 1154 1155 sal_Bool SAL_CALL PresenterAccessible::AccessibleObject::containsPoint ( 1156 const awt::Point& rPoint) 1157 throw (RuntimeException) 1158 { 1159 ThrowIfDisposed(); 1160 1161 if (mxContentWindow.is()) 1162 { 1163 const awt::Rectangle aBox (getBounds()); 1164 return rPoint.X>=aBox.X 1165 && rPoint.Y>=aBox.Y 1166 && rPoint.X<aBox.X+aBox.Width 1167 && rPoint.Y<aBox.Y+aBox.Height; 1168 } 1169 else 1170 return false; 1171 } 1172 1173 1174 1175 1176 Reference<XAccessible> SAL_CALL 1177 PresenterAccessible::AccessibleObject::getAccessibleAtPoint (const awt::Point& rPoint) 1178 throw (RuntimeException) 1179 { 1180 (void)rPoint; 1181 ThrowIfDisposed(); 1182 1183 return Reference<XAccessible>(); 1184 } 1185 1186 1187 1188 1189 awt::Rectangle SAL_CALL PresenterAccessible::AccessibleObject::getBounds (void) 1190 throw (RuntimeException) 1191 { 1192 ThrowIfDisposed(); 1193 1194 awt::Rectangle aBox; 1195 1196 const awt::Point aLocation (GetRelativeLocation()); 1197 const awt::Size aSize (GetSize()); 1198 1199 return awt::Rectangle (aLocation.X, aLocation.Y, aSize.Width, aSize.Height); 1200 } 1201 1202 1203 1204 1205 awt::Point SAL_CALL PresenterAccessible::AccessibleObject::getLocation (void) 1206 throw (RuntimeException) 1207 { 1208 ThrowIfDisposed(); 1209 1210 const awt::Point aLocation (GetRelativeLocation()); 1211 1212 return aLocation; 1213 } 1214 1215 1216 1217 1218 awt::Point SAL_CALL PresenterAccessible::AccessibleObject::getLocationOnScreen (void) 1219 throw (RuntimeException) 1220 { 1221 ThrowIfDisposed(); 1222 1223 awt::Point aRelativeLocation (GetRelativeLocation()); 1224 awt::Point aParentLocationOnScreen (GetAbsoluteParentLocation()); 1225 1226 return awt::Point( 1227 aRelativeLocation.X + aParentLocationOnScreen.X, 1228 aRelativeLocation.Y + aParentLocationOnScreen.Y); 1229 } 1230 1231 1232 1233 1234 awt::Size SAL_CALL PresenterAccessible::AccessibleObject::getSize (void) 1235 throw (RuntimeException) 1236 { 1237 ThrowIfDisposed(); 1238 1239 const awt::Size aSize (GetSize()); 1240 1241 return aSize; 1242 } 1243 1244 1245 1246 1247 void SAL_CALL PresenterAccessible::AccessibleObject::grabFocus (void) 1248 throw (RuntimeException) 1249 { 1250 ThrowIfDisposed(); 1251 if (mxBorderWindow.is()) 1252 mxBorderWindow->setFocus(); 1253 else if (mxContentWindow.is()) 1254 mxContentWindow->setFocus(); 1255 } 1256 1257 1258 1259 1260 sal_Int32 SAL_CALL PresenterAccessible::AccessibleObject::getForeground (void) 1261 throw (RuntimeException) 1262 { 1263 ThrowIfDisposed(); 1264 1265 return 0x00ffffff; 1266 } 1267 1268 1269 1270 1271 sal_Int32 SAL_CALL PresenterAccessible::AccessibleObject::getBackground (void) 1272 throw (RuntimeException) 1273 { 1274 ThrowIfDisposed(); 1275 1276 return 0x00000000; 1277 } 1278 1279 1280 1281 1282 //----- XAccessibleEventBroadcaster ------------------------------------------- 1283 1284 void SAL_CALL PresenterAccessible::AccessibleObject::addEventListener ( 1285 const Reference<XAccessibleEventListener>& rxListener) 1286 throw (RuntimeException) 1287 { 1288 if (rxListener.is()) 1289 { 1290 const osl::MutexGuard aGuard(m_aMutex); 1291 1292 if (IsDisposed()) 1293 { 1294 uno::Reference<uno::XInterface> xThis (static_cast<XWeak*>(this), UNO_QUERY); 1295 rxListener->disposing (lang::EventObject(xThis)); 1296 } 1297 else 1298 { 1299 maListeners.push_back(rxListener); 1300 } 1301 } 1302 } 1303 1304 1305 1306 1307 void SAL_CALL PresenterAccessible::AccessibleObject::removeEventListener ( 1308 const Reference<XAccessibleEventListener>& rxListener) 1309 throw (RuntimeException) 1310 { 1311 ThrowIfDisposed(); 1312 if (rxListener.is()) 1313 { 1314 const osl::MutexGuard aGuard(m_aMutex); 1315 1316 maListeners.erase(std::remove(maListeners.begin(), maListeners.end(), rxListener)); 1317 } 1318 } 1319 1320 1321 1322 1323 //----- XWindowListener --------------------------------------------------- 1324 1325 void SAL_CALL PresenterAccessible::AccessibleObject::windowResized ( 1326 const css::awt::WindowEvent& rEvent) 1327 throw (cssu::RuntimeException) 1328 { 1329 (void)rEvent; 1330 1331 FireAccessibleEvent(AccessibleEventId::BOUNDRECT_CHANGED, Any(), Any()); 1332 } 1333 1334 1335 1336 1337 void SAL_CALL PresenterAccessible::AccessibleObject::windowMoved ( 1338 const css::awt::WindowEvent& rEvent) 1339 throw (cssu::RuntimeException) 1340 { 1341 (void)rEvent; 1342 1343 FireAccessibleEvent(AccessibleEventId::BOUNDRECT_CHANGED, Any(), Any()); 1344 } 1345 1346 1347 1348 1349 void SAL_CALL PresenterAccessible::AccessibleObject::windowShown ( 1350 const css::lang::EventObject& rEvent) 1351 throw (cssu::RuntimeException) 1352 { 1353 (void)rEvent; 1354 UpdateStateSet(); 1355 } 1356 1357 1358 1359 1360 void SAL_CALL PresenterAccessible::AccessibleObject::windowHidden ( 1361 const css::lang::EventObject& rEvent) 1362 throw (cssu::RuntimeException) 1363 { 1364 (void)rEvent; 1365 UpdateStateSet(); 1366 } 1367 1368 1369 1370 1371 //----- XEventListener -------------------------------------------------------- 1372 1373 void SAL_CALL PresenterAccessible::AccessibleObject::disposing (const css::lang::EventObject& rEvent) 1374 throw (cssu::RuntimeException) 1375 { 1376 if (rEvent.Source == mxContentWindow) 1377 { 1378 mxContentWindow = NULL; 1379 mxBorderWindow = NULL; 1380 } 1381 else 1382 { 1383 SetWindow(NULL, NULL); 1384 } 1385 } 1386 1387 1388 1389 1390 //----- private --------------------------------------------------------------- 1391 1392 bool PresenterAccessible::AccessibleObject::GetWindowState (const sal_Int16 nType) const 1393 { 1394 switch (nType) 1395 { 1396 case AccessibleStateType::ENABLED: 1397 return mxContentWindow.is() && mxContentWindow->isEnabled(); 1398 1399 case AccessibleStateType::FOCUSABLE: 1400 return true; 1401 1402 case AccessibleStateType::FOCUSED: 1403 return mbIsFocused; 1404 1405 case AccessibleStateType::SHOWING: 1406 return mxContentWindow.is() && mxContentWindow->isVisible(); 1407 1408 default: 1409 return false; 1410 } 1411 } 1412 1413 1414 1415 1416 void PresenterAccessible::AccessibleObject::UpdateStateSet (void) 1417 { 1418 UpdateState(AccessibleStateType::FOCUSABLE, true); 1419 UpdateState(AccessibleStateType::VISIBLE, true); 1420 UpdateState(AccessibleStateType::ENABLED, true); 1421 UpdateState(AccessibleStateType::MULTI_LINE, true); 1422 UpdateState(AccessibleStateType::SENSITIVE, true); 1423 1424 UpdateState(AccessibleStateType::ENABLED, GetWindowState(AccessibleStateType::ENABLED)); 1425 UpdateState(AccessibleStateType::FOCUSED, GetWindowState(AccessibleStateType::FOCUSED)); 1426 UpdateState(AccessibleStateType::SHOWING, GetWindowState(AccessibleStateType::SHOWING)); 1427 // UpdateState(AccessibleStateType::ACTIVE, GetWindowState(AccessibleStateType::ACTIVE)); 1428 } 1429 1430 1431 1432 1433 void PresenterAccessible::AccessibleObject::UpdateState( 1434 const sal_Int16 nState, 1435 const bool bValue) 1436 { 1437 const sal_uInt32 nStateMask (AccessibleStateSet::GetStateMask(nState)); 1438 if (((mnStateSet & nStateMask)!=0) != bValue) 1439 { 1440 if (bValue) 1441 { 1442 mnStateSet |= nStateMask; 1443 FireAccessibleEvent(AccessibleEventId::STATE_CHANGED, Any(), Any(nState)); 1444 } 1445 else 1446 { 1447 mnStateSet &= ~nStateMask; 1448 FireAccessibleEvent(AccessibleEventId::STATE_CHANGED, Any(nState), Any()); 1449 } 1450 } 1451 } 1452 1453 1454 1455 1456 void PresenterAccessible::AccessibleObject::AddChild ( 1457 const ::rtl::Reference<AccessibleObject>& rpChild) 1458 { 1459 maChildren.push_back(rpChild); 1460 rpChild->SetAccessibleParent(this); 1461 FireAccessibleEvent(AccessibleEventId::INVALIDATE_ALL_CHILDREN, Any(), Any()); 1462 } 1463 1464 1465 1466 1467 void PresenterAccessible::AccessibleObject::RemoveChild ( 1468 const ::rtl::Reference<AccessibleObject>& rpChild) 1469 { 1470 rpChild->SetAccessibleParent(Reference<XAccessible>()); 1471 maChildren.erase(::std::find(maChildren.begin(), maChildren.end(), rpChild)); 1472 FireAccessibleEvent(AccessibleEventId::INVALIDATE_ALL_CHILDREN, Any(), Any()); 1473 } 1474 1475 1476 1477 1478 void PresenterAccessible::AccessibleObject::SetIsFocused (const bool bIsFocused) 1479 { 1480 if (mbIsFocused != bIsFocused) 1481 { 1482 mbIsFocused = bIsFocused; 1483 UpdateStateSet(); 1484 } 1485 } 1486 1487 1488 1489 1490 void PresenterAccessible::AccessibleObject::SetAccessibleName (const ::rtl::OUString& rsName) 1491 { 1492 if (msName != rsName) 1493 { 1494 const OUString sOldName(msName); 1495 msName = rsName; 1496 FireAccessibleEvent(AccessibleEventId::NAME_CHANGED, Any(sOldName), Any(msName)); 1497 } 1498 } 1499 1500 1501 1502 1503 void PresenterAccessible::AccessibleObject::FireAccessibleEvent ( 1504 const sal_Int16 nEventId, 1505 const uno::Any& rOldValue, 1506 const uno::Any& rNewValue ) 1507 { 1508 AccessibleEventObject aEventObject; 1509 1510 aEventObject.Source = Reference<XWeak>(this); 1511 aEventObject.EventId = nEventId; 1512 aEventObject.NewValue = rNewValue; 1513 aEventObject.OldValue = rOldValue; 1514 1515 ::std::vector<Reference<XAccessibleEventListener> > aListenerCopy(maListeners); 1516 for (::std::vector<Reference<XAccessibleEventListener> >::const_iterator 1517 iListener(aListenerCopy.begin()), 1518 iEnd(aListenerCopy.end()); 1519 iListener!=iEnd; 1520 ++iListener) 1521 { 1522 try 1523 { 1524 (*iListener)->notifyEvent(aEventObject); 1525 } 1526 catch(lang::DisposedException&) 1527 { 1528 // Listener has been disposed and should have been removed 1529 // already. 1530 removeEventListener(*iListener); 1531 } 1532 catch(Exception&) 1533 { 1534 // Ignore all other exceptions and assume that they are 1535 // caused by a temporary problem. 1536 } 1537 } 1538 } 1539 1540 1541 1542 awt::Point PresenterAccessible::AccessibleObject::GetRelativeLocation (void) 1543 { 1544 awt::Point aLocation; 1545 if (mxContentWindow.is()) 1546 { 1547 const awt::Rectangle aContentBox (mxContentWindow->getPosSize()); 1548 aLocation.X = aContentBox.X; 1549 aLocation.Y = aContentBox.Y; 1550 if (mxBorderWindow.is()) 1551 { 1552 const awt::Rectangle aBorderBox (mxBorderWindow->getPosSize()); 1553 aLocation.X += aBorderBox.X; 1554 aLocation.Y += aBorderBox.Y; 1555 } 1556 } 1557 return aLocation; 1558 } 1559 1560 1561 1562 1563 awt::Size PresenterAccessible::AccessibleObject::GetSize (void) 1564 { 1565 if (mxContentWindow.is()) 1566 { 1567 const awt::Rectangle aBox (mxContentWindow->getPosSize()); 1568 return awt::Size(aBox.Width, aBox.Height); 1569 } 1570 else 1571 return awt::Size(); 1572 } 1573 1574 1575 1576 1577 awt::Point PresenterAccessible::AccessibleObject::GetAbsoluteParentLocation (void) 1578 { 1579 Reference<XAccessibleComponent> xParentComponent; 1580 if (mxParentAccessible.is()) 1581 xParentComponent = Reference<XAccessibleComponent>( 1582 mxParentAccessible->getAccessibleContext(), UNO_QUERY); 1583 if (xParentComponent.is()) 1584 return xParentComponent->getLocationOnScreen(); 1585 else 1586 return awt::Point(); 1587 } 1588 1589 1590 1591 1592 sal_Bool PresenterAccessible::AccessibleObject::IsDisposed (void) const 1593 { 1594 return (rBHelper.bDisposed || rBHelper.bInDispose); 1595 } 1596 1597 1598 1599 1600 void PresenterAccessible::AccessibleObject::ThrowIfDisposed (void) const 1601 throw (lang::DisposedException) 1602 { 1603 if (rBHelper.bDisposed || rBHelper.bInDispose) 1604 ThrowException("object has already been disposed", ET_Disposed); 1605 } 1606 1607 1608 1609 1610 void PresenterAccessible::AccessibleObject::ThrowException ( 1611 const sal_Char* pMessage, 1612 const ExceptionType eExceptionType) const 1613 { 1614 const OUString sMessage (OUString(A2S("PresenterAccessible: ")) + OUString(A2S(pMessage))); 1615 const Reference<XInterface> xObject ( 1616 const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this))); 1617 switch (eExceptionType) 1618 { 1619 default: 1620 case ET_Runtime: 1621 throw RuntimeException(sMessage, xObject); 1622 case ET_Disposed: 1623 throw lang::DisposedException(sMessage, xObject); 1624 case ET_IndexOutOfBounds: 1625 throw lang::IndexOutOfBoundsException(sMessage, xObject); 1626 } 1627 } 1628 1629 1630 1631 1632 1633 //===== AccessibleStateSet ==================================================== 1634 1635 AccessibleStateSet::AccessibleStateSet (const sal_Int32 nStateSet) 1636 : AccessibleStateSetInterfaceBase(m_aMutex), 1637 mnStateSet (nStateSet) 1638 { 1639 } 1640 1641 1642 1643 1644 AccessibleStateSet::~AccessibleStateSet (void) 1645 { 1646 } 1647 1648 1649 1650 1651 sal_uInt32 AccessibleStateSet::GetStateMask (const sal_Int16 nState) 1652 { 1653 if (nState<0 || nState>=sal_Int16(sizeof(sal_uInt32)*8)) 1654 { 1655 throw RuntimeException(A2S("AccessibleStateSet::GetStateMask: invalid state"), NULL); 1656 } 1657 1658 return 1<<nState; 1659 } 1660 1661 1662 1663 1664 //----- XAccessibleStateSet --------------------------------------------------- 1665 1666 sal_Bool SAL_CALL AccessibleStateSet::isEmpty (void) 1667 throw (cssu::RuntimeException) 1668 { 1669 return mnStateSet==0; 1670 } 1671 1672 1673 1674 1675 sal_Bool SAL_CALL AccessibleStateSet::contains (sal_Int16 nState) 1676 throw (cssu::RuntimeException) 1677 { 1678 return (mnStateSet & GetStateMask(nState)) != 0; 1679 } 1680 1681 1682 1683 1684 sal_Bool SAL_CALL AccessibleStateSet::containsAll (const cssu::Sequence<sal_Int16>& rStateSet) 1685 throw (cssu::RuntimeException) 1686 { 1687 for (sal_Int32 nIndex=0,nCount=rStateSet.getLength(); nIndex<nCount; ++nIndex) 1688 { 1689 if ((mnStateSet & GetStateMask(rStateSet[nIndex])) == 0) 1690 return sal_False; 1691 } 1692 return sal_True; 1693 } 1694 1695 1696 1697 1698 cssu::Sequence<sal_Int16> SAL_CALL AccessibleStateSet::getStates (void) 1699 throw (cssu::RuntimeException) 1700 { 1701 ::std::vector<sal_Int16> aStates; 1702 aStates.reserve(sizeof(mnStateSet)*8); 1703 for (sal_uInt16 nIndex=0; nIndex<sizeof(mnStateSet)*8; ++nIndex) 1704 if ((mnStateSet & GetStateMask(nIndex)) != 0) 1705 aStates.push_back(nIndex); 1706 return Sequence<sal_Int16>(&aStates.front(), aStates.size()); 1707 } 1708 1709 1710 1711 1712 //===== AccessibleRelationSet ================================================= 1713 1714 AccessibleRelationSet::AccessibleRelationSet (void) 1715 : AccessibleRelationSetInterfaceBase(m_aMutex), 1716 maRelations() 1717 { 1718 } 1719 1720 1721 1722 1723 AccessibleRelationSet::~AccessibleRelationSet (void) 1724 { 1725 } 1726 1727 1728 1729 1730 void AccessibleRelationSet::AddRelation ( 1731 const sal_Int16 nRelationType, 1732 const Reference<XInterface>& rxObject) 1733 { 1734 maRelations.resize(maRelations.size()+1); 1735 maRelations.back().RelationType = nRelationType; 1736 maRelations.back().TargetSet.realloc(1); 1737 maRelations.back().TargetSet[0] = rxObject; 1738 } 1739 1740 1741 1742 1743 //----- XAccessibleRelationSet ------------------------------------------------ 1744 1745 sal_Int32 SAL_CALL AccessibleRelationSet::getRelationCount (void) 1746 throw (cssu::RuntimeException) 1747 { 1748 return maRelations.size(); 1749 } 1750 1751 1752 1753 1754 AccessibleRelation SAL_CALL AccessibleRelationSet::getRelation (sal_Int32 nIndex) 1755 throw (cssu::RuntimeException, css::lang::IndexOutOfBoundsException) 1756 { 1757 if (nIndex<0 && sal_uInt32(nIndex)>=maRelations.size()) 1758 return AccessibleRelation(); 1759 else 1760 return maRelations[nIndex]; 1761 } 1762 1763 1764 1765 1766 sal_Bool SAL_CALL AccessibleRelationSet::containsRelation (sal_Int16 nRelationType) 1767 throw (cssu::RuntimeException) 1768 { 1769 for (::std::vector<AccessibleRelation>::const_iterator iRelation(maRelations.begin()); 1770 iRelation!=maRelations.end(); 1771 ++iRelation) 1772 { 1773 if (iRelation->RelationType == nRelationType) 1774 return sal_True; 1775 } 1776 return sal_False; 1777 } 1778 1779 1780 1781 1782 AccessibleRelation SAL_CALL AccessibleRelationSet::getRelationByType (sal_Int16 nRelationType) 1783 throw (cssu::RuntimeException) 1784 { 1785 for (::std::vector<AccessibleRelation>::const_iterator iRelation(maRelations.begin()); 1786 iRelation!=maRelations.end(); 1787 ++iRelation) 1788 { 1789 if (iRelation->RelationType == nRelationType) 1790 return *iRelation; 1791 } 1792 return AccessibleRelation(); 1793 } 1794 1795 1796 1797 1798 //===== PresenterAccessible::AccessibleParagraph ============================== 1799 1800 PresenterAccessible::AccessibleParagraph::AccessibleParagraph ( 1801 const lang::Locale aLocale, 1802 const sal_Int16 nRole, 1803 const OUString& rsName, 1804 const SharedPresenterTextParagraph& rpParagraph, 1805 const sal_Int32 nParagraphIndex) 1806 : PresenterAccessibleParagraphInterfaceBase(aLocale, nRole, rsName), 1807 mpParagraph(rpParagraph), 1808 mnParagraphIndex(nParagraphIndex) 1809 { 1810 } 1811 1812 1813 1814 1815 PresenterAccessible::AccessibleParagraph::~AccessibleParagraph (void) 1816 { 1817 } 1818 1819 1820 1821 1822 //----- XAccessibleContext ---------------------------------------------------- 1823 1824 Reference<XAccessibleRelationSet> SAL_CALL 1825 PresenterAccessible::AccessibleParagraph::getAccessibleRelationSet (void) 1826 throw (RuntimeException) 1827 { 1828 ThrowIfDisposed(); 1829 1830 rtl::Reference<AccessibleRelationSet> pSet (new AccessibleRelationSet); 1831 1832 if (mxParentAccessible.is()) 1833 { 1834 Reference<XAccessibleContext> xParentContext (mxParentAccessible->getAccessibleContext()); 1835 if (xParentContext.is()) 1836 { 1837 if (mnParagraphIndex>0) 1838 pSet->AddRelation( 1839 AccessibleRelationType::CONTENT_FLOWS_FROM, 1840 xParentContext->getAccessibleChild(mnParagraphIndex-1)); 1841 1842 if (mnParagraphIndex<xParentContext->getAccessibleChildCount()-1) 1843 pSet->AddRelation( 1844 AccessibleRelationType::CONTENT_FLOWS_TO, 1845 xParentContext->getAccessibleChild(mnParagraphIndex+1)); 1846 } 1847 } 1848 1849 return Reference<XAccessibleRelationSet>(pSet.get()); 1850 } 1851 1852 1853 1854 1855 1856 1857 //----- XAccessibleText ------------------------------------------------------- 1858 1859 sal_Int32 SAL_CALL PresenterAccessible::AccessibleParagraph::getCaretPosition (void) 1860 throw (cssu::RuntimeException) 1861 { 1862 ThrowIfDisposed(); 1863 1864 sal_Int32 nPosition (-1); 1865 if (mpParagraph) 1866 nPosition = mpParagraph->GetCaretPosition(); 1867 1868 return nPosition; 1869 } 1870 1871 1872 1873 1874 sal_Bool SAL_CALL PresenterAccessible::AccessibleParagraph::setCaretPosition (sal_Int32 nIndex) 1875 throw (::com::sun::star::lang::IndexOutOfBoundsException, cssu::RuntimeException) 1876 { 1877 ThrowIfDisposed(); 1878 1879 if (mpParagraph) 1880 { 1881 mpParagraph->SetCaretPosition(nIndex); 1882 return sal_True; 1883 } 1884 else 1885 return sal_False; 1886 } 1887 1888 1889 1890 1891 sal_Unicode SAL_CALL PresenterAccessible::AccessibleParagraph::getCharacter (sal_Int32 nIndex) 1892 throw (::com::sun::star::lang::IndexOutOfBoundsException, cssu::RuntimeException) 1893 { 1894 ThrowIfDisposed(); 1895 1896 if (mpParagraph) 1897 return mpParagraph->GetCharacter(nIndex); 1898 else 1899 { 1900 ThrowException("no text support in current mode", ET_IndexOutOfBounds); 1901 // The method above throws an exception and the following line is 1902 // never reached. But there is at least one compiler that can not 1903 // detect this and we need the return to make it happy. 1904 return sal_Unicode(); 1905 } 1906 } 1907 1908 1909 1910 1911 Sequence<css::beans::PropertyValue> SAL_CALL 1912 PresenterAccessible::AccessibleParagraph::getCharacterAttributes ( 1913 ::sal_Int32 nIndex, 1914 const cssu::Sequence<rtl::OUString>& rRequestedAttributes) 1915 throw (css::lang::IndexOutOfBoundsException, cssu::RuntimeException) 1916 { 1917 ThrowIfDisposed(); 1918 1919 #ifdef VERBOSE 1920 OSL_TRACE("PresenterAccessible::AccessibleParagraph::getCharacterAttributes at %x,%d returns empty set\r", 1921 this,nIndex); 1922 for (sal_Int32 nAttributeIndex(0),nAttributeCount(rRequestedAttributes.getLength()); 1923 nAttributeIndex<nAttributeCount; 1924 ++nAttributeIndex) 1925 { 1926 OSL_TRACE(" requested attribute %d is %s\r", 1927 nAttributeIndex, 1928 OUStringToOString(rRequestedAttributes[nAttributeIndex], RTL_TEXTENCODING_UTF8).getStr()); 1929 } 1930 #endif 1931 1932 // Character properties are not supported. 1933 (void)nIndex; 1934 (void)rRequestedAttributes; 1935 return Sequence<css::beans::PropertyValue>(); 1936 } 1937 1938 1939 1940 1941 awt::Rectangle SAL_CALL PresenterAccessible::AccessibleParagraph::getCharacterBounds ( 1942 sal_Int32 nIndex) 1943 throw (css::lang::IndexOutOfBoundsException, cssu::RuntimeException) 1944 { 1945 ThrowIfDisposed(); 1946 1947 awt::Rectangle aCharacterBox; 1948 if (nIndex < 0) 1949 { 1950 ThrowException("invalid text index", ET_IndexOutOfBounds); 1951 } 1952 else if (mpParagraph) 1953 { 1954 aCharacterBox = mpParagraph->GetCharacterBounds(nIndex, false); 1955 // Convert coordinates relative to the window origin into absolute 1956 // screen coordinates. 1957 const awt::Point aWindowLocationOnScreen (getLocationOnScreen()); 1958 aCharacterBox.X += aWindowLocationOnScreen.X; 1959 aCharacterBox.Y += aWindowLocationOnScreen.Y; 1960 } 1961 else 1962 { 1963 ThrowException("no text support in current mode", ET_IndexOutOfBounds); 1964 } 1965 1966 return aCharacterBox; 1967 } 1968 1969 1970 1971 1972 sal_Int32 SAL_CALL PresenterAccessible::AccessibleParagraph::getCharacterCount (void) 1973 throw (cssu::RuntimeException) 1974 { 1975 ThrowIfDisposed(); 1976 1977 sal_Int32 nCount (0); 1978 if (mpParagraph) 1979 nCount = mpParagraph->GetCharacterCount(); 1980 1981 return nCount; 1982 } 1983 1984 1985 1986 1987 sal_Int32 SAL_CALL PresenterAccessible::AccessibleParagraph::getIndexAtPoint ( 1988 const css::awt::Point& rPoint) 1989 throw (cssu::RuntimeException) 1990 { 1991 ThrowIfDisposed(); 1992 1993 sal_Int32 nIndex (-1); 1994 if (mpParagraph) 1995 nIndex = mpParagraph->GetIndexAtPoint(rPoint); 1996 1997 return nIndex; 1998 } 1999 2000 2001 2002 2003 ::rtl::OUString SAL_CALL PresenterAccessible::AccessibleParagraph::getSelectedText (void) 2004 throw (cssu::RuntimeException) 2005 { 2006 ThrowIfDisposed(); 2007 2008 return getTextRange(getSelectionStart(), getSelectionEnd()); 2009 } 2010 2011 2012 2013 2014 sal_Int32 SAL_CALL PresenterAccessible::AccessibleParagraph::getSelectionStart (void) 2015 throw (cssu::RuntimeException) 2016 { 2017 ThrowIfDisposed(); 2018 2019 return getCaretPosition(); 2020 } 2021 2022 2023 2024 2025 sal_Int32 SAL_CALL PresenterAccessible::AccessibleParagraph::getSelectionEnd (void) 2026 throw (cssu::RuntimeException) 2027 { 2028 ThrowIfDisposed(); 2029 2030 return getCaretPosition(); 2031 } 2032 2033 2034 2035 2036 sal_Bool SAL_CALL PresenterAccessible::AccessibleParagraph::setSelection ( 2037 sal_Int32 nStartIndex, 2038 sal_Int32 nEndIndex) 2039 throw (css::lang::IndexOutOfBoundsException, cssu::RuntimeException) 2040 { 2041 (void)nEndIndex; 2042 ThrowIfDisposed(); 2043 2044 return setCaretPosition(nStartIndex); 2045 } 2046 2047 2048 2049 2050 ::rtl::OUString SAL_CALL PresenterAccessible::AccessibleParagraph::getText (void) 2051 throw (cssu::RuntimeException) 2052 { 2053 ThrowIfDisposed(); 2054 2055 ::rtl::OUString sText; 2056 if (mpParagraph) 2057 sText = mpParagraph->GetText(); 2058 2059 return sText; 2060 } 2061 2062 2063 2064 2065 ::rtl::OUString SAL_CALL PresenterAccessible::AccessibleParagraph::getTextRange ( 2066 sal_Int32 nLocalStartIndex, 2067 sal_Int32 nLocalEndIndex) 2068 throw (css::lang::IndexOutOfBoundsException, cssu::RuntimeException) 2069 { 2070 ThrowIfDisposed(); 2071 2072 ::rtl::OUString sText; 2073 if (mpParagraph) 2074 { 2075 const TextSegment aSegment ( 2076 mpParagraph->CreateTextSegment(nLocalStartIndex, nLocalEndIndex)); 2077 sText = aSegment.SegmentText; 2078 } 2079 2080 return sText; 2081 } 2082 2083 2084 2085 2086 TextSegment SAL_CALL PresenterAccessible::AccessibleParagraph::getTextAtIndex ( 2087 sal_Int32 nLocalCharacterIndex, 2088 sal_Int16 nTextType) 2089 throw (css::lang::IndexOutOfBoundsException, 2090 css::lang::IllegalArgumentException, 2091 cssu::RuntimeException) 2092 { 2093 ThrowIfDisposed(); 2094 2095 TextSegment aSegment; 2096 if (mpParagraph) 2097 aSegment = mpParagraph->GetTextSegment(0, nLocalCharacterIndex, nTextType); 2098 2099 return aSegment; 2100 } 2101 2102 2103 2104 2105 TextSegment SAL_CALL PresenterAccessible::AccessibleParagraph::getTextBeforeIndex ( 2106 sal_Int32 nLocalCharacterIndex, 2107 sal_Int16 nTextType) 2108 throw (css::lang::IndexOutOfBoundsException, 2109 css::lang::IllegalArgumentException, 2110 cssu::RuntimeException) 2111 { 2112 ThrowIfDisposed(); 2113 2114 TextSegment aSegment; 2115 if (mpParagraph) 2116 aSegment = mpParagraph->GetTextSegment(-1, nLocalCharacterIndex, nTextType); 2117 2118 return aSegment; 2119 } 2120 2121 2122 2123 2124 TextSegment SAL_CALL PresenterAccessible::AccessibleParagraph::getTextBehindIndex ( 2125 sal_Int32 nLocalCharacterIndex, 2126 sal_Int16 nTextType) 2127 throw (css::lang::IndexOutOfBoundsException, 2128 css::lang::IllegalArgumentException, 2129 cssu::RuntimeException) 2130 { 2131 ThrowIfDisposed(); 2132 2133 TextSegment aSegment; 2134 if (mpParagraph) 2135 aSegment = mpParagraph->GetTextSegment(+1, nLocalCharacterIndex, nTextType); 2136 2137 return aSegment; 2138 } 2139 2140 2141 2142 2143 sal_Bool SAL_CALL PresenterAccessible::AccessibleParagraph::copyText ( 2144 sal_Int32 nStartIndex, 2145 sal_Int32 nEndIndex) 2146 throw (css::lang::IndexOutOfBoundsException, cssu::RuntimeException) 2147 { 2148 ThrowIfDisposed(); 2149 2150 // Return false because copying to clipboard is not supported. 2151 // It IS supported in the notes view. There is no need to duplicate 2152 // this here. 2153 (void)nStartIndex; 2154 (void)nEndIndex; 2155 return sal_False; 2156 } 2157 2158 2159 2160 2161 //----- protected ------------------------------------------------------------- 2162 2163 awt::Point PresenterAccessible::AccessibleParagraph::GetRelativeLocation (void) 2164 { 2165 awt::Point aLocation (AccessibleObject::GetRelativeLocation()); 2166 if (mpParagraph) 2167 { 2168 const awt::Point aParagraphLocation (mpParagraph->GetRelativeLocation()); 2169 aLocation.X += aParagraphLocation.X; 2170 aLocation.Y += aParagraphLocation.Y; 2171 } 2172 2173 return aLocation; 2174 } 2175 2176 2177 2178 2179 awt::Size PresenterAccessible::AccessibleParagraph::GetSize (void) 2180 { 2181 if (mpParagraph) 2182 return mpParagraph->GetSize(); 2183 else 2184 return AccessibleObject::GetSize(); 2185 } 2186 2187 2188 2189 2190 awt::Point PresenterAccessible::AccessibleParagraph::GetAbsoluteParentLocation (void) 2191 { 2192 if (mxParentAccessible.is()) 2193 { 2194 Reference<XAccessibleContext> xParentContext( 2195 mxParentAccessible->getAccessibleContext(), UNO_QUERY); 2196 if (xParentContext.is()) 2197 { 2198 Reference<XAccessibleComponent> xGrandParentComponent( 2199 xParentContext->getAccessibleParent(), UNO_QUERY); 2200 if (xGrandParentComponent.is()) 2201 return xGrandParentComponent->getLocationOnScreen(); 2202 } 2203 } 2204 2205 return awt::Point(); 2206 } 2207 2208 2209 2210 2211 bool PresenterAccessible::AccessibleParagraph::GetWindowState (const sal_Int16 nType) const 2212 { 2213 switch (nType) 2214 { 2215 case AccessibleStateType::EDITABLE: 2216 return mpParagraph.get()!=NULL; 2217 2218 case AccessibleStateType::ACTIVE: 2219 return true; 2220 2221 default: 2222 return AccessibleObject::GetWindowState(nType); 2223 } 2224 } 2225 2226 2227 2228 2229 2230 2231 //===== AccessibleNotes ======================================================= 2232 2233 AccessibleNotes::AccessibleNotes ( 2234 const css::lang::Locale aLocale, 2235 const sal_Int16 nRole, 2236 const ::rtl::OUString& rsName) 2237 : AccessibleObject(aLocale,nRole,rsName), 2238 mpTextView() 2239 { 2240 } 2241 2242 2243 2244 2245 rtl::Reference<PresenterAccessible::AccessibleObject> AccessibleNotes::Create ( 2246 const css::uno::Reference<css::uno::XComponentContext>& rxContext, 2247 const lang::Locale aLocale, 2248 const Reference<awt::XWindow>& rxContentWindow, 2249 const Reference<awt::XWindow>& rxBorderWindow, 2250 const ::boost::shared_ptr<PresenterTextView>& rpTextView) 2251 { 2252 OUString sName (A2S("Presenter Notes Text")); 2253 { 2254 PresenterConfigurationAccess aConfiguration ( 2255 rxContext, 2256 OUString::createFromAscii("/org.openoffice.Office.extension.PresenterScreen/"), 2257 PresenterConfigurationAccess::READ_ONLY); 2258 aConfiguration.GetConfigurationNode(A2S("Presenter/Accessibility/Notes/String")) 2259 >>= sName; 2260 } 2261 2262 rtl::Reference<AccessibleNotes> pObject ( 2263 new AccessibleNotes( 2264 aLocale, 2265 AccessibleRole::PANEL, 2266 sName)); 2267 pObject->LateInitialization(); 2268 pObject->SetTextView(rpTextView); 2269 pObject->UpdateStateSet(); 2270 pObject->SetWindow(rxContentWindow, rxBorderWindow); 2271 2272 return rtl::Reference<PresenterAccessible::AccessibleObject>(pObject.get()); 2273 } 2274 2275 2276 2277 2278 void AccessibleNotes::SetTextView ( 2279 const ::boost::shared_ptr<PresenterTextView>& rpTextView) 2280 { 2281 ::std::vector<rtl::Reference<PresenterAccessible::AccessibleObject> > aChildren; 2282 2283 // Release any listeners to the current text view. 2284 if (mpTextView) 2285 { 2286 mpTextView->GetCaret()->SetCaretMotionBroadcaster( 2287 ::boost::function<void(sal_Int32,sal_Int32,sal_Int32,sal_Int32)>()); 2288 mpTextView->SetTextChangeBroadcaster( 2289 ::boost::function<void(void)>()); 2290 } 2291 2292 mpTextView = rpTextView; 2293 2294 if (mpTextView) 2295 { 2296 // Create a new set of children, one for each paragraph. 2297 const sal_Int32 nParagraphCount (mpTextView->GetParagraphCount()); 2298 for (sal_Int32 nIndex=0; nIndex<nParagraphCount; ++nIndex) 2299 { 2300 rtl::Reference<PresenterAccessible::AccessibleParagraph> pParagraph ( 2301 new PresenterAccessible::AccessibleParagraph( 2302 css::lang::Locale(), 2303 AccessibleRole::PARAGRAPH, 2304 A2S("Paragraph")+OUString::valueOf(nIndex), 2305 rpTextView->GetParagraph(nIndex), 2306 nIndex)); 2307 pParagraph->LateInitialization(); 2308 pParagraph->SetWindow( 2309 Reference<awt::XWindow>(mxContentWindow, UNO_QUERY), 2310 Reference<awt::XWindow>(mxBorderWindow, UNO_QUERY)); 2311 pParagraph->SetAccessibleParent(this); 2312 aChildren.push_back( 2313 rtl::Reference<PresenterAccessible::AccessibleObject>(pParagraph.get())); 2314 } 2315 maChildren.swap(aChildren); 2316 FireAccessibleEvent(AccessibleEventId::INVALIDATE_ALL_CHILDREN, Any(), Any()); 2317 2318 // Dispose the old children. (This will remove them from the focus 2319 // manager). 2320 for (std::vector<rtl::Reference<AccessibleObject> >::const_iterator 2321 iChild(aChildren.begin()), iEnd(aChildren.end()); 2322 iChild!=iEnd; 2323 ++iChild) 2324 { 2325 Reference<lang::XComponent> xComponent (static_cast<XWeak*>(iChild->get()), UNO_QUERY); 2326 if (xComponent.is()) 2327 xComponent->dispose(); 2328 } 2329 2330 // This class acts as a controller of who broadcasts caret motion 2331 // events and handles text changes. Register the corresponding 2332 // listeners here. 2333 mpTextView->GetCaret()->SetCaretMotionBroadcaster( 2334 ::boost::bind(&AccessibleNotes::NotifyCaretChange, this, _1, _2, _3, _4)); 2335 mpTextView->SetTextChangeBroadcaster( 2336 ::boost::bind(&AccessibleNotes::HandleTextChange, this)); 2337 } 2338 } 2339 2340 2341 2342 2343 void AccessibleNotes::SetWindow ( 2344 const cssu::Reference<css::awt::XWindow>& rxContentWindow, 2345 const cssu::Reference<css::awt::XWindow>& rxBorderWindow) 2346 { 2347 AccessibleObject::SetWindow(rxContentWindow, rxBorderWindow); 2348 2349 // Set the windows at the children as well, so that every paragraph can 2350 // setup its geometry. 2351 for (::std::vector<rtl::Reference<AccessibleObject> >::const_iterator 2352 iChild(maChildren.begin()), 2353 iEnd(maChildren.end()); 2354 iChild!=iEnd; 2355 ++iChild) 2356 { 2357 (*iChild)->SetWindow(rxContentWindow, rxBorderWindow); 2358 } 2359 } 2360 2361 2362 2363 2364 void AccessibleNotes::NotifyCaretChange ( 2365 const sal_Int32 nOldParagraphIndex, 2366 const sal_Int32 nOldCharacterIndex, 2367 const sal_Int32 nNewParagraphIndex, 2368 const sal_Int32 nNewCharacterIndex) 2369 { 2370 AccessibleFocusManager::Instance()->FocusObject( 2371 nNewParagraphIndex >= 0 2372 ? maChildren[nNewParagraphIndex] 2373 : this); 2374 2375 if (nOldParagraphIndex != nNewParagraphIndex) 2376 { 2377 // Moved caret from one paragraph to another (or showed or 2378 // hid the caret). Move focuse from one accessible 2379 // paragraph to another. 2380 if (nOldParagraphIndex >= 0) 2381 { 2382 maChildren[nOldParagraphIndex]->FireAccessibleEvent( 2383 AccessibleEventId::CARET_CHANGED, 2384 Any(nOldCharacterIndex), 2385 Any(sal_Int32(-1))); 2386 } 2387 if (nNewParagraphIndex >= 0) 2388 { 2389 maChildren[nNewParagraphIndex]->FireAccessibleEvent( 2390 AccessibleEventId::CARET_CHANGED, 2391 Any(sal_Int32(-1)), 2392 Any(nNewCharacterIndex)); 2393 } 2394 } 2395 else if (nNewParagraphIndex >= 0) 2396 { 2397 // Caret moved inside one paragraph. 2398 maChildren[nNewParagraphIndex]->FireAccessibleEvent( 2399 AccessibleEventId::CARET_CHANGED, 2400 Any(nOldCharacterIndex), 2401 Any(nNewCharacterIndex)); 2402 } 2403 } 2404 2405 2406 2407 2408 void AccessibleNotes::HandleTextChange (void) 2409 { 2410 SetTextView(mpTextView); 2411 } 2412 2413 2414 2415 2416 //===== AccessibleFocusManager ================================================ 2417 2418 ::boost::shared_ptr<AccessibleFocusManager> AccessibleFocusManager::mpInstance; 2419 2420 ::boost::shared_ptr<AccessibleFocusManager> AccessibleFocusManager::Instance (void) 2421 { 2422 if ( ! mpInstance) 2423 { 2424 mpInstance.reset(new AccessibleFocusManager()); 2425 } 2426 return mpInstance; 2427 } 2428 2429 2430 2431 2432 AccessibleFocusManager::AccessibleFocusManager (void) 2433 : maFocusableObjects() 2434 { 2435 } 2436 2437 2438 2439 2440 void AccessibleFocusManager::AddFocusableObject ( 2441 const ::rtl::Reference<PresenterAccessible::AccessibleObject>& rpObject) 2442 { 2443 OSL_ASSERT(rpObject.is()); 2444 OSL_ASSERT(::std::find(maFocusableObjects.begin(),maFocusableObjects.end(), rpObject)==maFocusableObjects.end()); 2445 2446 maFocusableObjects.push_back(rpObject); 2447 } 2448 2449 2450 2451 2452 void AccessibleFocusManager::RemoveFocusableObject ( 2453 const ::rtl::Reference<PresenterAccessible::AccessibleObject>& rpObject) 2454 { 2455 ::std::vector<rtl::Reference<PresenterAccessible::AccessibleObject> >::iterator iObject ( 2456 ::std::find(maFocusableObjects.begin(),maFocusableObjects.end(), rpObject)); 2457 2458 if (iObject != maFocusableObjects.end()) 2459 maFocusableObjects.erase(iObject); 2460 else 2461 { 2462 OSL_ASSERT(iObject!=maFocusableObjects.end()); 2463 } 2464 } 2465 2466 2467 2468 2469 void AccessibleFocusManager::FocusObject ( 2470 const ::rtl::Reference<PresenterAccessible::AccessibleObject>& rpObject) 2471 { 2472 // Remove the focus of any of the other focusable objects. 2473 for (::std::vector<rtl::Reference<PresenterAccessible::AccessibleObject> >::const_iterator 2474 iObject (maFocusableObjects.begin()), 2475 iEnd (maFocusableObjects.end()); 2476 iObject != iEnd; 2477 ++iObject) 2478 { 2479 if (*iObject!=rpObject) 2480 (*iObject)->SetIsFocused(false); 2481 } 2482 2483 if (rpObject.is()) 2484 rpObject->SetIsFocused(true); 2485 } 2486 2487 } } // end of namespace ::sd::presenter 2488