xref: /AOO41X/main/sd/source/ui/accessibility/AccessibleSlideSorterObject.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sd.hxx"
30 
31 #include "AccessibleSlideSorterObject.hxx"
32 
33 #include "SlideSorter.hxx"
34 #include "controller/SlideSorterController.hxx"
35 #include "controller/SlsPageSelector.hxx"
36 #include "controller/SlsFocusManager.hxx"
37 #include "model/SlideSorterModel.hxx"
38 #include "model/SlsPageDescriptor.hxx"
39 #include "view/SlideSorterView.hxx"
40 #include "view/SlsLayouter.hxx"
41 #include "view/SlsPageObjectLayouter.hxx"
42 #include <com/sun/star/accessibility/AccessibleRole.hpp>
43 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
44 #include <comphelper/accessibleeventnotifier.hxx>
45 #include <unotools/accessiblestatesethelper.hxx>
46 
47 #include "sdpage.hxx"
48 #include "sdresid.hxx"
49 #include <vcl/svapp.hxx>
50 
51 #include "glob.hrc"
52 
53 using ::rtl::OUString;
54 using namespace ::com::sun::star;
55 using namespace ::com::sun::star::uno;
56 using namespace ::com::sun::star::accessibility;
57 
58 
59 namespace accessibility {
60 
61 
62 AccessibleSlideSorterObject::AccessibleSlideSorterObject(
63     const Reference<XAccessible>& rxParent,
64     ::sd::slidesorter::SlideSorter& rSlideSorter,
65     sal_uInt16 nPageNumber)
66     : AccessibleSlideSorterObjectBase(::sd::MutexOwner::maMutex),
67       mxParent(rxParent),
68       mnPageNumber(nPageNumber),
69       mrSlideSorter(rSlideSorter),
70       mnClientId(0)
71 {
72 }
73 
74 
75 
76 
77 AccessibleSlideSorterObject::~AccessibleSlideSorterObject (void)
78 {
79     if ( ! IsDisposed())
80         dispose();
81 }
82 
83 
84 
85 
86 sal_uInt16 AccessibleSlideSorterObject::GetPageNumber (void) const
87 {
88     return mnPageNumber;
89 }
90 
91 
92 
93 
94 void AccessibleSlideSorterObject::FireAccessibleEvent (
95     short nEventId,
96     const uno::Any& rOldValue,
97     const uno::Any& rNewValue)
98 {
99     if (mnClientId != 0)
100     {
101         AccessibleEventObject aEventObject;
102 
103         aEventObject.Source = Reference<XWeak>(this);
104         aEventObject.EventId = nEventId;
105         aEventObject.NewValue = rNewValue;
106         aEventObject.OldValue = rOldValue;
107 
108 		comphelper::AccessibleEventNotifier::addEvent(mnClientId, aEventObject);
109     }
110 }
111 
112 
113 
114 
115 void SAL_CALL AccessibleSlideSorterObject::disposing (void)
116 {
117     const vos::OGuard aSolarGuard (Application::GetSolarMutex());
118 
119     // Send a disposing to all listeners.
120 	if (mnClientId != 0)
121 	{
122         comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing(mnClientId, *this);
123 		mnClientId =  0;
124 	}
125 }
126 
127 
128 
129 //===== XAccessible ===========================================================
130 
131 Reference<XAccessibleContext> SAL_CALL
132     AccessibleSlideSorterObject::getAccessibleContext (void)
133     throw (uno::RuntimeException)
134 {
135     ThrowIfDisposed();
136     return this;
137 }
138 
139 
140 
141 //===== XAccessibleContext ====================================================
142 
143 sal_Int32 SAL_CALL AccessibleSlideSorterObject::getAccessibleChildCount (void)
144     throw (uno::RuntimeException)
145 {
146     ThrowIfDisposed();
147     return 0;
148 }
149 
150 
151 
152 
153 Reference<XAccessible> SAL_CALL AccessibleSlideSorterObject::getAccessibleChild (sal_Int32 )
154     throw (lang::IndexOutOfBoundsException, RuntimeException)
155 {
156     ThrowIfDisposed();
157     throw lang::IndexOutOfBoundsException();
158 }
159 
160 
161 
162 
163 Reference<XAccessible> SAL_CALL AccessibleSlideSorterObject::getAccessibleParent (void)
164     throw (uno::RuntimeException)
165 {
166     ThrowIfDisposed();
167     return mxParent;
168 }
169 
170 
171 
172 
173 sal_Int32 SAL_CALL AccessibleSlideSorterObject::getAccessibleIndexInParent()
174     throw (uno::RuntimeException)
175 {
176     ThrowIfDisposed();
177     const vos::OGuard aSolarGuard (Application::GetSolarMutex());
178     sal_Int32 nIndexInParent(-1);
179 
180     if (mxParent.is())
181     {
182         Reference<XAccessibleContext> xParentContext (mxParent->getAccessibleContext());
183         if (xParentContext.is())
184         {
185             sal_Int32 nChildCount (xParentContext->getAccessibleChildCount());
186             for (sal_Int32 i=0; i<nChildCount; ++i)
187                 if (xParentContext->getAccessibleChild(i).get()
188                     == static_cast<XAccessible*>(this))
189                 {
190                     nIndexInParent = i;
191                     break;
192                 }
193         }
194     }
195 
196     return nIndexInParent;
197 }
198 
199 
200 
201 
202 sal_Int16 SAL_CALL AccessibleSlideSorterObject::getAccessibleRole (void)
203     throw (uno::RuntimeException)
204 {
205     ThrowIfDisposed();
206     static sal_Int16 nRole = AccessibleRole::LIST_ITEM;
207     return nRole;
208 }
209 
210 
211 
212 
213 ::rtl::OUString SAL_CALL AccessibleSlideSorterObject::getAccessibleDescription (void)
214     throw (uno::RuntimeException)
215 {
216     ThrowIfDisposed();
217     return String(SdResId(STR_PAGE));
218 }
219 
220 
221 
222 
223 ::rtl::OUString SAL_CALL AccessibleSlideSorterObject::getAccessibleName (void)
224     throw (uno::RuntimeException)
225 {
226     ThrowIfDisposed();
227     const vos::OGuard aSolarGuard (Application::GetSolarMutex());
228 
229     SdPage* pPage = GetPage();
230     if (pPage != NULL)
231         return pPage->GetName();
232     else
233         return String();
234 }
235 
236 
237 
238 
239 Reference<XAccessibleRelationSet> SAL_CALL
240     AccessibleSlideSorterObject::getAccessibleRelationSet (void)
241     throw (uno::RuntimeException)
242 {
243     ThrowIfDisposed();
244     return Reference<XAccessibleRelationSet>();
245 }
246 
247 
248 
249 
250 Reference<XAccessibleStateSet> SAL_CALL
251     AccessibleSlideSorterObject::getAccessibleStateSet (void)
252     throw (uno::RuntimeException)
253 {
254     ThrowIfDisposed();
255     const vos::OGuard aSolarGuard (Application::GetSolarMutex());
256     ::utl::AccessibleStateSetHelper* pStateSet = new ::utl::AccessibleStateSetHelper();
257 
258     if (mxParent.is())
259     {
260 	    // Unconditional states.
261 	    pStateSet->AddState(AccessibleStateType::SELECTABLE);
262 	    pStateSet->AddState(AccessibleStateType::FOCUSABLE);
263 	    pStateSet->AddState(AccessibleStateType::ENABLED);
264 	    pStateSet->AddState(AccessibleStateType::VISIBLE);
265 	    pStateSet->AddState(AccessibleStateType::SHOWING);
266 	    pStateSet->AddState(AccessibleStateType::ACTIVE);
267 	    pStateSet->AddState(AccessibleStateType::SENSITIVE);
268 
269 	    // Conditional states.
270         if (mrSlideSorter.GetController().GetPageSelector().IsPageSelected(mnPageNumber))
271             pStateSet->AddState(AccessibleStateType::SELECTED);
272         if (mrSlideSorter.GetController().GetFocusManager().GetFocusedPageIndex() == mnPageNumber)
273             if (mrSlideSorter.GetController().GetFocusManager().IsFocusShowing())
274                 pStateSet->AddState(AccessibleStateType::FOCUSED);
275     }
276 
277     return pStateSet;
278 }
279 
280 
281 
282 
283 lang::Locale SAL_CALL AccessibleSlideSorterObject::getLocale (void)
284     throw (IllegalAccessibleComponentStateException,
285         RuntimeException)
286 {
287     ThrowIfDisposed();
288     // Delegate request to parent.
289 	if (mxParent.is())
290     {
291     	Reference<XAccessibleContext> xParentContext (mxParent->getAccessibleContext());
292         if (xParentContext.is())
293 	    	return xParentContext->getLocale ();
294     }
295 
296     //	No locale and no parent.  Therefore throw exception to indicate this
297     //	cluelessness.
298     throw IllegalAccessibleComponentStateException();
299 }
300 
301 
302 
303 
304 
305 //===== XAccessibleEventBroadcaster ===========================================
306 
307 void SAL_CALL AccessibleSlideSorterObject::addEventListener(
308     const Reference<XAccessibleEventListener>& rxListener)
309     throw (RuntimeException)
310 {
311 	if (rxListener.is())
312     {
313         const osl::MutexGuard aGuard(maMutex);
314 
315         if (IsDisposed())
316         {
317             uno::Reference<uno::XInterface> x ((lang::XComponent *)this, uno::UNO_QUERY);
318 		    rxListener->disposing (lang::EventObject (x));
319 	    }
320         else
321         {
322             if (mnClientId == 0)
323                 mnClientId = comphelper::AccessibleEventNotifier::registerClient();
324             comphelper::AccessibleEventNotifier::addEventListener(mnClientId, rxListener);
325         }
326     }
327 }
328 
329 
330 
331 
332 void SAL_CALL AccessibleSlideSorterObject::removeEventListener(
333     const Reference<XAccessibleEventListener>& rxListener)
334     throw (uno::RuntimeException)
335 {
336     ThrowIfDisposed();
337 	if (rxListener.is())
338 	{
339         const osl::MutexGuard aGuard(maMutex);
340 
341         sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( mnClientId, rxListener );
342 		if ( !nListenerCount )
343 		{
344 			// no listeners anymore
345 			// -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
346 			// and at least to us not firing any events anymore, in case somebody calls
347 			// NotifyAccessibleEvent, again
348 			comphelper::AccessibleEventNotifier::revokeClient( mnClientId );
349 			mnClientId = 0;
350 		}
351 	}
352 }
353 
354 
355 
356 
357 //===== XAccessibleComponent ==================================================
358 
359 sal_Bool SAL_CALL AccessibleSlideSorterObject::containsPoint(const awt::Point& aPoint)
360     throw (uno::RuntimeException)
361 {
362     ThrowIfDisposed();
363     const awt::Size aSize (getSize());
364     return (aPoint.X >= 0)
365         && (aPoint.X < aSize.Width)
366         && (aPoint.Y >= 0)
367         && (aPoint.Y < aSize.Height);
368 }
369 
370 
371 
372 
373 Reference<XAccessible> SAL_CALL
374     AccessibleSlideSorterObject::getAccessibleAtPoint(const awt::Point& )
375     throw (uno::RuntimeException)
376 {
377     return NULL;
378 }
379 
380 
381 
382 
383 awt::Rectangle SAL_CALL AccessibleSlideSorterObject::getBounds (void)
384     throw (RuntimeException)
385 {
386     ThrowIfDisposed ();
387 
388     const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
389 
390     Rectangle aBBox (
391         mrSlideSorter.GetView().GetLayouter().GetPageObjectLayouter()->GetBoundingBox(
392             mrSlideSorter.GetModel().GetPageDescriptor(mnPageNumber),
393             ::sd::slidesorter::view::PageObjectLayouter::PageObject,
394             ::sd::slidesorter::view::PageObjectLayouter::WindowCoordinateSystem));
395 
396     if (mxParent.is())
397     {
398         Reference<XAccessibleComponent> xParentComponent(mxParent->getAccessibleContext(), UNO_QUERY);
399         if (xParentComponent.is())
400         {
401             awt::Rectangle aParentBBox (xParentComponent->getBounds());
402             aBBox.Intersection(Rectangle(
403                 aParentBBox.X,
404                 aParentBBox.Y,
405                 aParentBBox.Width,
406                 aParentBBox.Height));
407         }
408     }
409 
410     return awt::Rectangle(
411         aBBox.Left(),
412         aBBox.Top(),
413         aBBox.GetWidth(),
414         aBBox.GetHeight());
415 }
416 
417 
418 
419 
420 awt::Point SAL_CALL AccessibleSlideSorterObject::getLocation ()
421     throw (RuntimeException)
422 {
423     ThrowIfDisposed ();
424     const awt::Rectangle aBBox (getBounds());
425     return awt::Point(aBBox.X, aBBox.Y);
426 }
427 
428 
429 
430 
431 awt::Point SAL_CALL AccessibleSlideSorterObject::getLocationOnScreen (void)
432     throw (RuntimeException)
433 {
434     ThrowIfDisposed ();
435 
436     const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
437 
438     awt::Point aLocation (getLocation());
439 
440     if (mxParent.is())
441     {
442         Reference<XAccessibleComponent> xParentComponent(mxParent->getAccessibleContext(),UNO_QUERY);
443         if (xParentComponent.is())
444         {
445             const awt::Point aParentLocationOnScreen(xParentComponent->getLocationOnScreen());
446             aLocation.X += aParentLocationOnScreen.X;
447             aLocation.Y += aParentLocationOnScreen.Y;
448         }
449     }
450 
451     return aLocation;
452 }
453 
454 
455 
456 
457 awt::Size SAL_CALL AccessibleSlideSorterObject::getSize (void)
458     throw (RuntimeException)
459 {
460     ThrowIfDisposed ();
461     const awt::Rectangle aBBox (getBounds());
462     return awt::Size(aBBox.Width,aBBox.Height);
463 }
464 
465 
466 
467 
468 void SAL_CALL AccessibleSlideSorterObject::grabFocus (void)
469     throw (RuntimeException)
470 {
471     // nothing to do
472 }
473 
474 
475 
476 
477 sal_Int32 SAL_CALL AccessibleSlideSorterObject::getForeground (void)
478     throw (::com::sun::star::uno::RuntimeException)
479 {
480     ThrowIfDisposed ();
481 	svtools::ColorConfig aColorConfig;
482     sal_uInt32 nColor = aColorConfig.GetColorValue( svtools::FONTCOLOR ).nColor;
483     return static_cast<sal_Int32>(nColor);
484 }
485 
486 
487 
488 
489 sal_Int32 SAL_CALL AccessibleSlideSorterObject::getBackground (void)
490     throw (::com::sun::star::uno::RuntimeException)
491 {
492     ThrowIfDisposed ();
493     sal_uInt32 nColor = Application::GetSettings().GetStyleSettings().GetWindowColor().GetColor();
494     return static_cast<sal_Int32>(nColor);
495 }
496 
497 
498 
499 
500 
501 //=====  XServiceInfo  ========================================================
502 
503 ::rtl::OUString SAL_CALL
504    	AccessibleSlideSorterObject::getImplementationName (void)
505     throw (::com::sun::star::uno::RuntimeException)
506 {
507 	return OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleSlideSorterObject"));
508 }
509 
510 
511 
512 
513 sal_Bool SAL_CALL
514  	AccessibleSlideSorterObject::supportsService (const OUString& sServiceName)
515     throw (::com::sun::star::uno::RuntimeException)
516 {
517     ThrowIfDisposed ();
518 
519     //  Iterate over all supported service names and return true if on of them
520     //  matches the given name.
521     uno::Sequence< ::rtl::OUString> aSupportedServices (
522         getSupportedServiceNames ());
523     for (int i=0; i<aSupportedServices.getLength(); i++)
524         if (sServiceName == aSupportedServices[i])
525             return sal_True;
526     return sal_False;
527 }
528 
529 
530 
531 
532 uno::Sequence< ::rtl::OUString> SAL_CALL
533    	AccessibleSlideSorterObject::getSupportedServiceNames (void)
534     throw (::com::sun::star::uno::RuntimeException)
535 {
536     ThrowIfDisposed ();
537 
538 	static const OUString sServiceNames[2] = {
539         OUString(RTL_CONSTASCII_USTRINGPARAM(
540             "com.sun.star.accessibility.Accessible")),
541         OUString(RTL_CONSTASCII_USTRINGPARAM(
542             "com.sun.star.accessibility.AccessibleContext"))
543     };
544 	return uno::Sequence<OUString> (sServiceNames, 2);
545 }
546 
547 
548 
549 
550 void AccessibleSlideSorterObject::ThrowIfDisposed (void)
551     throw (lang::DisposedException)
552 {
553 	if (rBHelper.bDisposed || rBHelper.bInDispose)
554 	{
555         OSL_TRACE ("Calling disposed object. Throwing exception:");
556         throw lang::DisposedException (
557             OUString(RTL_CONSTASCII_USTRINGPARAM("object has been already disposed")),
558             static_cast<uno::XWeak*>(this));
559     }
560 }
561 
562 
563 
564 sal_Bool AccessibleSlideSorterObject::IsDisposed (void)
565 {
566 	return (rBHelper.bDisposed || rBHelper.bInDispose);
567 }
568 
569 
570 
571 
572 SdPage* AccessibleSlideSorterObject::GetPage (void) const
573 {
574     ::sd::slidesorter::model::SharedPageDescriptor pDescriptor(
575         mrSlideSorter.GetModel().GetPageDescriptor(mnPageNumber));
576     if (pDescriptor.get() != NULL)
577         return pDescriptor->GetPage();
578     else
579         return NULL;
580 }
581 
582 
583 } // end of namespace ::accessibility
584