Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "AccessibleSlideSorterObject.hxx"
21 :
22 : #include "SlideSorter.hxx"
23 : #include "controller/SlideSorterController.hxx"
24 : #include "controller/SlsPageSelector.hxx"
25 : #include "controller/SlsFocusManager.hxx"
26 : #include "model/SlideSorterModel.hxx"
27 : #include "model/SlsPageDescriptor.hxx"
28 : #include "view/SlideSorterView.hxx"
29 : #include "view/SlsLayouter.hxx"
30 : #include "view/SlsPageObjectLayouter.hxx"
31 : #include <com/sun/star/accessibility/AccessibleRole.hpp>
32 : #include <com/sun/star/accessibility/AccessibleStateType.hpp>
33 : #include <comphelper/accessibleeventnotifier.hxx>
34 : #include <cppuhelper/supportsservice.hxx>
35 : #include <unotools/accessiblestatesethelper.hxx>
36 :
37 : #include "sdpage.hxx"
38 : #include "sdresid.hxx"
39 : #include <vcl/svapp.hxx>
40 : #include <vcl/settings.hxx>
41 :
42 : #include "glob.hrc"
43 :
44 : using namespace ::com::sun::star;
45 : using namespace ::com::sun::star::uno;
46 : using namespace ::com::sun::star::accessibility;
47 :
48 : namespace accessibility {
49 :
50 0 : AccessibleSlideSorterObject::AccessibleSlideSorterObject(
51 : const Reference<XAccessible>& rxParent,
52 : ::sd::slidesorter::SlideSorter& rSlideSorter,
53 : sal_uInt16 nPageNumber)
54 : : AccessibleSlideSorterObjectBase(::sd::MutexOwner::maMutex),
55 : mxParent(rxParent),
56 : mnPageNumber(nPageNumber),
57 : mrSlideSorter(rSlideSorter),
58 0 : mnClientId(0)
59 : {
60 0 : }
61 :
62 0 : AccessibleSlideSorterObject::~AccessibleSlideSorterObject()
63 : {
64 0 : if ( ! IsDisposed())
65 0 : dispose();
66 0 : }
67 :
68 0 : void AccessibleSlideSorterObject::FireAccessibleEvent (
69 : short nEventId,
70 : const uno::Any& rOldValue,
71 : const uno::Any& rNewValue)
72 : {
73 0 : if (mnClientId != 0)
74 : {
75 0 : AccessibleEventObject aEventObject;
76 :
77 0 : aEventObject.Source = Reference<XWeak>(this);
78 0 : aEventObject.EventId = nEventId;
79 0 : aEventObject.NewValue = rNewValue;
80 0 : aEventObject.OldValue = rOldValue;
81 :
82 0 : comphelper::AccessibleEventNotifier::addEvent(mnClientId, aEventObject);
83 : }
84 0 : }
85 :
86 0 : void SAL_CALL AccessibleSlideSorterObject::disposing()
87 : {
88 0 : const SolarMutexGuard aSolarGuard;
89 :
90 : // Send a disposing to all listeners.
91 0 : if (mnClientId != 0)
92 : {
93 0 : comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing(mnClientId, *this);
94 0 : mnClientId = 0;
95 0 : }
96 0 : }
97 :
98 : //===== XAccessible ===========================================================
99 :
100 : Reference<XAccessibleContext> SAL_CALL
101 0 : AccessibleSlideSorterObject::getAccessibleContext()
102 : throw (uno::RuntimeException, std::exception)
103 : {
104 0 : ThrowIfDisposed();
105 0 : return this;
106 : }
107 :
108 : //===== XAccessibleContext ====================================================
109 :
110 0 : sal_Int32 SAL_CALL AccessibleSlideSorterObject::getAccessibleChildCount()
111 : throw (uno::RuntimeException, std::exception)
112 : {
113 0 : ThrowIfDisposed();
114 0 : return 0;
115 : }
116 :
117 0 : Reference<XAccessible> SAL_CALL AccessibleSlideSorterObject::getAccessibleChild (sal_Int32 )
118 : throw (lang::IndexOutOfBoundsException, RuntimeException, std::exception)
119 : {
120 0 : ThrowIfDisposed();
121 0 : throw lang::IndexOutOfBoundsException();
122 : }
123 :
124 0 : Reference<XAccessible> SAL_CALL AccessibleSlideSorterObject::getAccessibleParent()
125 : throw (uno::RuntimeException, std::exception)
126 : {
127 0 : ThrowIfDisposed();
128 0 : return mxParent;
129 : }
130 :
131 0 : sal_Int32 SAL_CALL AccessibleSlideSorterObject::getAccessibleIndexInParent()
132 : throw (uno::RuntimeException, std::exception)
133 : {
134 0 : ThrowIfDisposed();
135 0 : const SolarMutexGuard aSolarGuard;
136 0 : sal_Int32 nIndexInParent(-1);
137 :
138 0 : if (mxParent.is())
139 : {
140 0 : Reference<XAccessibleContext> xParentContext (mxParent->getAccessibleContext());
141 0 : if (xParentContext.is())
142 : {
143 0 : sal_Int32 nChildCount (xParentContext->getAccessibleChildCount());
144 0 : for (sal_Int32 i=0; i<nChildCount; ++i)
145 0 : if (xParentContext->getAccessibleChild(i).get()
146 0 : == static_cast<XAccessible*>(this))
147 : {
148 0 : nIndexInParent = i;
149 0 : break;
150 : }
151 0 : }
152 : }
153 :
154 0 : return nIndexInParent;
155 : }
156 :
157 0 : sal_Int16 SAL_CALL AccessibleSlideSorterObject::getAccessibleRole()
158 : throw (uno::RuntimeException, std::exception)
159 : {
160 0 : ThrowIfDisposed();
161 : //set Role = Shape
162 : //static sal_Int16 nRole = AccessibleRole::LIST_ITEM;
163 : static sal_Int16 nRole = AccessibleRole::SHAPE;
164 0 : return nRole;
165 : }
166 :
167 0 : OUString SAL_CALL AccessibleSlideSorterObject::getAccessibleDescription()
168 : throw (uno::RuntimeException, std::exception)
169 : {
170 0 : ThrowIfDisposed();
171 0 : return SD_RESSTR(STR_PAGE);
172 : }
173 :
174 0 : OUString SAL_CALL AccessibleSlideSorterObject::getAccessibleName()
175 : throw (uno::RuntimeException, std::exception)
176 : {
177 0 : ThrowIfDisposed();
178 0 : const SolarMutexGuard aSolarGuard;
179 :
180 0 : SdPage* pPage = GetPage();
181 0 : if (pPage != NULL)
182 0 : return pPage->GetName();
183 : else
184 0 : return OUString();
185 : }
186 :
187 : Reference<XAccessibleRelationSet> SAL_CALL
188 0 : AccessibleSlideSorterObject::getAccessibleRelationSet()
189 : throw (uno::RuntimeException, std::exception)
190 : {
191 0 : ThrowIfDisposed();
192 0 : return Reference<XAccessibleRelationSet>();
193 : }
194 :
195 : Reference<XAccessibleStateSet> SAL_CALL
196 0 : AccessibleSlideSorterObject::getAccessibleStateSet()
197 : throw (uno::RuntimeException, std::exception)
198 : {
199 0 : ThrowIfDisposed();
200 0 : const SolarMutexGuard aSolarGuard;
201 0 : ::utl::AccessibleStateSetHelper* pStateSet = new ::utl::AccessibleStateSetHelper();
202 :
203 0 : if (mxParent.is())
204 : {
205 : // Unconditional states.
206 0 : pStateSet->AddState(AccessibleStateType::SELECTABLE);
207 0 : pStateSet->AddState(AccessibleStateType::FOCUSABLE);
208 0 : pStateSet->AddState(AccessibleStateType::ENABLED);
209 0 : pStateSet->AddState(AccessibleStateType::VISIBLE);
210 0 : pStateSet->AddState(AccessibleStateType::SHOWING);
211 0 : pStateSet->AddState(AccessibleStateType::ACTIVE);
212 0 : pStateSet->AddState(AccessibleStateType::SENSITIVE);
213 :
214 : // Conditional states.
215 0 : if (mrSlideSorter.GetController().GetPageSelector().IsPageSelected(mnPageNumber))
216 0 : pStateSet->AddState(AccessibleStateType::SELECTED);
217 0 : if (mrSlideSorter.GetController().GetFocusManager().GetFocusedPageIndex() == mnPageNumber)
218 0 : if (mrSlideSorter.GetController().GetFocusManager().IsFocusShowing())
219 0 : pStateSet->AddState(AccessibleStateType::FOCUSED);
220 : }
221 :
222 0 : return pStateSet;
223 : }
224 :
225 0 : lang::Locale SAL_CALL AccessibleSlideSorterObject::getLocale()
226 : throw (IllegalAccessibleComponentStateException,
227 : RuntimeException, std::exception)
228 : {
229 0 : ThrowIfDisposed();
230 : // Delegate request to parent.
231 0 : if (mxParent.is())
232 : {
233 0 : Reference<XAccessibleContext> xParentContext (mxParent->getAccessibleContext());
234 0 : if (xParentContext.is())
235 0 : return xParentContext->getLocale ();
236 : }
237 :
238 : // No locale and no parent. Therefore throw exception to indicate this
239 : // cluelessness.
240 0 : throw IllegalAccessibleComponentStateException();
241 : }
242 :
243 : //===== XAccessibleEventBroadcaster ===========================================
244 :
245 0 : void SAL_CALL AccessibleSlideSorterObject::addAccessibleEventListener(
246 : const Reference<XAccessibleEventListener>& rxListener)
247 : throw (RuntimeException, std::exception)
248 : {
249 0 : if (rxListener.is())
250 : {
251 0 : const osl::MutexGuard aGuard(maMutex);
252 :
253 0 : if (IsDisposed())
254 : {
255 0 : uno::Reference<uno::XInterface> x (static_cast<lang::XComponent *>(this), uno::UNO_QUERY);
256 0 : rxListener->disposing (lang::EventObject (x));
257 : }
258 : else
259 : {
260 0 : if (mnClientId == 0)
261 0 : mnClientId = comphelper::AccessibleEventNotifier::registerClient();
262 0 : comphelper::AccessibleEventNotifier::addEventListener(mnClientId, rxListener);
263 0 : }
264 : }
265 0 : }
266 :
267 0 : void SAL_CALL AccessibleSlideSorterObject::removeAccessibleEventListener(
268 : const Reference<XAccessibleEventListener>& rxListener)
269 : throw (uno::RuntimeException, std::exception)
270 : {
271 0 : ThrowIfDisposed();
272 0 : if (rxListener.is())
273 : {
274 0 : const osl::MutexGuard aGuard(maMutex);
275 :
276 0 : sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( mnClientId, rxListener );
277 0 : if ( !nListenerCount )
278 : {
279 : // no listeners anymore
280 : // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
281 : // and at least to us not firing any events anymore, in case somebody calls
282 : // NotifyAccessibleEvent, again
283 0 : comphelper::AccessibleEventNotifier::revokeClient( mnClientId );
284 0 : mnClientId = 0;
285 0 : }
286 : }
287 0 : }
288 :
289 : //===== XAccessibleComponent ==================================================
290 :
291 0 : sal_Bool SAL_CALL AccessibleSlideSorterObject::containsPoint(const awt::Point& aPoint)
292 : throw (uno::RuntimeException, std::exception)
293 : {
294 0 : ThrowIfDisposed();
295 0 : const awt::Size aSize (getSize());
296 0 : return (aPoint.X >= 0)
297 0 : && (aPoint.X < aSize.Width)
298 0 : && (aPoint.Y >= 0)
299 0 : && (aPoint.Y < aSize.Height);
300 : }
301 :
302 : Reference<XAccessible> SAL_CALL
303 0 : AccessibleSlideSorterObject::getAccessibleAtPoint(const awt::Point& )
304 : throw (uno::RuntimeException, std::exception)
305 : {
306 0 : return NULL;
307 : }
308 :
309 0 : awt::Rectangle SAL_CALL AccessibleSlideSorterObject::getBounds()
310 : throw (RuntimeException, std::exception)
311 : {
312 0 : ThrowIfDisposed ();
313 :
314 0 : const SolarMutexGuard aSolarGuard;
315 :
316 : Rectangle aBBox (
317 0 : mrSlideSorter.GetView().GetLayouter().GetPageObjectLayouter()->GetBoundingBox(
318 0 : mrSlideSorter.GetModel().GetPageDescriptor(mnPageNumber),
319 : ::sd::slidesorter::view::PageObjectLayouter::PageObject,
320 0 : ::sd::slidesorter::view::PageObjectLayouter::WindowCoordinateSystem));
321 :
322 0 : if (mxParent.is())
323 : {
324 0 : Reference<XAccessibleComponent> xParentComponent(mxParent->getAccessibleContext(), UNO_QUERY);
325 0 : if (xParentComponent.is())
326 : {
327 0 : awt::Rectangle aParentBBox (xParentComponent->getBounds());
328 : aBBox.Intersection(Rectangle(
329 : aParentBBox.X,
330 : aParentBBox.Y,
331 : aParentBBox.Width,
332 0 : aParentBBox.Height));
333 0 : }
334 : }
335 :
336 : return awt::Rectangle(
337 0 : aBBox.Left(),
338 0 : aBBox.Top(),
339 0 : aBBox.GetWidth(),
340 0 : aBBox.GetHeight());
341 : }
342 :
343 0 : awt::Point SAL_CALL AccessibleSlideSorterObject::getLocation ()
344 : throw (RuntimeException, std::exception)
345 : {
346 0 : ThrowIfDisposed ();
347 0 : const awt::Rectangle aBBox (getBounds());
348 0 : return awt::Point(aBBox.X, aBBox.Y);
349 : }
350 :
351 0 : awt::Point SAL_CALL AccessibleSlideSorterObject::getLocationOnScreen()
352 : throw (RuntimeException, std::exception)
353 : {
354 0 : ThrowIfDisposed ();
355 :
356 0 : const SolarMutexGuard aSolarGuard;
357 :
358 0 : awt::Point aLocation (getLocation());
359 :
360 0 : if (mxParent.is())
361 : {
362 0 : Reference<XAccessibleComponent> xParentComponent(mxParent->getAccessibleContext(),UNO_QUERY);
363 0 : if (xParentComponent.is())
364 : {
365 0 : const awt::Point aParentLocationOnScreen(xParentComponent->getLocationOnScreen());
366 0 : aLocation.X += aParentLocationOnScreen.X;
367 0 : aLocation.Y += aParentLocationOnScreen.Y;
368 0 : }
369 : }
370 :
371 0 : return aLocation;
372 : }
373 :
374 0 : awt::Size SAL_CALL AccessibleSlideSorterObject::getSize()
375 : throw (RuntimeException, std::exception)
376 : {
377 0 : ThrowIfDisposed ();
378 0 : const awt::Rectangle aBBox (getBounds());
379 0 : return awt::Size(aBBox.Width,aBBox.Height);
380 : }
381 :
382 0 : void SAL_CALL AccessibleSlideSorterObject::grabFocus()
383 : throw (RuntimeException, std::exception)
384 : {
385 : // nothing to do
386 0 : }
387 :
388 0 : sal_Int32 SAL_CALL AccessibleSlideSorterObject::getForeground()
389 : throw (::com::sun::star::uno::RuntimeException, std::exception)
390 : {
391 0 : ThrowIfDisposed ();
392 0 : svtools::ColorConfig aColorConfig;
393 0 : sal_uInt32 nColor = aColorConfig.GetColorValue( svtools::FONTCOLOR ).nColor;
394 0 : return static_cast<sal_Int32>(nColor);
395 : }
396 :
397 0 : sal_Int32 SAL_CALL AccessibleSlideSorterObject::getBackground()
398 : throw (::com::sun::star::uno::RuntimeException, std::exception)
399 : {
400 0 : ThrowIfDisposed ();
401 0 : sal_uInt32 nColor = Application::GetSettings().GetStyleSettings().GetWindowColor().GetColor();
402 0 : return static_cast<sal_Int32>(nColor);
403 : }
404 :
405 : // XServiceInfo
406 : OUString SAL_CALL
407 0 : AccessibleSlideSorterObject::getImplementationName()
408 : throw (::com::sun::star::uno::RuntimeException, std::exception)
409 : {
410 0 : return OUString("AccessibleSlideSorterObject");
411 : }
412 :
413 0 : sal_Bool SAL_CALL AccessibleSlideSorterObject::supportsService (const OUString& sServiceName)
414 : throw (::com::sun::star::uno::RuntimeException, std::exception)
415 : {
416 0 : return cppu::supportsService(this, sServiceName);
417 : }
418 :
419 : uno::Sequence< OUString> SAL_CALL
420 0 : AccessibleSlideSorterObject::getSupportedServiceNames()
421 : throw (::com::sun::star::uno::RuntimeException, std::exception)
422 : {
423 0 : ThrowIfDisposed ();
424 :
425 : static const OUString sServiceNames[2] = {
426 : OUString("com.sun.star.accessibility.Accessible"),
427 : OUString("com.sun.star.accessibility.AccessibleContext")
428 0 : };
429 0 : return uno::Sequence<OUString> (sServiceNames, 2);
430 : }
431 :
432 0 : void AccessibleSlideSorterObject::ThrowIfDisposed()
433 : throw (lang::DisposedException)
434 : {
435 0 : if (rBHelper.bDisposed || rBHelper.bInDispose)
436 : {
437 : OSL_TRACE ("Calling disposed object. Throwing exception:");
438 : throw lang::DisposedException ("object has been already disposed",
439 0 : static_cast<uno::XWeak*>(this));
440 : }
441 0 : }
442 :
443 0 : bool AccessibleSlideSorterObject::IsDisposed()
444 : {
445 0 : return (rBHelper.bDisposed || rBHelper.bInDispose);
446 : }
447 :
448 0 : SdPage* AccessibleSlideSorterObject::GetPage() const
449 : {
450 : ::sd::slidesorter::model::SharedPageDescriptor pDescriptor(
451 0 : mrSlideSorter.GetModel().GetPageDescriptor(mnPageNumber));
452 0 : if (pDescriptor.get() != NULL)
453 0 : return pDescriptor->GetPage();
454 : else
455 0 : return NULL;
456 : }
457 :
458 66 : } // end of namespace ::accessibility
459 :
460 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|