bump product version to 7.2.5.1
[LibreOffice.git] / svx / source / accessibility / ChildrenManagerImpl.hxx
blob5520a4947b32dc6a86bad0b2c02ce89f88768981
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/compbase.hxx>
28 #include <tools/gen.hxx>
29 #include <vector>
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 sent 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>
72 @see ChildrenManager
74 class ChildrenManagerImpl final
75 : public MutexOwner,
76 public cppu::WeakComponentImplHelper<
77 css::document::XEventListener,
78 css::view::XSelectionChangeListener>,
79 public IAccessibleViewForwarderListener,
80 public IAccessibleParent
82 public:
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
87 update methods.
88 @param rxParent
89 The parent of the accessible objects which will be created
90 on demand at some point of time in the future.
91 @param rxShapeList
92 List of UNO shapes to manage.
93 @param rShapeTreeInfo
94 Bundle of information passed down the shape tree.
95 @param rContext
96 An accessible context object that is called for firing events
97 for new and deleted children, i.e. that holds a list of
98 listeners to be informed.
100 ChildrenManagerImpl (const css::uno::Reference<css::accessibility::XAccessible>& rxParent,
101 const css::uno::Reference<css::drawing::XShapes>& rxShapeList,
102 const AccessibleShapeTreeInfo& rShapeTreeInfo,
103 AccessibleContextBase& rContext);
105 /** If there still are managed children these are disposed and
106 released.
108 virtual ~ChildrenManagerImpl() override;
110 /** Do that part of the initialization that you can not or should not do
111 in the constructor like registering at broadcasters.
113 void Init();
115 /** Return the number of currently visible accessible children.
116 @return
117 If there are no children a 0 is returned.
119 tools::Long GetChildCount() const noexcept;
121 /// @throws css::uno::RuntimeException
122 /// @throws css::lang::IndexOutOfBoundsException
123 css::uno::Reference<css::drawing::XShape> GetChildShape(tools::Long nIndex);
124 /** Return the requested accessible child or throw and
125 IndexOutOfBoundsException if the given index is invalid.
126 @param nIndex
127 Index of the requested child. Call getChildCount for obtaining
128 the number of children.
129 @return
130 In case of a valid index this method returns a reference to the
131 requested accessible child. This reference is empty if it has
132 not been possible to create the accessible object of the
133 corresponding shape.
134 @throws
135 Throws an IndexOutOfBoundsException if the index is not valid.
137 css::uno::Reference<css::accessibility::XAccessible>
138 GetChild (tools::Long nIndex);
140 /** Return the requested accessible child.
141 @param aChildDescriptor
142 This object contains references to the original shape and its
143 associated accessible object.
144 @param _nIndex
145 The index which will be used in getAccessibleIndexInParent of the accessible shape.
146 @return
147 Returns a reference to the requested accessible child. This
148 reference is empty if it has not been possible to create the
149 accessible object of the corresponding shape.
150 @throws css::uno::RuntimeException
152 css::uno::Reference<css::accessibility::XAccessible>
153 GetChild (ChildDescriptor& aChildDescriptor,sal_Int32 _nIndex);
155 /** Update the child manager. Take care of a modified set of children
156 and modified visible area. This method can optimize the update
157 process with respect separate updates of a modified children list
158 and visible area.
159 @param bCreateNewObjectsOnDemand
160 If </true> then accessible objects associated with the visible
161 shapes are created only when asked for. No event is sent on
162 creation. If </false> then the accessible objects are created
163 before this method returns and events are sent to inform the
164 listeners of the new object.
166 void Update (bool bCreateNewObjectsOnDemand);
168 /** Set the list of UNO shapes to the given list. This removes the old
169 list and does not add to it. The list of accessible shapes that is
170 build up by calls to <member>AddAccessibleShape</member> is not
171 modified. Neither is the list of visible children. Accessible
172 objects are created on demand.
173 @param xShapeList
174 The list of UNO shapes that replaces the old list.
176 void SetShapeList (const css::uno::Reference<css::drawing::XShapes>& xShapeList);
178 /** Add an accessible shape. This does not modify the list of UNO shapes
179 or the list of visible shapes. Accessible shapes are, at the
180 moment, not tested against the visible area but are always appended
181 to the list of visible children.
182 @param shape
183 The new shape that is added to the list of accessible shapes; must
184 be non-null.
186 void AddAccessibleShape (css::uno::Reference<css::accessibility::XAccessible> const & shape);
188 /** Clear the lists of accessible shapes and that of visible accessible
189 shapes. The list of UNO shapes is not modified.
191 void ClearAccessibleShapeList();
193 /** Set a new event shape tree info. Call this method to inform the
194 children manager of a change of the info bundle.
195 @param rShapeTreeInfo
196 The new info that replaces the current one.
198 void SetInfo (const AccessibleShapeTreeInfo& rShapeTreeInfo);
200 /** Update the SELECTED and FOCUSED states of all visible children
201 according to the given selection. This includes setting
202 <em>and</em> resetting the states.
204 void UpdateSelection();
206 /** Return whether one of the shapes managed by this object has
207 currently the focus.
208 @return
209 Returns <true/> when there is a shape that has the focus and
210 <false/> when there is no such shape.
212 bool HasFocus() const;
214 /** When there is a shape that currently has the focus,
215 i.e. <member>HasFocus()</member> returns <true/> then remove the
216 focus from that shape. Otherwise nothing changes.
218 void RemoveFocus();
220 // lang::XEventListener
221 virtual void SAL_CALL
222 disposing (const css::lang::EventObject& rEventObject) override;
224 // document::XEventListener
225 virtual void SAL_CALL
226 notifyEvent (const css::document::EventObject& rEventObject) override;
228 // view::XSelectionChangeListener
229 virtual void SAL_CALL
230 selectionChanged (const css::lang::EventObject& rEvent) override;
232 // IAccessibleViewForwarderListener
233 /** Informs this children manager and its children about a change of one
234 (or more) aspect of the view forwarder.
235 @param aChangeType
236 A change type of <const>VISIBLE_AREA</const> leads to a call to
237 the <member>Update</member> which creates accessible objects of
238 new shapes immediately. Other change types are passed to the
239 visible accessible children without calling
240 <member>Update</member>.
241 @param pViewForwarder
242 The modified view forwarder. Use this one from now on.
244 virtual void ViewForwarderChanged() override;
246 // IAccessibleParent
247 /** Replace the specified child with a replacement.
248 @param pCurrentChild
249 This child is to be replaced.
250 @param pReplacement
251 The replacement for the current child.
252 @return
253 The returned value indicates whether the replacement has been
254 finished successfully.
256 virtual bool ReplaceChild (
257 AccessibleShape* pCurrentChild,
258 const css::uno::Reference< css::drawing::XShape >& _rxShape,
259 const tools::Long _nIndex,
260 const AccessibleShapeTreeInfo& _rShapeTreeInfo
261 ) override;
263 // Add the impl method for IAccessibleParent interface
264 virtual AccessibleControlShape* GetAccControlShapeFromModel
265 (css::beans::XPropertySet* pSet) override;
266 virtual css::uno::Reference<css::accessibility::XAccessible>
267 GetAccessibleCaption (const css::uno::Reference<css::drawing::XShape>& xShape) override;
269 private:
270 /** This list holds the descriptors of all currently visible shapes and
271 associated accessible object.
273 <p>With the descriptors it maintains a mapping of shapes to
274 accessible objects. It acts as a cache in that accessible objects
275 are only created on demand and released with every update (where the
276 latter may be optimized by the update methods).<p>
278 <p>The list is realized as a vector because it remains unchanged
279 between updates (i.e. complete rebuilds of the list) and allows a
280 fast (constant time) access to its elements for given indices.</p>
282 ChildDescriptorListType maVisibleChildren;
284 /** The original list of UNO shapes. The visible shapes are inserted
285 into the list of visible children
286 <member>maVisibleChildren</member>.
288 css::uno::Reference<css::drawing::XShapes> mxShapeList;
290 /** This list of additional accessible shapes that can or shall not be
291 created by the shape factory.
293 typedef std::vector< css::uno::Reference< css::accessibility::XAccessible> > AccessibleShapeList;
294 AccessibleShapeList maAccessibleShapes;
296 /** Rectangle that describes the visible area in which a shape has to lie
297 at least partly, to be accessible through this class. Used to
298 detect changes of the visible area after changes of the view forwarder.
300 tools::Rectangle maVisibleArea;
302 /** The parent of the shapes. It is used for creating accessible
303 objects for given shapes.
305 css::uno::Reference<css::accessibility::XAccessible> mxParent;
307 /** Bundle of information passed down the shape tree.
309 AccessibleShapeTreeInfo maShapeTreeInfo;
311 /** Reference to an accessible context object that is used to inform its
312 listeners of new and removed children.
314 AccessibleContextBase& mrContext;
316 /** This method is called from the component helper base class while
317 disposing.
319 virtual void SAL_CALL disposing() override;
321 void impl_dispose();
323 ChildrenManagerImpl (const ChildrenManagerImpl&) = delete;
324 ChildrenManagerImpl& operator= (const ChildrenManagerImpl&) = delete;
326 /** This member points to the currently focused shape. It is NULL when
327 there is no focused shape.
329 AccessibleShape* mpFocusedShape;
331 /** Three helper functions for the <member>Update</member> method.
334 /** Create a list of visible shapes from the list of UNO shapes
335 <member>maShapeList</member> and the list of accessible objects.
336 @param raChildList
337 For every visible shape from the two sources mentioned above one
338 descriptor is added to this list.
340 void CreateListOfVisibleShapes (ChildDescriptorListType& raChildList);
342 /** From the old list of (former) visible shapes remove those that
343 are not member of the new list. Send appropriate events for every
344 such shape.
345 @param raNewChildList
346 The new list of visible children against which the old one
347 is compared.
348 @param raOldChildList
349 The old list of visible children against which the new one
350 is compared.
352 void RemoveNonVisibleChildren (
353 const ChildDescriptorListType& raNewChildList,
354 ChildDescriptorListType& raOldChildList);
356 /** Merge the information that is already known about the visible shapes
357 from the current list into the new list.
358 @param raChildList
359 Information is merged from the current list of visible children
360 to this list.
362 void MergeAccessibilityInformation (ChildDescriptorListType& raChildList);
364 /** If the visible area has changed then send events that signal a
365 change of their bounding boxes for all shapes that are members of
366 both the current and the new list of visible shapes.
367 @param raChildList
368 Events are sent to all entries of this list that already contain
369 an accessible object.
371 static void SendVisibleAreaEvents (ChildDescriptorListType& raChildList);
373 /** If children have to be created immediately and not on demand the
374 create the missing accessible objects now.
375 @param raDescriptorList
376 Create an accessible object for every member of this list where
377 that object does not already exist.
379 void CreateAccessibilityObjects (ChildDescriptorListType& raChildList);
381 /** Add a single shape. Update all relevant data structures
382 accordingly. Use this method instead of <member>Update()</member>
383 when only a single shape has been added.
385 void AddShape (const css::uno::Reference<css::drawing::XShape>& xShape);
387 /** Remove a single shape. Update all relevant data structures
388 accordingly. Use this method instead of <member>Update()</member>
389 when only a single shape has been removed.
391 void RemoveShape (const css::uno::Reference<css::drawing::XShape>& xShape);
393 /** Add the children manager as dispose listener at the given shape so
394 that the associated accessible object can be disposed when the shape
395 is disposed.
396 @param xShape
397 Register at this shape as dispose listener.
399 void RegisterAsDisposeListener (const css::uno::Reference<css::drawing::XShape>& xShape);
401 /** Remove the children manager as dispose listener at the given shape
402 @param xShape
403 Unregister at this shape as dispose listener.
405 void UnregisterAsDisposeListener (const css::uno::Reference<css::drawing::XShape>& xShape);
409 /** A child descriptor holds a reference to a UNO shape and the
410 corresponding accessible object. There are two use cases:
411 <ol><li>The accessible object is only created on demand and is then
412 initially empty.</li>
413 <li>There is no UNO shape. The accessible object is given as argument
414 to the constructor.</li>
415 </ol>
416 In both cases the child descriptor assumes ownership over the accessible
417 object.
419 class ChildDescriptor
421 public:
422 /** Reference to a (partially) visible shape.
424 css::uno::Reference<css::drawing::XShape> mxShape;
426 /** The corresponding accessible object. This reference is initially
427 empty and only replaced by a reference to a new object when that is
428 requested from the outside.
430 css::uno::Reference<css::accessibility::XAccessible> mxAccessibleShape;
432 /** Return a pointer to the implementation object of the accessible
433 shape of this descriptor.
434 @return
435 The result is NULL if either the UNO reference to the accessible
436 shape is empty or it can not be transformed into a pointer to
437 the desired class.
439 AccessibleShape* GetAccessibleShape() const;
441 /** set the index _nIndex at the accessible shape
442 @param _nIndex
443 The new index in parent.
445 void setIndexAtAccessibleShape(sal_Int32 _nIndex);
447 /** This flag is set during the visibility calculation and indicates
448 that at one time in this process an event is sent that informs the
449 listeners of the creation of a new accessible object. This flags is
450 not reset afterwards. Don't use it unless you know exactly what you
451 are doing.
453 bool mbCreateEventPending;
455 /** Create a new descriptor for the specified shape with empty reference
456 to accessible object.
458 explicit ChildDescriptor (const css::uno::Reference<css::drawing::XShape>& xShape);
460 /** Create a new descriptor for the specified shape with empty reference
461 to the original shape.
463 explicit ChildDescriptor (const css::uno::Reference<css::accessibility::XAccessible>& rxAccessibleShape);
465 /** Dispose the accessible object of this descriptor. If that object
466 does not exist then do nothing.
467 @param rParent
468 The parent of the accessible object to dispose. A child event
469 is sent in its name.
471 void disposeAccessibleObject (AccessibleContextBase& rParent);
473 /** Compare two child descriptors. Take into account that a child
474 descriptor may be based on a UNO shape or, already, on an accessible
475 shape.
477 bool operator == (const ChildDescriptor& aDescriptor) const
479 return (
480 this == &aDescriptor ||
482 (mxShape.get() == aDescriptor.mxShape.get() ) &&
483 (mxShape.is() || mxAccessibleShape.get() == aDescriptor.mxAccessibleShape.get())
491 } // end of namespace accessibility
493 #endif
495 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */