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