1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #ifndef INCLUDED_SVX_SOURCE_ACCESSIBILITY_CHILDRENMANAGERIMPL_HXX
21 #define INCLUDED_SVX_SOURCE_ACCESSIBILITY_CHILDRENMANAGERIMPL_HXX
23 #include <svx/IAccessibleViewForwarderListener.hxx>
24 #include <svx/IAccessibleParent.hxx>
25 #include <svx/AccessibleShapeTreeInfo.hxx>
26 #include <editeng/AccessibleContextBase.hxx>
27 #include <cppuhelper/compbase2.hxx>
28 #include <osl/mutex.hxx>
30 #include <com/sun/star/drawing/XShape.hpp>
31 #include <com/sun/star/drawing/XShapes.hpp>
32 #include <com/sun/star/document/XEventListener.hpp>
33 #include <com/sun/star/view/XSelectionChangeListener.hpp>
34 #include <com/sun/star/accessibility/XAccessible.hpp>
36 namespace accessibility
{
38 class AccessibleShape
;
40 class ChildDescriptor
; // See below for declaration.
41 typedef ::std::vector
<ChildDescriptor
> ChildDescriptorListType
;
43 // Re-using MutexOwner class defined in AccessibleContextBase.hxx
45 /** This class contains the actual implementation of the children manager.
47 <p>It maintains a set of visible accessible shapes in
48 <member>maVisibleChildren</member>. The objects in this list stem from
49 two sources. The first is a list of UNO shapes like the list of shapes
50 in a draw page. A reference to this list is held in
51 <member>maShapeList</member>. Accessible objects for these shapes are
52 created on demand. The list can be replaced by calls to the
53 <member>SetShapeList</member> method. The second source is a list of
54 already accessible objects. It can be modified by calls to the
55 <member>AddAccessibleShape</member> and
56 <member>ClearAccessibleShapeList</member> methods.</p>
58 <p>Each call of the <member>Update</member> method leads to a
59 re-calculation of the visible shapes which then can be queried with the
60 <member>GetChildCount</member> and <member>GetChild</member> methods.
61 Events are send informing all listeners about the removed shapes which are
62 not visible anymore and about the added shapes.</p>
64 <p> The visible area which is used to determine the visibility of the
65 shapes is taken from the view forwarder. Thus, to signal a change of
66 the visible area call <member>ViewForwarderChanged</member>.</p>
68 <p>The children manager adds itself as disposing() listener at every UNO
69 shape it creates an accessible object for so that when the UNO shape
70 passes away it can dispose() the associated accessible object.</p>
74 class ChildrenManagerImpl
76 public cppu::WeakComponentImplHelper2
<
77 ::com::sun::star::document::XEventListener
,
78 ::com::sun::star::view::XSelectionChangeListener
>,
79 public IAccessibleViewForwarderListener
,
80 public IAccessibleParent
83 /** Create a children manager, which manages the children of the given
84 parent. The parent is used for creating accessible objects. The
85 list of shapes for which to create those objects is not derived from
86 the parent and has to be provided separately by calling one of the
89 The parent of the accessible objects which will be created
90 on demand at some point of time in the future.
92 List of UNO shapes to manage.
94 Bundel of information passed down the shape tree.
96 An accessible context object that is called for fireing events
97 for new and deleted children, i.e. that holds a list of
98 listeners to be informed.
100 ChildrenManagerImpl (const ::com::sun::star::uno::Reference
<
101 ::com::sun::star::accessibility::XAccessible
>& rxParent
,
102 const ::com::sun::star::uno::Reference
<
103 ::com::sun::star::drawing::XShapes
>& rxShapeList
,
104 const AccessibleShapeTreeInfo
& rShapeTreeInfo
,
105 AccessibleContextBase
& rContext
);
107 /** If there still are managed children these are disposed and
110 virtual ~ChildrenManagerImpl();
112 /** Do that part of the initialization that you can not or should not do
113 in the constructor like registering at broadcasters.
117 /** Return the number of currently visible accessible children.
119 If there are no children a 0 is returned.
121 long GetChildCount() const throw ();
123 ::com::sun::star::uno::Reference
<
124 ::com::sun::star::drawing::XShape
> GetChildShape(long nIndex
)
125 throw (::com::sun::star::uno::RuntimeException
,
126 ::com::sun::star::lang::IndexOutOfBoundsException
);
127 /** Return the requested accessible child or throw and
128 IndexOutOfBoundsException if the given index is invalid.
130 Index of the requested child. Call getChildCount for obtaining
131 the number of children.
133 In case of a valid index this method returns a reference to the
134 requested accessible child. This reference is empty if it has
135 not been possible to create the accessible object of the
138 Throws an IndexOutOfBoundsException if the index is not valid.
140 ::com::sun::star::uno::Reference
<
141 ::com::sun::star::accessibility::XAccessible
>
142 GetChild (long nIndex
)
143 throw (::com::sun::star::uno::RuntimeException
,
144 ::com::sun::star::lang::IndexOutOfBoundsException
);
146 /** Return the requested accessible child.
147 @param aChildDescriptor
148 This object contains references to the original shape and its
149 associated accessible object.
151 The index which will be used in getAccessibleIndexInParent of the accessible shape.
153 Returns a reference to the requested accessible child. This
154 reference is empty if it has not been possible to create the
155 accessible object of the corresponding shape.
157 ::com::sun::star::uno::Reference
<
158 ::com::sun::star::accessibility::XAccessible
>
159 GetChild (ChildDescriptor
& aChildDescriptor
,sal_Int32 _nIndex
)
160 throw (::com::sun::star::uno::RuntimeException
);
162 /** Return the requested accessible child given a shape. This method
163 searches the list of descriptors for the one that holds the
164 association of the given shape to the requested accessible object
165 and returns that. If no such descriptor is found that is
166 interpreted so that the specified shape is not visible at the moment.
168 The shape for which to return the associated accessible object.
170 Returns a reference to the requested accessible child. The
171 reference is empty if there is no shape descriptor that
172 associates the shape with an accessible object.
174 ::com::sun::star::uno::Reference
<
175 ::com::sun::star::accessibility::XAccessible
>
176 GetChild (const ::com::sun::star::uno::Reference
<
177 ::com::sun::star::drawing::XShape
>& xShape
)
178 throw (::com::sun::star::uno::RuntimeException
);
180 /** Update the child manager. Take care of a modified set of children
181 and modified visible area. This method can optimize the update
182 process with respect separate updates of a modified children list
184 @param bCreateNewObjectsOnDemand
185 If </true> then accessible objects associated with the visible
186 shapes are created only when asked for. No event is sent on
187 creation. If </false> then the accessible objects are created
188 before this method returns and events are sent to inform the
189 listeners of the new object.
191 void Update (bool bCreateNewObjectsOnDemand
= true);
193 /** Set the list of UNO shapes to the given list. This removes the old
194 list and does not add to it. The list of accessible shapes that is
195 build up by calls to <member>AddAccessibleShape</member> is not
196 modified. Neither is the list of visible children. Accessible
197 objects are created on demand.
199 The list of UNO shapes that replaces the old list.
201 void SetShapeList (const ::com::sun::star::uno::Reference
<
202 ::com::sun::star::drawing::XShapes
>& xShapeList
);
204 /** Add a accessible shape. This does not modify the list of UNO shapes
205 or the list of visible shapes. Accessible shapes are, at the
206 moment, not tested against the visible area but are always appended
207 to the list of visible children.
209 The new shape that is added to the list of accessible shapes; must
212 void AddAccessibleShape (css::uno::Reference
<css::accessibility::XAccessible
> const & shape
);
214 /** Clear the lists of accessible shapes and that of visible accessible
215 shapes. The list of UNO shapes is not modified.
217 void ClearAccessibleShapeList();
219 /** Set a new event shape tree info. Call this method to inform the
220 children manager of a change of the info bundle.
221 @param rShapeTreeInfo
222 The new info that replaces the current one.
224 void SetInfo (const AccessibleShapeTreeInfo
& rShapeTreeInfo
);
226 /** Update the SELECTED and FOCUSED states of all visible children
227 according to the given selection. This includes setting
228 <em>and</em> resetting the states.
230 void UpdateSelection();
232 /** Return whether one of the shapes managed by this object has
235 Returns <true/> when there is a shape that has the focus and
236 <false/> when there is no such shape.
240 /** When there is a shape that currently has the focus,
241 i.e. <member>HasFocus()</member> returns <true/> then remove the
242 focus from that shape. Otherwise nothing changes.
246 // lang::XEventListener
247 virtual void SAL_CALL
248 disposing (const ::com::sun::star::lang::EventObject
& rEventObject
)
249 throw (::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
251 // document::XEventListener
252 virtual void SAL_CALL
253 notifyEvent (const ::com::sun::star::document::EventObject
& rEventObject
)
254 throw (::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
256 // view::XSelectionChangeListener
257 virtual void SAL_CALL
258 selectionChanged (const ::com::sun::star::lang::EventObject
& rEvent
)
259 throw (::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
261 // IAccessibleViewForwarderListener
262 /** Informs this children manager and its children about a change of one
263 (or more) aspect of the view forwarder.
265 A change type of <const>VISIBLE_AREA</const> leads to a call to
266 the <member>Update</member> which creates accessible objects of
267 new shapes immediately. Other change types are passed to the
268 visible accessible children without calling
269 <member>Update</member>.
270 @param pViewForwarder
271 The modified view forwarder. Use this one from now on.
273 virtual void ViewForwarderChanged (ChangeType aChangeType
,
274 const IAccessibleViewForwarder
* pViewForwarder
) SAL_OVERRIDE
;
277 /** Replace the specified child with a replacement.
279 This child is to be replaced.
281 The replacement for the current child.
283 The returned value indicates whether the replacement has been
284 finished successfully.
286 virtual bool ReplaceChild (
287 AccessibleShape
* pCurrentChild
,
288 const ::com::sun::star::uno::Reference
< ::com::sun::star::drawing::XShape
>& _rxShape
,
290 const AccessibleShapeTreeInfo
& _rShapeTreeInfo
291 ) throw (::com::sun::star::uno::RuntimeException
) SAL_OVERRIDE
;
293 // Add the impl method for IAccessibleParent interface
294 virtual AccessibleControlShape
* GetAccControlShapeFromModel
295 (::com::sun::star::beans::XPropertySet
* pSet
)
296 throw (::com::sun::star::uno::RuntimeException
) SAL_OVERRIDE
;
297 virtual ::com::sun::star::uno::Reference
<
298 ::com::sun::star::accessibility::XAccessible
>
299 GetAccessibleCaption (const ::com::sun::star::uno::Reference
<
300 ::com::sun::star::drawing::XShape
>& xShape
)
301 throw (::com::sun::star::uno::RuntimeException
) SAL_OVERRIDE
;
303 /** This list holds the descriptors of all currently visible shapes and
304 associated accessible object.
306 <p>With the descriptors it maintains a mapping of shapes to
307 accessible objects. It acts as a cache in that accessible objects
308 are only created on demand and released with every update (where the
309 latter may be optimized by the update methods).<p>
311 <p>The list is realized as a vector because it remains unchanged
312 between updates (i.e. complete rebuilds of the list) and allows a
313 fast (constant time) access to its elements for given indices.</p>
315 ChildDescriptorListType maVisibleChildren
;
317 /** The original list of UNO shapes. The visible shapes are inserted
318 into the list of visible children
319 <member>maVisibleChildren</member>.
321 ::com::sun::star::uno::Reference
<
322 ::com::sun::star::drawing::XShapes
> mxShapeList
;
324 /** This list of additional accessible shapes that can or shall not be
325 created by the shape factory.
327 typedef std::vector
< ::com::sun::star::uno::Reference
<
328 ::com::sun::star::accessibility::XAccessible
> > AccessibleShapeList
;
329 AccessibleShapeList maAccessibleShapes
;
331 /** Rectangle that describes the visible area in which a shape has to lie
332 at least partly, to be accessible through this class. Used to
333 detect changes of the visible area after changes of the view forwarder.
335 Rectangle maVisibleArea
;
337 /** The parent of the shapes. It is used for creating accessible
338 objects for given shapes.
340 ::com::sun::star::uno::Reference
<
341 ::com::sun::star::accessibility::XAccessible
> mxParent
;
343 /** Bundel of information passed down the shape tree.
345 AccessibleShapeTreeInfo maShapeTreeInfo
;
347 /** Reference to an accessible context object that is used to inform its
348 listeners of new and remved children.
350 AccessibleContextBase
& mrContext
;
352 /** This method is called from the component helper base class while
355 virtual void SAL_CALL
disposing() SAL_OVERRIDE
;
360 /** Names of new accessible objects are disambiguated with this index.
361 It gets increased every time a new object is created and (at the
364 sal_Int32 mnNewNameIndex
;
366 ChildrenManagerImpl (const ChildrenManagerImpl
&) SAL_DELETED_FUNCTION
;
367 ChildrenManagerImpl
& operator= (const ChildrenManagerImpl
&) SAL_DELETED_FUNCTION
;
369 /** This member points to the currently focused shape. It is NULL when
370 there is no focused shape.
372 AccessibleShape
* mpFocusedShape
;
374 /** Three helper functions for the <member>Update</member> method.
377 /** Create a list of visible shapes from the list of UNO shapes
378 <member>maShapeList</member> and the list of accessible objects.
380 For every visible shape from the two sources mentioned above one
381 descriptor is added to this list.
383 void CreateListOfVisibleShapes (ChildDescriptorListType
& raChildList
);
385 /** From the old list of (former) visible shapes remove those that
386 are not member of the new list. Send appropriate events for every
388 @param raNewChildList
389 The new list of visible children against which the old one
391 @param raOldChildList
392 The old list of visible children against which the new one
395 void RemoveNonVisibleChildren (
396 const ChildDescriptorListType
& raNewChildList
,
397 ChildDescriptorListType
& raOldChildList
);
399 /** Merge the information that is already known about the visible shapes
400 from the current list into the new list.
402 Information is merged from the current list of visible children
405 void MergeAccessibilityInformation (ChildDescriptorListType
& raChildList
);
407 /** If the visible area has changed then send events that signal a
408 change of their bounding boxes for all shapes that are members of
409 both the current and the new list of visible shapes.
411 Events are sent to all entries of this list that already contain
412 an accessible object.
414 void SendVisibleAreaEvents (ChildDescriptorListType
& raChildList
);
416 /** If children have to be created immediately and not on demand the
417 create the missing accessible objects now.
418 @param raDescriptorList
419 Create an accessible object for every member of this list where
420 that object does not already exist.
422 void CreateAccessibilityObjects (ChildDescriptorListType
& raChildList
);
424 /** Add a single shape. Update all relevant data structures
425 accordingly. Use this method instead of <member>Update()</member>
426 when only a single shape has been added.
428 void AddShape (const ::com::sun::star::uno::Reference
<
429 ::com::sun::star::drawing::XShape
>& xShape
);
431 /** Remove a single shape. Update all relevant data structures
432 accordingly. Use this method instead of <member>Update()</member>
433 when only a single shape has been removed.
435 void RemoveShape (const ::com::sun::star::uno::Reference
<
436 ::com::sun::star::drawing::XShape
>& xShape
);
438 /** Add the children manager as dispose listener at the given shape so
439 that the associated accessible object can be disposed when the shape
442 Register at this shape as dispose listener.
444 void RegisterAsDisposeListener (const ::com::sun::star::uno::Reference
<
445 ::com::sun::star::drawing::XShape
>& xShape
);
447 /** Remove the children manager as dispose listener at the given shape
449 Unregister at this shape as dispose listener.
451 void UnregisterAsDisposeListener (const ::com::sun::star::uno::Reference
<
452 ::com::sun::star::drawing::XShape
>& xShape
);
458 /** A child descriptor holds a reference to a UNO shape and the
459 corresponding accessible object. There are two use cases:
460 <ol><li>The accessible object is only created on demand and is then
461 initially empty.</li>
462 <li>There is no UNO shape. The accessible object is given as argument
463 to the constructor.</li>
465 In both cases the child descriptor assumes ownership over the accessible
468 class ChildDescriptor
471 /** Reference to a (partially) visible shape.
473 ::com::sun::star::uno::Reference
<
474 ::com::sun::star::drawing::XShape
> mxShape
;
476 /** The corresponding accessible object. This reference is initially
477 empty and only replaced by a reference to a new object when that is
478 requested from the outside.
480 ::com::sun::star::uno::Reference
<
481 ::com::sun::star::accessibility::XAccessible
> mxAccessibleShape
;
483 /** Return a pointer to the implementation object of the accessible
484 shape of this descriptor.
486 The result is NULL if either the UNO reference to the accessible
487 shape is empty or it can not be transformed into a pointer to
490 AccessibleShape
* GetAccessibleShape() const;
492 /** set the index _nIndex at the accessible shape
494 The new index in parent.
496 void setIndexAtAccessibleShape(sal_Int32 _nIndex
);
498 /** This flag is set during the visibility calculation and indicates
499 that at one time in this process an event is sent that informs the
500 listeners of the creation of a new accessible object. This flags is
501 not reset afterwards. Don't use it unless you know exactly what you
504 bool mbCreateEventPending
;
506 /** Create a new descriptor for the specified shape with empty reference
507 to accessible object.
509 explicit ChildDescriptor (const ::com::sun::star::uno::Reference
<
510 ::com::sun::star::drawing::XShape
>& xShape
);
512 /** Create a new descriptor for the specified shape with empty reference
513 to the original shape.
515 explicit ChildDescriptor (const ::com::sun::star::uno::Reference
<
516 ::com::sun::star::accessibility::XAccessible
>& rxAccessibleShape
);
520 /** Dispose the accessible object of this descriptor. If that object
521 does not exist then do nothing.
523 The parent of the accessible object to dispose. A child event
526 void disposeAccessibleObject (AccessibleContextBase
& rParent
);
528 /** Compare two child descriptors. Take into account that a child
529 descriptor may be based on a UNO shape or, already, on an accessible
532 inline bool operator == (const ChildDescriptor
& aDescriptor
) const
535 this == &aDescriptor
||
537 (mxShape
.get() == aDescriptor
.mxShape
.get() ) &&
538 (mxShape
.is() || mxAccessibleShape
.get() == aDescriptor
.mxAccessibleShape
.get())
543 /** The ordering defined by this operator is only used in order to be able
544 to put child descriptors in some STL containers. The ordering itself is
545 not so important, its 'features' are not used.
547 inline bool operator < (const ChildDescriptor
& aDescriptor
) const
549 return (mxShape
.get() < aDescriptor
.mxShape
.get());
556 } // end of namespace accessibility
560 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */