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 
28 #include <vos/mutex.hxx>
29 #include <tools/list.hxx>
30 #include <tools/color.hxx>
31 #include <tools/string.hxx>
32 #ifndef _IMAGE_HXX
33 #include <vcl/image.hxx>
34 #endif
35 #include <rtl/uuid.h>
36 #include <cppuhelper/implbase5.hxx>
37 #include <cppuhelper/compbase6.hxx>
38 #include <comphelper/broadcasthelper.hxx>
39 #include <com/sun/star/lang/XUnoTunnel.hpp>
40 #include <com/sun/star/accessibility/XAccessible.hpp>
41 #include <com/sun/star/accessibility/XAccessibleContext.hpp>
42 #include <com/sun/star/accessibility/XAccessibleComponent.hpp>
43 #include <com/sun/star/accessibility/XAccessibleSelection.hpp>
44 #include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
45 #include <com/sun/star/lang/DisposedException.hpp>
46 
47 #include <memory>
48 #include <vector>
49 
50 // -----------
51 // - Defines -
52 // -----------
53 
54 #define ITEM_OFFSET 				4
55 #define ITEM_OFFSET_DOUBLE			6
56 #define NAME_LINE_OFF_X 			2
57 #define NAME_LINE_OFF_Y 			2
58 #define NAME_LINE_HEIGHT			2
59 #define NAME_OFFSET 				2
60 #define SCRBAR_OFFSET				1
61 #define VALUESET_ITEM_NONEITEM		0xFFFE
62 #define VALUESET_SCROLL_OFFSET		4
63 
64 // --------------------
65 // - ValueSetItemType -
66 // --------------------
67 
68 enum ValueSetItemType
69 {
70 	VALUESETITEM_NONE,
71 	VALUESETITEM_IMAGE,
72 	VALUESETITEM_COLOR,
73 	VALUESETITEM_USERDRAW,
74 	VALUESETITEM_SPACE
75 };
76 
77 // ----------------
78 // - ValueSetItem -
79 // ----------------
80 
81 class ValueSet;
82 
83 struct ValueSetItem
84 {
85 	ValueSet&           mrParent;
86     sal_uInt16				mnId;
87 	sal_uInt16				mnBits;
88 	ValueSetItemType	meType;
89 	Image				maImage;
90 	Color				maColor;
91 	XubString			maText;
92 	void*				mpData;
93 	Rectangle			maRect;
94 	::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >* mpxAcc;
95 
96     ValueSetItem( ValueSet& rParent );
97     ~ValueSetItem();
98 
99     ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
100                         GetAccessible( bool bIsTransientChildrenDisabled );
101      void               ClearAccessible();
102 };
103 
104 // -----------------------------------------------------------------------------
105 
106 DECLARE_LIST( ValueItemList, ValueSetItem* )
107 
108 // -----------------------------------------------------------------------------
109 
110 struct ValueSet_Impl
111 {
112     ::std::auto_ptr< ValueItemList >    mpItemList;
113     bool                                mbIsTransientChildrenDisabled;
114 	Link								maHighlightHdl;
115 
116     ValueSet_Impl() :   mpItemList( ::std::auto_ptr< ValueItemList >( new ValueItemList() ) ),
117                         mbIsTransientChildrenDisabled( false )
118     {
119     }
120 };
121 
122 // ---------------
123 // - ValueSetAcc -
124 // ---------------
125 
126 typedef ::cppu::WeakComponentImplHelper6<
127     ::com::sun::star::accessibility::XAccessible,
128     ::com::sun::star::accessibility::XAccessibleEventBroadcaster,
129     ::com::sun::star::accessibility::XAccessibleContext,
130     ::com::sun::star::accessibility::XAccessibleComponent,
131     ::com::sun::star::accessibility::XAccessibleSelection,
132     ::com::sun::star::lang::XUnoTunnel >
133     ValueSetAccComponentBase;
134 
135 class ValueSetAcc :
136     public ::comphelper::OBaseMutex,
137     public ValueSetAccComponentBase
138 {
139 public:
140 
141     ValueSetAcc( ValueSet* pParent, bool bIsTransientChildrenDisabled );
142     ~ValueSetAcc();
143 
144     void                FireAccessibleEvent( short nEventId, const ::com::sun::star::uno::Any& rOldValue, const ::com::sun::star::uno::Any& rNewValue );
145     sal_Bool                HasAccessibleListeners() const { return( mxEventListeners.size() > 0 ); }
146 
147     static ValueSetAcc* getImplementation( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rxData ) throw();
148 
149 public:
150 
151     /** Called by the corresponding ValueSet when it gets the focus.
152         Stores the new focus state and broadcasts a state change event.
153     */
154     void GetFocus (void);
155 
156     /** Called by the corresponding ValueSet when it loses the focus.
157         Stores the new focus state and broadcasts a state change event.
158     */
159     void LoseFocus (void);
160 
161 
162     // XAccessible
163     virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext(  ) throw (::com::sun::star::uno::RuntimeException);
164 
165     // XAccessibleEventBroadcaster
166     using cppu::WeakComponentImplHelper6<com::sun::star::accessibility::XAccessible, com::sun::star::accessibility::XAccessibleEventBroadcaster, com::sun::star::accessibility::XAccessibleContext, com::sun::star::accessibility::XAccessibleComponent, com::sun::star::accessibility::XAccessibleSelection, com::sun::star::lang::XUnoTunnel>::addEventListener;
167     virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
168     using cppu::WeakComponentImplHelper6<com::sun::star::accessibility::XAccessible, com::sun::star::accessibility::XAccessibleEventBroadcaster, com::sun::star::accessibility::XAccessibleContext, com::sun::star::accessibility::XAccessibleComponent, com::sun::star::accessibility::XAccessibleSelection, com::sun::star::lang::XUnoTunnel>::removeEventListener;
169     virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
170 
171     // XAccessibleContext
172     virtual sal_Int32 SAL_CALL getAccessibleChildCount(  ) throw (::com::sun::star::uno::RuntimeException);
173     virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int32 i ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
174     virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleParent(  ) throw (::com::sun::star::uno::RuntimeException);
175     virtual sal_Int32 SAL_CALL getAccessibleIndexInParent(  ) throw (::com::sun::star::uno::RuntimeException);
176     virtual sal_Int16 SAL_CALL getAccessibleRole(  ) throw (::com::sun::star::uno::RuntimeException);
177     virtual ::rtl::OUString SAL_CALL getAccessibleDescription(  ) throw (::com::sun::star::uno::RuntimeException);
178     virtual ::rtl::OUString SAL_CALL getAccessibleName(  ) throw (::com::sun::star::uno::RuntimeException);
179     virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet(  ) throw (::com::sun::star::uno::RuntimeException);
180     virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleStateSet > SAL_CALL getAccessibleStateSet(  ) throw (::com::sun::star::uno::RuntimeException);
181     virtual ::com::sun::star::lang::Locale SAL_CALL getLocale(  ) throw (::com::sun::star::accessibility::IllegalAccessibleComponentStateException, ::com::sun::star::uno::RuntimeException);
182 
183     // XAccessibleComponent
184     virtual sal_Bool SAL_CALL containsPoint( const ::com::sun::star::awt::Point& aPoint ) throw (::com::sun::star::uno::RuntimeException);
185     virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleAtPoint( const ::com::sun::star::awt::Point& aPoint ) throw (::com::sun::star::uno::RuntimeException);
186     virtual ::com::sun::star::awt::Rectangle SAL_CALL getBounds(  ) throw (::com::sun::star::uno::RuntimeException);
187     virtual ::com::sun::star::awt::Point SAL_CALL getLocation(  ) throw (::com::sun::star::uno::RuntimeException);
188     virtual ::com::sun::star::awt::Point SAL_CALL getLocationOnScreen(  ) throw (::com::sun::star::uno::RuntimeException);
189     virtual ::com::sun::star::awt::Size SAL_CALL getSize(  ) throw (::com::sun::star::uno::RuntimeException);
190     virtual void SAL_CALL grabFocus(  ) throw (::com::sun::star::uno::RuntimeException);
191     virtual ::com::sun::star::uno::Any SAL_CALL getAccessibleKeyBinding(  ) throw (::com::sun::star::uno::RuntimeException);
192     virtual sal_Int32 SAL_CALL getForeground(  ) throw (::com::sun::star::uno::RuntimeException);
193     virtual sal_Int32 SAL_CALL getBackground(  ) throw (::com::sun::star::uno::RuntimeException);
194 
195     // XAccessibleSelection
196     virtual void SAL_CALL selectAccessibleChild( sal_Int32 nChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
197     virtual sal_Bool SAL_CALL isAccessibleChildSelected( sal_Int32 nChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
198     virtual void SAL_CALL clearAccessibleSelection(  ) throw (::com::sun::star::uno::RuntimeException);
199     virtual void SAL_CALL selectAllAccessibleChildren(  ) throw (::com::sun::star::uno::RuntimeException);
200     virtual sal_Int32 SAL_CALL getSelectedAccessibleChildCount(  ) throw (::com::sun::star::uno::RuntimeException);
201     virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
202     virtual void SAL_CALL deselectAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
203 
204     // XUnoTunnel
205     virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& rId ) throw( ::com::sun::star::uno::RuntimeException );
206 
207 private:
208     //    ::vos::OMutex                                                                                                           maMutex;
209     ::std::vector< ::com::sun::star::uno::Reference<
210         ::com::sun::star::accessibility::XAccessibleEventListener > >   mxEventListeners;
211     ValueSet*                                                           mpParent;
212     bool                                                                mbIsTransientChildrenDisabled;
213     /// The current FOCUSED state.
214     bool mbIsFocused;
215 
216 	static const ::com::sun::star::uno::Sequence< sal_Int8 >& getUnoTunnelId();
217 
218     /** Tell all listeners that the object is dying.  This callback is
219         usually called from the WeakComponentImplHelper class.
220     */
221     virtual void SAL_CALL disposing (void);
222 
223     /** Return the number of items.  This takes the None-Item into account.
224     */
225     sal_uInt16 getItemCount (void) const;
226 
227     /** Return the item associated with the given index.  The None-Item is
228         taken into account which, when present, is taken to be the first
229         (with index 0) item.
230         @param nIndex
231             Index of the item to return.  The index 0 denotes the None-Item
232             when present.
233         @return
234             Returns NULL when the given index is out of range.
235     */
236     ValueSetItem* getItem (sal_uInt16 nIndex) const;
237 
238     /** Check whether or not the object has been disposed (or is in the
239         state of beeing disposed).  If that is the case then
240         DisposedException is thrown to inform the (indirect) caller of the
241         foul deed.
242     */
243     void ThrowIfDisposed (void)
244         throw (::com::sun::star::lang::DisposedException);
245 
246     /** Check whether or not the object has been disposed (or is in the
247         state of beeing disposed).
248 
249         @return sal_True, if the object is disposed or in the course
250         of being disposed. Otherwise, sal_False is returned.
251     */
252     sal_Bool IsDisposed (void);
253 
254     /** Check whether the value set has a 'none' field, i.e. a field (button)
255         that deselects any items (selects none of them).
256         @return
257             Returns <true/> if there is a 'none' field and <false/> it it is
258             missing.
259     */
260     bool HasNoneField (void) const;
261 };
262 
263 // ----------------
264 // - ValueItemAcc -
265 // ----------------
266 
267 class ValueItemAcc : public ::cppu::WeakImplHelper5< ::com::sun::star::accessibility::XAccessible,
268                                                      ::com::sun::star::accessibility::XAccessibleEventBroadcaster,
269                                                      ::com::sun::star::accessibility::XAccessibleContext,
270                                                      ::com::sun::star::accessibility::XAccessibleComponent,
271                                                      ::com::sun::star::lang::XUnoTunnel >
272 {
273 private:
274 
275     ::std::vector< ::com::sun::star::uno::Reference<
276         ::com::sun::star::accessibility::XAccessibleEventListener > >   mxEventListeners;
277     ::vos::OMutex                                                       maMutex;
278     ValueSetItem*                                                       mpParent;
279     bool                                                                mbIsTransientChildrenDisabled;
280 
281 	static const ::com::sun::star::uno::Sequence< sal_Int8 >& getUnoTunnelId();
282 
283 public:
284 
285     ValueItemAcc( ValueSetItem* pParent, bool bIsTransientChildrenDisabled );
286     ~ValueItemAcc();
287 
288     void    ParentDestroyed();
289 
290     void    FireAccessibleEvent( short nEventId, const ::com::sun::star::uno::Any& rOldValue, const ::com::sun::star::uno::Any& rNewValue );
291     sal_Bool    HasAccessibleListeners() const { return( mxEventListeners.size() > 0 ); }
292 
293     static ValueItemAcc* getImplementation( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rxData ) throw();
294 
295 public:
296 
297     // XAccessible
298     virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext(  ) throw (::com::sun::star::uno::RuntimeException);
299 
300     // XAccessibleEventBroadcaster
301     virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
302     virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
303 
304     // XAccessibleContext
305     virtual sal_Int32 SAL_CALL getAccessibleChildCount(  ) throw (::com::sun::star::uno::RuntimeException);
306     virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int32 i ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
307     virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleParent(  ) throw (::com::sun::star::uno::RuntimeException);
308     virtual sal_Int32 SAL_CALL getAccessibleIndexInParent(  ) throw (::com::sun::star::uno::RuntimeException);
309     virtual sal_Int16 SAL_CALL getAccessibleRole(  ) throw (::com::sun::star::uno::RuntimeException);
310     virtual ::rtl::OUString SAL_CALL getAccessibleDescription(  ) throw (::com::sun::star::uno::RuntimeException);
311     virtual ::rtl::OUString SAL_CALL getAccessibleName(  ) throw (::com::sun::star::uno::RuntimeException);
312     virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet(  ) throw (::com::sun::star::uno::RuntimeException);
313     virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleStateSet > SAL_CALL getAccessibleStateSet(  ) throw (::com::sun::star::uno::RuntimeException);
314     virtual ::com::sun::star::lang::Locale SAL_CALL getLocale(  ) throw (::com::sun::star::accessibility::IllegalAccessibleComponentStateException, ::com::sun::star::uno::RuntimeException);
315 
316     // XAccessibleComponent
317     virtual sal_Bool SAL_CALL containsPoint( const ::com::sun::star::awt::Point& aPoint ) throw (::com::sun::star::uno::RuntimeException);
318     virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleAtPoint( const ::com::sun::star::awt::Point& aPoint ) throw (::com::sun::star::uno::RuntimeException);
319     virtual ::com::sun::star::awt::Rectangle SAL_CALL getBounds(  ) throw (::com::sun::star::uno::RuntimeException);
320     virtual ::com::sun::star::awt::Point SAL_CALL getLocation(  ) throw (::com::sun::star::uno::RuntimeException);
321     virtual ::com::sun::star::awt::Point SAL_CALL getLocationOnScreen(  ) throw (::com::sun::star::uno::RuntimeException);
322     virtual ::com::sun::star::awt::Size SAL_CALL getSize(  ) throw (::com::sun::star::uno::RuntimeException);
323     virtual void SAL_CALL grabFocus(  ) throw (::com::sun::star::uno::RuntimeException);
324     virtual ::com::sun::star::uno::Any SAL_CALL getAccessibleKeyBinding(  ) throw (::com::sun::star::uno::RuntimeException);
325     virtual sal_Int32 SAL_CALL getForeground(  ) throw (::com::sun::star::uno::RuntimeException);
326     virtual sal_Int32 SAL_CALL getBackground(  ) throw (::com::sun::star::uno::RuntimeException);
327 
328     // XUnoTunnel
329     virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& rId ) throw( ::com::sun::star::uno::RuntimeException );
330 };
331