1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: AccessibleDocumentViewBase.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sd.hxx"
33 #include "AccessibleDocumentViewBase.hxx"
34 #include <com/sun/star/drawing/XDrawPage.hpp>
35 #include <com/sun/star/drawing/XDrawView.hpp>
36 #include <com/sun/star/drawing/XShapes.hpp>
37 #include <com/sun/star/container/XChild.hpp>
38 #include <com/sun/star/frame/XController.hpp>
39 #include <com/sun/star/frame/XFrame.hpp>
40 #include <com/sun/star/document/XEventBroadcaster.hpp>
41 #include <com/sun/star/beans/XPropertySet.hpp>
42 #ifndef _COM_SUN_STAR_ACCESSIBLE_ACCESSIBLEEVENTID_HPP_
43 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
45 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
46 #ifndef _COM_SUN_STAR_LANG_XMULSTISERVICEFACTORY_HPP_
47 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
49 #include <rtl/ustring.h>
51 #include<sfx2/viewfrm.hxx>
54 #include <svx/AccessibleShape.hxx>
56 #include <svx/svdobj.hxx>
57 #include <svx/svdmodel.hxx>
58 #include <svx/unoapi.hxx>
59 #include <toolkit/helper/vclunohelper.hxx>
61 #include <vcl/svapp.hxx>
64 #include "ViewShell.hxx"
68 using ::rtl::OUString
;
69 using namespace ::com::sun::star
;
70 using namespace ::com::sun::star::accessibility
;
71 using ::com::sun::star::uno::Reference
;
75 namespace accessibility
{
77 //===== internal ============================================================
78 AccessibleDocumentViewBase::AccessibleDocumentViewBase (
79 ::sd::Window
* pSdWindow
,
80 ::sd::ViewShell
* pViewShell
,
81 const uno::Reference
<frame::XController
>& rxController
,
82 const uno::Reference
<XAccessible
>& rxParent
)
83 : AccessibleContextBase (rxParent
, AccessibleRole::DOCUMENT
),
85 mxController (rxController
),
88 static_cast<SdrPaintView
*>(pViewShell
->GetView()),
89 *static_cast<OutputDevice
*>(pSdWindow
))
91 if (mxController
.is())
92 mxModel
= mxController
->getModel();
94 // Fill the shape tree info.
95 maShapeTreeInfo
.SetModelBroadcaster (
96 uno::Reference
<document::XEventBroadcaster
>(
97 mxModel
, uno::UNO_QUERY
));
98 maShapeTreeInfo
.SetController (mxController
);
99 maShapeTreeInfo
.SetSdrView (pViewShell
->GetView());
100 maShapeTreeInfo
.SetWindow (pSdWindow
);
101 maShapeTreeInfo
.SetViewForwarder (&maViewForwarder
);
103 mxWindow
= ::VCLUnoHelper::GetInterface (pSdWindow
);
109 AccessibleDocumentViewBase::~AccessibleDocumentViewBase (void)
111 // At this place we should be disposed. You may want to add a
112 // corresponding assertion into the destructor of a derived class.
118 void AccessibleDocumentViewBase::Init (void)
120 // Finish the initialization of the shape tree info container.
121 maShapeTreeInfo
.SetDocumentWindow (this);
123 // Register as window listener to stay up to date with its size and
125 mxWindow
->addWindowListener (this);
126 // Register as focus listener to
127 mxWindow
->addFocusListener (this);
129 // Determine the list of shapes on the current page.
130 uno::Reference
<drawing::XShapes
> xShapeList
;
131 uno::Reference
<drawing::XDrawView
> xView (mxController
, uno::UNO_QUERY
);
133 xShapeList
= uno::Reference
<drawing::XShapes
> (
134 xView
->getCurrentPage(), uno::UNO_QUERY
);
136 // Register this object as dispose event listener at the model.
138 mxModel
->addEventListener (
139 static_cast<awt::XWindowListener
*>(this));
141 // Register as property change listener at the controller.
142 uno::Reference
<beans::XPropertySet
> xSet (mxController
, uno::UNO_QUERY
);
144 xSet
->addPropertyChangeListener (
145 OUString (RTL_CONSTASCII_USTRINGPARAM("")),
146 static_cast<beans::XPropertyChangeListener
*>(this));
148 // Register this object as dispose event listener at the controller.
149 if (mxController
.is())
150 mxController
->addEventListener (
151 static_cast<awt::XWindowListener
*>(this));
153 // Register at VCL Window to be informed of activated and deactivated
155 Window
* pWindow
= maShapeTreeInfo
.GetWindow();
159 this, AccessibleDocumentViewBase
, WindowChildEventListener
);
161 pWindow
->AddChildEventListener (maWindowLink
);
163 USHORT nCount
= pWindow
->GetChildCount();
164 for (sal_uInt16 i
=0; i
<nCount
; i
++)
166 Window
* pChildWindow
= pWindow
->GetChild (i
);
168 (AccessibleRole::EMBEDDED_OBJECT
169 ==pChildWindow
->GetAccessibleRole()))
171 SetAccessibleOLEObject (pChildWindow
->GetAccessible());
180 IMPL_LINK(AccessibleDocumentViewBase
, WindowChildEventListener
,
181 VclSimpleEvent
*, pEvent
)
183 OSL_ASSERT(pEvent
!=NULL
&& pEvent
->ISA(VclWindowEvent
));
184 if (pEvent
!=NULL
&& pEvent
->ISA(VclWindowEvent
))
186 VclWindowEvent
* pWindowEvent
= static_cast<VclWindowEvent
*>(pEvent
);
187 // DBG_ASSERT( pVclEvent->GetWindow(), "Window???" );
188 switch (pWindowEvent
->GetId())
190 case VCLEVENT_OBJECT_DYING
:
192 // Window is dying. Unregister from VCL Window.
193 // This is also attempted in the disposing() method.
194 Window
* pWindow
= maShapeTreeInfo
.GetWindow();
195 Window
* pDyingWindow
= static_cast<Window
*>(
196 pWindowEvent
->GetWindow());
197 if (pWindow
==pDyingWindow
&& pWindow
!=NULL
&& maWindowLink
.IsSet())
199 pWindow
->RemoveChildEventListener (maWindowLink
);
200 maWindowLink
= Link();
205 case VCLEVENT_WINDOW_SHOW
:
207 // A new window has been created. Is it an OLE object?
208 Window
* pChildWindow
= static_cast<Window
*>(
209 pWindowEvent
->GetData());
210 if (pChildWindow
!=NULL
211 && (pChildWindow
->GetAccessibleRole()
212 == AccessibleRole::EMBEDDED_OBJECT
))
214 SetAccessibleOLEObject (pChildWindow
->GetAccessible());
219 case VCLEVENT_WINDOW_HIDE
:
221 // A window has been destroyed. Has that been an OLE
223 Window
* pChildWindow
= static_cast<Window
*>(
224 pWindowEvent
->GetData());
225 if (pChildWindow
!=NULL
226 && (pChildWindow
->GetAccessibleRole()
227 == AccessibleRole::EMBEDDED_OBJECT
))
229 SetAccessibleOLEObject (NULL
);
242 //===== IAccessibleViewForwarderListener ====================================
244 void AccessibleDocumentViewBase::ViewForwarderChanged(ChangeType
, const IAccessibleViewForwarder
* )
252 //===== XAccessibleContext ==================================================
254 Reference
<XAccessible
> SAL_CALL
255 AccessibleDocumentViewBase::getAccessibleParent (void)
256 throw (uno::RuntimeException
)
260 return AccessibleContextBase::getAccessibleParent();
266 AccessibleDocumentViewBase::getAccessibleChildCount (void)
267 throw (uno::RuntimeException
)
271 if (mxAccessibleOLEObject
.is())
280 Reference
<XAccessible
> SAL_CALL
281 AccessibleDocumentViewBase::getAccessibleChild (sal_Int32 nIndex
)
282 throw (uno::RuntimeException
)
286 ::osl::MutexGuard
aGuard (maMutex
);
287 if (mxAccessibleOLEObject
.is())
289 return mxAccessibleOLEObject
;
291 throw lang::IndexOutOfBoundsException (
292 ::rtl::OUString::createFromAscii ("no child with index ")
293 + rtl::OUString::valueOf(nIndex
),
300 //===== XAccessibleComponent ================================================
302 /** Iterate over all children and test whether the specified point lies
303 within one of their bounding boxes. Return the first child for which
306 uno::Reference
<XAccessible
> SAL_CALL
307 AccessibleDocumentViewBase::getAccessibleAtPoint (
308 const awt::Point
& aPoint
)
309 throw (uno::RuntimeException
)
313 ::osl::MutexGuard
aGuard (maMutex
);
314 uno::Reference
<XAccessible
> xChildAtPosition
;
316 sal_Int32 nChildCount
= getAccessibleChildCount ();
317 for (sal_Int32 i
=nChildCount
-1; i
>=0; --i
)
319 Reference
<XAccessible
> xChild (getAccessibleChild (i
));
322 Reference
<XAccessibleComponent
> xChildComponent (
323 xChild
->getAccessibleContext(), uno::UNO_QUERY
);
324 if (xChildComponent
.is())
326 awt::Rectangle
aBBox (xChildComponent
->getBounds());
327 if ( (aPoint
.X
>= aBBox
.X
)
328 && (aPoint
.Y
>= aBBox
.Y
)
329 && (aPoint
.X
< aBBox
.X
+aBBox
.Width
)
330 && (aPoint
.Y
< aBBox
.Y
+aBBox
.Height
) )
332 xChildAtPosition
= xChild
;
339 // Have not found a child under the given point. Returning empty
340 // reference to indicate this.
341 return xChildAtPosition
;
347 awt::Rectangle SAL_CALL
348 AccessibleDocumentViewBase::getBounds (void)
349 throw (::com::sun::star::uno::RuntimeException
)
353 // Transform visible area into screen coordinates.
354 ::Rectangle
aVisibleArea (
355 maShapeTreeInfo
.GetViewForwarder()->GetVisibleArea());
356 ::Point
aPixelTopLeft (
357 maShapeTreeInfo
.GetViewForwarder()->LogicToPixel (
358 aVisibleArea
.TopLeft()));
360 maShapeTreeInfo
.GetViewForwarder()->LogicToPixel (
361 aVisibleArea
.BottomRight())
364 // Prepare to subtract the parent position to transform into relative
366 awt::Point aParentPosition
;
367 Reference
<XAccessible
> xParent
= getAccessibleParent ();
370 Reference
<XAccessibleComponent
> xParentComponent (
371 xParent
->getAccessibleContext(), uno::UNO_QUERY
);
372 if (xParentComponent
.is())
373 aParentPosition
= xParentComponent
->getLocationOnScreen();
376 return awt::Rectangle (
377 aPixelTopLeft
.X() - aParentPosition
.X
,
378 aPixelTopLeft
.Y() - aParentPosition
.Y
,
387 AccessibleDocumentViewBase::getLocation (void)
388 throw (uno::RuntimeException
)
391 awt::Rectangle
aBoundingBox (getBounds());
392 return awt::Point (aBoundingBox
.X
, aBoundingBox
.Y
);
399 AccessibleDocumentViewBase::getLocationOnScreen (void)
400 throw (uno::RuntimeException
)
403 ::Point
aLogicalPoint (maShapeTreeInfo
.GetViewForwarder()->GetVisibleArea().TopLeft());
404 ::Point
aPixelPoint (maShapeTreeInfo
.GetViewForwarder()->LogicToPixel (aLogicalPoint
));
405 return awt::Point (aPixelPoint
.X(), aPixelPoint
.Y());
412 AccessibleDocumentViewBase::getSize (void)
413 throw (uno::RuntimeException
)
417 // Transform visible area into screen coordinates.
418 ::Rectangle
aVisibleArea (
419 maShapeTreeInfo
.GetViewForwarder()->GetVisibleArea());
420 ::Point
aPixelTopLeft (
421 maShapeTreeInfo
.GetViewForwarder()->LogicToPixel (
422 aVisibleArea
.TopLeft()));
424 maShapeTreeInfo
.GetViewForwarder()->LogicToPixel (
425 aVisibleArea
.BottomRight())
428 return awt::Size (aPixelSize
.X(), aPixelSize
.Y());
434 //===== XInterface ==========================================================
437 AccessibleDocumentViewBase::queryInterface (const uno::Type
& rType
)
438 throw (uno::RuntimeException
)
440 uno::Any aReturn
= AccessibleContextBase::queryInterface (rType
);
441 if ( ! aReturn
.hasValue())
442 aReturn
= ::cppu::queryInterface (rType
,
443 static_cast<XAccessibleComponent
*>(this),
444 static_cast<XAccessibleSelection
*>(this),
445 static_cast<lang::XEventListener
*>(
446 static_cast<awt::XWindowListener
*>(this)),
447 static_cast<beans::XPropertyChangeListener
*>(this),
448 static_cast<awt::XWindowListener
*>(this),
449 static_cast<awt::XFocusListener
*>(this)
458 AccessibleDocumentViewBase::acquire (void)
461 AccessibleContextBase::acquire ();
468 AccessibleDocumentViewBase::release (void)
471 AccessibleContextBase::release ();
477 //===== XServiceInfo ========================================================
479 ::rtl::OUString SAL_CALL
480 AccessibleDocumentViewBase::getImplementationName (void)
481 throw (::com::sun::star::uno::RuntimeException
)
483 return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleDocumentViewBase"));
489 ::com::sun::star::uno::Sequence
< ::rtl::OUString
> SAL_CALL
490 AccessibleDocumentViewBase::getSupportedServiceNames (void)
491 throw (::com::sun::star::uno::RuntimeException
)
494 return AccessibleContextBase::getSupportedServiceNames ();
501 //===== XTypeProvider =======================================================
503 ::com::sun::star::uno::Sequence
< ::com::sun::star::uno::Type
> SAL_CALL
504 AccessibleDocumentViewBase::getTypes (void)
505 throw (::com::sun::star::uno::RuntimeException
)
509 // Get list of types from the context base implementation, ...
510 uno::Sequence
<uno::Type
> aTypeList (AccessibleContextBase::getTypes());
511 // ... get list of types from component base implementation, ...
512 uno::Sequence
<uno::Type
> aComponentTypeList (AccessibleComponentBase::getTypes());
515 // ...and add the additional type for the component, ...
516 const uno::Type aLangEventListenerType
=
517 ::getCppuType((const uno::Reference
<lang::XEventListener
>*)0);
518 const uno::Type aPropertyChangeListenerType
=
519 ::getCppuType((const uno::Reference
<beans::XPropertyChangeListener
>*)0);
520 const uno::Type aWindowListenerType
=
521 ::getCppuType((const uno::Reference
<awt::XWindowListener
>*)0);
522 const uno::Type aFocusListenerType
=
523 ::getCppuType((const uno::Reference
<awt::XFocusListener
>*)0);
524 const uno::Type aEventBroadcaster
=
525 ::getCppuType((const uno::Reference
<XAccessibleEventBroadcaster
>*)0);
527 // ... and merge them all into one list.
528 sal_Int32
nTypeCount (aTypeList
.getLength()),
529 nComponentTypeCount (aComponentTypeList
.getLength()),
532 aTypeList
.realloc (nTypeCount
+ nComponentTypeCount
+ 5);
534 for (i
=0; i
<nComponentTypeCount
; i
++)
535 aTypeList
[nTypeCount
+ i
] = aComponentTypeList
[i
];
537 aTypeList
[nTypeCount
+ i
++ ] = aLangEventListenerType
;
538 aTypeList
[nTypeCount
+ i
++] = aPropertyChangeListenerType
;
539 aTypeList
[nTypeCount
+ i
++] = aWindowListenerType
;
540 aTypeList
[nTypeCount
+ i
++] = aFocusListenerType
;
541 aTypeList
[nTypeCount
+ i
++] = aEventBroadcaster
;
549 void AccessibleDocumentViewBase::impl_dispose()
551 // Unregister from VCL Window.
552 Window
* pWindow
= maShapeTreeInfo
.GetWindow();
553 if (maWindowLink
.IsSet())
556 pWindow
->RemoveChildEventListener (maWindowLink
);
557 maWindowLink
= Link();
561 DBG_ASSERT (pWindow
, "AccessibleDocumentViewBase::disposing");
564 // Unregister from window.
567 mxWindow
->removeWindowListener (this);
568 mxWindow
->removeFocusListener (this);
572 // Unregister form the model.
574 mxModel
->removeEventListener (
575 static_cast<awt::XWindowListener
*>(this));
577 // Unregister from the controller.
578 if (mxController
.is())
580 uno::Reference
<beans::XPropertySet
> xSet (mxController
, uno::UNO_QUERY
);
582 xSet
->removePropertyChangeListener (
583 OUString (RTL_CONSTASCII_USTRINGPARAM("")),
584 static_cast<beans::XPropertyChangeListener
*>(this));
586 mxController
->removeEventListener (
587 static_cast<awt::XWindowListener
*>(this));
590 // Propagate change of controller down the shape tree.
591 maShapeTreeInfo
.SetControllerBroadcaster (NULL
);
593 // Reset the model reference.
595 // Reset the model reference.
598 maShapeTreeInfo
.SetDocumentWindow (NULL
);
604 //===== XEventListener ======================================================
607 AccessibleDocumentViewBase::disposing (const lang::EventObject
& rEventObject
)
608 throw (::com::sun::star::uno::RuntimeException
)
612 // Register this object as dispose event and document::XEventListener
613 // listener at the model.
615 if ( ! rEventObject
.Source
.is())
617 // Paranoia. Can this really happen?
619 else if (rEventObject
.Source
== mxModel
|| rEventObject
.Source
== mxController
)
625 //===== XPropertyChangeListener =============================================
627 void SAL_CALL
AccessibleDocumentViewBase::propertyChange (const beans::PropertyChangeEvent
& )
628 throw (::com::sun::star::uno::RuntimeException
)
636 //===== XWindowListener =====================================================
639 AccessibleDocumentViewBase::windowResized (const ::com::sun::star::awt::WindowEvent
& )
640 throw (::com::sun::star::uno::RuntimeException
)
645 ViewForwarderChanged (
646 IAccessibleViewForwarderListener::VISIBLE_AREA
,
654 AccessibleDocumentViewBase::windowMoved (const ::com::sun::star::awt::WindowEvent
& )
655 throw (::com::sun::star::uno::RuntimeException
)
660 ViewForwarderChanged (
661 IAccessibleViewForwarderListener::VISIBLE_AREA
,
669 AccessibleDocumentViewBase::windowShown (const ::com::sun::star::lang::EventObject
& )
670 throw (::com::sun::star::uno::RuntimeException
)
675 ViewForwarderChanged (
676 IAccessibleViewForwarderListener::VISIBLE_AREA
,
684 AccessibleDocumentViewBase::windowHidden (const ::com::sun::star::lang::EventObject
& )
685 throw (::com::sun::star::uno::RuntimeException
)
690 ViewForwarderChanged (
691 IAccessibleViewForwarderListener::VISIBLE_AREA
,
698 //===== XFocusListener ==================================================
700 void AccessibleDocumentViewBase::focusGained (const ::com::sun::star::awt::FocusEvent
& e
)
701 throw (::com::sun::star::uno::RuntimeException
)
704 if (e
.Source
== mxWindow
)
708 void AccessibleDocumentViewBase::focusLost (const ::com::sun::star::awt::FocusEvent
& e
)
709 throw (::com::sun::star::uno::RuntimeException
)
712 if (e
.Source
== mxWindow
)
719 //===== protected internal ==================================================
721 // This method is called from the component helper base class while disposing.
722 void SAL_CALL
AccessibleDocumentViewBase::disposing (void)
726 AccessibleContextBase::disposing ();
732 /// Create a name for this view.
734 AccessibleDocumentViewBase::CreateAccessibleName (void)
735 throw (::com::sun::star::uno::RuntimeException
)
737 return ::rtl::OUString (
738 RTL_CONSTASCII_USTRINGPARAM("AccessibleDocumentViewBase"));
744 /** Create a description for this view. Use the model's description or URL
745 if a description is not available.
748 AccessibleDocumentViewBase::CreateAccessibleDescription (void)
749 throw (::com::sun::star::uno::RuntimeException
)
751 rtl::OUString sDescription
;
753 uno::Reference
<lang::XServiceInfo
> xInfo (mxController
, uno::UNO_QUERY
);
756 OUString sFirstService
= xInfo
->getSupportedServiceNames()[0];
757 if (sFirstService
== OUString (
758 RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.DrawingDocumentDrawView")))
760 sDescription
= OUString (RTL_CONSTASCII_USTRINGPARAM("Draw Document"));
763 sDescription
= sFirstService
;
766 sDescription
= OUString (
767 RTL_CONSTASCII_USTRINGPARAM("Accessible Draw Document"));
774 void AccessibleDocumentViewBase::Activated (void)
776 // Empty. Overwrite to do something usefull.
782 void AccessibleDocumentViewBase::Deactivated (void)
784 // Empty. Overwrite to do something usefull.
790 void AccessibleDocumentViewBase::SetAccessibleOLEObject (
791 const Reference
<XAccessible
>& xOLEObject
)
793 // Send child event about removed accessible OLE object if necessary.
794 if (mxAccessibleOLEObject
!= xOLEObject
)
795 if (mxAccessibleOLEObject
.is())
797 AccessibleEventId::CHILD
,
799 uno::makeAny (mxAccessibleOLEObject
));
801 // Assume that the accessible OLE Object disposes itself correctly.
804 ::osl::MutexGuard
aGuard (maMutex
);
805 mxAccessibleOLEObject
= xOLEObject
;
808 // Send child event about new accessible OLE object if necessary.
809 if (mxAccessibleOLEObject
.is())
811 AccessibleEventId::CHILD
,
812 uno::makeAny (mxAccessibleOLEObject
),
819 //===== methods from AccessibleSelectionBase ==================================================
821 // return the member maMutex;
823 AccessibleDocumentViewBase::implGetMutex()
828 // return ourself as context in default case
829 uno::Reference
< XAccessibleContext
>
830 AccessibleDocumentViewBase::implGetAccessibleContext()
831 throw (uno::RuntimeException
)
836 // return sal_False in default case
838 AccessibleDocumentViewBase::implIsSelected( sal_Int32
)
839 throw (uno::RuntimeException
)
844 // return nothing in default case
846 AccessibleDocumentViewBase::implSelect( sal_Int32
, sal_Bool
)
847 throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
)
851 } // end of namespace accessibility