579 lines
23 KiB
C++
579 lines
23 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*************************************************************************
|
|
*
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* Copyright 2000, 2010 Oracle and/or its affiliates.
|
|
*
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
|
*
|
|
* This file is part of OpenOffice.org.
|
|
*
|
|
* OpenOffice.org is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License version 3
|
|
* only, as published by the Free Software Foundation.
|
|
*
|
|
* OpenOffice.org is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Lesser General Public License version 3 for more details
|
|
* (a copy is included in the LICENSE file that accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* version 3 along with OpenOffice.org. If not, see
|
|
* <http://www.openoffice.org/license.html>
|
|
* for a copy of the LGPLv3 License.
|
|
*
|
|
************************************************************************/
|
|
|
|
#ifndef _SVX_ACCESSIBILITY_CHILDREN_MANAGER_IMPL_HXX
|
|
|
|
#include <svx/IAccessibleViewForwarderListener.hxx>
|
|
#include <svx/IAccessibleParent.hxx>
|
|
#include <svx/AccessibleShapeTreeInfo.hxx>
|
|
#include <editeng/AccessibleContextBase.hxx>
|
|
#include <cppuhelper/compbase2.hxx>
|
|
#include <osl/mutex.hxx>
|
|
#include <vector>
|
|
#include <memory>
|
|
#include <com/sun/star/drawing/XShape.hpp>
|
|
#include <com/sun/star/drawing/XShapes.hpp>
|
|
#include <com/sun/star/document/XEventListener.hpp>
|
|
#include <com/sun/star/view/XSelectionChangeListener.hpp>
|
|
#include <com/sun/star/accessibility/XAccessible.hpp>
|
|
|
|
using namespace ::com::sun::star;
|
|
|
|
namespace accessibility {
|
|
|
|
class AccessibleShape;
|
|
|
|
class ChildDescriptor; // See below for declaration.
|
|
typedef ::std::vector<ChildDescriptor> ChildDescriptorListType;
|
|
|
|
// Re-using MutexOwner class defined in AccessibleContextBase.hxx
|
|
|
|
/** This class contains the actual implementation of the children manager.
|
|
|
|
<p>It maintains a set of visible accessible shapes in
|
|
<member>maVisibleChildren</member>. The objects in this list stem from
|
|
two sources. The first is a list of UNO shapes like the list of shapes
|
|
in a draw page. A reference to this list is held in
|
|
<member>maShapeList</member>. Accessible objects for these shapes are
|
|
created on demand. The list can be replaced by calls to the
|
|
<member>SetShapeList</member> method. The second source is a list of
|
|
already accessible objects. It can be modified by calls to the
|
|
<member>AddAccessibleShape</member> and
|
|
<member>ClearAccessibleShapeList</member> methods.</p>
|
|
|
|
<p>Each call of the <member>Update</member> method leads to a
|
|
re-calculation of the visible shapes which then can be queried with the
|
|
<member>GetChildCount</member> and <member>GetChild</member> methods.
|
|
Events are send informing all listeners about the removed shapes which are
|
|
not visible anymore and about the added shapes.</p>
|
|
|
|
<p> The visible area which is used to determine the visibility of the
|
|
shapes is taken from the view forwarder. Thus, to signal a change of
|
|
the visible area call <member>ViewForwarderChanged</member>.</p>
|
|
|
|
<p>The children manager adds itself as disposing() listener at every UNO
|
|
shape it creates an accessible object for so that when the UNO shape
|
|
passes away it can dispose() the associated accessible object.</p>
|
|
|
|
@see ChildrenManager
|
|
*/
|
|
class ChildrenManagerImpl
|
|
: public MutexOwner,
|
|
public cppu::WeakComponentImplHelper2<
|
|
::com::sun::star::document::XEventListener,
|
|
::com::sun::star::view::XSelectionChangeListener>,
|
|
public IAccessibleViewForwarderListener,
|
|
public IAccessibleParent
|
|
{
|
|
public:
|
|
/** Create a children manager, which manages the children of the given
|
|
parent. The parent is used for creating accessible objects. The
|
|
list of shapes for which to create those objects is not derived from
|
|
the parent and has to be provided seperately by calling one of the
|
|
update methods.
|
|
@param rxParent
|
|
The parent of the accessible objects which will be created
|
|
on demand at some point of time in the future.
|
|
@param rxShapeList
|
|
List of UNO shapes to manage.
|
|
@param rShapeTreeInfo
|
|
Bundel of information passed down the shape tree.
|
|
@param rContext
|
|
An accessible context object that is called for fireing events
|
|
for new and deleted children, i.e. that holds a list of
|
|
listeners to be informed.
|
|
*/
|
|
ChildrenManagerImpl (const ::com::sun::star::uno::Reference<
|
|
::com::sun::star::accessibility::XAccessible>& rxParent,
|
|
const ::com::sun::star::uno::Reference<
|
|
::com::sun::star::drawing::XShapes>& rxShapeList,
|
|
const AccessibleShapeTreeInfo& rShapeTreeInfo,
|
|
AccessibleContextBase& rContext);
|
|
|
|
/** If there still are managed children these are disposed and
|
|
released.
|
|
*/
|
|
~ChildrenManagerImpl (void);
|
|
|
|
/** Do that part of the initialization that you can not or should not do
|
|
in the constructor like registering at broadcasters.
|
|
*/
|
|
void Init (void);
|
|
|
|
/** Return the number of currently visible accessible children.
|
|
@return
|
|
If there are no children a 0 is returned.
|
|
*/
|
|
long GetChildCount (void) const throw ();
|
|
|
|
/** Return the requested accessible child or throw and
|
|
IndexOutOfBoundsException if the given index is invalid.
|
|
@param nIndex
|
|
Index of the requested child. Call getChildCount for obtaining
|
|
the number of children.
|
|
@return
|
|
In case of a valid index this method returns a reference to the
|
|
requested accessible child. This reference is empty if it has
|
|
not been possible to create the accessible object of the
|
|
corresponding shape.
|
|
@raises
|
|
Throws an IndexOutOfBoundsException if the index is not valid.
|
|
*/
|
|
::com::sun::star::uno::Reference<
|
|
::com::sun::star::accessibility::XAccessible>
|
|
GetChild (long nIndex)
|
|
throw (::com::sun::star::uno::RuntimeException,
|
|
::com::sun::star::lang::IndexOutOfBoundsException);
|
|
|
|
/** Return the requested accessible child.
|
|
@param aChildDescriptor
|
|
This object contains references to the original shape and its
|
|
associated accessible object.
|
|
@param _nIndex
|
|
The index which will be used in getAccessibleIndexInParent of the accessible shape.
|
|
@return
|
|
Returns a reference to the requested accessible child. This
|
|
reference is empty if it has not been possible to create the
|
|
accessible object of the corresponding shape.
|
|
*/
|
|
::com::sun::star::uno::Reference<
|
|
::com::sun::star::accessibility::XAccessible>
|
|
GetChild (ChildDescriptor& aChildDescriptor,sal_Int32 _nIndex)
|
|
throw (::com::sun::star::uno::RuntimeException);
|
|
|
|
/** Return the requested accessible child given a shape. This method
|
|
searches the list of descriptors for the one that holds the
|
|
association of the given shape to the requested accessible object
|
|
and returns that. If no such descriptor is found that is
|
|
interpreted so that the specified shape is not visible at the moment.
|
|
@param xShape
|
|
The shape for which to return the associated accessible object.
|
|
@return
|
|
Returns a reference to the requested accessible child. The
|
|
reference is empty if there is no shape descriptor that
|
|
associates the shape with an accessible object.
|
|
*/
|
|
::com::sun::star::uno::Reference<
|
|
::com::sun::star::accessibility::XAccessible>
|
|
GetChild (const ::com::sun::star::uno::Reference<
|
|
::com::sun::star::drawing::XShape>& xShape)
|
|
throw (::com::sun::star::uno::RuntimeException);
|
|
|
|
/** Update the child manager. Take care of a modified set of children
|
|
and modified visible area. This method can optimize the update
|
|
process with respect seperate updates of a modified children list
|
|
and visible area.
|
|
@param bCreateNewObjectsOnDemand
|
|
If </true> then accessible objects associated with the visible
|
|
shapes are created only when asked for. No event is sent on
|
|
creation. If </false> then the accessible objects are created
|
|
before this method returns and events are sent to inform the
|
|
listeners of the new object.
|
|
*/
|
|
void Update (bool bCreateNewObjectsOnDemand = true);
|
|
|
|
/** Set the list of UNO shapes to the given list. This removes the old
|
|
list and does not add to it. The list of accessible shapes that is
|
|
build up by calls to <member>AddAccessibleShape</member> is not
|
|
modified. Neither is the list of visible children. Accessible
|
|
objects are created on demand.
|
|
@param xShapeList
|
|
The list of UNO shapes that replaces the old list.
|
|
*/
|
|
void SetShapeList (const ::com::sun::star::uno::Reference<
|
|
::com::sun::star::drawing::XShapes>& xShapeList);
|
|
|
|
/** Add a accessible shape. This does not modify the list of UNO shapes
|
|
or the list of visible shapes. Accessible shapes are, at the
|
|
moment, not tested against the visible area but are always appended
|
|
to the list of visible children.
|
|
@param pShape
|
|
The new shape that is added to the list of accessible shapes.
|
|
*/
|
|
void AddAccessibleShape (std::auto_ptr<AccessibleShape> pShape);
|
|
|
|
/** Clear the lists of accessible shapes and that of visible accessible
|
|
shapes. The list of UNO shapes is not modified.
|
|
*/
|
|
void ClearAccessibleShapeList (void);
|
|
|
|
/** Set a new event shape tree info. Call this method to inform the
|
|
children manager of a change of the info bundle.
|
|
@param rShapeTreeInfo
|
|
The new info that replaces the current one.
|
|
*/
|
|
void SetInfo (const AccessibleShapeTreeInfo& rShapeTreeInfo);
|
|
|
|
/** Update the SELECTED and FOCUSED states of all visible children
|
|
according to the given selection. This includes setting
|
|
<em>and</em> resetting the states.
|
|
*/
|
|
void UpdateSelection (void);
|
|
|
|
/** Return whether one of the shapes managed by this object has
|
|
currently the focus.
|
|
@return
|
|
Returns <true/> when there is a shape that has the focus and
|
|
<false/> when there is no such shape.
|
|
*/
|
|
bool HasFocus (void);
|
|
|
|
/** When there is a shape that currently has the focus,
|
|
i.e. <member>HasFocus()</member> returns <true/> then remove the
|
|
focus from that shape. Otherwise nothing changes.
|
|
*/
|
|
void RemoveFocus (void);
|
|
|
|
//===== lang::XEventListener ============================================
|
|
|
|
virtual void SAL_CALL
|
|
disposing (const ::com::sun::star::lang::EventObject& rEventObject)
|
|
throw (::com::sun::star::uno::RuntimeException);
|
|
|
|
|
|
//===== document::XEventListener ========================================
|
|
|
|
virtual void SAL_CALL
|
|
notifyEvent (const ::com::sun::star::document::EventObject& rEventObject)
|
|
throw (::com::sun::star::uno::RuntimeException);
|
|
|
|
|
|
//===== view::XSelectionChangeListener ==================================
|
|
|
|
virtual void SAL_CALL
|
|
selectionChanged (const ::com::sun::star::lang::EventObject& rEvent)
|
|
throw (::com::sun::star::uno::RuntimeException);
|
|
|
|
|
|
//===== IAccessibleViewForwarderListener ================================
|
|
|
|
/** Informs this children manager and its children about a change of one
|
|
(or more) aspect of the view forwarder.
|
|
@param aChangeType
|
|
A change type of <const>VISIBLE_AREA</const> leads to a call to
|
|
the <member>Update</memeber> which creates accessible objects of
|
|
new shapes immediately. Other change types are passed to the
|
|
visible accessible children without calling
|
|
<member>Update</memeber>.
|
|
@param pViewForwarder
|
|
The modified view forwarder. Use this one from now on.
|
|
*/
|
|
virtual void ViewForwarderChanged (ChangeType aChangeType,
|
|
const IAccessibleViewForwarder* pViewForwarder);
|
|
|
|
//===== IAccessibleParent ===============================================
|
|
|
|
/** Replace the specified child with a replacement.
|
|
@param pCurrentChild
|
|
This child is to be replaced.
|
|
@param pReplacement
|
|
The replacement for the current child.
|
|
@return
|
|
The returned value indicates wether the replacement has been
|
|
finished successfully.
|
|
*/
|
|
virtual sal_Bool ReplaceChild (
|
|
AccessibleShape* pCurrentChild,
|
|
const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& _rxShape,
|
|
const long _nIndex,
|
|
const AccessibleShapeTreeInfo& _rShapeTreeInfo
|
|
) throw (::com::sun::star::uno::RuntimeException);
|
|
|
|
|
|
protected:
|
|
/** This list holds the descriptors of all currently visible shapes and
|
|
associated accessible object.
|
|
|
|
<p>With the descriptors it maintains a mapping of shapes to
|
|
accessible objects. It acts as a cache in that accessible objects
|
|
are only created on demand and released with every update (where the
|
|
latter may be optimized by the update methods).<p>
|
|
|
|
<p>The list is realized as a vector because it remains unchanged
|
|
between updates (i.e. complete rebuilds of the list) and allows a
|
|
fast (constant time) access to its elements for given indices.</p>
|
|
*/
|
|
ChildDescriptorListType maVisibleChildren;
|
|
|
|
/** The original list of UNO shapes. The visible shapes are inserted
|
|
into the list of visible children
|
|
<member>maVisibleChildren</member>.
|
|
*/
|
|
::com::sun::star::uno::Reference<
|
|
::com::sun::star::drawing::XShapes> mxShapeList;
|
|
|
|
/** This list of additional accessible shapes that can or shall not be
|
|
created by the shape factory.
|
|
*/
|
|
typedef std::vector< ::com::sun::star::uno::Reference<
|
|
::com::sun::star::accessibility::XAccessible> > AccessibleShapeList;
|
|
AccessibleShapeList maAccessibleShapes;
|
|
|
|
/** Rectangle that describes the visible area in which a shape has to lie
|
|
at least partly, to be accessible through this class. Used to
|
|
detect changes of the visible area after changes of the view forwarder.
|
|
*/
|
|
Rectangle maVisibleArea;
|
|
|
|
/** The parent of the shapes. It is used for creating accessible
|
|
objects for given shapes.
|
|
*/
|
|
::com::sun::star::uno::Reference<
|
|
::com::sun::star::accessibility::XAccessible> mxParent;
|
|
|
|
/** Bundel of information passed down the shape tree.
|
|
*/
|
|
AccessibleShapeTreeInfo maShapeTreeInfo;
|
|
|
|
/** Reference to an accessible context object that is used to inform its
|
|
listeners of new and remved children.
|
|
*/
|
|
AccessibleContextBase& mrContext;
|
|
|
|
/** This method is called from the component helper base class while
|
|
disposing.
|
|
*/
|
|
virtual void SAL_CALL disposing (void);
|
|
|
|
/** Experimental: Get the index of the specified accessible object with
|
|
respect to the list of children maintained by this object.
|
|
|
|
@return
|
|
Return the index of the given child or -1 to indicate that the
|
|
child is unknown.
|
|
*/
|
|
long GetChildIndex (const ::com::sun::star::uno::Reference<
|
|
::com::sun::star::accessibility::XAccessible>& xChild) const
|
|
throw (::com::sun::star::uno::RuntimeException);
|
|
|
|
void impl_dispose (void);
|
|
|
|
private:
|
|
/** Names of new accessible objects are disambiguated with this index.
|
|
It gets increased every time a new object is created and (at the
|
|
moment) never reset.
|
|
*/
|
|
sal_Int32 mnNewNameIndex;
|
|
|
|
// Don't use the copy constructor or the assignment operator. They are
|
|
// not implemented (and are not intended to be).
|
|
ChildrenManagerImpl (const ChildrenManagerImpl&);
|
|
ChildrenManagerImpl& operator= (const ChildrenManagerImpl&);
|
|
|
|
/** This member points to the currently focused shape. It is NULL when
|
|
there is no focused shape.
|
|
*/
|
|
AccessibleShape* mpFocusedShape;
|
|
|
|
/** Three helper functions for the <member>Update</member> method.
|
|
*/
|
|
|
|
/** Create a list of visible shapes from the list of UNO shapes
|
|
<member>maShapeList</member> and the list of accessible objects.
|
|
@param raChildList
|
|
For every visible shape from the two sources mentioned above one
|
|
descriptor is added to this list.
|
|
*/
|
|
void CreateListOfVisibleShapes (ChildDescriptorListType& raChildList);
|
|
|
|
/** From the old list of (former) visible shapes remove those that
|
|
are not member of the new list. Send appropriate events for every
|
|
such shape.
|
|
@param raNewChildList
|
|
The new list of visible children against which the old one
|
|
is compared.
|
|
@param raOldChildList
|
|
The old list of visible children against which the new one
|
|
is compared.
|
|
*/
|
|
void RemoveNonVisibleChildren (
|
|
const ChildDescriptorListType& raNewChildList,
|
|
ChildDescriptorListType& raOldChildList);
|
|
|
|
/** Merge the information that is already known about the visible shapes
|
|
from the current list into the new list.
|
|
@param raChildList
|
|
Information is merged from the current list of visible children
|
|
to this list.
|
|
*/
|
|
void MergeAccessibilityInformation (ChildDescriptorListType& raChildList);
|
|
|
|
/** If the visible area has changed then send events that signal a
|
|
change of their bounding boxes for all shapes that are members of
|
|
both the current and the new list of visible shapes.
|
|
@param raChildList
|
|
Events are sent to all entries of this list that already contain
|
|
an accessible object.
|
|
*/
|
|
void SendVisibleAreaEvents (ChildDescriptorListType& raChildList);
|
|
|
|
/** If children have to be created immediately and not on demand the
|
|
create the missing accessible objects now.
|
|
@param raDescriptorList
|
|
Create an accessible object for every member of this list where
|
|
that obejct does not already exist.
|
|
*/
|
|
void CreateAccessibilityObjects (ChildDescriptorListType& raChildList);
|
|
|
|
/** Add a single shape. Update all relevant data structures
|
|
accordingly. Use this method instead of <member>Update()</member>
|
|
when only a single shape has been added.
|
|
*/
|
|
void AddShape (const ::com::sun::star::uno::Reference<
|
|
::com::sun::star::drawing::XShape>& xShape);
|
|
|
|
/** Remove a single shape. Update all relevant data structures
|
|
accordingly. Use this method instead of <member>Update()</member>
|
|
when only a single shape has been removed.
|
|
*/
|
|
void RemoveShape (const ::com::sun::star::uno::Reference<
|
|
::com::sun::star::drawing::XShape>& xShape);
|
|
|
|
/** Add the children manager as dispose listener at the given shape so
|
|
that the associated accessible object can be disposed when the shape
|
|
is disposed.
|
|
@param xShape
|
|
Register at this shape as dispose listener.
|
|
*/
|
|
void RegisterAsDisposeListener (const ::com::sun::star::uno::Reference<
|
|
::com::sun::star::drawing::XShape>& xShape);
|
|
|
|
/** Remove the children manager as dispose listener at the given shape
|
|
@param xShape
|
|
Unregister at this shape as dispose listener.
|
|
*/
|
|
void UnregisterAsDisposeListener (const ::com::sun::star::uno::Reference<
|
|
::com::sun::star::drawing::XShape>& xShape);
|
|
};
|
|
|
|
|
|
|
|
|
|
/** A child descriptor holds a reference to a UNO shape and the
|
|
corresponding accessible object. There are two use cases:
|
|
<ol><li>The accessible object is only created on demand and is then
|
|
initially empty.</li>
|
|
<li>There is no UNO shape. The accessible object is given as argument
|
|
to the constructor.</li>
|
|
</ol>
|
|
In both cases the child descriptor assumes ownership over the accessible
|
|
object.
|
|
*/
|
|
class ChildDescriptor
|
|
{
|
|
public:
|
|
/** Reference to a (partially) visible shape.
|
|
*/
|
|
::com::sun::star::uno::Reference<
|
|
::com::sun::star::drawing::XShape> mxShape;
|
|
|
|
/** The corresponding accessible object. This reference is initially
|
|
empty and only replaced by a reference to a new object when that is
|
|
requested from the outside.
|
|
*/
|
|
::com::sun::star::uno::Reference<
|
|
::com::sun::star::accessibility::XAccessible> mxAccessibleShape;
|
|
|
|
/** Return a pointer to the implementation object of the accessible
|
|
shape of this descriptor.
|
|
@return
|
|
The result is NULL if either the UNO reference to the accessible
|
|
shape is empty or it can not be transformed into a pointer to
|
|
the desired class.
|
|
*/
|
|
AccessibleShape* GetAccessibleShape (void) const;
|
|
|
|
/** set the index _nIndex at the accessible shape
|
|
@param _nIndex
|
|
The new index in parent.
|
|
*/
|
|
void setIndexAtAccessibleShape(sal_Int32 _nIndex);
|
|
|
|
/** This flag is set during the visibility calculation and indicates
|
|
that at one time in this process an event is sent that informs the
|
|
listners of the creation of a new accessible object. This flags is
|
|
not reset afterwards. Don't use it unless you know exactly what you
|
|
are doing.
|
|
*/
|
|
bool mbCreateEventPending;
|
|
|
|
/** Create a new descriptor for the specified shape with empty reference
|
|
to accessible object.
|
|
*/
|
|
explicit ChildDescriptor (const ::com::sun::star::uno::Reference<
|
|
::com::sun::star::drawing::XShape>& xShape);
|
|
|
|
/** Create a new descriptor for the specified shape with empty reference
|
|
to the original shape.
|
|
*/
|
|
explicit ChildDescriptor (const ::com::sun::star::uno::Reference<
|
|
::com::sun::star::accessibility::XAccessible>& rxAccessibleShape);
|
|
|
|
~ChildDescriptor (void);
|
|
|
|
/** Dispose the accessible object of this descriptor. If that object
|
|
does not exist then do nothing.
|
|
@param rParent
|
|
The parent of the accessible object to dispose. A child event
|
|
is sent in its name.
|
|
*/
|
|
void disposeAccessibleObject (AccessibleContextBase& rParent);
|
|
|
|
/** Compare two child descriptors. Take into account that a child
|
|
descriptor may be based on a UNO shape or, already, on an accessible
|
|
shape.
|
|
*/
|
|
inline bool operator == (const ChildDescriptor& aDescriptor) const
|
|
{
|
|
return (
|
|
this == &aDescriptor ||
|
|
(
|
|
(mxShape.get() == aDescriptor.mxShape.get() ) &&
|
|
(mxShape.is() || mxAccessibleShape.get() == aDescriptor.mxAccessibleShape.get())
|
|
)
|
|
);
|
|
}
|
|
|
|
/** The ordering defined by this operator is only used in order to be able
|
|
to put child descriptors in some STL containers. The ordering itself is
|
|
not so important, its 'features' are not used.
|
|
*/
|
|
inline bool operator < (const ChildDescriptor& aDescriptor) const
|
|
{
|
|
return (mxShape.get() < aDescriptor.mxShape.get());
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
} // end of namespace accessibility
|
|
|
|
#endif
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|