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