tdf#130857 qt weld: Implement QtInstanceWidget::get_text_height
[LibreOffice.git] / svx / source / accessibility / ChildrenManagerImpl.hxx
blob121a893bfea26ca2b39301ce9609e149d120ce2b
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/AccessibleShape.hxx>
24 #include <svx/IAccessibleViewForwarderListener.hxx>
25 #include <svx/IAccessibleParent.hxx>
26 #include <svx/AccessibleShapeTreeInfo.hxx>
27 #include <editeng/AccessibleContextBase.hxx>
28 #include <comphelper/compbase.hxx>
29 #include <tools/gen.hxx>
30 #include <vector>
31 #include <com/sun/star/drawing/XShape.hpp>
32 #include <com/sun/star/drawing/XShapes.hpp>
33 #include <com/sun/star/document/XEventListener.hpp>
34 #include <com/sun/star/view/XSelectionChangeListener.hpp>
35 #include <com/sun/star/accessibility/XAccessible.hpp>
37 namespace accessibility {
39 class ChildDescriptor; // See below for declaration.
40 typedef ::std::vector<ChildDescriptor> ChildDescriptorListType;
42 // Re-using MutexOwner class defined in AccessibleContextBase.hxx
44 /** This class contains the actual implementation of the children manager.
46 <p>It maintains a set of visible accessible shapes in
47 <member>maVisibleChildren</member>. The objects in this list stem from
48 two sources. The first is a list of UNO shapes like the list of shapes
49 in a draw page. A reference to this list is held in
50 <member>maShapeList</member>. Accessible objects for these shapes are
51 created on demand. The list can be replaced by calls to the
52 <member>SetShapeList</member> method. The second source is a list of
53 already accessible objects. It can be modified by calls to the
54 <member>AddAccessibleShape</member> and
55 <member>ClearAccessibleShapeList</member> methods.</p>
57 <p>Each call of the <member>Update</member> method leads to a
58 re-calculation of the visible shapes which then can be queried with the
59 <member>GetChildCount</member> and <member>GetChild</member> methods.
60 Events are sent informing all listeners about the removed shapes which are
61 not visible anymore and about the added shapes.</p>
63 <p> The visible area which is used to determine the visibility of the
64 shapes is taken from the view forwarder. Thus, to signal a change of
65 the visible area call <member>ViewForwarderChanged</member>.</p>
67 <p>The children manager adds itself as disposing() listener at every UNO
68 shape it creates an accessible object for so that when the UNO shape
69 passes away it can dispose() the associated accessible object.</p>
71 @see ChildrenManager
73 class ChildrenManagerImpl final
74 : public comphelper::WeakComponentImplHelper<
75 css::document::XEventListener,
76 css::view::XSelectionChangeListener>,
77 public IAccessibleViewForwarderListener,
78 public IAccessibleParent
80 public:
81 /** Create a children manager, which manages the children of the given
82 parent. The parent is used for creating accessible objects. The
83 list of shapes for which to create those objects is not derived from
84 the parent and has to be provided separately by calling one of the
85 update methods.
86 @param rxParent
87 The parent of the accessible objects which will be created
88 on demand at some point of time in the future.
89 @param rxShapeList
90 List of UNO shapes to manage.
91 @param rShapeTreeInfo
92 Bundle of information passed down the shape tree.
93 @param rContext
94 An accessible context object that is called for firing events
95 for new and deleted children, i.e. that holds a list of
96 listeners to be informed.
98 ChildrenManagerImpl (css::uno::Reference<css::accessibility::XAccessible> xParent,
99 css::uno::Reference<css::drawing::XShapes> xShapeList,
100 const AccessibleShapeTreeInfo& rShapeTreeInfo,
101 AccessibleContextBase& rContext);
103 /** If there still are managed children these are disposed and
104 released.
106 virtual ~ChildrenManagerImpl() override;
108 /** Do that part of the initialization that you can not or should not do
109 in the constructor like registering at broadcasters.
111 void Init();
113 /** Return the number of currently visible accessible children.
114 @return
115 If there are no children a 0 is returned.
117 sal_Int64 GetChildCount() const noexcept;
119 /// @throws css::uno::RuntimeException
120 /// @throws css::lang::IndexOutOfBoundsException
121 const css::uno::Reference<css::drawing::XShape>& GetChildShape(sal_Int64 nIndex);
122 /** Return the requested accessible child or throw and
123 IndexOutOfBoundsException if the given index is invalid.
124 @param nIndex
125 Index of the requested child. Call getChildCount for obtaining
126 the number of children.
127 @return
128 In case of a valid index this method returns a reference to the
129 requested accessible child. This reference is empty if it has
130 not been possible to create the accessible object of the
131 corresponding shape.
132 @throws
133 Throws an IndexOutOfBoundsException if the index is not valid.
135 css::uno::Reference<css::accessibility::XAccessible>
136 GetChild (sal_Int64 nIndex);
138 /** Return the requested accessible child.
139 @param aChildDescriptor
140 This object contains references to the original shape and its
141 associated accessible object.
142 @param _nIndex
143 The index which will be used in getAccessibleIndexInParent of the accessible shape.
144 @return
145 Returns a reference to the requested accessible child. This
146 reference is empty if it has not been possible to create the
147 accessible object of the corresponding shape.
148 @throws css::uno::RuntimeException
150 css::uno::Reference<css::accessibility::XAccessible>
151 GetChild (ChildDescriptor& aChildDescriptor,sal_Int32 _nIndex);
153 /** Update the child manager. Take care of a modified set of children
154 and modified visible area. This method can optimize the update
155 process with respect separate updates of a modified children list
156 and visible area.
157 @param bCreateNewObjectsOnDemand
158 If </true> then accessible objects associated with the visible
159 shapes are created only when asked for. No event is sent on
160 creation. If </false> then the accessible objects are created
161 before this method returns and events are sent to inform the
162 listeners of the new object.
164 void Update (bool bCreateNewObjectsOnDemand);
166 /** Set the list of UNO shapes to the given list. This removes the old
167 list and does not add to it. The list of accessible shapes that is
168 build up by calls to <member>AddAccessibleShape</member> is not
169 modified. Neither is the list of visible children. Accessible
170 objects are created on demand.
171 @param xShapeList
172 The list of UNO shapes that replaces the old list.
174 void SetShapeList (const css::uno::Reference<css::drawing::XShapes>& xShapeList);
176 /** Add an accessible shape. This does not modify the list of UNO shapes
177 or the list of visible shapes. Accessible shapes are, at the
178 moment, not tested against the visible area but are always appended
179 to the list of visible children.
180 @param shape
181 The new shape that is added to the list of accessible shapes; must
182 be non-null.
184 void AddAccessibleShape (rtl::Reference<AccessibleShape> const & shape);
186 /** Clear the lists of accessible shapes and that of visible accessible
187 shapes. The list of UNO shapes is not modified.
189 void ClearAccessibleShapeList();
191 /** Set a new event shape tree info. Call this method to inform the
192 children manager of a change of the info bundle.
193 @param rShapeTreeInfo
194 The new info that replaces the current one.
196 void SetInfo (const AccessibleShapeTreeInfo& rShapeTreeInfo);
198 /** Update the SELECTED and FOCUSED states of all visible children
199 according to the given selection. This includes setting
200 <em>and</em> resetting the states.
202 void UpdateSelection();
204 /** Return whether one of the shapes managed by this object has
205 currently the focus.
206 @return
207 Returns <true/> when there is a shape that has the focus and
208 <false/> when there is no such shape.
210 bool HasFocus() const;
212 /** When there is a shape that currently has the focus,
213 i.e. <member>HasFocus()</member> returns <true/> then remove the
214 focus from that shape. Otherwise nothing changes.
216 void RemoveFocus();
218 // lang::XEventListener
219 virtual void SAL_CALL
220 disposing (const css::lang::EventObject& rEventObject) override;
222 // document::XEventListener
223 virtual void SAL_CALL
224 notifyEvent (const css::document::EventObject& rEventObject) override;
226 // view::XSelectionChangeListener
227 virtual void SAL_CALL
228 selectionChanged (const css::lang::EventObject& rEvent) override;
230 // IAccessibleViewForwarderListener
231 /** Informs this children manager and its children about a change of one
232 (or more) aspect of the view forwarder.
233 @param aChangeType
234 A change type of <const>VISIBLE_AREA</const> leads to a call to
235 the <member>Update</member> which creates accessible objects of
236 new shapes immediately. Other change types are passed to the
237 visible accessible children without calling
238 <member>Update</member>.
239 @param pViewForwarder
240 The modified view forwarder. Use this one from now on.
242 virtual void ViewForwarderChanged() override;
244 // IAccessibleParent
245 /** Replace the specified child with a replacement.
246 @param pCurrentChild
247 This child is to be replaced.
248 @param pReplacement
249 The replacement for the current child.
250 @return
251 The returned value indicates whether the replacement has been
252 finished successfully.
254 virtual bool ReplaceChild (
255 AccessibleShape* pCurrentChild,
256 const css::uno::Reference< css::drawing::XShape >& _rxShape,
257 const tools::Long _nIndex,
258 const AccessibleShapeTreeInfo& _rShapeTreeInfo
259 ) override;
261 // Add the impl method for IAccessibleParent interface
262 virtual AccessibleControlShape* GetAccControlShapeFromModel
263 (css::beans::XPropertySet* pSet) override;
264 virtual css::uno::Reference<css::accessibility::XAccessible>
265 GetAccessibleCaption (const css::uno::Reference<css::drawing::XShape>& xShape) override;
267 private:
268 /** This list holds the descriptors of all currently visible shapes and
269 associated accessible object.
271 <p>With the descriptors it maintains a mapping of shapes to
272 accessible objects. It acts as a cache in that accessible objects
273 are only created on demand and released with every update (where the
274 latter may be optimized by the update methods).<p>
276 <p>The list is realized as a vector because it remains unchanged
277 between updates (i.e. complete rebuilds of the list) and allows a
278 fast (constant time) access to its elements for given indices.</p>
280 ChildDescriptorListType maVisibleChildren;
282 /** The original list of UNO shapes. The visible shapes are inserted
283 into the list of visible children
284 <member>maVisibleChildren</member>.
286 css::uno::Reference<css::drawing::XShapes> mxShapeList;
288 /** This list of additional accessible shapes that can or shall not be
289 created by the shape factory.
291 typedef std::vector< rtl::Reference< AccessibleShape> > AccessibleShapeList;
292 AccessibleShapeList maAccessibleShapes;
294 /** Rectangle that describes the visible area in which a shape has to lie
295 at least partly, to be accessible through this class. Used to
296 detect changes of the visible area after changes of the view forwarder.
298 tools::Rectangle maVisibleArea;
300 /** The parent of the shapes. It is used for creating accessible
301 objects for given shapes.
303 css::uno::Reference<css::accessibility::XAccessible> mxParent;
305 /** Bundle of information passed down the shape tree.
307 AccessibleShapeTreeInfo maShapeTreeInfo;
309 /** Reference to an accessible context object that is used to inform its
310 listeners of new and removed children.
312 AccessibleContextBase& mrContext;
314 /** This method is called from the component helper base class while
315 disposing.
317 virtual void disposing(std::unique_lock<std::mutex>&) override;
319 void impl_dispose();
321 ChildrenManagerImpl (const ChildrenManagerImpl&) = delete;
322 ChildrenManagerImpl& operator= (const ChildrenManagerImpl&) = delete;
324 /** This member points to the currently focused shape. It is NULL when
325 there is no focused shape.
327 AccessibleShape* mpFocusedShape;
329 /** Three helper functions for the <member>Update</member> method.
332 /** Create a list of visible shapes from the list of UNO shapes
333 <member>maShapeList</member> and the list of accessible objects.
334 @param raChildList
335 For every visible shape from the two sources mentioned above one
336 descriptor is added to this list.
338 void CreateListOfVisibleShapes (ChildDescriptorListType& raChildList);
340 /** From the old list of (former) visible shapes remove those that
341 are not member of the new list. Send appropriate events for every
342 such shape.
343 @param raNewChildList
344 The new list of visible children against which the old one
345 is compared.
346 @param raOldChildList
347 The old list of visible children against which the new one
348 is compared.
350 void RemoveNonVisibleChildren (
351 const std::vector<ChildDescriptor*>& rNonVisibleChildren);
353 /** Merge the information that is already known about the visible shapes
354 from the old list into the current list, and return a list of
355 children that are in the old list, but not the current one.
356 @param raChildList
357 Information is merged to the current list of visible children
358 from this list. The old list can get reordered.
359 @return
360 Vector of children that are in the old list, but not the current
361 one.
363 std::vector<ChildDescriptor*> MergeAccessibilityInformation (ChildDescriptorListType& raChildList);
365 /** If the visible area has changed then send events that signal a
366 change of their bounding boxes for all shapes that are members of
367 both the current and the new list of visible shapes.
368 @param raChildList
369 Events are sent to all entries of this list that already contain
370 an accessible object.
372 static void SendVisibleAreaEvents (ChildDescriptorListType& raChildList);
374 /** If children have to be created immediately and not on demand the
375 create the missing accessible objects now.
376 @param raDescriptorList
377 Create an accessible object for every member of this list where
378 that object does not already exist.
380 void CreateAccessibilityObjects (ChildDescriptorListType& raChildList);
382 /** Add a single shape. Update all relevant data structures
383 accordingly. Use this method instead of <member>Update()</member>
384 when only a single shape has been added.
386 void AddShape (const css::uno::Reference<css::drawing::XShape>& xShape);
388 /** Remove a single shape. Update all relevant data structures
389 accordingly. Use this method instead of <member>Update()</member>
390 when only a single shape has been removed.
392 void RemoveShape (const css::uno::Reference<css::drawing::XShape>& xShape);
394 /** Add the children manager as dispose listener at the given shape so
395 that the associated accessible object can be disposed when the shape
396 is disposed.
397 @param xShape
398 Register at this shape as dispose listener.
400 void RegisterAsDisposeListener (const css::uno::Reference<css::drawing::XShape>& xShape);
402 /** Remove the children manager as dispose listener at the given shape
403 @param xShape
404 Unregister at this shape as dispose listener.
406 void UnregisterAsDisposeListener (const css::uno::Reference<css::drawing::XShape>& xShape);
410 /** A child descriptor holds a reference to a UNO shape and the
411 corresponding accessible object. There are two use cases:
412 <ol><li>The accessible object is only created on demand and is then
413 initially empty.</li>
414 <li>There is no UNO shape. The accessible object is given as argument
415 to the constructor.</li>
416 </ol>
417 In both cases the child descriptor assumes ownership over the accessible
418 object.
420 class ChildDescriptor
422 public:
423 /** Reference to a (partially) visible shape.
425 css::uno::Reference<css::drawing::XShape> mxShape;
427 /** The corresponding accessible object. This reference is initially
428 empty and only replaced by a reference to a new object when that is
429 requested from the outside.
431 rtl::Reference<AccessibleShape> mxAccessibleShape;
433 /** Return a pointer to the implementation object of the accessible
434 shape of this descriptor.
435 @return
436 The result is NULL if either the UNO reference to the accessible
437 shape is empty or it can not be transformed into a pointer to
438 the desired class.
440 AccessibleShape* GetAccessibleShape() const { return mxAccessibleShape.get(); }
442 /** set the index _nIndex at the accessible shape
443 @param _nIndex
444 The new index in parent.
446 void setIndexAtAccessibleShape(sal_Int32 _nIndex);
448 /** This flag is set during the visibility calculation and indicates
449 that at one time in this process an event is sent that informs the
450 listeners of the creation of a new accessible object. This flags is
451 not reset afterwards. Don't use it unless you know exactly what you
452 are doing.
454 bool mbCreateEventPending;
456 /** Create a new descriptor for the specified shape with empty reference
457 to accessible object.
459 explicit ChildDescriptor (const css::uno::Reference<css::drawing::XShape>& xShape);
461 /** Create a new descriptor for the specified shape with empty reference
462 to the original shape.
464 explicit ChildDescriptor (const rtl::Reference<AccessibleShape>& rxAccessibleShape);
466 /** Dispose the accessible object of this descriptor. If that object
467 does not exist then do nothing.
468 @param rParent
469 The parent of the accessible object to dispose. A child event
470 is sent in its name.
472 void disposeAccessibleObject (AccessibleContextBase& rParent);
474 /** Compare two child descriptors. Take into account that a child
475 descriptor may be based on a UNO shape or, already, on an accessible
476 shape.
478 bool operator == (const ChildDescriptor& aDescriptor) const
480 return (
481 this == &aDescriptor ||
483 (mxShape.get() == aDescriptor.mxShape.get() ) &&
484 (mxShape.is() || mxAccessibleShape.get() == aDescriptor.mxAccessibleShape.get())
492 } // end of namespace accessibility
494 #endif
496 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */