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 :
21 : #include "AccessibleSlideSorterView.hxx"
22 : #include "AccessibleSlideSorterObject.hxx"
23 :
24 : #include "SlideSorter.hxx"
25 : #include "controller/SlideSorterController.hxx"
26 : #include "controller/SlsPageSelector.hxx"
27 : #include "controller/SlsFocusManager.hxx"
28 : #include "controller/SlsSelectionManager.hxx"
29 : #include "view/SlideSorterView.hxx"
30 : #include "model/SlideSorterModel.hxx"
31 : #include "model/SlsPageDescriptor.hxx"
32 : #include "SlideSorterViewShell.hxx"
33 :
34 : #include "ViewShellHint.hxx"
35 : #include "sdpage.hxx"
36 : #include "drawdoc.hxx"
37 :
38 : #include "sdresid.hxx"
39 : #include "accessibility.hrc"
40 : #include <com/sun/star/accessibility/AccessibleRole.hpp>
41 : #include <com/sun/star/accessibility/AccessibleEventId.hpp>
42 : #include <com/sun/star/accessibility/AccessibleStateType.hpp>
43 : #include <comphelper/accessibleeventnotifier.hxx>
44 : #include <cppuhelper/supportsservice.hxx>
45 : #include <unotools/accessiblestatesethelper.hxx>
46 : #include <rtl/ref.hxx>
47 :
48 : #include <vcl/settings.hxx>
49 : #include <vcl/svapp.hxx>
50 :
51 : using namespace ::com::sun::star;
52 : using namespace ::com::sun::star::uno;
53 : using namespace ::com::sun::star::accessibility;
54 :
55 : namespace accessibility {
56 :
57 :
58 : /** Inner implementation class of the AccessibleSlideSorterView.
59 :
60 : Note that some event broadcasting is done asynchronously because
61 : otherwise it could lead to deadlocks on (at least) some Solaris
62 : machines. Probably (but unverified) this can happen on all GTK based
63 : systems. The asynchronous broadcasting is just a workaround for a
64 : poorly understood problem.
65 : */
66 : class AccessibleSlideSorterView::Implementation
67 : : public SfxListener
68 : {
69 : public:
70 : Implementation (
71 : AccessibleSlideSorterView& rAccessibleSlideSorter,
72 : ::sd::slidesorter::SlideSorter& rSlideSorter,
73 : ::Window* pWindow);
74 : virtual ~Implementation (void);
75 :
76 : void RequestUpdateChildren (void);
77 : void Clear (void);
78 : sal_Int32 GetVisibleChildCount (void) const;
79 : AccessibleSlideSorterObject* GetAccessibleChild (sal_Int32 nIndex);
80 : AccessibleSlideSorterObject* GetVisibleChild (sal_Int32 nIndex);
81 :
82 : void ConnectListeners (void);
83 : void ReleaseListeners (void);
84 : void Notify (SfxBroadcaster& rBroadcaster, const SfxHint& rHint) SAL_OVERRIDE;
85 : DECL_LINK(WindowEventListener, VclWindowEvent*);
86 : DECL_LINK(SelectionChangeListener, void*);
87 : DECL_LINK(BroadcastSelectionChange, void*);
88 : DECL_LINK(FocusChangeListener, void*);
89 : DECL_LINK(VisibilityChangeListener, void*);
90 : DECL_LINK(UpdateChildrenCallback, void*);
91 :
92 : void Activated(void);
93 : private:
94 : AccessibleSlideSorterView& mrAccessibleSlideSorter;
95 : ::sd::slidesorter::SlideSorter& mrSlideSorter;
96 : typedef ::std::vector<rtl::Reference<AccessibleSlideSorterObject> > PageObjectList;
97 : PageObjectList maPageObjects;
98 : sal_Int32 mnFirstVisibleChild;
99 : sal_Int32 mnLastVisibleChild;
100 : bool mbListeningToDocument;
101 : ::Window* mpWindow;
102 : sal_Int32 mnFocusedIndex;
103 : bool mbModelChangeLocked;
104 : sal_uLong mnUpdateChildrenUserEventId;
105 : sal_uLong mnSelectionChangeUserEventId;
106 :
107 : void UpdateChildren (void);
108 : };
109 :
110 :
111 :
112 :
113 : //===== AccessibleSlideSorterView =============================================
114 :
115 0 : AccessibleSlideSorterView::AccessibleSlideSorterView(
116 : ::sd::slidesorter::SlideSorter& rSlideSorter,
117 : const Reference<XAccessible>& rxParent,
118 : ::Window* pContentWindow)
119 : : AccessibleSlideSorterViewBase(MutexOwner::maMutex),
120 : mrSlideSorter(rSlideSorter),
121 : mxParent(rxParent),
122 : mnClientId(0),
123 0 : mpContentWindow(pContentWindow)
124 : {
125 0 : }
126 :
127 :
128 :
129 :
130 :
131 0 : void AccessibleSlideSorterView::Init()
132 : {
133 0 : mpImpl.reset(new Implementation(*this,mrSlideSorter,mpContentWindow));
134 0 : }
135 :
136 :
137 :
138 :
139 :
140 0 : AccessibleSlideSorterView::~AccessibleSlideSorterView (void)
141 : {
142 0 : Destroyed ();
143 0 : }
144 :
145 :
146 :
147 :
148 0 : void AccessibleSlideSorterView::FireAccessibleEvent (
149 : short nEventId,
150 : const uno::Any& rOldValue,
151 : const uno::Any& rNewValue )
152 : {
153 0 : if (mnClientId != 0)
154 : {
155 0 : AccessibleEventObject aEventObject;
156 :
157 0 : aEventObject.Source = Reference<XWeak>(this);
158 0 : aEventObject.EventId = nEventId;
159 0 : aEventObject.NewValue = rNewValue;
160 0 : aEventObject.OldValue = rOldValue;
161 :
162 0 : comphelper::AccessibleEventNotifier::addEvent (mnClientId, aEventObject);
163 : }
164 0 : }
165 :
166 :
167 :
168 :
169 0 : void SAL_CALL AccessibleSlideSorterView::disposing (void)
170 : {
171 0 : if (mnClientId != 0)
172 : {
173 0 : comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( mnClientId, *this );
174 0 : mnClientId = 0;
175 : }
176 0 : mpImpl.reset();
177 0 : }
178 :
179 :
180 :
181 :
182 0 : AccessibleSlideSorterObject* AccessibleSlideSorterView::GetAccessibleChildImplementation (
183 : sal_Int32 nIndex)
184 : {
185 0 : AccessibleSlideSorterObject* pResult = NULL;
186 0 : ::osl::MutexGuard aGuard (maMutex);
187 :
188 0 : if (nIndex>=0 && nIndex<mpImpl->GetVisibleChildCount())
189 0 : pResult = mpImpl->GetVisibleChild(nIndex);
190 :
191 0 : return pResult;
192 : }
193 :
194 0 : void AccessibleSlideSorterView::Destroyed (void)
195 : {
196 0 : ::osl::MutexGuard aGuard (maMutex);
197 :
198 : // Send a disposing to all listeners.
199 0 : if (mnClientId != 0)
200 : {
201 0 : comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( mnClientId, *this );
202 0 : mnClientId = 0;
203 0 : }
204 0 : }
205 :
206 : //===== XAccessible =========================================================
207 :
208 : Reference<XAccessibleContext > SAL_CALL
209 0 : AccessibleSlideSorterView::getAccessibleContext (void)
210 : throw (uno::RuntimeException, std::exception)
211 : {
212 0 : ThrowIfDisposed ();
213 0 : return this;
214 : }
215 :
216 : //===== XAccessibleContext ==================================================
217 :
218 0 : sal_Int32 SAL_CALL AccessibleSlideSorterView::getAccessibleChildCount (void)
219 : throw (RuntimeException, std::exception)
220 : {
221 0 : ThrowIfDisposed();
222 0 : ::osl::MutexGuard aGuard (maMutex);
223 0 : return mpImpl->GetVisibleChildCount();
224 : }
225 :
226 : Reference<XAccessible > SAL_CALL
227 0 : AccessibleSlideSorterView::getAccessibleChild (sal_Int32 nIndex)
228 : throw (lang::IndexOutOfBoundsException, RuntimeException, std::exception)
229 : {
230 0 : ThrowIfDisposed();
231 0 : ::osl::MutexGuard aGuard (maMutex);
232 :
233 0 : if (nIndex<0 || nIndex>=mpImpl->GetVisibleChildCount())
234 0 : throw lang::IndexOutOfBoundsException();
235 :
236 0 : return mpImpl->GetVisibleChild(nIndex);
237 : }
238 :
239 0 : Reference<XAccessible > SAL_CALL AccessibleSlideSorterView::getAccessibleParent (void)
240 : throw (uno::RuntimeException, std::exception)
241 : {
242 0 : ThrowIfDisposed();
243 0 : const SolarMutexGuard aSolarGuard;
244 0 : Reference<XAccessible> xParent;
245 :
246 0 : if (mpContentWindow != NULL)
247 : {
248 0 : ::Window* pParent = mpContentWindow->GetAccessibleParentWindow();
249 0 : if (pParent != NULL)
250 0 : xParent = pParent->GetAccessible();
251 : }
252 :
253 0 : return xParent;
254 : }
255 :
256 0 : sal_Int32 SAL_CALL AccessibleSlideSorterView::getAccessibleIndexInParent (void)
257 : throw (uno::RuntimeException, std::exception)
258 : {
259 : OSL_ASSERT(getAccessibleParent().is());
260 0 : ThrowIfDisposed();
261 0 : const SolarMutexGuard aSolarGuard;
262 0 : sal_Int32 nIndexInParent(-1);
263 :
264 :
265 0 : Reference<XAccessibleContext> xParentContext (getAccessibleParent()->getAccessibleContext());
266 0 : if (xParentContext.is())
267 : {
268 0 : sal_Int32 nChildCount (xParentContext->getAccessibleChildCount());
269 0 : for (sal_Int32 i=0; i<nChildCount; ++i)
270 0 : if (xParentContext->getAccessibleChild(i).get()
271 0 : == static_cast<XAccessible*>(this))
272 : {
273 0 : nIndexInParent = i;
274 0 : break;
275 : }
276 : }
277 :
278 0 : return nIndexInParent;
279 : }
280 :
281 :
282 :
283 :
284 0 : sal_Int16 SAL_CALL AccessibleSlideSorterView::getAccessibleRole (void)
285 : throw (uno::RuntimeException, std::exception)
286 : {
287 0 : ThrowIfDisposed();
288 : static sal_Int16 nRole = AccessibleRole::DOCUMENT;
289 0 : return nRole;
290 : }
291 :
292 :
293 :
294 :
295 0 : OUString SAL_CALL AccessibleSlideSorterView::getAccessibleDescription (void)
296 : throw (uno::RuntimeException, std::exception)
297 : {
298 0 : ThrowIfDisposed();
299 0 : SolarMutexGuard aGuard;
300 :
301 0 : return SD_RESSTR(SID_SD_A11Y_I_SLIDEVIEW_D);
302 : }
303 :
304 :
305 :
306 :
307 0 : OUString SAL_CALL AccessibleSlideSorterView::getAccessibleName (void)
308 : throw (uno::RuntimeException, std::exception)
309 : {
310 0 : ThrowIfDisposed();
311 0 : SolarMutexGuard aGuard;
312 :
313 0 : return SD_RESSTR(SID_SD_A11Y_I_SLIDEVIEW_N);
314 : }
315 :
316 :
317 :
318 :
319 : Reference<XAccessibleRelationSet> SAL_CALL
320 0 : AccessibleSlideSorterView::getAccessibleRelationSet (void)
321 : throw (uno::RuntimeException, std::exception)
322 : {
323 0 : return Reference<XAccessibleRelationSet>();
324 : }
325 :
326 :
327 :
328 :
329 : Reference<XAccessibleStateSet > SAL_CALL
330 0 : AccessibleSlideSorterView::getAccessibleStateSet (void)
331 : throw (uno::RuntimeException, std::exception)
332 : {
333 0 : ThrowIfDisposed();
334 0 : const SolarMutexGuard aSolarGuard;
335 0 : ::utl::AccessibleStateSetHelper* pStateSet = new ::utl::AccessibleStateSetHelper();
336 :
337 0 : pStateSet->AddState(AccessibleStateType::FOCUSABLE);
338 0 : pStateSet->AddState(AccessibleStateType::SELECTABLE);
339 0 : pStateSet->AddState(AccessibleStateType::ENABLED);
340 0 : pStateSet->AddState(AccessibleStateType::ACTIVE);
341 0 : pStateSet->AddState(AccessibleStateType::MULTI_SELECTABLE);
342 0 : pStateSet->AddState(AccessibleStateType::OPAQUE);
343 0 : if (mpContentWindow!=NULL)
344 : {
345 0 : if (mpContentWindow->IsVisible())
346 0 : pStateSet->AddState(AccessibleStateType::VISIBLE);
347 0 : if (mpContentWindow->IsReallyVisible())
348 0 : pStateSet->AddState(AccessibleStateType::SHOWING);
349 : }
350 :
351 0 : return pStateSet;
352 : }
353 :
354 :
355 :
356 :
357 0 : lang::Locale SAL_CALL AccessibleSlideSorterView::getLocale (void)
358 : throw (IllegalAccessibleComponentStateException,
359 : RuntimeException, std::exception)
360 : {
361 0 : ThrowIfDisposed ();
362 0 : Reference<XAccessibleContext> xParentContext;
363 0 : Reference<XAccessible> xParent (getAccessibleParent());
364 0 : if (xParent.is())
365 0 : xParentContext = xParent->getAccessibleContext();
366 :
367 0 : if (xParentContext.is())
368 0 : return xParentContext->getLocale();
369 : else
370 : // Strange, no parent! Anyway, return the default locale.
371 0 : return Application::GetSettings().GetLanguageTag().getLocale();
372 : }
373 :
374 :
375 :
376 :
377 0 : void SAL_CALL AccessibleSlideSorterView::addAccessibleEventListener(
378 : const Reference<XAccessibleEventListener >& rxListener)
379 : throw (RuntimeException, std::exception)
380 : {
381 0 : if (rxListener.is())
382 : {
383 0 : const osl::MutexGuard aGuard(maMutex);
384 :
385 0 : if (IsDisposed())
386 : {
387 0 : uno::Reference<uno::XInterface> x ((lang::XComponent *)this, uno::UNO_QUERY);
388 0 : rxListener->disposing (lang::EventObject (x));
389 : }
390 : else
391 : {
392 0 : if ( ! mnClientId)
393 0 : mnClientId = comphelper::AccessibleEventNotifier::registerClient();
394 0 : comphelper::AccessibleEventNotifier::addEventListener(mnClientId, rxListener);
395 0 : }
396 : }
397 0 : }
398 :
399 :
400 :
401 :
402 0 : void SAL_CALL AccessibleSlideSorterView::removeAccessibleEventListener(
403 : const Reference<XAccessibleEventListener >& rxListener)
404 : throw (RuntimeException, std::exception)
405 : {
406 0 : ThrowIfDisposed();
407 0 : if (rxListener.is())
408 : {
409 0 : const osl::MutexGuard aGuard(maMutex);
410 :
411 0 : if (mnClientId != 0)
412 : {
413 : sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener(
414 0 : mnClientId, rxListener );
415 0 : if ( !nListenerCount )
416 : {
417 : // no listeners anymore -> revoke ourself. This may lead to
418 : // the notifier thread dying (if we were the last client),
419 : // and at least to us not firing any events anymore, in case
420 : // somebody calls NotifyAccessibleEvent, again
421 0 : comphelper::AccessibleEventNotifier::revokeClient( mnClientId );
422 0 : mnClientId = 0;
423 : }
424 0 : }
425 : }
426 0 : }
427 :
428 :
429 :
430 :
431 : //===== XAccessibleComponent ==================================================
432 :
433 0 : sal_Bool SAL_CALL AccessibleSlideSorterView::containsPoint (const awt::Point& aPoint)
434 : throw (RuntimeException, std::exception)
435 : {
436 0 : ThrowIfDisposed();
437 0 : const awt::Rectangle aBBox (getBounds());
438 0 : return (aPoint.X >= 0)
439 0 : && (aPoint.X < aBBox.Width)
440 0 : && (aPoint.Y >= 0)
441 0 : && (aPoint.Y < aBBox.Height);
442 : }
443 :
444 :
445 :
446 :
447 : Reference<XAccessible> SAL_CALL
448 0 : AccessibleSlideSorterView::getAccessibleAtPoint (const awt::Point& aPoint)
449 : throw (RuntimeException, std::exception)
450 : {
451 0 : ThrowIfDisposed();
452 0 : Reference<XAccessible> xAccessible;
453 0 : const SolarMutexGuard aSolarGuard;
454 :
455 0 : const Point aTestPoint (aPoint.X, aPoint.Y);
456 : ::sd::slidesorter::model::SharedPageDescriptor pHitDescriptor (
457 0 : mrSlideSorter.GetController().GetPageAt(aTestPoint));
458 0 : if (pHitDescriptor.get() != NULL)
459 0 : xAccessible = mpImpl->GetAccessibleChild(
460 0 : (pHitDescriptor->GetPage()->GetPageNum()-1)/2);
461 :
462 0 : return xAccessible;
463 : }
464 :
465 :
466 :
467 :
468 0 : awt::Rectangle SAL_CALL AccessibleSlideSorterView::getBounds (void)
469 : throw (uno::RuntimeException, std::exception)
470 : {
471 0 : ThrowIfDisposed();
472 0 : const SolarMutexGuard aSolarGuard;
473 0 : awt::Rectangle aBBox;
474 :
475 0 : if (mpContentWindow != NULL)
476 : {
477 0 : const Point aPosition (mpContentWindow->GetPosPixel());
478 0 : const Size aSize (mpContentWindow->GetOutputSizePixel());
479 :
480 0 : aBBox.X = aPosition.X();
481 0 : aBBox.Y = aPosition.Y();
482 0 : aBBox.Width = aSize.Width();
483 0 : aBBox.Height = aSize.Height();
484 : }
485 :
486 0 : return aBBox;
487 : }
488 :
489 :
490 :
491 :
492 0 : awt::Point SAL_CALL AccessibleSlideSorterView::getLocation (void)
493 : throw (uno::RuntimeException, std::exception)
494 : {
495 0 : ThrowIfDisposed();
496 0 : awt::Point aLocation;
497 :
498 0 : if (mpContentWindow != NULL)
499 : {
500 0 : const Point aPosition (mpContentWindow->GetPosPixel());
501 0 : aLocation.X = aPosition.X();
502 0 : aLocation.Y = aPosition.Y();
503 : }
504 :
505 0 : return aLocation;
506 : }
507 :
508 :
509 :
510 :
511 : /** Calculate the location on screen from the parent's location on screen
512 : and our own relative location.
513 : */
514 0 : awt::Point SAL_CALL AccessibleSlideSorterView::getLocationOnScreen()
515 : throw (uno::RuntimeException, std::exception)
516 : {
517 0 : ThrowIfDisposed();
518 0 : const SolarMutexGuard aSolarGuard;
519 0 : awt::Point aParentLocationOnScreen;
520 :
521 0 : Reference<XAccessible> xParent (getAccessibleParent());
522 0 : if (xParent.is())
523 : {
524 : Reference<XAccessibleComponent> xParentComponent (
525 0 : xParent->getAccessibleContext(), uno::UNO_QUERY);
526 0 : if (xParentComponent.is())
527 0 : aParentLocationOnScreen = xParentComponent->getLocationOnScreen();
528 : }
529 :
530 0 : awt::Point aLocationOnScreen (getLocation());
531 0 : aLocationOnScreen.X += aParentLocationOnScreen.X;
532 0 : aLocationOnScreen.Y += aParentLocationOnScreen.Y;
533 :
534 0 : return aLocationOnScreen;
535 : }
536 :
537 :
538 :
539 :
540 0 : awt::Size SAL_CALL AccessibleSlideSorterView::getSize (void)
541 : throw (uno::RuntimeException, std::exception)
542 : {
543 0 : ThrowIfDisposed();
544 0 : awt::Size aSize;
545 :
546 0 : if (mpContentWindow != NULL)
547 : {
548 0 : const Size aOutputSize (mpContentWindow->GetOutputSizePixel());
549 0 : aSize.Width = aOutputSize.Width();
550 0 : aSize.Height = aOutputSize.Height();
551 : }
552 :
553 0 : return aSize;
554 : }
555 :
556 :
557 :
558 :
559 0 : void SAL_CALL AccessibleSlideSorterView::grabFocus (void)
560 : throw (uno::RuntimeException, std::exception)
561 : {
562 0 : ThrowIfDisposed();
563 0 : const SolarMutexGuard aSolarGuard;
564 :
565 0 : if (mpContentWindow)
566 0 : mpContentWindow->GrabFocus();
567 0 : }
568 :
569 :
570 :
571 :
572 0 : sal_Int32 SAL_CALL AccessibleSlideSorterView::getForeground (void)
573 : throw (RuntimeException, std::exception)
574 : {
575 0 : ThrowIfDisposed();
576 0 : svtools::ColorConfig aColorConfig;
577 0 : sal_uInt32 nColor = aColorConfig.GetColorValue( svtools::FONTCOLOR ).nColor;
578 0 : return static_cast<sal_Int32>(nColor);
579 : }
580 :
581 :
582 :
583 :
584 0 : sal_Int32 SAL_CALL AccessibleSlideSorterView::getBackground (void)
585 : throw (RuntimeException, std::exception)
586 : {
587 0 : ThrowIfDisposed();
588 0 : sal_uInt32 nColor = Application::GetSettings().GetStyleSettings().GetWindowColor().GetColor();
589 0 : return static_cast<sal_Int32>(nColor);
590 : }
591 :
592 :
593 :
594 :
595 : //===== XAccessibleSelection ==================================================
596 :
597 0 : void SAL_CALL AccessibleSlideSorterView::selectAccessibleChild (sal_Int32 nChildIndex)
598 : throw (lang::IndexOutOfBoundsException,
599 : RuntimeException, std::exception)
600 : {
601 0 : ThrowIfDisposed();
602 0 : const SolarMutexGuard aSolarGuard;
603 :
604 0 : AccessibleSlideSorterObject* pChild = mpImpl->GetAccessibleChild(nChildIndex);
605 0 : if (pChild != NULL)
606 0 : mrSlideSorter.GetController().GetPageSelector().SelectPage(pChild->GetPageNumber());
607 : else
608 0 : throw lang::IndexOutOfBoundsException();
609 0 : }
610 :
611 :
612 :
613 :
614 0 : sal_Bool SAL_CALL AccessibleSlideSorterView::isAccessibleChildSelected (sal_Int32 nChildIndex)
615 : throw (lang::IndexOutOfBoundsException,
616 : RuntimeException, std::exception)
617 : {
618 0 : ThrowIfDisposed();
619 0 : sal_Bool bIsSelected = sal_False;
620 0 : const SolarMutexGuard aSolarGuard;
621 :
622 0 : AccessibleSlideSorterObject* pChild = mpImpl->GetAccessibleChild(nChildIndex);
623 0 : if (pChild != NULL)
624 0 : bIsSelected = mrSlideSorter.GetController().GetPageSelector().IsPageSelected(
625 0 : pChild->GetPageNumber());
626 : else
627 0 : throw lang::IndexOutOfBoundsException();
628 :
629 0 : return bIsSelected;
630 : }
631 :
632 :
633 :
634 :
635 0 : void SAL_CALL AccessibleSlideSorterView::clearAccessibleSelection (void)
636 : throw (uno::RuntimeException, std::exception)
637 : {
638 0 : ThrowIfDisposed();
639 0 : const SolarMutexGuard aSolarGuard;
640 :
641 0 : mrSlideSorter.GetController().GetPageSelector().DeselectAllPages();
642 0 : }
643 :
644 :
645 :
646 :
647 0 : void SAL_CALL AccessibleSlideSorterView::selectAllAccessibleChildren (void)
648 : throw (uno::RuntimeException, std::exception)
649 : {
650 0 : ThrowIfDisposed();
651 0 : const SolarMutexGuard aSolarGuard;
652 :
653 0 : mrSlideSorter.GetController().GetPageSelector().SelectAllPages();
654 0 : }
655 :
656 :
657 :
658 :
659 0 : sal_Int32 SAL_CALL AccessibleSlideSorterView::getSelectedAccessibleChildCount (void)
660 : throw (uno::RuntimeException, std::exception)
661 : {
662 0 : ThrowIfDisposed ();
663 0 : const SolarMutexGuard aSolarGuard;
664 0 : return mrSlideSorter.GetController().GetPageSelector().GetSelectedPageCount();
665 : }
666 :
667 :
668 :
669 :
670 : Reference<XAccessible > SAL_CALL
671 0 : AccessibleSlideSorterView::getSelectedAccessibleChild (sal_Int32 nSelectedChildIndex )
672 : throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
673 : {
674 0 : ThrowIfDisposed ();
675 0 : const SolarMutexGuard aSolarGuard;
676 0 : Reference<XAccessible> xChild;
677 :
678 : ::sd::slidesorter::controller::PageSelector& rSelector (
679 0 : mrSlideSorter.GetController().GetPageSelector());
680 0 : sal_Int32 nPageCount(rSelector.GetPageCount());
681 0 : sal_Int32 nSelectedCount = 0;
682 0 : for (sal_Int32 i=0; i<nPageCount; i++)
683 0 : if (rSelector.IsPageSelected(i))
684 : {
685 0 : if (nSelectedCount == nSelectedChildIndex)
686 : {
687 0 : xChild = mpImpl->GetAccessibleChild(i);
688 0 : break;
689 : }
690 0 : ++nSelectedCount;
691 : }
692 :
693 :
694 0 : if ( ! xChild.is() )
695 0 : throw lang::IndexOutOfBoundsException();
696 :
697 0 : return xChild;
698 : }
699 :
700 :
701 :
702 :
703 0 : void SAL_CALL AccessibleSlideSorterView::deselectAccessibleChild (sal_Int32 nChildIndex)
704 : throw (lang::IndexOutOfBoundsException,
705 : RuntimeException, std::exception)
706 : {
707 0 : ThrowIfDisposed();
708 0 : const SolarMutexGuard aSolarGuard;
709 :
710 0 : AccessibleSlideSorterObject* pChild = mpImpl->GetAccessibleChild(nChildIndex);
711 0 : if (pChild != NULL)
712 0 : mrSlideSorter.GetController().GetPageSelector().DeselectPage(pChild->GetPageNumber());
713 : else
714 0 : throw lang::IndexOutOfBoundsException();
715 0 : }
716 :
717 : //===== XServiceInfo ========================================================
718 : OUString SAL_CALL
719 0 : AccessibleSlideSorterView::getImplementationName (void)
720 : throw (::com::sun::star::uno::RuntimeException, std::exception)
721 : {
722 0 : return OUString("AccessibleSlideSorterView");
723 : }
724 :
725 0 : sal_Bool SAL_CALL AccessibleSlideSorterView::supportsService (const OUString& sServiceName)
726 : throw (::com::sun::star::uno::RuntimeException, std::exception)
727 : {
728 0 : return cppu::supportsService(this, sServiceName);
729 : }
730 :
731 : uno::Sequence< OUString> SAL_CALL
732 0 : AccessibleSlideSorterView::getSupportedServiceNames (void)
733 : throw (::com::sun::star::uno::RuntimeException, std::exception)
734 : {
735 0 : ThrowIfDisposed ();
736 :
737 : static const OUString sServiceNames[3] = {
738 : OUString("com.sun.star.accessibility.Accessible"),
739 : OUString("com.sun.star.accessibility.AccessibleContext"),
740 : OUString("com.sun.star.drawing.AccessibleSlideSorterView")
741 0 : };
742 0 : return uno::Sequence<OUString> (sServiceNames, 3);
743 : }
744 :
745 0 : void AccessibleSlideSorterView::ThrowIfDisposed (void)
746 : throw (lang::DisposedException)
747 : {
748 0 : if (rBHelper.bDisposed || rBHelper.bInDispose)
749 : {
750 : OSL_TRACE ("Calling disposed object. Throwing exception:");
751 : throw lang::DisposedException ("object has been already disposed",
752 0 : static_cast<uno::XWeak*>(this));
753 : }
754 0 : }
755 :
756 :
757 :
758 0 : sal_Bool AccessibleSlideSorterView::IsDisposed (void)
759 : {
760 0 : return (rBHelper.bDisposed || rBHelper.bInDispose);
761 : }
762 :
763 :
764 :
765 :
766 : //===== AccessibleSlideSorterView::Implementation =============================
767 :
768 0 : AccessibleSlideSorterView::Implementation::Implementation (
769 : AccessibleSlideSorterView& rAccessibleSlideSorter,
770 : ::sd::slidesorter::SlideSorter& rSlideSorter,
771 : ::Window* pWindow)
772 : : mrAccessibleSlideSorter(rAccessibleSlideSorter),
773 : mrSlideSorter(rSlideSorter),
774 : maPageObjects(),
775 : mnFirstVisibleChild(0),
776 : mnLastVisibleChild(-1),
777 : mbListeningToDocument(false),
778 : mpWindow(pWindow),
779 : mnFocusedIndex(-1),
780 : mbModelChangeLocked(false),
781 : mnUpdateChildrenUserEventId(0),
782 0 : mnSelectionChangeUserEventId(0)
783 : {
784 0 : ConnectListeners();
785 0 : UpdateChildren();
786 0 : }
787 :
788 :
789 :
790 :
791 0 : AccessibleSlideSorterView::Implementation::~Implementation (void)
792 : {
793 0 : if (mnUpdateChildrenUserEventId != 0)
794 0 : Application::RemoveUserEvent(mnUpdateChildrenUserEventId);
795 0 : if (mnSelectionChangeUserEventId != 0)
796 0 : Application::RemoveUserEvent(mnSelectionChangeUserEventId);
797 0 : ReleaseListeners();
798 0 : Clear();
799 0 : }
800 :
801 :
802 :
803 :
804 0 : void AccessibleSlideSorterView::Implementation::RequestUpdateChildren (void)
805 : {
806 0 : if (mnUpdateChildrenUserEventId == 0)
807 : mnUpdateChildrenUserEventId = Application::PostUserEvent(
808 : LINK(this, AccessibleSlideSorterView::Implementation,
809 0 : UpdateChildrenCallback));
810 0 : }
811 :
812 :
813 :
814 :
815 0 : void AccessibleSlideSorterView::Implementation::UpdateChildren (void)
816 : {
817 : //By default, all children should be accessable. So here workaround is to make all children visible.
818 : // MT: THis was in UpdateVisibility, which has some similarity, and hg merge automatically has put it here. Correct?!
819 : // In the IA2 CWS, also setting mnFirst/LastVisibleChild was commented out!
820 0 : mnLastVisibleChild = maPageObjects.size();
821 :
822 0 : if (mbModelChangeLocked)
823 : {
824 : // Do nothing right now. When the flag is reset, this method is
825 : // called again.
826 0 : return;
827 : }
828 :
829 0 : const Pair aRange (mrSlideSorter.GetView().GetVisiblePageRange());
830 0 : mnFirstVisibleChild = aRange.A();
831 0 : mnLastVisibleChild = aRange.B();
832 :
833 : // Release all children.
834 0 : Clear();
835 :
836 : // Create new children for the modified visible range.
837 0 : maPageObjects.resize(mrSlideSorter.GetModel().GetPageCount());
838 :
839 : // No Visible children
840 0 : if (mnFirstVisibleChild == -1 && mnLastVisibleChild == -1)
841 0 : return;
842 :
843 0 : for (sal_Int32 nIndex(mnFirstVisibleChild); nIndex<=mnLastVisibleChild; ++nIndex)
844 0 : GetAccessibleChild(nIndex);
845 : }
846 :
847 :
848 :
849 :
850 0 : void AccessibleSlideSorterView::Implementation::Clear (void)
851 : {
852 0 : PageObjectList::iterator iPageObject;
853 0 : PageObjectList::iterator iEnd = maPageObjects.end();
854 0 : for (iPageObject=maPageObjects.begin(); iPageObject!=iEnd; ++iPageObject)
855 0 : if (*iPageObject != NULL)
856 : {
857 : mrAccessibleSlideSorter.FireAccessibleEvent(
858 : AccessibleEventId::CHILD,
859 0 : Any(Reference<XAccessible>(iPageObject->get())),
860 0 : Any());
861 :
862 0 : Reference<XComponent> xComponent (Reference<XWeak>(iPageObject->get()), UNO_QUERY);
863 0 : if (xComponent.is())
864 0 : xComponent->dispose();
865 0 : *iPageObject = NULL;
866 : }
867 0 : maPageObjects.clear();
868 0 : }
869 :
870 :
871 :
872 :
873 0 : sal_Int32 AccessibleSlideSorterView::Implementation::GetVisibleChildCount (void) const
874 : {
875 0 : if (mnFirstVisibleChild<=mnLastVisibleChild && mnFirstVisibleChild>=0)
876 0 : return mnLastVisibleChild - mnFirstVisibleChild + 1;
877 : else
878 0 : return 0;
879 : }
880 :
881 :
882 :
883 :
884 0 : AccessibleSlideSorterObject* AccessibleSlideSorterView::Implementation::GetVisibleChild (
885 : sal_Int32 nIndex)
886 : {
887 : assert(nIndex>=0 && nIndex<GetVisibleChildCount());
888 :
889 0 : return GetAccessibleChild(nIndex+mnFirstVisibleChild);
890 : }
891 :
892 :
893 :
894 :
895 0 : AccessibleSlideSorterObject* AccessibleSlideSorterView::Implementation::GetAccessibleChild (
896 : sal_Int32 nIndex)
897 : {
898 0 : AccessibleSlideSorterObject* pChild = NULL;
899 :
900 0 : if (nIndex>=0 && (sal_uInt32)nIndex<maPageObjects.size())
901 : {
902 0 : if (maPageObjects[nIndex] == NULL)
903 : {
904 : ::sd::slidesorter::model::SharedPageDescriptor pDescriptor(
905 0 : mrSlideSorter.GetModel().GetPageDescriptor(nIndex));
906 0 : if (pDescriptor.get() != NULL)
907 : {
908 0 : maPageObjects[nIndex] = new AccessibleSlideSorterObject(
909 : &mrAccessibleSlideSorter,
910 : mrSlideSorter,
911 0 : (pDescriptor->GetPage()->GetPageNum()-1)/2);
912 :
913 : mrAccessibleSlideSorter.FireAccessibleEvent(
914 : AccessibleEventId::CHILD,
915 : Any(),
916 0 : Any(Reference<XAccessible>(maPageObjects[nIndex].get())));
917 0 : }
918 :
919 : }
920 :
921 0 : pChild = maPageObjects[nIndex].get();
922 : }
923 : else
924 : {
925 : OSL_ASSERT(nIndex>=0 && (sal_uInt32)nIndex<maPageObjects.size());
926 : }
927 :
928 0 : return pChild;
929 : }
930 :
931 :
932 :
933 :
934 0 : void AccessibleSlideSorterView::Implementation::ConnectListeners (void)
935 : {
936 0 : StartListening (*mrSlideSorter.GetModel().GetDocument());
937 0 : if (mrSlideSorter.GetViewShell() != NULL)
938 0 : StartListening (*mrSlideSorter.GetViewShell());
939 0 : mbListeningToDocument = true;
940 :
941 0 : if (mpWindow != NULL)
942 : mpWindow->AddEventListener(
943 0 : LINK(this,AccessibleSlideSorterView::Implementation,WindowEventListener));
944 :
945 0 : mrSlideSorter.GetController().GetSelectionManager()->AddSelectionChangeListener(
946 0 : LINK(this,AccessibleSlideSorterView::Implementation,SelectionChangeListener));
947 0 : mrSlideSorter.GetController().GetFocusManager().AddFocusChangeListener(
948 0 : LINK(this,AccessibleSlideSorterView::Implementation,FocusChangeListener));
949 0 : mrSlideSorter.GetView().AddVisibilityChangeListener(
950 0 : LINK(this,AccessibleSlideSorterView::Implementation,VisibilityChangeListener));
951 0 : }
952 :
953 :
954 :
955 :
956 0 : void AccessibleSlideSorterView::Implementation::ReleaseListeners (void)
957 : {
958 0 : mrSlideSorter.GetController().GetFocusManager().RemoveFocusChangeListener(
959 0 : LINK(this,AccessibleSlideSorterView::Implementation,FocusChangeListener));
960 0 : mrSlideSorter.GetController().GetSelectionManager()->RemoveSelectionChangeListener(
961 0 : LINK(this,AccessibleSlideSorterView::Implementation,SelectionChangeListener));
962 0 : mrSlideSorter.GetView().RemoveVisibilityChangeListener(
963 0 : LINK(this,AccessibleSlideSorterView::Implementation,VisibilityChangeListener));
964 :
965 0 : if (mpWindow != NULL)
966 : mpWindow->RemoveEventListener(
967 0 : LINK(this,AccessibleSlideSorterView::Implementation,WindowEventListener));
968 :
969 0 : if (mbListeningToDocument)
970 : {
971 0 : if (mrSlideSorter.GetViewShell() != NULL)
972 0 : StartListening(*mrSlideSorter.GetViewShell());
973 0 : EndListening (*mrSlideSorter.GetModel().GetDocument());
974 0 : mbListeningToDocument = false;
975 : }
976 0 : }
977 :
978 :
979 :
980 :
981 0 : void AccessibleSlideSorterView::Implementation::Notify (
982 : SfxBroadcaster&,
983 : const SfxHint& rHint)
984 : {
985 0 : if (rHint.ISA(SdrHint))
986 : {
987 0 : SdrHint& rSdrHint (*PTR_CAST(SdrHint,&rHint));
988 0 : switch (rSdrHint.GetKind())
989 : {
990 : case HINT_PAGEORDERCHG:
991 0 : RequestUpdateChildren();
992 0 : break;
993 : default:
994 0 : break;
995 : }
996 : }
997 0 : else if (rHint.ISA(sd::ViewShellHint))
998 : {
999 0 : sd::ViewShellHint& rViewShellHint (*PTR_CAST(sd::ViewShellHint, &rHint));
1000 0 : switch (rViewShellHint.GetHintId())
1001 : {
1002 : case sd::ViewShellHint::HINT_COMPLEX_MODEL_CHANGE_START:
1003 0 : mbModelChangeLocked = true;
1004 0 : break;
1005 :
1006 : case sd::ViewShellHint::HINT_COMPLEX_MODEL_CHANGE_END:
1007 0 : mbModelChangeLocked = false;
1008 0 : RequestUpdateChildren();
1009 0 : break;
1010 : default:
1011 0 : break;
1012 : }
1013 : }
1014 0 : }
1015 :
1016 :
1017 0 : void AccessibleSlideSorterView::SwitchViewActivated (void)
1018 : {
1019 : // Firstly, set focus to view
1020 : this->FireAccessibleEvent(AccessibleEventId::STATE_CHANGED,
1021 : Any(),
1022 0 : Any(AccessibleStateType::FOCUSED));
1023 :
1024 0 : mpImpl->Activated();
1025 0 : }
1026 :
1027 0 : void AccessibleSlideSorterView::Implementation::Activated()
1028 : {
1029 0 : mrSlideSorter.GetController().GetFocusManager().ShowFocus();
1030 :
1031 0 : }
1032 :
1033 :
1034 :
1035 0 : IMPL_LINK(AccessibleSlideSorterView::Implementation, WindowEventListener, VclWindowEvent*, pEvent)
1036 : {
1037 0 : switch (pEvent->GetId())
1038 : {
1039 : case VCLEVENT_WINDOW_MOVE:
1040 : case VCLEVENT_WINDOW_RESIZE:
1041 0 : RequestUpdateChildren();
1042 0 : break;
1043 :
1044 : case VCLEVENT_WINDOW_GETFOCUS:
1045 : case VCLEVENT_WINDOW_LOSEFOCUS:
1046 : mrAccessibleSlideSorter.FireAccessibleEvent(
1047 : AccessibleEventId::SELECTION_CHANGED,
1048 : Any(),
1049 0 : Any());
1050 0 : break;
1051 : default:
1052 0 : break;
1053 : }
1054 0 : return 1;
1055 : }
1056 :
1057 :
1058 :
1059 :
1060 0 : IMPL_LINK_NOARG(AccessibleSlideSorterView::Implementation, SelectionChangeListener)
1061 : {
1062 0 : if (mnSelectionChangeUserEventId == 0)
1063 : mnSelectionChangeUserEventId = Application::PostUserEvent(
1064 0 : LINK(this, AccessibleSlideSorterView::Implementation, BroadcastSelectionChange));
1065 0 : return 1;
1066 : }
1067 :
1068 :
1069 :
1070 :
1071 0 : IMPL_LINK_NOARG(AccessibleSlideSorterView::Implementation, BroadcastSelectionChange)
1072 : {
1073 0 : mnSelectionChangeUserEventId = 0;
1074 : mrAccessibleSlideSorter.FireAccessibleEvent(
1075 : AccessibleEventId::SELECTION_CHANGED,
1076 : Any(),
1077 0 : Any());
1078 0 : return 1;
1079 : }
1080 :
1081 :
1082 :
1083 :
1084 0 : IMPL_LINK_NOARG(AccessibleSlideSorterView::Implementation, FocusChangeListener)
1085 : {
1086 : sal_Int32 nNewFocusedIndex (
1087 0 : mrSlideSorter.GetController().GetFocusManager().GetFocusedPageIndex());
1088 :
1089 0 : sal_Bool bHasFocus = mrSlideSorter.GetController().GetFocusManager().IsFocusShowing();
1090 0 : if (!bHasFocus)
1091 0 : nNewFocusedIndex = -1;
1092 :
1093 : // add a checker whether the focus event is sent out. Only after sent, the mnFocusedIndex should be updated.
1094 0 : sal_Bool bSentFocus = sal_False;
1095 0 : if (nNewFocusedIndex != mnFocusedIndex)
1096 : {
1097 0 : if (mnFocusedIndex >= 0)
1098 : {
1099 0 : AccessibleSlideSorterObject* pObject = GetAccessibleChild(mnFocusedIndex);
1100 0 : if (pObject != NULL)
1101 : {
1102 : pObject->FireAccessibleEvent(
1103 : AccessibleEventId::STATE_CHANGED,
1104 : Any(AccessibleStateType::FOCUSED),
1105 0 : Any());
1106 0 : bSentFocus = sal_True;
1107 : }
1108 : }
1109 0 : if (nNewFocusedIndex >= 0)
1110 : {
1111 0 : AccessibleSlideSorterObject* pObject = GetAccessibleChild(nNewFocusedIndex);
1112 0 : if (pObject != NULL)
1113 : {
1114 : pObject->FireAccessibleEvent(
1115 : AccessibleEventId::STATE_CHANGED,
1116 : Any(),
1117 0 : Any(AccessibleStateType::FOCUSED));
1118 0 : bSentFocus = sal_True;
1119 : }
1120 : }
1121 0 : if (bSentFocus == sal_True)
1122 0 : mnFocusedIndex = nNewFocusedIndex;
1123 : }
1124 0 : return 1;
1125 : }
1126 :
1127 :
1128 :
1129 :
1130 0 : IMPL_LINK_NOARG(AccessibleSlideSorterView::Implementation, UpdateChildrenCallback)
1131 : {
1132 0 : mnUpdateChildrenUserEventId = 0;
1133 0 : UpdateChildren();
1134 :
1135 0 : return 1;
1136 : }
1137 :
1138 :
1139 :
1140 :
1141 0 : IMPL_LINK_NOARG(AccessibleSlideSorterView::Implementation, VisibilityChangeListener)
1142 : {
1143 0 : UpdateChildren();
1144 0 : return 1;
1145 : }
1146 :
1147 : } // end of namespace ::accessibility
1148 :
1149 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|