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: ChildrenManagerImpl.hxx,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 #ifndef _SVX_ACCESSIBILITY_CHILDREN_MANAGER_IMPL_HXX
33 #include <svx/IAccessibleViewForwarderListener.hxx>
34 #include <svx/IAccessibleParent.hxx>
35 #include <svx/AccessibleShapeTreeInfo.hxx>
36 #include <svx/AccessibleContextBase.hxx>
37 #include <cppuhelper/compbase2.hxx>
38 #include <vos/mutex.hxx>
40 #include <com/sun/star/drawing/XShape.hpp>
41 #include <com/sun/star/drawing/XShapes.hpp>
42 #include <com/sun/star/document/XEventListener.hpp>
43 #ifndef _COM_SUN_STAR_DOCUMENT_XSELECTIONCHANGELISTENER_HPP_
44 #include <com/sun/star/view/XSelectionChangeListener.hpp>
46 #ifndef _COM_SUN_STAR_ACCESSIBLE_XACCESSIBLE_HPP_
47 #include <com/sun/star/accessibility/XAccessible.hpp>
52 using namespace ::com::sun::star
;
54 namespace accessibility
{
56 class AccessibleShape
;
58 class ChildDescriptor
; // See below for declaration.
59 typedef ::std::vector
<ChildDescriptor
> ChildDescriptorListType
;
61 // Re-using MutexOwner class defined in AccessibleContextBase.hxx
63 /** This class contains the actual implementation of the children manager.
65 <p>It maintains a set of visible accessible shapes in
66 <member>maVisibleChildren</member>. The objects in this list stem from
67 two sources. The first is a list of UNO shapes like the list of shapes
68 in a draw page. A reference to this list is held in
69 <member>maShapeList</member>. Accessible objects for these shapes are
70 created on demand. The list can be replaced by calls to the
71 <member>SetShapeList</member> method. The second source is a list of
72 already accessible objects. It can be modified by calls to the
73 <member>AddAccessibleShape</member> and
74 <member>ClearAccessibleShapeList</member> methods.</p>
76 <p>Each call of the <member>Update</member> method leads to a
77 re-calculation of the visible shapes which then can be queried with the
78 <member>GetChildCount</member> and <member>GetChild</member> methods.
79 Events are send informing all listeners about the removed shapes which are
80 not visible anymore and about the added shapes.</p>
82 <p> The visible area which is used to determine the visibility of the
83 shapes is taken from the view forwarder. Thus, to signal a change of
84 the visible area call <member>ViewForwarderChanged</member>.</p>
86 <p>The children manager adds itself as disposing() listener at every UNO
87 shape it creates an accessible object for so that when the UNO shape
88 passes away it can dispose() the associated accessible object.</p>
92 class ChildrenManagerImpl
94 public cppu::WeakComponentImplHelper2
<
95 ::com::sun::star::document::XEventListener
,
96 ::com::sun::star::view::XSelectionChangeListener
>,
97 public IAccessibleViewForwarderListener
,
98 public IAccessibleParent
101 /** Create a children manager, which manages the children of the given
102 parent. The parent is used for creating accessible objects. The
103 list of shapes for which to create those objects is not derived from
104 the parent and has to be provided seperately by calling one of the
107 The parent of the accessible objects which will be created
108 on demand at some point of time in the future.
110 List of UNO shapes to manage.
111 @param rShapeTreeInfo
112 Bundel of information passed down the shape tree.
114 An accessible context object that is called for fireing events
115 for new and deleted children, i.e. that holds a list of
116 listeners to be informed.
118 ChildrenManagerImpl (const ::com::sun::star::uno::Reference
<
119 ::com::sun::star::accessibility::XAccessible
>& rxParent
,
120 const ::com::sun::star::uno::Reference
<
121 ::com::sun::star::drawing::XShapes
>& rxShapeList
,
122 const AccessibleShapeTreeInfo
& rShapeTreeInfo
,
123 AccessibleContextBase
& rContext
);
125 /** If there still are managed children these are disposed and
128 ~ChildrenManagerImpl (void);
130 /** Do that part of the initialization that you can not or should not do
131 in the constructor like registering at broadcasters.
135 /** Return the number of currently visible accessible children.
137 If there are no children a 0 is returned.
139 long GetChildCount (void) const throw ();
141 /** Return the requested accessible child or throw and
142 IndexOutOfBoundsException if the given index is invalid.
144 Index of the requested child. Call getChildCount for obtaining
145 the number of children.
147 In case of a valid index this method returns a reference to the
148 requested accessible child. This reference is empty if it has
149 not been possible to create the accessible object of the
152 Throws an IndexOutOfBoundsException if the index is not valid.
154 ::com::sun::star::uno::Reference
<
155 ::com::sun::star::accessibility::XAccessible
>
156 GetChild (long nIndex
)
157 throw (::com::sun::star::uno::RuntimeException
,
158 ::com::sun::star::lang::IndexOutOfBoundsException
);
160 /** Return the requested accessible child.
161 @param aChildDescriptor
162 This object contains references to the original shape and its
163 associated accessible object.
165 The index which will be used in getAccessibleIndexInParent of the accessible shape.
167 Returns a reference to the requested accessible child. This
168 reference is empty if it has not been possible to create the
169 accessible object of the corresponding shape.
171 ::com::sun::star::uno::Reference
<
172 ::com::sun::star::accessibility::XAccessible
>
173 GetChild (ChildDescriptor
& aChildDescriptor
,sal_Int32 _nIndex
)
174 throw (::com::sun::star::uno::RuntimeException
);
176 /** Return the requested accessible child given a shape. This method
177 searches the list of descriptors for the one that holds the
178 association of the given shape to the requested accessible object
179 and returns that. If no such descriptor is found that is
180 interpreted so that the specified shape is not visible at the moment.
182 The shape for which to return the associated accessible object.
184 Returns a reference to the requested accessible child. The
185 reference is empty if there is no shape descriptor that
186 associates the shape with an accessible object.
188 ::com::sun::star::uno::Reference
<
189 ::com::sun::star::accessibility::XAccessible
>
190 GetChild (const ::com::sun::star::uno::Reference
<
191 ::com::sun::star::drawing::XShape
>& xShape
)
192 throw (::com::sun::star::uno::RuntimeException
);
194 /** Update the child manager. Take care of a modified set of children
195 and modified visible area. This method can optimize the update
196 process with respect seperate updates of a modified children list
198 @param bCreateNewObjectsOnDemand
199 If </true> then accessible objects associated with the visible
200 shapes are created only when asked for. No event is sent on
201 creation. If </false> then the accessible objects are created
202 before this method returns and events are sent to inform the
203 listeners of the new object.
205 void Update (bool bCreateNewObjectsOnDemand
= true);
207 /** Set the list of UNO shapes to the given list. This removes the old
208 list and does not add to it. The list of accessible shapes that is
209 build up by calls to <member>AddAccessibleShape</member> is not
210 modified. Neither is the list of visible children. Accessible
211 objects are created on demand.
213 The list of UNO shapes that replaces the old list.
215 void SetShapeList (const ::com::sun::star::uno::Reference
<
216 ::com::sun::star::drawing::XShapes
>& xShapeList
);
218 /** Add a accessible shape. This does not modify the list of UNO shapes
219 or the list of visible shapes. Accessible shapes are, at the
220 moment, not tested against the visible area but are always appended
221 to the list of visible children.
223 The new shape that is added to the list of accessible shapes.
225 void AddAccessibleShape (std::auto_ptr
<AccessibleShape
> pShape
);
227 /** Clear the lists of accessible shapes and that of visible accessible
228 shapes. The list of UNO shapes is not modified.
230 void ClearAccessibleShapeList (void);
232 /** Set a new event shape tree info. Call this method to inform the
233 children manager of a change of the info bundle.
234 @param rShapeTreeInfo
235 The new info that replaces the current one.
237 void SetInfo (const AccessibleShapeTreeInfo
& rShapeTreeInfo
);
239 /** Update the SELECTED and FOCUSED states of all visible children
240 according to the given selection. This includes setting
241 <em>and</em> resetting the states.
243 void UpdateSelection (void);
245 /** Return whether one of the shapes managed by this object has
248 Returns <true/> when there is a shape that has the focus and
249 <false/> when there is no such shape.
251 bool HasFocus (void);
253 /** When there is a shape that currently has the focus,
254 i.e. <member>HasFocus()</member> returns <true/> then remove the
255 focus from that shape. Otherwise nothing changes.
257 void RemoveFocus (void);
259 //===== lang::XEventListener ============================================
261 virtual void SAL_CALL
262 disposing (const ::com::sun::star::lang::EventObject
& rEventObject
)
263 throw (::com::sun::star::uno::RuntimeException
);
266 //===== document::XEventListener ========================================
268 virtual void SAL_CALL
269 notifyEvent (const ::com::sun::star::document::EventObject
& rEventObject
)
270 throw (::com::sun::star::uno::RuntimeException
);
273 //===== view::XSelectionChangeListener ==================================
275 virtual void SAL_CALL
276 selectionChanged (const ::com::sun::star::lang::EventObject
& rEvent
)
277 throw (::com::sun::star::uno::RuntimeException
);
280 //===== IAccessibleViewForwarderListener ================================
282 /** Informs this children manager and its children about a change of one
283 (or more) aspect of the view forwarder.
285 A change type of <const>VISIBLE_AREA</const> leads to a call to
286 the <member>Update</memeber> which creates accessible objects of
287 new shapes immediately. Other change types are passed to the
288 visible accessible children without calling
289 <member>Update</memeber>.
290 @param pViewForwarder
291 The modified view forwarder. Use this one from now on.
293 virtual void ViewForwarderChanged (ChangeType aChangeType
,
294 const IAccessibleViewForwarder
* pViewForwarder
);
296 //===== IAccessibleParent ===============================================
298 /** Replace the specified child with a replacement.
300 This child is to be replaced.
302 The replacement for the current child.
304 The returned value indicates wether the replacement has been
305 finished successfully.
307 virtual sal_Bool
ReplaceChild (
308 AccessibleShape
* pCurrentChild
,
309 const ::com::sun::star::uno::Reference
< ::com::sun::star::drawing::XShape
>& _rxShape
,
311 const AccessibleShapeTreeInfo
& _rShapeTreeInfo
312 ) throw (::com::sun::star::uno::RuntimeException
);
316 /** This list holds the descriptors of all currently visible shapes and
317 associated accessible object.
319 <p>With the descriptors it maintains a mapping of shapes to
320 accessible objects. It acts as a cache in that accessible objects
321 are only created on demand and released with every update (where the
322 latter may be optimized by the update methods).<p>
324 <p>The list is realized as a vector because it remains unchanged
325 between updates (i.e. complete rebuilds of the list) and allows a
326 fast (constant time) access to its elements for given indices.</p>
328 ChildDescriptorListType maVisibleChildren
;
330 /** The original list of UNO shapes. The visible shapes are inserted
331 into the list of visible children
332 <member>maVisibleChildren</member>.
334 ::com::sun::star::uno::Reference
<
335 ::com::sun::star::drawing::XShapes
> mxShapeList
;
337 /** This list of additional accessible shapes that can or shall not be
338 created by the shape factory.
340 typedef std::vector
< ::com::sun::star::uno::Reference
<
341 ::com::sun::star::accessibility::XAccessible
> > AccessibleShapeList
;
342 AccessibleShapeList maAccessibleShapes
;
344 /** Rectangle that describes the visible area in which a shape has to lie
345 at least partly, to be accessible through this class. Used to
346 detect changes of the visible area after changes of the view forwarder.
348 Rectangle maVisibleArea
;
350 /** The parent of the shapes. It is used for creating accessible
351 objects for given shapes.
353 ::com::sun::star::uno::Reference
<
354 ::com::sun::star::accessibility::XAccessible
> mxParent
;
356 /** Bundel of information passed down the shape tree.
358 AccessibleShapeTreeInfo maShapeTreeInfo
;
360 /** Reference to an accessible context object that is used to inform its
361 listeners of new and remved children.
363 AccessibleContextBase
& mrContext
;
365 /** This method is called from the component helper base class while
368 virtual void SAL_CALL
disposing (void);
370 /** Experimental: Get the index of the specified accessible object with
371 respect to the list of children maintained by this object.
374 Return the index of the given child or -1 to indicate that the
377 long GetChildIndex (const ::com::sun::star::uno::Reference
<
378 ::com::sun::star::accessibility::XAccessible
>& xChild
) const
379 throw (::com::sun::star::uno::RuntimeException
);
381 void impl_dispose (void);
384 /** Names of new accessible objects are disambiguated with this index.
385 It gets increased every time a new object is created and (at the
388 sal_Int32 mnNewNameIndex
;
390 // Don't use the copy constructor or the assignment operator. They are
391 // not implemented (and are not intended to be).
392 ChildrenManagerImpl (const ChildrenManagerImpl
&);
393 ChildrenManagerImpl
& operator= (const ChildrenManagerImpl
&);
395 /** This member points to the currently focused shape. It is NULL when
396 there is no focused shape.
398 AccessibleShape
* mpFocusedShape
;
400 /** Three helper functions for the <member>Update</member> method.
403 /** Create a list of visible shapes from the list of UNO shapes
404 <member>maShapeList</member> and the list of accessible objects.
406 For every visible shape from the two sources mentioned above one
407 descriptor is added to this list.
409 void CreateListOfVisibleShapes (ChildDescriptorListType
& raChildList
);
411 /** From the old list of (former) visible shapes remove those that
412 are not member of the new list. Send appropriate events for every
414 @param raNewChildList
415 The new list of visible children against which the old one
417 @param raOldChildList
418 The old list of visible children against which the new one
421 void RemoveNonVisibleChildren (
422 const ChildDescriptorListType
& raNewChildList
,
423 ChildDescriptorListType
& raOldChildList
);
425 /** Merge the information that is already known about the visible shapes
426 from the current list into the new list.
428 Information is merged from the current list of visible children
431 void MergeAccessibilityInformation (ChildDescriptorListType
& raChildList
);
433 /** If the visible area has changed then send events that signal a
434 change of their bounding boxes for all shapes that are members of
435 both the current and the new list of visible shapes.
437 Events are sent to all entries of this list that already contain
438 an accessible object.
440 void SendVisibleAreaEvents (ChildDescriptorListType
& raChildList
);
442 /** If children have to be created immediately and not on demand the
443 create the missing accessible objects now.
444 @param raDescriptorList
445 Create an accessible object for every member of this list where
446 that obejct does not already exist.
448 void CreateAccessibilityObjects (ChildDescriptorListType
& raChildList
);
450 /** Add a single shape. Update all relevant data structures
451 accordingly. Use this method instead of <member>Update()</member>
452 when only a single shape has been added.
454 void AddShape (const ::com::sun::star::uno::Reference
<
455 ::com::sun::star::drawing::XShape
>& xShape
);
457 /** Remove a single shape. Update all relevant data structures
458 accordingly. Use this method instead of <member>Update()</member>
459 when only a single shape has been removed.
461 void RemoveShape (const ::com::sun::star::uno::Reference
<
462 ::com::sun::star::drawing::XShape
>& xShape
);
464 /** Add the children manager as dispose listener at the given shape so
465 that the associated accessible object can be disposed when the shape
468 Register at this shape as dispose listener.
470 void RegisterAsDisposeListener (const ::com::sun::star::uno::Reference
<
471 ::com::sun::star::drawing::XShape
>& xShape
);
473 /** Remove the children manager as dispose listener at the given shape
475 Unregister at this shape as dispose listener.
477 void UnregisterAsDisposeListener (const ::com::sun::star::uno::Reference
<
478 ::com::sun::star::drawing::XShape
>& xShape
);
484 /** A child descriptor holds a reference to a UNO shape and the
485 corresponding accessible object. There are two use cases:
486 <ol><li>The accessible object is only created on demand and is then
487 initially empty.</li>
488 <li>There is no UNO shape. The accessible object is given as argument
489 to the constructor.</li>
491 In both cases the child descriptor assumes ownership over the accessible
494 class ChildDescriptor
497 /** Reference to a (partially) visible shape.
499 ::com::sun::star::uno::Reference
<
500 ::com::sun::star::drawing::XShape
> mxShape
;
502 /** The corresponding accessible object. This reference is initially
503 empty and only replaced by a reference to a new object when that is
504 requested from the outside.
506 ::com::sun::star::uno::Reference
<
507 ::com::sun::star::accessibility::XAccessible
> mxAccessibleShape
;
509 /** Return a pointer to the implementation object of the accessible
510 shape of this descriptor.
512 The result is NULL if either the UNO reference to the accessible
513 shape is empty or it can not be transformed into a pointer to
516 AccessibleShape
* GetAccessibleShape (void) const;
518 /** set the index _nIndex at the accessible shape
520 The new index in parent.
522 void setIndexAtAccessibleShape(sal_Int32 _nIndex
);
524 /** This flag is set during the visibility calculation and indicates
525 that at one time in this process an event is sent that informs the
526 listners of the creation of a new accessible object. This flags is
527 not reset afterwards. Don't use it unless you know exactly what you
530 bool mbCreateEventPending
;
532 /** Create a new descriptor for the specified shape with empty reference
533 to accessible object.
535 explicit ChildDescriptor (const ::com::sun::star::uno::Reference
<
536 ::com::sun::star::drawing::XShape
>& xShape
);
538 /** Create a new descriptor for the specified shape with empty reference
539 to the original shape.
541 explicit ChildDescriptor (const ::com::sun::star::uno::Reference
<
542 ::com::sun::star::accessibility::XAccessible
>& rxAccessibleShape
);
544 ~ChildDescriptor (void);
546 /** Dispose the accessible object of this descriptor. If that object
547 does not exist then do nothing.
549 The parent of the accessible object to dispose. A child event
552 void disposeAccessibleObject (AccessibleContextBase
& rParent
);
554 /** Compare two child descriptors. Take into account that a child
555 descriptor may be based on a UNO shape or, already, on an accessible
558 inline bool operator == (const ChildDescriptor
& aDescriptor
) const
561 this == &aDescriptor
||
563 (mxShape
.get() == aDescriptor
.mxShape
.get() ) &&
564 (mxShape
.is() || mxAccessibleShape
.get() == aDescriptor
.mxAccessibleShape
.get())
569 /** The ordering defined by this operator is only used in order to be able
570 to put child descriptors in some STL containers. The ordering itself is
571 not so important, its 'features' are not used.
573 inline bool operator < (const ChildDescriptor
& aDescriptor
) const
575 return (mxShape
.get() < aDescriptor
.mxShape
.get());
582 } // end of namespace accessibility