1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 #ifndef _CHART2_ACCESSIBLEBASE_HXX_
28 #define _CHART2_ACCESSIBLEBASE_HXX_
29 
30 #include "ObjectIdentifier.hxx"
31 
32 #include <com/sun/star/chart2/XChartDocument.hpp>
33 #include <com/sun/star/accessibility/XAccessible.hpp>
34 #include <com/sun/star/accessibility/XAccessibleContext.hpp>
35 #include <com/sun/star/accessibility/XAccessibleComponent.hpp>
36 #include <com/sun/star/lang/XServiceInfo.hpp>
37 #include <com/sun/star/document/XEventListener.hpp>
38 #include <com/sun/star/lang/XEventListener.hpp>
39 #include <com/sun/star/lang/DisposedException.hpp>
40 #include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
41 #include <com/sun/star/view/XSelectionSupplier.hpp>
42 #include <comphelper/accessibleeventnotifier.hxx>
43 #include <cppuhelper/compbase6.hxx>
44 #include <cppuhelper/interfacecontainer.hxx>
45 #include <unotools/accessiblestatesethelper.hxx>
46 
47 #include <vector>
48 #include <map>
49 #include <boost/shared_ptr.hpp>
50 
51 #include "MutexContainer.hxx"
52 
53 class SfxItemSet;
54 class SdrObject;
55 class SdrView;
56 
57 namespace accessibility
58 {
59 class IAccessibleViewForwarder;
60 }
61 
62 namespace chart
63 {
64 
65 class AccessibleBase;
66 class ObjectHierarchy;
67 
68 typedef ObjectIdentifier AccessibleUniqueId;
69 
70 struct AccessibleElementInfo
71 {
72     AccessibleUniqueId m_aOID;
73 
74     ::com::sun::star::uno::WeakReference<
75             ::com::sun::star::chart2::XChartDocument > m_xChartDocument;
76     ::com::sun::star::uno::WeakReference<
77             ::com::sun::star::view::XSelectionSupplier > m_xSelectionSupplier;
78     ::com::sun::star::uno::WeakReference<
79             ::com::sun::star::uno::XInterface >   m_xView;
80     ::com::sun::star::uno::WeakReference<
81             ::com::sun::star::awt::XWindow >      m_xWindow;
82 
83     ::boost::shared_ptr< ObjectHierarchy > m_spObjectHierarchy;
84 
85     AccessibleBase * m_pParent;
86     SdrView* m_pSdrView;
87     ::accessibility::IAccessibleViewForwarder* m_pViewForwarder;
88 };
89 
90 
91 namespace impl
92 {
93 typedef ::cppu::WeakComponentImplHelper6<
94         ::com::sun::star::accessibility::XAccessible,
95         ::com::sun::star::accessibility::XAccessibleContext,
96         ::com::sun::star::accessibility::XAccessibleComponent,
97         ::com::sun::star::accessibility::XAccessibleEventBroadcaster,
98         ::com::sun::star::lang::XServiceInfo,
99         ::com::sun::star::lang::XEventListener
100         > AccessibleBase_Base;
101 }
102 
103 /** Base class for all Chart Accessibility objects
104  */
105 class AccessibleBase :
106     public MutexContainer,
107     public impl::AccessibleBase_Base
108 {
109 public:
110     enum EventType
111     {
112         OBJECT_CHANGE,
113         GOT_SELECTION,
114         LOST_SELECTION,
115         PROPERTY_CHANGE
116     };
117 
118     AccessibleBase( const AccessibleElementInfo & rAccInfo,
119                     bool bMayHaveChildren,
120                     bool bAlwaysTransparent = false );
121     virtual ~AccessibleBase();
122 
123 protected:
124     // for all calls to protected methods it is assumed that the mutex is locked
125     // unless calls outside via UNO, e.g. event notification, are done
126 
127     /** @param bThrowException if true, a DisposedException is thrown if the
128                object is already disposed
129         @return true, if the component is already disposed and bThrowException is false,
130                 false otherwise
131      */
132     bool             CheckDisposeState( bool bThrowException = true ) const throw (::com::sun::star::lang::DisposedException);
133 
134     /** Events coming from the core have to be processed in this methods.  The
135         default implementation returns false, which indicates that the object is
136         not interested in the event.  To react on events you have to implement
137         this method in derived classes.
138 
139         The default implementation iterates over all children and forwards the
140         event until the first child returns true.
141 
142         @param nObjId contains the object id of chart objects.  If the object is
143                 no chart object, the event is not broadcast.
144         @return If an object is the addressee of the event it should return
145                 true, false otherwise.
146      */
147     virtual bool     NotifyEvent( EventType eType, const AccessibleUniqueId & rId );
148 
149     /** Adds a state to the set.
150     */
151     void             AddState( sal_Int16 aState ) throw (::com::sun::star::uno::RuntimeException);
152 
153     /** Removes a state from the set if the set contains the state, otherwise
154         nothing is done.
155     */
156     void             RemoveState( sal_Int16 aState ) throw (::com::sun::star::uno::RuntimeException);
157 
158     /** has to be overloaded by derived classes that support child elements.
159         With this method a rescan is initiated that should result in a correct
160         list of children.
161 
162         This method is called when access to any methods concerning children is
163         invoked for the first time.
164      */
165     bool UpdateChildren();
166 
167     /** Is called by UpdateChildren.  This method is only called if an update is
168         really necessary.
169      */
170     virtual bool ImplUpdateChildren();
171 
172     /** adds a child to the end of the internal vector of children.  As a
173         result, the child-count increases by one, but all existing children keep
174         their indices.
175 
176         Important: as the implementation is needed, this should remain the only
177         method for adding children (i.e. there mustn't be an AddChild( Reference<
178         XAccessible > ) or the like).
179      */
180     void         AddChild( AccessibleBase* pChild );
181 
182     /** removes a child from the internal vector.  All children with index
183         greater than the index of the removed element get an index one less than
184         before.
185      */
186     void         RemoveChildByOId( const ObjectIdentifier& rOId );
187 
188     /** Retrieve the pixel coordinates of logical coordinates (0,0) of the
189         current logic coordinate system.  This can be used for
190         getLocationOnScreen, if the coordinates of an object are not relative to
191         its direct parent, but a parent higher up in hierarchy.
192 
193         @return the (x,y) pixel coordinates of the upper left corner
194      */
195     virtual ::com::sun::star::awt::Point   GetUpperLeftOnScreen() const;
196 
197     /** This method creates an AccessibleEventObject and sends it to all
198         listeners that are currently listening to this object
199 
200         If bSendGlobally is true, the event is also broadcast via
201         vcl::unohelper::NotifyAccessibleStateEventGlobally()
202      */
203     void         BroadcastAccEvent( sal_Int16 nId,
204                                     const ::com::sun::star::uno::Any & rNew,
205                                     const ::com::sun::star::uno::Any & rOld,
206                                     bool bSendGlobally = false ) const;
207 
208     /** Removes all children from the internal lists and broadcasts child remove
209         events.
210 
211         This method cares about mutex locking, and thus should be called without
212         the mutex locked.
213      */
214     virtual void KillAllChildren();
215 
216     /** Is called from getAccessibleChild(). Before this method is called, an
217         update of children is done if necessary.
218      */
219     virtual ::com::sun::star::uno::Reference<
220             ::com::sun::star::accessibility::XAccessible >
221         ImplGetAccessibleChildById( sal_Int32 i ) const
222         throw (::com::sun::star::lang::IndexOutOfBoundsException,
223                ::com::sun::star::uno::RuntimeException);
224 
225     /** Is called from getAccessibleChildCount(). Before this method is called,
226         an update of children is done if necessary.
227      */
228     virtual sal_Int32 ImplGetAccessibleChildCount() const
229         throw (::com::sun::star::uno::RuntimeException);
230 
231     AccessibleElementInfo GetInfo() const;
232     void SetInfo( const AccessibleElementInfo & rNewInfo );
233     AccessibleUniqueId GetId() const;
234 
235     // ________ WeakComponentImplHelper (XComponent::dispose) ________
236     virtual void SAL_CALL disposing();
237 
238     // ________ XAccessible ________
239     virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext()
240         throw (::com::sun::star::uno::RuntimeException);
241 
242     // ________ XAccessibleContext ________
243     virtual sal_Int32 SAL_CALL getAccessibleChildCount()
244         throw (::com::sun::star::uno::RuntimeException);
245     virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL
246         getAccessibleChild( sal_Int32 i )
247         throw (::com::sun::star::lang::IndexOutOfBoundsException,
248                ::com::sun::star::uno::RuntimeException);
249     virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL
250         getAccessibleParent()
251         throw (::com::sun::star::uno::RuntimeException);
252     virtual sal_Int32 SAL_CALL getAccessibleIndexInParent()
253         throw (::com::sun::star::uno::RuntimeException);
254     /// @return AccessibleRole.SHAPE
255     virtual sal_Int16 SAL_CALL getAccessibleRole()
256         throw (::com::sun::star::uno::RuntimeException);
257     // has to be implemented by derived classes
258 //     virtual ::rtl::OUString SAL_CALL getAccessibleName()
259 //         throw (::com::sun::star::uno::RuntimeException);
260     virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleRelationSet > SAL_CALL
261         getAccessibleRelationSet()
262         throw (::com::sun::star::uno::RuntimeException);
263     virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleStateSet > SAL_CALL
264         getAccessibleStateSet()
265         throw (::com::sun::star::uno::RuntimeException);
266     virtual ::com::sun::star::lang::Locale SAL_CALL getLocale()
267         throw (::com::sun::star::accessibility::IllegalAccessibleComponentStateException,
268                ::com::sun::star::uno::RuntimeException);
269     // has to be implemented by derived classes
270 //     virtual ::rtl::OUString SAL_CALL getAccessibleDescription()
271 //         throw (::com::sun::star::uno::RuntimeException);
272 
273     // ________ XAccessibleComponent ________
274     virtual sal_Bool SAL_CALL containsPoint(
275         const ::com::sun::star::awt::Point& aPoint )
276         throw (::com::sun::star::uno::RuntimeException);
277     virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL
278         getAccessibleAtPoint( const ::com::sun::star::awt::Point& aPoint )
279         throw (::com::sun::star::uno::RuntimeException);
280     // has to be defined in derived classes
281     virtual ::com::sun::star::awt::Rectangle SAL_CALL getBounds()
282         throw (::com::sun::star::uno::RuntimeException);
283     virtual ::com::sun::star::awt::Point SAL_CALL getLocation()
284         throw (::com::sun::star::uno::RuntimeException);
285     virtual ::com::sun::star::awt::Point SAL_CALL getLocationOnScreen()
286         throw (::com::sun::star::uno::RuntimeException);
287     virtual ::com::sun::star::awt::Size SAL_CALL getSize()
288         throw (::com::sun::star::uno::RuntimeException);
289     virtual void SAL_CALL grabFocus()
290         throw (::com::sun::star::uno::RuntimeException);
291     virtual sal_Int32 SAL_CALL getForeground()
292         throw (::com::sun::star::uno::RuntimeException);
293     virtual sal_Int32 SAL_CALL getBackground()
294         throw (::com::sun::star::uno::RuntimeException);
295 
296     // ________ XServiceInfo ________
297     virtual ::rtl::OUString SAL_CALL getImplementationName()
298         throw (::com::sun::star::uno::RuntimeException);
299     virtual sal_Bool SAL_CALL supportsService(
300         const ::rtl::OUString& ServiceName )
301         throw (::com::sun::star::uno::RuntimeException);
302     virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames()
303         throw (::com::sun::star::uno::RuntimeException);
304 
305     // ________ XEventListener ________
306     virtual void SAL_CALL disposing(
307         const ::com::sun::star::lang::EventObject& Source )
308         throw (::com::sun::star::uno::RuntimeException);
309 
310     using ::cppu::WeakComponentImplHelperBase::addEventListener;
311     using ::cppu::WeakComponentImplHelperBase::removeEventListener;
312 
313     // ________ XAccessibleEventBroadcaster ________
314     virtual void SAL_CALL addEventListener(
315         const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& xListener )
316         throw (::com::sun::star::uno::RuntimeException);
317     virtual void SAL_CALL removeEventListener(
318         const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& xListener )
319         throw (::com::sun::star::uno::RuntimeException);
320 
321 private:
322     enum eColorType
323     {
324         ACC_BASE_FOREGROUND,
325         ACC_BASE_BACKGROUND
326     };
327     sal_Int32 getColor( eColorType eColType );
328 
329 private:
330     typedef ::com::sun::star::uno::Reference<
331             ::com::sun::star::accessibility::XAccessible > tAccessible;
332     /** type of the vector containing the accessible children
333      */
334     typedef ::std::vector< tAccessible > ChildListVectorType;
335     /** type of the hash containing a vector index for every AccessibleUniqueId
336         of the object in the child list
337      */
338     typedef ::std::map< ObjectIdentifier, tAccessible > ChildOIDMap;
339 
340     bool                                  m_bIsDisposed;
341     const bool                            m_bMayHaveChildren;
342     bool                                  m_bChildrenInitialized;
343     ChildListVectorType                   m_aChildList;
344 
345     ChildOIDMap                           m_aChildOIDMap;
346 
347     ::comphelper::AccessibleEventNotifier::TClientId      m_nEventNotifierId;
348 
349     /** Implementation helper for getAccessibleStateSet()
350 
351         Note: This member must come before m_aStateSet!
352      */
353     ::utl::AccessibleStateSetHelper *     m_pStateSetHelper;
354     /** this is returned in getAccessibleStateSet().
355 
356         The implementation is an ::utl::AccessibleStateSetHelper.  To access
357         implementation methods use m_pStateSetHelper.
358 
359         Note: Keeping this reference ensures, that the helper object is only
360               destroyed after this object has been disposed().
361      */
362     ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleStateSet >
363         m_aStateSet;
364 
365     AccessibleElementInfo  m_aAccInfo;
366     const bool             m_bAlwaysTransparent;
367     /** denotes if the state-set is initialized.  On initialization the selected
368         state is checked.
369 
370         This variable is monitored by the solar mutex!
371 
372         Note: declared volatile to enable double-check-locking
373      */
374     volatile bool          m_bStateSetInitialized;
375 };
376 
377 }  // namespace chart
378 
379 #endif
380