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