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 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_accessibility.hxx"
30 
31 // includes --------------------------------------------------------------
32 #include <accessibility/standard/vclxaccessiblecheckbox.hxx>
33 
34 #include <toolkit/awt/vclxwindows.hxx>
35 #include <accessibility/helper/accresmgr.hxx>
36 #include <accessibility/helper/accessiblestrings.hrc>
37 
38 #include <unotools/accessiblestatesethelper.hxx>
39 #include <comphelper/accessiblekeybindinghelper.hxx>
40 #include <com/sun/star/awt/KeyModifier.hpp>
41 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
42 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
43 #include <cppuhelper/typeprovider.hxx>
44 #include <comphelper/sequence.hxx>
45 
46 #include <vcl/button.hxx>
47 
48 using namespace ::com::sun::star;
49 using namespace ::com::sun::star::uno;
50 using namespace ::com::sun::star::lang;
51 using namespace ::com::sun::star::beans;
52 using namespace ::com::sun::star::accessibility;
53 using namespace ::comphelper;
54 
55 
56 // -----------------------------------------------------------------------------
57 // VCLXAccessibleCheckBox
58 // -----------------------------------------------------------------------------
59 
60 VCLXAccessibleCheckBox::VCLXAccessibleCheckBox( VCLXWindow* pVCLWindow )
61 	:VCLXAccessibleTextComponent( pVCLWindow )
62 {
63     m_bChecked = IsChecked();
64     m_bIndeterminate = IsIndeterminate();
65 }
66 
67 // -----------------------------------------------------------------------------
68 
69 VCLXAccessibleCheckBox::~VCLXAccessibleCheckBox()
70 {
71 }
72 
73 // -----------------------------------------------------------------------------
74 
75 bool VCLXAccessibleCheckBox::IsChecked()
76 {
77     bool bChecked = false;
78 
79     VCLXCheckBox* pVCLXCheckBox = static_cast< VCLXCheckBox* >( GetVCLXWindow() );
80     if ( pVCLXCheckBox && pVCLXCheckBox->getState() == (sal_Int16) 1 )
81         bChecked = true;
82 
83     return bChecked;
84 }
85 
86 // -----------------------------------------------------------------------------
87 
88 bool VCLXAccessibleCheckBox::IsIndeterminate()
89 {
90     bool bIndeterminate = false;
91 
92     VCLXCheckBox* pVCLXCheckBox = static_cast< VCLXCheckBox* >( GetVCLXWindow() );
93     if ( pVCLXCheckBox && pVCLXCheckBox->getState() == (sal_Int16) 2 )
94         bIndeterminate = true;
95 
96     return bIndeterminate;
97 }
98 
99 // -----------------------------------------------------------------------------
100 
101 void VCLXAccessibleCheckBox::SetChecked( bool bChecked )
102 {
103 	if ( m_bChecked != bChecked )
104 	{
105 		Any aOldValue, aNewValue;
106 		if ( m_bChecked )
107 			aOldValue <<= AccessibleStateType::CHECKED;
108 		else
109 			aNewValue <<= AccessibleStateType::CHECKED;
110 		m_bChecked = bChecked;
111 		NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
112 	}
113 }
114 
115 // -----------------------------------------------------------------------------
116 
117 void VCLXAccessibleCheckBox::SetIndeterminate( bool bIndeterminate )
118 {
119 	if ( m_bIndeterminate != bIndeterminate )
120 	{
121 		Any aOldValue, aNewValue;
122 		if ( m_bIndeterminate )
123 			aOldValue <<= AccessibleStateType::INDETERMINATE;
124 		else
125 			aNewValue <<= AccessibleStateType::INDETERMINATE;
126 		m_bIndeterminate = bIndeterminate;
127 		NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
128 	}
129 }
130 
131 // -----------------------------------------------------------------------------
132 
133 void VCLXAccessibleCheckBox::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
134 {
135     switch ( rVclWindowEvent.GetId() )
136     {
137 		case VCLEVENT_CHECKBOX_TOGGLE:
138         {
139             SetChecked( IsChecked() );
140             SetIndeterminate( IsIndeterminate() );
141         }
142         break;
143 		default:
144 			VCLXAccessibleTextComponent::ProcessWindowEvent( rVclWindowEvent );
145    }
146 }
147 
148 // -----------------------------------------------------------------------------
149 
150 void VCLXAccessibleCheckBox::FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet )
151 {
152 	VCLXAccessibleTextComponent::FillAccessibleStateSet( rStateSet );
153 
154     rStateSet.AddState( AccessibleStateType::FOCUSABLE );
155 
156     if ( IsChecked() )
157         rStateSet.AddState( AccessibleStateType::CHECKED );
158 
159     if ( IsIndeterminate() )
160         rStateSet.AddState( AccessibleStateType::INDETERMINATE );
161 }
162 
163 // -----------------------------------------------------------------------------
164 // XInterface
165 // -----------------------------------------------------------------------------
166 
167 IMPLEMENT_FORWARD_XINTERFACE2( VCLXAccessibleCheckBox, VCLXAccessibleTextComponent, VCLXAccessibleCheckBox_BASE )
168 
169 // -----------------------------------------------------------------------------
170 // XTypeProvider
171 // -----------------------------------------------------------------------------
172 
173 IMPLEMENT_FORWARD_XTYPEPROVIDER2( VCLXAccessibleCheckBox, VCLXAccessibleTextComponent, VCLXAccessibleCheckBox_BASE )
174 
175 // -----------------------------------------------------------------------------
176 // XServiceInfo
177 // -----------------------------------------------------------------------------
178 
179 ::rtl::OUString VCLXAccessibleCheckBox::getImplementationName() throw (RuntimeException)
180 {
181 	return ::rtl::OUString::createFromAscii( "com.sun.star.comp.toolkit.AccessibleCheckBox" );
182 }
183 
184 // -----------------------------------------------------------------------------
185 
186 Sequence< ::rtl::OUString > VCLXAccessibleCheckBox::getSupportedServiceNames() throw (RuntimeException)
187 {
188 	Sequence< ::rtl::OUString > aNames(1);
189 	aNames[0] = ::rtl::OUString::createFromAscii( "com.sun.star.awt.AccessibleCheckBox" );
190 	return aNames;
191 }
192 
193 // -----------------------------------------------------------------------------
194 // XAccessibleAction
195 // -----------------------------------------------------------------------------
196 
197 sal_Int32 VCLXAccessibleCheckBox::getAccessibleActionCount( ) throw (RuntimeException)
198 {
199 	OExternalLockGuard aGuard( this );
200 
201 	return 1;
202 }
203 
204 // -----------------------------------------------------------------------------
205 
206 sal_Bool VCLXAccessibleCheckBox::doAccessibleAction ( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException)
207 {
208 	OExternalLockGuard aGuard( this );
209 
210 	if ( nIndex < 0 || nIndex >= getAccessibleActionCount() )
211         throw IndexOutOfBoundsException();
212 
213 	CheckBox* pCheckBox = (CheckBox*) GetWindow();
214 	VCLXCheckBox* pVCLXCheckBox = static_cast< VCLXCheckBox* >( GetVCLXWindow() );
215 	if ( pCheckBox && pVCLXCheckBox )
216 	{
217 		sal_Int32 nValueMin = (sal_Int32) 0;
218 		sal_Int32 nValueMax = (sal_Int32) 1;
219 
220 		if ( pCheckBox->IsTriStateEnabled() )
221 			nValueMax = (sal_Int32) 2;
222 
223 		sal_Int32 nValue = (sal_Int32) pVCLXCheckBox->getState();
224 
225 		++nValue;
226 
227 		if ( nValue > nValueMax )
228 			nValue = nValueMin;
229 
230 		pVCLXCheckBox->setState( (sal_Int16) nValue );
231 	}
232 
233 	return sal_True;
234 }
235 
236 // -----------------------------------------------------------------------------
237 
238 ::rtl::OUString VCLXAccessibleCheckBox::getAccessibleActionDescription ( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException)
239 {
240 	OExternalLockGuard aGuard( this );
241 
242 	if ( nIndex < 0 || nIndex >= getAccessibleActionCount() )
243         throw IndexOutOfBoundsException();
244 
245 	return ::rtl::OUString( TK_RES_STRING( RID_STR_ACC_ACTION_CLICK ) );
246 }
247 
248 // -----------------------------------------------------------------------------
249 
250 Reference< XAccessibleKeyBinding > VCLXAccessibleCheckBox::getAccessibleActionKeyBinding( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException)
251 {
252     OExternalLockGuard aGuard( this );
253 
254     if ( nIndex < 0 || nIndex >= getAccessibleActionCount() )
255         throw IndexOutOfBoundsException();
256 
257     OAccessibleKeyBindingHelper* pKeyBindingHelper = new OAccessibleKeyBindingHelper();
258     Reference< XAccessibleKeyBinding > xKeyBinding = pKeyBindingHelper;
259 
260     Window* pWindow = GetWindow();
261     if ( pWindow )
262     {
263         KeyEvent aKeyEvent = pWindow->GetActivationKey();
264         KeyCode aKeyCode = aKeyEvent.GetKeyCode();
265         if ( aKeyCode.GetCode() != 0 )
266         {
267             awt::KeyStroke aKeyStroke;
268             aKeyStroke.Modifiers = 0;
269             if ( aKeyCode.IsShift() )
270                 aKeyStroke.Modifiers |= awt::KeyModifier::SHIFT;
271             if ( aKeyCode.IsMod1() )
272                 aKeyStroke.Modifiers |= awt::KeyModifier::MOD1;
273             if ( aKeyCode.IsMod2() )
274                 aKeyStroke.Modifiers |= awt::KeyModifier::MOD2;
275             if ( aKeyCode.IsMod3() )
276                 aKeyStroke.Modifiers |= awt::KeyModifier::MOD3;
277             aKeyStroke.KeyCode = aKeyCode.GetCode();
278             aKeyStroke.KeyChar = aKeyEvent.GetCharCode();
279             aKeyStroke.KeyFunc = static_cast< sal_Int16 >( aKeyCode.GetFunction() );
280             pKeyBindingHelper->AddKeyBinding( aKeyStroke );
281         }
282     }
283 
284     return xKeyBinding;
285 }
286 
287 // -----------------------------------------------------------------------------
288 // XAccessibleValue
289 // -----------------------------------------------------------------------------
290 
291 Any VCLXAccessibleCheckBox::getCurrentValue(  ) throw (RuntimeException)
292 {
293 	OExternalLockGuard aGuard( this );
294 
295 	Any aValue;
296 
297 	VCLXCheckBox* pVCLXCheckBox = static_cast< VCLXCheckBox* >( GetVCLXWindow() );
298 	if ( pVCLXCheckBox )
299 		aValue <<= (sal_Int32) pVCLXCheckBox->getState();
300 
301 	return aValue;
302 }
303 
304 // -----------------------------------------------------------------------------
305 
306 sal_Bool VCLXAccessibleCheckBox::setCurrentValue( const Any& aNumber ) throw (RuntimeException)
307 {
308 	OExternalLockGuard aGuard( this );
309 
310 	sal_Bool bReturn = sal_False;
311 
312 	VCLXCheckBox* pVCLXCheckBox = static_cast< VCLXCheckBox* >( GetVCLXWindow() );
313 	if ( pVCLXCheckBox )
314 	{
315 		sal_Int32 nValue = 0, nValueMin = 0, nValueMax = 0;
316 		OSL_VERIFY( aNumber >>= nValue );
317 		OSL_VERIFY( getMinimumValue() >>= nValueMin );
318 		OSL_VERIFY( getMaximumValue() >>= nValueMax );
319 
320 		if ( nValue < nValueMin )
321 			nValue = nValueMin;
322 		else if ( nValue > nValueMax )
323 			nValue = nValueMax;
324 
325 		pVCLXCheckBox->setState( (sal_Int16) nValue );
326 		bReturn = sal_True;
327 	}
328 
329 	return bReturn;
330 }
331 
332 // -----------------------------------------------------------------------------
333 
334 Any VCLXAccessibleCheckBox::getMaximumValue(  ) throw (RuntimeException)
335 {
336 	OExternalLockGuard aGuard( this );
337 
338 	Any aValue;
339 
340 	CheckBox* pCheckBox = (CheckBox*) GetWindow();
341 	if ( pCheckBox && pCheckBox->IsTriStateEnabled() )
342 		aValue <<= (sal_Int32) 2;
343 	else
344 		aValue <<= (sal_Int32) 1;
345 
346 	return aValue;
347 }
348 
349 // -----------------------------------------------------------------------------
350 
351 Any VCLXAccessibleCheckBox::getMinimumValue(  ) throw (RuntimeException)
352 {
353 	OExternalLockGuard aGuard( this );
354 
355 	Any aValue;
356 	aValue <<= (sal_Int32) 0;
357 
358 	return aValue;
359 }
360 
361 // -----------------------------------------------------------------------------
362