1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20 #include <standard/accessiblemenucomponent.hxx>
21
22 #include <toolkit/awt/vclxfont.hxx>
23 #include <toolkit/helper/convert.hxx>
24
25 #include <com/sun/star/accessibility/AccessibleRole.hpp>
26 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
27 #include <com/sun/star/awt/XDevice.hpp>
28 #include <com/sun/star/awt/XWindowPeer.hpp>
29 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
30 #include <unotools/accessiblestatesethelper.hxx>
31 #include <unotools/accessiblerelationsethelper.hxx>
32 #include <vcl/svapp.hxx>
33 #include <vcl/window.hxx>
34 #include <vcl/menu.hxx>
35 #include <vcl/settings.hxx>
36 #include <i18nlangtag/languagetag.hxx>
37
38 using namespace ::com::sun::star::accessibility;
39 using namespace ::com::sun::star::uno;
40 using namespace ::com::sun::star::lang;
41 using namespace ::com::sun::star;
42 using namespace ::comphelper;
43
44
45
46
IsEnabled()47 bool OAccessibleMenuComponent::IsEnabled()
48 {
49 return true;
50 }
51
52
IsVisible()53 bool OAccessibleMenuComponent::IsVisible()
54 {
55 bool bVisible = false;
56
57 if ( m_pMenu )
58 bVisible = m_pMenu->IsMenuVisible();
59
60 return bVisible;
61 }
62
63
FillAccessibleStateSet(utl::AccessibleStateSetHelper & rStateSet)64 void OAccessibleMenuComponent::FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet )
65 {
66 if ( IsEnabled() )
67 {
68 rStateSet.AddState( AccessibleStateType::ENABLED );
69 rStateSet.AddState( AccessibleStateType::SENSITIVE );
70 }
71
72 rStateSet.AddState( AccessibleStateType::FOCUSABLE );
73
74 if ( IsFocused() )
75 rStateSet.AddState( AccessibleStateType::FOCUSED );
76
77 if ( IsVisible() )
78 {
79 rStateSet.AddState( AccessibleStateType::VISIBLE );
80 rStateSet.AddState( AccessibleStateType::SHOWING );
81 }
82
83 rStateSet.AddState( AccessibleStateType::OPAQUE );
84 }
85
86
87 // OCommonAccessibleComponent
88
89
implGetBounds()90 awt::Rectangle OAccessibleMenuComponent::implGetBounds()
91 {
92 awt::Rectangle aBounds( 0, 0, 0, 0 );
93
94 if ( m_pMenu )
95 {
96 vcl::Window* pWindow = m_pMenu->GetWindow();
97 if ( pWindow )
98 {
99 // get bounding rectangle of the window in screen coordinates
100 tools::Rectangle aRect = pWindow->GetWindowExtentsRelative( nullptr );
101 aBounds = AWTRectangle( aRect );
102
103 // get position of the accessible parent in screen coordinates
104 Reference< XAccessible > xParent = getAccessibleParent();
105 if ( xParent.is() )
106 {
107 Reference< XAccessibleComponent > xParentComponent( xParent->getAccessibleContext(), UNO_QUERY );
108 if ( xParentComponent.is() )
109 {
110 awt::Point aParentScreenLoc = xParentComponent->getLocationOnScreen();
111
112 // calculate position of the window relative to the accessible parent
113 aBounds.X -= aParentScreenLoc.X;
114 aBounds.Y -= aParentScreenLoc.Y;
115 }
116 }
117 }
118 }
119
120 return aBounds;
121 }
122
123
124 // XInterface
125
126
IMPLEMENT_FORWARD_XINTERFACE2(OAccessibleMenuComponent,OAccessibleMenuBaseComponent,OAccessibleMenuComponent_BASE)127 IMPLEMENT_FORWARD_XINTERFACE2( OAccessibleMenuComponent, OAccessibleMenuBaseComponent, OAccessibleMenuComponent_BASE )
128
129
130 // XTypeProvider
131
132
133 IMPLEMENT_FORWARD_XTYPEPROVIDER2( OAccessibleMenuComponent, OAccessibleMenuBaseComponent, OAccessibleMenuComponent_BASE )
134
135
136 // XAccessibleContext
137
138
139 sal_Int32 OAccessibleMenuComponent::getAccessibleChildCount()
140 {
141 OExternalLockGuard aGuard( this );
142
143 return GetChildCount();
144 }
145
146
getAccessibleChild(sal_Int32 i)147 Reference< XAccessible > OAccessibleMenuComponent::getAccessibleChild( sal_Int32 i )
148 {
149 OExternalLockGuard aGuard( this );
150
151 if ( i < 0 || i >= GetChildCount() )
152 throw IndexOutOfBoundsException();
153
154 return GetChild( i );
155 }
156
157
getAccessibleParent()158 Reference< XAccessible > OAccessibleMenuComponent::getAccessibleParent( )
159 {
160 OExternalLockGuard aGuard( this );
161
162 Reference< XAccessible > xParent;
163
164 if ( m_pMenu )
165 {
166 vcl::Window* pWindow = m_pMenu->GetWindow();
167 if ( pWindow )
168 {
169 vcl::Window* pParent = pWindow->GetAccessibleParentWindow();
170 if ( pParent )
171 xParent = pParent->GetAccessible();
172 }
173 }
174
175 return xParent;
176 }
177
178
getAccessibleRole()179 sal_Int16 OAccessibleMenuComponent::getAccessibleRole( )
180 {
181 OExternalLockGuard aGuard( this );
182
183 return AccessibleRole::UNKNOWN;
184 }
185
186
getAccessibleDescription()187 OUString OAccessibleMenuComponent::getAccessibleDescription( )
188 {
189 OExternalLockGuard aGuard( this );
190
191 OUString sDescription;
192 if ( m_pMenu )
193 {
194 vcl::Window* pWindow = m_pMenu->GetWindow();
195 if ( pWindow )
196 sDescription = pWindow->GetAccessibleDescription();
197 }
198
199 return sDescription;
200 }
201
202
getAccessibleName()203 OUString OAccessibleMenuComponent::getAccessibleName( )
204 {
205 OExternalLockGuard aGuard( this );
206
207 return OUString();
208 }
209
210
getAccessibleRelationSet()211 Reference< XAccessibleRelationSet > OAccessibleMenuComponent::getAccessibleRelationSet( )
212 {
213 OExternalLockGuard aGuard( this );
214
215 return new utl::AccessibleRelationSetHelper;
216 }
217
218
getLocale()219 Locale OAccessibleMenuComponent::getLocale( )
220 {
221 OExternalLockGuard aGuard( this );
222
223 return Application::GetSettings().GetLanguageTag().getLocale();
224 }
225
226
227 // XAccessibleComponent
228
229
getAccessibleAtPoint(const awt::Point & rPoint)230 Reference< XAccessible > OAccessibleMenuComponent::getAccessibleAtPoint( const awt::Point& rPoint )
231 {
232 OExternalLockGuard aGuard( this );
233
234 return GetChildAt( rPoint );
235 }
236
237
getLocationOnScreen()238 awt::Point OAccessibleMenuComponent::getLocationOnScreen( )
239 {
240 OExternalLockGuard aGuard( this );
241
242 awt::Point aPos;
243
244 if ( m_pMenu )
245 {
246 vcl::Window* pWindow = m_pMenu->GetWindow();
247 if ( pWindow )
248 {
249 tools::Rectangle aRect = pWindow->GetWindowExtentsRelative( nullptr );
250 aPos = AWTPoint( aRect.TopLeft() );
251 }
252 }
253
254 return aPos;
255 }
256
257
grabFocus()258 void OAccessibleMenuComponent::grabFocus( )
259 {
260 OExternalLockGuard aGuard( this );
261
262 if ( m_pMenu )
263 {
264 vcl::Window* pWindow = m_pMenu->GetWindow();
265 if ( pWindow )
266 pWindow->GrabFocus();
267 }
268 }
269
270
getForeground()271 sal_Int32 OAccessibleMenuComponent::getForeground( )
272 {
273 OExternalLockGuard aGuard( this );
274
275 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
276 Color nColor = rStyleSettings.GetMenuTextColor();
277
278 return sal_Int32(nColor);
279 }
280
281
getBackground()282 sal_Int32 OAccessibleMenuComponent::getBackground( )
283 {
284 OExternalLockGuard aGuard( this );
285
286 return 0;
287 }
288
289
290 // XAccessibleExtendedComponent
291
292
getFont()293 Reference< awt::XFont > OAccessibleMenuComponent::getFont( )
294 {
295 OExternalLockGuard aGuard( this );
296
297 Reference< awt::XFont > xFont;
298
299 if ( m_pMenu )
300 {
301 vcl::Window* pWindow = m_pMenu->GetWindow();
302 if ( pWindow )
303 {
304 Reference< awt::XDevice > xDev( pWindow->GetComponentInterface(), UNO_QUERY );
305 if ( xDev.is() )
306 {
307 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
308 rtl::Reference<VCLXFont> pVCLXFont = new VCLXFont;
309 pVCLXFont->Init( *xDev, rStyleSettings.GetMenuFont() );
310 xFont = pVCLXFont;
311 }
312 }
313 }
314
315 return xFont;
316 }
317
318
getTitledBorderText()319 OUString OAccessibleMenuComponent::getTitledBorderText( )
320 {
321 OExternalLockGuard aGuard( this );
322
323 return OUString();
324 }
325
326
getToolTipText()327 OUString OAccessibleMenuComponent::getToolTipText( )
328 {
329 OExternalLockGuard aGuard( this );
330
331 return OUString();
332 }
333
334
335 // XAccessibleSelection
336
337
selectAccessibleChild(sal_Int32 nChildIndex)338 void OAccessibleMenuComponent::selectAccessibleChild( sal_Int32 nChildIndex )
339 {
340 OExternalLockGuard aGuard( this );
341
342 if ( nChildIndex < 0 || nChildIndex >= GetChildCount() )
343 throw IndexOutOfBoundsException();
344
345 SelectChild( nChildIndex );
346 }
347
348
isAccessibleChildSelected(sal_Int32 nChildIndex)349 sal_Bool OAccessibleMenuComponent::isAccessibleChildSelected( sal_Int32 nChildIndex )
350 {
351 OExternalLockGuard aGuard( this );
352
353 if ( nChildIndex < 0 || nChildIndex >= GetChildCount() )
354 throw IndexOutOfBoundsException();
355
356 return IsChildSelected( nChildIndex );
357 }
358
359
clearAccessibleSelection()360 void OAccessibleMenuComponent::clearAccessibleSelection( )
361 {
362 OExternalLockGuard aGuard( this );
363
364 DeSelectAll();
365 }
366
367
selectAllAccessibleChildren()368 void OAccessibleMenuComponent::selectAllAccessibleChildren( )
369 {
370 // This method makes no sense in a menu, and so does nothing.
371 }
372
373
getSelectedAccessibleChildCount()374 sal_Int32 OAccessibleMenuComponent::getSelectedAccessibleChildCount( )
375 {
376 OExternalLockGuard aGuard( this );
377
378 sal_Int32 nRet = 0;
379
380 for ( sal_Int32 i = 0, nCount = GetChildCount(); i < nCount; i++ )
381 {
382 if ( IsChildSelected( i ) )
383 ++nRet;
384 }
385
386 return nRet;
387 }
388
389
getSelectedAccessibleChild(sal_Int32 nSelectedChildIndex)390 Reference< XAccessible > OAccessibleMenuComponent::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex )
391 {
392 OExternalLockGuard aGuard( this );
393
394 if ( nSelectedChildIndex < 0 || nSelectedChildIndex >= getSelectedAccessibleChildCount() )
395 throw IndexOutOfBoundsException();
396
397 Reference< XAccessible > xChild;
398
399 for ( sal_Int32 i = 0, j = 0, nCount = GetChildCount(); i < nCount; i++ )
400 {
401 if ( IsChildSelected( i ) && ( j++ == nSelectedChildIndex ) )
402 {
403 xChild = GetChild( i );
404 break;
405 }
406 }
407
408 return xChild;
409 }
410
411
deselectAccessibleChild(sal_Int32 nChildIndex)412 void OAccessibleMenuComponent::deselectAccessibleChild( sal_Int32 nChildIndex )
413 {
414 OExternalLockGuard aGuard( this );
415
416 if ( nChildIndex < 0 || nChildIndex >= GetChildCount() )
417 throw IndexOutOfBoundsException();
418
419 DeSelectAll();
420 }
421
422
423 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
424