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