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 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_accessibility.hxx"
26 
27 // includes --------------------------------------------------------------
28 #include <accessibility/standard/vclxaccessibleradiobutton.hxx>
29 
30 #include <toolkit/awt/vclxwindows.hxx>
31 #include <accessibility/helper/accresmgr.hxx>
32 #include <accessibility/helper/accessiblestrings.hrc>
33 
34 #include <unotools/accessiblerelationsethelper.hxx>
35 #include <unotools/accessiblestatesethelper.hxx>
36 #include <comphelper/accessiblekeybindinghelper.hxx>
37 #include <com/sun/star/awt/KeyModifier.hpp>
38 #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
39 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
40 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
41 #include <cppuhelper/typeprovider.hxx>
42 #include <comphelper/sequence.hxx>
43 #include <vcl/window.hxx>
44 #include <vcl/button.hxx>
45 
46 
47 using namespace ::com::sun::star;
48 using namespace ::com::sun::star::uno;
49 using namespace ::com::sun::star::lang;
50 using namespace ::com::sun::star::beans;
51 using namespace ::com::sun::star::accessibility;
52 using namespace ::comphelper;
53 
54 
55 // -----------------------------------------------------------------------------
56 // VCLXAccessibleRadioButton
57 // -----------------------------------------------------------------------------
58 
VCLXAccessibleRadioButton(VCLXWindow * pVCLWindow)59 VCLXAccessibleRadioButton::VCLXAccessibleRadioButton( VCLXWindow* pVCLWindow )
60 	:VCLXAccessibleTextComponent( pVCLWindow )
61 {
62 }
63 
64 // -----------------------------------------------------------------------------
65 
~VCLXAccessibleRadioButton()66 VCLXAccessibleRadioButton::~VCLXAccessibleRadioButton()
67 {
68 }
69 
70 // -----------------------------------------------------------------------------
71 
ProcessWindowEvent(const VclWindowEvent & rVclWindowEvent)72 void VCLXAccessibleRadioButton::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
73 {
74 	switch ( rVclWindowEvent.GetId() )
75 	{
76 		case VCLEVENT_RADIOBUTTON_TOGGLE:
77 		{
78 			Any aOldValue;
79 			Any aNewValue;
80 
81 			VCLXRadioButton* pVCLXRadioButton = static_cast< VCLXRadioButton* >( GetVCLXWindow() );
82 			if ( pVCLXRadioButton && pVCLXRadioButton->getState() )
83 				aNewValue <<= AccessibleStateType::CHECKED;
84 			else
85 				aOldValue <<= AccessibleStateType::CHECKED;
86 
87 			NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
88 		}
89 		break;
90 		default:
91 			VCLXAccessibleTextComponent::ProcessWindowEvent( rVclWindowEvent );
92 	}
93 }
94 
95 // -----------------------------------------------------------------------------
96 
FillAccessibleRelationSet(utl::AccessibleRelationSetHelper & rRelationSet)97 void VCLXAccessibleRadioButton::FillAccessibleRelationSet( utl::AccessibleRelationSetHelper& rRelationSet )
98 {
99 	VCLXAccessibleTextComponent::FillAccessibleRelationSet( rRelationSet );
100 
101 	RadioButton* pRadioButton = dynamic_cast< RadioButton* >( GetWindow() );
102 	if ( pRadioButton )
103 	{
104 		::std::vector< RadioButton* > aGroup;
105 		pRadioButton->GetRadioButtonGroup( aGroup, true );
106 		if ( !aGroup.empty() )
107 		{
108 			sal_Int32 i = 0;
109 			Sequence< Reference< XInterface > > aSequence( static_cast< sal_Int32 >( aGroup.size() ) );
110 			::std::vector< RadioButton* >::const_iterator aEndItr = aGroup.end();
111 			for ( ::std::vector< RadioButton* >::const_iterator aItr = aGroup.begin(); aItr < aEndItr; ++aItr )
112 			{
113 				aSequence[i++] = (*aItr)->GetAccessible();
114 			}
115 			rRelationSet.AddRelation( AccessibleRelation( AccessibleRelationType::MEMBER_OF, aSequence ) );
116 		}
117 	}
118 }
119 
120 // -----------------------------------------------------------------------------
121 
FillAccessibleStateSet(utl::AccessibleStateSetHelper & rStateSet)122 void VCLXAccessibleRadioButton::FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet )
123 {
124 	VCLXAccessibleTextComponent::FillAccessibleStateSet( rStateSet );
125 
126 	VCLXRadioButton* pVCLXRadioButton = static_cast< VCLXRadioButton* >( GetVCLXWindow() );
127 	if ( pVCLXRadioButton )
128 	{
129 		rStateSet.AddState( AccessibleStateType::FOCUSABLE );
130 		if ( pVCLXRadioButton->getState() )
131 			rStateSet.AddState( AccessibleStateType::CHECKED );
132 	}
133 }
134 
135 // -----------------------------------------------------------------------------
136 // XInterface
137 // -----------------------------------------------------------------------------
138 
IMPLEMENT_FORWARD_XINTERFACE2(VCLXAccessibleRadioButton,VCLXAccessibleTextComponent,VCLXAccessibleRadioButton_BASE)139 IMPLEMENT_FORWARD_XINTERFACE2( VCLXAccessibleRadioButton, VCLXAccessibleTextComponent, VCLXAccessibleRadioButton_BASE )
140 
141 // -----------------------------------------------------------------------------
142 // XTypeProvider
143 // -----------------------------------------------------------------------------
144 
145 IMPLEMENT_FORWARD_XTYPEPROVIDER2( VCLXAccessibleRadioButton, VCLXAccessibleTextComponent, VCLXAccessibleRadioButton_BASE )
146 
147 // -----------------------------------------------------------------------------
148 // XServiceInfo
149 // -----------------------------------------------------------------------------
150 
151 ::rtl::OUString VCLXAccessibleRadioButton::getImplementationName() throw (RuntimeException)
152 {
153 	return ::rtl::OUString::createFromAscii( "com.sun.star.comp.toolkit.AccessibleRadioButton" );
154 }
155 
156 // -----------------------------------------------------------------------------
157 
getSupportedServiceNames()158 Sequence< ::rtl::OUString > VCLXAccessibleRadioButton::getSupportedServiceNames() throw (RuntimeException)
159 {
160 	Sequence< ::rtl::OUString > aNames(1);
161 	aNames[0] = ::rtl::OUString::createFromAscii( "com.sun.star.awt.AccessibleRadioButton" );
162 	return aNames;
163 }
164 
165 // -----------------------------------------------------------------------------
166 // XAccessibleAction
167 // -----------------------------------------------------------------------------
168 
getAccessibleActionCount()169 sal_Int32 VCLXAccessibleRadioButton::getAccessibleActionCount( ) throw (RuntimeException)
170 {
171 	OExternalLockGuard aGuard( this );
172 
173 	return 1;
174 }
175 
176 // -----------------------------------------------------------------------------
177 
doAccessibleAction(sal_Int32 nIndex)178 sal_Bool VCLXAccessibleRadioButton::doAccessibleAction ( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException)
179 {
180 	OExternalLockGuard aGuard( this );
181 
182 	if ( nIndex < 0 || nIndex >= getAccessibleActionCount() )
183 		throw IndexOutOfBoundsException();
184 
185 	VCLXRadioButton* pVCLXRadioButton = static_cast< VCLXRadioButton* >( GetVCLXWindow() );
186 	if ( pVCLXRadioButton && !pVCLXRadioButton->getState() )
187 		pVCLXRadioButton->setState( sal_True );
188 
189 	return sal_True;
190 }
191 
192 // -----------------------------------------------------------------------------
193 
getAccessibleActionDescription(sal_Int32 nIndex)194 ::rtl::OUString VCLXAccessibleRadioButton::getAccessibleActionDescription ( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException)
195 {
196 	OExternalLockGuard aGuard( this );
197 
198 	if ( nIndex < 0 || nIndex >= getAccessibleActionCount() )
199 		throw IndexOutOfBoundsException();
200 	return ::rtl::OUString( TK_RES_STRING( RID_STR_ACC_ACTION_SELECT ) );
201 }
202 
203 // -----------------------------------------------------------------------------
204 
getAccessibleActionKeyBinding(sal_Int32 nIndex)205 Reference< XAccessibleKeyBinding > VCLXAccessibleRadioButton::getAccessibleActionKeyBinding( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException)
206 {
207 	OExternalLockGuard aGuard( this );
208 
209 	if ( nIndex < 0 || nIndex >= getAccessibleActionCount() )
210 		throw IndexOutOfBoundsException();
211 
212 	OAccessibleKeyBindingHelper* pKeyBindingHelper = new OAccessibleKeyBindingHelper();
213 	Reference< XAccessibleKeyBinding > xKeyBinding = pKeyBindingHelper;
214 
215 	Window* pWindow = GetWindow();
216 	if ( pWindow )
217 	{
218 		KeyEvent aKeyEvent = pWindow->GetActivationKey();
219 		KeyCode aKeyCode = aKeyEvent.GetKeyCode();
220 		if ( aKeyCode.GetCode() != 0 )
221 		{
222 			awt::KeyStroke aKeyStroke;
223 			aKeyStroke.Modifiers = 0;
224 			if ( aKeyCode.IsShift() )
225 				aKeyStroke.Modifiers |= awt::KeyModifier::SHIFT;
226 			if ( aKeyCode.IsMod1() )
227 				aKeyStroke.Modifiers |= awt::KeyModifier::MOD1;
228 			if ( aKeyCode.IsMod2() )
229 				aKeyStroke.Modifiers |= awt::KeyModifier::MOD2;
230 			if ( aKeyCode.IsMod3() )
231 				aKeyStroke.Modifiers |= awt::KeyModifier::MOD3;
232 			aKeyStroke.KeyCode = aKeyCode.GetCode();
233 			aKeyStroke.KeyChar = aKeyEvent.GetCharCode();
234 			aKeyStroke.KeyFunc = static_cast< sal_Int16 >( aKeyCode.GetFunction() );
235 			pKeyBindingHelper->AddKeyBinding( aKeyStroke );
236 		}
237 	}
238 
239 	return xKeyBinding;
240 }
241 
242 // -----------------------------------------------------------------------------
243 // XAccessibleValue
244 // -----------------------------------------------------------------------------
245 
getCurrentValue()246 Any VCLXAccessibleRadioButton::getCurrentValue(  ) throw (RuntimeException)
247 {
248 	OExternalLockGuard aGuard( this );
249 
250 	Any aValue;
251 
252 	VCLXRadioButton* pVCLXRadioButton = static_cast< VCLXRadioButton* >( GetVCLXWindow() );
253 	if ( pVCLXRadioButton )
254 		aValue <<= (sal_Int32) pVCLXRadioButton->getState();
255 
256 	return aValue;
257 }
258 
259 // -----------------------------------------------------------------------------
260 
setCurrentValue(const Any & aNumber)261 sal_Bool VCLXAccessibleRadioButton::setCurrentValue( const Any& aNumber ) throw (RuntimeException)
262 {
263 	OExternalLockGuard aGuard( this );
264 
265 	sal_Bool bReturn = sal_False;
266 
267 	VCLXRadioButton* pVCLXRadioButton = static_cast< VCLXRadioButton* >( GetVCLXWindow() );
268 	if ( pVCLXRadioButton )
269 	{
270 		sal_Int32 nValue = 0;
271 		OSL_VERIFY( aNumber >>= nValue );
272 
273 		if ( nValue < 0 )
274 			nValue = 0;
275 		else if ( nValue > 1 )
276 			nValue = 1;
277 
278 		pVCLXRadioButton->setState( (sal_Bool) nValue );
279 		bReturn = sal_True;
280 	}
281 
282 	return bReturn;
283 }
284 
285 // -----------------------------------------------------------------------------
286 
getMaximumValue()287 Any VCLXAccessibleRadioButton::getMaximumValue(  ) throw (RuntimeException)
288 {
289 	OExternalLockGuard aGuard( this );
290 
291 	Any aValue;
292 	aValue <<= (sal_Int32) 1;
293 
294 	return aValue;
295 }
296 
297 // -----------------------------------------------------------------------------
298 
getMinimumValue()299 Any VCLXAccessibleRadioButton::getMinimumValue(  ) throw (RuntimeException)
300 {
301 	OExternalLockGuard aGuard( this );
302 
303 	Any aValue;
304 	aValue <<= (sal_Int32) 0;
305 
306 	return aValue;
307 }
308 
309 // -----------------------------------------------------------------------------
310