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:
Create(const css::uno::Reference<css::uno::XComponentContext> & rxContext,const lang::Locale aLocale)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.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:
Create(const Reference<css::uno::XComponentContext> & rxContext,const lang::Locale aLocale,const Reference<awt::XWindow> & rxContentWindow,const Reference<awt::XWindow> & rxBorderWindow)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.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 
PresenterAccessible(const css::uno::Reference<css::uno::XComponentContext> & rxContext,const::rtl::Reference<PresenterController> & rpPresenterController,const Reference<drawing::framework::XPane> & rxMainPane)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 
~PresenterAccessible(void)611 PresenterAccessible::~PresenterAccessible (void)
612 {
613 }
614 
615 
616 
617 
GetPreviewPane(void) const618 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 
UpdateAccessibilityHierarchy(void)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 
UpdateAccessibilityHierarchy(const Reference<awt::XWindow> & rxPreviewContentWindow,const Reference<awt::XWindow> & rxPreviewBorderWindow,const::rtl::OUString & rsTitle,const Reference<awt::XWindow> & rxNotesContentWindow,const Reference<awt::XWindow> & rxNotesBorderWindow,const::boost::shared_ptr<PresenterTextView> & rpNotesTextView)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 
NotifyCurrentSlideChange(const sal_Int32 nCurrentSlideIndex,const sal_Int32 nSlideCount)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 
IsAccessibilityActive(void) const782 bool PresenterAccessible::IsAccessibilityActive (void) const
783 {
784 	return mpAccessibleConsole.is();
785 }
786 
787 
788 
789 
disposing(void)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 
getAccessibleContext(void)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 
focusGained(const css::awt::FocusEvent & rEvent)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 
focusLost(const css::awt::FocusEvent & rEvent)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 
disposing(const css::lang::EventObject & rEvent)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 
initialize(const cssu::Sequence<cssu::Any> & rArguments)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 
AccessibleObject(const lang::Locale aLocale,const sal_Int16 nRole,const OUString & rsName)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 
LateInitialization(void)928 void PresenterAccessible::AccessibleObject::LateInitialization (void)
929 {
930 	AccessibleFocusManager::Instance()->AddFocusableObject(this);
931 }
932 
933 
934 
935 
~AccessibleObject(void)936 PresenterAccessible::AccessibleObject::~AccessibleObject (void)
937 {
938 }
939 
940 
941 
942 
SetWindow(const Reference<awt::XWindow> & rxContentWindow,const Reference<awt::XWindow> & rxBorderWindow)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 
SetAccessibleParent(const Reference<XAccessible> & rxAccessibleParent)971 void PresenterAccessible::AccessibleObject::SetAccessibleParent (
972 	const Reference<XAccessible>& rxAccessibleParent)
973 {
974 	mxParentAccessible = rxAccessibleParent;
975 }
976 
977 
978 
979 
disposing(void)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
getAccessibleContext(void)992 	PresenterAccessible::AccessibleObject::getAccessibleContext (void)
993 	throw (RuntimeException)
994 {
995 	ThrowIfDisposed();
996 
997 	return this;
998 }
999 
1000 
1001 
1002 
1003 //----- XAccessibleContext ------------------------------------------------
1004 
getAccessibleChildCount(void)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
getAccessibleChild(sal_Int32 nIndex)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
getAccessibleParent(void)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
getAccessibleIndexInParent(void)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
getAccessibleRole(void)1071 	PresenterAccessible::AccessibleObject::getAccessibleRole (void)
1072 	throw (RuntimeException)
1073 {
1074 	ThrowIfDisposed();
1075 
1076 	return mnRole;
1077 }
1078 
1079 
1080 
1081 
1082 OUString SAL_CALL
getAccessibleDescription(void)1083 	PresenterAccessible::AccessibleObject::getAccessibleDescription (void)
1084 	throw (RuntimeException)
1085 {
1086 	ThrowIfDisposed();
1087 
1088 	return msName;
1089 }
1090 
1091 
1092 
1093 
1094 OUString SAL_CALL
getAccessibleName(void)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
getAccessibleRelationSet(void)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
getAccessibleStateSet(void)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
getLocale(void)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 
containsPoint(const awt::Point & rPoint)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
getAccessibleAtPoint(const awt::Point & rPoint)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 
getBounds(void)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 
getLocation(void)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 
getLocationOnScreen(void)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 
getSize(void)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 
grabFocus(void)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 
getForeground(void)1256 sal_Int32 SAL_CALL PresenterAccessible::AccessibleObject::getForeground (void)
1257 	throw (RuntimeException)
1258 {
1259 	ThrowIfDisposed();
1260 
1261 	return 0x00ffffff;
1262 }
1263 
1264 
1265 
1266 
getBackground(void)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 
addEventListener(const Reference<XAccessibleEventListener> & rxListener)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 
removeEventListener(const Reference<XAccessibleEventListener> & rxListener)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 
windowResized(const css::awt::WindowEvent & rEvent)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 
windowMoved(const css::awt::WindowEvent & rEvent)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 
windowShown(const css::lang::EventObject & rEvent)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 
windowHidden(const css::lang::EventObject & rEvent)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 
disposing(const css::lang::EventObject & rEvent)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 
GetWindowState(const sal_Int16 nType) const1388 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 
UpdateStateSet(void)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 
UpdateState(const sal_Int16 nState,const bool bValue)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 
AddChild(const::rtl::Reference<AccessibleObject> & rpChild)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 
RemoveChild(const::rtl::Reference<AccessibleObject> & rpChild)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 
SetIsFocused(const bool bIsFocused)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 
SetAccessibleName(const::rtl::OUString & rsName)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 
FireAccessibleEvent(const sal_Int16 nEventId,const uno::Any & rOldValue,const uno::Any & rNewValue)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 
GetRelativeLocation(void)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 
GetSize(void)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 
GetAbsoluteParentLocation(void)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 
IsDisposed(void) const1588 sal_Bool PresenterAccessible::AccessibleObject::IsDisposed (void) const
1589 {
1590 	return (rBHelper.bDisposed || rBHelper.bInDispose);
1591 }
1592 
1593 
1594 
1595 
ThrowIfDisposed(void) const1596 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 
ThrowException(const sal_Char * pMessage,const ExceptionType eExceptionType) const1606 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 
AccessibleStateSet(const sal_Int32 nStateSet)1631 AccessibleStateSet::AccessibleStateSet (const sal_Int32 nStateSet)
1632 	: AccessibleStateSetInterfaceBase(m_aMutex),
1633 	  mnStateSet (nStateSet)
1634 {
1635 }
1636 
1637 
1638 
1639 
~AccessibleStateSet(void)1640 AccessibleStateSet::~AccessibleStateSet (void)
1641 {
1642 }
1643 
1644 
1645 
1646 
GetStateMask(const sal_Int16 nState)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 
isEmpty(void)1662 sal_Bool SAL_CALL AccessibleStateSet::isEmpty (void)
1663 	throw (cssu::RuntimeException)
1664 {
1665 	return mnStateSet==0;
1666 }
1667 
1668 
1669 
1670 
contains(sal_Int16 nState)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 
containsAll(const cssu::Sequence<sal_Int16> & rStateSet)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 
getStates(void)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 
AccessibleRelationSet(void)1710 AccessibleRelationSet::AccessibleRelationSet (void)
1711 	: AccessibleRelationSetInterfaceBase(m_aMutex),
1712 	  maRelations()
1713 {
1714 }
1715 
1716 
1717 
1718 
~AccessibleRelationSet(void)1719 AccessibleRelationSet::~AccessibleRelationSet (void)
1720 {
1721 }
1722 
1723 
1724 
1725 
AddRelation(const sal_Int16 nRelationType,const Reference<XInterface> & rxObject)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 
getRelationCount(void)1741 sal_Int32 SAL_CALL AccessibleRelationSet::getRelationCount (void)
1742 	throw (cssu::RuntimeException)
1743 {
1744 	return maRelations.size();
1745 }
1746 
1747 
1748 
1749 
getRelation(sal_Int32 nIndex)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 
containsRelation(sal_Int16 nRelationType)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 
getRelationByType(sal_Int16 nRelationType)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 
AccessibleParagraph(const lang::Locale aLocale,const sal_Int16 nRole,const OUString & rsName,const SharedPresenterTextParagraph & rpParagraph,const sal_Int32 nParagraphIndex)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 
~AccessibleParagraph(void)1811 PresenterAccessible::AccessibleParagraph::~AccessibleParagraph (void)
1812 {
1813 }
1814 
1815 
1816 
1817 
1818 //----- XAccessibleContext ----------------------------------------------------
1819 
1820 Reference<XAccessibleRelationSet> SAL_CALL
getAccessibleRelationSet(void)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 
getCaretPosition(void)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 
setCaretPosition(sal_Int32 nIndex)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 
getCharacter(sal_Int32 nIndex)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
getCharacterAttributes(::sal_Int32 nIndex,const cssu::Sequence<rtl::OUString> & rRequestedAttributes)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 
getCharacterBounds(sal_Int32 nIndex)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 
getCharacterCount(void)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 
getIndexAtPoint(const css::awt::Point & rPoint)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 
getSelectedText(void)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 
getSelectionStart(void)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 
getSelectionEnd(void)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 
setSelection(sal_Int32 nStartIndex,sal_Int32 nEndIndex)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 
getText(void)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 
getTextRange(sal_Int32 nLocalStartIndex,sal_Int32 nLocalEndIndex)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 
getTextAtIndex(sal_Int32 nLocalCharacterIndex,sal_Int16 nTextType)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 
getTextBeforeIndex(sal_Int32 nLocalCharacterIndex,sal_Int16 nTextType)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 
getTextBehindIndex(sal_Int32 nLocalCharacterIndex,sal_Int16 nTextType)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 
copyText(sal_Int32 nStartIndex,sal_Int32 nEndIndex)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 
GetRelativeLocation(void)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 
GetSize(void)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 
GetAbsoluteParentLocation(void)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 
GetWindowState(const sal_Int16 nType) const2207 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 
AccessibleNotes(const css::lang::Locale aLocale,const sal_Int16 nRole,const::rtl::OUString & rsName)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 
Create(const css::uno::Reference<css::uno::XComponentContext> & rxContext,const lang::Locale aLocale,const Reference<awt::XWindow> & rxContentWindow,const Reference<awt::XWindow> & rxBorderWindow,const::boost::shared_ptr<PresenterTextView> & rpTextView)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.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 
SetTextView(const::boost::shared_ptr<PresenterTextView> & rpTextView)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 
SetWindow(const cssu::Reference<css::awt::XWindow> & rxContentWindow,const cssu::Reference<css::awt::XWindow> & rxBorderWindow)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 
NotifyCaretChange(const sal_Int32 nOldParagraphIndex,const sal_Int32 nOldCharacterIndex,const sal_Int32 nNewParagraphIndex,const sal_Int32 nNewCharacterIndex)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 focus 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 
HandleTextChange(void)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 
Instance(void)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 
AccessibleFocusManager(void)2428 AccessibleFocusManager::AccessibleFocusManager (void)
2429 	: maFocusableObjects()
2430 {
2431 }
2432 
2433 
2434 
2435 
AddFocusableObject(const::rtl::Reference<PresenterAccessible::AccessibleObject> & rpObject)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 
RemoveFocusableObject(const::rtl::Reference<PresenterAccessible::AccessibleObject> & rpObject)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 
FocusObject(const::rtl::Reference<PresenterAccessible::AccessibleObject> & rpObject)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